我是Prolog的新手,我只是在想,爲什麼這個規則在一個真實之後給了我一個假結果。瞭解規則 - 作爲回答的錯誤
likes(1,banana).
likes(1,mango).
test :- likes(1,banana),likes(1,mango).
?- test.
true;
false.
我想知道這背後錯誤的原因。
我是Prolog的新手,我只是在想,爲什麼這個規則在一個真實之後給了我一個假結果。瞭解規則 - 作爲回答的錯誤
likes(1,banana).
likes(1,mango).
test :- likes(1,banana),likes(1,mango).
?- test.
true;
false.
我想知道這背後錯誤的原因。
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上進行一個小小的複習,我真的很喜歡它,但很久沒有用過了。
感謝您的詳細描述。事實上,我之前並不清楚回溯的概念,而且我認爲回溯只會在我們試圖實例化像'like(1,X)'這樣的變量時纔會完成。但是現在我對這個概念更加清楚了。再次感謝。 – anilonwebs 2011-02-16 08:42:18