Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Knowing when to use cut in prolog

I've took a course in which I learned some prolog. I couldn't figure out how / when to use cuts. Even though I get the general idea of cuts, I can't seem to use them properly. Can anyone explain it briefly or give a good tutorial (that's not learnprolognow.org) on "cuts" that they can recommend?

like image 559
matanc1 Avatar asked Jan 26 '13 20:01

matanc1


People also ask

Why cut is used in Prolog?

The cut, in Prolog, is a goal, written as !, which always succeeds, but cannot be backtracked. Cuts can be used to prevent unwanted backtracking, which could add unwanted solutions and/or space/time overhead to a query. The cut should be used sparingly.

What is the use of cut and fail in Prolog?

If we want to restrict backtracking we can control which sub-goals can be redone using the cut !. We use it as a predicate within the body of clause. It succeeds when called, but fails the parent goal (the goal that matched the head of the clause containing the cut) when an attempt is made to redo it on backtracking.

What is red cut and green cut in Prolog?

Green cuts prune only computational paths that do not lead to new solutions. Cuts that are not green are red." A red cut prunes away solutions that might otherwise be there. Your example acts as a red cut. If you do a Google search on "Prolog red green cut" you'll see similar definitions.

What is fail predicate in Prolog?

As a first step, let's introduce another built-in predicate: fail/0 . As its name suggests, fail/0 is a special symbol that will immediately fail when Prolog encounters it as a goal. That may not sound too useful, but remember: when Prolog fails, it tries to backtrack .


Video Answer


1 Answers

TL;DR: Don't.

The cut prunes Prolog's search tree. That is, given a pure Prolog program without cut and the same program with cuts the only difference is that the program with cuts might spend less time in fruitless branches, and thus is more efficient ; might have fewer answers ; it might also terminate whereas the original program doesn't.

Sounds pretty harmless ... or even useful, doesn't it? Well, most of the time things are more complex.

Red cuts

Cuts are often used in a way such that the program without cuts has no sensible meaning at all. Such cuts are called red cuts. In the better cases it is used to implement a crude form of non-monotonic negation. And in some other cases it is half negation, half some procedural meaning that is very difficult to understand. Not only for the reader of the program but also for its writer. In fact, often such uses unintentionally lack steadfastness. In any case: these cuts are not placed into an existing program. They are meant to be in that program right from the beginning.

For the more structured uses of such red cuts, better use once/1, (\+)/1, or (;)/2 – if-then-else like ( If -> Then ; Else ) instead. Even better, try to guard such constructs against unintended uses by issuing instantiation_errors. Or use iwhen/2 which produces instantiation errors or when/2 (offered in SWI, YAP, SICStus) which delays goals.

Green cuts

Cuts that remove useless choicepoints (and also redundant answers) are called green cuts. But beware: You cannot place them into your program simply pressing ! and some #00ff00. Most of the time you need a clean read-only guard to ensure that there is no way this cut turns #ff0000. There is also a simple way to remove some leftover choicepoints safely: call_semidet/1. Here are some related cases:

  • What's the SLD tree for this query?

  • Prolog append with cut operator

  • What are the optimal green cuts for successor arithmetics sum?

  • Implementing "last" in Prolog

Cut is not commit

Finally, let me point out that cut is not a commit-operator. It sometimes acts a bit like it, but would need lots of restrictions to be one. A commit-operator cannot be (ab)used to implement (\+)/1. A commit requires that each clause is tried independently of each other. Each clause thus needs a full guard ; it cannot rely on being tried only after some other clauses have been tried first. Also, a commit would have to occur in each clause of a predicate. The cut can occur anywhere.

like image 158
false Avatar answered Sep 21 '22 11:09

false