2011-02-16 49 views
4

我是Prolog的新手,我只是在想,爲什麼這個規則在一個真實之後給了我一個假結果。瞭解規則 - 作爲回答的錯誤

likes(1,banana).
likes(1,mango).

test :- likes(1,banana),likes(1,mango).

?- test. 
true; 
false. 

我想知道這背後錯誤的原因。

回答

7

prolog的工作方式是通過評估查詢直到否定失敗。

在這裏,你已經建立了兩個事實:

likes(1, banana).它說 「1喜歡香蕉」

likes(1, mango).它說 「1個喜歡芒果」

那麼你已經建立了一個規則,基本上計算結果爲:

left_hand_side :- right_hand_side.left_hand_side如果right_hand_side

作爲查詢的規則評估嘗試匹配事實,如果可能則返回true,如果不匹配則返回false。需要注意的一點是,如果指定,只要規則評估爲true,prolog就會繼續匹配事實。

因此,讓我們逐步test :- likes(1,banana),likes(1,mango).

如果test運行一個查詢,Prolog的第一嘗試likes(1,banana)這是一個以前建立的事實,是事實。然後,它轉向likes(1,mango),這又是一個事實,並且是事實。 Prolog然後達到了規則的結尾,並輸出true

在這一點上,如果你不搜索更多的匹配,你可以縮短查詢,只是真實。但是,如果您正在尋找更多(全部)匹配項,則可以使用序列號回溯並嘗試再次評估規則,以搜索更多匹配項。

然而,由於你的規則只匹配「喜歡香蕉,喜歡芒果」和序言回溯,並試圖再次評估likes(1,banana),因爲我們之前已經匹配它,當我們已經匹配likes(1,banana),這個時候有沒有另外一個事實(在換句話說,1不能「喜歡」香蕉不止一次,除非已經定義)匹配。所以這就是false的來源。

在您的prolog解釋器中,您可以通過輸入trace.然後運行您的查詢來跟蹤程序的執行情況。下面我跟蹤給定:

| ?- trace 
. 
The debugger will first creep -- showing everything (trace) 

(1 ms) yes 
{trace} 
| ?- test. 
     1 1 Call: test ? 
     2 2 Call: likes(1,banana) ? 
     2 2 Exit: likes(1,banana) ? 
     3 2 Call: likes(1,mango) ? 
     3 2 Exit: likes(1,mango) ? 
     1 1 Exit: test ? 

true ? ; 
     1 1 Redo: test ? 
     2 2 Redo: likes(1,banana) ? 
     2 2 Fail: likes(1,banana) ? 
     1 1 Fail: test ? 

(1 ms) no 
{trace} 
| ?- 

最後一件事要注意:如果,而不是在true ?提示按下;,如果我按<ENTER>,腳本會只用true完成。

我很高興你問這個問題,因爲它允許我在prolog上進行一個小小的複習,我真的很喜歡它,但很久沒有用過了。

+0

感謝您的詳細描述。事實上,我之前並不清楚回溯的概念,而且我認爲回溯只會在我們試圖實例化像'like(1,X)'這樣的變量時纔會完成。但是現在我對這個概念更加清楚了。再次感謝。 – anilonwebs 2011-02-16 08:42:18