scryer-prolog icon indicating copy to clipboard operation
scryer-prolog copied to clipboard

Defined predicates sometimes yield unexpected existence errors

Open triska opened this issue 1 year ago • 10 comments

For instance, when defining f/0 as:


f :- false, _ is [_|_].

I get:

$ scryer-prolog 
?- [user].
f :- false, _ is [_|_].

   error(type_error(evaluable,'.'/2),load/1).
?- f.
   error(existence_error(procedure,f/0),f/0), unexpected.
   false. % expected

I found this issue based on a recent question on StackOverflow: https://stackoverflow.com/q/78774323

triska avatar Jul 21 '24 08:07 triska

I apologize, but to be honest, I have a problem to understand the wording "defined" in the title. If there is an error at the end of defining a predicate, then, from my naive perspective, the existence error is expected, because the predicate is not defined (it was not accepted by the Prolog system).

Or, I suspect, I see it from the wrong point of view, perhaps I completely misunderstood this issue.

haijinSk avatar Jul 21 '24 09:07 haijinSk

In the above example, f/0 is user-defined in the terminology of the Prolog standard:

3.195 user-defined procedure: A procedure which is
defined by a sequence of clauses where the head of each
clause has the same predicate indicator, and each clause
is expressed by Prolog text or has been asserted during
execution (see 8.9).

triska avatar Jul 21 '24 09:07 triska

Thank you for the explanation of the term "defined".

I'm an extremely naive user, I simply see: the "defined" predicate is not accepted by the Prolog system in the first place (the system says "type_error", however unexpected here). Therefore I see the "existence_error" as expected. In my perspective, in my "languaging", the unexpected is not accepting the predicate.

haijinSk avatar Jul 21 '24 10:07 haijinSk

Updated comment: This is 100% reproducible error starts somewhere around compile_is function. Will try to investigate further.

hurufu avatar Jul 21 '24 11:07 hurufu

Whole loading of a new terms has a few steps. In one of the first steps it tries to expand whatever is possible to expand, and then it tries to compile. There is a special set of functions for handling arithmetic expressions, mainly there is this code that explicitly produces an error when a list (or string) is found. So I think that changing compiler behavior is a bad idea in such case, so I decided to expand away invalid arithmetic expression to throw(error(not_evaluable)). UPD: It is done a little bit differently now.

I have no idea if this is a good place of doing this, but I think general picture is clear.

P.S. It is possible to learn a bit of Rust in one weekend ;)

hurufu avatar Jul 21 '24 17:07 hurufu

Other arithmetic operations are also affected by this issue. For instance:

f :- false, _ > [_|_].

triska avatar Jul 21 '24 21:07 triska

It's also not limited to [_|_] as the outermost expression. The following also yields an error:

f :- false, _ is 5+[_|_].

triska avatar Jul 21 '24 21:07 triska

Just a general remark. Fixing this issue currently does not make much sense, because the deeper problem behind is the current representation of partial strings. So fixing this will only delay the transition towards a better representation.

UWN avatar Jul 23 '24 19:07 UWN

Thanks, understood, but it also fails for other kinds of invalid arithmetical expressions, is it also expected?

?- [user].
f :- false, _ is foo.

   error(type_error(evaluable,foo/0),load/1).
?- f.
   error(existence_error(procedure,f/0),f/0).

hurufu avatar Jul 23 '24 19:07 hurufu

Just a general remark. Fixing this issue currently does not make much sense, because the deeper problem behind is the current representation of partial strings. So fixing this will only delay the transition towards a better representation.

I think this comment rather applies to #2455 instead of the present issue?

triska avatar Jul 23 '24 21:07 triska