-2

I'm using swi-prolog version 6.6.6 if that matters.
As far as I can tell they should be equivalent since the only difference is which side of the 'is' everything is on. Why do they give different results?

[trace] 48 ?- mod(3,3) is 0.
false.

[trace] 49 ?- 0 is mod(3,3).
true.

Volker Stolz
  • 7,274
  • 1
  • 32
  • 50
Player 3
  • 1
  • 1
  • 3
    You are looking for `(=:=)/2`. – mat Apr 08 '15 at 16:21
  • 4
    Look up the [description of the `is/2` predicate](http://www.swi-prolog.org/pldoc/man?predicate=is/2). It does not define a "symmetrical" relationship. So what side of the `is` the terms are on makes a big difference. It *evaluates* the expression represented by the 2nd argument, and unifies that result with the term represented by the first argument. It succeeds if it can unify, and fails otherwise. In your second example, clearly `mod(3,3)` *evaluated* (result `0`) unifies with `0`. But in your first example, `0` (evaluates to `0`) does not unify with the unevaluated term `mod(3,3)`. – lurker Apr 08 '15 at 16:21
  • This very behavior is explicitly explained in the official documentation of SWI-Prolog's `is/2`. This is beyond lazy. –  Apr 09 '15 at 13:02
  • @Boris The behavior explicitly explained in [the is/2 docs](http://www.swi-prolog.org/pldoc/man?predicate=is/2) has to do with floats vs integers. While it does say it should typically be used with an unbound left operand it does not address unevaluated expressions like some [other people](http://homepages.inf.ed.ac.uk/pbrna/prologbook/node68.html) do. The best searching the swi docs do to let you know what numbers are, and how they behave, is to tell you how to find out _if_ something is a number. Prolog is weird. Don't be mean. If I knew what to look for I wouldn't have asked here. – Player 3 Apr 09 '15 at 18:09
  • You made me go and read the documentation again. Do it as well, and pay attention to the words _Number_, _Value_, and _Expression_. All you need to know is literally in the first sentence. –  Apr 09 '15 at 19:26
  • @Boris So from "True when Number is the value to which Expr evaluates" I'm supposed to infer with absolute confidence, and little prior experience with prolog, that when it says Number it means an integer/float unless there's a variable to unify in which case it doesn't need to be a number, but that if I leave some valid function call or non int/float/var in there _which would evaluate to a number_ instead of throwing some kind of exception or just evaluating the expression like a normal language it returns false? Even though [traces can make them look the same](http://imgur.com/5Hf7nBd)? – Player 3 Apr 09 '15 at 22:52
  • If you spent more time reading (documentation, tutorials, textbooks, etc) and less time arguing with strangers on the internet, wasting time and bandwitdth, you might have more success in learning new things. –  Apr 10 '15 at 07:08
  • @Boris If you spent less time leaving comments to strangers that just say "You suck" without even being constructive then maybe strangers wouldn't feel the need to defend themselves. I really don't see why you're treating me like this when [other people have asked much more trivial questions](http://stackoverflow.com/questions/1417253/prolog-operator) without people getting mean about it. – Player 3 Apr 10 '15 at 16:03

1 Answers1

0

What every one else said. is/2 evaluates the right-hand side as an arithmetic expression and unifies the result of that evaluation (assuming that it was, in fact, a valid arithmetic expression, with the left hand side. So you can say things like:

  • X is 3+2 * 4 mod 3
  • 0 is 3+2-5

And it's not really intended for arithmetic comparisons. But that would be clear if you had read the documentation for is/2:

-Number is +Expr

True when Number is the value to which Expr evaluates. Typically, is/2 should be used with unbound left operand. If equality is to be tested, =:=/2 should be used. For example:

  • ?- 1 is sin(pi/2). Fails! sin(pi/2) evaluates to the float 1.0, which does not unify with the integer 1.
  • ?- 1 =:= sin(pi/2). Succeeds as expected.

And if you chase down the docs for =:=/2 and its relatives, you discover

  • +Expr1 > +Expr2.
    True if expression Expr1 evaluates to a larger number than Expr2.

  • +Expr1 < +Expr2.
    True if expression Expr1 evaluates to a smaller number than Expr2.

  • +Expr1 =< +Expr2.
    True if expression Expr1 evaluates to a smaller or equal number to Expr2.

  • +Expr1 >= +Expr2.
    True if expression Expr1 evaluates to a larger or equal number to Expr2.

  • +Expr1 =\= +Expr2.
    True if expression Expr1 evaluates to a number non-equal to Expr2.

  • +Expr1 =:= +Expr2.
    True if expression Expr1 evaluates to a number equal to Expr2.

A little curiousity won't hurt you.

Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135