List 在prolog中重新组织列表

List 在prolog中重新组织列表,list,prolog,List,Prolog,我正在尝试编写一些Prolog代码以获取如下列表: [[park, joe], [park, bob], [park, kate], [school, joe], [zoo, amy], [zoo, ted]]. 并将列表组织成以下形式: [[park,[joe, bob, kate]], [school,[joe]], [zoo,[amy, ted]]]. 可以假设每个元素(park=park,zoo=zoo)的所有匹配头在列表中都是紧挨着的,因为我创建列表的代码是按字母顺序排序的。我

我正在尝试编写一些Prolog代码以获取如下列表:

[[park, joe], [park, bob], [park, kate], [school, joe], [zoo, amy], [zoo, ted]]. 
并将列表组织成以下形式:

[[park,[joe, bob, kate]], [school,[joe]], [zoo,[amy, ted]]]. 
可以假设每个元素(park=park,zoo=zoo)的所有匹配头在列表中都是紧挨着的,因为我创建列表的代码是按字母顺序排序的。我似乎不知道如何做到这一点,而且似乎每次都会出错:(.下面是我到目前为止在最后一个状态下运行时没有错误的代码,我将尝试解释我的想法

merge([],[]).
merge([First|Rest], Z) :- 
merge(Rest, U),
[Meet1, Person1] = First,
( =(U, []) ->   % beginning case from recursion, U is empty
    Meet2 = [],
    Person2 = [];
    [[Meet2|Person2]|_] = U),
 ( =(Meet1, Meet2) -> % Case of matching heads, combine the tails
    print('Match '),
    append([First], U, Z); 
 print('No-match '), % otherwise, not matching
append([First], U, Z) ).
所以我想做的是使用appends来添加对U的所有更改,并使用Z将其返回到控制台

( =(Meet1, Meet2) ->
  append(Person1, Person2, Combpersons),
  append([Meet1], [Combpersons], T),
  append(T, U, Z);
   ...no match code here..).

然而,当我在这里输入的第一个代码块中尝试更改或添加这样的附录时,我的代码总是过早地以false结尾。即使是将append([first],U,Z)变成append([Meet1],U,Z)这样的更改使我的代码以false结尾,我不明白为什么。请提供有关创建解决方案的任何帮助/提示。

您的代码失败,因为您正在尝试提取位置和人员,然后再检查是否有

没有使用
append
在这里,重新排序看起来相当复杂,但我尽了最大努力处理变量名。此外,您只需要一个
->
:如果您没有找到具有相同第一坐标的元组,您将需要一个元组来开始一个新的元组,以前是否没有元组并不重要

merge([],[]).
merge([[Place,Person]|Rest], [[Place,Group]|OtherGroups]) :- 
    merge(Rest, U),
    (U = [[Place,Others]|OtherGroups] ->
     Group = [Person|Others];
     [OtherGroups,Group] = [U, [Person]]).

编辑:出于可读性原因,我更改了解决方案。

如果您将初始列表改为成对列表,则可以使用SWI Prolog中提供的

?- group_pairs_by_key([park-joe, park-bob, park-kate, school-joe, zoo-amy, zoo-ted], G).
G = [park-[joe, bob, kate], school-[joe], zoo-[amy, ted]].

使用这个库不仅仅是“重组”还有一种可能更合适,这取决于你在做什么。

我认为学习任何语言都是一个低层次和高层次问题必须交错的过程。到目前为止,你正在学习基本语法。但是为什么你要使用这种不可读的结构呢?当然,任何编程语言都是建立在一组模式之上的通常由……覆盖

l2p([A,B],A-B).

?- maplist(l2p,[[park, joe], [park, bob], [park, kate], [school, joe], [zoo, amy], [zoo, ted]], L),group_pairs_by_key(L,G).
L = [park-joe, park-bob, park-kate, school-joe, zoo-amy, zoo-ted],
G = [park-[joe, bob, kate], school-[joe], zoo-[amy, ted]].
无论如何,以下是您的代码重组:

merge([],[]).
merge([[Meet, Person]|Rest], Z) :- 
    merge(Rest, U),
    (   U = []
    ->  % beginning case from recursion, U is empty
        Z = [[Meet, [Person]]]
    ;   U = [[Meet, Persons] | Rest1]
    ->  % Case of matching heads, combine the tails
        Z = [[Meet, [Person | Persons]] | Rest1]
    ;   % otherwise, not matching
        Z = [[Meet, [Person]] | U]
    ).

和我写的一样:)