Prolog找到了家庭中最年长和最年轻的孩子

时间:2016-04-16 03:10:07

标签: list recursion prolog

我是Prolog的新手。由于我参加了范式编程课程,我需要每隔几周学习不同的编程。

我参加了一次锻炼,找到了家里最年长和最小的孩子,下面是我的知识库。

family( person(alex, fox, date(26, oct, 1970), work(ucl, wc1e)),
      person(lan, fox, date(6, dec, 1971), unemployed),
      [ person(adrian, fox, date(17, nov, 1996), unemployed),
        person(lisa, fox, date(7, june, 2002), unemployed)
      ]).
family( person(james, bond, date(29, feb, 1950), work(mi6, secretLocation)),
      person(girl, bond, date(01, dec, 2004), unemployed),
      []).
family( person(superman, hero, date(29, feb, 1979), unemployed),
      person(superwoman, hero, date(29, feb, 1979), work(crisisSpot, anywhere)),
      [ person(superbaby, hero, date(7, june, 2002), unemployed) ]).
family( person(picard, captain, date(29, feb, 2400), unemployed),
      person(kirk, captain, date(29, feb, 2300), unemployed),
      [ person(janeway, captain, date(29, feb, 2450), unemployed),
        person(cisco, captain, date(29, feb, 2450), unemployed)
      ]).

我已经解决了剩下的问题只是这个问题我试过了几次仍然不知道,我很难理解列表中的孩子是如何工作的。任何帮助将不胜感激。

% Find eldest children in family
dateofbirth(person(_,_,Date,_), Date).
eldest(X,Y) :-
   family(_,_,Kids),
   member(X,Kids),
   dateofbirth(X, date(_,_,Y)),
   (dateofbirth(X, date(_,_,Y)).

以上是我尝试的答案,但仍然无效。

1 个答案:

答案 0 :(得分:2)

由于关系应描述最年长的孩子,我认为需要一个单位谓词,例如: eldestkid / 1。然后让所有孩子都在列表中会很有帮助。如果你检查你的谓词eldest / 2的前2个目标......

   ?- family(_,_,Kids),member(X,Kids).
Kids = [person(adrian,fox,date(17,nov,1996),unemployed),person(lisa,fox,date(7,june,2002),unemployed)],
X = person(adrian,fox,date(17,nov,1996),unemployed) ? ;
...

......他们一个接一个地给你所有绑定变量X的孩子。所以让我们使用setof / 3将所有这些孩子放在一个列表中:

   ?-  setof(X,A^B^Kids^(family(A,B,Kids),member(X,Kids)),L).
L = [person(adrian,fox,date(17,nov,1996),unemployed),person(cisco,captain,date(29,feb,2450),unemployed),person(janeway,captain,date(29,feb,2450),unemployed),person(lisa,fox,date(7,june,2002),unemployed),person(superbaby,hero,date(7,june,2002),unemployed)]

其余的很直接:

:- use_module(library(lists)).

eldestkid(K) :-
   setof(X,A^B^Kids^(family(A,B,Kids),member(X,Kids)),L),
   eldest_in(K,L).                     % K is the eldest kid in L

eldest_in(EK,[K|Ks]) :-                % the first kid in the list
   eldest_in_(EK,Ks,K).                % is the eldest so far

eldest_in_(EK,[],EK).                  % empty list: ESF is eldest
eldest_in_(EK,[K|Ks],ESF) :-           % case 1: the Eldest So Far
   dateofbirth(K, date(_,_,KY)),
   dateofbirth(ESF, date(_,_,ESFY)),
   ESFY =< KY,                         % is elder that K ...
   eldest_in_(EK,Ks,ESF).              % hence still the ESF
eldest_in_(EK,[K|Ks],ESF) :-           % case 2: the ESF
   dateofbirth(K, date(_,_,KY)),
   dateofbirth(ESF, date(_,_,ESFY)),
   ESFY > KY,                          % is younger than K
   eldest_in_(EK,Ks,K).                % hence K is now the eldest

dateofbirth(person(_,_,Date,_), Date).

示例查询:

   ?- eldestkid(K).
K = person(adrian,fox,date(17,nov,1996),unemployed) ? ;
no

请注意,eldest_in_ / 3仅按照评论中的建议比较年份。如果您还想考虑月份和日期,则需要为此编写谓词并相应地替换eldest_in_ / 3中的比较目标。