37
38:- module(prolog_clause,
39 [ clause_info/4, 40 clause_info/5, 41 42 initialization_layout/4, 43 predicate_name/2, 44 clause_name/2 45 ]). 46:- use_module(library(debug),[debugging/1,debug/3]). 47:- autoload(library(listing),[portray_clause/1]). 48:- autoload(library(lists),[append/3]). 49:- autoload(library(occurs),[sub_term/2]). 50:- autoload(library(option),[option/3]). 51:- autoload(library(prolog_source),[read_source_term_at_location/3]). 52
53
54:- public 55 unify_term/2,
56 make_varnames/5,
57 do_make_varnames/3. 58
59:- multifile
60 unify_goal/5, 61 unify_clause_hook/5,
62 make_varnames_hook/5,
63 open_source/2. 64
65:- predicate_options(prolog_clause:clause_info/5, 5,
66 [ head(-any),
67 body(-any),
68 variable_names(-list)
69 ]). 70
81
108
109clause_info(ClauseRef, File, TermPos, NameOffset) :-
110 clause_info(ClauseRef, File, TermPos, NameOffset, []).
111
112clause_info(ClauseRef, File, TermPos, NameOffset, Options) :-
113 ( debugging(clause_info)
114 -> clause_name(ClauseRef, Name),
115 debug(clause_info, 'clause_info(~w) (~w)... ',
116 [ClauseRef, Name])
117 ; true
118 ),
119 clause_property(ClauseRef, file(File)),
120 File \== user, 121 '$clause'(Head0, Body, ClauseRef, VarOffset),
122 option(head(Head0), Options, _),
123 option(body(Body), Options, _),
124 ( module_property(Module, file(File))
125 -> true
126 ; strip_module(user:Head0, Module, _)
127 ),
128 unqualify(Head0, Module, Head),
129 ( Body == true
130 -> DecompiledClause = Head
131 ; DecompiledClause = (Head :- Body)
132 ),
133 clause_property(ClauseRef, line_count(LineNo)),
134 debug(clause_info, 'from ~w:~d ... ', [File, LineNo]),
135 read_term_at_line(File, LineNo, Module, Clause, TermPos0, VarNames),
136 option(variable_names(VarNames), Options, _),
137 debug(clause_info, 'read ...', []),
138 unify_clause(Clause, DecompiledClause, Module, TermPos0, TermPos),
139 debug(clause_info, 'unified ...', []),
140 make_varnames(Clause, DecompiledClause, VarOffset, VarNames, NameOffset),
141 debug(clause_info, 'got names~n', []),
142 !.
143
144unqualify(Module:Head, Module, Head) :-
145 !.
146unqualify(Head, _, Head).
147
148
159
160unify_term(X, X) :- !.
161unify_term(X1, X2) :-
162 compound(X1),
163 compound(X2),
164 functor(X1, F, Arity),
165 functor(X2, F, Arity),
166 !,
167 unify_args(0, Arity, X1, X2).
168unify_term(X, Y) :-
169 float(X), float(Y),
170 !.
171unify_term(X, '$BLOB'(_)) :-
172 blob(X, _),
173 \+ atom(X).
174unify_term(X, Y) :-
175 string(X),
176 is_list(Y),
177 string_codes(X, Y),
178 !.
179unify_term(_, Y) :-
180 Y == '...',
181 !. 182unify_term(_:X, Y) :-
183 unify_term(X, Y),
184 !.
185unify_term(X, _:Y) :-
186 unify_term(X, Y),
187 !.
188unify_term(X, Y) :-
189 format('[INTERNAL ERROR: Diff:~n'),
190 portray_clause(X),
191 format('~N*** <->~n'),
192 portray_clause(Y),
193 break.
194
195unify_args(N, N, _, _) :- !.
196unify_args(I, Arity, T1, T2) :-
197 A is I + 1,
198 arg(A, T1, A1),
199 arg(A, T2, A2),
200 unify_term(A1, A2),
201 unify_args(A, Arity, T1, T2).
202
203
208
209read_term_at_line(File, Line, Module, Clause, TermPos, VarNames) :-
210 setup_call_cleanup(
211 '$push_input_context'(clause_info),
212 read_term_at_line_2(File, Line, Module, Clause, TermPos, VarNames),
213 '$pop_input_context').
214
215read_term_at_line_2(File, Line, Module, Clause, TermPos, VarNames) :-
216 catch(try_open_source(File, In), error(_,_), fail),
217 set_stream(In, newline(detect)),
218 call_cleanup(
219 read_source_term_at_location(
220 In, Clause,
221 [ line(Line),
222 module(Module),
223 subterm_positions(TermPos),
224 variable_names(VarNames)
225 ]),
226 close(In)).
227
238
239:- public try_open_source/2. 240
241try_open_source(File, In) :-
242 open_source(File, In),
243 !.
244try_open_source(File, In) :-
245 open(File, read, In, [reposition(true)]).
246
247
263
264make_varnames(ReadClause, DecompiledClause, Offsets, Names, Term) :-
265 make_varnames_hook(ReadClause, DecompiledClause, Offsets, Names, Term),
266 !.
267make_varnames((Head --> _Body), _, Offsets, Names, Bindings) :-
268 !,
269 functor(Head, _, Arity),
270 In is Arity,
271 memberchk(In=IVar, Offsets),
272 Names1 = ['<DCG_list>'=IVar|Names],
273 Out is Arity + 1,
274 memberchk(Out=OVar, Offsets),
275 Names2 = ['<DCG_tail>'=OVar|Names1],
276 make_varnames(xx, xx, Offsets, Names2, Bindings).
277make_varnames(_, _, Offsets, Names, Bindings) :-
278 length(Offsets, L),
279 functor(Bindings, varnames, L),
280 do_make_varnames(Offsets, Names, Bindings).
281
282do_make_varnames([], _, _).
283do_make_varnames([N=Var|TO], Names, Bindings) :-
284 ( find_varname(Var, Names, Name)
285 -> true
286 ; Name = '_'
287 ),
288 AN is N + 1,
289 arg(AN, Bindings, Name),
290 do_make_varnames(TO, Names, Bindings).
291
292find_varname(Var, [Name = TheVar|_], Name) :-
293 Var == TheVar,
294 !.
295find_varname(Var, [_|T], Name) :-
296 find_varname(Var, T, Name).
297
318
319unify_clause(Read, _, _, _, _) :-
320 var(Read),
321 !,
322 fail.
323unify_clause((RHead :- RBody), (CHead :- CBody), Module, TermPos1, TermPos) :-
324 '$expand':f2_pos(TermPos1, HPos, BPos1,
325 TermPos2, HPos, BPos2),
326 inlined_unification(RBody, CBody, RBody1, CBody1, RHead,
327 BPos1, BPos2),
328 RBody1 \== RBody,
329 !,
330 unify_clause2((RHead :- RBody1), (CHead :- CBody1), Module,
331 TermPos2, TermPos).
332unify_clause(Read, Decompiled, _, TermPos, TermPos) :-
333 Read =@= Decompiled,
334 !,
335 Read = Decompiled.
336unify_clause(Read, Decompiled, Module, TermPos0, TermPos) :-
337 unify_clause_hook(Read, Decompiled, Module, TermPos0, TermPos),
338 !.
339 340unify_clause(:->(Head, Body), (PlHead :- PlBody), M, TermPos0, TermPos) :-
341 !,
342 pce_method_clause(Head, Body, PlHead, PlBody, M, TermPos0, TermPos).
343 344unify_clause(:<-(Head, Body), (PlHead :- PlBody), M, TermPos0, TermPos) :-
345 !,
346 pce_method_clause(Head, Body, PlHead, PlBody, M, TermPos0, TermPos).
347 348unify_clause((TH :- RBody), (CH :- !, CBody), Module, TP0, TP) :-
349 plunit_source_head(TH),
350 plunit_compiled_head(CH),
351 !,
352 TP0 = term_position(F,T,FF,FT,[HP,BP0]),
353 ubody(RBody, CBody, Module, BP0, BP),
354 TP = term_position(F,T,FF,FT,[HP,term_position(0,0,0,0,[FF-FT,BP])]).
355 356unify_clause((Head :- Read),
357 (Head :- _M:Compiled), Module, TermPos0, TermPos) :-
358 unify_clause2((Head :- Read), (Head :- Compiled), Module, TermPos0, TermPos1),
359 TermPos1 = term_position(TA,TZ,FA,FZ,[PH,PB]),
360 TermPos = term_position(TA,TZ,FA,FZ,
361 [ PH,
362 term_position(0,0,0,0,[0-0,PB])
363 ]).
364 365unify_clause(Read, Compiled1, Module, TermPos0, TermPos) :-
366 Read = (_ --> Terminal, _),
367 is_list(Terminal),
368 ci_expand(Read, Compiled2, Module, TermPos0, TermPos1),
369 Compiled2 = (DH :- _),
370 functor(DH, _, Arity),
371 DArg is Arity - 1,
372 append(Terminal, _Tail, List),
373 arg(DArg, DH, List),
374 TermPos1 = term_position(F,T,FF,FT,[ HP,
375 term_position(_,_,_,_,[_,BP])
376 ]),
377 !,
378 TermPos2 = term_position(F,T,FF,FT,[ HP, BP ]),
379 match_module(Compiled2, Compiled1, Module, TermPos2, TermPos).
380 381unify_clause((Head,RCond => Body), (CHead :- CCondAndBody), Module,
382 term_position(F,T,FF,FT,
383 [ term_position(_,_,_,_,[HP,CP]),
384 BP
385 ]),
386 TermPos) :-
387 split_on_cut(CCondAndBody, CCond, CBody0),
388 !,
389 inlined_unification(RCond, CCond, RCond1, CCond1, Head, CP, CP1),
390 TermPos1 = term_position(F,T,FF,FT, [HP, BP1]),
391 BP2 = term_position(_,_,_,_, [FF-FT, BP]), 392 ( CCond1 == true 393 -> BP1 = BP2, 394 unify_clause2((Head :- !, Body), (CHead :- !, CBody0),
395 Module, TermPos1, TermPos)
396 ; mkconj_pos(RCond1, CP1, (!,Body), BP2, RBody, BP1),
397 mkconj_npos(CCond1, (!,CBody0), CBody),
398 unify_clause2((Head :- RBody), (CHead :- CBody),
399 Module, TermPos1, TermPos)
400 ).
401unify_clause((Head => Body), Compiled1, Module, TermPos0, TermPos) :-
402 !,
403 unify_clause2(Head :- Body, Compiled1, Module, TermPos0, TermPos).
404unify_clause(Read, Decompiled, Module, TermPos0, TermPos) :-
405 unify_clause2(Read, Decompiled, Module, TermPos0, TermPos).
406
408mkconj_pos((A,B), term_position(F,T,FF,FT,[PA,PB]), Ex, ExPos, Code, Pos) =>
409 Code = (A,B1),
410 Pos = term_position(F,T,FF,FT,[PA,PB1]),
411 mkconj_pos(B, PB, Ex, ExPos, B1, PB1).
412mkconj_pos(Last, LastPos, Ex, ExPos, Code, Pos) =>
413 Code = (Last,Ex),
414 Pos = term_position(_,_,_,_,[LastPos,ExPos]).
415
417mkconj_npos((A,B), Ex, Code) =>
418 Code = (A,B1),
419 mkconj_npos(B, Ex, B1).
420mkconj_npos(A, Ex, Code) =>
421 Code = (A,Ex).
422
426
427unify_clause2(Read, Decompiled, _, TermPos, TermPos) :-
428 Read =@= Decompiled,
429 !,
430 Read = Decompiled.
431unify_clause2(Read, Compiled1, Module, TermPos0, TermPos) :-
432 ci_expand(Read, Compiled2, Module, TermPos0, TermPos1),
433 match_module(Compiled2, Compiled1, Module, TermPos1, TermPos).
434 435unify_clause2(_, _, _, _, _) :-
436 debug(clause_info, 'Could not unify clause', []),
437 fail.
438
439unify_clause_head(H1, H2) :-
440 strip_module(H1, _, H),
441 strip_module(H2, _, H).
442
443plunit_source_head(test(_,_)) => true.
444plunit_source_head(test(_)) => true.
445plunit_source_head(_) => fail.
446
447plunit_compiled_head(_:'unit body'(_, _)) => true.
448plunit_compiled_head('unit body'(_, _)) => true.
449plunit_compiled_head(_) => fail.
450
455
456inlined_unification((V=T,RBody0), (CV=CT,CBody0),
457 RBody, CBody, RHead, BPos1, BPos),
458 inlineable_head_var(RHead, V2),
459 V == V2,
460 (V=T) =@= (CV=CT) =>
461 argpos(2, BPos1, BPos2),
462 inlined_unification(RBody0, CBody0, RBody, CBody, RHead, BPos2, BPos).
463inlined_unification((V=T), (CV=CT),
464 RBody, CBody, RHead, BPos1, BPos),
465 inlineable_head_var(RHead, V2),
466 V == V2,
467 (V=T) =@= (CV=CT) =>
468 RBody = true,
469 CBody = true,
470 argpos(2, BPos1, BPos).
471inlined_unification((V=T,RBody0), CBody0,
472 RBody, CBody, RHead, BPos1, BPos),
473 inlineable_head_var(RHead, V2),
474 V == V2,
475 \+ (CBody0 = (G1,_), G1 =@= (V=T)) =>
476 argpos(2, BPos1, BPos2),
477 inlined_unification(RBody0, CBody0, RBody, CBody, RHead, BPos2, BPos).
478inlined_unification((V=_), true,
479 RBody, CBody, RHead, BPos1, BPos),
480 inlineable_head_var(RHead, V2),
481 V == V2 =>
482 RBody = true,
483 CBody = true,
484 argpos(2, BPos1, BPos).
485inlined_unification(RBody0, CBody0, RBody, CBody, _RHead,
486 BPos0, BPos) =>
487 RBody = RBody0,
488 BPos = BPos0,
489 CBody = CBody0.
490
495
496inlineable_head_var(Head, Var) :-
497 compound(Head),
498 arg(_, Head, Var).
499
500split_on_cut((Cond0,!,Body0), Cond, Body) =>
501 Cond = Cond0,
502 Body = Body0.
503split_on_cut((!,Body0), Cond, Body) =>
504 Cond = true,
505 Body = Body0.
506split_on_cut((A,B), Cond, Body) =>
507 Cond = (A,Cond1),
508 split_on_cut(B, Cond1, Body).
509split_on_cut(_, _, _) =>
510 fail.
511
512ci_expand(Read, Compiled, Module, TermPos0, TermPos) :-
513 catch(setup_call_cleanup(
514 ( set_xref_flag(OldXRef),
515 '$set_source_module'(Old, Module)
516 ),
517 expand_term(Read, TermPos0, Compiled, TermPos),
518 ( '$set_source_module'(Old),
519 set_prolog_flag(xref, OldXRef)
520 )),
521 E,
522 expand_failed(E, Read)),
523 compound(TermPos), 524 arg(1, TermPos, A1), nonvar(A1),
525 arg(2, TermPos, A2), nonvar(A2).
526
527set_xref_flag(Value) :-
528 current_prolog_flag(xref, Value),
529 !,
530 set_prolog_flag(xref, true).
531set_xref_flag(false) :-
532 create_prolog_flag(xref, true, [type(boolean)]).
533
534match_module((H1 :- B1), (H2 :- B2), Module, Pos0, Pos) :-
535 !,
536 unify_clause_head(H1, H2),
537 unify_body(B1, B2, Module, Pos0, Pos).
538match_module((H1 :- B1), H2, _Module, Pos0, Pos) :-
539 B1 == true,
540 unify_clause_head(H1, H2),
541 Pos = Pos0,
542 !.
543match_module(H1, H2, _, Pos, Pos) :- 544 unify_clause_head(H1, H2).
545
549
550expand_failed(E, Read) :-
551 debugging(clause_info),
552 message_to_string(E, Msg),
553 debug(clause_info, 'Term-expand ~p failed: ~w', [Read, Msg]),
554 fail.
555
562
563unify_body(B, C, _, Pos, Pos) :-
564 B =@= C, B = C,
565 does_not_dcg_after_binding(B, Pos),
566 !.
567unify_body(R, D, Module,
568 term_position(F,T,FF,FT,[HP,BP0]),
569 term_position(F,T,FF,FT,[HP,BP])) :-
570 ubody(R, D, Module, BP0, BP).
571
579
580does_not_dcg_after_binding(B, Pos) :-
581 \+ sub_term(brace_term_position(_,_,_), Pos),
582 \+ (sub_term((Cut,_=_), B), Cut == !),
583 !.
584
585
593
599
606
607ubody(B, DB, _, P, P) :-
608 var(P), 609 !,
610 B = DB.
611ubody(B, C, _, P, P) :-
612 B =@= C, B = C,
613 does_not_dcg_after_binding(B, P),
614 !.
615ubody(X0, X, M, parentheses_term_position(_, _, P0), P) :-
616 !,
617 ubody(X0, X, M, P0, P).
618ubody(X, Y, _, 619 Pos,
620 term_position(From, To, From, To, [Pos])) :-
621 nonvar(Y),
622 Y = call(X),
623 !,
624 arg(1, Pos, From),
625 arg(2, Pos, To).
626ubody(A, B, _, P1, P2) :-
627 nonvar(A), A = (_=_),
628 nonvar(B), B = (LB=RB),
629 A =@= (RB=LB),
630 !,
631 P1 = term_position(F,T, FF,FT, [PL,PR]),
632 P2 = term_position(F,T, FF,FT, [PR,PL]).
633ubody(A, B, _, P1, P2) :-
634 nonvar(A), A = (_==_),
635 nonvar(B), B = (LB==RB),
636 A =@= (RB==LB),
637 !,
638 P1 = term_position(F,T, FF,FT, [PL,PR]),
639 P2 = term_position(F,T, FF,FT, [PR,PL]).
640ubody(B, D, _, term_position(_,_,_,_,[_,RP]), TPOut) :-
641 nonvar(B), B = M:R,
642 ubody(R, D, M, RP, TPOut).
643ubody(B, D, M, term_position(_,_,_,_,[RP0,RP1]), TPOut) :-
644 nonvar(B), B = (B0,B1),
645 ( maybe_optimized(B0),
646 ubody(B1, D, M, RP1, TPOut)
647 -> true
648 ; maybe_optimized(B1),
649 ubody(B0, D, M, RP0, TPOut)
650 ),
651 !.
652ubody(B0, B, M,
653 brace_term_position(F,T,A0),
654 Pos) :-
655 B0 = (_,_=_),
656 !,
657 T1 is T - 1,
658 ubody(B0, B, M,
659 term_position(F,T,
660 F,T,
661 [A0,T1-T]),
662 Pos).
663ubody(B0, B, M,
664 brace_term_position(F,T,A0),
665 term_position(F,T,F,T,[A])) :-
666 !,
667 ubody(B0, B, M, A0, A).
668ubody(C0, C, M, P0, P) :-
669 nonvar(C0), nonvar(C),
670 C0 = (_,_), C = (_,_),
671 !,
672 conj(C0, P0, GL, PL),
673 mkconj(C, M, P, GL, PL).
674ubody(Read, Decompiled, Module, TermPosRead, TermPosDecompiled) :-
675 unify_goal(Read, Decompiled, Module, TermPosRead, TermPosDecompiled),
676 !.
677ubody(X0, X, M,
678 term_position(F,T,FF,TT,PA0),
679 term_position(F,T,FF,TT,PA)) :-
680 callable(X0),
681 callable(X),
682 meta(M, X0, S),
683 !,
684 X0 =.. [_|A0],
685 X =.. [_|A],
686 S =.. [_|AS],
687 ubody_list(A0, A, AS, M, PA0, PA).
688ubody(X0, X, M,
689 term_position(F,T,FF,TT,PA0),
690 term_position(F,T,FF,TT,PA)) :-
691 expand_goal(X0, X1, M, PA0, PA),
692 X1 =@= X,
693 X1 = X.
694
695 696ubody(_=_, true, _, 697 term_position(F,T,_FF,_TT,_PA),
698 F-T) :- !.
699ubody(_==_, fail, _, 700 term_position(F,T,_FF,_TT,_PA),
701 F-T) :- !.
702ubody(A1=B1, B2=A2, _, 703 term_position(F,T,FF,TT,[PA1,PA2]),
704 term_position(F,T,FF,TT,[PA2,PA1])) :-
705 var(B1), var(B2),
706 (A1==B1) =@= (B2==A2),
707 !,
708 A1 = A2, B1=B2.
709ubody(A1==B1, B2==A2, _, 710 term_position(F,T,FF,TT,[PA1,PA2]),
711 term_position(F,T,FF,TT,[PA2,PA1])) :-
712 var(B1), var(B2),
713 (A1==B1) =@= (B2==A2),
714 !,
715 A1 = A2, B1=B2.
716ubody(A is B - C, A is B + C2, _, Pos, Pos) :-
717 integer(C),
718 C2 =:= -C,
719 !.
720
721ubody_list([], [], [], _, [], []).
722ubody_list([G0|T0], [G|T], [AS|ASL], M, [PA0|PAT0], [PA|PAT]) :-
723 ubody_elem(AS, G0, G, M, PA0, PA),
724 ubody_list(T0, T, ASL, M, PAT0, PAT).
725
726ubody_elem(0, G0, G, M, PA0, PA) :-
727 !,
728 ubody(G0, G, M, PA0, PA).
729ubody_elem(_, G, G, _, PA, PA).
730
735
736conj(Goal, Pos, GoalList, PosList) :-
737 conj(Goal, Pos, GoalList, [], PosList, []).
738
739conj((A,B), term_position(_,_,_,_,[PA,PB]), GL, TG, PL, TP) :-
740 !,
741 conj(A, PA, GL, TGA, PL, TPA),
742 conj(B, PB, TGA, TG, TPA, TP).
743conj((A,B), brace_term_position(_,T,PA), GL, TG, PL, TP) :-
744 B = (_=_),
745 !,
746 conj(A, PA, GL, TGA, PL, TPA),
747 T1 is T - 1,
748 conj(B, T1-T, TGA, TG, TPA, TP).
749conj(A, parentheses_term_position(_,_,Pos), GL, TG, PL, TP) :-
750 nonvar(Pos),
751 !,
752 conj(A, Pos, GL, TG, PL, TP).
753conj((!,(S=SR)), F-T, [!,S=SR|TG], TG, [F-T,F1-T1|TP], TP) :-
754 F1 is F+1,
755 T1 is T+1.
756conj(A, P, [A|TG], TG, [P|TP], TP).
757
758
760
761mkconj(Goal, M, Pos, GoalList, PosList) :-
762 mkconj(Goal, M, Pos, GoalList, [], PosList, []).
763
764mkconj(Conj, M, term_position(0,0,0,0,[PA,PB]), GL, TG, PL, TP) :-
765 nonvar(Conj),
766 Conj = (A,B),
767 !,
768 mkconj(A, M, PA, GL, TGA, PL, TPA),
769 mkconj(B, M, PB, TGA, TG, TPA, TP).
770mkconj(A0, M, P0, [A|TG], TG, [P|TP], TP) :-
771 ubody(A, A0, M, P, P0),
772 !.
773mkconj(A0, M, P0, [RG|TG0], TG, [_|TP0], TP) :-
774 maybe_optimized(RG),
775 mkconj(A0, M, P0, TG0, TG, TP0, TP).
776
777maybe_optimized(debug(_,_,_)).
778maybe_optimized(assertion(_)).
779maybe_optimized(true).
780
784
785argpos(N, parentheses_term_position(_,_,PosIn), Pos) =>
786 argpos(N, PosIn, Pos).
787argpos(N, term_position(_,_,_,_,ArgPos), Pos) =>
788 nth1(N, ArgPos, Pos).
789argpos(_, _, _) => true.
790
791
792 795
805
806pce_method_clause(Head, Body, M:PlHead, PlBody, _, TermPos0, TermPos) :-
807 !,
808 pce_method_clause(Head, Body, PlBody, PlHead, M, TermPos0, TermPos).
809pce_method_clause(Head, Body,
810 send_implementation(_Id, Msg, Receiver), PlBody,
811 M, TermPos0, TermPos) :-
812 !,
813 debug(clause_info, 'send method ...', []),
814 arg(1, Head, Receiver),
815 functor(Head, _, Arity),
816 pce_method_head_arguments(2, Arity, Head, Msg),
817 debug(clause_info, 'head ...', []),
818 pce_method_body(Body, PlBody, M, TermPos0, TermPos).
819pce_method_clause(Head, Body,
820 get_implementation(_Id, Msg, Receiver, Result), PlBody,
821 M, TermPos0, TermPos) :-
822 !,
823 debug(clause_info, 'get method ...', []),
824 arg(1, Head, Receiver),
825 debug(clause_info, 'receiver ...', []),
826 functor(Head, _, Arity),
827 arg(Arity, Head, PceResult),
828 debug(clause_info, '~w?~n', [PceResult = Result]),
829 pce_unify_head_arg(PceResult, Result),
830 Ar is Arity - 1,
831 pce_method_head_arguments(2, Ar, Head, Msg),
832 debug(clause_info, 'head ...', []),
833 pce_method_body(Body, PlBody, M, TermPos0, TermPos).
834
835pce_method_head_arguments(N, Arity, Head, Msg) :-
836 N =< Arity,
837 !,
838 arg(N, Head, PceArg),
839 PLN is N - 1,
840 arg(PLN, Msg, PlArg),
841 pce_unify_head_arg(PceArg, PlArg),
842 debug(clause_info, '~w~n', [PceArg = PlArg]),
843 NextArg is N+1,
844 pce_method_head_arguments(NextArg, Arity, Head, Msg).
845pce_method_head_arguments(_, _, _, _).
846
847pce_unify_head_arg(V, A) :-
848 var(V),
849 !,
850 V = A.
851pce_unify_head_arg(A:_=_, A) :- !.
852pce_unify_head_arg(A:_, A).
853
866
867pce_method_body(A0, A, M, TermPos0, TermPos) :-
868 TermPos0 = term_position(F, T, FF, FT,
869 [ HeadPos,
870 BodyPos0
871 ]),
872 TermPos = term_position(F, T, FF, FT,
873 [ HeadPos,
874 term_position(0,0,0,0, [0-0,BodyPos])
875 ]),
876 pce_method_body2(A0, A, M, BodyPos0, BodyPos).
877
878
879pce_method_body2(::(_,A0), A, M, TermPos0, TermPos) :-
880 !,
881 TermPos0 = term_position(_, _, _, _, [_Cmt,BodyPos0]),
882 TermPos = BodyPos,
883 expand_goal(A0, A, M, BodyPos0, BodyPos).
884pce_method_body2(A0, A, M, TermPos0, TermPos) :-
885 A0 =.. [Func,B0,C0],
886 control_op(Func),
887 !,
888 A =.. [Func,B,C],
889 TermPos0 = term_position(F, T, FF, FT,
890 [ BP0,
891 CP0
892 ]),
893 TermPos = term_position(F, T, FF, FT,
894 [ BP,
895 CP
896 ]),
897 pce_method_body2(B0, B, M, BP0, BP),
898 expand_goal(C0, C, M, CP0, CP).
899pce_method_body2(A0, A, M, TermPos0, TermPos) :-
900 expand_goal(A0, A, M, TermPos0, TermPos).
901
902control_op(',').
903control_op((;)).
904control_op((->)).
905control_op((*->)).
906
907 910
923
924expand_goal(G, call(G), _, P, term_position(0,0,0,0,[P])) :-
925 var(G),
926 !.
927expand_goal(G, G1, _, P, P) :-
928 var(G),
929 !,
930 G1 = G.
931expand_goal(M0, M, Module, P0, P) :-
932 meta(Module, M0, S),
933 !,
934 P0 = term_position(F,T,FF,FT,PL0),
935 P = term_position(F,T,FF,FT,PL),
936 functor(M0, Functor, Arity),
937 functor(M, Functor, Arity),
938 expand_meta_args(PL0, PL, 1, S, Module, M0, M).
939expand_goal(A, B, Module, P0, P) :-
940 goal_expansion(A, B0, P0, P1),
941 !,
942 expand_goal(B0, B, Module, P1, P).
943expand_goal(A, A, _, P, P).
944
945expand_meta_args([], [], _, _, _, _, _).
946expand_meta_args([P0|T0], [P|T], I, S, Module, M0, M) :-
947 arg(I, M0, A0),
948 arg(I, M, A),
949 arg(I, S, AS),
950 expand_arg(AS, A0, A, Module, P0, P),
951 NI is I + 1,
952 expand_meta_args(T0, T, NI, S, Module, M0, M).
953
954expand_arg(0, A0, A, Module, P0, P) :-
955 !,
956 expand_goal(A0, A, Module, P0, P).
957expand_arg(_, A, A, _, P, P).
958
959meta(M, G, S) :- predicate_property(M:G, meta_predicate(S)).
960
961goal_expansion(send(R, Msg), send_class(R, _, SuperMsg), P, P) :-
962 compound(Msg),
963 Msg =.. [send_super, Selector | Args],
964 !,
965 SuperMsg =.. [Selector|Args].
966goal_expansion(get(R, Msg, A), get_class(R, _, SuperMsg, A), P, P) :-
967 compound(Msg),
968 Msg =.. [get_super, Selector | Args],
969 !,
970 SuperMsg =.. [Selector|Args].
971goal_expansion(send_super(R, Msg), send_class(R, _, Msg), P, P).
972goal_expansion(get_super(R, Msg, V), get_class(R, _, Msg, V), P, P).
973goal_expansion(SendSuperN, send_class(R, _, Msg), P, P) :-
974 compound(SendSuperN),
975 compound_name_arguments(SendSuperN, send_super, [R,Sel|Args]),
976 Msg =.. [Sel|Args].
977goal_expansion(SendN, send(R, Msg), P, P) :-
978 compound(SendN),
979 compound_name_arguments(SendN, send, [R,Sel|Args]),
980 atom(Sel), Args \== [],
981 Msg =.. [Sel|Args].
982goal_expansion(GetSuperN, get_class(R, _, Msg, Answer), P, P) :-
983 compound(GetSuperN),
984 compound_name_arguments(GetSuperN, get_super, [R,Sel|AllArgs]),
985 append(Args, [Answer], AllArgs),
986 Msg =.. [Sel|Args].
987goal_expansion(GetN, get(R, Msg, Answer), P, P) :-
988 compound(GetN),
989 compound_name_arguments(GetN, get, [R,Sel|AllArgs]),
990 append(Args, [Answer], AllArgs),
991 atom(Sel), Args \== [],
992 Msg =.. [Sel|Args].
993goal_expansion(G0, G, P, P) :-
994 user:goal_expansion(G0, G), 995 G0 \== G. 996
997
998 1001
1006
1007initialization_layout(File:Line, M:Goal0, Goal, TermPos) :-
1008 read_term_at_line(File, Line, M, Directive, DirectivePos, _),
1009 Directive = (:- initialization(ReadGoal)),
1010 DirectivePos = term_position(_, _, _, _, [InitPos]),
1011 InitPos = term_position(_, _, _, _, [GoalPos]),
1012 ( ReadGoal = M:_
1013 -> Goal = M:Goal0
1014 ; Goal = Goal0
1015 ),
1016 unify_body(ReadGoal, Goal, M, GoalPos, TermPos),
1017 !.
1018
1019
1020 1023
1024:- module_transparent
1025 predicate_name/2. 1026:- multifile
1027 user:prolog_predicate_name/2,
1028 user:prolog_clause_name/2. 1029
1030hidden_module(user).
1031hidden_module(system).
1032hidden_module(pce_principal). 1033hidden_module(Module) :- 1034 import_module(Module, system).
1035
1036thaffix(1, st) :- !.
1037thaffix(2, nd) :- !.
1038thaffix(_, th).
1039
1043
1044predicate_name(Predicate, PName) :-
1045 strip_module(Predicate, Module, Head),
1046 ( user:prolog_predicate_name(Module:Head, PName)
1047 -> true
1048 ; functor(Head, Name, Arity),
1049 ( hidden_module(Module)
1050 -> format(string(PName), '~q/~d', [Name, Arity])
1051 ; format(string(PName), '~q:~q/~d', [Module, Name, Arity])
1052 )
1053 ).
1054
1058
1059clause_name(Ref, Name) :-
1060 user:prolog_clause_name(Ref, Name),
1061 !.
1062clause_name(Ref, Name) :-
1063 nth_clause(Head, N, Ref),
1064 !,
1065 predicate_name(Head, PredName),
1066 thaffix(N, Th),
1067 format(string(Name), '~d-~w clause of ~w', [N, Th, PredName]).
1068clause_name(Ref, Name) :-
1069 clause_property(Ref, erased),
1070 !,
1071 clause_property(Ref, predicate(M:PI)),
1072 format(string(Name), 'erased clause from ~q', [M:PI]).
1073clause_name(_, '<meta-call>')