1/* Part of LogicMOO Base Logicmoo Debug Tools
    2% ===================================================================
    3% File '$FILENAME.pl'
    4% Purpose: An Implementation in SWI-Prolog of certain debugging tools
    5% Maintainer: Douglas Miles
    6% Contact: $Author: dmiles $@users.sourceforge.net ;
    7% Version: '$FILENAME.pl' 1.0.0
    8% Revision: $Revision: 1.1 $
    9% Revised At:  $Date: 2002/07/11 21:57:28 $
   10% Licience: LGPL
   11% ===================================================================
   12*/
   13
   14:- module(each_call_cleanup,
   15   [
   16      each_call_cleanup/3,             % +Setup, +Goal, +Cleanup
   17      each_call_catcher_cleanup/4      % +Setup, +Goal, +Catcher, +Cleanup
   18    ]).

Each call cleanup

Call Setup Goal Cleanup Each Iteration

See also
- https://groups.google.com/forum/#!searchin/comp.lang.prolog/redo_call_cleanup%7Csort:relevance/comp.lang.prolog/frH_4RzMAHg/2bBub5t6AwAJ

*/

   28:- meta_predicate
   29        each_call_cleanup(0,0,0),
   30        each_call_catcher_cleanup(0,0,?,0),
   31        each_call_cleanup0(*,0,*).   32
   33
   34% Writeq/1s a term the user_error and flushes
   35:- if( \+ current_predicate(dmsg/1)).   36dmsg(M):-format(user_error,'~N % dmsg: ~q.~n',[M]),flush_output(user_error).
   37:- export(dmsg/1).   38:- endif.
 each_call_cleanup(:Setup, :Goal, :Cleanup)
 each_call_catcher_cleanup(:Setup, :Goal, +Catcher, :Cleanup)
Call Setup before Goal like normal but also before each Goal is redone. Also call Cleanup each time Goal is finished
   47each_call_cleanup(Setup,Goal,Cleanup):- 
   48 (ground(Setup);ground(Cleanup)),!,
   49  each_call_cleanup0(Setup,Goal,Cleanup).
   50
   51each_call_cleanup(Setup,Goal,Cleanup):-
   52 setup_call_cleanup(
   53   asserta(('$each_call_cleanup'(Setup):-Cleanup),HND), 
   54   each_call_cleanup0(pt1(HND),Goal,pt2(HND)),
   55   erase(HND)).
   56
   57:- dynamic('$each_call_cleanup'/1).   58:- dynamic('$each_call_undo'/2).   59
   60pt1(HND) :- clause('$each_call_cleanup'(Setup),Cleanup,HND),call(Setup),asserta('$each_call_undo'(HND,Cleanup)).
   61pt2(HND) :- retract('$each_call_undo'(HND,Cleanup))->call(Cleanup);true.
   62
   63each_call_cleanup0(Setup,Goal,Cleanup):-
   64   \+ \+ '$sig_atomic'(Setup), 
   65   catch( 
   66     ((Goal, deterministic(DET)),
   67       '$sig_atomic'(Cleanup),
   68         (DET == true -> !
   69          ; (true;('$sig_atomic'(Setup),fail)))), 
   70      E, 
   71      ('$sig_atomic'(Cleanup),throw(E))). 
   72
   73
   74each_call_catcher_cleanup(Setup, Goal, Catcher, Cleanup):-
   75   setup_call_catcher_cleanup(true, 
   76     each_call_cleanup(Setup, Goal, Cleanup), Catcher, true)