When a term passes through term_expansion/2 trying to debug/understand the term expansion can be challenging at first.
One effective aid in debugging term_expansion/2 is using debug/3 with listing/1.
Here is a very simple module with term_expansion/2 and debug/3.
Note: This is in a file C:/directories/simple_rewrite_example.pl
.
:- module( simple_rewrite, [
op(1200, xfx, '::=')
]).
user:term_expansion((H::=T), (H:-T)) :-
debug(rewrite_topic,'::= rewrite rule applied.',[]).
It simply takes a term written using ::=
and rewrites it with :-
.
And here is a very simple module with a predicate containing ::=
:- module(example_module,
[
a_predicate/0
]).
:- use_module('C:/directories/simple_rewrite_example.pl').
a_predicate ::=
Value = 1,
Value == 2.
Normally when a predicate is listed, e.g.
?- listing(a_predicate).
example_module:a_predicate :-
Value=1,
Value==2.
no debug messages are printed.
If the debug topic is enabled, e.g.
?- debug(rewrite_topic).
Warning: rewrite_topic: no matching debug topic (yet)
true.
and then the same predicate is listed, e.g.
?- listing(a_predicate).
% ::= rewrite rule applied.
example_module:a_predicate :-
Value=1,
Value==2.
the debug message appears.
While this is a very simple example its effectiveness is easily amplified by adding more debug/3 calls.
Also see this related post: Sharing my debugging message discovery
Here is an example of the messages when a single predicate is expanded with the library(edcg) using a custom version of library(edcg) with copious debug/3 calls.
?- debug(edcg).
Warning: edcg: no matching debug topic (yet)
true.
?- listing(called_07).
% Expanding called_07(_312)
% _new_goal - entry - Goal:called_07(_312), GList:[acc_07], GArity:_3362, TGoal:_846
% _new_goal - exit - Goal:called_07(_312), GList:[acc_07], GArity:1
TGoal:called_07(_312,_3460,_3462)
% _create_acc_pass - recursive 1 - entry - A:acc_07, AList:[], Index:1, TGoal:called_07(_312,_3460,_3462), LeftA:_3576, RightA:_3578, Acc:_3570, Pass:_3630
% _create_acc_pass - base 1
% _create_acc_pass - recursive 1 - exit - A:acc_07, AList:[], Index:1, TGoal:called_07(_312,_3460,_3462), LeftA:_3460, RightA:_3462, Acc:[], Pass:[]
% _expand_goal - recursive 1 - entry - (G1,G2) - G1:_328/acc_07, G2:[_380]:acc_07,acc_07/_380,{format(Value: ~w, A: ~w, B: ~w~n,[_312,_328,_380])}, TG1:_3924, TG2:_3926, NaAr:called_07/1, HList:[acc_07], Acc:[acc(acc_07,_3460,_3462)], NewAcc:_3972, Pass:[]
% _expand_goal - base 8 - (X/A) - exit - X:_328, A:acc_07, Acc:[acc(acc_07,_328,_3462)]
% _expand_goal - recursive 1 - entry - (G1,G2) - G1:[_380]:acc_07, G2:acc_07/_380,{format(Value: ~w, A: ~w, B: ~w~n,[_312,_328,_380])}, TG1:_4166, TG2:_4168, NaAr:called_07/1, HList:[acc_07], Acc:[acc(acc_07,_328,_3462)], NewAcc:_3972, Pass:[]
% _expand_goal - base 6 - (L:A) - exit - L:[_380], A:acc_07, Joiner:_328=_380,true, NaAr:called_07/1, Acc:[acc(acc_07,_328,_3462)], NewAcc:[acc(acc_07,_4328,_3462)]
% _expand_goal - recursive 1 - entry - (G1,G2) - G1:acc_07/_380, G2:{format(Value: ~w, A: ~w, B: ~w~n,[_312,_328,_380])}, TG1:_4460, TG2:_4462, NaAr:called_07/1, HList:[acc_07], Acc:[acc(acc_07,_4328,_3462)], NewAcc:_3972, Pass:[]
% _expand_goal - base 10 - (A/X) - exit - A:acc_07, X:_380, Acc:[acc(acc_07,_4328,_380)]
% _expand_goal - base 1 - {G} - exit - G:format(Value: ~w, A: ~w, B: ~w~n,[_312,_328,_380]), Acc:[acc(acc_07,_4328,_380)]
% _expand_goal - recursive 1 - exit - (G1,G2) - G1:acc_07/_380, G2:{format(Value: ~w, A: ~w, B: ~w~n,[_312,_328,_380])}, TG1:true, TG2:format(Value: ~w, A: ~w, B: ~w~n,[_312,_328,_380]), NaAr:called_07/1, HList:[acc_07], Acc:[acc(acc_07,_4328,_380)], NewAcc:[acc(acc_07,_4328,_380)], Pass:[]
% _expand_goal - recursive 1 - exit - (G1,G2) - G1:[_380]:acc_07, G2:acc_07/_380,{format(Value: ~w, A: ~w, B: ~w~n,[_312,_328,_380])}, TG1:_328=_380,true, TG2:true,format(Value: ~w, A: ~w, B: ~w~n,[_312,_328,_380]), NaAr:called_07/1, HList:[acc_07], Acc:[acc(acc_07,_328,_380)], NewAcc:[acc(acc_07,_4328,_380)], Pass:[]
% _expand_goal - recursive 1 - exit - (G1,G2) - G1:_328/acc_07, G2:[_380]:acc_07,acc_07/_380,{format(Value: ~w, A: ~w, B: ~w~n,[_312,_328,_380])}, TG1:true, TG2:(_328=_380,true),true,format(Value: ~w, A: ~w, B: ~w~n,[_312,_328,_380]), NaAr:called_07/1, HList:[acc_07], Acc:[acc(acc_07,_328,_380)], NewAcc:[acc(acc_07,_4328,_380)], Pass:[]
% _finish_acc - recursive 1 - entry - Link:_380,Acc:[]
% _finish_acc - base 1
% _finish_acc - recursive 1 - exit - Link:_380,Acc:[]
edcg_example:called_07(Value, A, B) :-
true,
A=B,
true,
true,
format('Value: ~w, A: ~w, B: ~w~n', [Value, A, B]).
true.