Reputation: 15800
Suppose we have:
g(0,0).
g(0,1).
h(1,2).
f(Z,X):- g(Z,X).
% Match h IFF g does not match
f(Z,X):- \+ g(Z,X), h(Z,X).
So we have a rule, f, that can decide to exclusively take solutions from g, or from h, both never from both:
f(A,B) is true IF:
g(A,B) is true, or
h(A,B) is true and g(A,B) is false).
?- f(0, X).
X=0 ; % solution from g
X=1 . % solution from g
?- f(1, X).
X=2 . % solution from h
Is there are better version of this that:
g
a
second time, which may be expensive of have other unwanted side effects (such as IO).OK... this is not quite XOR, which would be
f(A,B) is true IFF:
g(A,B) is true and h(A,B) is false, or
h(A,B) is true and g(A,B) is false).
... but a similar issue applies: Can we avoid negation. Can we avoid redundant re-proving?
Upvotes: 1
Views: 63
Reputation: 15338
This is wrong:
g(0,0).
g(0,1).
h(1,2).
f(Z,X):- g(Z,X).
f(Z,X):- \+ g(Z,X), h(Z,X).
If Z
and Y
are fresh in the last line, the query is " "Fail if there is any g(_,_)
, otherwise h(Z,X)
".
Observe:
?- f(0,1),f(0,0),f(1,2). % f(1,2) is TRUE
true ;
false.
?- bagof([X,Y],f(X,Y),Bag). % f(1,2) is NOT TRUE
Bag = [[0, 0], [0, 1]].
The program is inconsistent.
On the other hand:
g(0,0).
g(0,1).
h(1,2).
f(Z,X):- g(Z,X).
f(Z,X):- h(Z,X), \+ g(Z,X).
?- f(0,1),f(0,0),f(1,2).
true ;
false.
?- bagof([X,Y],f(X,Y),Bag).
Bag = [[0, 0], [0, 1], [1, 2]].
The universe has been saved from total annihilation!
That being said:
g(Z,X)
(or the negation) at that point if you already knew the truth value of g(Z,X)
at that point of the clause, but you don't. People don't worry about "redundant comparison with the limit" in for loops either.Upvotes: 2
Reputation: 117154
Are you happy using a cut?
g(0,0).
g(0,1).
h(1,2).
f(Z,X):- g(Z,X), !.
% Match h IFF g does not match
f(Z,X):- h(Z,X).
Upvotes: 0