我正在开发一个包含人员数据库的简单程序。如果给予一年,它应该说出当年的“国王”,国王是最年长的人。
为简单起见,数据库中的所有人都有资格,只要他们在给定年份还活着,我假设没有双胞胎。
我的问题是挑选一年中活着的“最老的”人。我似乎无法弄清楚如何让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 during 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).
任何帮助比较所有可能的答案相互比较将不胜感激。我之前试图使用findall但是没有成功。
答案 0 :(得分: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).