List 如何在prolog中对年龄列表进行排序?
我试图在序言中按年龄从高到低排列亲属名单:List 如何在prolog中对年龄列表进行排序?,list,sorting,prolog,List,Sorting,Prolog,我试图在序言中按年龄从高到低排列亲属名单: born(kate,date(11,2,1960)). born(marc,date(11,2,1961)). born(I,date(9,3,1962)). born(michel,date(24,4,1963)). born(harry,date(26,5,1964)). born(jess,date(16,1,1965)). born(ruth,date(26,9,1966)). born(fran,date(4,3,1967)). 结果应该是
born(kate,date(11,2,1960)).
born(marc,date(11,2,1961)).
born(I,date(9,3,1962)).
born(michel,date(24,4,1963)).
born(harry,date(26,5,1964)).
born(jess,date(16,1,1965)).
born(ruth,date(26,9,1966)).
born(fran,date(4,3,1967)).
结果应该是一个列表:[凯特、马克、我、米歇尔、哈里、杰西、露丝、弗兰]
我通过@capelical尝试此代码片段:
pairs_values([], []).
pairs_values([_-V|T0], [V|T]) :-
pairs_values(T0, T).
by_date(Sorted) :-
findall(Date-Person, born(Person,Date), List),
keysort(List, Pairs),
pairs_values(Pairs, Sorted).
但是这个代码并没有对它进行排序。
我需要在ciao Prolog中完成。我们可以在SWi Prolog中完成,使用一些内置的:
by_date(Sorted) :-
findall(Date-Person, born(Person,Date), List),
keysort(List, Pairs),
pairs_values(Pairs, Sorted).
编辑:pairs\u值非常简单:这里是SWI Prolog片段
%% pairs_values(+Pairs, -Values) is det.
%
% Remove the keys from a list of Key-Value pairs. Same as
% pairs_keys_values(Pairs, _, Values)
pairs_values([], []).
pairs_values([_-V|T0], [V|T]) :-
pairs_values(T0, T).
TL;DR:您得到的序列已排序,但排序标准出乎您的意料 让我们试着重现OP观察到的奇怪行为
$ ciao
Ciao 1.14.2-13646: Mon Aug 15 10:15:33 CEST 2011
?- compile(dmy_vs_ymd).
{Reading /home/stefan/Prolog/dmy_vs_ymd.pl
WARNING: (lns 3-3) [I] - singleton variables in born/2
}
yes
?- by_date(S).
S = [fran,_,kate,marc,jess,michel,harry,ruth] ? ;
no
似乎每个元素都放错了位置(相当大的差异:)
- 预计:
[凯特、马克、我、米歇尔、哈里、杰西、露丝、弗兰]
- 观察:
[fran,_uu,kate,marc,jess,michel,harry,ruth]
[弗兰、凯特、马克、杰西、米歇尔、哈里、露丝]
然后检查:
born(fran , date( 4, 03, 1967)).
born(I , date( 9, 03, 1962)).
born(kate , date(11, 02, 1960)).%\_______________________________________________
born(marc , date(11, 02, 1961)).%/ equal primary & secondary, different tertiary
born(jess , date(16, 01, 1965)).
born(michel, date(24, 04, 1963)).
born(harry , date(26, 05, 1964)).%\____________________________________
born(ruth , date(26, 09, 1966)).%/ equal primary, different secondary
% ^^ ^^ ^^^^
% || || ||||
% || || \+++------- tertiary sorting criterion
% || ||
% || \+------------ secondary sorting criterion
% ||
% \+------------------ primary sorting criterion
示例查询:
?- by_date(S).
S = [kate,marc,_,michel,harry,jess,ruth,fran].
嗯。。。我们做完了吗
- 预计:
[凯特、马克、我、米歇尔、哈里、杰西、露丝、弗兰]
- 观察:
[kate,marc,\uz,michel,harry,jess,ruth,fran]
I
是一个变量,我们实际上想要一个常数;将其替换为atomi
。
这个匿名变量是我们在Ciao Prolog会话开始时收到“singleton variable”警告的原因。嗯 我在“ciao prolog”中尝试了这一点,但它抛出了一个错误“存在错误:过程:用户:pairs\u values/2不存在”我需要在“ciao prolog”中完成,对不起。更简单的是:
findall(Date-p,born(p,Date),L0),keysort(L0,L1),findall(p,member(u-p,L1),L2)。
@larsman:有趣,而且可能更高效。在没有垃圾收集的情况下(我不知道Ciao Prolog是否有垃圾收集),findall使用所需的最小空间。我肯定会使用sort/2
代替keysort/2
,因为sort/2
删除重复项和同龄人员的(准随机)顺序。我真的很想使用setof/3
,但是当born/2
没有解决方案时,它失败了(出于一些好的原因),而不是给出一个空列表。而否决投票的原因是@德米特里:在这个问题上,Ciao没有什么特别的,因此标签不合适。将标签保留在有特定问题的问题上。
?- by_date(S).
S = [kate,marc,_,michel,harry,jess,ruth,fran].