【问题标题】:Prolog find family eldest and youngest children in listProlog在列表中查找家庭最大和最小的孩子
【发布时间】:2016-04-16 19:02:59
【问题描述】:

我是 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)).

以上是我尝试的答案,但仍然无法正常工作。

【问题讨论】:

  • 什么是最年长的?这只是根据年还是日和月?
  • 儿童年。感谢您的答复。根据年份找出谁是家庭中最年长或最小的孩子。

标签: list recursion prolog


【解决方案1】:

由于关系将描述最年长的孩子,我认为需要一个单一的谓词,例如大孩子/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 中的比较目标。

【讨论】:

  • 感谢您的有用解释和回复!您的代码有效,但我需要一些时间来理解您的代码。再次感谢您的帮助。
猜你喜欢
  • 2017-09-19
  • 2015-02-24
  • 2013-11-16
  • 1970-01-01
  • 1970-01-01
  • 2021-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多