Understanding rules - false as answer

☆樱花仙子☆ 提交于 2019-12-22 08:29:47

问题


I am new in Prolog and I was just thinking that why this rule giving me false result after one true.

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

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

?- test.  
true;  
false.

I want to know the reason behind this false.


回答1:


The way prolog works is by evaluating queries until a fail by negation.

Here, you've established two facts:

likes(1, banana). which says "1 likes banana"

likes(1, mango). which says "1 likes mango"

Then you have established a rule, which basically evaluates as:

left_hand_side :- right_hand_side. left_hand_side if right_hand_side

Evaluation of the rule as a query tries to match facts and returns true if it can, and false if it cannot match. One important thing to note is that, if specified, prolog will continue to match facts as long as rules evaluate to true.

So let's step through test :- likes(1,banana),likes(1,mango).

If test is run as a query, prolog first tries likes(1,banana) which is a previously established fact, and is true. Then, it moves on to likes(1,mango) which, again, is a fact, and is true. Prolog has then reached the end of the rule, and outputs true.

At this point, if you're not searching for more matches you can cut the query short and just have true. However, if you're looking for more (all) matches, prolog backtracks and tries to evaluate the rule again, searching for more matches.

However, since your rule is only matching "likes banana and likes mango" and we already matched likes(1,banana), when prolog backtracks and tries evaluating likes(1,banana) again, since we already matched it before, this time there is not another fact (in other words, 1 cannot "like" banana more than once, unless that has been defined) to match. So that's where the false comes from.

In your prolog interpreter you may be able to trace the execution of your program by typing trace. then running your query. My trace is given below:

| ?- 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}
| ?-

One last thing to note: If, instead of pressing ; at the true ? prompt, had I pressed <ENTER>, the script would have finished with only the true.

I'm glad you asked this question 'cause it allowed me a tiny refresher on prolog, which I really like but haven't used in a long time.



来源:https://stackoverflow.com/questions/5013323/understanding-rules-false-as-answer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!