HSchmale
HSchmale

Reputation: 1929

In prolog, why is `(1+2) is (2+1)` false?

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

Answers (2)

TA_intern
TA_intern

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

David Tonhofer
David Tonhofer

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

Related Questions