Question

I have these clauses:

a(1).
a(2).
b(a).
c(A,B,C) :- a(A),d(B,C).
c(A,B,C) :- b(A),d(B,C).
d(B,C) :- a(B),!,a(C).
d(B,_) :- b(B).

When I run the query c(X,Y,Z) the answers are:

X = 1, Y = 1, Z = 1 ;
X = 1, Y = 1, Z = 2 ;
X = 2, Y = 1, Z = 1 ;
X = 2, Y = 1, Z = 2 ;
X = a, Y = 1, Z = 1 ;
X = a, Y = 1, Z = 2.

So basically, the cut operator (in here d(B,C) :- a(B),!,a(C).) ignores the most recent choice points, i.e. it does not do a further search for d() and a(). I though that the cut ignores ALL previous choice points and won't do any backtracking.

Can someone explain the exact behavior and why am I wrong?

Was it helpful?

Solution 2

I did some reading and the cut is working as follows:

1. Kills off the parent choice-point
2. Commits to all the choices made going through the rule

Thus :

1. d(B,_) :- b(B). is not explored
2. B in d(B,C) :- a(B),!,a(C). is irrevocably bound to 1.

OTHER TIPS

Because I did not immediately understand your explanation of what the cut is doing, I looked at your code. My reading went roughly as follows:

  • c(A,B,C) is true when:
    • a(A) and d(B,C),
    • or b(A) and d(B,C)
  • d(B,C) is true when a(B), but only for the first a(B) you encounter, and don't look for any other d(B,C) definitions that you might find below this one.

My reading went like this because my interpretation of the cut is: commit to the choices made before encountering the cut within this predicate body, and discard clauses for this predicate below the clause containing the cut.

I hope this is at least remotely helpful.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top