Prev Next Up Home Keys Figs Search New

How To Invent A Meta-interpreter For The Ancestor Cut

Jacek Martinek, Pawel Pietrzak
Email: pawelp@ruby.poz.edu.pl

Appeared in Volume 7/4, November 1994

Keywords: meta-level, cut.

The designing of meta-interpreters for certain extensions of Prolog can be a difficult programming task. We illustrate a method which simplifies this task by applying one extension of Prolog to describe another one. Then partial evaluation is used to obtain the final meta-interpreter written directly in Prolog.

We assume an ancestor cut as a mechanism difficult to define by writing a meta-interpreter. In the first step, we introduce an exception handling mechanism to Prolog, increasing its expressiveness. Then we apply it to define the meta-interpreter for Prolog with the ancestor cut. Finally, using partial evaluation, we eliminate the exception handling extension. In such a way we obtain the desired meta-interpreter for the ancestor cut as a program written directly in ordinary Prolog.

Our exception handling mechanism is similar to the one discussed in [Meie89] and [Demo89]. The meta-interpreter supporting it is shown in the figure 1.

solve_except(true,noball).
solve_except((G,R),B):-
  solve_except(G,B1),
  ( B1 = ball(_),
    B=B1
  ; solve_except(R,B) ).
solve_except(exit_block(B),ball(B)).
solve_except(block(G,C,R),B):-
  copy_term(G,Copy),
  solve_except(Copy,B1),
  ( B1=ball(C),
    !,
    solve_except(R,B)
  ; G=Copy,
    B=B1 ).
solve_except(G,noball):-
  system(G),
  G.
solve_except(G,B):-
  clause(G,C),
  solve_except(C,B).

Fig. 1 The meta-interpreter for exception handling.

We assume that a block is abandoned deterministically if an exception signal arises inside it. Otherwise, the block is interpreted with no restrictions of backtracking. This allows to write the meta-interpreter for the ancestor cut as shown in figure 2.

solve_cut(true). 
solve_cut(!(_)). 
solve_cut(!(A)):-
  exit_block(A). 
solve_cut((G,R)):-
  solve_cut(G),
  solve_cut(R). 
solve_cut(G):-
  block((clause(G,B),solve_cut(B)),
         A,
         goto_ancestor(A,G)).

goto_ancestor(N,_):-
  number(N),
  N > 0,
  N1 is N - 1,
  exit_block(N1). 
goto_ancestor(A,G):-
  A=.._,
  A \= G,
  exit_block(A).

Fig. 2 The meta-interpreter for the ancestor cut written in Prolog with exception handling.

The ancestor cut is defined according to the description in [StSh86]. A result of using such a cut is similar to using the standard cut in the ancestor's clause (pointed by the parameter of the ancestor cut).

To apply the meta-interpreter solve_cut/1 to a goal G, we use the following query:

?-solve_except(solve_cut(G),B).

Now, we perform the specialization of the meta-interpreter solve_except/2 w.r.t. the meta-interpreter solve_cut/1 by partial evaluation. We obtain the procedure shown in the figure 3 as the result. This is the meta-interpreter for the ancestor cut written in ordinary Prolog.

solve_cut(true,noball).
solve_cut(!(_),noball).
solve_cut(!(A),ball(A)).
solve_cut((G,R),B):-
  solve_cut(G,B1),
  ( B1 = ball(_)
    B = B1
  ; solve_cut(R,B) ).
solve_cut(G,B):-
  clause(G,C),
  solve_cut(C,B1),
  ( B1 = ball(A),
    !,
    goto_ancestor(A,G,B)
  ; B = B1 ).

goto_ancestor(N,_,B):-
  number(N),
  N > 0,
  N1 is N - 1,
  B = ball(N1).
goto_ancestor(A,G,B) :-
  A =.._,
  A \= G,
  B = ball(A).

Fig. 3 The meta-interpreter for the ancestor cut compiled to ordinary Prolog.

The applied specialization algorithm uses unfolding and the "pushing down of meta-arguments".

During the partial evaluation, we heuristically eliminated calls to copy_term/2. In the meta-interpreter in figure 2 the exception signal is handled by the procedure goto_ancestor/2. This procedure sends the proper exception signal to one of its parents or causes failure, which makes the variables free in the interpreted goal. So, removing the call of copy_term/2 doesn't affect the procedural equivalence between solve_except/2 and its version specialized w.r.t. solve_cut/1.

The example illustrates how to collapse the meta-interpreter tower by means of partial evaluation. It seems that this method may be applied to other mechanisms. Also, this method is not restricted to Prolog and its extensions.

References

[BeLl90] K.Benkerimi, J.W.Lloyd: A Partial Evaluation Procedure for Logic Programs, in: Logic Programming, Proceedings of the North American Conference, MIT Press, 1990, pp.343-358.

[BuRu89] M.Bugliesi, F.Russo: Partial Evaluation in Prolog: Some Improvements about Cut, in: Logic Programming Proceedings of the North American Conference, MIT Press, 1989, pp.645-660.

[Demo89] B.Demoen: The Implementation of Catch and Throw in WAM: Optimizations and Alternatives, Report CW 99, Department of Computer Science K.U.Leuven, 1989.

[LaSt88] A.Lakhotia, L.Sterling: How to Control Unfolding when Specializing Intepreters, Case Western Reserve University, CES-TR-88-08, 1988.

[LaSt90] A.Lakhotia, L.Sterling: ProMiX: a Prolog Partial Evaluation System, in: L.Sterling (ed.) Th Practice of Prolog, MIT Press, 1990, pp.137-179.

[Meie89] M.Meier: Event Handling in Prolog, in: Logic Programming, Proceedings of the North American Conference, MIT Press, 1989, pp.871-887.

[Owen88] S.Owen: Issues in the Partial Evaluation of Meta-interpreters, in: H.D.Abramson, M.H.Rogers (eds.), Meta-Programming in Logic Programming, MIT Press, 1989, pp. 319-339.

[Sahl90] D.Sahlin: The Mixtus Approach to Automatic Partial Evaluation of Full Prolog, in: Logic Programming Proceedings of the North American Conference, MIT Press, 1990, pp.377-398.

[StSh86] L.Sterling, E.Shapiro: The Art of Prolog, MIT Press, 1986.

[VeDe88] R.Venken, B.Demoen: A Partial Evaluation System for Prolog: some Practical Considerations, in: New Generation Computing , 6, 1988, pp.279-290.

Jacek Martinek, Pawel Pietrzak
Technical University of Poznan
pl.Sklodowskiej-Curie 5
60-965 Poznan, Poland
Email: pawelp@ruby.poz.edu.pl
Prev Next Up Home Keys Figs Search New