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

Is cut a predicate?

Open notoria opened this issue 4 years ago • 7 comments

The following happens:

?- !.
caught: error(existence_error(procedure,!/0),!/0)
?- 

While:

?- true, !.
   true.
?- !, true.
   true.
?- 

notoria avatar Oct 23 '20 14:10 notoria

No. Rather, "!" is interpreted by the (,)/2 predicate, which is being called in your examples.

mthom avatar Oct 23 '20 17:10 mthom

So some inputs to (',')/2 change the execution of the engine.

But ! also changes the execution of (;)/2:

?- ! ; true.
   true.
?- true ; !.
   true
;  true.
?- 

And:

?- [user].
a :- !.
a :- write(a), nl.

?- a.
   true.
?- 

It's not a predicate, what would it be?

ghost avatar Oct 23 '20 17:10 ghost

It's not a predicate, what would it be?

In the ISO Prolog Core standard, the cut is a control construct, not a (built-in) predicate.

pmoura avatar Oct 23 '20 17:10 pmoura

Thank you, I understand now, it's like true/0, closing.

ghost avatar Oct 23 '20 19:10 ghost

@notoria: Why close this? It is still a problem that there is an existence error. After all, the procedure (see 3.136 in case of doubt) !/0 is defined as static and private. Idem call(!). There is no responsibility of (',')/2 to interpret its arguments. Instead, there is 7.6.2 Converting a term to the body of a clause.

(That is: Of course (',')/2 and other control constructs may take the burden of 7.6.2 by itself. But at least conceptually, there is just one such term-to-body conversion prior to calling such constructs - see e.g. 7.8.3.1 f.)

UWN avatar Oct 24 '20 08:10 UWN

?- call((G_0=!, G_0)).
   G_0 = !.
?- call((G_0=!, call(G_0))).
caught: error(existence_error(procedure,!/0),!/0)        % unexpected
?- call((G_0=!, G_0 ; Snd = true )).
   G_0 = !.                                              % missing alternative Snd = true
?- call((G_0=!, call(G_0) ; Snd = true )).
caught: error(existence_error(procedure,!/0),!/0))       % unexpected

Maybe this better illustrates what is currently happening. Upon call/1, the argument should undergo a term-to-body conversion, effectively replacing (G_0=!, G_0 ; Snd = true ) by (G_0=!, call(G_0) ; Snd = true). But it seems that conversion is never performed (it does not need to be performed some as-if alternate interpretation would be good enough).

UWN avatar Oct 24 '20 16:10 UWN

This is now fixed in rebis-dev.

mthom avatar Mar 06 '22 03:03 mthom