Newsgroups: comp.lang.prolog
Path: cantaloupe.srv.cs.cmu.edu!das-news2.harvard.edu!news2.near.net!howland.reston.ans.net!gatech!newsxfer.itd.umich.edu!nntp.cs.ubc.ca!unixg.ubc.ca!news.bc.net!newsserver.sfu.ca!fornax!cs.sfu.ca!serge
From: serge@cs.sfu.ca (Serge Le Huitouze)
Subject: Re: Question about "cut"
In-Reply-To: billaud@claudia's message of 13 Jan 1995 13:34:51 GMT
Message-ID: <SERGE.95Jan16113414@maroilles.cs.sfu.ca>
Sender: news@cs.sfu.ca
Organization: School of Computing Science, Simon Fraser University
References: <3f43s6$go0@hustle.rahul.net> <3f5vhr$gmd@serveur.cribx1.u-bordeaux.fr>
Date: 16 Jan 1995 19:34:14 GMT
Lines: 88



   A small example using side effects and backtracking to print answer to a question

	   p(Q) :- solve(Q,A), !- , write('->'), write(A), nl, fail.
	   p(Q) -- write('no solution at all'), nl.


   :   Could this distinction be implemented in a way that would fit in nicely 
   : with however it is that "cut" is normally implemented? 

   I'm afraid not.  I actually implemented an similar operator in a (toy) 
   .... stuff deleted

If you are talking about WAM-based implementation, it might indeed be quite
tricky to implement this easily.
But with other intermediate machines, it can be far easier. For exmaple in
MALI, which is an abstract machine for non-deterministic languages, it is a
child game !
In this abstract machine, you don't manipulate pointers, you use different
kinds of term: lists, tuples, variables, updatable terms (for implementing
constraints) and "levels". A level denotes a certain state of the choice-point
stack (ie. which alternatives are still to be considered upon backtracking).

It is easy to make this low-level "level" (sorry about the confusion) visible
for a Prolog system using MALI. What you have to do is to separate the notion
of a choice-point stack and the notion of modifying cut.
E.g. the symbol "!" becomes a denotation for the current choice-point stack
and the predicate "cut/1" becomes the operation pruning the search-tree.
Syntactic sugar can be provided for "!" appearing in a goal position to be
considered as "cut(!)".
The nice thing is that "levels" are now Prolog terms that can be passed 
in arguments to any predicates.

Some examples to clarify (at least I hope) this notion:

Example 1:
p :- p1(!), p2.
p :- ....

p1(L) :- cond1, cut(L).
p1(_) :- ...

If "cond1" succeeds in "p1/1", the "cut" will suppress all choice-points more
recent than (or as recent as) the choice-point created when invoking "p/0".

Eample 2:
p :- p1(L), cut(L), p2.
p :- ....

p1(!) :- cond1.
p1(_) :- ...

Here, if "cond1" succeeds in "p1/1", the cut in the first clause of "p/0" will
only suppress the choice-points more recent than (or as recent as) the
choice-point created when invoking "p1/1". That means that the choice-point 
on "p/0" will still be considered upon backtracking.

Another easy extension of the use of these levels is possible, and we arrive
to the real concern of this message :-).

Besides the regular "cut/1" operation, MALI also provides a "cut/2" operation
which will delete the choice-points between the two levels given as arguments

The "canonical" example we had was the implementation of PrologII's 
"default/2". The expected behavior of this predicate is like that :
"default(P,Q)" attempts to prove P in all possible ways, and executes Q upon
backtracking only if there were no proofs for P".
As someone pointed out eralier, the only way to achieve this on a WAM-based
implementation was to patch a prolog object to note for the success of P, and
then test this object before possibly executing Q.

With MALI "cut/2", the solution is quite obvious (?) :

default(P,_) :- P, getlevel(L), cut(!,L).
default(_,Q) :- Q.

getlevel(!).

--
--------------------------------------------------
A bird in the bush is better than two in the hand.

Serge Le Huitouze                       School of Computing Science
email: serge@cs.sfu.ca                  Simon Fraser University
tel: (604) 291-5423                     Burnaby, British Columbia
fax: (604) 291-3045                     V5A 1S6 Canada

