2010-07-24 75 views
25

我SWI-Prolog的知識庫包含以下兩個事實:爲什麼這個prolog查詢既是真的也是假的?

f(a,b). 
f(a,c). 

現在,如果我提出查詢

?- f(a,c). 
true. 

?- f(a,b). 
true ; 
false. 

爲什麼F(A,B)是真是假?當知識庫中有三個事實時也會發生這種情況。如果我追加f(a,d)。到KB,則f(a,d)爲真(僅),但是f(a,b)和f(a,c)都是真和假。發生了什麼,以及我能做些什麼,以便Prolog只回答這些查詢?

+3

該死的,好問題。 – 2010-07-24 00:05:22

回答

24

(注:這個答案是有點的猜測)

考慮的Prolog如何確定是否f(a,c)是真還是假。它檢查第一條規則f(a,b),並且找不到匹配項,但第二條規則f(a,c)匹配。因此,f(a,c)是正確的。此外,由於f沒有更多的規則,所以允許回溯發生沒有意義 - 沒有其他可能的解決方案。

現在考慮f(a,b)。 Prolog會檢查第一條規則,並找到一個匹配項。因此,f(a,b)是正確的。但是,並非所有規則都已經用盡。因此,Prolog將允許搜索繼續(如果您點擊了;)。當你繼續搜索和回溯時,它會發現其餘的規則,特別是f(a,c),不匹配f(a,b)。因此,結果是錯誤的。

+11

這個答案是正確的。在Prolog中,編寫事實的規則順序決定了查詢的順序。更具體地說,「回溯」選項「;」本質上告訴力量查詢引擎放棄返回的結果並回答「有沒有其他*答案?」的問題。 所以,並不是f(a,b)既是真的也是假的;而是它是真的,如果你選擇忽略這個結果,引擎會告訴你沒有其他f(a,b)事實條目。爲了證明這一點,看看如果添加第二個f(a,b)事實會發生什麼。 – Assaf 2010-07-24 02:17:49

+4

這也說明了爲什麼你應該關注你的論點的順序,如果你擔心表現。如果謂詞'f'中的參數順序被翻轉了,那麼這不會發生,因爲初始參數不再相同,所以不要留下選擇點。發生這種情況是因爲大多數prolog都執行參數索引,它允許事先從搜索空間修剪帶有不兼容參數的謂詞。 SWI Prolog默認只索引第一個參數,但可以更改。 – nedned 2010-07-26 01:58:40

11

只是除了邁克爾威廉姆森的答案。如果您想告訴Prolog在第一次成功點擊後停止尋找答案,請使用剪切(!):

?- f(a, b), !. 
true. 

?- f(a, c), !. 
true.