A simpler solution is to parse the input file (defining the EDCG) twice. In the first pass, collect and save the clauses that define accumulators, etc. In the second pass, actually load and expand the file using the data collected in the first pass. The expansion rules need, of course, to be modified to access the collected data. This way there would be zero interference with tools such as the graphical tracer. As a proof of concept, I defined:
:- object(edcg_collect,
implements(expanding)).
:- public([
pred_info/3, acc_info/7, acc_info/5, pass_info/2, pass_info/1
]).
:- dynamic([
pred_info/3, acc_info/7, acc_info/5, pass_info/2, pass_info/1
]).
cleanup :-
retractall(pred_info(_,_,_)),
retractall(acc_info(_,_,_,_,_,_,_)),
retractall(acc_info(_,_,_,_,_)),
retractall(pass_info(_,_)),
retractall(pass_info(_)).
term_expansion(begin_of_file, _) :-
cleanup,
fail.
term_expansion(pred_info(A,B,C), _) :-
assertz(pred_info(A,B,C)),
fail.
term_expansion(acc_info(A,B,C,D,E,F,G), _) :-
assertz(acc_info(A,B,C,D,E,F,G)),
fail.
term_expansion(acc_info(A,B,C,D,E), _) :-
assertz(acc_info(A,B,C,D,E)),
fail.
term_expansion(pass_info(A,B), _) :-
assertz(pass_info(A,B)),
fail.
term_expansion(pass_info(A), _) :-
assertz(pass_info(A)),
fail.
:- end_object.
And then modified the edcg
parsing code to do:
pred_info(A,B,C) :-
edcg_collect::pred_info(A,B,C).
acc_info(A,B,C,D,E,F,G) :-
edcg_collect::acc_info(A,B,C,D,E,F,G).
acc_info(A,B,C,D,E) :-
edcg_collect::acc_info(A,B,C,D,E).
pass_info(A,B) :-
edcg_collect::pass_info(A,B).
pass_info(A) :-
edcg_collect::pass_info(A).
cleanup :- true.
Parsing twice is then done using:
?- {edcg_collect, edcg(loader)}.
...
% (0 warnings)
true.
?- logtalk_compile('~/Desktop/pl.pl', [hook(edcg_collect)]).
% [ /Users/pmoura/Desktop/pl.pl compiled ]
% (0 warnings)
true.
?- logtalk_load('~/Desktop/pl.pl', [hook(edcg)]).
% [ /Users/pmoura/Desktop/pl.pl loaded ]
% (0 warnings)
true.
?- len([a,b,a], Len).
Len = 3.
As the logtalk_compile/2
predicate compiles to disk, the pl.pl
file is only loaded into memory once. It should be possible to adapt this solution to your case. Note that this is in essence similar to what Jan suggested when he wrote " Another dirty trick I use in the XSB emulation is to expand begin_of_file
to pre-read the entire file and collect all its declarations.".