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 var(X),
107 Term = l(X*K,_),
108 get_attr(X,clpqr_itf,Att),
109 arg(5,Att,order(OrdX)), 110 Res = [0.0,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(LinA,Ka,LinB,Kb,LinC) :-
125 LinA = [Ia,Ra|Ha],
126 LinB = [Ib,Rb|Hb],
127 LinC = [Ic,Rc|Hc],
128 Ic is Ia*Ka+Ib*Kb,
129 Rc is Ra*Ka+Rb*Kb,
130 add_linear_ffh(Ha,Ka,Hb,Kb,Hc).
131
136
137add_linear_ffh([],_,Ys,Kb,Zs) :- mult_hom(Ys,Kb,Zs).
138add_linear_ffh([l(X*Kx,OrdX)|Xs],Ka,Ys,Kb,Zs) :-
139 add_linear_ffh(Ys,X,Kx,OrdX,Xs,Zs,Ka,Kb).
140
145
146add_linear_ffh([],X,Kx,OrdX,Xs,Zs,Ka,_) :- mult_hom([l(X*Kx,OrdX)|Xs],Ka,Zs).
147add_linear_ffh([l(Y*Ky,OrdY)|Ys],X,Kx,OrdX,Xs,Zs,Ka,Kb) :-
148 compare(Rel,OrdX,OrdY),
149 ( Rel = (=)
150 -> Kz is Kx*Ka+Ky*Kb,
151 ( 152 Kz =< 1.0e-10,
153 Kz >= -1.0e-10
154 -> add_linear_ffh(Xs,Ka,Ys,Kb,Zs)
155 ; Zs = [l(X*Kz,OrdX)|Ztail],
156 add_linear_ffh(Xs,Ka,Ys,Kb,Ztail)
157 )
158 ; Rel = (<)
159 -> Zs = [l(X*Kz,OrdX)|Ztail],
160 Kz is Kx*Ka,
161 add_linear_ffh(Xs,Y,Ky,OrdY,Ys,Ztail,Kb,Ka)
162 ; Rel = (>)
163 -> Zs = [l(Y*Kz,OrdY)|Ztail],
164 Kz is Ky*Kb,
165 add_linear_ffh(Ys,X,Kx,OrdX,Xs,Ztail,Ka,Kb)
166 ).
167
171
172add_linear_f1(LinA,Ka,LinB,LinC) :-
173 LinA = [Ia,Ra|Ha],
174 LinB = [Ib,Rb|Hb],
175 LinC = [Ic,Rc|Hc],
176 Ic is Ia*Ka+Ib,
177 Rc is Ra*Ka+Rb,
178 add_linear_f1h(Ha,Ka,Hb,Hc).
179
183
184add_linear_f1h([],_,Ys,Ys).
185add_linear_f1h([l(X*Kx,OrdX)|Xs],Ka,Ys,Zs) :-
186 add_linear_f1h(Ys,X,Kx,OrdX,Xs,Zs,Ka).
187
191
192add_linear_f1h([],X,Kx,OrdX,Xs,Zs,Ka) :- mult_hom([l(X*Kx,OrdX)|Xs],Ka,Zs).
193add_linear_f1h([l(Y*Ky,OrdY)|Ys],X,Kx,OrdX,Xs,Zs,Ka) :-
194 compare(Rel,OrdX,OrdY),
195 ( Rel = (=)
196 -> Kz is Kx*Ka+Ky,
197 ( 198 Kz =< 1.0e-10,
199 Kz >= -1.0e-10
200 -> add_linear_f1h(Xs,Ka,Ys,Zs)
201 ; Zs = [l(X*Kz,OrdX)|Ztail],
202 add_linear_f1h(Xs,Ka,Ys,Ztail)
203 )
204 ; Rel = (<)
205 -> Zs = [l(X*Kz,OrdX)|Ztail],
206 Kz is Kx*Ka,
207 add_linear_f1h(Xs,Ka,[l(Y*Ky,OrdY)|Ys],Ztail)
208 ; Rel = (>)
209 -> Zs = [l(Y*Ky,OrdY)|Ztail],
210 add_linear_f1h(Ys,X,Kx,OrdX,Xs,Ztail,Ka)
211 ).
212
216
217add_linear_11(LinA,LinB,LinC) :-
218 LinA = [Ia,Ra|Ha],
219 LinB = [Ib,Rb|Hb],
220 LinC = [Ic,Rc|Hc],
221 Ic is Ia+Ib,
222 Rc is Ra+Rb,
223 add_linear_11h(Ha,Hb,Hc).
224
228
229add_linear_11h([],Ys,Ys).
230add_linear_11h([l(X*Kx,OrdX)|Xs],Ys,Zs) :-
231 add_linear_11h(Ys,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],X,Kx,OrdX,Xs,Zs) :-
239 compare(Rel,OrdX,OrdY),
240 ( Rel = (=)
241 -> Kz is Kx+Ky,
242 ( 243 Kz =< 1.0e-10,
244 Kz >= -1.0e-10
245 -> add_linear_11h(Xs,Ys,Zs)
246 ; Zs = [l(X*Kz,OrdX)|Ztail],
247 add_linear_11h(Xs,Ys,Ztail)
248 )
249 ; Rel = (<)
250 -> Zs = [l(X*Kx,OrdX)|Ztail],
251 add_linear_11h(Xs,Y,Ky,OrdY,Ys,Ztail)
252 ; Rel = (>)
253 -> Zs = [l(Y*Ky,OrdY)|Ztail],
254 add_linear_11h(Ys,X,Kx,OrdX,Xs,Ztail)
255 ).
256
261
262mult_linear_factor(Lin,K,Mult) :-
263 TestK is K - 1.0, 264 TestK =< 1.0e-10,
265 TestK >= -1.0e-10, 266 !,
267 Mult = Lin.
268mult_linear_factor(Lin,K,Res) :-
269 Lin = [I,R|Hom],
270 Res = [Ik,Rk|Mult],
271 Ik is I*K,
272 Rk is R*K,
273 mult_hom(Hom,K,Mult).
274
279
280mult_hom([],_,[]).
281mult_hom([l(A*Fa,OrdA)|As],F,[l(A*Fan,OrdA)|Afs]) :-
282 Fan is F*Fa,
283 mult_hom(As,F,Afs).
284
290
291nf_substitute(OrdV,LinV,LinX,LinX1) :-
292 delete_factor(OrdV,LinX,LinW,K),
293 add_linear_f1(LinV,K,LinW,LinX1).
294
299
300delete_factor(OrdV,Lin,Res,Coeff) :-
301 Lin = [I,R|Hom],
302 Res = [I,R|Hdel],
303 delete_factor_hom(OrdV,Hom,Hdel,Coeff).
304
309
310delete_factor_hom(VOrd,[Car|Cdr],RCdr,RKoeff) :-
311 Car = l(_*Koeff,Ord),
312 compare(Rel,VOrd,Ord),
313 ( Rel= (=)
314 -> RCdr = Cdr,
315 RKoeff=Koeff
316 ; Rel= (>)
317 -> RCdr = [Car|RCdr1],
318 delete_factor_hom(VOrd,Cdr,RCdr1,RKoeff)
319 ).
320
321
325
326nf_coeff_of([_,_|Hom],VOrd,Coeff) :-
327 nf_coeff_hom(Hom,VOrd,Coeff).
328
333
334nf_coeff_hom([l(_*K,OVar)|Vs],OVid,Coeff) :-
335 compare(Rel,OVid,OVar),
336 ( Rel = (=)
337 -> Coeff = K
338 ; Rel = (>)
339 -> nf_coeff_hom(Vs,OVid,Coeff)
340 ).
341
345
346nf_rhs_x(Lin,OrdX,Rhs,K) :-
347 Lin = [I,R|Tail],
348 nf_coeff_hom(Tail,OrdX,K),
349 Rhs is R+I. 350
355
356isolate(OrdN,Lin,Lin1) :-
357 delete_factor(OrdN,Lin,Lin0,Coeff),
358 K is -1.0/Coeff,
359 mult_linear_factor(Lin0,K,Lin1).
360
364
365indep(Lin,OrdX) :-
366 Lin = [I,_|[l(_*K,OrdY)]],
367 OrdX == OrdY,
368 369 TestK is K - 1.0,
370 TestK =< 1.0e-10,
371 TestK >= -1.0e-10,
372 373 I =< 1.0e-10,
374 I >= -1.0e-10.
375
380
381nf2sum([],I,I).
382nf2sum([X|Xs],I,Sum) :-
383 ( 384 I =< 1.0e-10,
385 I >= -1.0e-10
386 -> X = l(Var*K,_),
387 ( 388 TestK is K - 1.0,
389 TestK =< 1.0e-10,
390 TestK >= -1.0e-10
391 -> hom2sum(Xs,Var,Sum)
392 ; 393 TestK is K + 1.0,
394 TestK =< 1.0e-10,
395 TestK >= -1.0e-10
396 -> hom2sum(Xs,-Var,Sum)
397 ; hom2sum(Xs,K*Var,Sum)
398 )
399 ; hom2sum([X|Xs],I,Sum)
400 ).
401
408
409hom2sum([],Term,Term).
410hom2sum([l(Var*K,_)|Cs],Sofar,Term) :-
411 ( 412 TestK is K - 1.0,
413 TestK =< 1.0e-10,
414 TestK >= -1.0e-10
415 -> Next = Sofar + Var
416 ; 417 TestK is K + 1.0,
418 TestK =< 1.0e-10,
419 TestK >= -1.0e-10
420 -> Next = Sofar - Var
421 ; 422 K < -1.0e-10
423 -> Ka is -K,
424 Next = Sofar - Ka*Var
425 ; Next = Sofar + K*Var
426 ),
427 hom2sum(Cs,Next,Term)