Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!utgpu!water!watnot!watmath!clyde!rutgers!husc6!seismo!mcvax!unido!ecrcvax!micha From: micha@ecrcvax.UUCP Newsgroups: comp.lang.prolog Subject: Re: Control Structures Message-ID: <276@ecrcvax.UUCP> Date: Mon, 6-Apr-87 12:53:21 EST Article-I.D.: ecrcvax.276 Posted: Mon Apr 6 12:53:21 1987 Date-Received: Sat, 11-Apr-87 03:20:55 EST References: Reply-To: mcvax!unido!ecrcvax!micha (Micha Meier) Organization: ECRC, D-8000 Muenchen 81, W. Germany Lines: 65 From the efficiency point of view, a solution with nonstandard cuts (see Lee's note) is the best one, I even think that it is not too complicated to include the soft cut into WAM, if one has the source of the system (this is however rarely the case). When it is too expensive to repeat the execution, the only remaining possibilities are assert or record or a special cut (I guess that the strings proposed by Jan Chomicki are slightly less efficient than assert). The second predicate is more general than the first one: for the xor/2 predicate it is enough to get rid of one choice point, for the other it is necessary to erase several successive choice points which are not at the stack top. (Btw, this is yet another reason to split the environment and choice point stack, it is then easier and the space can be better reclaimed.) There was a concept of remote cuts which allows to mark a place and then to cut all choices up to this point; this, however works only when thay are at the stack top. So the most efficient thing here would be a generalized structure which marks the beginning and the end of an area and then performs the cut, the default for the end being the stack top. With this one the two problems could be rewritten as xor(A, B) :- cutstart(label), xor1(A, B). xor1(A, _) :- cutend(label), call(A), cut(label). xor1(_, B) :- call(B). P :- cutstart(label), A, cutend(label), B, cut(label), C, D. Note that the xor/2 does not seem to be very straightforward, however the auxiliary procedure does not slow it down. This primitive is really powerful, all the cut types can be defined using it (although some of them not quite easy): usual cut: p(X) :- ..., !, ... p(X) :- cutstart(label), p'(X). p'(X) :- ..., cut(label), ... soft cut: p(X) :- ..., softcut, ... p(X) :- cutstart(label), p'(X). p'(X) :- cutend(label), ..., cut(label), ... Keith Hughes' snips: p(X) :- ..., [! A, B, C !], ... p(X) :- ..., cutstart(label), A, B, C, cut(label), ... remote cut: p(X) :- ..., mark(label), ... q(Y) :- ..., cut(label), ... p(X) :- ..., cutstart(label), ... q(Y) :- ..., cut(label), ... The exact semantics, mainly concerning backtracking and label management would have to be polished as well as the syntax. The question is now, is it useful/necessary/sound to include such a primitive into Prolog? It does not seem to be more nonlogical than the usual cut and as we have seen, there really are cases where it would be useful (Francois-Michel, I'm sorry that this is of no use for you now). --Micha