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:- encoding(utf8).
47:- use_module(library(debug),[debugging/1,debug/3]). 48:- autoload(library(listing),[portray_clause/1]). 49:- autoload(library(lists),[append/3]). 50:- autoload(library(occurs),[sub_term/2]). 51:- autoload(library(option),[option/3]). 52:- autoload(library(prolog_source),[read_source_term_at_location/3]). 53
54
55:- public 56 unify_term/2,
57 make_varnames/5,
58 do_make_varnames/3. 59
60:- multifile
61 unify_goal/5, 62 unify_clause_hook/5,
63 make_varnames_hook/5,
64 open_source/2. 65
66:- predicate_options(prolog_clause:clause_info/5, 5,
67 [ head(-any),
68 body(-any),
69 variable_names(-list)
70 ]). 71
82
109
110clause_info(ClauseRef, File, TermPos, NameOffset) :-
111 clause_info(ClauseRef, File, TermPos, NameOffset, []).
112
113clause_info(ClauseRef, File, TermPos, NameOffset, Options) :-
114 ( debugging(clause_info)
115 -> clause_name(ClauseRef, Name),
116 debug(clause_info, 'clause_info(~w) (~w)... ',
117 [ClauseRef, Name])
118 ; true
119 ),
120 clause_property(ClauseRef, file(File)),
121 File \== user, 122 '$clause'(Head0, Body, ClauseRef, VarOffset),
123 option(head(Head0), Options, _),
124 option(body(Body), Options, _),
125 ( module_property(Module, file(File))
126 -> true
127 ; strip_module(user:Head0, Module, _)
128 ),
129 unqualify(Head0, Module, Head),
130 ( Body == true
131 -> DecompiledClause = Head
132 ; DecompiledClause = (Head :- Body)
133 ),
134 clause_property(ClauseRef, line_count(LineNo)),
135 debug(clause_info, 'from ~w:~d ... ', [File, LineNo]),
136 read_term_at_line(File, LineNo, Module, Clause, TermPos0, VarNames),
137 option(variable_names(VarNames), Options, _),
138 debug(clause_info, 'read ...', []),
139 unify_clause(Clause, DecompiledClause, Module, TermPos0, TermPos),
140 debug(clause_info, 'unified ...', []),
141 make_varnames(Clause, DecompiledClause, VarOffset, VarNames, NameOffset),
142 debug(clause_info, 'got names~n', []),
143 !.
144
145unqualify(Module:Head, Module, Head) :-
146 !.
147unqualify(Head, _, Head).
148
149
160
161unify_term(X, X) :- !.
162unify_term(X1, X2) :-
163 compound(X1),
164 compound(X2),
165 functor(X1, F, Arity),
166 functor(X2, F, Arity),
167 !,
168 unify_args(0, Arity, X1, X2).
169unify_term(X, Y) :-
170 float(X), float(Y),
171 !.
172unify_term(X, '$BLOB'(_)) :-
173 blob(X, _),
174 \+ atom(X).
175unify_term(X, Y) :-
176 string(X),
177 is_list(Y),
178 string_codes(X, Y),
179 !.
180unify_term(_, Y) :-
181 Y == '...',
182 !. 183unify_term(_, Y) :-
184 Y == '…',
185 !. 186unify_term(_:X, Y) :-
187 unify_term(X, Y),
188 !.
189unify_term(X, _:Y) :-
190 unify_term(X, Y),
191 !.
192unify_term(X, Y) :-
193 format('[INTERNAL ERROR: Diff:~n'),
194 portray_clause(X),
195 format('~N*** <->~n'),
196 portray_clause(Y),
197 break.
198
199unify_args(N, N, _, _) :- !.
200unify_args(I, Arity, T1, T2) :-
201 A is I + 1,
202 arg(A, T1, A1),
203 arg(A, T2, A2),
204 unify_term(A1, A2),
205 unify_args(A, Arity, T1, T2).
206
207
212
213read_term_at_line(File, Line, Module, Clause, TermPos, VarNames) :-
214 setup_call_cleanup(
215 '$push_input_context'(clause_info),
216 read_term_at_line_2(File, Line, Module, Clause, TermPos, VarNames),
217 '$pop_input_context').
218
219read_term_at_line_2(File, Line, Module, Clause, TermPos, VarNames) :-
220 catch(try_open_source(File, In), error(_,_), fail),
221 set_stream(In, newline(detect)),
222 call_cleanup(
223 read_source_term_at_location(
224 In, Clause,
225 [ line(Line),
226 module(Module),
227 subterm_positions(TermPos),
228 variable_names(VarNames)
229 ]),
230 close(In)).
231
242
243:- public try_open_source/2. 244
245try_open_source(File, In) :-
246 open_source(File, In),
247 !.
248try_open_source(File, In) :-
249 open(File, read, In, [reposition(true)]).
250
251
267
268make_varnames(ReadClause, DecompiledClause, Offsets, Names, Term) :-
269 make_varnames_hook(ReadClause, DecompiledClause, Offsets, Names, Term),
270 !.
271make_varnames(ReadClause, _, Offsets, Names, Bindings) :-
272 dcg_head(ReadClause, Head),
273 !,
274 functor(Head, _, Arity),
275 In is Arity,
276 memberchk(In=IVar, Offsets),
277 Names1 = ['<DCG_list>'=IVar|Names],
278 Out is Arity + 1,
279 memberchk(Out=OVar, Offsets),
280 Names2 = ['<DCG_tail>'=OVar|Names1],
281 make_varnames(xx, xx, Offsets, Names2, Bindings).
282make_varnames(_, _, Offsets, Names, Bindings) :-
283 length(Offsets, L),
284 functor(Bindings, varnames, L),
285 do_make_varnames(Offsets, Names, Bindings).
286
287dcg_head((Head,_ --> _Body), Head).
288dcg_head((Head --> _Body), Head).
289dcg_head((Head,_ ==> _Body), Head).
290dcg_head((Head ==> _Body), Head).
291
292do_make_varnames([], _, _).
293do_make_varnames([N=Var|TO], Names, Bindings) :-
294 ( find_varname(Var, Names, Name)
295 -> true
296 ; Name = '_'
297 ),
298 AN is N + 1,
299 arg(AN, Bindings, Name),
300 do_make_varnames(TO, Names, Bindings).
301
302find_varname(Var, [Name = TheVar|_], Name) :-
303 Var == TheVar,
304 !.
305find_varname(Var, [_|T], Name) :-
306 find_varname(Var, T, Name).
307
328
329unify_clause(Read, _, _, _, _) :-
330 var(Read),
331 !,
332 fail.
333unify_clause((RHead :- RBody), (CHead :- CBody), Module, TermPos1, TermPos) :-
334 '$expand':f2_pos(TermPos1, HPos, BPos1,
335 TermPos2, HPos, BPos2),
336 inlined_unification(RBody, CBody, RBody1, CBody1, RHead,
337 BPos1, BPos2),
338 RBody1 \== RBody,
339 !,
340 unify_clause2((RHead :- RBody1), (CHead :- CBody1), Module,
341 TermPos2, TermPos).
342unify_clause(Read, Decompiled, _, TermPos, TermPos) :-
343 Read =@= Decompiled,
344 !,
345 Read = Decompiled.
346unify_clause(Read, Decompiled, Module, TermPos0, TermPos) :-
347 unify_clause_hook(Read, Decompiled, Module, TermPos0, TermPos),
348 !.
349 350unify_clause(:->(Head, Body), (PlHead :- PlBody), M, TermPos0, TermPos) :-
351 !,
352 pce_method_clause(Head, Body, PlHead, PlBody, M, TermPos0, TermPos).
353 354unify_clause(:<-(Head, Body), (PlHead :- PlBody), M, TermPos0, TermPos) :-
355 !,
356 pce_method_clause(Head, Body, PlHead, PlBody, M, TermPos0, TermPos).
357 358unify_clause((TH :- RBody), (CH :- !, CBody), Module, TP0, TP) :-
359 plunit_source_head(TH),
360 plunit_compiled_head(CH),
361 !,
362 TP0 = term_position(F,T,FF,FT,[HP,BP0]),
363 ubody(RBody, CBody, Module, BP0, BP),
364 TP = term_position(F,T,FF,FT,[HP,term_position(0,0,0,0,[FF-FT,BP])]).
365 366unify_clause((Head :- Read),
367 (Head :- _M:Compiled), Module, TermPos0, TermPos) :-
368 unify_clause2((Head :- Read), (Head :- Compiled), Module, TermPos0, TermPos1),
369 TermPos1 = term_position(TA,TZ,FA,FZ,[PH,PB]),
370 TermPos = term_position(TA,TZ,FA,FZ,
371 [ PH,
372 term_position(0,0,0,0,[0-0,PB])
373 ]).
374 375unify_clause(Read, Compiled1, Module, TermPos0, TermPos) :-
376 Read = (_ --> Terminal0, _),
377 ( is_list(Terminal0)
378 -> Terminal = Terminal0
379 ; string(Terminal0)
380 -> string_codes(Terminal0, Terminal)
381 ),
382 ci_expand(Read, Compiled2, Module, TermPos0, TermPos1),
383 ( dcg_unify_in_head(Compiled2, Compiled3)
384 -> true
385 ; Compiled2 = (DH :- _CBody),
386 functor(DH, _, Arity),
387 DArg is Arity - 1,
388 append(Terminal, _Tail, List),
389 arg(DArg, DH, List),
390 Compiled3 = Compiled2
391 ),
392 TermPos1 = term_position(F,T,FF,FT,[ HP,
393 term_position(_,_,_,_,[_,BP])
394 ]),
395 !,
396 TermPos2 = term_position(F,T,FF,FT,[ HP, BP ]),
397 match_module(Compiled3, Compiled1, Module, TermPos2, TermPos).
398 399unify_clause((Head,RCond => Body), (CHead :- CCondAndBody), Module,
400 term_position(F,T,FF,FT,
401 [ term_position(_,_,_,_,[HP,CP]),
402 BP
403 ]),
404 TermPos) :-
405 split_on_cut(CCondAndBody, CCond, CBody0),
406 !,
407 inlined_unification(RCond, CCond, RCond1, CCond1, Head, CP, CP1),
408 TermPos1 = term_position(F,T,FF,FT, [HP, BP1]),
409 BP2 = term_position(_,_,_,_, [FF-FT, BP]), 410 ( CCond1 == true 411 -> BP1 = BP2, 412 unify_clause2((Head :- !, Body), (CHead :- !, CBody0),
413 Module, TermPos1, TermPos)
414 ; mkconj_pos(RCond1, CP1, (!,Body), BP2, RBody, BP1),
415 mkconj_npos(CCond1, (!,CBody0), CBody),
416 unify_clause2((Head :- RBody), (CHead :- CBody),
417 Module, TermPos1, TermPos)
418 ).
419unify_clause((Head => Body), Compiled1, Module, TermPos0, TermPos) :-
420 !,
421 unify_clause2((Head :- Body), Compiled1, Module, TermPos0, TermPos).
422unify_clause(Read, Compiled1, Module, TermPos0, TermPos) :-
423 Read = (_ ==> _),
424 ci_expand(Read, Compiled2, Module, TermPos0, TermPos1),
425 Compiled2 \= (_ ==> _),
426 !,
427 unify_clause(Compiled2, Compiled1, Module, TermPos1, TermPos).
428unify_clause(Read, Decompiled, Module, TermPos0, TermPos) :-
429 unify_clause2(Read, Decompiled, Module, TermPos0, TermPos).
430
431dcg_unify_in_head((Head :- L1=L2, Body), (Head :- Body)) :-
432 functor(Head, _, Arity),
433 DArg is Arity - 1,
434 arg(DArg, Head, L0),
435 L0 == L1,
436 L1 = L2.
437
439mkconj_pos((A,B), term_position(F,T,FF,FT,[PA,PB]), Ex, ExPos, Code, Pos) =>
440 Code = (A,B1),
441 Pos = term_position(F,T,FF,FT,[PA,PB1]),
442 mkconj_pos(B, PB, Ex, ExPos, B1, PB1).
443mkconj_pos(Last, LastPos, Ex, ExPos, Code, Pos) =>
444 Code = (Last,Ex),
445 Pos = term_position(_,_,_,_,[LastPos,ExPos]).
446
448mkconj_npos((A,B), Ex, Code) =>
449 Code = (A,B1),
450 mkconj_npos(B, Ex, B1).
451mkconj_npos(A, Ex, Code) =>
452 Code = (A,Ex).
453
457
458unify_clause2(Read, Decompiled, _, TermPos, TermPos) :-
459 Read =@= Decompiled,
460 !,
461 Read = Decompiled.
462unify_clause2(Read, Compiled1, Module, TermPos0, TermPos) :-
463 ci_expand(Read, Compiled2, Module, TermPos0, TermPos1),
464 match_module(Compiled2, Compiled1, Module, TermPos1, TermPos),
465 !.
466unify_clause2(_, _, _, _, _) :- 467 debug(clause_info, 'Could not unify clause', []),
468 fail.
469
470unify_clause_head(H1, H2) :-
471 strip_module(H1, _, H),
472 strip_module(H2, _, H).
473
474plunit_source_head(test(_,_)) => true.
475plunit_source_head(test(_)) => true.
476plunit_source_head(_) => fail.
477
478plunit_compiled_head(_:'unit body'(_, _)) => true.
479plunit_compiled_head('unit body'(_, _)) => true.
480plunit_compiled_head(_) => fail.
481
486
487inlined_unification((V=T,RBody0), (CV=CT,CBody0),
488 RBody, CBody, RHead, BPos1, BPos),
489 inlineable_head_var(RHead, V2),
490 V == V2,
491 (V=T) =@= (CV=CT) =>
492 argpos(2, BPos1, BPos2),
493 inlined_unification(RBody0, CBody0, RBody, CBody, RHead, BPos2, BPos).
494inlined_unification((V=T), (CV=CT),
495 RBody, CBody, RHead, BPos1, BPos),
496 inlineable_head_var(RHead, V2),
497 V == V2,
498 (V=T) =@= (CV=CT) =>
499 RBody = true,
500 CBody = true,
501 argpos(2, BPos1, BPos).
502inlined_unification((V=T,RBody0), CBody0,
503 RBody, CBody, RHead, BPos1, BPos),
504 inlineable_head_var(RHead, V2),
505 V == V2,
506 \+ (CBody0 = (G1,_), G1 =@= (V=T)) =>
507 argpos(2, BPos1, BPos2),
508 inlined_unification(RBody0, CBody0, RBody, CBody, RHead, BPos2, BPos).
509inlined_unification((V=_), true,
510 RBody, CBody, RHead, BPos1, BPos),
511 inlineable_head_var(RHead, V2),
512 V == V2 =>
513 RBody = true,
514 CBody = true,
515 argpos(2, BPos1, BPos).
516inlined_unification(RBody0, CBody0, RBody, CBody, _RHead,
517 BPos0, BPos) =>
518 RBody = RBody0,
519 BPos = BPos0,
520 CBody = CBody0.
521
526
527inlineable_head_var(Head, Var) :-
528 compound(Head),
529 arg(_, Head, Var).
530
531split_on_cut((Cond0,!,Body0), Cond, Body) =>
532 Cond = Cond0,
533 Body = Body0.
534split_on_cut((!,Body0), Cond, Body) =>
535 Cond = true,
536 Body = Body0.
537split_on_cut((A,B), Cond, Body) =>
538 Cond = (A,Cond1),
539 split_on_cut(B, Cond1, Body).
540split_on_cut(_, _, _) =>
541 fail.
542
543ci_expand(Read, Compiled, Module, TermPos0, TermPos) :-
544 catch(setup_call_cleanup(
545 ( set_xref_flag(OldXRef),
546 '$set_source_module'(Old, Module)
547 ),
548 expand_term(Read, TermPos0, Compiled, TermPos),
549 ( '$set_source_module'(Old),
550 set_prolog_flag(xref, OldXRef)
551 )),
552 E,
553 expand_failed(E, Read)),
554 compound(TermPos), 555 arg(1, TermPos, A1), nonvar(A1),
556 arg(2, TermPos, A2), nonvar(A2).
557
558set_xref_flag(Value) :-
559 current_prolog_flag(xref, Value),
560 !,
561 set_prolog_flag(xref, true).
562set_xref_flag(false) :-
563 create_prolog_flag(xref, true, [type(boolean)]).
564
565match_module((H1 :- B1), (H2 :- B2), Module, Pos0, Pos) :-
566 !,
567 unify_clause_head(H1, H2),
568 unify_body(B1, B2, Module, Pos0, Pos).
569match_module((H1 :- B1), H2, _Module, Pos0, Pos) :-
570 B1 == true,
571 unify_clause_head(H1, H2),
572 Pos = Pos0,
573 !.
574match_module(H1, H2, _, Pos, Pos) :- 575 unify_clause_head(H1, H2).
576
580
581expand_failed(E, Read) :-
582 debugging(clause_info),
583 message_to_string(E, Msg),
584 debug(clause_info, 'Term-expand ~p failed: ~w', [Read, Msg]),
585 fail.
586
593
594unify_body(B, C, _, Pos, Pos) :-
595 B =@= C, B = C,
596 does_not_dcg_after_binding(B, Pos),
597 !.
598unify_body(R, D, Module,
599 term_position(F,T,FF,FT,[HP,BP0]),
600 term_position(F,T,FF,FT,[HP,BP])) :-
601 ubody(R, D, Module, BP0, BP).
602
610
611does_not_dcg_after_binding(B, Pos) :-
612 \+ sub_term(brace_term_position(_,_,_), Pos),
613 \+ (sub_term((Cut,_=_), B), Cut == !),
614 !.
615
616
624
630
637
638ubody(B, DB, _, P, P) :-
639 var(P), 640 !,
641 B = DB.
642ubody(B, C, _, P, P) :-
643 B =@= C, B = C,
644 does_not_dcg_after_binding(B, P),
645 !.
646ubody(X0, X, M, parentheses_term_position(_, _, P0), P) :-
647 !,
648 ubody(X0, X, M, P0, P).
649ubody(X, Y, _, 650 Pos,
651 term_position(From, To, From, To, [Pos])) :-
652 nonvar(Y),
653 Y = call(X),
654 !,
655 arg(1, Pos, From),
656 arg(2, Pos, To).
657ubody(A, B, _, P1, P2) :-
658 nonvar(A), A = (_=_),
659 nonvar(B), B = (LB=RB),
660 A =@= (RB=LB),
661 !,
662 P1 = term_position(F,T, FF,FT, [PL,PR]),
663 P2 = term_position(F,T, FF,FT, [PR,PL]).
664ubody(A, B, _, P1, P2) :-
665 nonvar(A), A = (_==_),
666 nonvar(B), B = (LB==RB),
667 A =@= (RB==LB),
668 !,
669 P1 = term_position(F,T, FF,FT, [PL,PR]),
670 P2 = term_position(F,T, FF,FT, [PR,PL]).
671ubody(B, D, _, term_position(_,_,_,_,[_,RP]), TPOut) :-
672 nonvar(B), B = M:R,
673 ubody(R, D, M, RP, TPOut).
674ubody(B, D, M, term_position(_,_,_,_,[RP0,RP1]), TPOut) :-
675 nonvar(B), B = (B0,B1),
676 ( maybe_optimized(B0),
677 ubody(B1, D, M, RP1, TPOut)
678 -> true
679 ; maybe_optimized(B1),
680 ubody(B0, D, M, RP0, TPOut)
681 ),
682 !.
683ubody(B0, B, M,
684 brace_term_position(F,T,A0),
685 Pos) :-
686 B0 = (_,_=_),
687 !,
688 T1 is T - 1,
689 ubody(B0, B, M,
690 term_position(F,T,
691 F,T,
692 [A0,T1-T]),
693 Pos).
694ubody(B0, B, M,
695 brace_term_position(F,T,A0),
696 term_position(F,T,F,T,[A])) :-
697 !,
698 ubody(B0, B, M, A0, A).
699ubody(C0, C, M, P0, P) :-
700 nonvar(C0), nonvar(C),
701 C0 = (_,_), C = (_,_),
702 !,
703 conj(C0, P0, GL, PL),
704 mkconj(C, M, P, GL, PL).
705ubody(Read, Decompiled, Module, TermPosRead, TermPosDecompiled) :-
706 unify_goal(Read, Decompiled, Module, TermPosRead, TermPosDecompiled),
707 !.
708ubody(X0, X, M,
709 term_position(F,T,FF,TT,PA0),
710 term_position(F,T,FF,TT,PA)) :-
711 callable(X0),
712 callable(X),
713 meta(M, X0, S),
714 !,
715 X0 =.. [_|A0],
716 X =.. [_|A],
717 S =.. [_|AS],
718 ubody_list(A0, A, AS, M, PA0, PA).
719ubody(X0, X, M,
720 term_position(F,T,FF,TT,PA0),
721 term_position(F,T,FF,TT,PA)) :-
722 expand_goal(X0, X1, M, PA0, PA),
723 X1 =@= X,
724 X1 = X.
725
726 727ubody(_=_, true, _, 728 term_position(F,T,_FF,_TT,_PA),
729 F-T) :- !.
730ubody(_==_, fail, _, 731 term_position(F,T,_FF,_TT,_PA),
732 F-T) :- !.
733ubody(A1=B1, B2=A2, _, 734 term_position(F,T,FF,TT,[PA1,PA2]),
735 term_position(F,T,FF,TT,[PA2,PA1])) :-
736 var(B1), var(B2),
737 (A1==B1) =@= (B2==A2),
738 !,
739 A1 = A2, B1=B2.
740ubody(A1==B1, B2==A2, _, 741 term_position(F,T,FF,TT,[PA1,PA2]),
742 term_position(F,T,FF,TT,[PA2,PA1])) :-
743 var(B1), var(B2),
744 (A1==B1) =@= (B2==A2),
745 !,
746 A1 = A2, B1=B2.
747ubody(A is B - C, A is B + C2, _, Pos, Pos) :-
748 integer(C),
749 C2 =:= -C,
750 !.
751
752ubody_list([], [], [], _, [], []).
753ubody_list([G0|T0], [G|T], [AS|ASL], M, [PA0|PAT0], [PA|PAT]) :-
754 ubody_elem(AS, G0, G, M, PA0, PA),
755 ubody_list(T0, T, ASL, M, PAT0, PAT).
756
757ubody_elem(0, G0, G, M, PA0, PA) :-
758 !,
759 ubody(G0, G, M, PA0, PA).
760ubody_elem(_, G, G, _, PA, PA).
761
766
767conj(Goal, Pos, GoalList, PosList) :-
768 conj(Goal, Pos, GoalList, [], PosList, []).
769
770conj((A,B), term_position(_,_,_,_,[PA,PB]), GL, TG, PL, TP) :-
771 !,
772 conj(A, PA, GL, TGA, PL, TPA),
773 conj(B, PB, TGA, TG, TPA, TP).
774conj((A,B), brace_term_position(_,T,PA), GL, TG, PL, TP) :-
775 B = (_=_),
776 !,
777 conj(A, PA, GL, TGA, PL, TPA),
778 T1 is T - 1,
779 conj(B, T1-T, TGA, TG, TPA, TP).
780conj(A, parentheses_term_position(_,_,Pos), GL, TG, PL, TP) :-
781 nonvar(Pos),
782 !,
783 conj(A, Pos, GL, TG, PL, TP).
784conj((!,(S=SR)), F-T, [!,S=SR|TG], TG, [F-T,F1-T1|TP], TP) :-
785 F1 is F+1,
786 T1 is T+1.
787conj(A, P, [A|TG], TG, [P|TP], TP).
788
789
791
792mkconj(Goal, M, Pos, GoalList, PosList) :-
793 mkconj(Goal, M, Pos, GoalList, [], PosList, []).
794
795mkconj(Conj, M, term_position(0,0,0,0,[PA,PB]), GL, TG, PL, TP) :-
796 nonvar(Conj),
797 Conj = (A,B),
798 !,
799 mkconj(A, M, PA, GL, TGA, PL, TPA),
800 mkconj(B, M, PB, TGA, TG, TPA, TP).
801mkconj(A0, M, P0, [A|TG], TG, [P|TP], TP) :-
802 ubody(A, A0, M, P, P0),
803 !.
804mkconj(A0, M, P0, [RG|TG0], TG, [_|TP0], TP) :-
805 maybe_optimized(RG),
806 mkconj(A0, M, P0, TG0, TG, TP0, TP).
807
808maybe_optimized(debug(_,_,_)).
809maybe_optimized(assertion(_)).
810maybe_optimized(true).
811
815
816argpos(N, parentheses_term_position(_,_,PosIn), Pos) =>
817 argpos(N, PosIn, Pos).
818argpos(N, term_position(_,_,_,_,ArgPos), Pos) =>
819 nth1(N, ArgPos, Pos).
820argpos(_, _, _) => true.
821
822
823 826
836
837pce_method_clause(Head, Body, M:PlHead, PlBody, _, TermPos0, TermPos) :-
838 !,
839 pce_method_clause(Head, Body, PlBody, PlHead, M, TermPos0, TermPos).
840pce_method_clause(Head, Body,
841 send_implementation(_Id, Msg, Receiver), PlBody,
842 M, TermPos0, TermPos) :-
843 !,
844 debug(clause_info, 'send method ...', []),
845 arg(1, Head, Receiver),
846 functor(Head, _, Arity),
847 pce_method_head_arguments(2, Arity, Head, Msg),
848 debug(clause_info, 'head ...', []),
849 pce_method_body(Body, PlBody, M, TermPos0, TermPos).
850pce_method_clause(Head, Body,
851 get_implementation(_Id, Msg, Receiver, Result), PlBody,
852 M, TermPos0, TermPos) :-
853 !,
854 debug(clause_info, 'get method ...', []),
855 arg(1, Head, Receiver),
856 debug(clause_info, 'receiver ...', []),
857 functor(Head, _, Arity),
858 arg(Arity, Head, PceResult),
859 debug(clause_info, '~w?~n', [PceResult = Result]),
860 pce_unify_head_arg(PceResult, Result),
861 Ar is Arity - 1,
862 pce_method_head_arguments(2, Ar, Head, Msg),
863 debug(clause_info, 'head ...', []),
864 pce_method_body(Body, PlBody, M, TermPos0, TermPos).
865
866pce_method_head_arguments(N, Arity, Head, Msg) :-
867 N =< Arity,
868 !,
869 arg(N, Head, PceArg),
870 PLN is N - 1,
871 arg(PLN, Msg, PlArg),
872 pce_unify_head_arg(PceArg, PlArg),
873 debug(clause_info, '~w~n', [PceArg = PlArg]),
874 NextArg is N+1,
875 pce_method_head_arguments(NextArg, Arity, Head, Msg).
876pce_method_head_arguments(_, _, _, _).
877
878pce_unify_head_arg(V, A) :-
879 var(V),
880 !,
881 V = A.
882pce_unify_head_arg(A:_=_, A) :- !.
883pce_unify_head_arg(A:_, A).
884
897
898pce_method_body(A0, A, M, TermPos0, TermPos) :-
899 TermPos0 = term_position(F, T, FF, FT,
900 [ HeadPos,
901 BodyPos0
902 ]),
903 TermPos = term_position(F, T, FF, FT,
904 [ HeadPos,
905 term_position(0,0,0,0, [0-0,BodyPos])
906 ]),
907 pce_method_body2(A0, A, M, BodyPos0, BodyPos).
908
909
910pce_method_body2(::(_,A0), A, M, TermPos0, TermPos) :-
911 !,
912 TermPos0 = term_position(_, _, _, _, [_Cmt,BodyPos0]),
913 TermPos = BodyPos,
914 expand_goal(A0, A, M, BodyPos0, BodyPos).
915pce_method_body2(A0, A, M, TermPos0, TermPos) :-
916 A0 =.. [Func,B0,C0],
917 control_op(Func),
918 !,
919 A =.. [Func,B,C],
920 TermPos0 = term_position(F, T, FF, FT,
921 [ BP0,
922 CP0
923 ]),
924 TermPos = term_position(F, T, FF, FT,
925 [ BP,
926 CP
927 ]),
928 pce_method_body2(B0, B, M, BP0, BP),
929 expand_goal(C0, C, M, CP0, CP).
930pce_method_body2(A0, A, M, TermPos0, TermPos) :-
931 expand_goal(A0, A, M, TermPos0, TermPos).
932
933control_op(',').
934control_op((;)).
935control_op((->)).
936control_op((*->)).
937
938 941
954
955expand_goal(G, call(G), _, P, term_position(0,0,0,0,[P])) :-
956 var(G),
957 !.
958expand_goal(G, G1, _, P, P) :-
959 var(G),
960 !,
961 G1 = G.
962expand_goal(M0, M, Module, P0, P) :-
963 meta(Module, M0, S),
964 !,
965 P0 = term_position(F,T,FF,FT,PL0),
966 P = term_position(F,T,FF,FT,PL),
967 functor(M0, Functor, Arity),
968 functor(M, Functor, Arity),
969 expand_meta_args(PL0, PL, 1, S, Module, M0, M).
970expand_goal(A, B, Module, P0, P) :-
971 goal_expansion(A, B0, P0, P1),
972 !,
973 expand_goal(B0, B, Module, P1, P).
974expand_goal(A, A, _, P, P).
975
976expand_meta_args([], [], _, _, _, _, _).
977expand_meta_args([P0|T0], [P|T], I, S, Module, M0, M) :-
978 arg(I, M0, A0),
979 arg(I, M, A),
980 arg(I, S, AS),
981 expand_arg(AS, A0, A, Module, P0, P),
982 NI is I + 1,
983 expand_meta_args(T0, T, NI, S, Module, M0, M).
984
985expand_arg(0, A0, A, Module, P0, P) :-
986 !,
987 expand_goal(A0, A, Module, P0, P).
988expand_arg(_, A, A, _, P, P).
989
990meta(M, G, S) :- predicate_property(M:G, meta_predicate(S)).
991
992goal_expansion(send(R, Msg), send_class(R, _, SuperMsg), P, P) :-
993 compound(Msg),
994 Msg =.. [send_super, Selector | Args],
995 !,
996 SuperMsg =.. [Selector|Args].
997goal_expansion(get(R, Msg, A), get_class(R, _, SuperMsg, A), P, P) :-
998 compound(Msg),
999 Msg =.. [get_super, Selector | Args],
1000 !,
1001 SuperMsg =.. [Selector|Args].
1002goal_expansion(send_super(R, Msg), send_class(R, _, Msg), P, P).
1003goal_expansion(get_super(R, Msg, V), get_class(R, _, Msg, V), P, P).
1004goal_expansion(SendSuperN, send_class(R, _, Msg), P, P) :-
1005 compound(SendSuperN),
1006 compound_name_arguments(SendSuperN, send_super, [R,Sel|Args]),
1007 Msg =.. [Sel|Args].
1008goal_expansion(SendN, send(R, Msg), P, P) :-
1009 compound(SendN),
1010 compound_name_arguments(SendN, send, [R,Sel|Args]),
1011 atom(Sel), Args \== [],
1012 Msg =.. [Sel|Args].
1013goal_expansion(GetSuperN, get_class(R, _, Msg, Answer), P, P) :-
1014 compound(GetSuperN),
1015 compound_name_arguments(GetSuperN, get_super, [R,Sel|AllArgs]),
1016 append(Args, [Answer], AllArgs),
1017 Msg =.. [Sel|Args].
1018goal_expansion(GetN, get(R, Msg, Answer), P, P) :-
1019 compound(GetN),
1020 compound_name_arguments(GetN, get, [R,Sel|AllArgs]),
1021 append(Args, [Answer], AllArgs),
1022 atom(Sel), Args \== [],
1023 Msg =.. [Sel|Args].
1024goal_expansion(G0, G, P, P) :-
1025 user:goal_expansion(G0, G), 1026 G0 \== G. 1027
1028
1029 1032
1037
1038initialization_layout(File:Line, M:Goal0, Goal, TermPos) :-
1039 read_term_at_line(File, Line, M, Directive, DirectivePos, _),
1040 Directive = (:- initialization(ReadGoal)),
1041 DirectivePos = term_position(_, _, _, _, [InitPos]),
1042 InitPos = term_position(_, _, _, _, [GoalPos]),
1043 ( ReadGoal = M:_
1044 -> Goal = M:Goal0
1045 ; Goal = Goal0
1046 ),
1047 unify_body(ReadGoal, Goal, M, GoalPos, TermPos),
1048 !.
1049
1050
1051 1054
1055:- module_transparent
1056 predicate_name/2. 1057:- multifile
1058 user:prolog_predicate_name/2,
1059 user:prolog_clause_name/2. 1060
1061hidden_module(user).
1062hidden_module(system).
1063hidden_module(pce_principal). 1064hidden_module(Module) :- 1065 import_module(Module, system).
1066
1067thaffix(1, st) :- !.
1068thaffix(2, nd) :- !.
1069thaffix(_, th).
1070
1074
1075predicate_name(Predicate, PName) :-
1076 strip_module(Predicate, Module, Head),
1077 ( user:prolog_predicate_name(Module:Head, PName)
1078 -> true
1079 ; functor(Head, Name, Arity),
1080 ( hidden_module(Module)
1081 -> format(string(PName), '~q/~d', [Name, Arity])
1082 ; format(string(PName), '~q:~q/~d', [Module, Name, Arity])
1083 )
1084 ).
1085
1089
1090clause_name(Ref, Name) :-
1091 user:prolog_clause_name(Ref, Name),
1092 !.
1093clause_name(Ref, Name) :-
1094 nth_clause(Head, N, Ref),
1095 !,
1096 predicate_name(Head, PredName),
1097 thaffix(N, Th),
1098 format(string(Name), '~d-~w clause of ~w', [N, Th, PredName]).
1099clause_name(Ref, Name) :-
1100 clause_property(Ref, erased),
1101 !,
1102 clause_property(Ref, predicate(M:PI)),
1103 format(string(Name), 'erased clause from ~q', [M:PI]).
1104clause_name(_, '<meta-call>')