Path: utzoo!utgpu!water!watmath!clyde!att!osu-cis!tut.cis.ohio-state.edu!mailrus!cornell!uw-beaver!teknowledge-vaxc!sri-unix!quintus!ok From: ok@quintus.uucp (Richard A. O'Keefe) Newsgroups: comp.lang.prolog Subject: Re: !/metacall/metainterpreter Message-ID: <396@quintus.UUCP> Date: 14 Sep 88 00:24:18 GMT References: <1435@kulcs.kulcs.uucp> Sender: news@quintus.UUCP Reply-To: ok@quintus.UUCP (Richard A. O'Keefe) Organization: Quintus Computer Systems, Inc. Lines: 64 In article <1435@kulcs.kulcs.uucp> bimbart@kulcs.UUCP (Bart Demoen) writes: >This is a reply to article <358@quintus.UUCP> (R. O'Keefe) >whose author does not understand why the mentioned metainterpreter does not >work for programs containing metacall if ! does cut outside the scope of call/1; >so, I will show it: This is an unwarranted inference about what I do and do not understand. The thing I didn't understand was >>Demoen's message<<. Bear in mind that *NONE* of the interpreters described in my tutorial is supposed to be able to handle call/1, and only one of them is supposed to be able to handle cuts. >first of all, the metainterpreter does not handle builtinpredicates, so >one has to add a rule like: > prove(Goal) :- > builtin(Goal), > !, > call(Goal). People who have read the tutorial in question or who have followed the discussion in this newsgroup will recall that the interpreters I described (a) aren't *supposed* to handle arbitrary built-in predicates, but (b) can handle any *specific* built-in predicate by building it into the rule/3 table. For example, rule(write(X), B, B) :- write(X). rule(nl, B, B) :- nl. In particular, since the Horn-clause languages I presented interpreters for do not use the same representation as Prolog, it simply would not make SENSE for them to call Prolog's call/1. It does make sense for them to call prove/1, which can be done by adding the clause rule(prove(X), B, B) :- prove(X). or even rule(prove(X), [X|B], B). >Suppose there are two definitions of rule/4: > rule(a(X),[],0,[call(X)]) . > rule(a(X),[],0,[write('not cut away')]) . >and execute the query > ?- prove(a(!)) . >The result is the same as for the program > a(X) :- call(X) . > a(X) :- write('not cut away') . > and query ?- a(!) . >only if !/0 does NOT cut outside call/1 And that is exactly the way that call/1 works in DEC-10 Prolog and C Prolog and ALS Prolog and others. I'm afraid that I didn't feel any obligation in my tutorial to explain how to do everything in every possible dialect of Prolog. I didn't even feel obliged to say how to do everything in VM/PROLOG or micro-PROLOG. The mnemonic, by the way, is that cuts can cut through built in control structures made of punctuation marks (',', ';', '|', '->', '(' ')', '{' '}', even '\+') but not through ones made of letters (call, setof, bagof, findall, once, forall, ...). It is possible to break *any* program by making it do things the author deliberately chose not to make it do and then assuming that the primitives the new code uses don't work properly. Big deal.