Metainterpreter that prints call stack in case of failure.

From: Maurizio Colucci (look_at_in.signature)
Date: 07/01/04


Date: Thu, 01 Jul 2004 12:45:40 GMT

Hello dear gurus, this is for you.

It is no secret that 90% of my predicates are not supposed to fail.

For debugging purposes, I would like to label some predicates with an
attribute "cannot_fail", and write a metainterpreter that, if a predicate
that is labeled "cannot_fail" happens to fail, issues a runtime exception
and prints the call history and the exact line number of the failure in the
source file.

Example:

cannot_fail(redraw_screen/3). % hint for the metainterpreter

redraw_screen(Objects, Mouse, Objects2):-
    apply_gravity(Objects, O2),
    apply_mouse_movements(Mouse, O2, Objects2),
    forall( member(O, Objects2), draw(O)).

apply_gravity([], []).
apply_gravity([O|T], [O2|T2]):-
    apply_gravity_AUX(O, O2),
    apply_gravity(T, T2).

apply_gravity_AUX( O, O2):-
    get_position(O, P),
    get_x(P, PX),
    get_y(P, PY),
    Y2 is PY + 4,
    set_position(O, point(PX, Y2), O2).
    
The trick is that the actual failure is in apply_gravity/2, not in
redraw_screen/3.

The metainterpreter should print something like:

RUN-TIME ERROR: Failure in deterministic predicate redraw_screen/3. Call
stack:

1. redraw_screen(...)
2. apply_gravity(...)
3. apply_gravity_AUX(...)
3. get_position( null , _G123) FAILED at line 1130 of file test.pl

In normal situations, redraw_screen would simply fail and I'd have to locate
the point of failure with trace/0 (I hate it), or by adding writeln/1 in
many clever point in the source. This is unnerving :-). OTOH, with such a
metainterpreter, I would immediately understand the problem: get_position
was passed the atom "null", which is certainly not an object with a
position. This means that the original list "Objects" was ill-formed.

Needless to say, I am completely clueless how to write such a
metainterpreter. Thanks for any help.

PS: Avoiding assert would be nice :-)

PPS: Speed is not important because I would only use such a metainterpreter
during debug.

-- 
Best Regards,
Maurizio Colucci
Please remove the uppercase letters "S,P,A,M":
seSgPuAsMo.forever@tin.it


Relevant Pages

  • Re: Simulating inheritance with a metainterpreter
    ... In prolog I must define all the predicates twice ... > size(box(Siz, _), Siz). ... > and write a metainterpreter that, when it encounters inherits, behaves as ... > the four predicates were defined for abox too. ...
    (comp.lang.prolog)
  • Re: User-question
    ... predicates don't return values like functions/functional ... procedures in other programming language. ... readto "yes" is unsuccessful -> P is matched against fail. ... You could let "askUser" fail if the user answered ...
    (comp.lang.prolog)
  • Re: Metainterpreter that prints call stack in case of failure.
    ... Maurizio Colucci wrote: ... > but the metainterpreter tells me ... How can I specify that = can fail? ...
    (comp.lang.prolog)