1
votes

Say you have a program:

a(X) :- b(X).
a(X) :- c(X).

b(a).
b(b) :- !,fail.
b(c).
c(a).

A query a(X) will return A=a; X=a. I'm looking however for a mechanism where the cut (!) does not only prevent one from further executing predicates in the same node of the execution tree, but will simply backtrack to a certain level.


Virtual cut (?)

For instance if that operator would be ?,

the program:

a(X) :- ?,b(X).
a(X) :- c(X).

b(a).
b(b) :- !,fail.
b(c).
c(a).

Would result in X=a, because it first binds with b(a) (this X=a), next attempts to bind with b(b) and fails, and since ? was placed on the level of a(X), this "virtual cut" is activated as well preventing a(X) from taking the next branch.

In case of the following program however:

a(X) :- ?,b(X).
a(X) :- c(X).

b(a).
b(b).
b(c).
c(a).

The result should be X=a; X=b; X=c; X=a. since the cut is never activated underneath the a(X) SLD-tree.

The question is wether such virtual cut exists.

1
So, um… what is the question? - Daniel Lyons
By the way, in your first example with ?, an X=b binding is never forged because b(b) always fails. Thinking of predicate definition as goal :- <steps-to-prove-goal> it's hard for me to see your semantics. I bet you could implement it with a meta-interpreter (apologies to Richard O'Keefe) but I think you'll find it difficult to achieve coherent semantics if you create bindings upon failure sometimes. - Daniel Lyons
@DanielLyons: The question is whether such virtual cut exists. And indeed X=b never bind. "attempts to bind" is probably a better expression. - Willem Van Onsem

1 Answers

1
votes

This feature is called 'ancestral cut', see the documentation page. Searching for it yields a fair amount of answers.

In summary, I think exception handling (see throw/1, ISO standardized) it's the true alternative to this older tool.