2014-02-19 27 views
0

我正在研究一個簡單的程序,它有一個人的數據庫。給予一年的時間應該說明當年的「國王」,國王是最年長的活人。Prolog最早的後繼者

爲了簡單起見,只要數據庫中的所有人在給定年份都活着,並且我假設沒有雙胞胎,那麼所有人都符合條件。

我的問題是在給定年份挑選「最古老」的人。我似乎無法弄清楚如何詢問序言來檢查所有可能的國王並挑選最古老的國王。


male(jack). 
male(roy). 
male(ele). 


born(jack,2000). 

born(dave,1999). 
born(roy,1980). 
born(ele,1990). 

died(jack, 2100). 
died(dave, 2099). 
died(roy, 1990). 
died(ele, 1999). 


% compare X against all other possibleSuccessors and make sure he was born 1st. 

eldest(X,Year):- 
    born(X,T1), 
    born((possibleSuccessor(Year,_)),T2), 
    T1 < T2. 

% must be male and have been born before or durring the given year and must not be dead. 

possibleSuccessor(Year,X):- 
    male(X), 
    born(X,B), 
    died(X,D), 
    (B =< Year), 
    (D >= Year). 


successor(Year):- 
    possibleSuccessor(Year,X), 
    eldest(X,Year), 
    write(X). 

上比較所有可能的答案VS彼此任何幫助,將不勝感激。我之前試圖使用findall,但沒有成功。

+0

出生((posibleSuccessor(年,_)),T2)的表達''沒有做什麼你認爲它的確如此。 Prolog沒有返回值的函數。它具有用於查詢和實例化參數的謂詞。因此,表達式總是會失敗,因爲沒有與出生((possibleSuccessor(...)),...)相匹配的'born/2'事實或謂詞。 – lurker

回答

0

的Prolog提供了否定的限制形式(通過失敗否定)能夠解決您的問題:

eldest(X,Year):- 
    born(X,Year), 
    \+((born(_,T), T<Year)). 

此說,X是長子,如果我們不能找到任何其他在他之前出生的。

可選地,SETOF/3可用於:

eldest(X,Year):- 
    setof((Y,K), born(K,Y), [(Year,X)|_]). 

這個作品排序的所有對(Y,K),那麼我們可以只選擇結果的頭部。

編輯這應該解決的問題,但我已經介紹了服務謂語

eldest(X, Year):- 
    alive(X, Year, B), 
    \+((alive(_, Year, T), T<B)). 

alive(X, Year, B) :- born(X, B), B =< Year, \+ (died(X, D), D < Year). 

% must be male and have been born before or durring the given year and must not be dead. 

possibleSuccessor(Year,X):- 
    male(X), 
    alive(X, Year, _). 

successor(Year):- 
    possibleSuccessor(Year,X), 
    eldest(X,Year), 
    write(X). 
+0

這非常有幫助,但我不認爲它解決了整個問題。這並沒有考慮到人們死亡。經過測試,我已經看到,除非你選擇出生在第一位的人,否則將會因爲在他們之前出生的人而返回假。 – user3330206

+0

你是對的,我誤解了年齡最大的一年的論點...我會嘗試糾正它 – CapelliC