Reputation: 1929
I'm trying to learn some prolog using the gprolog tool. I'm trying to see if lists sum up to the same value. I'm trying to understand why this expression is false.
{trace,1}
| ?- (2+1) is (1+2).
2 2 Call: 2+1 is 1+2 ?
2 2 Fail: 2+1 is 1+2 ?
no
Shouldn't 1+2 and 2+1 be equivalent because addition is associative?
Upvotes: 1
Views: 469
Reputation: 2436
The two terms 1+2
and 2+1
are not equivalent. If you evaluate them as arithmetic expression, they have equal numeric values:
?- 1+2 =:= 2+1. % arithmetic equality
Alternatively, you could evaluate explicitly both sides and then compare:
?- X is 1 + 2, Y is 2 + 1, X == Y.
But this has its own different semantics. For example:
?- X is sin(pi/2), X == 1. % no!
?- X is sin(pi/2), X =:= 1. % yes
Unification with =
and equivalence with ==
are two different things. This is what unification can do:
?- X + 2 = 1 + Y.
Equivalence checks if the two terms are equivalent. +(1, 2)
and +(2, 1)
are not equivalent; the functor is the same but the two arguments are swapped.
Upvotes: 0
Reputation: 15338
It's simple because is
evaluates the right-hand side and tries to unify it with the left-hand side.
Thus you get:
(2+1) = 3.
These two don't look the same (in fact, the "term" on the left-hand side is the prettyprinted structure +(2,1)
as you can check by calling write_canonical(2+1).
) and =
(which is "unification", not comparison or assignment) fails.
What you want in his case is
?- 2+1 =:= 2+1.
true.
which performs numeric evaluation on both left-hand and right-hand sides, and then numerically compares the results.
Which is why this fails:
?- X =:= 2+1.
ERROR: Arguments are not sufficiently instantiated
but this succeeds:
?- X = 3, X =:= 2+1.
X = 3.
Upvotes: 2