using namespace CVC4::theory;
using namespace CVC4::theory::arith ;
+bool RowVector::isSorted(const VarCoeffArray& arr, bool strictlySorted) {
+ if(arr.size() >= 2){
+ NonZeroIterator curr = arr.begin();
+ NonZeroIterator end = arr.end();
+ ArithVar prev = getArithVar(*curr);
+ ++curr;
+ for(;curr != end; ++curr){
+ ArithVar v = getArithVar(*curr);
+ if(strictlySorted && prev > v) return false;
+ if(!strictlySorted && prev >= v) return false;
+ prev = v;
+ }
+ }
+ return true;
+}
+
+bool RowVector::noZeroCoefficients(const VarCoeffArray& arr){
+ for(NonZeroIterator curr = arr.begin(), end = arr.end();
+ curr != end; ++curr){
+ const Rational& coeff = getCoefficient(*curr);
+ if(coeff == 0) return false;
+ }
+ return true;
+}
+
void RowVector::zip(const vector< ArithVar >& variables,
const vector< Rational >& coefficients,
VarCoeffArray& output){
}
RowVector::RowVector(const vector< ArithVar >& variables,
- const vector< Rational >& coefficients){
+ const vector< Rational >& coefficients,
+ std::vector<uint32_t>& counts):
+ d_rowCount(counts)
+{
zip(variables, coefficients, d_entries);
std::sort(d_entries.begin(), d_entries.end(), cmp);
+ for(NonZeroIterator i=beginNonZero(), end=endNonZero(); i != end; ++i){
+ ++d_rowCount[getArithVar(*i)];
+ }
+
Assert(isSorted(d_entries, true));
Assert(noZeroCoefficients(d_entries));
}
-void RowVector::merge(VarCoeffArray& arr, const VarCoeffArray& other, const Rational& c){
+void RowVector::merge(VarCoeffArray& arr,
+ const VarCoeffArray& other,
+ const Rational& c,
+ std::vector<uint32_t>& counts){
VarCoeffArray copy = arr;
arr.clear();
arr.push_back(*curr1);
++curr1;
}else if(getArithVar(*curr1) > getArithVar(*curr2)){
+ ++counts[getArithVar(*curr2)];
+
arr.push_back( make_pair(getArithVar(*curr2), c * getCoefficient(*curr2)));
++curr2;
}else{
Rational res = getCoefficient(*curr1) + c * getCoefficient(*curr2);
if(res != 0){
+ ++counts[getArithVar(*curr2)];
+
arr.push_back(make_pair(getArithVar(*curr1), res));
+ }else{
+ --counts[getArithVar(*curr2)];
}
++curr1;
++curr2;
++curr1;
}
while(curr2 != end2){
+ ++counts[getArithVar(*curr2)];
+
arr.push_back(make_pair(getArithVar(*curr2), c * getCoefficient(*curr2)));
++curr2;
}
void RowVector::addRowTimesConstant(const Rational& c, const RowVector& other){
Assert(c != 0);
- merge(d_entries, other.d_entries, c);
+ merge(d_entries, other.d_entries, c, d_rowCount);
}
void RowVector::printRow(){
ReducedRowVector::ReducedRowVector(ArithVar basic,
const vector<ArithVar>& variables,
- const vector<Rational>& coefficients):
- RowVector(variables, coefficients), d_basic(basic){
+ const vector<Rational>& coefficients,
+ std::vector<uint32_t>& count):
+ RowVector(variables, coefficients, count), d_basic(basic){
VarCoeffArray justBasic;
justBasic.push_back(make_pair(basic, Rational(-1)));
- merge(d_entries,justBasic, Rational(1));
+ merge(d_entries,justBasic, Rational(1), d_rowCount);
Assert(wellFormed());
}
* isSorted(arr, strictlySorted) is then equivalent to
* If i<j, cmp(getArithVar(d_entries[i]), getArithVar(d_entries[j])) <= c.
*/
- static bool isSorted(const VarCoeffArray& arr, bool strictlySorted) {
- if(arr.size() >= 2){
- NonZeroIterator curr = arr.begin();
- NonZeroIterator end = arr.end();
- ArithVar prev = getArithVar(*curr);
- ++curr;
- for(;curr != end; ++curr){
- ArithVar v = getArithVar(*curr);
- if(strictlySorted && prev > v) return false;
- if(!strictlySorted && prev >= v) return false;
- prev = v;
- }
- }
- return true;
- }
+ static bool isSorted(const VarCoeffArray& arr, bool strictlySorted);
/**
* noZeroCoefficients(arr) is equivalent to
* 0 != getCoefficient(arr[i]) for all i.
*/
- static bool noZeroCoefficients(const VarCoeffArray& arr){
- for(NonZeroIterator curr = arr.begin(), end = arr.end();
- curr != end; ++curr){
- const Rational& coeff = getCoefficient(*curr);
- if(coeff == 0) return false;
- }
- return true;
- }
+ static bool noZeroCoefficients(const VarCoeffArray& arr);
/**
* Zips together an array of variables and coefficients and appends
const std::vector< Rational >& coefficients,
VarCoeffArray& output);
- static void merge(VarCoeffArray& arr, const VarCoeffArray& other, const Rational& c);
+ static void merge(VarCoeffArray& arr, const VarCoeffArray& other, const Rational& c, std::vector<uint32_t>& count);
protected:
*/
VarCoeffArray d_entries;
+ std::vector<uint32_t>& d_rowCount;
+
NonZeroIterator lower_bound(ArithVar x_j) const{
return std::lower_bound(d_entries.begin(), d_entries.end(), make_pair(x_j,0), cmp);
}
public:
- RowVector() : d_entries() {}
+ //RowVector() : d_entries() {}
RowVector(const std::vector< ArithVar >& variables,
- const std::vector< Rational >& coefficients);
+ const std::vector< Rational >& coefficients,
+ std::vector<uint32_t>& counts);
//Iterates over the nonzero entries in the Vector
ReducedRowVector(ArithVar basic,
const std::vector< ArithVar >& variables,
- const std::vector< Rational >& coefficients);
+ const std::vector< Rational >& coefficients,
+ std::vector<uint32_t>& count);
ArithVar basic() const{
ArithVar SimplexDecisionProcedure::selectSlack(ArithVar x_i){
ReducedRowVector* row_i = d_tableau.lookup(x_i);
+ ArithVar slack = ARITHVAR_SENTINEL;
+ uint32_t numRows = std::numeric_limits<uint32_t>::max();
+
for(ReducedRowVector::NonZeroIterator nbi = row_i->beginNonZero(), end = row_i->endNonZero();
nbi != end; ++nbi){
ArithVar nonbasic = getArithVar(*nbi);
int cmp = a_ij.cmp(d_constants.d_ZERO);
if(above){ // beta(x_i) > u_i
if( cmp < 0 && d_partialModel.strictlyBelowUpperBound(nonbasic)){
- return nonbasic;
+ if(d_pivotStage){
+ if(d_tableau.getRowCount(nonbasic) < numRows){
+ slack = nonbasic;
+ numRows = d_tableau.getRowCount(nonbasic);
+ }
+ }else{
+ slack = nonbasic; break;
+ }
}else if( cmp > 0 && d_partialModel.strictlyAboveLowerBound(nonbasic)){
- return nonbasic;
+ if(d_pivotStage){
+ if(d_tableau.getRowCount(nonbasic) < numRows){
+ slack = nonbasic;
+ numRows = d_tableau.getRowCount(nonbasic);
+ }
+ }else{
+ slack = nonbasic; break;
+ }
}
}else{ //beta(x_i) < l_i
if(cmp > 0 && d_partialModel.strictlyBelowUpperBound(nonbasic)){
- return nonbasic;
- }else if(cmp < 0 && d_partialModel.strictlyAboveLowerBound(nonbasic)){
- return nonbasic;
+ if(d_pivotStage){
+ if(d_tableau.getRowCount(nonbasic) < numRows){
+ slack = nonbasic;
+ numRows = d_tableau.getRowCount(nonbasic);
+ }
+ }else{
+ slack = nonbasic; break;
+ }
+ }else if(cmp < 0 && d_partialModel.strictlyAboveLowerBound(nonbasic)){if(d_pivotStage){
+ if(d_tableau.getRowCount(nonbasic) < numRows){
+ slack = nonbasic;
+ numRows = d_tableau.getRowCount(nonbasic);
+ }
+ }else{
+ slack = nonbasic; break;
+ }
}
}
}
- return ARITHVAR_SENTINEL;
+
+ return slack;
}
Node SimplexDecisionProcedure::updateInconsistentVars(){
+ Node possibleConflict = privateUpdateInconsistentVars();
+ Assert(!possibleConflict.isNull() || d_griggioRuleQueue.empty());
+ Assert(!possibleConflict.isNull() || d_possiblyInconsistent.empty());
d_pivotStage = true;
- return privateUpdateInconsistentVars();
+
+ while(!d_griggioRuleQueue.empty()){
+ d_griggioRuleQueue.pop();
+ }
+ while(!d_possiblyInconsistent.empty()){
+ d_possiblyInconsistent.pop();
+ }
+
+ return possibleConflict;
}
//corresponds to Check() in dM06
d_activityMonitor(am),
d_out(out),
d_tableau(tableau),
- d_numVariables(0)
+ d_numVariables(0),
+ d_pivotStage(true)
{}
void increaseMax() {d_numVariables++;}
//The new basic variable cannot already be a basic variable
Assert(!isActiveBasicVariable(basicVar));
d_activeBasicVars.insert(basicVar);
- ReducedRowVector* row_current = new ReducedRowVector(basicVar,variables, coeffs);
+ ReducedRowVector* row_current = new ReducedRowVector(basicVar,variables, coeffs,d_rowCount);
d_rowsTable[basicVar] = row_current;
//A variable in the row may have been made non-basic already.
ActivityMonitor& d_activityMonitor;
ArithVarDenseSet& d_basicManager;
+ std::vector<uint32_t> d_rowCount;
+
public:
/**
* Constructs an empty tableau.
void increaseSize(){
d_activeBasicVars.increaseSize();
d_rowsTable.push_back(NULL);
+ d_rowCount.push_back(0);
}
ArithVarSet::iterator begin(){
}
public:
+ uint32_t getRowCount(ArithVar x){
+ Assert(x < d_rowCount.size());
+ return d_rowCount[x];
+ }
+
void addRow(ArithVar basicVar,
const std::vector<Rational>& coeffs,
const std::vector<ArithVar>& variables);