39
40:- module(bv_r,
41 [
42 allvars/2,
43 backsubst/3,
44 backsubst_delta/4,
45 basis_add/2,
46 dec_step/2,
47 deref/2,
48 deref_var/2,
49 detach_bounds/1,
50 detach_bounds_vlv/5,
51 determine_active_dec/1,
52 determine_active_inc/1,
53 dump_var/6,
54 dump_nz/5,
55 export_binding/1,
56 export_binding/2,
57 get_or_add_class/2,
58 inc_step/2,
59 intro_at/3,
60 iterate_dec/2,
61 lb/3,
62 pivot_a/4,
63 pivot/5,
64 rcbl_status/6,
65 reconsider/1,
66 same_class/2,
67 solve/1,
68 solve_ord_x/3,
69 ub/3,
70 unconstrained/4,
71 var_intern/2,
72 var_intern/3,
73 var_intern/4,
74 var_with_def_assign/2,
75 var_with_def_intern/4,
76 maximize/1,
77 minimize/1,
78 sup/2,
79 sup/4,
80 inf/2,
81 inf/4,
82 'solve_<'/1,
83 'solve_=<'/1,
84 'solve_=\\='/1,
85 log_deref/4
86 ]). 87:- use_module(store_r,
88 [
89 add_linear_11/3,
90 add_linear_f1/4,
91 add_linear_ff/5,
92 delete_factor/4,
93 indep/2,
94 isolate/3,
95 nf2sum/3,
96 nf_rhs_x/4,
97 nf_substitute/4,
98 normalize_scalar/2,
99 mult_hom/3,
100 mult_linear_factor/3
101 ]). 102:- use_module('../clpqr/class',
103 [
104 class_allvars/2,
105 class_basis/2,
106 class_basis_add/3,
107 class_basis_drop/2,
108 class_basis_pivot/3,
109 class_new/5
110 ]). 111:- use_module(ineq_r,
112 [
113 ineq/4
114 ]). 115:- use_module(nf_r,
116 [
117 {}/1,
118 split/3,
119 wait_linear/3
120 ]). 121:- use_module(bb_r,
122 [
123 vertex_value/2
124 ]). 125:- use_module(library(ordsets),
126 [
127 ord_add_element/3
128 ]). 129
137
148
151
157
158deref(Lin,Lind) :-
159 split(Lin,H,I),
160 normalize_scalar(I,Nonvar),
161 length(H,Len),
162 log_deref(Len,H,[],Restd),
163 add_linear_11(Nonvar,Restd,Lind).
164
171
172log_deref(0,Vs,Vs,Lin) :-
173 !,
174 Lin = [0.0,0.0].
175log_deref(1,[v(K,[X^1])|Vs],Vs,Lin) :-
176 !,
177 deref_var(X,Lx),
178 mult_linear_factor(Lx,K,Lin).
179log_deref(2,[v(Kx,[X^1]),v(Ky,[Y^1])|Vs],Vs,Lin) :-
180 !,
181 deref_var(X,Lx),
182 deref_var(Y,Ly),
183 add_linear_ff(Lx,Kx,Ly,Ky,Lin).
184log_deref(N,V0,V2,Lin) :-
185 P is N >> 1,
186 Q is N - P,
187 log_deref(P,V0,V1,Lp),
188 log_deref(Q,V1,V2,Lq),
189 add_linear_11(Lp,Lq,Lin).
190
195
196deref_var(X,Lin) :-
197 ( get_attr(X,clpqr_itf,Att)
198 -> ( \+ arg(1,Att,clpr)
199 -> throw(error(permission_error('mix CLP(Q) variables with',
200 'CLP(R) variables:',X),context(_,_)))
201 ; arg(4,Att,lin(Lin))
202 -> true
203 ; setarg(2,Att,type(t_none)),
204 setarg(3,Att,strictness(0)),
205 Lin = [0.0,0.0,l(X*1.0,Ord)],
206 setarg(4,Att,lin(Lin)),
207 setarg(5,Att,order(Ord))
208 )
209 ; Lin = [0.0,0.0,l(X*1.0,Ord)],
210 put_attr(X,clpqr_itf,t(clpr,type(t_none),strictness(0),
211 lin(Lin),order(Ord),n,n,n,n,n,n))
212 ).
213
217
218var_with_def_assign(Var,Lin) :-
219 Lin = [I,_|Hom],
220 ( Hom = []
221 -> 222 Var = I
223 ; Hom = [l(V*K,_)|Cs]
224 -> ( Cs = [],
225 TestK is K - 1.0, 226 TestK =< 1.0e-10,
227 TestK >= -1.0e-10,
228 I >= -1.0e-010, 229 I =< 1.0e-010
230 -> 231 Var = V
232 ; 233 var_with_def_intern(t_none,Var,Lin,0)
234 )
235 ).
236
247
248var_with_def_intern(Type,Var,Lin,Strict) :-
249 put_attr(Var,clpqr_itf,t(clpr,type(Type),strictness(Strict),lin(Lin),
250 order(_),n,aux,n,n,n,n)), 251 Lin = [_,_|Hom],
252 get_or_add_class(Var,Class),
253 same_class(Hom,Class).
254
258
259var_intern(Type,Var,Strict) :-
260 var_intern(Type,Var,Strict,n).
261
267
268var_intern(Type,Var,Strict,Aux) :-
269 put_attr(Var,clpqr_itf,t(clpr,type(Type),strictness(Strict),
270 lin([0.0,0.0,l(Var*1.0,Ord)]),order(Ord),n,Aux,n,n,n,n)),
271 get_or_add_class(Var,_Class).
272
276
277var_intern(Var,Class) :- 278 get_attr(Var,clpqr_itf,Att),
279 arg(2,Att,type(_)),
280 arg(4,Att,lin(_)),
281 !,
282 get_or_add_class(Var,Class).
283var_intern(Var,Class) :-
284 put_attr(Var,clpqr_itf,t(clpr,type(t_none),strictness(0),
285 lin([0.0,0.0,l(Var*1.0,Ord)]),order(Ord),n,n,n,n,n,n)),
286 get_or_add_class(Var,Class).
287
289
293
294export_binding([]).
295export_binding([X-Y|Gs]) :-
296 export_binding(Y,X),
297 export_binding(Gs).
298
303
304export_binding(Y,X) :-
305 ( nonvar(Y),
306 Y >= -1.0e-10, 307 Y =< 1.0e-10
308 -> X = 0.0
309 ; Y = X
310 ).
314
315'solve_=\\='(Nf) :-
316 deref(Nf,Lind), 317 Lind = [Inhom,_|Hom],
318 ( Hom = []
319 -> 320 \+ (Inhom >= -1.0e-10, Inhom =< 1.0e-10) 321 ; 322 var_with_def_intern(t_none,Nz,Lind,0),
323 324 get_attr(Nz,clpqr_itf,Att),
325 setarg(8,Att,nonzero)
326 ).
327
331
332'solve_<'(Nf) :-
333 split(Nf,H,I),
334 ineq(H,I,Nf,strict).
335
339
340'solve_=<'(Nf) :-
341 split(Nf,H,I),
342 ineq(H,I,Nf,nonstrict).
343
344maximize(Term) :-
345 minimize(-Term).
346
372minimize(Term) :-
373 wait_linear(Term,Nf,minimize_lin(Nf)).
374
379
380minimize_lin(Lin) :-
381 deref(Lin,Lind),
382 var_with_def_intern(t_none,Dep,Lind,0),
383 determine_active_dec(Lind),
384 iterate_dec(Dep,Inf),
385 { Dep =:= Inf }.
386
387sup(Expression,Sup) :-
388 sup(Expression,Sup,[],[]).
389
390sup(Expression,Sup,Vector,Vertex) :-
391 inf(-Expression,-Sup,Vector,Vertex).
392
393inf(Expression,Inf) :-
394 inf(Expression,Inf,[],[]).
395
396inf(Expression,Inf,Vector,Vertex) :-
397 398 399 wait_linear(Expression,Nf,inf_lin(Nf,Inf,Vector,Vertex)).
400
405
406inf_lin(Lin,Infimum,Vector,Vertex) :-
407 State = state(none),
408 ( deref(Lin,Lind),
409 var_with_def_intern(t_none,Dep,Lind,0), 410 determine_active_dec(Lind), 411 iterate_dec(Dep,Inf),
412 vertex_value(Vector,Values),
413 nb_setarg(1,State,[Inf|Values]),
414 fail
415 ; arg(1,State,L),
416 L = [_|_],
417 assign([Infimum|Vertex],L)
418 ).
419
425
426assign([],[]).
427assign([X|Xs],[Y|Ys]) :-
428 {X =:= Y}, 429 assign(Xs,Ys).
430
450
451
457
458iterate_dec(OptVar,Opt) :-
459 get_attr(OptVar,clpqr_itf,Att),
460 arg(4,Att,lin([I,R|H])),
461 dec_step(H,Status),
462 ( Status = applied
463 -> iterate_dec(OptVar,Opt)
464 ; Status = optimum,
465 Opt is R + I
466 ).
473
474dec_step_cont([],optimum,Cont,Cont).
475dec_step_cont([l(V*K,OrdV)|Vs],Status,ContIn,ContOut) :-
476 get_attr(V,clpqr_itf,Att),
477 arg(2,Att,type(W)),
478 arg(6,Att,class(Class)),
479 ( dec_step_2_cont(W,l(V*K,OrdV),Class,Status,ContIn,ContOut)
480 -> true
481 ; dec_step_cont(Vs,Status,ContIn,ContOut)
482 ).
483
484inc_step_cont([],optimum,Cont,Cont).
485inc_step_cont([l(V*K,OrdV)|Vs],Status,ContIn,ContOut) :-
486 get_attr(V,clpqr_itf,Att),
487 arg(2,Att,type(W)),
488 arg(6,Att,class(Class)),
489 ( inc_step_2_cont(W,l(V*K,OrdV),Class,Status,ContIn,ContOut)
490 -> true
491 ; inc_step_cont(Vs,Status,ContIn,ContOut)
492 ).
493
494dec_step_2_cont(t_U(U),l(V*K,OrdV),Class,Status,ContIn,ContOut) :-
495 K > 1.0e-10,
496 ( lb(Class,OrdV,Vub-Vb-_)
497 -> 498 Status = applied,
499 pivot_a(Vub,V,Vb,t_u(U)),
500 replace_in_cont(ContIn,Vub,V,ContOut)
501 ; Status = unlimited(V,t_u(U)),
502 ContIn = ContOut
503 ).
504dec_step_2_cont(t_lU(L,U),l(V*K,OrdV),Class,applied,ContIn,ContOut) :-
505 K > 1.0e-10,
506 Init is L - U,
507 class_basis(Class,Deps),
508 lb(Deps,OrdV,V-t_Lu(L,U)-Init,Vub-Vb-_),
509 pivot_b(Vub,V,Vb,t_lu(L,U)),
510 replace_in_cont(ContIn,Vub,V,ContOut).
511dec_step_2_cont(t_L(L),l(V*K,OrdV),Class,Status,ContIn,ContOut) :-
512 K < -1.0e-10,
513 ( ub(Class,OrdV,Vub-Vb-_)
514 -> Status = applied,
515 pivot_a(Vub,V,Vb,t_l(L)),
516 replace_in_cont(ContIn,Vub,V,ContOut)
517 ; Status = unlimited(V,t_l(L)),
518 ContIn = ContOut
519 ).
520dec_step_2_cont(t_Lu(L,U),l(V*K,OrdV),Class,applied,ContIn,ContOut) :-
521 K < -1.0e-10,
522 Init is U - L,
523 class_basis(Class,Deps),
524 ub(Deps,OrdV,V-t_lU(L,U)-Init,Vub-Vb-_),
525 pivot_b(Vub,V,Vb,t_lu(L,U)),
526 replace_in_cont(ContIn,Vub,V,ContOut).
527dec_step_2_cont(t_none,l(V*_,_),_,unlimited(V,t_none),Cont,Cont).
528
529
530
531inc_step_2_cont(t_U(U),l(V*K,OrdV),Class,Status,ContIn,ContOut) :-
532 K < -1.0e-10,
533 ( lb(Class,OrdV,Vub-Vb-_)
534 -> Status = applied,
535 pivot_a(Vub,V,Vb,t_u(U)),
536 replace_in_cont(ContIn,Vub,V,ContOut)
537 ; Status = unlimited(V,t_u(U)),
538 ContIn = ContOut
539 ).
540inc_step_2_cont(t_lU(L,U),l(V*K,OrdV),Class,applied,ContIn,ContOut) :-
541 K < -1.0e-10,
542 Init is L - U,
543 class_basis(Class,Deps),
544 lb(Deps,OrdV,V-t_Lu(L,U)-Init,Vub-Vb-_),
545 pivot_b(Vub,V,Vb,t_lu(L,U)),
546 replace_in_cont(ContIn,Vub,V,ContOut).
547inc_step_2_cont(t_L(L),l(V*K,OrdV),Class,Status,ContIn,ContOut) :-
548 K > 1.0e-10,
549 ( ub(Class,OrdV,Vub-Vb-_)
550 -> Status = applied,
551 pivot_a(Vub,V,Vb,t_l(L)),
552 replace_in_cont(ContIn,Vub,V,ContOut)
553 ; Status = unlimited(V,t_l(L)),
554 ContIn = ContOut
555 ).
556inc_step_2_cont(t_Lu(L,U),l(V*K,OrdV),Class,applied,ContIn,ContOut) :-
557 K > 1.0e-10,
558 Init is U - L,
559 class_basis(Class,Deps),
560 ub(Deps,OrdV,V-t_lU(L,U)-Init,Vub-Vb-_),
561 pivot_b(Vub,V,Vb,t_lu(L,U)),
562 replace_in_cont(ContIn,Vub,V,ContOut).
563inc_step_2_cont(t_none,l(V*_,_),_,unlimited(V,t_none),Cont,Cont).
564
565replace_in_cont([],_,_,[]).
566replace_in_cont([H1|T1],X,Y,[H2|T2]) :-
567 ( H1 == X
568 -> H2 = Y,
569 T1 = T2
570 ; H2 = H1,
571 replace_in_cont(T1,X,Y,T2)
572 ).
573
574dec_step([],optimum).
575dec_step([l(V*K,OrdV)|Vs],Status) :-
576 get_attr(V,clpqr_itf,Att),
577 arg(2,Att,type(W)),
578 arg(6,Att,class(Class)),
579 ( dec_step_2(W,l(V*K,OrdV),Class,Status)
580 -> true
581 ; dec_step(Vs,Status)
582 ).
583
584dec_step_2(t_U(U),l(V*K,OrdV),Class,Status) :-
585 K > 1.0e-10,
586 ( lb(Class,OrdV,Vub-Vb-_)
587 -> 588 Status = applied,
589 pivot_a(Vub,V,Vb,t_u(U))
590 ; Status = unlimited(V,t_u(U))
591 ).
592dec_step_2(t_lU(L,U),l(V*K,OrdV),Class,applied) :-
593 K > 1.0e-10,
594 Init is L - U,
595 class_basis(Class,Deps),
596 lb(Deps,OrdV,V-t_Lu(L,U)-Init,Vub-Vb-_),
597 pivot_b(Vub,V,Vb,t_lu(L,U)).
598dec_step_2(t_L(L),l(V*K,OrdV),Class,Status) :-
599 K < -1.0e-10,
600 ( ub(Class,OrdV,Vub-Vb-_)
601 -> Status = applied,
602 pivot_a(Vub,V,Vb,t_l(L))
603 ; Status = unlimited(V,t_l(L))
604 ).
605dec_step_2(t_Lu(L,U),l(V*K,OrdV),Class,applied) :-
606 K < -1.0e-10,
607 Init is U - L,
608 class_basis(Class,Deps),
609 ub(Deps,OrdV,V-t_lU(L,U)-Init,Vub-Vb-_),
610 pivot_b(Vub,V,Vb,t_lu(L,U)).
611dec_step_2(t_none,l(V*_,_),_,unlimited(V,t_none)).
612
613inc_step([],optimum). 614inc_step([l(V*K,OrdV)|Vs],Status) :-
615 get_attr(V,clpqr_itf,Att),
616 arg(2,Att,type(W)),
617 arg(6,Att,class(Class)),
618 ( inc_step_2(W,l(V*K,OrdV),Class,Status)
619 -> true
620 ; inc_step(Vs,Status)
621 ).
622
623inc_step_2(t_U(U),l(V*K,OrdV),Class,Status) :-
624 K < -1.0e-10,
625 ( lb(Class,OrdV,Vub-Vb-_)
626 -> Status = applied,
627 pivot_a(Vub,V,Vb,t_u(U))
628 ; Status = unlimited(V,t_u(U))
629 ).
630inc_step_2(t_lU(L,U),l(V*K,OrdV),Class,applied) :-
631 K < -1.0e-10,
632 Init is L - U,
633 class_basis(Class,Deps),
634 lb(Deps,OrdV,V-t_Lu(L,U)-Init,Vub-Vb-_),
635 pivot_b(Vub,V,Vb,t_lu(L,U)).
636inc_step_2(t_L(L),l(V*K,OrdV),Class,Status) :-
637 K > 1.0e-10,
638 ( ub(Class,OrdV,Vub-Vb-_)
639 -> Status = applied,
640 pivot_a(Vub,V,Vb,t_l(L))
641 ; Status = unlimited(V,t_l(L))
642 ).
643inc_step_2(t_Lu(L,U),l(V*K,OrdV),Class,applied) :-
644 K > 1.0e-10,
645 Init is U - L,
646 class_basis(Class,Deps),
647 ub(Deps,OrdV,V-t_lU(L,U)-Init,Vub-Vb-_),
648 pivot_b(Vub,V,Vb,t_lu(L,U)).
649inc_step_2(t_none,l(V*_,_),_,unlimited(V,t_none)).
650
667
668ub(Class,OrdX,Ub) :-
669 class_basis(Class,Deps),
670 ub_first(Deps,OrdX,Ub).
671
678
679ub_first([Dep|Deps],OrdX,Tightest) :-
680 ( get_attr(Dep,clpqr_itf,Att),
681 arg(2,Att,type(Type)),
682 arg(4,Att,lin(Lin)),
683 ub_inner(Type,OrdX,Lin,W,Ub),
684 Ub > -1.0e-10 685 -> ub(Deps,OrdX,Dep-W-Ub,Tightest)
686 ; ub_first(Deps,OrdX,Tightest)
687 ).
688
692
693ub([],_,T0,T0).
694ub([Dep|Deps],OrdX,T0,T1) :-
695 ( get_attr(Dep,clpqr_itf,Att),
696 arg(2,Att,type(Type)),
697 arg(4,Att,lin(Lin)),
698 ub_inner(Type,OrdX,Lin,W,Ub),
699 T0 = _-Ubb,
700 701 Ub - Ubb < -1.0e-10,
702 703 Ub > -1.0e-10
704 -> ub(Deps,OrdX,Dep-W-Ub,T1) 705 ; ub(Deps,OrdX,T0,T1) 706 ).
707
711
712ub_inner(t_l(L),OrdX,Lin,t_L(L),Ub) :-
713 nf_rhs_x(Lin,OrdX,Rhs,K),
714 715 K < -1.0e-10, 716 Ub is (L-Rhs)/K.
717ub_inner(t_u(U),OrdX,Lin,t_U(U),Ub) :-
718 nf_rhs_x(Lin,OrdX,Rhs,K),
719 K > 1.0e-10, 720 Ub is (U-Rhs)/K.
721ub_inner(t_lu(L,U),OrdX,Lin,W,Ub) :-
722 nf_rhs_x(Lin,OrdX,Rhs,K),
723 ( K < -1.0e-10 724 -> W = t_Lu(L,U),
725 Ub = (L-Rhs)/K
726 ; K > 1.0e-10 727 -> W = t_lU(L,U),
728 Ub = (U-Rhs)/K
729 ).
730
739
740lb(Class,OrdX,Lb) :-
741 class_basis(Class,Deps),
742 lb_first(Deps,OrdX,Lb).
743
752
753lb_first([Dep|Deps],OrdX,Tightest) :-
754 ( get_attr(Dep,clpqr_itf,Att),
755 arg(2,Att,type(Type)),
756 arg(4,Att,lin(Lin)),
757 lb_inner(Type,OrdX,Lin,W,Lb),
758 Lb < 1.0e-10 759 -> lb(Deps,OrdX,Dep-W-Lb,Tightest)
760 ; lb_first(Deps,OrdX,Tightest)
761 ).
762
767
768lb([],_,T0,T0).
769lb([Dep|Deps],OrdX,T0,T1) :-
770 ( get_attr(Dep,clpqr_itf,Att),
771 arg(2,Att,type(Type)),
772 arg(4,Att,lin(Lin)),
773 lb_inner(Type,OrdX,Lin,W,Lb),
774 T0 = _-Lbb,
775 Lb - Lbb > 1.0e-10, 776 777 Lb < 1.0e-10 778 -> lb(Deps,OrdX,Dep-W-Lb,T1)
779 ; lb(Deps,OrdX,T0,T1)
780 ).
781
794
795lb_inner(t_l(L),OrdX,Lin,t_L(L),Lb) :-
796 nf_rhs_x(Lin,OrdX,Rhs,K), 797 798 799 K > 1.0e-10, 800 Lb is (L-Rhs)/K.
801lb_inner(t_u(U),OrdX,Lin,t_U(U),Lb) :-
802 nf_rhs_x(Lin,OrdX,Rhs,K),
803 K < -1.0e-10, 804 Lb is (U-Rhs)/K.
805lb_inner(t_lu(L,U),OrdX,Lin,W,Lb) :-
806 nf_rhs_x(Lin,OrdX,Rhs,K),
807 ( K < -1.0e-10
808 -> W = t_lU(L,U),
809 Lb is (U-Rhs)/K
810 ; K > 1.0e-10
811 -> W = t_Lu(L,U),
812 Lb is (L-Rhs)/K
813 ).
814
822
823solve(Lin) :-
824 Lin = [I,_|H],
825 solve(H,Lin,I,Bindings,[]),
826 export_binding(Bindings).
827
831
832solve([],_,I,Bind0,Bind0) :-
833 !,
834 I >= -1.0e-10, 835 I =< 1.0e-10.
836solve(H,Lin,_,Bind0,BindT) :-
837 sd(H,[],ClassesUniq,9-9-0,Category-Selected-_,NV,NVT),
838 get_attr(Selected,clpqr_itf,Att),
839 arg(5,Att,order(Ord)),
840 isolate(Ord,Lin,Lin1), 841 ( Category = 1 842 -> setarg(4,Att,lin(Lin1)),
843 Lin1 = [Inhom,_|Hom],
844 bs_collect_binding(Hom,Selected,Inhom,Bind0,BindT),
845 eq_classes(NV,NVT,ClassesUniq)
846 ; Category = 2 847 -> arg(6,Att,class(NewC)),
848 class_allvars(NewC,Deps),
849 ( ClassesUniq = [_] 850 -> bs_collect_bindings(Deps,Ord,Lin1,Bind0,BindT)
851 ; Bind0 = BindT,
852 bs(Deps,Ord,Lin1)
853 ),
854 eq_classes(NV,NVT,ClassesUniq)
855 ; Category = 3 856 857 -> arg(2,Att,type(Type)),
858 setarg(4,Att,lin(Lin1)),
859 deactivate_bound(Type,Selected),
860 eq_classes(NV,NVT,ClassesUniq),
861 basis_add(Selected,Basis),
862 undet_active(Lin1), 863 864 Lin1 = [Inhom,_|Hom],
865 bs_collect_binding(Hom,Selected,Inhom,Bind0,Bind1), 866 867 rcbl(Basis,Bind1,BindT) 868 ; Category = 4 869 870 -> arg(2,Att,type(Type)),
871 arg(6,Att,class(NewC)),
872 class_allvars(NewC,Deps),
873 ( ClassesUniq = [_] 874 -> bs_collect_bindings(Deps,Ord,Lin1,Bind0,Bind1)
875 ; Bind0 = Bind1,
876 bs(Deps,Ord,Lin1)
877 ),
878 deactivate_bound(Type,Selected),
879 basis_add(Selected,Basis),
880 881 882 equate(ClassesUniq,_),
883 undet_active(Lin1),
884 rcbl(Basis,Bind1,BindT)
885 ).
886
891
892solve_ord_x(Lin,OrdX,ClassX) :-
893 Lin = [I,_|H],
894 solve_ord_x(H,Lin,I,OrdX,ClassX,Bindings,[]),
895 export_binding(Bindings).
896
897solve_ord_x([],_,I,_,_,Bind0,Bind0) :-
898 I >= -1.0e-10, 899 I =< 1.0e-10.
900solve_ord_x([_|_],Lin,_,OrdX,ClassX,Bind0,BindT) :-
901 isolate(OrdX,Lin,Lin1),
902 Lin1 = [_,_|H1],
903 sd(H1,[],ClassesUniq1,9-9-0,_,NV,NVT), 904 905 ord_add_element(ClassesUniq1,ClassX,ClassesUniq),
906 class_allvars(ClassX,Deps),
907 ( ClassesUniq = [_] 908 -> bs_collect_bindings(Deps,OrdX,Lin1,Bind0,BindT)
909 ; Bind0 = BindT,
910 bs(Deps,OrdX,Lin1)
911 ),
912 eq_classes(NV,NVT,ClassesUniq).
913
915
921
922sd([],Class0,Class0,Preference0,Preference0,NV0,NV0).
923sd([l(X*K,_)|Xs],Class0,ClassN,Preference0,PreferenceN,NV0,NVt) :-
924 get_attr(X,clpqr_itf,Att),
925 ( arg(6,Att,class(Xc)) 926 -> NV0 = NV1,
927 ord_add_element(Class0,Xc,Class1),
928 ( arg(2,Att,type(t_none))
929 -> preference(Preference0,2-X-K,Preference1)
930 931 ; preference(Preference0,4-X-K,Preference1)
932 933 )
934 ; 935 Class1 = Class0,
936 NV0 = [X|NV1], 937 ( arg(2,Att,type(t_none))
938 -> preference(Preference0,1-X-K,Preference1)
939 940 ; preference(Preference0,3-X-K,Preference1)
941 942 )
943 ),
944 sd(Xs,Class1,ClassN,Preference1,PreferenceN,NV1,NVt).
945
949preference(A,B,Pref) :-
950 A = Px-_-_,
951 B = Py-_-_,
952 ( Px < Py
953 -> Pref = A
954 ; Pref = B
955 ).
956
963
964eq_classes(NV,_,Cs) :-
965 var(NV),
966 !,
967 equate(Cs,_).
968eq_classes(NV,NVT,Cs) :-
969 class_new(Su,clpr,NV,NVT,[]), 970 attach_class(NV,Su), 971 equate(Cs,Su).
972
973equate([],_).
974equate([X|Xs],X) :- equate(Xs,X).
975
979attach_class(Xs,_) :-
980 var(Xs), 981 !.
982attach_class([X|Xs],Class) :-
983 get_attr(X,clpqr_itf,Att),
984 setarg(6,Att,class(Class)),
985 attach_class(Xs,Class).
986
991
992unconstrained(Lin,Uc,Kuc,Rest) :-
993 Lin = [_,_|H],
994 sd(H,[],_,9-9-0,Category-Uc-_,_,_),
995 Category =< 2,
996 get_attr(Uc,clpqr_itf,Att),
997 arg(5,Att,order(OrdUc)),
998 delete_factor(OrdUc,Lin,Rest,Kuc).
999
1004same_class([],_).
1005same_class([l(X*_,_)|Xs],Class) :-
1006 get_or_add_class(X,Class),
1007 same_class(Xs,Class).
1008
1013
1014get_or_add_class(X,Class) :-
1015 get_attr(X,clpqr_itf,Att),
1016 arg(1,Att,CLP),
1017 ( arg(6,Att,class(ClassX))
1018 -> ClassX = Class
1019 ; setarg(6,Att,class(Class)),
1020 class_new(Class,CLP,[X|Tail],Tail,[])
1021 ).
1022
1026
1027allvars(X,Allvars) :-
1028 get_attr(X,clpqr_itf,Att),
1029 arg(6,Att,class(C)),
1030 class_allvars(C,Allvars).
1031
1037
1038deactivate_bound(t_l(_),_).
1039deactivate_bound(t_u(_),_).
1040deactivate_bound(t_lu(_,_),_).
1041deactivate_bound(t_L(L),X) :-
1042 get_attr(X,clpqr_itf,Att),
1043 setarg(2,Att,type(t_l(L))).
1044deactivate_bound(t_Lu(L,U),X) :-
1045 get_attr(X,clpqr_itf,Att),
1046 setarg(2,Att,type(t_lu(L,U))).
1047deactivate_bound(t_U(U),X) :-
1048 get_attr(X,clpqr_itf,Att),
1049 setarg(2,Att,type(t_u(U))).
1050deactivate_bound(t_lU(L,U),X) :-
1051 get_attr(X,clpqr_itf,Att),
1052 setarg(2,Att,type(t_lu(L,U))).
1053
1060
1061intro_at(X,Value,Type) :-
1062 get_attr(X,clpqr_itf,Att),
1063 arg(5,Att,order(Ord)),
1064 arg(6,Att,class(Class)),
1065 setarg(2,Att,type(Type)),
1066 ( Value >= -1.0e-10, 1067 Value =< 1.0e-010
1068 -> true
1069 ; backsubst_delta(Class,Ord,X,Value)
1070 ).
1071
1076
1077undet_active([_,_|H]) :-
1078 undet_active_h(H).
1079
1084
1085undet_active_h([]).
1086undet_active_h([l(X*_,_)|Xs]) :-
1087 get_attr(X,clpqr_itf,Att),
1088 arg(2,Att,type(Type)),
1089 undet_active(Type,X),
1090 undet_active_h(Xs).
1091
1096
1097undet_active(t_none,_). 1098undet_active(t_L(_),_).
1099undet_active(t_Lu(_,_),_).
1100undet_active(t_U(_),_).
1101undet_active(t_lU(_,_),_).
1102undet_active(t_l(L),X) :- intro_at(X,L,t_L(L)).
1103undet_active(t_u(U),X) :- intro_at(X,U,t_U(U)).
1104undet_active(t_lu(L,U),X) :- intro_at(X,L,t_Lu(L,U)).
1105
1112
1113determine_active_dec([_,_|H]) :-
1114 determine_active(H,-1).
1115
1122
1123determine_active_inc([_,_|H]) :-
1124 determine_active(H,1).
1125
1132
1133determine_active([],_).
1134determine_active([l(X*K,_)|Xs],S) :-
1135 get_attr(X,clpqr_itf,Att),
1136 arg(2,Att,type(Type)),
1137 determine_active(Type,X,K,S),
1138 determine_active(Xs,S).
1139
1140determine_active(t_L(_),_,_,_).
1141determine_active(t_Lu(_,_),_,_,_).
1142determine_active(t_U(_),_,_,_).
1143determine_active(t_lU(_,_),_,_,_).
1144determine_active(t_l(L),X,_,_) :- intro_at(X,L,t_L(L)).
1145determine_active(t_u(U),X,_,_) :- intro_at(X,U,t_U(U)).
1146determine_active(t_lu(L,U),X,K,S) :-
1147 TestKs is K*S,
1148 ( TestKs < -1.0e-10 1149 -> intro_at(X,L,t_Lu(L,U))
1150 ; TestKs > 1.0e-10
1151 -> intro_at(X,U,t_lU(L,U))
1152 ).
1153
1157
1158detach_bounds(V) :-
1159 get_attr(V,clpqr_itf,Att),
1160 arg(2,Att,type(Type)),
1161 arg(4,Att,lin(Lin)),
1162 arg(5,Att,order(OrdV)),
1163 arg(6,Att,class(Class)),
1164 setarg(2,Att,type(t_none)),
1165 setarg(3,Att,strictness(0)),
1166 ( indep(Lin,OrdV)
1167 -> ( ub(Class,OrdV,Vub-Vb-_)
1168 -> 1169 class_basis_drop(Class,Vub),
1170 pivot(Vub,Class,OrdV,Vb,Type)
1171 ; lb(Class,OrdV,Vlb-Vb-_)
1172 -> class_basis_drop(Class,Vlb),
1173 pivot(Vlb,Class,OrdV,Vb,Type)
1174 ; true
1175 )
1176 ; class_basis_drop(Class,V)
1177 ).
1178
1179detach_bounds_vlv(OrdV,Lin,Class,Var,NewLin) :-
1180 ( indep(Lin,OrdV)
1181 -> Lin = [_,R|_],
1182 ( ub(Class,OrdV,Vub-Vb-_)
1183 -> 1184 1185 class_basis_drop(Class,Var),
1186 pivot_vlv(Vub,Class,OrdV,Vb,R,NewLin)
1187 ; lb(Class,OrdV,Vlb-Vb-_)
1188 -> class_basis_drop(Class,Var),
1189 pivot_vlv(Vlb,Class,OrdV,Vb,R,NewLin)
1190 ; NewLin = Lin
1191 )
1192 ; NewLin = Lin,
1193 class_basis_drop(Class,Var)
1194 ).
1199
1200basis_add(X,NewBasis) :-
1201 get_attr(X,clpqr_itf,Att),
1202 arg(6,Att,class(Cv)),
1203 class_basis_add(Cv,X,NewBasis).
1204
1209
1210basis_pivot(Leave,Enter) :-
1211 get_attr(Leave,clpqr_itf,Att),
1212 arg(6,Att,class(Cv)),
1213 class_basis_pivot(Cv,Enter,Leave).
1214
1216
1223
1224
1225pivot_a(Dep,Indep,Vb,Wd) :-
1226 basis_pivot(Dep,Indep),
1227 get_attr(Indep,clpqr_itf,Att),
1228 arg(2,Att,type(Type)),
1229 arg(5,Att,order(Ord)),
1230 arg(6,Att,class(Class)),
1231 pivot(Dep,Class,Ord,Vb,Type),
1232 get_attr(Indep,clpqr_itf,Att2), 1233 setarg(2,Att2,type(Wd)).
1234
1235pivot_b(Vub,V,Vb,Wd) :-
1236 ( Vub == V
1237 -> get_attr(V,clpqr_itf,Att),
1238 arg(5,Att,order(Ord)),
1239 arg(6,Att,class(Class)),
1240 setarg(2,Att,type(Vb)),
1241 pivot_b_delta(Vb,Delta), 1242 backsubst_delta(Class,Ord,V,Delta)
1243 ; pivot_a(Vub,V,Vb,Wd)
1244 ).
1245
1246pivot_b_delta(t_Lu(L,U),Delta) :- Delta is L-U.
1247pivot_b_delta(t_lU(L,U),Delta) :- Delta is U-L.
1248
1252
1253select_active_bound(t_L(L),L).
1254select_active_bound(t_Lu(L,_),L).
1255select_active_bound(t_U(U),U).
1256select_active_bound(t_lU(_,U),U).
1257select_active_bound(t_none,0.0).
1261select_active_bound(t_l(_),0.0).
1262select_active_bound(t_u(_),0.0).
1263select_active_bound(t_lu(_,_),0.0).
1264
1265
1270
1275pivot(Dep,Class,IndepOrd,DepAct,IndAct) :-
1276 get_attr(Dep,clpqr_itf,Att),
1277 arg(4,Att,lin(H)),
1278 arg(5,Att,order(DepOrd)),
1279 setarg(2,Att,type(DepAct)),
1280 select_active_bound(DepAct,AbvD), 1281 select_active_bound(IndAct,AbvI), 1282 delete_factor(IndepOrd,H,H0,Coeff), 1283 AbvDm is -AbvD,
1284 AbvIm is -AbvI,
1285 add_linear_f1([0.0,AbvIm],Coeff,H0,H1),
1286 K is -1.0/Coeff,
1287 add_linear_ff(H1,K,[0.0,AbvDm,l(Dep* -1.0,DepOrd)],K,H2),
1288 1289 add_linear_11(H2,[0.0,AbvIm],Lin),
1290 backsubst(Class,IndepOrd,Lin).
1291
1292pivot_vlv(Dep,Class,IndepOrd,DepAct,AbvI,Lin) :-
1293 get_attr(Dep,clpqr_itf,Att),
1294 arg(4,Att,lin(H)),
1295 arg(5,Att,order(DepOrd)),
1296 setarg(2,Att,type(DepAct)),
1297 select_active_bound(DepAct,AbvD), 1298 delete_factor(IndepOrd,H,H0,Coeff), 1299 AbvDm is -AbvD,
1300 AbvIm is -AbvI,
1301 add_linear_f1([0.0,AbvIm],Coeff,H0,H1),
1302 K is -1.0/Coeff,
1303 add_linear_ff(H1,K,[0.0,AbvDm,l(Dep* -1.0,DepOrd)],K,Lin),
1304 1305 add_linear_11(Lin,[0.0,AbvIm],SubstLin),
1306 backsubst(Class,IndepOrd,SubstLin).
1307
1313
1314backsubst_delta(Class,OrdX,X,Delta) :-
1315 backsubst(Class,OrdX,[0.0,Delta,l(X*1.0,OrdX)]).
1316
1321
1322backsubst(Class,OrdX,Lin) :-
1323 class_allvars(Class,Allvars),
1324 bs(Allvars,OrdX,Lin).
1325
1333
1334bs(Xs,_,_) :-
1335 var(Xs),
1336 !.
1337bs([X|Xs],OrdV,Lin) :-
1338 ( get_attr(X,clpqr_itf,Att),
1339 arg(4,Att,lin(LinX)),
1340 nf_substitute(OrdV,Lin,LinX,LinX1) 1341 -> setarg(4,Att,lin(LinX1)),
1342 bs(Xs,OrdV,Lin)
1343 ; bs(Xs,OrdV,Lin)
1344 ).
1345
1349
1359
1360bs_collect_bindings(Xs,_,_,Bind0,BindT) :-
1361 var(Xs),
1362 !,
1363 Bind0 = BindT.
1364bs_collect_bindings([X|Xs],OrdV,Lin,Bind0,BindT) :-
1365 ( get_attr(X,clpqr_itf,Att),
1366 arg(4,Att,lin(LinX)),
1367 nf_substitute(OrdV,Lin,LinX,LinX1) 1368 -> setarg(4,Att,lin(LinX1)),
1369 LinX1 = [Inhom,_|Hom],
1370 bs_collect_binding(Hom,X,Inhom,Bind0,Bind1),
1371 bs_collect_bindings(Xs,OrdV,Lin,Bind1,BindT)
1372 ; bs_collect_bindings(Xs,OrdV,Lin,Bind0,BindT)
1373 ).
1374
1380bs_collect_binding([],X,Inhom) --> [X-Inhom].
1381bs_collect_binding([_|_],_,_) --> [].
1382
1386
1390
1391rcbl([],Bind0,Bind0).
1392rcbl([X|Continuation],Bind0,BindT) :-
1393 ( rcb_cont(X,Status,Violated,Continuation,NewContinuation) 1394 -> rcbl_status(Status,X,NewContinuation,Bind0,BindT,Violated)
1395 ; rcbl(Continuation,Bind0,BindT)
1396 ).
1397
1398rcb_cont(X,Status,Violated,ContIn,ContOut) :-
1399 get_attr(X,clpqr_itf,Att),
1400 arg(2,Att,type(Type)),
1401 arg(4,Att,lin([I,R|H])),
1402 ( Type = t_l(L) 1403 1404 -> R + I - L < 1.0e-10,
1405 Violated = l(L),
1406 inc_step_cont(H,Status,ContIn,ContOut)
1407 ; Type = t_u(U) 1408 1409 -> R + I - U > -1.0e-10,
1410 Violated = u(U),
1411 dec_step_cont(H,Status,ContIn,ContOut)
1412 ; Type = t_lu(L,U) 1413 -> At is R + I,
1414 ( At - L < 1.0e-10
1415 -> Violated = l(L),
1416 inc_step_cont(H,Status,ContIn,ContOut)
1417 ; At - U > -1.0e-10
1418 -> Violated = u(U),
1419 dec_step_cont(H,Status,ContIn,ContOut)
1420 )
1421 ). 1422
1423
1424
1429reconsider(X) :-
1430 rcb(X,Status,Violated),
1431 !,
1432 rcbl_status(Status,X,[],Binds,[],Violated),
1433 export_binding(Binds).
1434reconsider(_).
1435
1451
1452rcb(X,Status,Violated) :-
1453 get_attr(X,clpqr_itf,Att),
1454 arg(2,Att,type(Type)),
1455 arg(4,Att,lin([I,R|H])),
1456 ( Type = t_l(L) 1457 1458 -> R + I - L < 1.0e-10, 1459 Violated = l(L),
1460 inc_step(H,Status)
1461 ; Type = t_u(U) 1462 1463 -> R + I - U > -1.0e-10, 1464 Violated = u(U),
1465 dec_step(H,Status)
1466 ; Type = t_lu(L,U) 1467 -> At is R + I,
1468 ( At - L < 1.0e-10 1469 -> Violated = l(L),
1470 inc_step(H,Status)
1471 ; At - U > -1.0e-10 1472 -> Violated = u(U),
1473 dec_step(H,Status)
1474 )
1475 ). 1476
1480
1481rcbl_status(optimum,X,Cont,B0,Bt,Violated) :- rcbl_opt(Violated,X,Cont,B0,Bt).
1482rcbl_status(applied,X,Cont,B0,Bt,Violated) :- rcbl_app(Violated,X,Cont,B0,Bt).
1483rcbl_status(unlimited(Indep,DepT),X,Cont,B0,Bt,Violated) :-
1484 rcbl_unl(Violated,X,Cont,B0,Bt,Indep,DepT).
1485
1493rcbl_opt(l(L),X,Continuation,B0,B1) :-
1494 get_attr(X,clpqr_itf,Att),
1495 arg(2,Att,type(Type)),
1496 arg(3,Att,strictness(Strict)),
1497 arg(4,Att,lin(Lin)),
1498 Lin = [I,R|_],
1499 Opt is R + I,
1500 TestLO is L - Opt,
1501 ( TestLO < -1.0e-10 1502 -> narrow_u(Type,X,Opt), 1503 rcbl(Continuation,B0,B1)
1504 ; TestLO =< 1.0e-10, 1505 Strict /\ 2 =:= 0, 1506 Mop is -Opt,
1507 normalize_scalar(Mop,MopN),
1508 add_linear_11(MopN,Lin,Lin1),
1509 Lin1 = [Inhom,_|Hom],
1510 ( Hom = []
1511 -> rcbl(Continuation,B0,B1) 1512 ; solve(Hom,Lin1,Inhom,B0,B1)
1513 )
1514 ).
1515rcbl_opt(u(U),X,Continuation,B0,B1) :-
1516 get_attr(X,clpqr_itf,Att),
1517 arg(2,Att,type(Type)),
1518 arg(3,Att,strictness(Strict)),
1519 arg(4,Att,lin(Lin)),
1520 Lin = [I,R|_],
1521 Opt is R + I,
1522 TestUO is U - Opt,
1523 ( TestUO > 1.0e-10 1524 -> narrow_l(Type,X,Opt), 1525 rcbl(Continuation,B0,B1)
1526 ; TestUO >= -1.0e-10, 1527 Strict /\ 1 =:= 0, 1528 Mop is -Opt,
1529 normalize_scalar(Mop,MopN),
1530 add_linear_11(MopN,Lin,Lin1),
1531 Lin1 = [Inhom,_|Hom],
1532 ( Hom = []
1533 -> rcbl(Continuation,B0,B1) 1534 ; solve(Hom,Lin1,Inhom,B0,B1)
1535 )
1536 ).
1537
1541rcbl_app(l(L),X,Continuation,B0,B1) :-
1542 get_attr(X,clpqr_itf,Att),
1543 arg(4,Att,lin([I,R|H])),
1544 ( R + I - L > 1.0e-10 1545 -> rcbl(Continuation,B0,B1)
1546 ; inc_step(H,Status),
1547 rcbl_status(Status,X,Continuation,B0,B1,l(L))
1548 ).
1549rcbl_app(u(U),X,Continuation,B0,B1) :-
1550 get_attr(X,clpqr_itf,Att),
1551 arg(4,Att,lin([I,R|H])),
1552 ( R + I - U < -1.0e-10 1553 -> rcbl(Continuation,B0,B1)
1554 ; dec_step(H,Status),
1555 rcbl_status(Status,X,Continuation,B0,B1,u(U))
1556 ).
1560rcbl_unl(l(L),X,Continuation,B0,B1,Indep,DepT) :-
1561 pivot_a(X,Indep,t_L(L),DepT), 1562 rcbl(Continuation,B0,B1).
1563rcbl_unl(u(U),X,Continuation,B0,B1,Indep,DepT) :-
1564 pivot_a(X,Indep,t_U(U),DepT), 1565 rcbl(Continuation,B0,B1).
1566
1571
1572narrow_u(t_u(_),X,U) :-
1573 get_attr(X,clpqr_itf,Att),
1574 setarg(2,Att,type(t_u(U))).
1575narrow_u(t_lu(L,_),X,U) :-
1576 get_attr(X,clpqr_itf,Att),
1577 setarg(2,Att,type(t_lu(L,U))).
1578
1583
1584narrow_l( t_l(_), X, L) :-
1585 get_attr(X,clpqr_itf,Att),
1586 setarg(2,Att,type(t_l(L))).
1587
1588narrow_l( t_lu(_,U), X, L) :-
1589 get_attr(X,clpqr_itf,Att),
1590 setarg(2,Att,type(t_lu(L,U))).
1591
1593
1598
1599dump_var(t_none,V,I,H) -->
1600 !,
1601 ( {
1602 H = [l(W*K,_)],
1603 V == W,
1604 I >= -1.0e-10, 1605 I =< 1.0e-010,
1606 TestK is K - 1.0, 1607 TestK >= -1.0e-10,
1608 TestK =< 1.0e-10
1609 }
1610 -> 1611 []
1612 ; {nf2sum(H,I,Sum)},
1613 [V = Sum]
1614 ).
1615dump_var(t_L(L),V,I,H) -->
1616 !,
1617 dump_var(t_l(L),V,I,H).
1621dump_var(t_l(L),V,I,H) -->
1622 !,
1623 {
1624 H = [l(_*K,_)|_], 1625 get_attr(V,clpqr_itf,Att),
1626 arg(3,Att,strictness(Strict)),
1627 Sm is Strict /\ 2,
1628 Kr is 1.0/K,
1629 Li is Kr*(L - I),
1630 mult_hom(H,Kr,H1),
1631 nf2sum(H1,0.0,Sum),
1632 ( K > 1.0e-10 1633 -> dump_strict(Sm,Sum >= Li,Sum > Li,Result)
1634 ; dump_strict(Sm,Sum =< Li,Sum < Li,Result)
1635 )
1636 },
1637 [Result].
1638dump_var(t_U(U),V,I,H) -->
1639 !,
1640 dump_var(t_u(U),V,I,H).
1641dump_var(t_u(U),V,I,H) -->
1642 !,
1643 {
1644 H = [l(_*K,_)|_], 1645 get_attr(V,clpqr_itf,Att),
1646 arg(3,Att,strictness(Strict)),
1647 Sm is Strict /\ 1,
1648 Kr is 1.0/K,
1649 Ui is Kr*(U-I),
1650 mult_hom(H,Kr,H1),
1651 nf2sum(H1,0.0,Sum),
1652 ( K > 1.0e-10 1653 -> dump_strict(Sm,Sum =< Ui,Sum < Ui,Result)
1654 ; dump_strict(Sm,Sum >= Ui,Sum > Ui,Result)
1655 )
1656 },
1657 [Result].
1658dump_var(t_Lu(L,U),V,I,H) -->
1659 !,
1660 dump_var(t_l(L),V,I,H),
1661 dump_var(t_u(U),V,I,H).
1662dump_var(t_lU(L,U),V,I,H) -->
1663 !,
1664 dump_var(t_l(L),V,I,H),
1665 dump_var(t_u(U),V,I,H).
1666dump_var(t_lu(L,U),V,I,H) -->
1667 !,
1668 dump_var(t_l(L),V,I,H),
1669 dump_var(t_U(U),V,I,H).
1670dump_var(T,V,I,H) --> 1671 [V:T:I+H].
1672
1679
1680dump_strict(0,Result,_,Result).
1681dump_strict(1,_,Result,Result).
1682dump_strict(2,_,Result,Result).
1683
1689
1690dump_nz(_,H,I) -->
1691 {
1692 H = [l(_*K,_)|_],
1693 Kr is 1.0/K,
1694 I1 is -Kr*I,
1695 mult_hom(H,Kr,H1),
1696 nf2sum(H1,0.0,Sum)
1697 },
1698 [Sum =\= I1].
1699
1700 1703:- multifile
1704 sandbox:safe_primitive/1. 1705
1706sandbox:safe_primitive(bv_r:inf(_,_)).
1707sandbox:safe_primitive(bv_r:inf(_,_,_,_)).
1708sandbox:safe_primitive(bv_r:sup(_,_)).
1709sandbox:safe_primitive(bv_r:sup(_,_,_,_)).
1710sandbox:safe_primitive(bv_r:maximize(_)).
1711sandbox:safe_primitive(bv_r:minimize(_))