2014-12-04 61 views
3

我尝试写一些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)). 

所以我试图做的是利用追加到所有的变化增加U和它与Z.如返回到控制台,

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

但是我的代码保持当我尝试在我放置的第一个代码块中尝试更改或添加像这样的附加内容时,会提前结束使用false。即使将附加内容([First],U,Z)添加到append([Meet1],U, Z)使我的代码以假结束,我不明白为什么。任何帮助/提示创建解决方案,将不胜感激。

回答

1

我认为,学习任何语言它是一个过程,其中低和高水平问题必须交错。到目前为止,您正在学习基本语法。但为什么你使用这种不可读的构造?当然,任何编程语言都建立在一组模式上,通常由libraries覆盖。考虑

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] 
    ). 
0

您的代码失败,因为您正在尝试提取地点和人员,然后检查是否有任何问题。

这里append没有用,重新排序看起来相当复杂,但我尽我所能用变量名称。此外,您只需要一个->:如果您未找到具有相同第一个坐标的元组,则您需要a开始一个新元素,如果之前没有元素,则无关紧要。

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

编辑:我改变的原因可读性 - 该解决方案。

1

如果您将初始列表作为对的列表,则可以使用SWIFT-Prolog中提供的library(pairs)

?- 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]]. 

使用图书馆不仅仅是这种“重组”。也有library(ugraphs),这可能更适合,取决于你在做什么。

+1

我写差不多:) – CapelliC 2014-12-04 13:20:26