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