40
41:- module(store_r,
42 [
43 add_linear_11/3,
44 add_linear_f1/4,
45 add_linear_ff/5,
46 normalize_scalar/2,
47 delete_factor/4,
48 mult_linear_factor/3,
49 nf_rhs_x/4,
50 indep/2,
51 isolate/3,
52 nf_substitute/4,
53 mult_hom/3,
54 nf2sum/3,
55 nf_coeff_of/3,
56 renormalize/2
57 ]). 58
62
63normalize_scalar(S,[S,0.0]).
64
72
73renormalize([I,R|Hom],Lin) :-
74 length(Hom,Len),
75 renormalize_log(Len,Hom,[],Lin0),
76 add_linear_11([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,[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(LinA,LinB,Lin).
94renormalize_log(N,L0,L2,Lin) :-
95 P is N>>1,
96 Q is N-P,
97 renormalize_log(P,L0,L1,Lp),
98 renormalize_log(Q,L1,L2,Lq),
99 add_linear_11(Lp,Lq,Lin).
100
104
105renormalize_log_one(X,Term,Res) :-
106 Term = l(X*K,_),
107 ( var(X)
108 -> get_attr(X,clpqr_itf,Att),
109 arg(5,Att,order(OrdX)), 110 Res = [0.0,0.0,l(X*K,OrdX)]
111 ; Xk is X*K,
112 normalize_scalar(Xk,Res)
113 ).
114
116
121
122add_linear_ff(LinA,Ka,LinB,Kb,LinC) :-
123 LinA = [Ia,Ra|Ha],
124 LinB = [Ib,Rb|Hb],
125 LinC = [Ic,Rc|Hc],
126 Ic is Ia*Ka+Ib*Kb,
127 Rc is Ra*Ka+Rb*Kb,
128 add_linear_ffh(Ha,Ka,Hb,Kb,Hc).
129
134
135add_linear_ffh([],_,Ys,Kb,Zs) :- mult_hom(Ys,Kb,Zs).
136add_linear_ffh([l(X*Kx,OrdX)|Xs],Ka,Ys,Kb,Zs) :-
137 add_linear_ffh(Ys,X,Kx,OrdX,Xs,Zs,Ka,Kb).
138
143
144add_linear_ffh([],X,Kx,OrdX,Xs,Zs,Ka,_) :- mult_hom([l(X*Kx,OrdX)|Xs],Ka,Zs).
145add_linear_ffh([l(Y*Ky,OrdY)|Ys],X,Kx,OrdX,Xs,Zs,Ka,Kb) :-
146 compare(Rel,OrdX,OrdY),
147 ( Rel = (=)
148 -> Kz is Kx*Ka+Ky*Kb,
149 ( 150 Kz =< 1.0e-10,
151 Kz >= -1.0e-10
152 -> add_linear_ffh(Xs,Ka,Ys,Kb,Zs)
153 ; Zs = [l(X*Kz,OrdX)|Ztail],
154 add_linear_ffh(Xs,Ka,Ys,Kb,Ztail)
155 )
156 ; Rel = (<)
157 -> Zs = [l(X*Kz,OrdX)|Ztail],
158 Kz is Kx*Ka,
159 add_linear_ffh(Xs,Y,Ky,OrdY,Ys,Ztail,Kb,Ka)
160 ; Rel = (>)
161 -> Zs = [l(Y*Kz,OrdY)|Ztail],
162 Kz is Ky*Kb,
163 add_linear_ffh(Ys,X,Kx,OrdX,Xs,Ztail,Ka,Kb)
164 ).
165
169
170add_linear_f1(LinA,Ka,LinB,LinC) :-
171 LinA = [Ia,Ra|Ha],
172 LinB = [Ib,Rb|Hb],
173 LinC = [Ic,Rc|Hc],
174 Ic is Ia*Ka+Ib,
175 Rc is Ra*Ka+Rb,
176 add_linear_f1h(Ha,Ka,Hb,Hc).
177
181
182add_linear_f1h([],_,Ys,Ys).
183add_linear_f1h([l(X*Kx,OrdX)|Xs],Ka,Ys,Zs) :-
184 add_linear_f1h(Ys,X,Kx,OrdX,Xs,Zs,Ka).
185
189
190add_linear_f1h([],X,Kx,OrdX,Xs,Zs,Ka) :- mult_hom([l(X*Kx,OrdX)|Xs],Ka,Zs).
191add_linear_f1h([l(Y*Ky,OrdY)|Ys],X,Kx,OrdX,Xs,Zs,Ka) :-
192 compare(Rel,OrdX,OrdY),
193 ( Rel = (=)
194 -> Kz is Kx*Ka+Ky,
195 ( 196 Kz =< 1.0e-10,
197 Kz >= -1.0e-10
198 -> add_linear_f1h(Xs,Ka,Ys,Zs)
199 ; Zs = [l(X*Kz,OrdX)|Ztail],
200 add_linear_f1h(Xs,Ka,Ys,Ztail)
201 )
202 ; Rel = (<)
203 -> Zs = [l(X*Kz,OrdX)|Ztail],
204 Kz is Kx*Ka,
205 add_linear_f1h(Xs,Ka,[l(Y*Ky,OrdY)|Ys],Ztail)
206 ; Rel = (>)
207 -> Zs = [l(Y*Ky,OrdY)|Ztail],
208 add_linear_f1h(Ys,X,Kx,OrdX,Xs,Ztail,Ka)
209 ).
210
214
215add_linear_11(LinA,LinB,LinC) :-
216 LinA = [Ia,Ra|Ha],
217 LinB = [Ib,Rb|Hb],
218 LinC = [Ic,Rc|Hc],
219 Ic is Ia+Ib,
220 Rc is Ra+Rb,
221 add_linear_11h(Ha,Hb,Hc).
222
226
227add_linear_11h([],Ys,Ys).
228add_linear_11h([l(X*Kx,OrdX)|Xs],Ys,Zs) :-
229 add_linear_11h(Ys,X,Kx,OrdX,Xs,Zs).
230
234
235add_linear_11h([],X,Kx,OrdX,Xs,[l(X*Kx,OrdX)|Xs]).
236add_linear_11h([l(Y*Ky,OrdY)|Ys],X,Kx,OrdX,Xs,Zs) :-
237 compare(Rel,OrdX,OrdY),
238 ( Rel = (=)
239 -> Kz is Kx+Ky,
240 ( 241 Kz =< 1.0e-10,
242 Kz >= -1.0e-10
243 -> add_linear_11h(Xs,Ys,Zs)
244 ; Zs = [l(X*Kz,OrdX)|Ztail],
245 add_linear_11h(Xs,Ys,Ztail)
246 )
247 ; Rel = (<)
248 -> Zs = [l(X*Kx,OrdX)|Ztail],
249 add_linear_11h(Xs,Y,Ky,OrdY,Ys,Ztail)
250 ; Rel = (>)
251 -> Zs = [l(Y*Ky,OrdY)|Ztail],
252 add_linear_11h(Ys,X,Kx,OrdX,Xs,Ztail)
253 ).
254
259
260mult_linear_factor(Lin,K,Mult) :-
261 TestK is K - 1.0, 262 TestK =< 1.0e-10,
263 TestK >= -1.0e-10, 264 !,
265 Mult = Lin.
266mult_linear_factor(Lin,K,Res) :-
267 Lin = [I,R|Hom],
268 Res = [Ik,Rk|Mult],
269 Ik is I*K,
270 Rk is R*K,
271 mult_hom(Hom,K,Mult).
272
277
278mult_hom([],_,[]).
279mult_hom([l(A*Fa,OrdA)|As],F,[l(A*Fan,OrdA)|Afs]) :-
280 Fan is F*Fa,
281 mult_hom(As,F,Afs).
282
288
289nf_substitute(OrdV,LinV,LinX,LinX1) :-
290 delete_factor(OrdV,LinX,LinW,K),
291 add_linear_f1(LinV,K,LinW,LinX1).
292
297
298delete_factor(OrdV,Lin,Res,Coeff) :-
299 Lin = [I,R|Hom],
300 Res = [I,R|Hdel],
301 delete_factor_hom(OrdV,Hom,Hdel,Coeff).
302
307
308delete_factor_hom(VOrd,[Car|Cdr],RCdr,RKoeff) :-
309 Car = l(_*Koeff,Ord),
310 compare(Rel,VOrd,Ord),
311 ( Rel= (=)
312 -> RCdr = Cdr,
313 RKoeff=Koeff
314 ; Rel= (>)
315 -> RCdr = [Car|RCdr1],
316 delete_factor_hom(VOrd,Cdr,RCdr1,RKoeff)
317 ).
318
319
323
324nf_coeff_of([_,_|Hom],VOrd,Coeff) :-
325 nf_coeff_hom(Hom,VOrd,Coeff).
326
331
332nf_coeff_hom([l(_*K,OVar)|Vs],OVid,Coeff) :-
333 compare(Rel,OVid,OVar),
334 ( Rel = (=)
335 -> Coeff = K
336 ; Rel = (>)
337 -> nf_coeff_hom(Vs,OVid,Coeff)
338 ).
339
343
344nf_rhs_x(Lin,OrdX,Rhs,K) :-
345 Lin = [I,R|Tail],
346 nf_coeff_hom(Tail,OrdX,K),
347 Rhs is R+I. 348
353
354isolate(OrdN,Lin,Lin1) :-
355 delete_factor(OrdN,Lin,Lin0,Coeff),
356 K is -1.0/Coeff,
357 mult_linear_factor(Lin0,K,Lin1).
358
362
363indep(Lin,OrdX) :-
364 Lin = [I,_|[l(_*K,OrdY)]],
365 OrdX == OrdY,
366 367 TestK is K - 1.0,
368 TestK =< 1.0e-10,
369 TestK >= -1.0e-10,
370 371 I =< 1.0e-10,
372 I >= -1.0e-10.
373
378
379nf2sum([],I,I).
380nf2sum([X|Xs],I,Sum) :-
381 ( 382 I =< 1.0e-10,
383 I >= -1.0e-10
384 -> X = l(Var*K,_),
385 ( 386 TestK is K - 1.0,
387 TestK =< 1.0e-10,
388 TestK >= -1.0e-10
389 -> hom2sum(Xs,Var,Sum)
390 ; 391 TestK is K + 1.0,
392 TestK =< 1.0e-10,
393 TestK >= -1.0e-10
394 -> hom2sum(Xs,-Var,Sum)
395 ; hom2sum(Xs,K*Var,Sum)
396 )
397 ; hom2sum([X|Xs],I,Sum)
398 ).
399
406
407hom2sum([],Term,Term).
408hom2sum([l(Var*K,_)|Cs],Sofar,Term) :-
409 ( 410 TestK is K - 1.0,
411 TestK =< 1.0e-10,
412 TestK >= -1.0e-10
413 -> Next = Sofar + Var
414 ; 415 TestK is K + 1.0,
416 TestK =< 1.0e-10,
417 TestK >= -1.0e-10
418 -> Next = Sofar - Var
419 ; 420 K < -1.0e-10
421 -> Ka is -K,
422 Next = Sofar - Ka*Var
423 ; Next = Sofar + K*Var
424 ),
425 hom2sum(Cs,Next,Term)