2013-01-20 34 views
2

我試圖創建謂詞,如果第三個列表由TF值組成,則取決於第一個列表和第二個列表中相同索引的兩個元素是否相等的謂詞。像truth_list(['abc','def'],['zui','def'],L).這樣的查詢應該給L=['F','T']爲什麼在Prolog中構造真值列表時出現錯誤結果?

這裏是我的嘗試:

truth_list([],[],_). 
truth_list([H1|T1],[H2|T2],TL):- 
    (H1==H2)->(H3='T');(H3='F'), 
    Temp=TL, 
    TL=[H3|Temp], 
    truth_list(T1,T2,TL). 

我會很感激,如果有人可以提供一個解釋,爲什麼預期這不起作用。

回答

2

所以我們都在同一頁上,當我跑的查詢我得到了這樣的結果:

L = ['F'|L]. 

所以,想到的第一件事是,你可能會重複使用一個變量,的確,下列條款看犯罪嫌疑人:

Temp=TL, 
TL=[H3|Temp], 

變量Prolog中是不是真正的「assignables」在其他語言;所有你能真正做的是建立一個綁定,所以上面的代碼是一樣的這樣說:

TL=[H3|TL] 

這就是爲什麼我們的結果看起來像它:L = [「F」 | L]。我改寫了身體微微來解決這個問題,並結束了與此代碼:

truth_list([H1|T1],[H2|T2],[H3|TL]):- 
    (H1=H2 -> H3='T' ; H3='F'), 
    truth_list(T1,T2,TL). 

你需要有圍繞整個條件括號否則你會得到奇怪的行爲。從那裏,我只刪除了不必要的TL綁定(它們無法工作,因爲Prolog中的變量不是可賦值的)。事實證明,一旦你解決這些問題,你會發現另一個問題,這就是你會得到這樣的:

L = ['F', 'T'|_G297]. 

如果不是很明顯,這是因爲你的基礎的情況下過於含糊,而應像這樣的:

truth_list([], [], []). 

所以最終的修正版本是這樣的:

truth_list([],[],[]). 
truth_list([H1|T1],[H2|T2],[H3|TL]):- 
    (H1=H2 -> H3='T' ; H3='F'), 
    truth_list(T1,T2,TL). 

這通常就是@false顯示出來,並指出,我們必須使用與DIF謂詞問題ferent實例,讓我們檢查,現在和避免一些憤怒:

?- truth_list(['abc','def'],['zui','def'],['T','F']). 
false. 
?- truth_list(['abc','def'],['zui','def'],['F','T']). 
true. 
?- truth_list(['abc','def'],['zui','def'],['F','T','T']). 
false. 
?- truth_list(['abc','def'],['zui','def','def'],['F','T','T']). 
false. 

這些看起來都好了,所以它看起來並不像我們產生幻覺,謊言當所有的參數都被實例化。那很好。現在讓我們來看看部分實例:

?- truth_list([X, 'def'], ['abc', Y], ['T', 'T']). 
X = abc, 
Y = def. 

很酷,工作。

?- truth_list([X, 'def'], ['abc', Y], ['F', 'T']). 
false. 

Eh。那麼,它看起來像Prolog不知道爲了那個'F'價值而產生幻覺。不知道這是否是一個問題,但我沒有看到明顯的解決方案。這意味着以下可能不會工作:

?- truth_list(X, Y, ['T', 'T']). 
X = Y, Y = [_G296, _G302]. 

奇怪,但它實際上沒有工作,分配到兩個兩個未知的同一列表。涼。我認爲我們狀態良好。

編輯:讓我們合併@ false的改進。然後,我們得到如下:

truth_list([], [], []). 
truth_list([H1|T1], [H2|T2], [H3|TL]) :- 
    (H1 = H2, H3 = 'T' ; dif(H1,H2), H3 = 'F'), 
    truth_list(T1, T2, TL). 

現在我們獲得所需的行爲:

?- truth_list([X, 'def'], ['abc', Y], ['F', 'T']). 
Y = def, 
dif(X, abc) ; 

所以Prolog有推斷Y是「高清」,並得出結論,X至少不是「ABC」,所以這是一個改進。

+0

感謝,丹尼爾,逗我醒了! – CapelliC

+0

to hallucinate Prolog它已經足夠用(=)/ 2替換(==)/ 2。去搞清楚! – CapelliC

+0

'truth_list(Xs,Ys,[Tr])'不完整。幻覺不夠。 '(H1 = H2,H3 ='T'; dif(H1,H2),H3 ='F')'可以優化'=='和'\ ='的形狀。或者當(?=(H1,H2),(H1 == H2-> H3 ='T'; H3 ='F'))'時。但是,避免'when'和'freeze'有好處。 – false

2

MAPLIST/4可以簡化代碼:

truth_list(A, B, C) :- 
    maplist(truth_, A, B, C). 
truth_(A, B, C) :- 
    A == B -> C = 'T' ; C = 'F'. 

你也可以考慮以提高你的代碼(最終)重用。

而是任意常數「T」,「F」你可以使用可調用謂詞像truefalse,或10得到表達直接使用與中電(FD)

相關問題