SWI-Prolog / issues

Dummy repository for issue tracking
7 stars 3 forks source link

Wrong result from X is -1**2. #123

Closed RECHE23 closed 1 year ago

RECHE23 commented 1 year ago

Hi!

I have noticed that the order of operations is wrong for negation and exponentiation...

X is -1**2. should return X = -1. but it returns X = 1.

I am using SWI-Prolog (threaded, 64 bits, version 9.0.4) on Mac OS.

JanWielemaker commented 1 year ago

?? Y*2 is the same as YY and -1*-1 is 1. What am I missing?

RECHE23 commented 1 year ago

Since we are dealing with a numerical value, -1**2 should equal -(1**2), not (-1)**2.

If we have X is -1, Y is X*X. or X is -1, Y is X**2., the behaviour is correct : it returns Y = 1..

The behaviour of X is 1, Y is -X**2. is also correct: it returns Y = -1..

But, X is -1**2. isn't respecting the operator precedence, for some reason, as it returns X = 1..

EricGT commented 1 year ago

Checked this against Wolfram Alpha

-12 = -1 ([ref](https://www.wolframalpha.com/input?i=-12))

-(12) = -1 [(ref)](https://www.wolframalpha.com/input?i=-%2812%29)

(-1)2 = 1 ([ref](https://www.wolframalpha.com/input?i=%28-1%292))

Is a Negative Number Squared Negative or Positive? (YouTube)

JanWielemaker commented 1 year ago

numerical value, -1**2 should equal -(1**2), not (-1)**2

Well, Prolog syntax works differently . The term is read as **(-1, 2). -1 is read as integer. Even if we would write -(1)**2, operator precedence reads this as **(-(1),2) and we still get 1.

RECHE23 commented 1 year ago

But why would X is -1**2. return X = 1. when Y is 1, X is -Y**2. returns X = -1.?

This is incoherent behaviour and it doesn't respect the standard operator precedence...

EricGT commented 1 year ago

Checked the ISO standard for Prolog. The standard operators are listed in Table 7 - The operator table

To keep the list short will only show the relevent parts

Priority  Specifier   Operator(s)
500       yfx          + - 
400       yfx          * /  //  rem mod
200       xfx          **
200       xfy          ^ 
200       fy           -

Note: ^ is not the exponentiation but the caret operator
The Operator table in the SWI-Prolog documentation (ref)

From 6.3.4

A lower priority means stronger operator binding.

The unary prefix (-) with -1 binds stronger than **.

So as Jan notes Prolog syntax works differently and thus it should be noted about the differences and parenthesis used as needed.

HTH

JanWielemaker commented 1 year ago

Still, because -1 is read as an integer. That is defined such by the standard and all Prolog systems on my machine agree to this. I was not involved when this was decided, but I can think of a good reason. Consider e.g. mynum(-1). as fact and the query ?- X is 2-3, mynum(X). If we would not read -1 as an integer this query would fail. In functional languages this is not a problem because -(1) is always evaluated and thus the same as the negative integer. In Prolog, one is a term and the other an integer and thus they do not compare equal as terms, but only using =:=/2.