2016-12-05 32 views
0

我正在爲我的任務而苦苦掙扎。 首先,我們必須定義謂詞tree/1,其中node(leaf(1), node(leaf(2), leaf(3)))。應該返回true獲取二叉樹的標籤

tree(leaf(_)). 
tree(node(X,Y)) :- tree(X), tree(Y).  

很簡單。
現在我必須寫兩個謂詞,它們本質上應該是一樣的。 label/2labels/2
label(B,X)檢查X是否爲B中的標籤,並應打印X=1;X=2;X=3。 (B是二叉樹)
labels(B,Y)label/2相同,只是Y是包含所有標籤的列表。 (Y=[1,2,3])
我有什麼權利現在:

label(leaf(Y),X) :- 
    %print X? 
label(node(Y,Z),X) :- 
    label(Y,X), label(Z,X). 

labels(leaf(Y),X) :- 
    %append Y to X 
labels(node(Y,Z),X) :- 
    labels(Y,X), labels(Z,X). 

我不能左右的Prolog打印時只是真實,總結我的頭時,它提供了X/Y的解決方案。

回答

1

你不遠。

第一個:label/2

對於leaf/1的情況,您只需簡單地將第二個參數與標籤的內容進行統一;這是

label(leaf(X), X). 

對於node/2情況下,這是錯的(如果我understan您的要求)

label(Y,X), label(Z,X) 

,因爲你問這個X存在於節點Y在節點Z值。您應該要求X存在於節點Y的節點Z中。這是(使用 「或」 操作員 「;」)

label(node(Y,Z),X) :- 
    label(Y,X) ; label(Z,X). 

或更好的(恕我直言)制定兩個獨立的條款

label(node(Y, _), X) :- 
    label(Y, X). 

label(node(_, Y), X) :- 
    label(Y, X). 

二:labels/2

leaf/1情況類似label不同之處在於你必須統一第二個參數,而不是與label/1(第一個參數)的內容相同,但是與列表包含該內容。這很簡單

labels(leaf(X), [X]). 

node/2的情況是不同的。

您的解決方案

labels(Y,X), labels(Z,X). 

,因爲你問的是,子節點Y和子節點Z都包含標籤相同的列表是錯誤的。

您必須收集Y的子列表,收集Z的子列表並連接它們獲得X;這是

labels(node(Y, Z), X) :- 
    labels(Y, X1), 
    labels(Z, X2), 
    append(X1, X2, X). 

彙總,我提出以下label/2labels/2

label(leaf(X), X). 

label(node(Y, _), X) :- 
    label(Y, X). 

label(node(_, Y), X) :- 
    label(Y, X). 


labels(leaf(X), [X]). 

labels(node(Y, Z), X) :- 
    labels(Y, X1), 
    labels(Z, X2), 
    append(X1, X2, X). 
+0

非常感謝你。在Prolog中看起來簡單的解決方案真是太神奇了,但作爲初學者可以變得相當複雜。爲什麼你會爲label/2建議兩個單獨的子句?它只是強調OR? –

+0

@TaikiKurosowa - 我同意:Prolog非常簡單,而且非常優雅,但對於在其他語言中使用的程序員,它有點難以適應。我建議使用兩個子句,而不是一個帶有「或」的子句,因爲我發現兩個子句更容易理解。但我想可以是個人品味的問題。 – max66