2014-12-04 59 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