36
37:- module(prolog_clause,
38 [ clause_info/4, 39 clause_info/5, 40 41 initialization_layout/4, 42 predicate_name/2, 43 clause_name/2 44 ]). 45:- autoload(library(debug),[debugging/1,debug/3]). 46:- autoload(library(listing),[portray_clause/1]). 47:- autoload(library(lists),[append/3]). 48:- autoload(library(occurs),[sub_term/2]). 49:- autoload(library(option),[option/3]). 50:- autoload(library(prolog_source),[read_source_term_at_location/3]). 51
52
53:- public 54 unify_term/2,
55 make_varnames/5,
56 do_make_varnames/3. 57
58:- multifile
59 unify_goal/5, 60 unify_clause_hook/5,
61 make_varnames_hook/5,
62 open_source/2. 63
64:- predicate_options(prolog_clause:clause_info/5, 5,
65 [ head(-any),
66 body(-any),
67 variable_names(-list)
68 ]). 69
80
102
103clause_info(ClauseRef, File, TermPos, NameOffset) :-
104 clause_info(ClauseRef, File, TermPos, NameOffset, []).
105
106clause_info(ClauseRef, File, TermPos, NameOffset, Options) :-
107 ( debugging(clause_info)
108 -> clause_name(ClauseRef, Name),
109 debug(clause_info, 'clause_info(~w) (~w)... ',
110 [ClauseRef, Name])
111 ; true
112 ),
113 clause_property(ClauseRef, file(File)),
114 File \== user, 115 '$clause'(Head0, Body, ClauseRef, VarOffset),
116 option(head(Head0), Options, _),
117 option(body(Body), Options, _),
118 ( module_property(Module, file(File))
119 -> true
120 ; strip_module(user:Head0, Module, _)
121 ),
122 unqualify(Head0, Module, Head),
123 ( Body == true
124 -> DecompiledClause = Head
125 ; DecompiledClause = (Head :- Body)
126 ),
127 clause_property(ClauseRef, line_count(LineNo)),
128 debug(clause_info, 'from ~w:~d ... ', [File, LineNo]),
129 read_term_at_line(File, LineNo, Module, Clause, TermPos0, VarNames),
130 option(variable_names(VarNames), Options, _),
131 debug(clause_info, 'read ...', []),
132 unify_clause(Clause, DecompiledClause, Module, TermPos0, TermPos),
133 debug(clause_info, 'unified ...', []),
134 make_varnames(Clause, DecompiledClause, VarOffset, VarNames, NameOffset),
135 debug(clause_info, 'got names~n', []),
136 !.
137
138unqualify(Module:Head, Module, Head) :-
139 !.
140unqualify(Head, _, Head).
141
142
153
154unify_term(X, X) :- !.
155unify_term(X1, X2) :-
156 compound(X1),
157 compound(X2),
158 functor(X1, F, Arity),
159 functor(X2, F, Arity),
160 !,
161 unify_args(0, Arity, X1, X2).
162unify_term(X, Y) :-
163 float(X), float(Y),
164 !.
165unify_term(X, '$BLOB'(_)) :-
166 blob(X, _),
167 \+ atom(X).
168unify_term(X, Y) :-
169 string(X),
170 is_list(Y),
171 string_codes(X, Y),
172 !.
173unify_term(_, Y) :-
174 Y == '...',
175 !. 176unify_term(_:X, Y) :-
177 unify_term(X, Y),
178 !.
179unify_term(X, _:Y) :-
180 unify_term(X, Y),
181 !.
182unify_term(X, Y) :-
183 format('[INTERNAL ERROR: Diff:~n'),
184 portray_clause(X),
185 format('~N*** <->~n'),
186 portray_clause(Y),
187 break.
188
189unify_args(N, N, _, _) :- !.
190unify_args(I, Arity, T1, T2) :-
191 A is I + 1,
192 arg(A, T1, A1),
193 arg(A, T2, A2),
194 unify_term(A1, A2),
195 unify_args(A, Arity, T1, T2).
196
197
202
203read_term_at_line(File, Line, Module, Clause, TermPos, VarNames) :-
204 setup_call_cleanup(
205 '$push_input_context'(clause_info),
206 read_term_at_line_2(File, Line, Module, Clause, TermPos, VarNames),
207 '$pop_input_context').
208
209read_term_at_line_2(File, Line, Module, Clause, TermPos, VarNames) :-
210 catch(try_open_source(File, In), error(_,_), fail),
211 set_stream(In, newline(detect)),
212 call_cleanup(
213 read_source_term_at_location(
214 In, Clause,
215 [ line(Line),
216 module(Module),
217 subterm_positions(TermPos),
218 variable_names(VarNames)
219 ]),
220 close(In)).
221
232
233:- public try_open_source/2. 234
235try_open_source(File, In) :-
236 open_source(File, In),
237 !.
238try_open_source(File, In) :-
239 open(File, read, In).
240
241
257
258make_varnames(ReadClause, DecompiledClause, Offsets, Names, Term) :-
259 make_varnames_hook(ReadClause, DecompiledClause, Offsets, Names, Term),
260 !.
261make_varnames((Head --> _Body), _, Offsets, Names, Bindings) :-
262 !,
263 functor(Head, _, Arity),
264 In is Arity,
265 memberchk(In=IVar, Offsets),
266 Names1 = ['<DCG_list>'=IVar|Names],
267 Out is Arity + 1,
268 memberchk(Out=OVar, Offsets),
269 Names2 = ['<DCG_tail>'=OVar|Names1],
270 make_varnames(xx, xx, Offsets, Names2, Bindings).
271make_varnames(_, _, Offsets, Names, Bindings) :-
272 length(Offsets, L),
273 functor(Bindings, varnames, L),
274 do_make_varnames(Offsets, Names, Bindings).
275
276do_make_varnames([], _, _).
277do_make_varnames([N=Var|TO], Names, Bindings) :-
278 ( find_varname(Var, Names, Name)
279 -> true
280 ; Name = '_'
281 ),
282 AN is N + 1,
283 arg(AN, Bindings, Name),
284 do_make_varnames(TO, Names, Bindings).
285
286find_varname(Var, [Name = TheVar|_], Name) :-
287 Var == TheVar,
288 !.
289find_varname(Var, [_|T], Name) :-
290 find_varname(Var, T, Name).
291
305
306unify_clause(Read, Decompiled, _, TermPos, TermPos) :-
307 Read =@= Decompiled,
308 !,
309 Read = Decompiled.
310 311unify_clause(Read, Decompiled, Module, TermPos0, TermPos) :-
312 unify_clause_hook(Read, Decompiled, Module, TermPos0, TermPos),
313 !.
314unify_clause(:->(Head, Body), (PlHead :- PlBody), M, TermPos0, TermPos) :-
315 !,
316 pce_method_clause(Head, Body, PlHead, PlBody, M, TermPos0, TermPos).
317 318unify_clause(:<-(Head, Body), (PlHead :- PlBody), M, TermPos0, TermPos) :-
319 !,
320 pce_method_clause(Head, Body, PlHead, PlBody, M, TermPos0, TermPos).
321 322unify_clause((TH :- Body),
323 (_:'unit body'(_, _) :- !, Body), _,
324 TP0, TP) :-
325 ( TH = test(_,_)
326 ; TH = test(_)
327 ),
328 !,
329 TP0 = term_position(F,T,FF,FT,[HP,BP]),
330 TP = term_position(F,T,FF,FT,[HP,term_position(0,0,0,0,[FF-FT,BP])]).
331 332unify_clause((Head :- Read),
333 (Head :- _M:Compiled), Module, TermPos0, TermPos) :-
334 unify_clause((Head :- Read), (Head :- Compiled), Module, TermPos0, TermPos1),
335 TermPos1 = term_position(TA,TZ,FA,FZ,[PH,PB]),
336 TermPos = term_position(TA,TZ,FA,FZ,
337 [ PH,
338 term_position(0,0,0,0,[0-0,PB])
339 ]).
340 341unify_clause(Read, Compiled1, Module, TermPos0, TermPos) :-
342 Read = (_ --> Terminal, _),
343 is_list(Terminal),
344 ci_expand(Read, Compiled2, Module, TermPos0, TermPos1),
345 Compiled2 = (DH :- _),
346 functor(DH, _, Arity),
347 DArg is Arity - 1,
348 append(Terminal, _Tail, List),
349 arg(DArg, DH, List),
350 TermPos1 = term_position(F,T,FF,FT,[ HP,
351 term_position(_,_,_,_,[_,BP])
352 ]),
353 !,
354 TermPos2 = term_position(F,T,FF,FT,[ HP, BP ]),
355 match_module(Compiled2, Compiled1, Module, TermPos2, TermPos).
356 357unify_clause(Read, Compiled1, Module, TermPos0, TermPos) :-
358 ci_expand(Read, Compiled2, Module, TermPos0, TermPos1),
359 match_module(Compiled2, Compiled1, Module, TermPos1, TermPos).
360 361unify_clause(_, _, _, _, _) :-
362 debug(clause_info, 'Could not unify clause', []),
363 fail.
364
365unify_clause_head(H1, H2) :-
366 strip_module(H1, _, H),
367 strip_module(H2, _, H).
368
369ci_expand(Read, Compiled, Module, TermPos0, TermPos) :-
370 catch(setup_call_cleanup(
371 ( set_xref_flag(OldXRef),
372 '$set_source_module'(Old, Module)
373 ),
374 expand_term(Read, TermPos0, Compiled, TermPos),
375 ( '$set_source_module'(Old),
376 set_prolog_flag(xref, OldXRef)
377 )),
378 E,
379 expand_failed(E, Read)).
380
381set_xref_flag(Value) :-
382 current_prolog_flag(xref, Value),
383 !,
384 set_prolog_flag(xref, true).
385set_xref_flag(false) :-
386 create_prolog_flag(xref, true, [type(boolean)]).
387
388match_module((H1 :- B1), (H2 :- B2), Module, Pos0, Pos) :-
389 !,
390 unify_clause_head(H1, H2),
391 unify_body(B1, B2, Module, Pos0, Pos).
392match_module((H1 :- B1), H2, _Module, Pos0, Pos) :-
393 B1 == true,
394 unify_clause_head(H1, H2),
395 Pos = Pos0,
396 !.
397match_module(H1, H2, _, Pos, Pos) :- 398 unify_clause_head(H1, H2).
399
403
404expand_failed(E, Read) :-
405 debugging(clause_info),
406 message_to_string(E, Msg),
407 debug(clause_info, 'Term-expand ~p failed: ~w', [Read, Msg]),
408 fail.
409
416
417unify_body(B, C, _, Pos, Pos) :-
418 B =@= C, B = C,
419 does_not_dcg_after_binding(B, Pos),
420 !.
421unify_body(R, D, Module,
422 term_position(F,T,FF,FT,[HP,BP0]),
423 term_position(F,T,FF,FT,[HP,BP])) :-
424 ubody(R, D, Module, BP0, BP).
425
433
434does_not_dcg_after_binding(B, Pos) :-
435 \+ sub_term(brace_term_position(_,_,_), Pos),
436 \+ (sub_term((Cut,_=_), B), Cut == !),
437 !.
438
439
447
453
460
461ubody(B, DB, _, P, P) :-
462 var(P), 463 !,
464 B = DB.
465ubody(B, C, _, P, P) :-
466 B =@= C, B = C,
467 does_not_dcg_after_binding(B, P),
468 !.
469ubody(X0, X, M, parentheses_term_position(_, _, P0), P) :-
470 !,
471 ubody(X0, X, M, P0, P).
472ubody(X, call(X), _, 473 Pos,
474 term_position(From, To, From, To, [Pos])) :-
475 !,
476 arg(1, Pos, From),
477 arg(2, Pos, To).
478ubody(A, B, _, P1, P2) :-
479 nonvar(A), A = (_=_),
480 nonvar(B), B = (LB=RB),
481 A =@= (RB=LB),
482 !,
483 P1 = term_position(F,T, FF,FT, [PL,PR]),
484 P2 = term_position(F,T, FF,FT, [PR,PL]).
485ubody(A, B, _, P1, P2) :-
486 nonvar(A), A = (_==_),
487 nonvar(B), B = (LB==RB),
488 A =@= (RB==LB),
489 !,
490 P1 = term_position(F,T, FF,FT, [PL,PR]),
491 P2 = term_position(F,T, FF,FT, [PR,PL]).
492ubody(B, D, _, term_position(_,_,_,_,[_,RP]), TPOut) :-
493 nonvar(B), B = M:R,
494 ubody(R, D, M, RP, TPOut).
495ubody(B0, B, M,
496 brace_term_position(F,T,A0),
497 Pos) :-
498 B0 = (_,_=_),
499 !,
500 T1 is T - 1,
501 ubody(B0, B, M,
502 term_position(F,T,
503 F,T,
504 [A0,T1-T]),
505 Pos).
506ubody(B0, B, M,
507 brace_term_position(F,T,A0),
508 term_position(F,T,F,T,[A])) :-
509 !,
510 ubody(B0, B, M, A0, A).
511ubody(C0, C, M, P0, P) :-
512 nonvar(C0), nonvar(C),
513 C0 = (_,_), C = (_,_),
514 !,
515 conj(C0, P0, GL, PL),
516 mkconj(C, M, P, GL, PL).
517ubody(Read, Decompiled, Module, TermPosRead, TermPosDecompiled) :-
518 unify_goal(Read, Decompiled, Module, TermPosRead, TermPosDecompiled),
519 !.
520ubody(X0, X, M,
521 term_position(F,T,FF,TT,PA0),
522 term_position(F,T,FF,TT,PA)) :-
523 meta(M, X0, S),
524 !,
525 X0 =.. [_|A0],
526 X =.. [_|A],
527 S =.. [_|AS],
528 ubody_list(A0, A, AS, M, PA0, PA).
529ubody(X0, X, M,
530 term_position(F,T,FF,TT,PA0),
531 term_position(F,T,FF,TT,PA)) :-
532 expand_goal(X0, X1, M, PA0, PA),
533 X1 =@= X,
534 X1 = X.
535
536 537ubody(_=_, true, _, 538 term_position(F,T,_FF,_TT,_PA),
539 F-T) :- !.
540ubody(_==_, fail, _, 541 term_position(F,T,_FF,_TT,_PA),
542 F-T) :- !.
543ubody(A1=B1, B2=A2, _, 544 term_position(F,T,FF,TT,[PA1,PA2]),
545 term_position(F,T,FF,TT,[PA2,PA1])) :-
546 var(B1), var(B2),
547 (A1==B1) =@= (B2==A2),
548 !,
549 A1 = A2, B1=B2.
550ubody(A1==B1, B2==A2, _, 551 term_position(F,T,FF,TT,[PA1,PA2]),
552 term_position(F,T,FF,TT,[PA2,PA1])) :-
553 var(B1), var(B2),
554 (A1==B1) =@= (B2==A2),
555 !,
556 A1 = A2, B1=B2.
557ubody(A is B - C, A is B + C2, _, Pos, Pos) :-
558 integer(C),
559 C2 =:= -C,
560 !.
561
562ubody_list([], [], [], _, [], []).
563ubody_list([G0|T0], [G|T], [AS|ASL], M, [PA0|PAT0], [PA|PAT]) :-
564 ubody_elem(AS, G0, G, M, PA0, PA),
565 ubody_list(T0, T, ASL, M, PAT0, PAT).
566
567ubody_elem(0, G0, G, M, PA0, PA) :-
568 !,
569 ubody(G0, G, M, PA0, PA).
570ubody_elem(_, G, G, _, PA, PA).
571
572conj(Goal, Pos, GoalList, PosList) :-
573 conj(Goal, Pos, GoalList, [], PosList, []).
574
575conj((A,B), term_position(_,_,_,_,[PA,PB]), GL, TG, PL, TP) :-
576 !,
577 conj(A, PA, GL, TGA, PL, TPA),
578 conj(B, PB, TGA, TG, TPA, TP).
579conj((A,B), brace_term_position(_,T,PA), GL, TG, PL, TP) :-
580 B = (_=_),
581 !,
582 conj(A, PA, GL, TGA, PL, TPA),
583 T1 is T - 1,
584 conj(B, T1-T, TGA, TG, TPA, TP).
585conj(A, parentheses_term_position(_,_,Pos), GL, TG, PL, TP) :-
586 nonvar(Pos),
587 !,
588 conj(A, Pos, GL, TG, PL, TP).
589conj((!,(S=SR)), F-T, [!,S=SR|TG], TG, [F-T,F1-T1|TP], TP) :-
590 F1 is F+1,
591 T1 is T+1.
592conj(A, P, [A|TG], TG, [P|TP], TP).
593
594
595mkconj(Goal, M, Pos, GoalList, PosList) :-
596 mkconj(Goal, M, Pos, GoalList, [], PosList, []).
597
598mkconj(Conj, M, term_position(0,0,0,0,[PA,PB]), GL, TG, PL, TP) :-
599 nonvar(Conj),
600 Conj = (A,B),
601 !,
602 mkconj(A, M, PA, GL, TGA, PL, TPA),
603 mkconj(B, M, PB, TGA, TG, TPA, TP).
604mkconj(A0, M, P0, [A|TG], TG, [P|TP], TP) :-
605 ubody(A, A0, M, P, P0).
606
607
608 611
621
622pce_method_clause(Head, Body, M:PlHead, PlBody, _, TermPos0, TermPos) :-
623 !,
624 pce_method_clause(Head, Body, PlBody, PlHead, M, TermPos0, TermPos).
625pce_method_clause(Head, Body,
626 send_implementation(_Id, Msg, Receiver), PlBody,
627 M, TermPos0, TermPos) :-
628 !,
629 debug(clause_info, 'send method ...', []),
630 arg(1, Head, Receiver),
631 functor(Head, _, Arity),
632 pce_method_head_arguments(2, Arity, Head, Msg),
633 debug(clause_info, 'head ...', []),
634 pce_method_body(Body, PlBody, M, TermPos0, TermPos).
635pce_method_clause(Head, Body,
636 get_implementation(_Id, Msg, Receiver, Result), PlBody,
637 M, TermPos0, TermPos) :-
638 !,
639 debug(clause_info, 'get method ...', []),
640 arg(1, Head, Receiver),
641 debug(clause_info, 'receiver ...', []),
642 functor(Head, _, Arity),
643 arg(Arity, Head, PceResult),
644 debug(clause_info, '~w?~n', [PceResult = Result]),
645 pce_unify_head_arg(PceResult, Result),
646 Ar is Arity - 1,
647 pce_method_head_arguments(2, Ar, Head, Msg),
648 debug(clause_info, 'head ...', []),
649 pce_method_body(Body, PlBody, M, TermPos0, TermPos).
650
651pce_method_head_arguments(N, Arity, Head, Msg) :-
652 N =< Arity,
653 !,
654 arg(N, Head, PceArg),
655 PLN is N - 1,
656 arg(PLN, Msg, PlArg),
657 pce_unify_head_arg(PceArg, PlArg),
658 debug(clause_info, '~w~n', [PceArg = PlArg]),
659 NextArg is N+1,
660 pce_method_head_arguments(NextArg, Arity, Head, Msg).
661pce_method_head_arguments(_, _, _, _).
662
663pce_unify_head_arg(V, A) :-
664 var(V),
665 !,
666 V = A.
667pce_unify_head_arg(A:_=_, A) :- !.
668pce_unify_head_arg(A:_, A).
669
682
683pce_method_body(A0, A, M, TermPos0, TermPos) :-
684 TermPos0 = term_position(F, T, FF, FT,
685 [ HeadPos,
686 BodyPos0
687 ]),
688 TermPos = term_position(F, T, FF, FT,
689 [ HeadPos,
690 term_position(0,0,0,0, [0-0,BodyPos])
691 ]),
692 pce_method_body2(A0, A, M, BodyPos0, BodyPos).
693
694
695pce_method_body2(::(_,A0), A, M, TermPos0, TermPos) :-
696 !,
697 TermPos0 = term_position(_, _, _, _, [_Cmt,BodyPos0]),
698 TermPos = BodyPos,
699 expand_goal(A0, A, M, BodyPos0, BodyPos).
700pce_method_body2(A0, A, M, TermPos0, TermPos) :-
701 A0 =.. [Func,B0,C0],
702 control_op(Func),
703 !,
704 A =.. [Func,B,C],
705 TermPos0 = term_position(F, T, FF, FT,
706 [ BP0,
707 CP0
708 ]),
709 TermPos = term_position(F, T, FF, FT,
710 [ BP,
711 CP
712 ]),
713 pce_method_body2(B0, B, M, BP0, BP),
714 expand_goal(C0, C, M, CP0, CP).
715pce_method_body2(A0, A, M, TermPos0, TermPos) :-
716 expand_goal(A0, A, M, TermPos0, TermPos).
717
718control_op(',').
719control_op((;)).
720control_op((->)).
721control_op((*->)).
722
723 726
739
740expand_goal(G, call(G), _, P, term_position(0,0,0,0,[P])) :-
741 var(G),
742 !.
743expand_goal(G, G1, _, P, P) :-
744 var(G),
745 !,
746 G1 = G.
747expand_goal(M0, M, Module, P0, P) :-
748 meta(Module, M0, S),
749 !,
750 P0 = term_position(F,T,FF,FT,PL0),
751 P = term_position(F,T,FF,FT,PL),
752 functor(M0, Functor, Arity),
753 functor(M, Functor, Arity),
754 expand_meta_args(PL0, PL, 1, S, Module, M0, M).
755expand_goal(A, B, Module, P0, P) :-
756 goal_expansion(A, B0, P0, P1),
757 !,
758 expand_goal(B0, B, Module, P1, P).
759expand_goal(A, A, _, P, P).
760
761expand_meta_args([], [], _, _, _, _, _).
762expand_meta_args([P0|T0], [P|T], I, S, Module, M0, M) :-
763 arg(I, M0, A0),
764 arg(I, M, A),
765 arg(I, S, AS),
766 expand_arg(AS, A0, A, Module, P0, P),
767 NI is I + 1,
768 expand_meta_args(T0, T, NI, S, Module, M0, M).
769
770expand_arg(0, A0, A, Module, P0, P) :-
771 !,
772 expand_goal(A0, A, Module, P0, P).
773expand_arg(_, A, A, _, P, P).
774
775meta(M, G, S) :- predicate_property(M:G, meta_predicate(S)).
776
777goal_expansion(send(R, Msg), send_class(R, _, SuperMsg), P, P) :-
778 compound(Msg),
779 Msg =.. [send_super, Selector | Args],
780 !,
781 SuperMsg =.. [Selector|Args].
782goal_expansion(get(R, Msg, A), get_class(R, _, SuperMsg, A), P, P) :-
783 compound(Msg),
784 Msg =.. [get_super, Selector | Args],
785 !,
786 SuperMsg =.. [Selector|Args].
787goal_expansion(send_super(R, Msg), send_class(R, _, Msg), P, P).
788goal_expansion(get_super(R, Msg, V), get_class(R, _, Msg, V), P, P).
789goal_expansion(SendSuperN, send_class(R, _, Msg), P, P) :-
790 compound(SendSuperN),
791 compound_name_arguments(SendSuperN, send_super, [R,Sel|Args]),
792 Msg =.. [Sel|Args].
793goal_expansion(SendN, send(R, Msg), P, P) :-
794 compound(SendN),
795 compound_name_arguments(SendN, send, [R,Sel|Args]),
796 atom(Sel), Args \== [],
797 Msg =.. [Sel|Args].
798goal_expansion(GetSuperN, get_class(R, _, Msg, Answer), P, P) :-
799 compound(GetSuperN),
800 compound_name_arguments(GetSuperN, get_super, [R,Sel|AllArgs]),
801 append(Args, [Answer], AllArgs),
802 Msg =.. [Sel|Args].
803goal_expansion(GetN, get(R, Msg, Answer), P, P) :-
804 compound(GetN),
805 compound_name_arguments(GetN, get, [R,Sel|AllArgs]),
806 append(Args, [Answer], AllArgs),
807 atom(Sel), Args \== [],
808 Msg =.. [Sel|Args].
809goal_expansion(G0, G, P, P) :-
810 user:goal_expansion(G0, G), 811 G0 \== G. 812
813
814 817
822
823initialization_layout(File:Line, M:Goal0, Goal, TermPos) :-
824 read_term_at_line(File, Line, M, Directive, DirectivePos, _),
825 Directive = (:- initialization(ReadGoal)),
826 DirectivePos = term_position(_, _, _, _, [InitPos]),
827 InitPos = term_position(_, _, _, _, [GoalPos]),
828 ( ReadGoal = M:_
829 -> Goal = M:Goal0
830 ; Goal = Goal0
831 ),
832 unify_body(ReadGoal, Goal, M, GoalPos, TermPos),
833 !.
834
835
836 839
840:- module_transparent
841 predicate_name/2. 842:- multifile
843 user:prolog_predicate_name/2,
844 user:prolog_clause_name/2. 845
846hidden_module(user).
847hidden_module(system).
848hidden_module(pce_principal). 849hidden_module(Module) :- 850 import_module(Module, system).
851
852thaffix(1, st) :- !.
853thaffix(2, nd) :- !.
854thaffix(_, th).
855
859
860predicate_name(Predicate, PName) :-
861 strip_module(Predicate, Module, Head),
862 ( user:prolog_predicate_name(Module:Head, PName)
863 -> true
864 ; functor(Head, Name, Arity),
865 ( hidden_module(Module)
866 -> format(string(PName), '~q/~d', [Name, Arity])
867 ; format(string(PName), '~q:~q/~d', [Module, Name, Arity])
868 )
869 ).
870
874
875clause_name(Ref, Name) :-
876 user:prolog_clause_name(Ref, Name),
877 !.
878clause_name(Ref, Name) :-
879 nth_clause(Head, N, Ref),
880 !,
881 predicate_name(Head, PredName),
882 thaffix(N, Th),
883 format(string(Name), '~d-~w clause of ~w', [N, Th, PredName]).
884clause_name(Ref, Name) :-
885 clause_property(Ref, erased),
886 !,
887 clause_property(Ref, predicate(M:PI)),
888 format(string(Name), 'erased clause from ~q', [M:PI]).
889clause_name(_, '<meta-call>')