2

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.

false
  • 10,264
  • 13
  • 101
  • 209
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
  • So, um… what is the question? – Daniel Lyons Apr 15 '14 at 03:40
  • 1
    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 :- ` 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 Apr 15 '14 at 03:45
  • @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 Apr 15 '14 at 03:47

1 Answers1

2

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.

CapelliC
  • 59,646
  • 5
  • 47
  • 90
  • Exception handling is a very nice solution to this problem. What is the expected overhead that comes with this solution in (swi-)Prolog? – Willem Van Onsem Apr 15 '14 at 06:11
  • I think it's lightweight... I've seen it used to clean-up constrained variables store, for instance... – CapelliC Apr 15 '14 at 06:11
  • 2
    The common name is *ancestor cut*. Don't know where SWI go that odd terminology from. In any case, it is definitely better to go with catch/throw. – false Apr 15 '14 at 08:06
  • @false: I initially posted exactly that, but after looking at doc page, I changed it... – CapelliC Apr 15 '14 at 08:42