d_presolveHasBeenCalled(false),
d_tableauResetDensity(1.6),
d_tableauResetPeriod(10),
- d_propagator(c),
+ d_propagator(c, out),
d_simplex(d_partialModel, d_tableau),
d_DELTA_ZERO(0),
d_statistics()
//d_tableauSizeHistory("theory::arith::tableauSizeHistory"),
d_currSetToSmaller("theory::arith::currSetToSmaller", 0),
d_smallerSetToCurr("theory::arith::smallerSetToCurr", 0),
- d_restartTimer("theory::arith::restartTimer"),
- d_diseqSplitCalls("theory::arith::diseqSplitCalls", 0),
- d_diseqSplitTimer("theory::arith::diseqSplitTimer")
+ d_restartTimer("theory::arith::restartTimer")
{
StatisticsRegistry::registerStat(&d_statUserVariables);
StatisticsRegistry::registerStat(&d_statSlackVariables);
StatisticsRegistry::registerStat(&d_currSetToSmaller);
StatisticsRegistry::registerStat(&d_smallerSetToCurr);
StatisticsRegistry::registerStat(&d_restartTimer);
-
- StatisticsRegistry::registerStat(&d_diseqSplitCalls);
- StatisticsRegistry::registerStat(&d_diseqSplitTimer);
}
TheoryArith::Statistics::~Statistics(){
StatisticsRegistry::unregisterStat(&d_currSetToSmaller);
StatisticsRegistry::unregisterStat(&d_smallerSetToCurr);
StatisticsRegistry::unregisterStat(&d_restartTimer);
-
- StatisticsRegistry::unregisterStat(&d_diseqSplitCalls);
- StatisticsRegistry::unregisterStat(&d_diseqSplitTimer);
}
void TheoryArith::staticLearning(TNode n, NodeBuilder<>& learned) {
setupInitialValue(varN);
}
- if(n.getKind() == PLUS){
- Assert(!n.hasAttribute(Slack()));
- setupSlack(n);
- }
-
if(isRelationOperator(k)){
Assert(Comparison::isNormalAtom(n));
- Assert(n[0].getKind() != PLUS || (n[0]).hasAttribute(Slack()) );
+
+
d_propagator.addAtom(n);
+
+ TNode left = n[0];
+ TNode right = n[1];
+ if(left.getKind() == PLUS){
+ //We may need to introduce a slack variable.
+ Assert(left.getNumChildren() >= 2);
+ if(!left.hasAttribute(Slack())){
+ setupSlack(left);
+ }
+ }
}
Debug("arith_preregister") << "end arith::preRegisterTerm("<< n <<")"<< endl;
}
}
void TheoryArith::splitDisequalities(){
- TimerStat::CodeTimer codeTimer(d_statistics.d_diseqSplitTimer);
- ++(d_statistics.d_diseqSplitCalls);
-
context::CDSet<Node, NodeHashFunction>::iterator it = d_diseq.begin();
context::CDSet<Node, NodeHashFunction>::iterator it_end = d_diseq.end();
for(; it != it_end; ++ it) {
}
void TheoryArith::propagate(Effort e) {
- while(d_propagator.hasMoreLemmas()){
- Node lemma = d_propagator.getNextLemma();
- d_out->lemma(lemma);
- }
-
if(quickCheckOrMore(e)){
while(d_simplex.hasMoreLemmas()){
Node lemma = d_simplex.popLemma();
IntStat d_smallerSetToCurr;
TimerStat d_restartTimer;
- IntStat d_diseqSplitCalls;
- TimerStat d_diseqSplitTimer;
-
Statistics();
~Statistics();
};
using namespace std;
-ArithUnatePropagator::ArithUnatePropagator(context::Context* cxt) :
- d_orderedListMap()
+ArithUnatePropagator::ArithUnatePropagator(context::Context* cxt, OutputChannel& out) :
+ d_arithOut(out), d_orderedListMap()
{ }
bool ArithUnatePropagator::leftIsSetup(TNode left){
Debug("arith-propagate") << "ArithUnatePropagator::addImplication";
Debug("arith-propagate") << "(" << a << ", " << b <<")" << endl;
- addLemma(imp);
+ d_arithOut.lemma(imp);
}
#include "theory/arith/ordered_set.h"
#include <ext/hash_map>
-#include <queue>
namespace CVC4 {
namespace theory {
class ArithUnatePropagator {
private:
- typedef std::queue<Node> LemmaQueue;
- /** Unate implication queue */
- LemmaQueue d_lemmas;
+ /**
+ * OutputChannel for the theory of arithmetic.
+ * The propagator uses this to pass implications back to the SAT solver.
+ */
+ OutputChannel& d_arithOut;
struct OrderedSetTriple {
OrderedSet d_leqSet;
NodeToOrderedSetMap d_orderedListMap;
public:
- ArithUnatePropagator(context::Context* cxt);
+ ArithUnatePropagator(context::Context* cxt, OutputChannel& arith);
/**
* Adds an atom to the propagator.
/** Returns true if v has been added as a left hand side in an atom */
bool hasAnyAtoms(TNode v);
- bool hasMoreLemmas() const { return !d_lemmas.empty(); }
-
- Node getNextLemma() {
- Node lemma = d_lemmas.front();
- d_lemmas.pop();
- return lemma;
- }
private:
- void addLemma(Node lemma) {
- d_lemmas.push(lemma);
- }
-
-
OrderedSetTriple& getOrderedSetTriple(TNode left);
OrderedSet& getEqSet(TNode left);
OrderedSet& getLeqSet(TNode left);
d_arith->check(d_level);
- TS_ASSERT_EQUALS(d_outputChannel.getNumCalls(), 0u);
-
d_arith->propagate(d_level);
Node leq0ThenLeq1 = NodeBuilder<2>(IMPLIES) << leq0 << (leq1);
d_arith->check(d_level);
- TS_ASSERT_EQUALS(d_outputChannel.getNumCalls(), 0u);
-
- d_arith->propagate(d_level);
Node leq0ThenLeq1 = NodeBuilder<2>(IMPLIES) << leq0 << (leq1);
Node lt1ThenLeq1 = NodeBuilder<2>(IMPLIES) << lt1 << leq1;
d_arith->check(d_level);
- TS_ASSERT_EQUALS(d_outputChannel.getNumCalls(), 0u);
-
d_arith->propagate(d_level);
Node leq0ThenLeq1 = NodeBuilder<2>(IMPLIES) << leq0 << (leq1);
TS_ASSERT_EQUALS(d_outputChannel.getIthCallType(2), LEMMA);
TS_ASSERT_EQUALS(d_outputChannel.getIthNode(2), leq0ThenLt1);
}
-
- void testConflict() {
- Node x = d_nm->mkVar(*d_realType);
- Node c0 = d_nm->mkConst<Rational>(d_zero);
- Node c1 = d_nm->mkConst<Rational>(d_one);
-
- Node leq0 = d_nm->mkNode(LEQ, x, c0);
- Node leq1 = d_nm->mkNode(LEQ, x, c1);
- Node gt1 = d_nm->mkNode(NOT, leq1);
-
- fakeTheoryEnginePreprocess(leq0);
- fakeTheoryEnginePreprocess(leq1);
-
- d_arith->assertFact(leq0);
- d_arith->assertFact(gt1);
-
- d_arith->check(d_level);
-
-
- Node conf = d_nm->mkNode(AND, leq0, gt1);
- TS_ASSERT_EQUALS(d_outputChannel.getNumCalls(), 1u);
-
- TS_ASSERT_EQUALS(d_outputChannel.getIthCallType(0), CONFLICT);
- TS_ASSERT_EQUALS(d_outputChannel.getIthNode(0), conf);
- }
};