40
41:- module(clpcd_store,
42 [
43 add_linear_11/4,
44 add_linear_f1/5,
45 add_linear_ff/6,
46 normalize_scalar/2,
47 delete_factor/4,
48 mult_linear_factor/4,
49 nf_rhs_x/5,
50 isolate/4,
51 nf_substitute/5,
52 mult_hom/4,
53 nf_coeff_of/3,
54 renormalize/3
55 ]). 56
57:- use_module(library(clpcd/domain_ops)). 58
62
63normalize_scalar(S,[S,0]).
64
72
73renormalize(CLP, [I,R|Hom], Lin) :-
74 length(Hom,Len),
75 renormalize_log(Len, CLP, Hom, [], Lin0),
76 add_linear_11(CLP, [I,R], Lin0, Lin).
77
82
83renormalize_log(1, _, [Term|Xs], Xs, Lin) :-
84 !,
85 Term = l(X*_,_),
86 renormalize_log_one(X,Term,Lin).
87renormalize_log(2, CLP, [A,B|Xs], Xs, Lin) :-
88 !,
89 A = l(X*_,_),
90 B = l(Y*_,_),
91 renormalize_log_one(X,A,LinA),
92 renormalize_log_one(Y,B,LinB),
93 add_linear_11(CLP, LinA, LinB, Lin).
94renormalize_log(N, CLP, L0, L2, Lin) :-
95 P is N>>1,
96 Q is N-P,
97 renormalize_log(P, CLP, L0, L1, Lp),
98 renormalize_log(Q, CLP, L1, L2, Lq),
99 add_linear_11(CLP, Lp, Lq, Lin).
100
104
105renormalize_log_one(X,Term,Res) :-
106 var(X),
107 Term = l(X*K,_),
108 get_attr(X,clpcd_itf,Att),
109 arg(5,Att,order(OrdX)), 110 Res = [0,0,l(X*K,OrdX)].
111renormalize_log_one(X,Term,Res) :-
112 nonvar(X),
113 Term = l(X*K,_),
114 Xk is X*K,
115 normalize_scalar(Xk,Res).
116
118
123
124add_linear_ff(CLP, LinA, Ka, LinB, Kb, LinC) :-
125 LinA = [Ia,Ra|Ha],
126 LinB = [Ib,Rb|Hb],
127 LinC = [Ic,Rc|Hc],
128 eval_d(CLP, Ia*Ka+Ib*Kb, Ic),
129 eval_d(CLP, Ra*Ka+Rb*Kb, Rc),
130 add_linear_ffh(Ha, CLP, Ka, Hb, Kb, Hc).
131
136
137add_linear_ffh([], CLP, _, Ys, Kb, Zs) :- mult_hom(Ys,CLP,Kb,Zs).
138add_linear_ffh([l(X*Kx,OrdX)|Xs], CLP, Ka, Ys, Kb, Zs) :-
139 add_linear_ffh(Ys, CLP, X, Kx, OrdX, Xs, Zs, Ka, Kb).
140
145
146add_linear_ffh([], CLP, X, Kx, OrdX, Xs, Zs, Ka, _) :-
147 mult_hom([l(X*Kx,OrdX)|Xs], CLP, Ka, Zs).
148add_linear_ffh([l(Y*Ky,OrdY)|Ys], CLP, X, Kx, OrdX, Xs, Zs, Ka, Kb) :-
149 compare(Rel,OrdX,OrdY),
150 ( Rel = (=)
151 -> eval_d(CLP, Kx*Ka+Ky*Kb, Kz),
152 ( 153 compare_d(CLP, =, Kx*Ka, -Ky*Kb)
154 -> add_linear_ffh(Xs, CLP, Ka, Ys, Kb, Zs)
155 ; Zs = [l(X*Kz,OrdX)|Ztail],
156 add_linear_ffh(Xs, CLP, Ka, Ys, Kb, Ztail)
157 )
158 ; Rel = (<)
159 -> Zs = [l(X*Kz,OrdX)|Ztail],
160 eval_d(CLP, Kx*Ka, Kz),
161 add_linear_ffh(Xs, CLP, Y, Ky, OrdY, Ys, Ztail, Kb, Ka)
162 ; Rel = (>)
163 -> Zs = [l(Y*Kz,OrdY)|Ztail],
164 eval_d(CLP, Ky*Kb, Kz),
165 add_linear_ffh(Ys, CLP, X, Kx, OrdX, Xs, Ztail, Ka, Kb)
166 ).
167
171
172add_linear_f1(CLP, LinA, Ka, LinB, LinC) :-
173 LinA = [Ia,Ra|Ha],
174 LinB = [Ib,Rb|Hb],
175 LinC = [Ic,Rc|Hc],
176 eval_d(CLP, Ia*Ka+Ib, Ic),
177 eval_d(CLP, Ra*Ka+Rb, Rc),
178 add_linear_f1h(Ha, CLP, Ka, Hb, Hc).
179
183
184add_linear_f1h([], _, _, Ys, Ys).
185add_linear_f1h([l(X*Kx,OrdX)|Xs], CLP, Ka, Ys, Zs) :-
186 add_linear_f1h(Ys, CLP, X, Kx, OrdX, Xs, Zs, Ka).
187
191
192add_linear_f1h([], CLP, X, Kx, OrdX, Xs, Zs, Ka) :-
193 mult_hom([l(X*Kx,OrdX)|Xs], CLP, Ka, Zs).
194add_linear_f1h([l(Y*Ky,OrdY)|Ys], CLP, X, Kx, OrdX, Xs, Zs, Ka) :-
195 compare(Rel,OrdX,OrdY),
196 ( Rel = (=)
197 -> eval_d(CLP, Kx*Ka+Ky, Kz),
198 ( 199 compare_d(CLP, =, Kx*Ka, -Ky)
200 -> add_linear_f1h(Xs, CLP, Ka, Ys, Zs)
201 ; Zs = [l(X*Kz,OrdX)|Ztail],
202 add_linear_f1h(Xs, CLP, Ka, Ys, Ztail)
203 )
204 ; Rel = (<)
205 -> Zs = [l(X*Kz,OrdX)|Ztail],
206 eval_d(CLP, Kx*Ka, Kz),
207 add_linear_f1h(Xs, CLP, Ka, [l(Y*Ky,OrdY)|Ys], Ztail)
208 ; Rel = (>)
209 -> Zs = [l(Y*Ky,OrdY)|Ztail],
210 add_linear_f1h(Ys, CLP, X, Kx, OrdX, Xs, Ztail, Ka)
211 ).
212
216
217add_linear_11(CLP, LinA, LinB, LinC) :-
218 LinA = [Ia,Ra|Ha],
219 LinB = [Ib,Rb|Hb],
220 LinC = [Ic,Rc|Hc],
221 eval_d(CLP, Ia+Ib, Ic),
222 eval_d(CLP, Ra+Rb, Rc),
223 add_linear_11h(Ha, CLP, Hb, Hc).
224
228
229add_linear_11h([], _, Ys, Ys).
230add_linear_11h([l(X*Kx,OrdX)|Xs], CLP, Ys, Zs) :-
231 add_linear_11h(Ys, CLP, X, Kx, OrdX, Xs, Zs).
232
236
237add_linear_11h([], _, X, Kx, OrdX, Xs, [l(X*Kx,OrdX)|Xs]).
238add_linear_11h([l(Y*Ky,OrdY)|Ys], CLP, X, Kx, OrdX, Xs, Zs) :-
239 compare(Rel,OrdX,OrdY),
240 ( Rel = (=)
241 -> eval_d(CLP, Kx+Ky, Kz),
242 ( 243 compare_d(CLP, =, Kx, -Ky)
244 -> add_linear_11h(Xs, CLP, Ys, Zs)
245 ; Zs = [l(X*Kz,OrdX)|Ztail],
246 add_linear_11h(Xs, CLP, Ys, Ztail)
247 )
248 ; Rel = (<)
249 -> Zs = [l(X*Kx,OrdX)|Ztail],
250 add_linear_11h(Xs, CLP, Y, Ky, OrdY, Ys, Ztail)
251 ; Rel = (>)
252 -> Zs = [l(Y*Ky,OrdY)|Ztail],
253 add_linear_11h(Ys, CLP, X, Kx, OrdX, Xs, Ztail)
254 ).
255
260
261mult_linear_factor(CLP, Lin, K, Mult) :-
262 compare_d(CLP, =, K, 1),
263 !,
264 Mult = Lin.
265mult_linear_factor(CLP, Lin, K, Res) :-
266 Lin = [I,R|Hom],
267 Res = [Ik, Rk|Mult],
268 eval_d(CLP, I*K, Ik),
269 eval_d(CLP, R*K, Rk),
270 mult_hom(Hom, CLP, K, Mult).
271
272div_linear_factor(CLP, Lin, K, Mult) :-
273 compare_d(CLP, =, K, 1),
274 !,
275 Mult = Lin.
276div_linear_factor(CLP, Lin, K, Res) :-
277 Lin = [I,R|Hom],
278 Res = [Ik,Rk|Mult],
279 eval_d(CLP, I/K, Ik),
280 eval_d(CLP, R/K, Rk),
281 div_hom(Hom, CLP, K, Mult).
282
287
288mult_hom([], _, _, []).
289mult_hom([l(A*Fa,OrdA)|As], CLP, F, [l(A*Fan,OrdA)|Afs]) :-
290 eval_d(CLP, F*Fa, Fan),
291 mult_hom(As, CLP, F, Afs).
292
293div_hom([], _, _, []).
294div_hom([l(A*Fa,OrdA)|As], CLP, F, [l(A*Fan,OrdA)|Afs]) :-
295 eval_d(CLP, Fa/F, Fan),
296 div_hom(As, CLP, F, Afs).
297
303
304nf_substitute(CLP, OrdV, LinV, LinX, LinX1) :-
305 delete_factor(OrdV,LinX,LinW,K),
306 add_linear_f1(CLP, LinV, K, LinW, LinX1).
307
312
313delete_factor(OrdV,Lin,Res,Coeff) :-
314 Lin = [I,R|Hom],
315 Res = [I,R|Hdel],
316 delete_factor_hom(OrdV,Hom,Hdel,Coeff).
317
322
323delete_factor_hom(VOrd,[Car|Cdr],RCdr,RKoeff) :-
324 Car = l(_*Koeff,Ord),
325 compare(Rel,VOrd,Ord),
326 ( Rel= (=)
327 -> RCdr = Cdr,
328 RKoeff=Koeff
329 ; Rel= (>)
330 -> RCdr = [Car|RCdr1],
331 delete_factor_hom(VOrd,Cdr,RCdr1,RKoeff)
332 ).
333
334
338
339nf_coeff_of([_,_|Hom],VOrd,Coeff) :-
340 nf_coeff_hom(Hom,VOrd,Coeff).
341
346
347nf_coeff_hom([l(_*K,OVar)|Vs],OVid,Coeff) :-
348 compare(Rel,OVid,OVar),
349 ( Rel = (=)
350 -> Coeff = K
351 ; Rel = (>)
352 -> nf_coeff_hom(Vs,OVid,Coeff)
353 ).
354
358
359nf_rhs_x(CLP, Lin,OrdX,Rhs,K) :-
360 Lin = [I,R|Tail],
361 nf_coeff_hom(Tail,OrdX,K),
362 eval_d(CLP, R+I, Rhs). 363
368
369isolate(CLP, OrdN, Lin, Lin1) :-
370 delete_factor(OrdN,Lin,Lin0,Coeff),
371 div_linear_factor(CLP, Lin0, -Coeff, Lin1)