3

I'd appreciate it if someone could elaborate on the difference between the is keyword and the = operator in prolog. I saw this discussion in == and =, but it excludes is. The documentation talks about an unclear to me "unbound left operand." Can anyone elaborate?

I have a following example of is:

age(Person,X) :-
birth_year(Person,Y1),
current_year(Y2),
X is Y2-Y1. 

Is the difference assignment vs comparison? Any help is appreciated!

Edit: What is the relationship between == and is? I am not asking the relationship of == and =, unless I have a misunderstanding of the aforementioned relationship.

Community
  • 1
  • 1
jblakeley
  • 816
  • 1
  • 10
  • 20

3 Answers3

5

As usual, a bit of poking around helps:

?- X = 2 + 1. % unify X with 2 + 1
X = 2+1.

?- X = 2 + 1, write_canonical(X). % how does Prolog see X?
+(2,1)
X = 2+1.

?- is(X, +(2,1)). % evaluate the term +(2,1) as an arithmetic expression
                  % and unify X with the result
X = 3.

The point about X being a free variable is that since the result of the arithmetic expression is unified with it, you might get surprises when the terms are not the same even though the arithmetic expression seem as if they should be:

?- 1+2 is 2+1. % Evaluate 2+1 and try to unify with +(1,2)
false.

?- 1 is (1.5*2)-2. % Evaluates to 1.0 (float), unify with 1 (integer)
false.

?- 1+2 =:= 2+1.
true.

?- 1 =:= (1.5*2)-2.
true.

And please keep in mind that both =/2 and is/2 are predicates. They can also be just atoms, so they can also be names of functors. Both happen to be declared as operators. I don't think either should be called a "keyword".

2

'is' is an operator, and so is '='. But they differ in their working. 'is' should be used (or works correctly) only when its RHS can be evaluated, provided all the operads on the RHS of 'is' are instantiated (has a ready value for them).

Eg:

?- X is X+1.

This will give error until X on the RHS of 'is' has a value already assigned to it (has been instantiated).

However, the following will work:

?- X = 3, X is X+1.

Now X becomes 4 here.

'=' on other hand does not cause or any sort of evaluation of its RHS to be assigned to LHS.

?- X = 3 + 1.

This will give '3+1' and not 4. Remember, '=' causes no evaluation at all.

?- X is 3+1.

This will give 4.

However, following works as follows:

?- X = 5, Y = X.

Now, Y will become 5 as there is no evaluation needed.

'=' can also be used for matching:

?- likes(john, X) = likes(Y, burger).
X = burger,
Y = john.

The above will be the result.

So, 'is' should only be used when an evaluation is required and all the operands on its RHS have been instantiated. '=' should be used only when there is no need for evaluation and the purpose is to either assign a value or perform matching.

Hope this helps.

a_r
  • 488
  • 6
  • 12
0

You said "is" should only be used when an evaluation is required. So why does this fail?

L is [a, b, c, d], last(L, E).

and this succeeds?

L = [a, b, c, d], last(L, E).

It seems to me that no evaluation is needed for [a, b, c, d].

Mark Volkmann
  • 909
  • 12
  • 15
  • It seems the answer to my question is that `is` should only be used when the right-hand side is an arithmetic expression. – Mark Volkmann Jul 01 '23 at 14:21