Article View: comp.lang.prolog
Article #3599re:meta-circular-meta-interpreters (long)
From: Thom Fruehwirth
Date: Mon, 22 Aug 1988 17:50
Date: Mon, 22 Aug 1988 17:50
124 lines
4486 bytes
4486 bytes
Some time ago <ok@quintus> wrote on Meta-circular interpreters:
>I have finally seen the "vanilla interpreter" one time too many:
> prove(true).
> prove((A,B)) :-
> prove(A),
> prove(B).
> prove(H) :-
> clause(H, B),
> prove(B).
>
>It is time somebody told the truth about this:
>(1) it is DISGUSTING
>(2) in DEC-10 Prolog, it worked (well, sort of) only by accident
>(3) it doesn't work in Quintus Prolog
>(4) it is intrinsically inefficient.
>
>Why is it disgusting? Because the third clause claims to be
>applicable in ALL cases (it imposes no restrictions whatsoever
>on H), but that isn't really so.
>.....
>It is possible to correct the program as it stands by adding a cut to
>each of the first two clauses, or by adding an explicit test...
>The first alternative is ugly, and the second is inefficient.
>
>A general rule for "defaulty" representations (such as here, where a
>user goal is identified as such only by not being recognised as
>anything else) is to translate them to a clean representation and
>work on the clean version. In this case, a good representation for
> H :- B1, ..., Bn.
>is
> rule(H, [B1,...,Bn|C], C).
I appreciate O'Keefes very sophisticated solution utilizing difference
lists. But one should not compare it directly with the vanilla meta-
interpreter. The latter is more towards a specification while the
former is more towards an implementation. The handling of built-in
predicates emphasizes this:
>You can hook built-in predicates into this representation thus:
> rule(p(X,..,Z), C, C) :- p(X,...,Z).
>e.g.
> rule(rule(H,B0,B), C, C) :-
> rule(H, B0, B).
(Somebody might have the idea to add a rule for the conjunction ','/2,
as
it is also a built-in).
In fact, I will show that O'Keefes suggestion is a implementation
version derivable form a specification based on the vanilla meta-
interpreter.
>If you want to experiment with this, here is the definition of rule/3
>for naive reverse and a meta-circular version of prove_goal/1...
I did experiments in AAIS-Prolog on the Mac and - surprise!,surprise! -
both the vanilla (as defined just below) and meta-circular version
have about the same speed and adding cuts to either of them does not
increase speed significantly !
For the specification of the meta-interpeter I will use user defined
rule/2 instead of the built-in clause/2:
prove(true).
prove((H,Hs)) :-
prove(H),
prove(Hs).
prove(H) :-
rule(H, B),
prove(B).
Now we derive the implementation. As it is the case with O'Keefes
meta circular-meta-interpreter we do not handle left-paranthesized
subgoals (e.g. ((a,b),c) ). Therefore the first subgoal in a conjunction
can directly call rule/2:
prove(true).
prove((H,Hs)) :-
rule(H,B),
prove(B),
prove(Hs).
prove(H) :-
rule(H, B),
prove(B).
Next we change the representation of the rules from
rule(A,(B1,B2..,Bn)) into rule(A,[B1,B2..,Bn])
so that every clause-body ends in the empty list '[]'. Therefore the
third clause of prove/2 can be removed:
prove([]).
prove([H|Hs]) :-
rule(H,B),
prove(B),
prove(Hs).
Now we fold the two recursive subgoals into one with help of append/3:
prove([]).
prove([H|Hs]) :-
rule(H,B),
append(B,Hs,H1),
prove(H1).
Then we use difference lists in rule/2 to get rid of append again by
transforming
rule(A,[B1,B2..,Bn]) into rule(A,[B1,B2..,Bn|Gs],Gs)
and result in O'Keefes meta-circular-meta-interpreter:
prove([]).
prove([H|Hs]) :-
rule(H,Hs1,Hs),
prove(Hs1).
We could have also choosen the transformation
rule(A,[B1,B2..,Bn]) into rule([A|Gs],[B1,B2..,Bn|Gs])
which gives in a strinkingly simple looking but less efficient version:
prove([]).
prove(Gs) :-
rule(Gs, Gs1),
prove(Gs1).
Concluding, O'Keefes meta-circular-meta-interpreter is a
master-piece resulting from year-long experience. Although there may
be applications where the vanilla version is more efficient.
Technical Details
Message-ID:
<1170@tuhold>Path:
arc1-ca.pugleaf.net!utzoo!attcan!uunet!mcvax!tuvie!tuhold!thomShow Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!attcan!uunet!mcvax!tuvie!tuhold!thom From: thom@tuhold (Thom Fruehwirth) Newsgroups: comp.lang.prolog Subject: re:meta-circular-meta-interpreters (long) Message-ID: <1170@tuhold> Date: 22 Aug 88 17:50:48 GMT Organization: Institut f. Angewandte Informatik, TU Vienna Lines: 124