summaryrefslogtreecommitdiff
path: root/src/theory/arith/difference_manager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/theory/arith/difference_manager.cpp')
-rw-r--r--src/theory/arith/difference_manager.cpp169
1 files changed, 144 insertions, 25 deletions
diff --git a/src/theory/arith/difference_manager.cpp b/src/theory/arith/difference_manager.cpp
index b67240d4c..70588bc16 100644
--- a/src/theory/arith/difference_manager.cpp
+++ b/src/theory/arith/difference_manager.cpp
@@ -1,23 +1,131 @@
#include "theory/arith/difference_manager.h"
#include "theory/uf/equality_engine_impl.h"
+#include "theory/arith/constraint.h"
+#include "theory/arith/arith_utilities.h"
+
namespace CVC4 {
namespace theory {
namespace arith {
-DifferenceManager::DifferenceManager(context::Context* c, PropManager& pm)
- : d_literalsQueue(c),
- d_queue(pm),
+DifferenceManager::DifferenceManager(context::Context* c, ConstraintDatabase& cd, TNodeCallBack& setup)
+ : d_conflict(c),
+ d_literalsQueue(c),
+ d_propagatations(c),
+ d_explanationMap(c),
+ d_constraintDatabase(cd),
+ d_setupLiteral(setup),
d_notify(*this),
d_ee(d_notify, c, "theory::arith::DifferenceManager"),
d_false(NodeManager::currentNM()->mkConst<bool>(false)),
d_hasSharedTerms(c, false)
{}
-void DifferenceManager::propagate(TNode x){
+void DifferenceManager::differenceIsZero(Constraint lb, Constraint ub){
+ Assert(lb->isLowerBound());
+ Assert(ub->isUpperBound());
+ Assert(lb->getVariable() == ub->getVariable());
+ Assert(lb->getValue().sgn() == 0);
+ Assert(ub->getValue().sgn() == 0);
+
+ ArithVar s = lb->getVariable();
+ Node reason = ConstraintValue::explainConflict(lb,ub);
+
+ assertLiteral(true, s, reason);
+}
+
+void DifferenceManager::differenceIsZero(Constraint eq){
+ Assert(eq->isEquality());
+ Assert(eq->getValue().sgn() == 0);
+
+ ArithVar s = eq->getVariable();
+
+ //Explain for conflict is correct as these proofs are generated and stored eagerly
+ //These will be safe for propagation later as well
+ Node reason = eq->explainForConflict();
+
+ assertLiteral(true, s, reason);
+}
+
+void DifferenceManager::differenceCannotBeZero(Constraint c){
+ ArithVar s = c->getVariable();
+
+ //Explain for conflict is correct as these proofs are generated and stored eagerly
+ //These will be safe for propagation later as well
+ Node reason = c->explainForConflict();
+ assertLiteral(false, s, reason);
+}
+
+
+bool DifferenceManager::propagate(TNode x){
Debug("arith::differenceManager")<< "DifferenceManager::propagate("<<x<<")"<<std::endl;
+ if(inConflict()){
+ return true;
+ }
+
+ Node rewritten = Rewriter::rewrite(x);
+
+ //Need to still propagate this!
+ if(rewritten.getKind() == kind::CONST_BOOLEAN){
+ pushBack(x);
+ }
- d_queue.propagate(x, explain(x), true);
+ Assert(rewritten.getKind() != kind::CONST_BOOLEAN);
+
+ Constraint c = d_constraintDatabase.lookup(rewritten);
+ if(c == NullConstraint){
+ //using setup as there may not be a corresponding difference literal yet
+ d_setupLiteral(rewritten);
+ c = d_constraintDatabase.lookup(rewritten);
+ Assert(c != NullConstraint);
+ //c = d_constraintDatabase.addLiteral(rewritten);
+ }
+
+ Debug("arith::differenceManager")<< "x is "
+ << c->hasProof() << " "
+ << (x == rewritten) << " "
+ << c->canBePropagated() << " "
+ << c->negationHasProof() << std::endl;
+
+ if(c->negationHasProof()){
+ Node expC = explainInternal(x);
+ Node neg = c->getNegation()->explainForConflict();
+ Node conf = expC.andNode(neg);
+ Node final = flattenAnd(conf);
+
+ d_conflict.set(final);
+ Debug("arith::differenceManager") << "differenceManager found a conflict " << final << std::endl;
+ return false;
+ }
+
+ // Cases for propagation
+ // C : c has a proof
+ // S : x == rewritten
+ // P : c can be propagated
+ //
+ // CSP
+ // 000 : propagate x, and mark C it as being explained
+ // 001 : propagate x, and propagate c after marking it as being explained
+ // 01* : propagate x, mark c but do not propagate c
+ // 10* : propagate x, do not mark c and do not propagate c
+ // 11* : drop the constraint, do not propagate x or c
+
+ if(!c->hasProof() && x != rewritten){
+ pushBack(x, rewritten);
+
+ c->setEqualityEngineProof();
+ if(c->canBePropagated() && !c->assertedToTheTheory()){
+ c->propagate();
+ }
+ }else if(!c->hasProof() && x == rewritten){
+ pushBack(x, rewritten);
+ c->setEqualityEngineProof();
+ }else if(c->hasProof() && x != rewritten){
+ pushBack(x, rewritten);
+ }else{
+ Assert(c->hasProof() && x == rewritten);
+ }
+ return true;
}
void DifferenceManager::explain(TNode literal, std::vector<TNode>& assumptions) {
@@ -37,33 +145,44 @@ void DifferenceManager::explain(TNode literal, std::vector<TNode>& assumptions)
d_ee.explainEquality(lhs, rhs, assumptions);
}
-Node mkAnd(const std::vector<TNode>& conjunctions) {
- Assert(conjunctions.size() > 0);
+void DifferenceManager::enqueueIntoNB(const std::set<TNode> s, NodeBuilder<>& nb){
+ std::set<TNode>::const_iterator it = s.begin();
+ std::set<TNode>::const_iterator it_end = s.end();
+ for(; it != it_end; ++it) {
+ nb << *it;
+ }
+}
- std::set<TNode> all;
- all.insert(conjunctions.begin(), conjunctions.end());
+Node DifferenceManager::explainInternal(TNode internal){
+ std::vector<TNode> assumptions;
+ explain(internal, assumptions);
- if (all.size() == 1) {
- // All the same, or just one
- return conjunctions[0];
- }
+ std::set<TNode> assumptionSet;
+ assumptionSet.insert(assumptions.begin(), assumptions.end());
- NodeBuilder<> conjunction(kind::AND);
- std::set<TNode>::const_iterator it = all.begin();
- std::set<TNode>::const_iterator it_end = all.end();
- while (it != it_end) {
- conjunction << *it;
- ++ it;
+ if (assumptionSet.size() == 1) {
+ // All the same, or just one
+ return assumptions[0];
+ }else{
+ NodeBuilder<> conjunction(kind::AND);
+ enqueueIntoNB(assumptionSet, conjunction);
+ return conjunction;
}
-
- return conjunction;
+}
+Node DifferenceManager::explain(TNode external){
+ Node internal = externalToInternal(external);
+ return explainInternal(internal);
}
+void DifferenceManager::explain(TNode external, NodeBuilder<>& out){
+ Node internal = externalToInternal(external);
-Node DifferenceManager::explain(TNode lit){
std::vector<TNode> assumptions;
- explain(lit, assumptions);
- return mkAnd(assumptions);
+ explain(internal, assumptions);
+ std::set<TNode> assumptionSet;
+ assumptionSet.insert(assumptions.begin(), assumptions.end());
+
+ enqueueIntoNB(assumptionSet, out);
}
void DifferenceManager::addDifference(ArithVar s, Node x, Node y){
@@ -90,7 +209,7 @@ void DifferenceManager::addAssertionToEqualityEngine(bool eq, ArithVar s, TNode
void DifferenceManager::dequeueLiterals(){
Assert(d_hasSharedTerms);
- while(!d_literalsQueue.empty()){
+ while(!d_literalsQueue.empty() && !inConflict()){
const LiteralsQueueElem& front = d_literalsQueue.front();
d_literalsQueue.dequeue();
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback