My SWI-Prolog knowledge base contains the following two facts:
f(a,b). f(a,c).
Now if I pose the query
?- f(a,c). true.
But
?- f(a,b). true ; false.
Why is f(a,b) both true and false? This also happens when there are three facts in the KB. If I append f(a,d). to the KB, then f(a,d) is true (only), but f(a,b) and f(a,c) are both true and false. What's going on, and what can I do so that Prolog answers (only) true to these queries?
Prolog queries work by pattern matching. The query pattern is called a goal. If there is a fact that matches the goal, then the query succeeds and the listener responds with 'yes. ' If there is no matching fact, then the query fails and the listener responds with 'no.
The true is a prompt to allow you to find out if this is so - i.e. that the query can be proven in more than one way. Type a semicolon if you want Prolog to go ahead and look for a different proof. Press "return" if you are happy with a single proof.
The concept of logical negation in Prolog is problematical, in the sense that the only method that Prolog can use to tell if a proposition is false is to try to prove it (from the facts and rules that it has been told about), and then if this attempt fails, it concludes that the proposition is false.
You don't "return" a value of false in Prolog. A predicate fails (results in false ) if it cannot succeed with the given arguments. So the absence of a predicate clause that supports the empty list will automatically fail. Just leave parseList([], N) out of your code.
(Note: this answer is somewhat of a guess)
Consider how Prolog determines whether f(a,c)
is true or not. It checks the first rule, f(a,b)
, and doesn't find a match, but the second rule, f(a,c)
matches. Therefore, f(a,c)
is true. Furthermore, since there are no more rules for f
, there is no point in allowing a backtrack to occur -- there are no other possible solutions.
Now consider f(a,b)
. Prolog will check the first rule, and find a match. Therefore, f(a,b)
is true. However, not all rules have been exhausted. Therefore, Prolog will allow the search to continue (if you hit ;
). When you do continue the search and backtrack, it will discover that the remaining rules, specifically f(a,c)
, do not match f(a,b)
. Therefore, the result is false.
Just in addition to Michael Williamson's answer. If you want to tell Prolog to stop looking for answers after the first successful hit, then use the cut (!
):
?- f(a, b), !. true. ?- f(a, c), !. true.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With