is/2: constraining the first operand to variables or numbers

Discussion on the revision of the current Core standard

Moderator: Paulo Moura

is/2: constraining the first operand to variables or numbers

Postby Paulo Moura » Fri May 18, 2007 4:18 pm

Hi!

Following some private emails between me and Bart, we would like your feedback on constraining the first operand of the is/2 standard predicate to be either a variable or a number, throwing an exception on all other cases.

In the current core Prolog standard, a goal such as:

?- a is 3.

Simply fails. If you agree that an exception should be generated instead, which exception term do you think should be used? If you prefer the current behavior, can you tell us in what circumstances is it useful?

All the best,

Paulo
Paulo Moura
Logtalk developer
Paulo Moura
Site Admin
 
Posts: 18
Joined: Sun May 13, 2007 11:32 am
Location: Portugal

is/2 exception

Postby mauro » Tue May 22, 2007 12:22 pm

I agree that is/2 should throw an exception on that cases.

I argument my opinion with the following:

?- a is a.
ERROR: is/2: Arithmetic: `a/0' is not a function

So, since is/2 expect a number or a function (whose result is a number) as its second argument, it has to expect a number as a result of the arithmetic unification.
Indeed, a call like "?- a is 3" should simply be a non-sense goal.

On the other hand, consider the following:

?- pi is pi.
No

Perhaps one should want such a goal to succeed.

So, since I cannot find a situation in which silent failure could be useful (as in the last case), and since one cannot speak rigorously of a domain error (see, "pi is pi"), I propose a simple type error.

Cheers,
Last edited by mauro on Wed May 23, 2007 2:56 pm, edited 1 time in total.
Mauro Di Nuzzo

Thou great star! What would be thy happiness if thou hadst not those for whom thou shinest!
mauro
 
Posts: 7
Joined: Tue May 22, 2007 11:55 am
Location: Rome, Italy

Re: is/2 exception

Postby Paulo Moura » Tue May 22, 2007 12:46 pm

mauro wrote:On the other hand, consider the following:

?- pi is pi.
No

Perhaps one should want such a goal to succeed.


No. The right argument is to be interpreted as an arithmetic expression. The left argument should be either a variable or a number (but not an expression). The current standard specifies that the right argument is evaluated and then unified with the left argument. Thus, the atom "pi" have different meanings when using on the left and on the right argument. The consequence be that the above goal should generated an exception.

Paulo

P.S. Adding pi/0 as a built-in function is part of the current core revision proposal.
Paulo Moura
Logtalk developer
Paulo Moura
Site Admin
 
Posts: 18
Joined: Sun May 13, 2007 11:32 am
Location: Portugal

Postby mauro » Wed May 23, 2007 2:44 pm

Yes, indeed. I highlighted the "pi is pi" in respect to the following situation (which has nothing to do with the is/2 standard).

I have the program:

:- arithmetic_function(one).
one(1.0).

Now suppose I want to test arithmetic equality involving "one" and, for example, "sin(pi/2)".
I cannot use =/2 (and similar) because Prolog does atomic (or terms order, or whatever) comparision.
I cannot use is/2 because the standard is/2 predicate raise (well, it will do) an exception.
So, the only way is the following:

?- X is one, Y is sin(pi/2), X = Y.

Often, I created my own "direct" arithmetic test operators which evaluates an expression before the actual comparison.

But it seems logical to me that being incorrect the goal:

?- one is sin(pi/2).

it should be incorrect also the goal:

?- 1.0 is sin(pi/2).

as the latter involve a "direct" (in the meaning above) arithmetic comparision.

So, FINALLY, according to me, is/2 should accept only variables on its left side to be coherent. Otherwise it should (as I would prefer) contemplate all possible cases of instantiation and perform arithmetic evaluation wherever necessary.

It's an opinion.

Cheers,
Last edited by mauro on Wed May 23, 2007 2:56 pm, edited 1 time in total.
Mauro Di Nuzzo

Thou great star! What would be thy happiness if thou hadst not those for whom thou shinest!
mauro
 
Posts: 7
Joined: Tue May 22, 2007 11:55 am
Location: Rome, Italy

Postby mauro » Wed May 23, 2007 2:49 pm

Moreover (reading better your reply :) ):

The current standard specifies that the right argument is evaluated and then unified with the left argument.


If you keep this definition, then is/2 must not raise exception when it fail to unify the result of an arithmetic function (on the right) and, say, an atom (on the left).

So, the goal

?- a is 3.
No

behaves perfectly according to the standard definition.
Mauro Di Nuzzo

Thou great star! What would be thy happiness if thou hadst not those for whom thou shinest!
mauro
 
Posts: 7
Joined: Tue May 22, 2007 11:55 am
Location: Rome, Italy

Re: is/2: constraining the first operand to variables or num

Postby Joachim Schimpf » Thu May 24, 2007 7:17 pm

Paulo Moura wrote:Hi!

Following some private emails between me and Bart, we would like your feedback on constraining the first operand of the is/2 standard predicate to be either a variable or a number, throwing an exception on all other cases.

In the current core Prolog standard, a goal such as:

?- a is 3.

Simply fails. If you agree that an exception should be generated instead, which exception term do you think should be used? If you prefer the current behavior, can you tell us in what circumstances is it useful?

All the best,

Paulo


Could we please not change any of the few things that actually have been standardised, unless there is a really, really good reason to do so? In particular an issue like this which has rather serious implementation consequences? Many compilers presumably exploit the fact that currently
Code: Select all
X is Y+1
is equivalent to
Code: Select all
Tmp is Y+1, X=Tmp
and compile that into two instructions, one for the addition, and a get_value for the unification. Of course it is possible to change that, but if you want systems to conform, then don't make the standard a moving target.

I am aware that the standard has other precedents for the behaviour you are advocating (type checking on output arguments), which means that e.g. get_char(X) is not equivalent to get_char(Tmp), X=Tmp even though this looks like a perfectly logical transformation. I don't find this particularly desirable either.

But if you insist on going for extreme type checking, then you should also catch
Code: Select all
2.0 is 1+1
because failures due to numeric type mismatch are probably even more common than the ones you were targeting. But then again, you can catch them only as long as the unification happens inside the is/2. The joys of a dynamically typed language...
-- Joachim
Joachim Schimpf
 
Posts: 2
Joined: Thu May 24, 2007 4:12 pm

is/2: constraining the first operand to variables or numbers

Postby asvanyi » Mon Jul 23, 2007 1:41 pm

I think, (=:=)/2 serves for arithmetic comparison. Therefore, the first operand of is/2 should be constrained to variables. After all, I have never used is/2 for arithmetic comparison. Could you give me a useful example?

High regards,
Tibor
asvanyi
 
Posts: 1
Joined: Mon Jul 23, 2007 12:42 pm

Re: is/2: constraining the first operand to variables or num

Postby v » Fri Mar 21, 2008 12:04 pm

asvanyi wrote:I think, (=:=)/2 serves for arithmetic comparison. Therefore, the first operand of is/2 should be constrained to variables. After all, I have never used is/2 for arithmetic comparison. Could you give me a useful example?

High regards,
Tibor


is/2 should be implemented like this:
Code: Select all
Place is Expression :- number(Expression), Place = Expression.
Place is Left + Right :- LeftValue is Left, RightValue is Right, '$builtin_plus'(LeftValue, RightValue, Place).
% ...


It's useful to unify the result with Place rather than demand Place be a variable and bind it directly because you can write code like this:
Code: Select all
% Example to generate magic squares
saturn([A,B,C,
        D,E,F,
        G,H,I]) -->
     select(A),
     select(B),
     select(C),
     { S is A + B + C },
     select(D),
     select(G),
     { S is A + D + G },
     select(E),
     { S is C + E + G },
     select(F),
     { S is D + E + F },
     select(H),
     { S is B + E + H },
     select(I),
     { S is G + H + I },
     { S is C + F + I },
     { S is A + E + I }.


The first use of is binds S, and the others fail unless the sum is the same as the number that S equals.

I argue that it doesn't make sense declaratively to require the first argument of is/2 be a variable since it forces you to consider the procedural interpretation of the code. In general there should be no logical difference between variables and values.



It may be worth considering methods to define new number types in Prolog itself?
v
 
Posts: 3
Joined: Fri Mar 21, 2008 11:46 am


Return to Core Revision

Who is online

Users browsing this forum: No registered users and 1 guest

cron