Understanding the rules - false as an answer

I am new to Prolog, and I just wondered why this rule gives me a false result after one true one.

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

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

 ?- test. true; false. 

I want to know the reason for this false.

+4
source share
1 answer

The prologue works by evaluating requests to failure by denying it.

Here you have established two facts:

likes(1, banana). which says: "1 loves a banana"

likes(1, mango). , which says: "1 loves mangoes"

Then you set up a rule that basically evaluates to:

left_hand_side :- right_hand_side. left_hand_side if right_hand_side

Evaluating the rule as a query tries to match the facts and returns true if possible, and false if it cannot match. It is important to note that, if indicated, the prolog will continue to be consistent with the facts, as long as the rules are evaluated to true .

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

If test run as a request, the prolog first tries likes(1,banana) , which is a previously established fact and is true. Then he switches to likes(1,mango) , which, again, is a fact and is true. Then Prolog completed the rule and printed true .

At this point, if you are not looking for more matches, you can shorten the short query and just have true. However, if you are looking for more (all) matches, the prolog backtracks and try to evaluate the rule again, look for more matches.

However, since your rule only matches โ€œloves a banana and loves mangoโ€, and we already match likes(1,banana) when the prolog returns and tries to evaluate likes(1,banana) again, since we already matched it earlier, this one since there is no other fact (in other words, 1 cannot โ€œloveโ€ a banana more than once, unless it has been determined) to match. So where does the false come from.

In your prolog interpreter, you can track the execution of your program by entering trace. , then running the 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 final note: if instead of clicking ; at the true ? prompt true ? if I pressed <ENTER> , the script would only complete true .

I am glad that you asked this question because it allowed me to update the prologue a little, which I really like, but have not used for a long time.

+7
source

Source: https://habr.com/ru/post/1339947/


All Articles