27
28:- module(scasp_call_graph,
29 [ build_call_graph/2,
30 destroy_call_graph/0,
31 a/4,
32 ar/2
33 ]).
44:- use_module(common).
72:- thread_local
73 a/4, 74 ar/2.
84build_call_graph([], []) :-
85 !.
86build_call_graph(R, Ns) :-
87 get_arcs(R, [], As),
88 sort(As, As2),
89 merge_arcs(As2, As3, Rs),
90 get_nodes(As3, Ns),
91 assert_all(As3),
92 assert_all(Rs).
102get_nodes([X|T], [N|Ns]) :-
103 X = a(N, _, _, _),
104 get_nodes(T, N, Ns).
105get_nodes([], []).
106
107get_nodes([], _, []).
108get_nodes([X|T], N, Ns) :-
109 X = a(Y, _, _, _),
110 ( Y = N
111 -> get_nodes(T, N, Ns)
112 ; Ns = [Y|Ns2],
113 get_nodes(T, Y, Ns2)
114 ).
125get_arcs([], G, G).
126get_arcs([R|T], Gi, Go) :-
127 ( rule(R, H, I, Y)
128 -> true
129 ; c_rule(R, H, Y)
130 -> I = -1
131 ),
132 rule(R, H, I, Y), 133 predicate(H, F, _), 134 \+ ignore_edge(F),
135 !,
136 get_arcs2(F, I, Y, Gi, G1),
137 get_arcs(T, G1, Go).
138get_arcs([_|T], Gi, Go) :-
139 get_arcs(T, Gi, Go).
140
141ignore_edge('_false_0'). 142ignore_edge(F) :- 143 is_dual(F).
157get_arcs2(_, _, [], G, G) :-
158 !.
159get_arcs2(H, I, [Y|T], Gi, [G|Go]) :-
160 predicate(Y, Gy, _), 161 \+ is_dual(Gy),
162 !,
163 G = a(H, Gy, 0, I),
164 get_arcs2(H, I, T, Gi, Go).
165get_arcs2(H, I, [Y|T], Gi, [G|Go]) :-
166 Y = not(Y2),
167 !,
168 predicate(Y2, Gn, _), 169 G = a(H, Gn, 1, I),
170 get_arcs2(H, I, T, Gi, Go).
171get_arcs2(H, I, [Y|T], Gi, Go) :-
172 \+ predicate(Y, _, _), 173 get_arcs2(H, I, T, Gi, Go).
185:- det(merge_arcs/3). 186
187merge_arcs([X|T], [X|As], [Ar|Is]) :-
188 X = a(H, G, N, I),
189 merge_arcs2(H, G, N, T, To, Rs),
190 Ar = ar(I, [I|Rs]),
191 merge_arcs(To, As, Is).
192merge_arcs([], [], []).
206merge_arcs2(_, _, _, [], [], []) :-
207 !.
208merge_arcs2(H, G, N, [X|T], To, [I|Rs]) :-
209 X = a(H, G, N, I),
210 !,
211 merge_arcs2(H, G, N, T, To, Rs).
212merge_arcs2(_, _, _, [X|T], [X|T], []).
220assert_all([X|T]) :-
221 assertz(X),
222 assert_all(T).
223assert_all([]).
229destroy_call_graph :-
230 retractall(a(_,_,_,_)),
231 retractall(ar(_,_))
Build the call graph used for NMR check construction and indexing.
Given the input program, build a call graph and assert the components.