35
36:- module(prolog_code,
37 [ comma_list/2, 38 semicolon_list/2, 39
40 mkconj/3, 41 mkdisj/3, 42
43 pi_head/2, 44 head_name_arity/3, 45
46 most_general_goal/2, 47 extend_goal/3, 48
49 predicate_label/2, 50 predicate_sort_key/2, 51
52 is_control_goal/1, 53 is_predicate_indicator/1, 54
55 body_term_calls/2 56 ]). 57:- autoload(library(error),[must_be/2, instantiation_error/1]). 58:- autoload(library(lists),[append/3]). 59
60:- meta_predicate
61 body_term_calls(:, -). 62
63:- multifile
64 user:prolog_predicate_name/2. 65
79
94
95comma_list(CommaList, List) :-
96 phrase(binlist(CommaList, ','), List).
97semicolon_list(CommaList, List) :-
98 phrase(binlist(CommaList, ';'), List).
99
100binlist(Term, Functor) -->
101 { nonvar(Term) },
102 !,
103 ( { Term =.. [Functor,A,B] }
104 -> binlist(A, Functor),
105 binlist(B, Functor)
106 ; [Term]
107 ).
108binlist(Term, Functor) -->
109 [A],
110 ( var_tail
111 -> ( { Term = A }
112 ; { Term =.. [Functor,A,B] },
113 binlist(B,Functor)
114 )
115 ; \+ [_]
116 -> {Term = A}
117 ; binlist(B,Functor),
118 {Term =.. [Functor,A,B]}
119 ).
120
121var_tail(H, H) :-
122 var(H).
123
137
138mkconj(A,B,Conj) :-
139 ( is_true(A)
140 -> Conj = B
141 ; is_true(B)
142 -> Conj = A
143 ; mkconj_(A,B,Conj)
144 ).
145
146mkconj_((A,B), C, Conj) =>
147 Conj = (A,C2),
148 mkconj_(B,C,C2).
149mkconj_(A, B, C) =>
150 C = (A,B).
151
152mkdisj(A,B,Disj) :-
153 ( is_false(A)
154 -> Disj = B
155 ; is_false(B)
156 -> Disj = A
157 ; mkdisj_(A,B,Disj)
158 ).
159
160mkdisj_((A;B), C, Disj) =>
161 Disj = (A;C2),
162 mkdisj_(B, C, C2).
163mkdisj_(A, B, C) =>
164 C = (A;B).
165
166is_true(Goal) :- Goal == true.
167is_false(Goal) :- (Goal == false -> true ; Goal == fail).
168
172
173is_predicate_indicator(Var) :-
174 var(Var),
175 !,
176 instantiation_error(Var).
177is_predicate_indicator(PI) :-
178 strip_module(PI, M, PI1),
179 atom(M),
180 ( PI1 = (Name/Arity)
181 -> true
182 ; PI1 = (Name//Arity)
183 ),
184 atom(Name),
185 integer(Arity),
186 Arity >= 0.
187
194
195pi_head(PI, Head) :-
196 '$pi_head'(PI, Head).
197
203
204head_name_arity(Goal, Name, Arity) :-
205 '$head_name_arity'(Goal, Name, Arity).
206
212
213most_general_goal(Goal, General) :-
214 var(Goal),
215 !,
216 General = Goal.
217most_general_goal(Goal, General) :-
218 atom(Goal),
219 !,
220 General = Goal.
221most_general_goal(M:Goal, M:General) :-
222 !,
223 most_general_goal(Goal, General).
224most_general_goal(Compound, General) :-
225 compound_name_arity(Compound, Name, Arity),
226 compound_name_arity(General, Name, Arity).
227
228
234
235extend_goal(Goal0, Extra, Goal) :-
236 var(Goal0),
237 !,
238 Goal =.. [call,Goal0|Extra].
239extend_goal(M:Goal0, Extra, M:Goal) :-
240 extend_goal(Goal0, Extra, Goal).
241extend_goal(Atom, Extra, Goal) :-
242 atom(Atom),
243 !,
244 Goal =.. [Atom|Extra].
245extend_goal(Goal0, Extra, Goal) :-
246 compound_name_arguments(Goal0, Name, Args0),
247 append(Args0, Extra, Args),
248 compound_name_arguments(Goal, Name, Args).
249
250
251 254
264
265predicate_label(PI, Label) :-
266 must_be(ground, PI),
267 pi_head(PI, Head),
268 user:prolog_predicate_name(Head, Label),
269 !.
270predicate_label(M:Name/Arity, Label) :-
271 !,
272 predicate_name_(Name, PName),
273 ( hidden_module(M, PName/Arity)
274 -> atomic_list_concat([PName, /, Arity], Label)
275 ; atomic_list_concat([M, :, PName, /, Arity], Label)
276 ).
277predicate_label(M:Name//Arity, Label) :-
278 !,
279 predicate_name_(Name, PName),
280 ( hidden_module(M, PName//Arity)
281 -> atomic_list_concat([PName, //, Arity], Label)
282 ; atomic_list_concat([M, :, PName, //, Arity], Label)
283 ).
284predicate_label(Name/Arity, Label) :-
285 !,
286 predicate_name_(Name, PName),
287 atomic_list_concat([PName, /, Arity], Label).
288predicate_label(Name//Arity, Label) :-
289 !,
290 predicate_name_(Name, PName),
291 atomic_list_concat([PName, //, Arity], Label).
292
293predicate_name_([], '[]') :- !. 294predicate_name_(Name, Name).
295
296hidden_module(system, _).
297hidden_module(user, _).
298hidden_module(M, Name/Arity) :-
299 current_predicate(system:Name/Arity),
300 functor(H, Name, Arity),
301 predicate_property(system:H, imported_from(M)).
302hidden_module(M, Name//DCGArity) :-
303 Arity is DCGArity+1,
304 current_predicate(system:Name/Arity),
305 functor(H, Name, Arity),
306 predicate_property(system:H, imported_from(M)).
307
311
312predicate_sort_key(_:PI, Name) :-
313 !,
314 predicate_sort_key(PI, Name).
315predicate_sort_key(Name/_Arity, Name).
316predicate_sort_key(Name//_Arity, Name).
317
325
326is_control_goal(Goal) :-
327 var(Goal),
328 !, fail.
329is_control_goal((_,_)).
330is_control_goal((_;_)).
331is_control_goal((_->_)).
332is_control_goal((_|_)).
333is_control_goal((_*->_)).
334is_control_goal(\+(_)).
335
344
345body_term_calls(M:Body, Calls) :-
346 body_term_calls(Body, M, M, Calls).
347
348body_term_calls(Var, M, C, Calls) :-
349 var(Var),
350 !,
351 qualify(M, C, Var, Calls).
352body_term_calls(M:Goal, _, C, Calls) :-
353 !,
354 body_term_calls(Goal, M, C, Calls).
355body_term_calls(Goal, M, C, Calls) :-
356 qualify(M, C, Goal, Calls).
357body_term_calls((A,B), M, C, Calls) :-
358 !,
359 ( body_term_calls(A, M, C, Calls)
360 ; body_term_calls(B, M, C, Calls)
361 ).
362body_term_calls((A;B), M, C, Calls) :-
363 !,
364 ( body_term_calls(A, M, C, Calls)
365 ; body_term_calls(B, M, C, Calls)
366 ).
367body_term_calls((A->B), M, C, Calls) :-
368 !,
369 ( body_term_calls(A, M, C, Calls)
370 ; body_term_calls(B, M, C, Calls)
371 ).
372body_term_calls((A*->B), M, C, Calls) :-
373 !,
374 ( body_term_calls(A, M, C, Calls)
375 ; body_term_calls(B, M, C, Calls)
376 ).
377body_term_calls(\+ A, M, C, Calls) :-
378 !,
379 body_term_calls(A, M, C, Calls).
380body_term_calls(Goal, M, C, Calls) :-
381 predicate_property(M:Goal, meta_predicate(Spec)),
382 \+ ( functor(Goal, call, _),
383 arg(1, Goal, A1),
384 strip_module(A1, _, P1),
385 var(P1)
386 ),
387 !,
388 arg(I, Spec, SArg),
389 arg(I, Goal, GArg),
390 meta_calls(SArg, GArg, Call0),
391 body_term_calls(Call0, M, C, Calls).
392
393meta_calls(0, Goal, Goal) :-
394 !.
395meta_calls(I, Goal0, Goal) :-
396 integer(I),
397 !,
398 length(Extra, I),
399 extend_goal(Goal0, Extra, Goal).
400meta_calls(//, Goal0, Goal) :-
401 extend_goal(Goal0, [_,_], Goal).
402meta_calls(^, Goal0, Goal) :-
403 !,
404 strip_existential(Goal0, Goal).
405
406strip_existential(Var, Var) :-
407 var(Var),
408 !.
409strip_existential(_^In, Out) :-
410 strip_existential(In, Out).
411
412qualify(M, C, Goal, Calls) :-
413 M == C,
414 !,
415 Calls = Goal.
416qualify(M, _, Goal, M:Goal)