theory_arith_type_rules.h \
type_enumerator.h \
arithvar.h \
+ arithvar.cpp \
arith_rewriter.h \
arith_rewriter.cpp \
arith_static_learner.h \
--- /dev/null
+
+#include "theory/arith/arithvar.h"
+#include <limits>
+
+namespace CVC4 {
+namespace theory {
+namespace arith {
+
+const ArithVar ARITHVAR_SENTINEL = std::numeric_limits<ArithVar>::max();
+
+}/* CVC4::theory::arith namespace */
+}/* CVC4::theory namespace */
+}/* CVC4 namespace */
#ifndef __CVC4__THEORY__ARITH__ARITHVAR_H
#define __CVC4__THEORY__ARITH__ARITHVAR_H
-#include <limits>
#include <ext/hash_map>
#include "expr/node.h"
#include "context/cdhashset.h"
-#include "context/cdhashset.h"
#include "util/index.h"
+#include "util/dense_map.h"
namespace CVC4 {
namespace theory {
namespace arith {
typedef Index ArithVar;
-const ArithVar ARITHVAR_SENTINEL = std::numeric_limits<ArithVar>::max();
+extern const ArithVar ARITHVAR_SENTINEL;
//Maps from Nodes -> ArithVars, and vice versa
typedef __gnu_cxx::hash_map<Node, ArithVar, NodeHashFunction> NodeToArithVarMap;
-typedef __gnu_cxx::hash_map<ArithVar, Node> ArithVarToNodeMap;
+typedef DenseMap<Node> ArithVarToNodeMap;
/**
* ArithVarCallBack provides a mechanism for agreeing on callbacks while
ArithVarToNodeMap d_arithVarToNodeMap;
public:
+
+ typedef ArithVarToNodeMap::const_iterator var_iterator;
+
ArithVarNodeMap() {}
inline bool hasArithVar(TNode x) const {
return d_nodeToArithVarMap.find(x) != d_nodeToArithVarMap.end();
}
+ inline bool hasNode(ArithVar a) const {
+ return d_arithVarToNodeMap.isKey(a);
+ }
+
inline ArithVar asArithVar(TNode x) const{
Assert(hasArithVar(x));
Assert((d_nodeToArithVarMap.find(x))->second <= ARITHVAR_SENTINEL);
return (d_nodeToArithVarMap.find(x))->second;
}
+
inline Node asNode(ArithVar a) const{
- Assert(d_arithVarToNodeMap.find(a) != d_arithVarToNodeMap.end());
- return (d_arithVarToNodeMap.find(a))->second;
+ Assert(hasNode(a));
+ return d_arithVarToNodeMap[a];
}
inline void setArithVar(TNode x, ArithVar a){
Assert(!hasArithVar(x));
- Assert(d_arithVarToNodeMap.find(a) == d_arithVarToNodeMap.end());
- d_arithVarToNodeMap[a] = x;
+ Assert(!d_arithVarToNodeMap.isKey(a));
+ d_arithVarToNodeMap.set(a, x);
d_nodeToArithVarMap[x] = a;
}
- const ArithVarToNodeMap& getArithVarToNodeMap() const {
- return d_arithVarToNodeMap;
+ inline void remove(ArithVar x){
+ Assert(hasNode(x));
+ Node node = asNode(x);
+
+ d_nodeToArithVarMap.erase(d_nodeToArithVarMap.find(node));
+ d_arithVarToNodeMap.remove(x);
+ }
+
+ var_iterator var_begin() const {
+ return d_arithVarToNodeMap.begin();
+ }
+ var_iterator var_end() const {
+ return d_arithVarToNodeMap.end();
}
};/* class ArithVarNodeMap */
d_watchedVariables.add(s);
Node eq = x.eqNode(y);
- d_watchedEqualities[s] = eq;
+ d_watchedEqualities.set(s, eq);
}
void ArithCongruenceManager::assertionToEqualityEngine(bool isEquality, ArithVar s, TNode reason){
d_database->pushAssertionOrderWatch(this, witness);
}
+// bool ConstraintValue::isPsuedoConstraint() const {
+// return d_proof == d_database->d_psuedoConstraintProof;
+// }
+
bool ConstraintValue::isSelfExplaining() const {
return d_proof == d_database->d_selfExplainingProof;
}
d_equalityEngineProof = d_proofs.size();
d_proofs.push_back(NullConstraint);
+
+ // d_psuedoConstraintProof = d_proofs.size();
+ // d_proofs.push_back(NullConstraint);
}
Constraint ConstraintDatabase::getConstraint(ArithVar v, ConstraintType t, const DeltaRational& r){
}
void ConstraintDatabase::addVariable(ArithVar v){
- Assert(v == d_varDatabases.size());
- d_varDatabases.push_back(new PerVariableDatabase(v));
+ if(d_reclaimable.isMember(v)){
+ SortedConstraintMap& scm = getVariableSCM(v);
+
+ std::vector<Constraint> constraintList;
+
+ for(SortedConstraintMapIterator i = scm.begin(), end = scm.end(); i != end; ++i){
+ (i->second).push_into(constraintList);
+ }
+ while(!constraintList.empty()){
+ Constraint c = constraintList.back();
+ constraintList.pop_back();
+ Assert(c->safeToGarbageCollect());
+ delete c;
+ }
+ Assert(scm.empty());
+
+ d_reclaimable.remove(v);
+ }else{
+ Assert(v == d_varDatabases.size());
+ d_varDatabases.push_back(new PerVariableDatabase(v));
+ }
+}
+
+void ConstraintDatabase::removeVariable(ArithVar v){
+ Assert(!d_reclaimable.isMember(v));
+ d_reclaimable.add(v);
}
bool ConstraintValue::safeToGarbageCollect() const{
}
}
+// void ConstraintValue::setPsuedoConstraint(){
+// Assert(truthIsUnknown());
+// Assert(!hasLiteral());
+
+// d_database->pushProofWatch(this, d_database->d_psuedoConstraintProof);
+// }
+
void ConstraintValue::setEqualityEngineProof(){
Assert(truthIsUnknown());
Assert(hasLiteral());
void ConstraintValue::markAsTrue(Constraint imp){
Assert(truthIsUnknown());
Assert(imp->hasProof());
+ //Assert(!imp->isPsuedoConstraint());
d_database->d_proofs.push_back(NullConstraint);
d_database->d_proofs.push_back(imp);
Assert(truthIsUnknown());
Assert(impA->hasProof());
Assert(impB->hasProof());
+ //Assert(!impA->isPsuedoConstraint());
+ //Assert(!impB->isPsuedoConstraint());
d_database->d_proofs.push_back(NullConstraint);
d_database->d_proofs.push_back(impA);
for(vector<Constraint>::const_iterator i = a.begin(), end = a.end(); i != end; ++i){
Constraint c_i = *i;
Assert(c_i->hasProof());
+ //Assert(!c_i->isPsuedoConstraint());
d_database->d_proofs.push_back(c_i);
}
bool ConstraintValue::proofIsEmpty() const{
Assert(hasProof());
bool result = d_database->d_proofs[d_proof] == NullConstraint;
+ //Assert((!result) || isSelfExplaining() || hasEqualityEngineProof() || isPsuedoConstraint());
Assert((!result) || isSelfExplaining() || hasEqualityEngineProof());
return result;
}
Assert(hasProof());
Assert(!isSelfExplaining() || assertedToTheTheory());
+
if(assertedBefore(order)){
nb << getWitness();
}else if(hasEqualityEngineProof()){
void setEqualityEngineProof();
bool hasEqualityEngineProof() const;
+
+ /**
+ * There cannot be a literal associated with this constraint.
+ * The explanation is the constant true.
+ * explainInto() does nothing.
+ */
+ //void setPsuedoConstraint();
+ //bool isPsuedoConstraint() const;
+
/**
* Returns a explanation of the constraint that is appropriate for conflicts.
*
*/
ProofId d_equalityEngineProof;
+ /**
+ * Marks a node as being true always.
+ * This is only okay for purely internal things.
+ *
+ * This is a special proof that is always a member of the list.
+ */
+ //ProofId d_psuedoConstraintProof;
+
typedef context::CDList<Constraint, ConstraintValue::ProofCleanup> ProofCleanupList;
typedef context::CDList<Constraint, ConstraintValue::CanBePropagatedCleanup> CBPList;
typedef context::CDList<Constraint, ConstraintValue::AssertionOrderCleanup> AOList;
void addVariable(ArithVar v);
bool variableDatabaseIsSetup(ArithVar v) const;
+ void removeVariable(ArithVar v);
Node eeExplain(ConstConstraint c) const;
void eeExplain(ConstConstraint c, NodeBuilder<>& nb) const;
private:
void raiseUnateConflict(Constraint ant, Constraint cons);
+ DenseSet d_reclaimable;
+
class Statistics {
public:
IntStat d_unatePropagateCalls;
if(Debug.isOn("paranoid:check_tableau")){ debugCheckTableau(); }
}
-void LinearEqualityModule::pivotAndUpdate(ArithVar x_i, ArithVar x_j, DeltaRational& v){
+void LinearEqualityModule::pivotAndUpdate(ArithVar x_i, ArithVar x_j, const DeltaRational& v){
Assert(x_i != x_j);
TimerStat::CodeTimer codeTimer(d_statistics.d_pivotTime);
Assert(sum == shouldBe);
}
}
+bool LinearEqualityModule::debugEntireLinEqIsConsistent(const string& s){
+ bool result = true;
+ for(ArithVar var = 0, end = d_tableau.getNumColumns(); var != end; ++var){
+ // for(VarIter i = d_variables.begin(), end = d_variables.end(); i != end; ++i){
+ //ArithVar var = d_arithvarNodeMap.asArithVar(*i);
+ if(!d_partialModel.assignmentIsConsistent(var)){
+ d_partialModel.printModel(var);
+ Warning() << s << ":" << "Assignment is not consistent for " << var ;
+ if(d_tableau.isBasic(var)){
+ Warning() << " (basic)";
+ }
+ Warning() << endl;
+ result = false;
+ }
+ }
+ return result;
+}
DeltaRational LinearEqualityModule::computeBound(ArithVar basic, bool upperBound){
DeltaRational sum(0,0);
* and then pivots x_i with the nonbasic variable in its row x_j.
* Updates the assignment of the other basic variables accordingly.
*/
- void pivotAndUpdate(ArithVar x_i, ArithVar x_j, DeltaRational& v);
+ void pivotAndUpdate(ArithVar x_i, ArithVar x_j, const DeltaRational& v);
ArithPartialModel& getPartialModel() const{ return d_partialModel; }
/** Debugging information for a pivot. */
void debugPivot(ArithVar x_i, ArithVar x_j);
+ /**
+ *
+ */
+ bool debugEntireLinEqIsConsistent(const std::string& s);
+
private:
/** These fields are designed to be accessible to TheoryArith methods. */
d_basic2RowIndex.remove(basicOld);
d_basic2RowIndex.set(basicNew, rid);
- d_rowIndex2basic[rid] = basicNew;
+ d_rowIndex2basic.set(rid, basicNew);
}
// void Tableau::addEntry(ArithVar row, ArithVar col, const Rational& coeff){
RowIndex newRow = Matrix<Rational>::addRow(coefficients, variables);
addEntry(newRow, basic, Rational(-1));
- Assert(d_rowIndex2basic.size() == newRow);
+ Assert(!d_basic2RowIndex.isKey(basic));
+ Assert(!d_rowIndex2basic.isKey(newRow));
d_basic2RowIndex.set(basic, newRow);
- d_rowIndex2basic.push_back(basic);
+ d_rowIndex2basic.set(newRow, basic);
if(Debug.isOn("matrix")){ printMatrix(); }
// return newId;
// }
+void Tableau::removeBasicRow(ArithVar basic){
+ RowIndex rid = basicToRowIndex(basic);
+
+ removeRow(rid);
+ d_basic2RowIndex.remove(basic);
+ d_rowIndex2basic.remove(rid);
+
+}
+
}/* CVC4::theory::arith namespace */
}/* CVC4::theory namespace */
#include "util/dense_map.h"
#include "theory/arith/arithvar.h"
+#include "theory/arith/arithvar_node_map.h"
#include "theory/arith/normal_form.h"
#include <queue>
uint32_t d_entriesInUse;
MatrixEntryVector<T> d_entries;
+ std::vector<RowIndex> d_pool;
+
T d_zero;
public:
d_entries.freeEntry(id);
}
+ private:
+ RowIndex requestRowIndex(){
+ if(d_pool.empty()){
+ RowIndex ridx = d_rows.size();
+ d_rows.push_back(RowVectorT(&d_entries));
+ return ridx;
+ }else{
+ RowIndex rid = d_pool.back();
+ d_pool.pop_back();
+ return rid;
+ }
+ }
+
+ void releaseRowIndex(RowIndex rid){
+ d_pool.push_back(rid);
+ }
+
public:
size_t getNumRows() const {
*/
RowIndex addRow(const std::vector<T>& coeffs,
const std::vector<ArithVar>& variables){
- RowIndex ridx = d_rows.size();
- d_rows.push_back(RowVectorT(&d_entries));
+
+ RowIndex ridx = requestRowIndex();
+
+ //RowIndex ridx = d_rows.size();
+ //d_rows.push_back(RowVectorT(&d_entries));
std::vector<Rational>::const_iterator coeffIter = coeffs.begin();
std::vector<ArithVar>::const_iterator varsIter = variables.begin();
EntryID id = i.getID();
removeEntry(id);
}
- }
-
-
- Node rowAsEquality(RowIndex rid, const ArithVarToNodeMap& map){
- using namespace CVC4::kind;
-
- Assert(getRowLength(rid) >= 2);
-
- std::vector<Node> pairs;
- for(RowIterator i = getRow(rid); !i.atEnd(); ++i){
- const Entry& entry = *i;
- ArithVar colVar = entry.getColVar();
-
- Node var = (map.find(colVar))->second;
- Node coeff = mkRationalNode(entry.getCoefficient());
-
- Node mult = NodeBuilder<2>(MULT) << coeff << var;
- pairs.push_back(mult);
- }
-
- Node sum = Node::null();
- if(pairs.size() == 1 ){
- sum = pairs.front();
- }else{
- Assert(pairs.size() >= 2);
- NodeBuilder<> sumBuilder(PLUS);
- sumBuilder.append(pairs);
- sum = sumBuilder;
- }
- return NodeBuilder<2>(EQUAL) << sum << mkRationalNode(d_zero);
+ releaseRowIndex(rid);
}
double densityMeasure() const{
}
}
+ void loadSignQueries(RowIndex rid, DenseMap<int>& target) const{
+
+ RowIterator i = getRow(rid).begin(), i_end = getRow(rid).end();
+ for(; i != i_end; ++i){
+ const MatrixEntry<T>& entry = *i;
+ target.set(entry.getColVar(), entry.getCoefficient().sgn());
+ }
+ }
+
protected:
uint32_t numNonZeroEntries() const { return size(); }
// Set of all of the basic variables in the tableau.
// ArithVarMap<RowIndex> : ArithVar |-> RowIndex
BasicToRowMap d_basic2RowIndex;
+
// RowIndex |-> Basic Variable
- std::vector<ArithVar> d_rowIndex2basic;
+ typedef DenseMap<ArithVar> RowIndexToBasicMap;
+ RowIndexToBasicMap d_rowIndex2basic;
public:
return getRow(basicToRowIndex(basic)).begin();
}
- // RowIterator rowIterator(RowIndex r) const {
- // return getRow(r).begin();
- // }
-
/**
* Adds a row to the tableau.
* The new row is equivalent to:
void removeBasicRow(ArithVar basic);
-
private:
/* Changes the basic variable on the row for basicOld to basicNew. */
void rowPivot(ArithVar basicOld, ArithVar basicNew);
d_unknownsInARow(0),
d_hasDoneWorkSinceCut(false),
d_learner(u),
+ d_numberOfVariables(0),
+ d_pool(),
d_setupLiteralCallback(this),
d_assertionsThatDoNotMatchTheirLiterals(c),
d_nextIntegerCheckVar(0),
d_tableauResetPeriod(10),
d_conflicts(c),
d_raiseConflict(d_conflicts),
+ d_tempVarMalloc(*this),
d_congruenceManager(c, d_constraintDatabase, d_setupLiteralCallback, d_arithvarNodeMap, d_raiseConflict),
d_simplex(d_linEq, d_raiseConflict),
d_constraintDatabase(c, u, d_arithvarNodeMap, d_congruenceManager, d_raiseConflict),
Assert(!isSetup(n));
++(d_statistics.d_statUserVariables);
- ArithVar varN = requestArithVar(n,false);
- setupInitialValue(varN);
+ requestArithVar(n,false);
+ //ArithVar varN = requestArithVar(n,false);
+ //setupInitialValue(varN);
markSetup(n);
d_nlIncomplete = true;
++(d_statistics.d_statUserVariables);
- ArithVar av = requestArithVar(vlNode, false);
- setupInitialValue(av);
+ requestArithVar(vlNode, false);
+ //ArithVar av = requestArithVar(vlNode, false);
+ //setupInitialValue(av);
markSetup(vlNode);
}
ArithVar varSlack = requestArithVar(polyNode, true);
d_tableau.addRow(varSlack, coefficients, variables);
- setupInitialValue(varSlack);
+ setupBasicValue(varSlack);
//Add differences to the difference manager
Polynomial::iterator i = poly.begin(), end = poly.end();
Debug("arith::preregister") << "end arith::preRegisterTerm("<< n <<")" << endl;
}
+void TheoryArith::releaseArithVar(ArithVar v){
+ Assert(d_arithvarNodeMap.hasNode(v));
+
+ d_constraintDatabase.removeVariable(v);
+ d_arithvarNodeMap.remove(v);
+
+ d_pool.push_back(v);
+}
ArithVar TheoryArith::requestArithVar(TNode x, bool slack){
//TODO : The VarList trick is good enough?
Assert(!d_arithvarNodeMap.hasArithVar(x));
Assert(x.getType().isReal());// real or integer
- ArithVar varX = d_variables.size();
- d_variables.push_back(Node(x));
- Debug("integers") << "isInteger[[" << x << "]]: " << x.getType().isInteger() << endl;
+ // ArithVar varX = d_variables.size();
+ // d_variables.push_back(Node(x));
+
+ bool reclaim = !d_pool.empty();
+ ArithVar varX;
+
+ if(reclaim){
+ varX = d_pool.back();
+ d_pool.pop_back();
+
+ d_partialModel.setAssignment(varX, d_DELTA_ZERO, d_DELTA_ZERO);
+ }else{
+ varX = d_numberOfVariables;
+ ++d_numberOfVariables;
+
+ d_slackVars.push_back(true);
+ d_variableTypes.push_back(ATReal);
+ d_simplex.increaseMax();
+
+ d_tableau.increaseSize();
+ d_tableauSizeHasBeenModified = true;
+
+ d_partialModel.initialize(varX, d_DELTA_ZERO);
+ }
+
+ ArithType type;
if(slack){
//The type computation is not quite accurate for Rationals that are integral.
//We'll use the isIntegral check from the polynomial package instead.
Polynomial p = Polynomial::parsePolynomial(x);
- d_variableTypes.push_back(p.isIntegral() ? ATInteger : ATReal);
+ type = p.isIntegral() ? ATInteger : ATReal;
}else{
- d_variableTypes.push_back(nodeToArithType(x));
+ type = nodeToArithType(x);
}
+ d_variableTypes[varX] = type;
+ d_slackVars[varX] = slack;
- d_slackVars.push_back(slack);
-
- d_simplex.increaseMax();
+ d_constraintDatabase.addVariable(varX);
d_arithvarNodeMap.setArithVar(x,varX);
- d_tableau.increaseSize();
- d_tableauSizeHasBeenModified = true;
+ // Debug("integers") << "isInteger[[" << x << "]]: " << x.getType().isInteger() << endl;
- d_constraintDatabase.addVariable(varX);
+ // if(slack){
+ // //The type computation is not quite accurate for Rationals that are integral.
+ // //We'll use the isIntegral check from the polynomial package instead.
+ // Polynomial p = Polynomial::parsePolynomial(x);
+ // d_variableTypes.push_back(p.isIntegral() ? ATInteger : ATReal);
+ // }else{
+ // d_variableTypes.push_back(nodeToArithType(x));
+ // }
+
+ // d_slackVars.push_back(slack);
+
+ // d_simplex.increaseMax();
+
+ // d_tableau.increaseSize();
+ // d_tableauSizeHasBeenModified = true;
+
+ // d_constraintDatabase.addVariable(varX);
Debug("arith::arithvar") << x << " |-> " << varX << endl;
+ Assert(!d_partialModel.hasUpperBound(varX));
+ Assert(!d_partialModel.hasLowerBound(varX));
+
return varX;
}
Assert(theoryOf(n) != THEORY_ARITH || d_arithvarNodeMap.hasArithVar(n));
Assert(d_arithvarNodeMap.hasArithVar(n));
- ArithVar av;
- // The first if is likely dead is likely dead code:
- // if (theoryOf(n) != THEORY_ARITH && !d_arithvarNodeMap.hasArithVar(n)) {
- // // The only way not to get it through pre-register is if it's a foreign term
- // ++(d_statistics.d_statUserVariables);
- // av = requestArithVar(n,false);
- // setupInitialValue(av);
- // } else {
- // // Otherwise, we already have it's variable
- // av = d_arithvarNodeMap.asArithVar(n);
- // }
- av = d_arithvarNodeMap.asArithVar(n);
+ ArithVar av = d_arithvarNodeMap.asArithVar(n);
coeffs.push_back(constant.getValue());
variables.push_back(av);
/* Requirements:
* For basic variables the row must have been added to the tableau.
*/
-void TheoryArith::setupInitialValue(ArithVar x){
+void TheoryArith::setupBasicValue(ArithVar x){
+ Assert(d_tableau.isBasic(x));
- if(!d_tableau.isBasic(x)){
- d_partialModel.initialize(x, d_DELTA_ZERO);
- }else{
+ // if(!d_tableau.isBasic(x)){
+ // d_partialModel.setAssignment(x, d_DELTA_ZERO, d_DELTA_ZERO);
+ // }else{
//If the variable is basic, assertions may have already happened and updates
//may have occured before setting this variable up.
//time instead of register
DeltaRational safeAssignment = d_linEq.computeRowValue(x, true);
DeltaRational assignment = d_linEq.computeRowValue(x, false);
- d_partialModel.initialize(x,safeAssignment);
- d_partialModel.setAssignment(x,assignment);
- }
+ //d_partialModel.initialize(x,safeAssignment);
+ //d_partialModel.setAssignment(x,assignment);
+ d_partialModel.setAssignment(x,safeAssignment,assignment);
+
+ // }
Debug("arith") << "setupVariable("<<x<<")"<<std::endl;
}
context::Context::ScopedPush speculativePush(getSatContext());
//DO NOT TOUCH THE OUTPUTSTREAM
- //TODO: Improve this
- for(ArithVar v = 0, end = d_variables.size(); v != end; ++v){
+ for(var_iterator vi = var_begin(), vend = var_end(); vi != vend; ++vi){
+ ArithVar v = *vi;
if(isInteger(v)){
const DeltaRational& dr = d_partialModel.getAssignment(v);
if(d_partialModel.equalsUpperBound(v, dr) || d_partialModel.equalsLowerBound(v, dr)){
* If this returns true, all integer variables have an integer assignment.
*/
bool TheoryArith::hasIntegerModel(){
- if(d_variables.size() > 0){
+ //if(d_variables.size() > 0){
+ if(getNumberOfVariables()){
const ArithVar rrEnd = d_nextIntegerCheckVar;
do {
//Do not include slack variables
return false;
}
}
- } while((d_nextIntegerCheckVar = (1 + d_nextIntegerCheckVar == d_variables.size() ? 0 : 1 + d_nextIntegerCheckVar)) != rrEnd);
+ } while((d_nextIntegerCheckVar = (1 + d_nextIntegerCheckVar == getNumberOfVariables() ? 0 : 1 + d_nextIntegerCheckVar)) != rrEnd);
}
return true;
}
Assert(d_conflicts.empty());
d_qflraStatus = d_simplex.findModel(fullEffort(effortLevel));
+
switch(d_qflraStatus){
case Result::SAT:
if(newFacts){
*/
void TheoryArith::debugPrintAssertions() {
Debug("arith::print_assertions") << "Assertions:" << endl;
- for (ArithVar i = 0; i < d_variables.size(); ++ i) {
+ for (var_iterator vi = var_begin(), vend = var_end(); vi != vend; ++vi){
+ ArithVar i = *vi;
if (d_partialModel.hasLowerBound(i)) {
Constraint lConstr = d_partialModel.getLowerBoundConstraint(i);
Debug("arith::print_assertions") << lConstr << endl;
void TheoryArith::debugPrintModel(){
Debug("arith::print_model") << "Model:" << endl;
-
- for (ArithVar i = 0; i < d_variables.size(); ++ i) {
- Debug("arith::print_model") << d_variables[i] << " : " <<
- d_partialModel.getAssignment(i);
- if(d_tableau.isBasic(i))
- Debug("arith::print_model") << " (basic)";
- Debug("arith::print_model") << endl;
+ for (var_iterator vi = var_begin(), vend = var_end(); vi != vend; ++vi){
+ ArithVar i = *vi;
+ if(d_arithvarNodeMap.hasNode(i)){
+ Debug("arith::print_model") << d_arithvarNodeMap.asNode(i) << " : " <<
+ d_partialModel.getAssignment(i);
+ if(d_tableau.isBasic(i))
+ Debug("arith::print_model") << " (basic)";
+ Debug("arith::print_model") << endl;
+ }
}
}
relevantDeltaValues.insert(val);
}
- for(ArithVar v = 0; v < d_variables.size(); ++v){
+ for(var_iterator vi = var_begin(), vend = var_end(); vi != vend; ++vi){
+ ArithVar v = *vi;
const DeltaRational& value = d_partialModel.getAssignment(v);
relevantDeltaValues.insert(value);
if( d_partialModel.hasLowerBound(v)){
// TODO:
// This is not very good for user push/pop....
// Revisit when implementing push/pop
- for(ArithVar v = 0; v < d_variables.size(); ++v){
+ for(var_iterator vi = var_begin(), vend = var_end(); vi != vend; ++vi){
+ ArithVar v = *vi;
if(!isSlackVariable(v)){
Node term = d_arithvarNodeMap.asNode(v);
}
bool TheoryArith::entireStateIsConsistent(const string& s){
- typedef std::vector<Node>::const_iterator VarIter;
bool result = true;
- for(VarIter i = d_variables.begin(), end = d_variables.end(); i != end; ++i){
- ArithVar var = d_arithvarNodeMap.asArithVar(*i);
+ for(var_iterator vi = var_begin(), vend = var_end(); vi != vend; ++vi){
+ ArithVar var = *vi;
+ //ArithVar var = d_arithvarNodeMap.asArithVar(*i);
if(!d_partialModel.assignmentIsConsistent(var)){
d_partialModel.printModel(var);
- Warning() << s << ":" << "Assignment is not consistent for " << var << *i;
+ Warning() << s << ":" << "Assignment is not consistent for " << var << d_arithvarNodeMap.asNode(var);
if(d_tableau.isBasic(var)){
Warning() << " (basic)";
}
}
bool TheoryArith::unenqueuedVariablesAreConsistent(){
- typedef std::vector<Node>::const_iterator VarIter;
bool result = true;
- for(VarIter i = d_variables.begin(), end = d_variables.end(); i != end; ++i){
- ArithVar var = d_arithvarNodeMap.asArithVar(*i);
+ for(var_iterator vi = var_begin(), vend = var_end(); vi != vend; ++vi){
+ ArithVar var = *vi;
if(!d_partialModel.assignmentIsConsistent(var)){
if(!d_simplex.debugIsInCollectionQueue(var)){
d_partialModel.printModel(var);
- Warning() << "Unenqueued var is not consistent for " << var << *i;
+ Warning() << "Unenqueued var is not consistent for " << var << d_arithvarNodeMap.asNode(var);
if(d_tableau.isBasic(var)){
Warning() << " (basic)";
}
result = false;
} else if(Debug.isOn("arith::consistency::initial")){
d_partialModel.printModel(var);
- Warning() << "Initial var is not consistent for " << var << *i;
+ Warning() << "Initial var is not consistent for " << var << d_arithvarNodeMap.asNode(var);
if(d_tableau.isBasic(var)){
Warning() << " (basic)";
}
/** Static learner. */
ArithStaticLearner d_learner;
- /**
- * List of the variables in the system.
- * This is needed to keep a positive ref count on slack variables.
- */
- std::vector<Node> d_variables;
+
+ ArithVar d_numberOfVariables;
+ inline ArithVar getNumberOfVariables() const { return d_numberOfVariables; }
+ std::vector<ArithVar> d_pool;
+ void releaseArithVar(ArithVar v);
/**
* The map between arith variables to nodes.
*/
ArithVarNodeMap d_arithvarNodeMap;
+ typedef ArithVarNodeMap::var_iterator var_iterator;
+ var_iterator var_begin() const { return d_arithvarNodeMap.var_begin(); }
+ var_iterator var_end() const { return d_arithvarNodeMap.var_end(); }
NodeSet d_setupNodes;
bool isSetup(Node n) const {
void outputConflicts();
+ class TempVarMalloc : public ArithVarMalloc {
+ private:
+ TheoryArith& d_ta;
+ public:
+ TempVarMalloc(TheoryArith& ta) : d_ta(ta) {}
+ ArithVar request(){
+ Node skolem = mkRealSkolem("tmpVar");
+ return d_ta.requestArithVar(skolem, false);
+ }
+ void release(ArithVar v){ d_ta.releaseArithVar(v); }
+ } d_tempVarMalloc;
+
/**
* A copy of the tableau.
* This is equivalent to the original tableau if d_tableauSizeHasBeenModified
ArithVar requestArithVar(TNode x, bool slack);
/** Initial (not context dependent) sets up for a variable.*/
- void setupInitialValue(ArithVar x);
+ void setupBasicValue(ArithVar x);
/** Initial (not context dependent) sets up for a new slack variable.*/
void setupSlack(TNode left);
d_tableaux.clear();\r
d_ceTableaux.clear();\r
//search for instantiation rows in simplex tableaux\r
- ArithVarToNodeMap avtnm = d_th->d_arithvarNodeMap.getArithVarToNodeMap();\r
- for( ArithVarToNodeMap::iterator it = avtnm.begin(); it != avtnm.end(); ++it ){\r
- ArithVar x = (*it).first;\r
+ ArithVarNodeMap& avnm = d_th->d_arithvarNodeMap;\r
+ ArithVarNodeMap::var_iterator vi, vend;\r
+ for(vi = avnm.var_begin(), vend = avnm.var_end(); vi != vend; ++vi ){\r
+ ArithVar x = *vi;\r
if( d_th->d_partialModel.hasEitherBound( x ) ){\r
- Node n = (*it).second;\r
+ Node n = avnm.asNode(x);\r
Node f;\r
NodeBuilder<> t(kind::PLUS);\r
if( n.getKind()==PLUS ){\r
}\r
\r
void InstStrategySimplex::debugPrint( const char* c ){\r
- ArithVarToNodeMap avtnm = d_th->d_arithvarNodeMap.getArithVarToNodeMap();\r
- for( ArithVarToNodeMap::iterator it = avtnm.begin(); it != avtnm.end(); ++it ){\r
- ArithVar x = (*it).first;\r
- Node n = (*it).second;\r
+ const ArithVarNodeMap& avnm = d_th->d_arithvarNodeMap;\r
+ ArithVarNodeMap::var_iterator vi, vend;\r
+ for(vi = avnm.var_begin(), vend = avnm.var_end(); vi != vend; ++vi ){\r
+ ArithVar x = *vi;\r
+ Node n = avnm.asNode(x);\r
//if( ((TheoryArith*)getTheory())->d_partialModel.hasEitherBound( x ) ){\r
Debug(c) << x << " : " << n << ", bounds = ";\r
if( d_th->d_partialModel.hasLowerBound( x ) ){\r
pop_back();
}
+ /** Returns the key at the back of a non-empty list.*/
Key back() const {
return d_list.back();
}
d_list.pop_back();
}
+
+ /** Adds at least a constant fraction of the elements in the current map to another map. */
+ void splitInto(DenseMap<T>& target){
+ uint32_t targetSize = size()/2;
+ while(size() > targetSize){
+ Key key = back();
+ target.set(key, get(key));
+ pop_back();
+ }
+ }
+
+ /** Adds the current target map to the current map.*/
+ void addAll(const DenseMap<T>& target){
+ for(const_iterator i = target.begin(), e = target.end(); i != e; ++i){
+ Key k = *i;
+ set(k, target[k]);
+ }
+ }
+
+
+
private:
size_t allocated() const {