* improving arithmetic getEqualityStatus
authorDejan Jovanović <dejan.jovanovic@gmail.com>
Thu, 22 Mar 2012 23:09:03 +0000 (23:09 +0000)
committerDejan Jovanović <dejan.jovanovic@gmail.com>
Thu, 22 Mar 2012 23:09:03 +0000 (23:09 +0000)
* some sharing improvements based on model

src/theory/arith/delta_rational.h
src/theory/arith/theory_arith.cpp
src/theory/arith/theory_arith.h
src/theory/uf/theory_uf.cpp

index c004a681f549fc32096a68c32da8a045ff11a3ad..a46dde1cf4b2f18d8ca51aafffe5018e8bbdf3b2 100644 (file)
@@ -89,6 +89,18 @@ public:
     return *(this) + (a * negOne);
   }
 
+  DeltaRational operator/(const Rational& a) const{
+    CVC4::Rational tmpC = c/a;
+    CVC4::Rational tmpK = k/a;
+    return DeltaRational(tmpC, tmpK);
+  }
+
+  DeltaRational operator/(const Integer& a) const{
+    CVC4::Rational tmpC = c/a;
+    CVC4::Rational tmpK = k/a;
+    return DeltaRational(tmpC, tmpK);
+  }
+
   bool operator==(const DeltaRational& other) const{
     return (k == other.k) && (c == other.c);
   }
index 3760e233d5c12214e4938e57c21b7ecfbd668689..590a9f1cfe84229c7fbdcae9dfa9121a64308553 100644 (file)
@@ -334,6 +334,17 @@ Node TheoryArith::AssertEquality(ArithVar x_i, DeltaRational& c_i, TNode origina
 
 void TheoryArith::addSharedTerm(TNode n){
   d_differenceManager.addSharedTerm(n);
+  if(!n.isConst() && !isSetup(n)){
+    Polynomial poly = Polynomial::parsePolynomial(n);
+    Polynomial::iterator it = poly.begin();
+    Polynomial::iterator it_end = poly.end();
+    for (; it != it_end; ++ it) {
+      Monomial m = *it;
+      if (!m.isConstant() && !isSetup(m.getVarList().getNode())) {
+        setupVariableList(m.getVarList());
+      }
+    }
+  }
 }
 
 Node TheoryArith::ppRewrite(TNode atom) {
@@ -1170,6 +1181,95 @@ void TheoryArith::propagate(Effort e) {
   }
 }
 
+bool TheoryArith::getDeltaAtomValue(TNode n) {
+
+  switch (n.getKind()) {
+    case kind::EQUAL: // 2 args
+      return getDeltaValue(n[0]) == getDeltaValue(n[1]);
+    case kind::LT: // 2 args
+      return getDeltaValue(n[0]) < getDeltaValue(n[1]);
+    case kind::LEQ: // 2 args
+      return getDeltaValue(n[0]) <= getDeltaValue(n[1]);
+    case kind::GT: // 2 args
+      return getDeltaValue(n[0]) > getDeltaValue(n[1]);
+    case kind::GEQ: // 2 args
+      return getDeltaValue(n[0]) >= getDeltaValue(n[1]);
+    default:
+      Unreachable();
+  }
+}
+
+
+DeltaRational TheoryArith::getDeltaValue(TNode n) {
+
+  Debug("arith::value") << n << std::endl;
+
+  switch(n.getKind()) {
+
+  case kind::CONST_INTEGER:
+    return Rational(n.getConst<Integer>());
+
+  case kind::CONST_RATIONAL:
+    return n.getConst<Rational>();
+
+  case kind::PLUS: { // 2+ args
+    DeltaRational value(0);
+    for(TNode::iterator i = n.begin(),
+            iend = n.end();
+          i != iend;
+          ++i) {
+      value = value + getDeltaValue(*i);
+    }
+    return value;
+  }
+
+  case kind::MULT: { // 2+ args
+    Assert(n.getNumChildren() == 2 && n[0].isConst());
+    DeltaRational value(1);
+    if (n[0].getKind() == kind::CONST_INTEGER) {
+      return getDeltaValue(n[1]) * n[0].getConst<Integer>();
+    }
+    if (n[0].getKind() == kind::CONST_RATIONAL) {
+      return getDeltaValue(n[1]) * n[0].getConst<Rational>();
+    }
+    Unreachable();
+  }
+
+  case kind::MINUS: // 2 args
+    // should have been rewritten
+    Unreachable();
+
+  case kind::UMINUS: // 1 arg
+    // should have been rewritten
+    Unreachable();
+
+  case kind::DIVISION: // 2 args
+    Assert(n[1].isConst());
+    if (n[1].getKind() == kind::CONST_RATIONAL) {
+      return getDeltaValue(n[0]) / n[0].getConst<Rational>();
+    }
+    if (n[1].getKind() == kind::CONST_INTEGER) {
+      return getDeltaValue(n[0]) / n[0].getConst<Integer>();
+    }
+    Unreachable();
+
+
+  default:
+  {
+    ArithVar var = d_arithvarNodeMap.asArithVar(n);
+
+    if(d_removedRows.find(var) != d_removedRows.end()){
+      Node eq = d_removedRows.find(var)->second;
+      Assert(n == eq[0]);
+      Node rhs = eq[1];
+      return getDeltaValue(rhs);
+    }
+
+    return d_partialModel.getAssignment(var);
+  }
+  }
+}
+
 Node TheoryArith::getValue(TNode n) {
   NodeManager* nodeManager = NodeManager::currentNM();
 
@@ -1389,7 +1489,7 @@ void TheoryArith::presolve(){
 }
 
 EqualityStatus TheoryArith::getEqualityStatus(TNode a, TNode b) {
-  if (getValue(a) == getValue(b)) {
+  if (getDeltaValue(a) == getDeltaValue(b)) {
     return EQUALITY_TRUE_IN_MODEL;
   } else {
     return EQUALITY_FALSE_IN_MODEL;
index 929ef11739dfcd764304b65bf50132814a32dae4..ec2df3e175c6e0cdc82dcbd856c51d844994e517 100644 (file)
@@ -249,6 +249,13 @@ private:
 
   /** This implements the Simplex decision procedure. */
   SimplexDecisionProcedure d_simplex;
+
+  /** Internal model value for the atom */
+  bool getDeltaAtomValue(TNode n);
+
+  /** Internal model value for the node */
+  DeltaRational getDeltaValue(TNode n);
+
 public:
   TheoryArith(context::Context* c, context::UserContext* u, OutputChannel& out, Valuation valuation);
   virtual ~TheoryArith();
index f0694462d05b296e4b994b3f8665166fb14cb5ed..a3e347b90ef4c08f5eeceaa0635a8b71057cc757 100644 (file)
@@ -488,6 +488,19 @@ void TheoryUF::computeCareGraph() {
           TNode x_shared = d_equalityEngine.getTriggerTermRepresentative(x);
           TNode y_shared = d_equalityEngine.getTriggerTermRepresentative(y);
 
+          EqualityStatus eqStatusDomain = d_valuation.getEqualityStatus(x_shared, y_shared);
+          switch (eqStatusDomain) {
+          case EQUALITY_FALSE_AND_PROPAGATED:
+          case EQUALITY_FALSE:
+          case EQUALITY_FALSE_IN_MODEL:
+            somePairIsDisequal = true;
+            continue;
+            break;
+          default:
+            break;
+            // nothing
+          }
+
           // Otherwise, we need to figure it out
           Debug("uf::sharing") << "TheoryUf::computeCareGraph(): adding to care-graph" << std::endl;
           currentPairs.push_back(make_pair(x_shared, y_shared));