35
36:- module(rewrite_term,
37 [ rewrite_term/2, 38 rew_term_expansion/2,
39 rew_goal_expansion/2,
40
41 op(1200, xfx, (::=))
42 ]). 43:- autoload(library(occurs),[sub_term/2]). 44
45:- meta_predicate
46 rewrite_term(1, +). 47
48 51
52rew_term_expansion((Rule ::= RuleBody), (Head :- Body)) :-
53 translate(RuleBody, Term, Body0),
54 simplify(Body0, Body),
55 Rule =.. [Name|List],
56 Head =.. [Name,Term|List].
57
58rew_goal_expansion(rewrite_term(To, From), Goal) :-
59 nonvar(To),
60 To = \Rule,
61 callable(Rule),
62 Rule =.. [Name|List],
63 Goal =.. [Name,From|List].
64
65
66 69
73
74rewrite_term(M:T, From) :-
75 ( var(T)
76 -> From = T
77 ; T = \Rule
78 -> Rule =.. [Name|List],
79 Goal =.. [Name,From|List],
80 M:Goal
81 ; match(T, M, From)
82 ).
83
84match(Rule, M, From) :-
85 translate(Rule, From, Code),
86 M:Code.
87
88translate(Var, Var, true) :-
89 var(Var),
90 !.
91translate((\Command, !), Var, (Goal, !)) :-
92 !,
93 ( callable(Command),
94 Command =.. [Name|List]
95 -> Goal =.. [Name,Var|List]
96 ; Goal = rewrite(\Command, Var)
97 ).
98translate(\Command, Var, Goal) :-
99 !,
100 ( callable(Command),
101 Command =.. [Name|List]
102 -> Goal =.. [Name,Var|List]
103 ; Goal = rewrite(\Command, Var)
104 ).
105translate(Atomic, Atomic, true) :-
106 atomic(Atomic),
107 !.
108translate(C, _, Cmd) :-
109 command(C, Cmd),
110 !.
111translate((A, B), T, Code) :-
112 ( command(A, Cmd)
113 -> !, translate(B, T, C),
114 Code = (Cmd, C)
115 ; command(B, Cmd)
116 -> !, translate(A, T, C),
117 Code = (C, Cmd)
118 ).
119translate(Term0, Term, Command) :-
120 functor(Term0, Name, Arity),
121 functor(Term, Name, Arity),
122 translate_args(0, Arity, Term0, Term, Command).
123
124translate_args(N, N, _, _, true) :- !.
125translate_args(I0, Arity, T0, T1, (C0,C)) :-
126 I is I0 + 1,
127 arg(I, T0, A0),
128 arg(I, T1, A1),
129 translate(A0, A1, C0),
130 translate_args(I, Arity, T0, T1, C).
131
132command(0, _) :- 133 !,
134 fail.
135command({A}, A).
136command(!, !).
137
138 141
145
146simplify(V, V) :-
147 var(V),
148 !.
149simplify((A0,B), A) :-
150 B == true,
151 !,
152 simplify(A0, A).
153simplify((A,B0), B) :-
154 A == true,
155 !,
156 simplify(B0, B).
157simplify((A0, B0), C) :-
158 !,
159 simplify(A0, A),
160 simplify(B0, B),
161 ( ( A \== A0
162 ; B \== B0
163 )
164 -> simplify((A,B), C)
165 ; C = (A,B)
166 ).
167simplify(X, X).
168
169 172
173:- multifile
174 prolog:called_by/2. 175
176prolog:called_by(rewrite(Spec, _Term), Called) :-
177 findall(G+1, sub_term(\G, Spec), Called)