Reputation: 1396
I'm running my first few programs in Prolog and have hit a snag in the kind of experiment I'm trying to run. Initially I was doing it on a mini-map of a few US states but I simplified it to an alphabet:
adj(a,b).
adj(b,a).
adj(b,c).
adj(c,b).
adj(c,d).
na(X, Z) :- \+adj(X, Z).
When I query for na(a, What). I don't get any responses (just a no) but if I individually check na(a,d) it, of course, naturally returns yes.
What's the explanation behind why this would happen? I've been able to get other queries to work in different programs so I'm wondering what key information I'm missing. Thanks!
Upvotes: 3
Views: 225
Reputation: 40768
Think of (\+)/1 not as logical negation, but as "not provable". \+ na(a, What)
succeeds if and only if na(a, What)
is not provable. Since na(a, What)
yields at least one solution and is thus provable, its negation (in this sense) fails. (\+)/1 is thus logically incomplete: It fails in this case although, as you observed, there are ground values that would make it succeed. However, (\+/1) works like you expect from logical negation if its argument is ground. You can therefore solve it for example with
na(X, Y) :- country(X), country(Y), \+ adj(X, Y).
where country/1 yields ground instances of countries. Another way to solve it is to explicitly enumerate countries that are not adjacent, which is possible since the domain is finite. An advantage of this approach is that your queries are then monotonic: Adding new facts will never make a query that previously succeeded fail (this does not hold when using (\+)/1 as above). This is a nice property for declarative debugging.
Upvotes: 6