2 #include "theory/arith/tableau.h"
5 using namespace CVC4::theory
;
6 using namespace CVC4::theory::arith
;
8 Row::Row(ArithVar basic
,
9 const std::vector
< Rational
>& coefficients
,
10 const std::vector
< ArithVar
>& variables
):
14 Assert(coefficients
.size() == variables
.size() );
16 std::vector
<Rational
>::const_iterator coeffIter
= coefficients
.begin();
17 std::vector
<Rational
>::const_iterator coeffEnd
= coefficients
.end();
18 std::vector
<ArithVar
>::const_iterator varIter
= variables
.begin();
20 for(; coeffIter
!= coeffEnd
; ++coeffIter
, ++varIter
){
21 const Rational
& coeff
= *coeffIter
;
22 ArithVar var_i
= *varIter
;
24 Assert(var_i
!= d_x_i
);
26 Assert(coeff
!= Rational(0,1));
28 d_coeffs
[var_i
] = coeff
;
29 Assert(d_coeffs
[var_i
] != Rational(0,1));
33 void Row::subsitute(Row
& row_s
){
34 ArithVar x_s
= row_s
.basicVar();
41 Rational a_rs
= lookup(x_s
);
45 for(iterator iter
= row_s
.begin(), iter_end
= row_s
.end();
46 iter
!= iter_end
; ++iter
){
47 ArithVar x_j
= iter
->first
;
48 Rational a_sj
= iter
->second
;
50 CoefficientTable::iterator coeff_iter
= d_coeffs
.find(x_j
);
52 if(coeff_iter
!= d_coeffs
.end()){
53 coeff_iter
->second
+= a_sj
;
54 if(coeff_iter
->second
== zero
){
55 d_coeffs
.erase(coeff_iter
);
58 d_coeffs
.insert(std::make_pair(x_j
,a_sj
));
63 void Row::pivot(ArithVar x_j
){
64 Rational negInverseA_rs
= -(lookup(x_j
).inverse());
65 d_coeffs
[d_x_i
] = Rational(Integer(-1));
70 for(iterator nonbasicIter
= begin(), nonbasicIter_end
= end();
71 nonbasicIter
!= nonbasicIter_end
; ++nonbasicIter
){
72 nonbasicIter
->second
*= negInverseA_rs
;
78 Debug("tableau") << d_x_i
<< " ";
79 for(iterator nonbasicIter
= d_coeffs
.begin();
80 nonbasicIter
!= d_coeffs
.end();
82 ArithVar nb
= nonbasicIter
->first
;
83 Debug("tableau") << "{" << nb
<< "," << d_coeffs
[nb
] << "}";
85 Debug("tableau") << std::endl
;
88 void Tableau::addRow(ArithVar basicVar
,
89 const std::vector
<Rational
>& coeffs
,
90 const std::vector
<ArithVar
>& variables
){
92 Assert(coeffs
.size() == variables
.size());
93 Assert(d_basicManager
.isBasic(basicVar
));
95 //The new basic variable cannot already be a basic variable
96 Assert(!isActiveBasicVariable(basicVar
));
97 d_activeBasicVars
.insert(basicVar
);
98 Row
* row_current
= new Row(basicVar
,coeffs
,variables
);
99 d_activeRows
[basicVar
] = row_current
;
101 //A variable in the row may have been made non-basic already.
102 //If this is the case we fake pivoting this variable
103 std::vector
<Rational
>::const_iterator coeffsIter
= coeffs
.begin();
104 std::vector
<Rational
>::const_iterator coeffsEnd
= coeffs
.end();
106 std::vector
<ArithVar
>::const_iterator varsIter
= variables
.begin();
108 for( ; coeffsIter
!= coeffsEnd
; ++coeffsIter
, ++ varsIter
){
109 ArithVar var
= *varsIter
;
111 if(d_basicManager
.isBasic(var
)){
112 if(!isActiveBasicVariable(var
)){
115 Assert(isActiveBasicVariable(var
));
117 Row
* row_var
= lookup(var
);
118 row_current
->subsitute(*row_var
);
123 void Tableau::pivot(ArithVar x_r
, ArithVar x_s
){
124 Assert(d_basicManager
.isBasic(x_r
));
125 Assert(!d_basicManager
.isBasic(x_s
));
127 RowsTable::iterator ptrRow_r
= d_activeRows
.find(x_r
);
128 Assert(ptrRow_r
!= d_activeRows
.end());
130 Row
* row_s
= (*ptrRow_r
).second
;
132 Assert(row_s
->has(x_s
));
135 d_activeRows
.erase(ptrRow_r
);
136 d_activeBasicVars
.erase(x_r
);
137 d_basicManager
.makeNonbasic(x_r
);
139 d_activeRows
.insert(std::make_pair(x_s
,row_s
));
140 d_activeBasicVars
.insert(x_s
);
141 d_basicManager
.makeBasic(x_s
);
143 for(VarSet::iterator basicIter
= begin(), endIter
= end();
144 basicIter
!= endIter
; ++basicIter
){
145 ArithVar basic
= *basicIter
;
146 Row
* row_k
= lookup(basic
);
148 d_activityMonitor
.increaseActivity(basic
, 30);
149 row_k
->subsitute(*row_s
);
154 void Tableau::printTableau(){
155 for(VarSet::iterator basicIter
= begin(), endIter
= end();
156 basicIter
!= endIter
; ++basicIter
){
157 ArithVar basic
= *basicIter
;
158 Row
* row_k
= lookup(basic
);
161 for(RowsTable::iterator basicIter
= d_inactiveRows
.begin(), endIter
= d_inactiveRows
.end();
162 basicIter
!= endIter
; ++basicIter
){
163 ArithVar basic
= (*basicIter
).first
;
164 Row
* row_k
= lookupEjected(basic
);
170 void Tableau::updateRow(Row
* row
){
171 for(Row::iterator i
=row
->begin(), endIter
= row
->end(); i
!= endIter
; ){
172 ArithVar var
= i
->first
;
174 if(d_basicManager
.isBasic(var
)){
175 Row
* row_var
= isActiveBasicVariable(var
) ? lookup(var
) : lookupEjected(var
);
177 Assert(row_var
!= row
);
178 row
->subsitute(*row_var
);
181 endIter
= row
->end();