Adding listeners to Options.
[cvc5.git] / test / unit / theory / theory_arith_white.h
index fe9cbb3883e2acd0ac73227e04eb98ad1264627c..49231071bd16c06c81f0a5c82fd26d45cfa9402e 100644 (file)
@@ -1,16 +1,35 @@
+/*********************                                                        */
+/*! \file theory_arith_white.h
+ ** \verbatim
+ ** Original author: Tim King
+ ** Major contributors: Morgan Deters
+ ** Minor contributors (to current version): Kshitij Bansal, Dejan Jovanovic
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2014  New York University and The University of Iowa
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief [[ Add one-line brief description here ]]
+ **
+ ** [[ Add lengthier description here ]]
+ ** \todo document this file
+ **/
 
 #include <cxxtest/TestSuite.h>
 
-#include "theory/theory.h"
-#include "theory/arith/theory_arith.h"
+#include <vector>
+
+#include "context/context.h"
 #include "expr/node.h"
 #include "expr/node_manager.h"
-#include "context/context.h"
-#include "util/rational.h"
-
+#include "smt/smt_engine.h"
+#include "smt/smt_engine_scope.h"
+#include "theory/arith/theory_arith.h"
+#include "theory/quantifiers_engine.h"
+#include "theory/theory.h"
+#include "theory/theory_engine.h"
 #include "theory/theory_test_utils.h"
-
-#include <vector>
+#include "util/rational.h"
 
 using namespace CVC4;
 using namespace CVC4::theory;
@@ -18,22 +37,28 @@ using namespace CVC4::theory::arith;
 using namespace CVC4::expr;
 using namespace CVC4::context;
 using namespace CVC4::kind;
+using namespace CVC4::smt;
 
 using namespace std;
 
 class TheoryArithWhite : public CxxTest::TestSuite {
 
   Context* d_ctxt;
+  UserContext* d_uctxt;
+  ExprManager* d_em;
   NodeManager* d_nm;
-  NodeManagerScope* d_scope;
+  SmtScope* d_scope;
+  SmtEngine* d_smt;
 
   TestOutputChannel d_outputChannel;
+  LogicInfo d_logicInfo;
   Theory::Effort d_level;
 
   TheoryArith* d_arith;
 
   TypeNode* d_booleanType;
   TypeNode* d_realType;
+  TypeNode* d_intType;
 
   const Rational d_zero;
   const Rational d_one;
@@ -44,37 +69,10 @@ class TheoryArithWhite : public CxxTest::TestSuite {
 
 public:
 
-  TheoryArithWhite() : d_level(Theory::FULL_EFFORT), d_zero(0), d_one(1), debug(false) {}
-
-  void setUp() {
-    d_ctxt = new Context;
-    d_nm = new NodeManager(d_ctxt);
-    d_scope = new NodeManagerScope(d_nm);
-    d_outputChannel.clear();
-    d_arith = new TheoryArith(d_ctxt, d_outputChannel);
-
-    preregistered = new std::set<Node>();
-
-    d_booleanType = new TypeNode(d_nm->booleanType());
-    d_realType = new TypeNode(d_nm->realType());
-
-  }
-
-  void tearDown() {
-    delete d_realType;
-    delete d_booleanType;
-
-    delete preregistered;
-
-    delete d_arith;
-    d_outputChannel.clear();
-    delete d_scope;
-    delete d_nm;
-    delete d_ctxt;
-  }
+  TheoryArithWhite() : d_level(Theory::EFFORT_FULL), d_zero(0), d_one(1), debug(false) {}
 
-  Node fakeTheoryEnginePreprocess(TNode inp){
-    Node rewrite = d_arith->rewrite(inp);
+  void fakeTheoryEnginePreprocess(TNode inp){
+    Node rewrite = inp; //FIXME this needs to enforce that inp is fully rewritten already!
 
     if(debug) cout << rewrite << inp << endl;
 
@@ -97,18 +95,59 @@ public:
       if(debug) cout << n.getId() << " "<< n << endl;
       d_arith->preRegisterTerm(n);
     }
+  }
+
+  void setUp() {
+    d_em = new ExprManager();
+    d_nm = NodeManager::fromExprManager(d_em);
+    d_smt = new SmtEngine(d_em);
+    d_smt->setOption("incremental", CVC4::SExpr(false));
+    d_ctxt = d_smt->d_context;
+    d_uctxt = d_smt->d_userContext;
+    d_scope = new SmtScope(d_smt);
+    d_outputChannel.clear();
+    d_logicInfo.lock();
+
+    // guard against duplicate statistics assertion errors
+    delete d_smt->d_theoryEngine->d_theoryTable[THEORY_ARITH];
+    delete d_smt->d_theoryEngine->d_theoryOut[THEORY_ARITH];
+    d_smt->d_theoryEngine->d_theoryTable[THEORY_ARITH] = NULL;
+    d_smt->d_theoryEngine->d_theoryOut[THEORY_ARITH] = NULL;
+
+    d_arith = new TheoryArith(d_ctxt, d_uctxt, d_outputChannel, Valuation(NULL),
+                              d_logicInfo);
+
+    preregistered = new std::set<Node>();
+
+    d_booleanType = new TypeNode(d_nm->booleanType());
+    d_realType = new TypeNode(d_nm->realType());
+    d_intType = new TypeNode(d_nm->integerType());
+
+  }
+
+  void tearDown() {
+    delete d_intType;
+    delete d_realType;
+    delete d_booleanType;
+
+    delete preregistered;
 
-    return rewrite;
+    delete d_arith;
+    d_outputChannel.clear();
+    delete d_scope;
+    delete d_smt;
+    delete d_em;
   }
 
   void testAssert() {
     Node x = d_nm->mkVar(*d_realType);
     Node c = d_nm->mkConst<Rational>(d_zero);
 
-    Node leq = d_nm->mkNode(LEQ, x, c);
-    Node rLeq = fakeTheoryEnginePreprocess(leq);
+    Node gt = d_nm->mkNode(GT, x, c);
+    Node leq = gt.notNode();
+    fakeTheoryEnginePreprocess(leq);
 
-    d_arith->assertFact(rLeq);
+    d_arith->assertFact(leq, true);
 
     d_arith->check(d_level);
 
@@ -124,189 +163,158 @@ public:
     return dis;
   }
 
-  void testAssertEqualityEagerSplit() {
+  void testTPLt1() {
     Node x = d_nm->mkVar(*d_realType);
-    Node c = d_nm->mkConst<Rational>(d_zero);
-
-    Node eq = d_nm->mkNode(EQUAL, x, c);
-    Node expectedDisjunct = simulateSplit(x,c);
+    Node c0 = d_nm->mkConst<Rational>(d_zero);
+    Node c1 = d_nm->mkConst<Rational>(d_one);
 
-    Node rEq = fakeTheoryEnginePreprocess(eq);
+    Node gt0 = d_nm->mkNode(GT, x, c0);
+    Node gt1 = d_nm->mkNode(GT, x, c1);
+    Node geq1 = d_nm->mkNode(GEQ, x, c1);
+    Node leq0 = gt0.notNode();
+    Node leq1 = gt1.notNode();
+    Node lt1 = geq1.notNode();
 
-    d_arith->assertFact(rEq);
+    fakeTheoryEnginePreprocess(leq0);
+    fakeTheoryEnginePreprocess(leq1);
+    fakeTheoryEnginePreprocess(geq1);
 
+    d_arith->presolve();
+    d_arith->assertFact(lt1, true);
     d_arith->check(d_level);
+    d_arith->propagate(d_level);
 
-    TS_ASSERT_EQUALS(d_outputChannel.getNumCalls(), 1u);
-
-    TS_ASSERT_EQUALS(d_outputChannel.getIthNode(0), expectedDisjunct);
-    TS_ASSERT_EQUALS(d_outputChannel.getIthCallType(0), AUG_LEMMA);
-
-  }
-  void testLtRewrite() {
-    Node x = d_nm->mkVar(*d_realType);
-    Node c = d_nm->mkConst<Rational>(d_zero);
-
-    Node lt = d_nm->mkNode(LT, x, c);
-    Node geq = d_nm->mkNode(GEQ, x, c);
-    Node expectedRewrite = d_nm->mkNode(NOT, geq);
-
-    Node rewrite = d_arith->rewrite(lt);
-
-    TS_ASSERT_EQUALS(expectedRewrite, rewrite);
-  }
-
-  void testBasicConflict() {
-    Node x = d_nm->mkVar(*d_realType);
-    Node c = d_nm->mkConst<Rational>(d_zero);
-
-    Node eq = d_nm->mkNode(EQUAL, x, c);
-    Node lt = d_nm->mkNode(LT, x, c);
-    Node expectedDisjunct = simulateSplit(x,c);
-
-    Node rEq = fakeTheoryEnginePreprocess(eq);
-    Node rLt = fakeTheoryEnginePreprocess(lt);
-
-    d_arith->assertFact(rEq);
-    d_arith->assertFact(rLt);
 
+    Node gt0Orlt1  = NodeBuilder<2>(OR) << gt0 << lt1;
+    Node geq0OrLeq1  = NodeBuilder<2>(OR) << geq1 << leq1;
 
-    d_arith->check(d_level);
+    cout << d_outputChannel.getIthNode(0) << endl << endl;
+    cout << d_outputChannel.getIthNode(1) << endl << endl;
+    cout << d_outputChannel.getIthNode(2) << endl << endl;
 
-    TS_ASSERT_EQUALS(d_outputChannel.getNumCalls(), 2u);
-    TS_ASSERT_EQUALS(d_outputChannel.getIthNode(0), expectedDisjunct);
-    TS_ASSERT_EQUALS(d_outputChannel.getIthCallType(0), AUG_LEMMA);
+    TS_ASSERT_EQUALS(d_outputChannel.getNumCalls(), 3u);
 
-    TS_ASSERT_EQUALS(d_outputChannel.getIthCallType(1), CONFLICT);
+    TS_ASSERT_EQUALS(d_outputChannel.getIthCallType(0), LEMMA);
+    TS_ASSERT_EQUALS(d_outputChannel.getIthNode(0), gt0Orlt1);
 
-    Node expectedClonflict = d_nm->mkNode(AND, rEq, rLt);
+    TS_ASSERT_EQUALS(d_outputChannel.getIthCallType(1), LEMMA);
+    TS_ASSERT_EQUALS(d_outputChannel.getIthNode(1), geq0OrLeq1);
 
-    TS_ASSERT_EQUALS(d_outputChannel.getIthNode(1), expectedClonflict);
+    TS_ASSERT_EQUALS(d_outputChannel.getIthCallType(2), PROPAGATE);
+    TS_ASSERT_EQUALS(d_outputChannel.getIthNode(2), leq1);
   }
 
-  void testBasicPropagate() {
-    Node x = d_nm->mkVar(*d_realType);
-    Node c = d_nm->mkConst<Rational>(d_zero);
-
-    Node eq = d_nm->mkNode(EQUAL, x, c);
-    Node lt = d_nm->mkNode(LT, x, c);
-    Node expectedDisjunct = simulateSplit(x,c);
 
-    Node rEq = fakeTheoryEnginePreprocess(eq);
-    Node rLt = fakeTheoryEnginePreprocess(lt);
+  void testTPLeq0() {
+    Node x = d_nm->mkVar(*d_realType);
+    Node c0 = d_nm->mkConst<Rational>(d_zero);
+    Node c1 = d_nm->mkConst<Rational>(d_one);
 
-    d_arith->assertFact(rEq);
+    Node gt0 = d_nm->mkNode(GT, x, c0);
+    Node gt1 = d_nm->mkNode(GT, x, c1);
+    Node geq1 = d_nm->mkNode(GEQ, x, c1);
+    Node leq0 = gt0.notNode();
+    Node leq1 = gt1.notNode();
+    Node lt1 = geq1.notNode();
 
+    fakeTheoryEnginePreprocess(leq0);
+    fakeTheoryEnginePreprocess(leq1);
+    fakeTheoryEnginePreprocess(geq1);
 
+    d_arith->presolve();
+    d_arith->assertFact(leq0, true);
     d_arith->check(d_level);
     d_arith->propagate(d_level);
 
-    TS_ASSERT_EQUALS(d_outputChannel.getNumCalls(), 2u);
-    TS_ASSERT_EQUALS(d_outputChannel.getIthCallType(0), AUG_LEMMA);
-
-
-    Node expectedProp = d_nm->mkNode(GEQ, x, c);
-    TS_ASSERT_EQUALS(d_outputChannel.getIthCallType(1), PROPOGATE);
-    TS_ASSERT_EQUALS(d_outputChannel.getIthNode(1), expectedProp);
-
-  }
-  void testTPLt1() {
-    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 lt1 = d_nm->mkNode(LT, x, c1);
+    Node gt0Orlt1  = NodeBuilder<2>(OR) << gt0 << lt1;
+    Node geq0OrLeq1  = NodeBuilder<2>(OR) << geq1 << leq1;
 
-    Node rLeq0 = fakeTheoryEnginePreprocess(leq0);
-    Node rLt1 = fakeTheoryEnginePreprocess(lt1);
-    Node rLeq1 = fakeTheoryEnginePreprocess(leq1);
+    cout << d_outputChannel.getIthNode(0) << endl;
+    cout << d_outputChannel.getIthNode(1) << endl;
+    cout << d_outputChannel.getIthNode(2) << endl;
+    cout << d_outputChannel.getIthNode(3) << endl;
 
-    d_arith->assertFact(rLt1);
+    TS_ASSERT_EQUALS(d_outputChannel.getNumCalls(), 4u);
 
+    TS_ASSERT_EQUALS(d_outputChannel.getIthCallType(0), LEMMA);
+    TS_ASSERT_EQUALS(d_outputChannel.getIthNode(0), gt0Orlt1);
 
-    d_arith->check(d_level);
-    d_arith->propagate(d_level);
+    TS_ASSERT_EQUALS(d_outputChannel.getIthCallType(1), LEMMA);
+    TS_ASSERT_EQUALS(d_outputChannel.getIthNode(1), geq0OrLeq1);
 
-#ifdef CVC4_ASSERTIONS
-    TS_ASSERT_THROWS(  d_arith->explain(rLeq0, d_level), AssertionException );
-    TS_ASSERT_THROWS(  d_arith->explain(rLt1, d_level), AssertionException );
-#endif
-    d_arith->explain(rLeq1, d_level);
+    TS_ASSERT_EQUALS(d_outputChannel.getIthCallType(2), PROPAGATE);
+    TS_ASSERT_EQUALS(d_outputChannel.getIthNode(2), lt1 );
 
-    TS_ASSERT_EQUALS(d_outputChannel.getNumCalls(), 2u);
-    TS_ASSERT_EQUALS(d_outputChannel.getIthCallType(0), PROPOGATE);
-    TS_ASSERT_EQUALS(d_outputChannel.getIthCallType(1), EXPLANATION);
-    TS_ASSERT_EQUALS(d_outputChannel.getIthNode(0), leq1);
-    TS_ASSERT_EQUALS(d_outputChannel.getIthNode(1), rLt1);
+    TS_ASSERT_EQUALS(d_outputChannel.getIthCallType(3), PROPAGATE);
+    TS_ASSERT_EQUALS(d_outputChannel.getIthNode(3), leq1);
   }
 
-
-  void testTPLeq0() {
+  void testTPLeq1() {
     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 lt1 = d_nm->mkNode(LT, x, c1);
-
-    Node rLeq0 = fakeTheoryEnginePreprocess(leq0);
-    Node rLt1 = fakeTheoryEnginePreprocess(lt1);
-    Node rLeq1 = fakeTheoryEnginePreprocess(leq1);
-
-    d_arith->assertFact(rLeq0);
+    Node gt0 = d_nm->mkNode(GT, x, c0);
+    Node gt1 = d_nm->mkNode(GT, x, c1);
+    Node geq1 = d_nm->mkNode(GEQ, x, c1);
+    Node leq0 = gt0.notNode();
+    Node leq1 = gt1.notNode();
+    Node lt1 = geq1.notNode();
 
+    fakeTheoryEnginePreprocess(leq0);
+    fakeTheoryEnginePreprocess(leq1);
+    fakeTheoryEnginePreprocess(geq1);
 
+    d_arith->presolve();
+    d_arith->assertFact(leq1, true);
     d_arith->check(d_level);
     d_arith->propagate(d_level);
 
+    Node gt0Orlt1  = NodeBuilder<2>(OR) << gt0 << lt1;
+    Node geq0OrLeq1  = NodeBuilder<2>(OR) << geq1 << leq1;
 
-    d_arith->explain(rLt1, d_level);
-#ifdef CVC4_ASSERTIONS
-    TS_ASSERT_THROWS(  d_arith->explain(rLeq0, d_level), AssertionException );
-#endif
-    d_arith->explain(rLeq1, d_level);
-
-    TS_ASSERT_EQUALS(d_outputChannel.getNumCalls(), 4u);
-    TS_ASSERT_EQUALS(d_outputChannel.getIthCallType(0), PROPOGATE);
-    TS_ASSERT_EQUALS(d_outputChannel.getIthCallType(1), PROPOGATE);
-    TS_ASSERT_EQUALS(d_outputChannel.getIthCallType(2), EXPLANATION);
-    TS_ASSERT_EQUALS(d_outputChannel.getIthCallType(3), EXPLANATION);
+    cout << d_outputChannel.getIthNode(0) << endl;
+    cout << d_outputChannel.getIthNode(1) << endl;
 
-    TS_ASSERT_EQUALS(d_outputChannel.getIthNode(1), rLt1);
-    TS_ASSERT_EQUALS(d_outputChannel.getIthNode(0), rLeq1);
+    TS_ASSERT_EQUALS(d_outputChannel.getNumCalls(), 2u);
 
+    TS_ASSERT_EQUALS(d_outputChannel.getIthCallType(0), LEMMA);
+    TS_ASSERT_EQUALS(d_outputChannel.getIthNode(0), gt0Orlt1);
 
-    TS_ASSERT_EQUALS(d_outputChannel.getIthNode(2), rLeq0);
-    TS_ASSERT_EQUALS(d_outputChannel.getIthNode(3), rLeq0);
+    TS_ASSERT_EQUALS(d_outputChannel.getIthCallType(1), LEMMA);
+    TS_ASSERT_EQUALS(d_outputChannel.getIthNode(1), geq0OrLeq1);
   }
-  void testTPLeq1() {
-    Node x = d_nm->mkVar(*d_realType);
+
+  void testIntNormalForm() {
+    Node x = d_nm->mkVar(*d_intType);
     Node c0 = d_nm->mkConst<Rational>(d_zero);
     Node c1 = d_nm->mkConst<Rational>(d_one);
+    Node c2 = d_nm->mkConst<Rational>(Rational(2));
 
-    Node leq0 = d_nm->mkNode(LEQ, x, c0);
-    Node leq1 = d_nm->mkNode(LEQ, x, c1);
-    Node lt1 = d_nm->mkNode(LT, x, c1);
 
-    Node rLeq0 = fakeTheoryEnginePreprocess(leq0);
-    Node rLt1 = fakeTheoryEnginePreprocess(lt1);
-    Node rLeq1 = fakeTheoryEnginePreprocess(leq1);
+    Node geq0 = d_nm->mkNode(GEQ, x, c0);
+    Node geq1 = d_nm->mkNode(GEQ, x, c1);
+    Node geq2 = d_nm->mkNode(GEQ, x, c2);
 
-    d_arith->assertFact(rLeq1);
+    TS_ASSERT_EQUALS(Rewriter::rewrite(geq0), geq0);
+    TS_ASSERT_EQUALS(Rewriter::rewrite(geq1), geq1);
 
+    Node gt0 = d_nm->mkNode(GT, x, c0);
+    Node gt1 = d_nm->mkNode(GT, x, c1);
 
-    d_arith->check(d_level);
-    d_arith->propagate(d_level);
+    TS_ASSERT_EQUALS(Rewriter::rewrite(gt0), Rewriter::rewrite(geq1));
+    TS_ASSERT_EQUALS(Rewriter::rewrite(gt1), Rewriter::rewrite(geq2));
 
-#ifdef CVC4_ASSERTIONS
-    TS_ASSERT_THROWS(  d_arith->explain(rLeq0, d_level), AssertionException );
-    TS_ASSERT_THROWS(  d_arith->explain(rLeq1, d_level), AssertionException );
-    TS_ASSERT_THROWS(  d_arith->explain(rLt1, d_level), AssertionException );
-#endif
+    Node lt0 = d_nm->mkNode(LT, x, c0);
+    Node lt1 = d_nm->mkNode(LT, x, c1);
 
-    TS_ASSERT_EQUALS(d_outputChannel.getNumCalls(), 0u);
+    TS_ASSERT_EQUALS(Rewriter::rewrite(lt0), Rewriter::rewrite(geq0.notNode()));
+    TS_ASSERT_EQUALS(Rewriter::rewrite(lt1), Rewriter::rewrite(geq1.notNode()));
+
+    Node leq0 = d_nm->mkNode(LEQ, x, c0);
+    Node leq1 = d_nm->mkNode(LEQ, x, c1);
+
+    TS_ASSERT_EQUALS(Rewriter::rewrite(leq0), Rewriter::rewrite(geq1.notNode()));
+    TS_ASSERT_EQUALS(Rewriter::rewrite(leq1), Rewriter::rewrite(geq2.notNode()));
   }
 };