didoudiaz / gprolog

GNU Prolog
Other
106 stars 13 forks source link

Unexpected type error in length/2 #8

Closed UWN closed 2 years ago

UWN commented 3 years ago

This was #95.

| ?- X #>= 0, length(_,X).
uncaught exception: error(type_error(integer,_#2097954(0..268435455)),(#>=)/2)
| ?- length(_,X), X #>= 0, length(_,X). 

X = 0 ? ;

X = 1 ? ;

X = 2 ? ;

X = 3 ? ;

X = 4 ? 

All instances permitted by _#2097954(0..268435455) are valid integers. Therefore, a type error integer does not fit.

didoudiaz commented 3 years ago

An FD variable is not an integer (it is a new type wrt ISO) even if, when solved, it will be bound to an integer. I don't know what to do with length(L, X) where L is a variable and X an FD variable (except treating length/2 as an FD constraint and suspending it until L or X is known, which is really out of the scope here). Silently failing is not much better...

UWN commented 3 years ago

We agree that silent failure would not be a better situation. It is however semantically equivalent to a type error.

| ?- X = 3, X #>= 0, length(_,X), X = 3.

X = 3

yes
| ?-        X #>= 0, length(_,X), X = 3.
uncaught exception: error(type_error(integer,_#2097954(0..268435455)),(#>=)/2)

So in case of silent failure (as it was up to 1.4.5 or so), the second query fails. And the type error just means failure.

How is it possible that by removing an instantiation, a succeeding query fails or produces a type error? Apart from ambiguities like X=1+1,X#=1+1,X=1+1. which we do no have in this example as we have only integers and variables - no expressions.

Also w.r.t ISO FDs are not a type. See 5.5.4.

UWN commented 3 years ago

Or to put it the other way round: How is it possible that in the presence of a type error a further instantiation can remove that type error? That is impossible.

(What you mean by a type is something different than what Prolog with its type systems sees as a type. And since the standard already has three different meanings of type it is no wonder that things are terminologically a bit difficult.)

didoudiaz commented 2 years ago

Last version only checks the type if strict_iso flag if off

UWN commented 2 years ago

What is the latest version?

ulrich@p0:/opt/gupu/gprolog$ git describe
v1.5.0-16-ge6354f6
ulrich@p0:/opt/gupu/gprolog$ ./src/TopComp/gprolog 
GNU Prolog 1.5.1 (64 bits)
Compiled Feb 24 2022, 09:43:50 with gcc -std=gnu99
Copyright (C) 1999-2022 Daniel Diaz

| ?- X #>= 0, length(_,X).
uncaught exception: error(type_error(integer,_#2098210(0..268435455)),(#>=)/2)
| ?- 
UWN commented 2 years ago

UWN_open (This serves to mark that I do not see that closing is justified)

UWN commented 2 years ago

This is not fixed at all:

ulrich@p0:/opt/gupu/gprolog/src$ git describe
v1.5.0-18-g3088434
ulrich@p0:/opt/gupu/gprolog/src$ TopComp/gprolog 
GNU Prolog 1.5.1 (64 bits)
Compiled Feb 24 2022, 09:43:50 with gcc -std=gnu99
Copyright (C) 1999-2022 Daniel Diaz

| ?- X #>= 0, length(_,X).
uncaught exception: error(type_error(integer,_#2098210(0..268435455)),(#>=)/2)
| ?- current_prolog_flag(strict_iso,V).

V = on

yes
| ?- set_prolog_flag(strict_iso, off). 

yes
| ?- X #>= 0, length(_,X).             
uncaught exception: error(type_error(integer,_#2098210(0..268435455)),(#>=)/2)