Path: utzoo!attcan!uunet!husc6!mailrus!cornell!uw-beaver!teknowledge-vaxc!sri-unix!quintus!ok From: ok@quintus.uucp (Richard A. O'Keefe) Newsgroups: comp.lang.prolog Subject: Re: prolog tutorial seattle Message-ID: <358@quintus.UUCP> Date: 7 Sep 88 06:05:54 GMT References: <1429@kulcs.kulcs.uucp> Sender: news@quintus.UUCP Reply-To: ok@quintus.UUCP (Richard A. O'Keefe) Organization: Quintus Computer Systems, Inc. Lines: 79 In article <1429@kulcs.kulcs.uucp> bimbart@kulcs.UUCP (Bart Demoen) writes: >Tutorial No:8 of LP'88 Seattle (R. O'Keefe) makes 'interesting' reading, but >be careful: some topics depend heavily on the Prolog system at hand; >here is an example: Surely someone has told Demoen by now that calling something "'interesting'" is about 10 times more insulting than calling it "trash"? The *topic* in question doesn't depend on the Prolog system at all, the *code* in one of the *examples* may perhaps fail to work in some systems. >Section 9 p.107 is about meta-interpreters that can handle the ! cut. >The proposal is to represent clauses as > rule(Head,Goals_before_cut,Cut,Goals_after_cut) . >and base the interpreter on this representation. >This only works if the ! inside the metacall (call/1) does not cut outside >the metacall, and that's something implementations do not agree on. I cannot follow this. The interpreter in question does not call the built-in call/1 predicate! Here is the code: prove(Goal) :- rule(Goal, Before, Cut, After), % Cut is 0 or 1 prove_body(Before), ------------> ( Cut =:= 1 -> ! ; true ), prove_body(After). prove_body([]). prove_body([Goal|Goals]) :- prove(Goal), prove_body(Goals). THERE IS NO META-CALL HERE! There _is_ a cut inside an if->then;else, but I went to some trouble about four years ago to explain on the net (a) that cut is supposed to cut through disjunctions, and (b) why that is useful, and (c) how to write a Prolog interpreter using this feature. The ALS Prolog manual says that their debugger is based on that interpreter, so I'm pretty sure ALS Prolog gets cuts in disjunctions right! The code as written would not work in DEC-10 Prolog, because the DEC-10 Prolog compiler did not understand (If->Then;Else) -- though the interpreter did -- but the conditional cut can be written as ( Cut =:= 1, ! ; true ) in DEC-10 Prolog or in any Prolog whose implementors have made a genuine attempt to be "Edinburgh-compatible". (Even C Prolog, which _does_ handle if->then;else with a sort of meta-call, gets this right.) I have not been able to tell from the old VM/Programming in Logic manual that I have access to whether this would work in VM/PROLOG or not, but if not, the variant PROVE(*GOAL) <- LABEL(PROVE_MARKER) & RULE(*GOAL, *BEFORE, *CUT, *AFTER) & PROVE_BODY(*BEFORE) & ( *CUT = 1 & CUT(PROVE_MARKER) | TRUE ) & PROVE_BODY(*AFTER). would do. I cannot tell from the old BIM_Prolog manual I have access to whether BIM_Prolog gets this right or not (since the Edinburgh convention is that (If->Then;Else) is bracketed as ;(->(If,Then);Else) but the BIM convention is ->(If,;(Then,Else)) there is at least one difference) but in the extremely unlikely event that BIM were inadvertently offering a system for sale which had this possible incompatibility the old manual describes two commands which could be used to jury-rig a similar repair: prove(_goal) :- mark(137), % pick a magic integer rule(_goal, _before, _cut, _after), prove_body(_before), (_cut =:= 1 -> (cut(137) ; true)), prove_body(_after). I have not been able to try this, and have based this code on an old version of the manual. No fee, no guarantee!