Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unexpected scope of cut in a If-Then construct #2739

Open
hurufu opened this issue Jan 1, 2025 · 11 comments
Open

Unexpected scope of cut in a If-Then construct #2739

hurufu opened this issue Jan 1, 2025 · 11 comments

Comments

@hurufu
Copy link
Contributor

hurufu commented Jan 1, 2025

Given the following test file:

t :- a, (! -> true).

a.
a.

This query seems to cut too many choice points:

?- t.
   true.

I've expected it to succeed 2 times, but it succeeds only once.

On the other hand the query that must be equivalent behaves as expected:

?- a, (! -> true).
   true
;  true.
@hurufu hurufu changed the title Unexpected scope of cut in a _If-Then_ construct Unexpected scope of cut in a If-Then construct Jan 1, 2025
@flexoron
Copy link

flexoron commented Jan 1, 2025

Does it make sense to have a 'cut' in this position at all?

Because:
with
t(X) :- a, (true -> X).
?- t(!).
true
; true.
?-
but with
t(X) :- a, (true -> !).
?- t(!).
true.
?-

Or
?- X=!, a, (true->X). % or X=!, a, X.
X = !
; X = !.
?- X=!, a, (true->!).
X = !.
?-

What I mean is this:
t(X) :- a, (X -> true).
?- t(!).
true
; true.

@haijinSk
Copy link

haijinSk commented Jan 1, 2025

From my perspective, reporting things like this is not much about the practical-coding sense, but about how can we be sure, that this problem is not a sign of some other problem with more practical consequences.

@flexoron
Copy link

flexoron commented Jan 1, 2025

@haijinSk Can you give us an example where 'if !' is false?

@haijinSk
Copy link

haijinSk commented Jan 1, 2025

@flexoron, I apologize if my tone here sounds offensive. I appreciate and admire your work in this project, and work of others as well.

I don't know how a Prolog system should work in cases like this, I can only give examples of other Prolog systems, where the cut/! inside "If-then" in this position will not "preven[t] alternative solutions to calls before the cut being considered" (Lee Naish), as it prevents in the example and as it normally does/prevents (I have the Naish's words from the normal case), when the cut is not inside the "If-then-else" in this position.

@hurufu
Copy link
Contributor Author

hurufu commented Jan 1, 2025

By definition a -> b should behave as once(a), b, which clearly shows, that all side-effects of ! must be contained withing once/1 predicate. I reported this issue, because I stumbled upon it during my work, and wanted to be extra pedantic.

@flexoron Regarding your question it might happen in more nefarious test cases like this one:

?- !, false -> write(a); write(b).

What do you expect this query to produce?

@triska
Copy link
Contributor

triska commented Jan 1, 2025

some other problem with more practical consequences

That, and also: Even if such code may currently occur rarely in practical examples, it may very well arise frequently by automated code generation, program transformations etc., so it is also important to correct in its own right.

@hurufu
Copy link
Contributor Author

hurufu commented Jan 1, 2025

On the other hand I don't care on the spread of cut side-effects in this particular case, but at least it should be consistent as I've shown in first post.

@flexoron
Copy link

flexoron commented Jan 1, 2025

@hurufu Depends on the associativity and precedence of operators.

Are these a mandatory standard(the operator definitions)?

?- write_canonical((!,false -> write(a); write(b))). % I would not write a query like so
;(->(','(!,false),write(a)),write(b))   true.

?- write_canonical((!,(false -> (write(a); write(b))))).
','(!,->(false,;(write(a),write(b))))   true.

@haijinSk
Copy link

haijinSk commented Jan 1, 2025

One more word... Even if Scryer were the only Prolog system in the world, I think, it can be seen as a plain erroneous behavior, because of the logical inconsistency: one behavior if the (! -> true) is in a rule and a different behavior if as a top-level query. And in that context, I see it as a possible sign of some possible inconsistency on some other "place" in the system.

@flexoron
Copy link

flexoron commented Jan 1, 2025

Recommendation:

?- [user]. t(X) :- a, ( X=! -> !; X). a. a. end_of_file.
?- t(!).
   true.
?- t(true).
   true
;  true.
?- t(false).
   false.
?- 

@flexoron
Copy link

flexoron commented Jan 1, 2025

@hurufu What do you expect here?

?- [user]. t :- (a(1) -> a(2)). a(X):-write(X). a(X):-write(X). end_of_file.

Ahh, sorry. You answered above already. see: once/1 :-)

And thanks for pointing at this: (you're right).

?- ','(!,false).
   false.
?- ','(true,false).
   false.
?- ;(','(true,false),;(true,true)).
   true
;  true.
?- ;(','(!,false),;(true,true)).
   false.
?-

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants