diff options
author | Andrew Reynolds <andrew.j.reynolds@gmail.com> | 2021-08-17 12:52:53 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-17 12:52:53 -0500 |
commit | 0783307a81f3f27194d7c08e1e8f32123432b9b8 (patch) | |
tree | 080b4b48b245aa2f055033708b6788a92610ce55 /src/theory | |
parent | 1f9f73a863401da3bc06fc82bb06f0afe947cce9 (diff) | |
parent | e8f18dd65c829c3c12158d57e1fc7d2c9dcdcfd4 (diff) |
Merge branch 'master' into rmMaybermMaybe
Diffstat (limited to 'src/theory')
56 files changed, 473 insertions, 551 deletions
diff --git a/src/theory/arith/arith_state.cpp b/src/theory/arith/arith_state.cpp index 93d410bf8..3d43077e5 100644 --- a/src/theory/arith/arith_state.cpp +++ b/src/theory/arith/arith_state.cpp @@ -21,10 +21,8 @@ namespace cvc5 { namespace theory { namespace arith { -ArithState::ArithState(context::Context* c, - context::UserContext* u, - Valuation val) - : TheoryState(c, u, val), d_parent(nullptr) +ArithState::ArithState(Env& env, Valuation val) + : TheoryState(env, val), d_parent(nullptr) { } diff --git a/src/theory/arith/arith_state.h b/src/theory/arith/arith_state.h index a54ae6bf0..0f0f02f02 100644 --- a/src/theory/arith/arith_state.h +++ b/src/theory/arith/arith_state.h @@ -38,7 +38,8 @@ class TheoryArithPrivate; class ArithState : public TheoryState { public: - ArithState(context::Context* c, context::UserContext* u, Valuation val); + ArithState(Env& env, + Valuation val); ~ArithState() {} /** Are we currently in conflict? */ bool isInConflict() const override; diff --git a/src/theory/arith/nl/nonlinear_extension.cpp b/src/theory/arith/nl/nonlinear_extension.cpp index a8b056d45..785127db5 100644 --- a/src/theory/arith/nl/nonlinear_extension.cpp +++ b/src/theory/arith/nl/nonlinear_extension.cpp @@ -48,7 +48,7 @@ NonlinearExtension::NonlinearExtension(TheoryArith& containing, d_extTheory(d_extTheoryCb, containing.getSatContext(), containing.getUserContext(), - containing.getOutputChannel()), + d_im), d_model(containing.getSatContext()), d_trSlv(d_im, d_model, pnm, containing.getUserContext()), d_extState(d_im, d_model, pnm, containing.getUserContext()), diff --git a/src/theory/arith/theory_arith.cpp b/src/theory/arith/theory_arith.cpp index 2c7187089..37069d8b8 100644 --- a/src/theory/arith/theory_arith.cpp +++ b/src/theory/arith/theory_arith.cpp @@ -35,24 +35,20 @@ namespace cvc5 { namespace theory { namespace arith { -TheoryArith::TheoryArith(context::Context* c, - context::UserContext* u, - OutputChannel& out, - Valuation valuation, - const LogicInfo& logicInfo, - ProofNodeManager* pnm) - : Theory(THEORY_ARITH, c, u, out, valuation, logicInfo, pnm), +TheoryArith::TheoryArith(Env& env, OutputChannel& out, Valuation valuation) + : Theory(THEORY_ARITH, env, out, valuation), d_ppRewriteTimer(smtStatisticsRegistry().registerTimer( "theory::arith::ppRewriteTimer")), - d_astate(c, u, valuation), - d_im(*this, d_astate, pnm), - d_ppre(c, pnm), - d_bab(d_astate, d_im, d_ppre, pnm), + d_astate(env, valuation), + d_im(*this, d_astate, d_pnm), + d_ppre(getSatContext(), d_pnm), + d_bab(d_astate, d_im, d_ppre, d_pnm), d_eqSolver(nullptr), - d_internal(new TheoryArithPrivate(*this, c, u, d_bab, pnm)), + d_internal(new TheoryArithPrivate( + *this, getSatContext(), getUserContext(), d_bab, d_pnm)), d_nonlinearExtension(nullptr), - d_opElim(pnm, logicInfo), - d_arithPreproc(d_astate, d_im, pnm, d_opElim), + d_opElim(d_pnm, getLogicInfo()), + d_arithPreproc(d_astate, d_im, d_pnm, d_opElim), d_rewriter(d_opElim) { // currently a cyclic dependency to TheoryArithPrivate diff --git a/src/theory/arith/theory_arith.h b/src/theory/arith/theory_arith.h index ee99f44e8..4b0c88fd2 100644 --- a/src/theory/arith/theory_arith.h +++ b/src/theory/arith/theory_arith.h @@ -44,12 +44,7 @@ class TheoryArithPrivate; class TheoryArith : public Theory { friend class TheoryArithPrivate; public: - TheoryArith(context::Context* c, - context::UserContext* u, - OutputChannel& out, - Valuation valuation, - const LogicInfo& logicInfo, - ProofNodeManager* pnm = nullptr); + TheoryArith(Env& env, OutputChannel& out, Valuation valuation); virtual ~TheoryArith(); //--------------------------------- initialization diff --git a/src/theory/arrays/theory_arrays.cpp b/src/theory/arrays/theory_arrays.cpp index 6c9c162ab..1a6dfedbb 100644 --- a/src/theory/arrays/theory_arrays.cpp +++ b/src/theory/arrays/theory_arrays.cpp @@ -55,14 +55,11 @@ const bool d_solveWrite2 = false; //bool d_useNonLinearOpt = true; //bool d_eagerIndexSplitting = false; -TheoryArrays::TheoryArrays(context::Context* c, - context::UserContext* u, +TheoryArrays::TheoryArrays(Env& env, OutputChannel& out, Valuation valuation, - const LogicInfo& logicInfo, - ProofNodeManager* pnm, std::string name) - : Theory(THEORY_ARRAYS, c, u, out, valuation, logicInfo, pnm, name), + : Theory(THEORY_ARRAYS, env, out, valuation, name), d_numRow( smtStatisticsRegistry().registerInt(name + "number of Row lemmas")), d_numExt( @@ -83,37 +80,37 @@ TheoryArrays::TheoryArrays(context::Context* c, name + "number of setModelVal splits")), d_numSetModelValConflicts(smtStatisticsRegistry().registerInt( name + "number of setModelVal conflicts")), - d_ppEqualityEngine(u, name + "pp", true), - d_ppFacts(u), - d_rewriter(pnm), - d_state(c, u, valuation), - d_im(*this, d_state, pnm), - d_literalsToPropagate(c), - d_literalsToPropagateIndex(c, 0), - d_isPreRegistered(c), - d_mayEqualEqualityEngine(c, name + "mayEqual", true), + d_ppEqualityEngine(getUserContext(), name + "pp", true), + d_ppFacts(getUserContext()), + d_rewriter(d_pnm), + d_state(env, valuation), + d_im(*this, d_state, d_pnm), + d_literalsToPropagate(getSatContext()), + d_literalsToPropagateIndex(getSatContext(), 0), + d_isPreRegistered(getSatContext()), + d_mayEqualEqualityEngine(getSatContext(), name + "mayEqual", true), d_notify(*this), - d_backtracker(c), - d_infoMap(c, &d_backtracker, name), - d_mergeQueue(c), + d_backtracker(getSatContext()), + d_infoMap(getSatContext(), &d_backtracker, name), + d_mergeQueue(getSatContext()), d_mergeInProgress(false), - d_RowQueue(c), - d_RowAlreadyAdded(u), - d_sharedArrays(c), - d_sharedOther(c), - d_sharedTerms(c, false), - d_reads(c), - d_constReadsList(c), + d_RowQueue(getSatContext()), + d_RowAlreadyAdded(getUserContext()), + d_sharedArrays(getSatContext()), + d_sharedOther(getSatContext()), + d_sharedTerms(getSatContext(), false), + d_reads(getSatContext()), + d_constReadsList(getSatContext()), d_constReadsContext(new context::Context()), - d_contextPopper(c, d_constReadsContext), - d_skolemIndex(c, 0), - d_decisionRequests(c), - d_permRef(c), - d_modelConstraints(c), - d_lemmasSaved(c), - d_defValues(c), + d_contextPopper(getSatContext(), d_constReadsContext), + d_skolemIndex(getSatContext(), 0), + d_decisionRequests(getSatContext()), + d_permRef(getSatContext()), + d_modelConstraints(getSatContext()), + d_lemmasSaved(getSatContext()), + d_defValues(getSatContext()), d_readTableContext(new context::Context()), - d_arrayMerges(c), + d_arrayMerges(getSatContext()), d_inCheckModel(false), d_dstrat(new TheoryArraysDecisionStrategy(this)), d_dstratInit(false) diff --git a/src/theory/arrays/theory_arrays.h b/src/theory/arrays/theory_arrays.h index 772fc1b79..d255e44f1 100644 --- a/src/theory/arrays/theory_arrays.h +++ b/src/theory/arrays/theory_arrays.h @@ -132,12 +132,9 @@ class TheoryArrays : public Theory { IntStat d_numSetModelValConflicts; public: - TheoryArrays(context::Context* c, - context::UserContext* u, + TheoryArrays(Env& env, OutputChannel& out, Valuation valuation, - const LogicInfo& logicInfo, - ProofNodeManager* pnm = nullptr, std::string name = "theory::arrays::"); ~TheoryArrays(); diff --git a/src/theory/bags/solver_state.cpp b/src/theory/bags/solver_state.cpp index 6c80e00bd..50c6919fa 100644 --- a/src/theory/bags/solver_state.cpp +++ b/src/theory/bags/solver_state.cpp @@ -27,10 +27,7 @@ namespace cvc5 { namespace theory { namespace bags { -SolverState::SolverState(context::Context* c, - context::UserContext* u, - Valuation val) - : TheoryState(c, u, val) +SolverState::SolverState(Env& env, Valuation val) : TheoryState(env, val) { d_true = NodeManager::currentNM()->mkConst(true); d_false = NodeManager::currentNM()->mkConst(false); diff --git a/src/theory/bags/solver_state.h b/src/theory/bags/solver_state.h index 9c2222e95..68fffacbd 100644 --- a/src/theory/bags/solver_state.h +++ b/src/theory/bags/solver_state.h @@ -29,7 +29,8 @@ namespace bags { class SolverState : public TheoryState { public: - SolverState(context::Context* c, context::UserContext* u, Valuation val); + SolverState(Env& env, + Valuation val); /** * This function adds the bag representative n to the set d_bags if it is not diff --git a/src/theory/bags/theory_bags.cpp b/src/theory/bags/theory_bags.cpp index 580d26c08..f8483064d 100644 --- a/src/theory/bags/theory_bags.cpp +++ b/src/theory/bags/theory_bags.cpp @@ -27,15 +27,10 @@ namespace cvc5 { namespace theory { namespace bags { -TheoryBags::TheoryBags(context::Context* c, - context::UserContext* u, - OutputChannel& out, - Valuation valuation, - const LogicInfo& logicInfo, - ProofNodeManager* pnm) - : Theory(THEORY_BAGS, c, u, out, valuation, logicInfo, pnm), - d_state(c, u, valuation), - d_im(*this, d_state, pnm), +TheoryBags::TheoryBags(Env& env, OutputChannel& out, Valuation valuation) + : Theory(THEORY_BAGS, env, out, valuation), + d_state(env, valuation), + d_im(*this, d_state, d_pnm), d_ig(&d_state, &d_im), d_notify(*this, d_im), d_statistics(), diff --git a/src/theory/bags/theory_bags.h b/src/theory/bags/theory_bags.h index 4ed131e64..671623d05 100644 --- a/src/theory/bags/theory_bags.h +++ b/src/theory/bags/theory_bags.h @@ -36,12 +36,7 @@ class TheoryBags : public Theory { public: /** Constructs a new instance of TheoryBags w.r.t. the provided contexts. */ - TheoryBags(context::Context* c, - context::UserContext* u, - OutputChannel& out, - Valuation valuation, - const LogicInfo& logicInfo, - ProofNodeManager* pnm); + TheoryBags(Env& env, OutputChannel& out, Valuation valuation); ~TheoryBags() override; //--------------------------------- initialization diff --git a/src/theory/booleans/theory_bool.cpp b/src/theory/booleans/theory_bool.cpp index 3aac5ecfb..33bb820b4 100644 --- a/src/theory/booleans/theory_bool.cpp +++ b/src/theory/booleans/theory_bool.cpp @@ -32,13 +32,8 @@ namespace cvc5 { namespace theory { namespace booleans { -TheoryBool::TheoryBool(context::Context* c, - context::UserContext* u, - OutputChannel& out, - Valuation valuation, - const LogicInfo& logicInfo, - ProofNodeManager* pnm) - : Theory(THEORY_BOOL, c, u, out, valuation, logicInfo, pnm) +TheoryBool::TheoryBool(Env& env, OutputChannel& out, Valuation valuation) + : Theory(THEORY_BOOL, env, out, valuation) { } diff --git a/src/theory/booleans/theory_bool.h b/src/theory/booleans/theory_bool.h index dd574a455..e0b7e6511 100644 --- a/src/theory/booleans/theory_bool.h +++ b/src/theory/booleans/theory_bool.h @@ -29,12 +29,7 @@ namespace booleans { class TheoryBool : public Theory { public: - TheoryBool(context::Context* c, - context::UserContext* u, - OutputChannel& out, - Valuation valuation, - const LogicInfo& logicInfo, - ProofNodeManager* pnm = nullptr); + TheoryBool(Env& env, OutputChannel& out, Valuation valuation); /** get the official theory rewriter of this theory */ TheoryRewriter* getTheoryRewriter() override; diff --git a/src/theory/builtin/theory_builtin.cpp b/src/theory/builtin/theory_builtin.cpp index 1db03d22b..092bcc9ab 100644 --- a/src/theory/builtin/theory_builtin.cpp +++ b/src/theory/builtin/theory_builtin.cpp @@ -25,15 +25,10 @@ namespace cvc5 { namespace theory { namespace builtin { -TheoryBuiltin::TheoryBuiltin(context::Context* c, - context::UserContext* u, - OutputChannel& out, - Valuation valuation, - const LogicInfo& logicInfo, - ProofNodeManager* pnm) - : Theory(THEORY_BUILTIN, c, u, out, valuation, logicInfo, pnm), - d_state(c, u, valuation), - d_im(*this, d_state, pnm, "theory::builtin::") +TheoryBuiltin::TheoryBuiltin(Env& env, OutputChannel& out, Valuation valuation) + : Theory(THEORY_BUILTIN, env, out, valuation), + d_state(env, valuation), + d_im(*this, d_state, d_pnm, "theory::builtin::") { // indicate we are using the default theory state and inference managers d_theoryState = &d_state; diff --git a/src/theory/builtin/theory_builtin.h b/src/theory/builtin/theory_builtin.h index 72485f0ea..29a3cfb36 100644 --- a/src/theory/builtin/theory_builtin.h +++ b/src/theory/builtin/theory_builtin.h @@ -31,12 +31,7 @@ namespace builtin { class TheoryBuiltin : public Theory { public: - TheoryBuiltin(context::Context* c, - context::UserContext* u, - OutputChannel& out, - Valuation valuation, - const LogicInfo& logicInfo, - ProofNodeManager* pnm = nullptr); + TheoryBuiltin(Env& env, OutputChannel& out, Valuation valuation); /** get the official theory rewriter of this theory */ TheoryRewriter* getTheoryRewriter() override; diff --git a/src/theory/bv/theory_bv.cpp b/src/theory/bv/theory_bv.cpp index 547d24b23..d4926a785 100644 --- a/src/theory/bv/theory_bv.cpp +++ b/src/theory/bv/theory_bv.cpp @@ -30,35 +30,33 @@ namespace cvc5 { namespace theory { namespace bv { -TheoryBV::TheoryBV(context::Context* c, - context::UserContext* u, +TheoryBV::TheoryBV(Env& env, OutputChannel& out, Valuation valuation, - const LogicInfo& logicInfo, - ProofNodeManager* pnm, std::string name) - : Theory(THEORY_BV, c, u, out, valuation, logicInfo, pnm, name), + : Theory(THEORY_BV, env, out, valuation, name), d_internal(nullptr), d_rewriter(), - d_state(c, u, valuation), + d_state(env, valuation), d_im(*this, d_state, nullptr, "theory::bv::"), d_notify(d_im), - d_invalidateModelCache(c, true), + d_invalidateModelCache(getSatContext(), true), d_stats("theory::bv::") { switch (options::bvSolver()) { case options::BVSolver::BITBLAST: - d_internal.reset(new BVSolverBitblast(&d_state, d_im, pnm)); + d_internal.reset(new BVSolverBitblast(&d_state, d_im, d_pnm)); break; case options::BVSolver::LAYERED: - d_internal.reset(new BVSolverLayered(*this, c, u, pnm, name)); + d_internal.reset(new BVSolverLayered( + *this, getSatContext(), getUserContext(), d_pnm, name)); break; default: AlwaysAssert(options::bvSolver() == options::BVSolver::BITBLAST_INTERNAL); - d_internal.reset(new BVSolverBitblastInternal(&d_state, d_im, pnm)); + d_internal.reset(new BVSolverBitblastInternal(&d_state, d_im, d_pnm)); } d_theoryState = &d_state; d_inferManager = &d_im; diff --git a/src/theory/bv/theory_bv.h b/src/theory/bv/theory_bv.h index da44d7022..b4afb5f5d 100644 --- a/src/theory/bv/theory_bv.h +++ b/src/theory/bv/theory_bv.h @@ -39,12 +39,9 @@ class TheoryBV : public Theory friend class BVSolverLayered; public: - TheoryBV(context::Context* c, - context::UserContext* u, + TheoryBV(Env& env, OutputChannel& out, Valuation valuation, - const LogicInfo& logicInfo, - ProofNodeManager* pnm = nullptr, std::string name = ""); ~TheoryBV(); diff --git a/src/theory/datatypes/theory_datatypes.cpp b/src/theory/datatypes/theory_datatypes.cpp index 50c955d48..2162c4d14 100644 --- a/src/theory/datatypes/theory_datatypes.cpp +++ b/src/theory/datatypes/theory_datatypes.cpp @@ -47,24 +47,20 @@ namespace cvc5 { namespace theory { namespace datatypes { -TheoryDatatypes::TheoryDatatypes(Context* c, - UserContext* u, +TheoryDatatypes::TheoryDatatypes(Env& env, OutputChannel& out, - Valuation valuation, - const LogicInfo& logicInfo, - ProofNodeManager* pnm) - : Theory(THEORY_DATATYPES, c, u, out, valuation, logicInfo, pnm), - d_term_sk(u), - d_labels(c), - d_selector_apps(c), - d_collectTermsCache(c), - d_collectTermsCacheU(u), - d_functionTerms(c), - d_singleton_eq(u), - d_lemmas_produced_c(u), + Valuation valuation) + : Theory(THEORY_DATATYPES, env, out, valuation), + d_term_sk(getUserContext()), + d_labels(getSatContext()), + d_selector_apps(getSatContext()), + d_collectTermsCache(getSatContext()), + d_collectTermsCacheU(getUserContext()), + d_functionTerms(getSatContext()), + d_singleton_eq(getUserContext()), d_sygusExtension(nullptr), - d_state(c, u, valuation), - d_im(*this, d_state, pnm), + d_state(env, valuation), + d_im(*this, d_state, d_pnm), d_notify(d_im, *this) { @@ -542,129 +538,151 @@ void TheoryDatatypes::eqNotifyMerge(TNode t1, TNode t2) } void TheoryDatatypes::merge( Node t1, Node t2 ){ - if (!d_state.isInConflict()) + if (d_state.isInConflict()) { - Trace("datatypes-merge") << "Merge " << t1 << " " << t2 << std::endl; - Assert(areEqual(t1, t2)); - TNode trep1 = t1; - TNode trep2 = t2; - EqcInfo* eqc2 = getOrMakeEqcInfo( t2 ); - if( eqc2 ){ - bool checkInst = false; - if( !eqc2->d_constructor.get().isNull() ){ - trep2 = eqc2->d_constructor.get(); - } - EqcInfo* eqc1 = getOrMakeEqcInfo( t1 ); - if( eqc1 ){ - Trace("datatypes-debug") << " merge eqc info " << eqc2 << " into " << eqc1 << std::endl; - if( !eqc1->d_constructor.get().isNull() ){ - trep1 = eqc1->d_constructor.get(); - } - //check for clash - TNode cons1 = eqc1->d_constructor.get(); - TNode cons2 = eqc2->d_constructor.get(); - //if both have constructor, then either clash or unification - if( !cons1.isNull() && !cons2.isNull() ){ - Trace("datatypes-debug") << " constructors : " << cons1 << " " << cons2 << std::endl; - Node unifEq = cons1.eqNode( cons2 ); - std::vector< Node > rew; - if (utils::checkClash(cons1, cons2, rew)) - { - std::vector<Node> conf; - conf.push_back(unifEq); - Trace("dt-conflict") - << "CONFLICT: Clash conflict : " << conf << std::endl; - d_im.sendDtConflict(conf, InferenceId::DATATYPES_CLASH_CONFLICT); - return; - } - else - { - Assert(areEqual(cons1, cons2)); - //do unification - for( int i=0; i<(int)cons1.getNumChildren(); i++ ) { - if( !areEqual( cons1[i], cons2[i] ) ){ - Node eq = cons1[i].eqNode( cons2[i] ); - d_im.addPendingInference( - eq, InferenceId::DATATYPES_UNIF, unifEq); - Trace("datatypes-infer") << "DtInfer : cons-inj : " << eq << " by " << unifEq << std::endl; - } - } - } - } - Trace("datatypes-debug") << " instantiated : " << eqc1->d_inst << " " << eqc2->d_inst << std::endl; - eqc1->d_inst = eqc1->d_inst || eqc2->d_inst; - if( !cons2.isNull() ){ - if( cons1.isNull() ){ - Trace("datatypes-debug") << " must check if it is okay to set the constructor." << std::endl; - checkInst = true; - addConstructor( eqc2->d_constructor.get(), eqc1, t1 ); - if (d_state.isInConflict()) - { - return; - } - } - } - }else{ - Trace("datatypes-debug") << " no eqc info for " << t1 << ", must create" << std::endl; - //just copy the equivalence class information - eqc1 = getOrMakeEqcInfo( t1, true ); - eqc1->d_inst.set( eqc2->d_inst ); - eqc1->d_constructor.set( eqc2->d_constructor ); - eqc1->d_selectors.set( eqc2->d_selectors ); + return; + } + Trace("datatypes-merge") << "Merge " << t1 << " " << t2 << std::endl; + Assert(areEqual(t1, t2)); + TNode trep1 = t1; + TNode trep2 = t2; + EqcInfo* eqc2 = getOrMakeEqcInfo(t2); + if (eqc2 == nullptr) + { + return; + } + bool checkInst = false; + if (!eqc2->d_constructor.get().isNull()) + { + trep2 = eqc2->d_constructor.get(); + } + EqcInfo* eqc1 = getOrMakeEqcInfo(t1); + if (eqc1) + { + Trace("datatypes-debug") + << " merge eqc info " << eqc2 << " into " << eqc1 << std::endl; + if (!eqc1->d_constructor.get().isNull()) + { + trep1 = eqc1->d_constructor.get(); + } + // check for clash + TNode cons1 = eqc1->d_constructor.get(); + TNode cons2 = eqc2->d_constructor.get(); + // if both have constructor, then either clash or unification + if (!cons1.isNull() && !cons2.isNull()) + { + Trace("datatypes-debug") + << " constructors : " << cons1 << " " << cons2 << std::endl; + Node unifEq = cons1.eqNode(cons2); + std::vector<Node> rew; + if (utils::checkClash(cons1, cons2, rew)) + { + std::vector<Node> conf; + conf.push_back(unifEq); + Trace("dt-conflict") + << "CONFLICT: Clash conflict : " << conf << std::endl; + d_im.sendDtConflict(conf, InferenceId::DATATYPES_CLASH_CONFLICT); + return; } - - - //merge labels - NodeUIntMap::iterator lbl_i = d_labels.find(t2); - if( lbl_i != d_labels.end() ){ - Trace("datatypes-debug") << " merge labels from " << eqc2 << " " << t2 << std::endl; - size_t n_label = (*lbl_i).second; - for (size_t i = 0; i < n_label; i++) + else + { + Assert(areEqual(cons1, cons2)); + // do unification + for (size_t i = 0, nchild = cons1.getNumChildren(); i < nchild; i++) { - Assert(i < d_labels_data[t2].size()); - Node t = d_labels_data[ t2 ][i]; - Node t_arg = d_labels_args[t2][i]; - unsigned tindex = d_labels_tindex[t2][i]; - addTester( tindex, t, eqc1, t1, t_arg ); - if (d_state.isInConflict()) + if (!areEqual(cons1[i], cons2[i])) { - Trace("datatypes-debug") << " conflict!" << std::endl; - return; + Node eq = cons1[i].eqNode(cons2[i]); + d_im.addPendingInference(eq, InferenceId::DATATYPES_UNIF, unifEq); + Trace("datatypes-infer") << "DtInfer : cons-inj : " << eq << " by " + << unifEq << std::endl; } } - } - //merge selectors - if( !eqc1->d_selectors && eqc2->d_selectors ){ - eqc1->d_selectors = true; + } + Trace("datatypes-debug") << " instantiated : " << eqc1->d_inst << " " + << eqc2->d_inst << std::endl; + eqc1->d_inst = eqc1->d_inst || eqc2->d_inst; + if (!cons2.isNull()) + { + if (cons1.isNull()) + { + Trace("datatypes-debug") + << " must check if it is okay to set the constructor." + << std::endl; checkInst = true; - } - NodeUIntMap::iterator sel_i = d_selector_apps.find(t2); - if( sel_i != d_selector_apps.end() ){ - Trace("datatypes-debug") << " merge selectors from " << eqc2 << " " << t2 << std::endl; - size_t n_sel = (*sel_i).second; - for (size_t j = 0; j < n_sel; j++) - { - addSelector( d_selector_apps_data[t2][j], eqc1, t1, eqc2->d_constructor.get().isNull() ); - } - } - if( checkInst ){ - Trace("datatypes-debug") << " checking instantiate" << std::endl; - instantiate( eqc1, t1 ); + addConstructor(eqc2->d_constructor.get(), eqc1, t1); if (d_state.isInConflict()) { return; } } } - Trace("datatypes-debug") << "Finished Merge " << t1 << " " << t2 << std::endl; } + else + { + Trace("datatypes-debug") + << " no eqc info for " << t1 << ", must create" << std::endl; + // just copy the equivalence class information + eqc1 = getOrMakeEqcInfo(t1, true); + eqc1->d_inst.set(eqc2->d_inst); + eqc1->d_constructor.set(eqc2->d_constructor); + eqc1->d_selectors.set(eqc2->d_selectors); + } + + // merge labels + NodeUIntMap::iterator lbl_i = d_labels.find(t2); + if (lbl_i != d_labels.end()) + { + Trace("datatypes-debug") + << " merge labels from " << eqc2 << " " << t2 << std::endl; + size_t n_label = (*lbl_i).second; + for (size_t i = 0; i < n_label; i++) + { + Assert(i < d_labels_data[t2].size()); + Node t = d_labels_data[t2][i]; + Node t_arg = d_labels_args[t2][i]; + unsigned tindex = d_labels_tindex[t2][i]; + addTester(tindex, t, eqc1, t1, t_arg); + if (d_state.isInConflict()) + { + Trace("datatypes-debug") << " conflict!" << std::endl; + return; + } + } + } + // merge selectors + if (!eqc1->d_selectors && eqc2->d_selectors) + { + eqc1->d_selectors = true; + checkInst = true; + } + NodeUIntMap::iterator sel_i = d_selector_apps.find(t2); + if (sel_i != d_selector_apps.end()) + { + Trace("datatypes-debug") + << " merge selectors from " << eqc2 << " " << t2 << std::endl; + size_t n_sel = (*sel_i).second; + for (size_t j = 0; j < n_sel; j++) + { + addSelector(d_selector_apps_data[t2][j], + eqc1, + t1, + eqc2->d_constructor.get().isNull()); + } + } + if (checkInst) + { + Trace("datatypes-debug") << " checking instantiate" << std::endl; + instantiate(eqc1, t1); + } + Trace("datatypes-debug") << "Finished Merge " << t1 << " " << t2 << std::endl; } -TheoryDatatypes::EqcInfo::EqcInfo( context::Context* c ) - : d_inst( c, false ) - , d_constructor( c, Node::null() ) - , d_selectors( c, false ) +TheoryDatatypes::EqcInfo::EqcInfo(context::Context* c) + : d_inst(c, false), + d_constructor(c, Node::null()), + d_selectors(c, false) {} bool TheoryDatatypes::hasLabel( EqcInfo* eqc, Node n ){ @@ -826,7 +844,7 @@ void TheoryDatatypes::addTester( const DType& dt = t_arg.getType().getDType(); Debug("datatypes-labels") << "Labels at " << n_lbl << " / " << dt.getNumConstructors() << std::endl; if( tpolarity ){ - instantiate( eqc, n ); + instantiate(eqc, n); // We could propagate is-C1(x) => not is-C2(x) here for all other // constructors, but empirically this hurts performance. }else{ @@ -1412,13 +1430,14 @@ Node TheoryDatatypes::getInstantiateCons(Node n, const DType& dt, int index) return n_ic; } -void TheoryDatatypes::instantiate( EqcInfo* eqc, Node n ){ +bool TheoryDatatypes::instantiate(EqcInfo* eqc, Node n) +{ Trace("datatypes-debug") << "Instantiate: " << n << std::endl; //add constructor to equivalence class if not done so already int index = getLabelIndex( eqc, n ); if (index == -1 || eqc->d_inst) { - return; + return false; } Node exp; Node tt; @@ -1440,7 +1459,8 @@ void TheoryDatatypes::instantiate( EqcInfo* eqc, Node n ){ Node eq; if (tt == tt_cons) { - return; + // not necessary + return false; } eq = tt.eqNode(tt_cons); // Determine if the equality must be sent out as a lemma. Notice that @@ -1463,9 +1483,10 @@ void TheoryDatatypes::instantiate( EqcInfo* eqc, Node n ){ } Trace("datatypes-infer-debug") << "DtInstantiate : " << eqc << " " << eq << " forceLemma = " << forceLemma << std::endl; - d_im.addPendingInference(eq, InferenceId::DATATYPES_INST, exp, forceLemma); Trace("datatypes-infer") << "DtInfer : instantiate : " << eq << " by " << exp << std::endl; + d_im.addPendingInference(eq, InferenceId::DATATYPES_INST, exp, forceLemma); + return true; } void TheoryDatatypes::checkCycles() { diff --git a/src/theory/datatypes/theory_datatypes.h b/src/theory/datatypes/theory_datatypes.h index 951aea804..68dedb6f3 100644 --- a/src/theory/datatypes/theory_datatypes.h +++ b/src/theory/datatypes/theory_datatypes.h @@ -158,8 +158,6 @@ private: std::map< TypeNode, Node > d_singleton_lemma[2]; /** Cache for singleton equalities processed */ BoolMap d_singleton_eq; - /** list of all lemmas produced */ - BoolMap d_lemmas_produced_c; private: /** assert fact */ void assertFact( Node fact, Node exp ); @@ -183,12 +181,7 @@ private: void computeCareGraph() override; public: - TheoryDatatypes(context::Context* c, - context::UserContext* u, - OutputChannel& out, - Valuation valuation, - const LogicInfo& logicInfo, - ProofNodeManager* pnm = nullptr); + TheoryDatatypes(Env& env, OutputChannel& out, Valuation valuation); ~TheoryDatatypes(); //--------------------------------- initialization @@ -273,9 +266,10 @@ private: void collectTerms( Node n ); /** get instantiate cons */ Node getInstantiateCons(Node n, const DType& dt, int index); - /** check instantiate */ - void instantiate( EqcInfo* eqc, Node n ); -private: + /** check instantiate, return true if an inference was generated. */ + bool instantiate(EqcInfo* eqc, Node n); + + private: //equality queries bool hasTerm( TNode a ); bool areEqual( TNode a, TNode b ); diff --git a/src/theory/ext_theory.cpp b/src/theory/ext_theory.cpp index b4bb896ae..627129c3a 100644 --- a/src/theory/ext_theory.cpp +++ b/src/theory/ext_theory.cpp @@ -84,9 +84,9 @@ bool ExtTheoryCallback::getReduction(int effort, ExtTheory::ExtTheory(ExtTheoryCallback& p, context::Context* c, context::UserContext* u, - OutputChannel& out) + TheoryInferenceManager& im) : d_parent(p), - d_out(out), + d_im(im), d_ext_func_terms(c), d_extfExtReducedIdMap(c), d_ci_inactive(u), @@ -237,7 +237,7 @@ bool ExtTheory::doInferencesInternal(int effort, if (!nr.isNull() && n != nr) { Node lem = NodeManager::currentNM()->mkNode(kind::EQUAL, n, nr); - if (sendLemma(lem, true)) + if (sendLemma(lem, InferenceId::EXTT_SIMPLIFY, true)) { Trace("extt-lemma") << "ExtTheory : reduction lemma : " << lem << std::endl; @@ -287,7 +287,7 @@ bool ExtTheory::doInferencesInternal(int effort, Trace("extt-debug") << "ExtTheory::doInferences : infer : " << eq << " by " << exp[i] << std::endl; Trace("extt-debug") << "...send lemma " << lem << std::endl; - if (sendLemma(lem)) + if (sendLemma(lem, InferenceId::EXTT_SIMPLIFY)) { Trace("extt-lemma") << "ExtTheory : substitution + rewrite lemma : " << lem @@ -359,14 +359,14 @@ bool ExtTheory::doInferencesInternal(int effort, return false; } -bool ExtTheory::sendLemma(Node lem, bool preprocess) +bool ExtTheory::sendLemma(Node lem, InferenceId id, bool preprocess) { if (preprocess) { if (d_pp_lemmas.find(lem) == d_pp_lemmas.end()) { d_pp_lemmas.insert(lem); - d_out.lemma(lem); + d_im.lemma(lem, id); return true; } } @@ -375,7 +375,7 @@ bool ExtTheory::sendLemma(Node lem, bool preprocess) if (d_lemmas.find(lem) == d_lemmas.end()) { d_lemmas.insert(lem); - d_out.lemma(lem); + d_im.lemma(lem, id); return true; } } diff --git a/src/theory/ext_theory.h b/src/theory/ext_theory.h index f5e08e2f5..01b191e0a 100644 --- a/src/theory/ext_theory.h +++ b/src/theory/ext_theory.h @@ -41,6 +41,7 @@ #include "context/cdo.h" #include "context/context.h" #include "expr/node.h" +#include "theory/theory_inference_manager.h" namespace cvc5 { namespace theory { @@ -176,7 +177,7 @@ class ExtTheory ExtTheory(ExtTheoryCallback& p, context::Context* c, context::UserContext* u, - OutputChannel& out); + TheoryInferenceManager& im); virtual ~ExtTheory() {} /** Tells this class to treat terms with Kind k as extended functions */ void addFunctionKind(Kind k) { d_extf_kind[k] = true; } @@ -291,11 +292,11 @@ class ExtTheory bool batch, bool isRed); /** send lemma on the output channel */ - bool sendLemma(Node lem, bool preprocess = false); + bool sendLemma(Node lem, InferenceId id, bool preprocess = false); /** reference to the callback */ ExtTheoryCallback& d_parent; - /** Reference to the output channel we are using */ - OutputChannel& d_out; + /** inference manager used to send lemmas */ + TheoryInferenceManager& d_im; /** the true node */ Node d_true; /** extended function terms, map to whether they are active */ diff --git a/src/theory/fp/theory_fp.cpp b/src/theory/fp/theory_fp.cpp index 9b5ac66d3..bd5662cdd 100644 --- a/src/theory/fp/theory_fp.cpp +++ b/src/theory/fp/theory_fp.cpp @@ -60,24 +60,19 @@ Node buildConjunct(const std::vector<TNode> &assumptions) { } // namespace helper /** Constructs a new instance of TheoryFp w.r.t. the provided contexts. */ -TheoryFp::TheoryFp(context::Context* c, - context::UserContext* u, - OutputChannel& out, - Valuation valuation, - const LogicInfo& logicInfo, - ProofNodeManager* pnm) - : Theory(THEORY_FP, c, u, out, valuation, logicInfo, pnm), +TheoryFp::TheoryFp(Env& env, OutputChannel& out, Valuation valuation) + : Theory(THEORY_FP, env, out, valuation), d_notification(*this), - d_registeredTerms(u), - d_conv(new FpConverter(u)), + d_registeredTerms(getUserContext()), + d_conv(new FpConverter(getUserContext())), d_expansionRequested(false), - d_realToFloatMap(u), - d_floatToRealMap(u), - d_abstractionMap(u), - d_rewriter(u), - d_state(c, u, valuation), - d_im(*this, d_state, pnm, "theory::fp::", false), - d_wbFactsCache(u) + d_realToFloatMap(getUserContext()), + d_floatToRealMap(getUserContext()), + d_abstractionMap(getUserContext()), + d_rewriter(getUserContext()), + d_state(env, valuation), + d_im(*this, d_state, d_pnm, "theory::fp::", false), + d_wbFactsCache(getUserContext()) { // indicate we are using the default theory state and inference manager d_theoryState = &d_state; diff --git a/src/theory/fp/theory_fp.h b/src/theory/fp/theory_fp.h index 14779cc3d..1e1041980 100644 --- a/src/theory/fp/theory_fp.h +++ b/src/theory/fp/theory_fp.h @@ -39,12 +39,7 @@ class TheoryFp : public Theory { public: /** Constructs a new instance of TheoryFp w.r.t. the provided contexts. */ - TheoryFp(context::Context* c, - context::UserContext* u, - OutputChannel& out, - Valuation valuation, - const LogicInfo& logicInfo, - ProofNodeManager* pnm = nullptr); + TheoryFp(Env& env, OutputChannel& out, Valuation valuation); //--------------------------------- initialization /** Get the official theory rewriter of this theory. */ diff --git a/src/theory/inference_id.cpp b/src/theory/inference_id.cpp index 9d8cddb69..7bb87819e 100644 --- a/src/theory/inference_id.cpp +++ b/src/theory/inference_id.cpp @@ -28,6 +28,7 @@ const char* toString(InferenceId i) { case InferenceId::EQ_CONSTANT_MERGE: return "EQ_CONSTANT_MERGE"; case InferenceId::COMBINATION_SPLIT: return "COMBINATION_SPLIT"; + case InferenceId::EXTT_SIMPLIFY: return "EXTT_SIMPLIFY"; case InferenceId::ARITH_BLACK_BOX: return "ARITH_BLACK_BOX"; case InferenceId::ARITH_CONF_EQ: return "ARITH_CONF_EQ"; case InferenceId::ARITH_CONF_LOWER: return "ARITH_CONF_LOWER"; diff --git a/src/theory/inference_id.h b/src/theory/inference_id.h index 3a317e0a4..4c6140872 100644 --- a/src/theory/inference_id.h +++ b/src/theory/inference_id.h @@ -45,6 +45,9 @@ enum class InferenceId EQ_CONSTANT_MERGE, // a split from theory combination COMBINATION_SPLIT, + // ---------------------------------- ext theory + // a simplification from the extended theory utility + EXTT_SIMPLIFY, // ---------------------------------- arith theory //-------------------- linear core // black box conflicts. It's magic. diff --git a/src/theory/quantifiers/ematching/inst_strategy_e_matching.cpp b/src/theory/quantifiers/ematching/inst_strategy_e_matching.cpp index ab237fc6c..8901ec314 100644 --- a/src/theory/quantifiers/ematching/inst_strategy_e_matching.cpp +++ b/src/theory/quantifiers/ematching/inst_strategy_e_matching.cpp @@ -111,7 +111,10 @@ InstStrategyStatus InstStrategyAutoGenTriggers::process(Node f, int e) { options::UserPatMode upMode = getInstUserPatMode(); - if (hasUserPatterns(f) && upMode == options::UserPatMode::TRUST) + // we don't auto-generate triggers if the mode is trust or strict + if (hasUserPatterns(f) + && (upMode == options::UserPatMode::TRUST + || upMode == options::UserPatMode::STRICT)) { return InstStrategyStatus::STATUS_UNKNOWN; } diff --git a/src/theory/quantifiers/ematching/instantiation_engine.cpp b/src/theory/quantifiers/ematching/instantiation_engine.cpp index d490dce83..d9bec820c 100644 --- a/src/theory/quantifiers/ematching/instantiation_engine.cpp +++ b/src/theory/quantifiers/ematching/instantiation_engine.cpp @@ -200,11 +200,15 @@ bool InstantiationEngine::checkCompleteFor( Node q ) { void InstantiationEngine::checkOwnership(Node q) { - if( options::strictTriggers() && q.getNumChildren()==3 ){ + if (options::userPatternsQuant() == options::UserPatMode::STRICT + && q.getNumChildren() == 3) + { //if strict triggers, take ownership of this quantified formula bool hasPat = false; - for( unsigned i=0; i<q[2].getNumChildren(); i++ ){ - if( q[2][i].getKind()==INST_PATTERN || q[2][i].getKind()==INST_NO_PATTERN ){ + for (const Node& qc : q) + { + if (qc.getKind() == INST_PATTERN || qc.getKind() == INST_NO_PATTERN) + { hasPat = true; break; } diff --git a/src/theory/quantifiers/expr_miner.cpp b/src/theory/quantifiers/expr_miner.cpp index 72605e9d1..0f46fa790 100644 --- a/src/theory/quantifiers/expr_miner.cpp +++ b/src/theory/quantifiers/expr_miner.cpp @@ -38,38 +38,19 @@ void ExprMiner::initialize(const std::vector<Node>& vars, SygusSampler* ss) Node ExprMiner::convertToSkolem(Node n) { - std::vector<Node> fvs; - TermUtil::computeVarContains(n, fvs); - if (fvs.empty()) + if (d_skolems.empty()) { - return n; - } - std::vector<Node> sfvs; - std::vector<Node> sks; - // map to skolems - NodeManager* nm = NodeManager::currentNM(); - SkolemManager* sm = nm->getSkolemManager(); - for (unsigned i = 0, size = fvs.size(); i < size; i++) - { - Node v = fvs[i]; - // only look at the sampler variables - if (std::find(d_vars.begin(), d_vars.end(), v) != d_vars.end()) + NodeManager* nm = NodeManager::currentNM(); + SkolemManager* sm = nm->getSkolemManager(); + for (const Node& v : d_vars) { - sfvs.push_back(v); - std::map<Node, Node>::iterator itf = d_fv_to_skolem.find(v); - if (itf == d_fv_to_skolem.end()) - { - Node sk = sm->mkDummySkolem("rrck", v.getType()); - d_fv_to_skolem[v] = sk; - sks.push_back(sk); - } - else - { - sks.push_back(itf->second); - } + Node sk = sm->mkDummySkolem("rrck", v.getType()); + d_skolems.push_back(sk); + d_fv_to_skolem[v] = sk; } } - return n.substitute(sfvs.begin(), sfvs.end(), sks.begin(), sks.end()); + return n.substitute( + d_vars.begin(), d_vars.end(), d_skolems.begin(), d_skolems.end()); } void ExprMiner::initializeChecker(std::unique_ptr<SmtEngine>& checker, diff --git a/src/theory/quantifiers/expr_miner.h b/src/theory/quantifiers/expr_miner.h index 36fae1549..79d0c6650 100644 --- a/src/theory/quantifiers/expr_miner.h +++ b/src/theory/quantifiers/expr_miner.h @@ -62,13 +62,15 @@ class ExprMiner protected: /** the set of variables used by this class */ std::vector<Node> d_vars; - /** pointer to the sygus sampler object we are using */ - SygusSampler* d_sampler; /** - * Maps to skolems for each free variable that appears in a check. This is + * The set of skolems corresponding to the above variables. These are * used during initializeChecker so that query (which may contain free * variables) is converted to a formula without free variables. */ + std::vector<Node> d_skolems; + /** pointer to the sygus sampler object we are using */ + SygusSampler* d_sampler; + /** Maps to skolems for each free variable based on d_vars/d_skolems. */ std::map<Node, Node> d_fv_to_skolem; /** convert */ Node convertToSkolem(Node n); diff --git a/src/theory/quantifiers/quantifiers_attributes.cpp b/src/theory/quantifiers/quantifiers_attributes.cpp index 1abbd1989..33ed6f536 100644 --- a/src/theory/quantifiers/quantifiers_attributes.cpp +++ b/src/theory/quantifiers/quantifiers_attributes.cpp @@ -30,8 +30,7 @@ namespace quantifiers { bool QAttributes::isStandard() const { - return !d_sygus && !d_quant_elim && !isFunDef() && d_name.isNull() - && !d_isInternal; + return !d_sygus && !d_quant_elim && !isFunDef() && !d_isInternal; } QuantAttributes::QuantAttributes() {} diff --git a/src/theory/quantifiers/quantifiers_attributes.h b/src/theory/quantifiers/quantifiers_attributes.h index b3fdd09da..910dbab5b 100644 --- a/src/theory/quantifiers/quantifiers_attributes.h +++ b/src/theory/quantifiers/quantifiers_attributes.h @@ -162,8 +162,7 @@ struct QAttributes * perform destructive updates (variable elimination, miniscoping, etc). * * A quantified formula is not standard if it is sygus, one for which - * we are performing quantifier elimination, is a function definition, or - * has a name. + * we are performing quantifier elimination, or is a function definition. */ bool isStandard() const; }; diff --git a/src/theory/quantifiers/quantifiers_rewriter.cpp b/src/theory/quantifiers/quantifiers_rewriter.cpp index 48106b858..02af92887 100644 --- a/src/theory/quantifiers/quantifiers_rewriter.cpp +++ b/src/theory/quantifiers/quantifiers_rewriter.cpp @@ -701,9 +701,65 @@ bool QuantifiersRewriter::isVarElim(Node v, Node s) return !expr::hasSubterm(s, v) && s.getType().isSubtypeOf(v.getType()); } -Node QuantifiersRewriter::getVarElimLitBv(Node lit, - const std::vector<Node>& args, - Node& var) +Node QuantifiersRewriter::getVarElimEq(Node lit, + const std::vector<Node>& args, + Node& var) +{ + Assert(lit.getKind() == EQUAL); + Node slv; + TypeNode tt = lit[0].getType(); + if (tt.isReal()) + { + slv = getVarElimEqReal(lit, args, var); + } + else if (tt.isBitVector()) + { + slv = getVarElimEqBv(lit, args, var); + } + else if (tt.isStringLike()) + { + slv = getVarElimEqString(lit, args, var); + } + return slv; +} + +Node QuantifiersRewriter::getVarElimEqReal(Node lit, + const std::vector<Node>& args, + Node& var) +{ + // for arithmetic, solve the equality + std::map<Node, Node> msum; + if (!ArithMSum::getMonomialSumLit(lit, msum)) + { + return Node::null(); + } + std::vector<Node>::const_iterator ita; + for (std::map<Node, Node>::iterator itm = msum.begin(); itm != msum.end(); + ++itm) + { + if (itm->first.isNull()) + { + continue; + } + ita = std::find(args.begin(), args.end(), itm->first); + if (ita != args.end()) + { + Node veq_c; + Node val; + int ires = ArithMSum::isolate(itm->first, msum, veq_c, val, EQUAL); + if (ires != 0 && veq_c.isNull() && isVarElim(itm->first, val)) + { + var = itm->first; + return val; + } + } + } + return Node::null(); +} + +Node QuantifiersRewriter::getVarElimEqBv(Node lit, + const std::vector<Node>& args, + Node& var) { if (Trace.isOn("quant-velim-bv")) { @@ -752,9 +808,9 @@ Node QuantifiersRewriter::getVarElimLitBv(Node lit, return Node::null(); } -Node QuantifiersRewriter::getVarElimLitString(Node lit, - const std::vector<Node>& args, - Node& var) +Node QuantifiersRewriter::getVarElimEqString(Node lit, + const std::vector<Node>& args, + Node& var) { Assert(lit.getKind() == EQUAL); NodeManager* nm = NodeManager::currentNM(); @@ -900,48 +956,10 @@ bool QuantifiersRewriter::getVarElimLit(Node lit, return true; } } - if (lit.getKind() == EQUAL && lit[0].getType().isReal() && pol) - { - // for arithmetic, solve the equality - std::map< Node, Node > msum; - if (ArithMSum::getMonomialSumLit(lit, msum)) - { - for( std::map< Node, Node >::iterator itm = msum.begin(); itm != msum.end(); ++itm ){ - if( !itm->first.isNull() ){ - std::vector< Node >::iterator ita = std::find( args.begin(), args.end(), itm->first ); - if( ita!=args.end() ){ - Assert(pol); - Node veq_c; - Node val; - int ires = ArithMSum::isolate(itm->first, msum, veq_c, val, EQUAL); - if (ires != 0 && veq_c.isNull() && isVarElim(itm->first, val)) - { - Trace("var-elim-quant") - << "Variable eliminate based on solved equality : " - << itm->first << " -> " << val << std::endl; - vars.push_back(itm->first); - subs.push_back(val); - args.erase(ita); - return true; - } - } - } - } - } - } if (lit.getKind() == EQUAL && pol) { Node var; - Node slv; - TypeNode tt = lit[0].getType(); - if (tt.isBitVector()) - { - slv = getVarElimLitBv(lit, args, var); - } - else if (tt.isStringLike()) - { - slv = getVarElimLitString(lit, args, var); - } + Node slv = getVarElimEq(lit, args, var); if (!slv.isNull()) { Assert(!var.isNull()); @@ -1797,7 +1815,7 @@ bool QuantifiersRewriter::doOperation(Node q, { bool is_strict_trigger = qa.d_hasPattern - && options::userPatternsQuant() == options::UserPatMode::TRUST; + && options::userPatternsQuant() == options::UserPatMode::STRICT; bool is_std = qa.isStandard() && !is_strict_trigger; if (computeOption == COMPUTE_ELIM_SYMBOLS) { diff --git a/src/theory/quantifiers/quantifiers_rewriter.h b/src/theory/quantifiers/quantifiers_rewriter.h index ae7f75f34..f0c3b0414 100644 --- a/src/theory/quantifiers/quantifiers_rewriter.h +++ b/src/theory/quantifiers/quantifiers_rewriter.h @@ -80,22 +80,34 @@ class QuantifiersRewriter : public TheoryRewriter std::vector<Node>& args, std::vector<Node>& vars, std::vector<Node>& subs); + /** + * Get variable eliminate for an equality based on theory-specific reasoning. + */ + static Node getVarElimEq(Node lit, const std::vector<Node>& args, Node& var); + /** variable eliminate for real equalities + * + * If this returns a non-null value ret, then var is updated to a member of + * args, lit is equivalent to ( var = ret ). + */ + static Node getVarElimEqReal(Node lit, + const std::vector<Node>& args, + Node& var); /** variable eliminate for bit-vector equalities * * If this returns a non-null value ret, then var is updated to a member of * args, lit is equivalent to ( var = ret ). */ - static Node getVarElimLitBv(Node lit, - const std::vector<Node>& args, - Node& var); + static Node getVarElimEqBv(Node lit, + const std::vector<Node>& args, + Node& var); /** variable eliminate for string equalities * * If this returns a non-null value ret, then var is updated to a member of * args, lit is equivalent to ( var = ret ). */ - static Node getVarElimLitString(Node lit, - const std::vector<Node>& args, - Node& var); + static Node getVarElimEqString(Node lit, + const std::vector<Node>& args, + Node& var); /** get variable elimination * * If n asserted with polarity pol entails a literal lit that corresponds diff --git a/src/theory/quantifiers/quantifiers_state.cpp b/src/theory/quantifiers/quantifiers_state.cpp index 7654a6326..39af9c2c9 100644 --- a/src/theory/quantifiers/quantifiers_state.cpp +++ b/src/theory/quantifiers/quantifiers_state.cpp @@ -22,11 +22,12 @@ namespace cvc5 { namespace theory { namespace quantifiers { -QuantifiersState::QuantifiersState(context::Context* c, - context::UserContext* u, +QuantifiersState::QuantifiersState(Env& env, Valuation val, const LogicInfo& logicInfo) - : TheoryState(c, u, val), d_ierCounterc(c), d_logicInfo(logicInfo) + : TheoryState(env, val), + d_ierCounterc(env.getContext()), + d_logicInfo(logicInfo) { // allow theory combination to go first, once initially d_ierCounter = options::instWhenTcFirst() ? 0 : 1; diff --git a/src/theory/quantifiers/quantifiers_state.h b/src/theory/quantifiers/quantifiers_state.h index e4a05b078..92b744cd0 100644 --- a/src/theory/quantifiers/quantifiers_state.h +++ b/src/theory/quantifiers/quantifiers_state.h @@ -32,8 +32,7 @@ namespace quantifiers { class QuantifiersState : public TheoryState { public: - QuantifiersState(context::Context* c, - context::UserContext* u, + QuantifiersState(Env& env, Valuation val, const LogicInfo& logicInfo); ~QuantifiersState() {} diff --git a/src/theory/quantifiers/theory_quantifiers.cpp b/src/theory/quantifiers/theory_quantifiers.cpp index c74146c9c..a108d4614 100644 --- a/src/theory/quantifiers/theory_quantifiers.cpp +++ b/src/theory/quantifiers/theory_quantifiers.cpp @@ -30,17 +30,14 @@ namespace cvc5 { namespace theory { namespace quantifiers { -TheoryQuantifiers::TheoryQuantifiers(Context* c, - context::UserContext* u, +TheoryQuantifiers::TheoryQuantifiers(Env& env, OutputChannel& out, - Valuation valuation, - const LogicInfo& logicInfo, - ProofNodeManager* pnm) - : Theory(THEORY_QUANTIFIERS, c, u, out, valuation, logicInfo, pnm), - d_qstate(c, u, valuation, logicInfo), + Valuation valuation) + : Theory(THEORY_QUANTIFIERS, env, out, valuation), + d_qstate(env, valuation, getLogicInfo()), d_qreg(), d_treg(d_qstate, d_qreg), - d_qim(*this, d_qstate, d_qreg, d_treg, pnm), + d_qim(*this, d_qstate, d_qreg, d_treg, d_pnm), d_qengine(nullptr) { out.handleUserAttribute( "fun-def", this ); @@ -50,7 +47,8 @@ TheoryQuantifiers::TheoryQuantifiers(Context* c, out.handleUserAttribute( "quant-elim-partial", this ); // construct the quantifiers engine - d_qengine.reset(new QuantifiersEngine(d_qstate, d_qreg, d_treg, d_qim, pnm)); + d_qengine.reset( + new QuantifiersEngine(d_qstate, d_qreg, d_treg, d_qim, d_pnm)); // indicate we are using the quantifiers theory state object d_theoryState = &d_qstate; diff --git a/src/theory/quantifiers/theory_quantifiers.h b/src/theory/quantifiers/theory_quantifiers.h index 544be84d6..0ef5cfcbb 100644 --- a/src/theory/quantifiers/theory_quantifiers.h +++ b/src/theory/quantifiers/theory_quantifiers.h @@ -37,12 +37,7 @@ class QuantifiersMacros; class TheoryQuantifiers : public Theory { public: - TheoryQuantifiers(context::Context* c, - context::UserContext* u, - OutputChannel& out, - Valuation valuation, - const LogicInfo& logicInfo, - ProofNodeManager* pnm = nullptr); + TheoryQuantifiers(Env& env, OutputChannel& out, Valuation valuation); ~TheoryQuantifiers(); //--------------------------------- initialization diff --git a/src/theory/sep/theory_sep.cpp b/src/theory/sep/theory_sep.cpp index 98130beb5..92d15653e 100644 --- a/src/theory/sep/theory_sep.cpp +++ b/src/theory/sep/theory_sep.cpp @@ -42,20 +42,15 @@ namespace cvc5 { namespace theory { namespace sep { -TheorySep::TheorySep(context::Context* c, - context::UserContext* u, - OutputChannel& out, - Valuation valuation, - const LogicInfo& logicInfo, - ProofNodeManager* pnm) - : Theory(THEORY_SEP, c, u, out, valuation, logicInfo, pnm), - d_lemmas_produced_c(u), +TheorySep::TheorySep(Env& env, OutputChannel& out, Valuation valuation) + : Theory(THEORY_SEP, env, out, valuation), + d_lemmas_produced_c(getUserContext()), d_bounds_init(false), - d_state(c, u, valuation), - d_im(*this, d_state, pnm, "theory::sep::"), + d_state(env, valuation), + d_im(*this, d_state, d_pnm, "theory::sep::"), d_notify(*this), - d_reduce(u), - d_spatial_assertions(c) + d_reduce(getUserContext()), + d_spatial_assertions(getSatContext()) { d_true = NodeManager::currentNM()->mkConst<bool>(true); d_false = NodeManager::currentNM()->mkConst<bool>(false); diff --git a/src/theory/sep/theory_sep.h b/src/theory/sep/theory_sep.h index b028f0686..985513fd8 100644 --- a/src/theory/sep/theory_sep.h +++ b/src/theory/sep/theory_sep.h @@ -77,12 +77,7 @@ class TheorySep : public Theory { bool underSpatial); public: - TheorySep(context::Context* c, - context::UserContext* u, - OutputChannel& out, - Valuation valuation, - const LogicInfo& logicInfo, - ProofNodeManager* pnm = nullptr); + TheorySep(Env& env, OutputChannel& out, Valuation valuation); ~TheorySep(); /** diff --git a/src/theory/sets/solver_state.cpp b/src/theory/sets/solver_state.cpp index 2aaa82706..6f8976f4d 100644 --- a/src/theory/sets/solver_state.cpp +++ b/src/theory/sets/solver_state.cpp @@ -26,11 +26,8 @@ namespace cvc5 { namespace theory { namespace sets { -SolverState::SolverState(context::Context* c, - context::UserContext* u, - Valuation val, - SkolemCache& skc) - : TheoryState(c, u, val), d_skCache(skc), d_members(c) +SolverState::SolverState(Env& env, Valuation val, SkolemCache& skc) + : TheoryState(env, val), d_skCache(skc), d_members(env.getContext()) { d_true = NodeManager::currentNM()->mkConst(true); d_false = NodeManager::currentNM()->mkConst(false); diff --git a/src/theory/sets/solver_state.h b/src/theory/sets/solver_state.h index 63039eddd..ff9bc8bf9 100644 --- a/src/theory/sets/solver_state.h +++ b/src/theory/sets/solver_state.h @@ -46,8 +46,7 @@ class SolverState : public TheoryState typedef context::CDHashMap<Node, size_t> NodeIntMap; public: - SolverState(context::Context* c, - context::UserContext* u, + SolverState(Env& env, Valuation val, SkolemCache& skc); //-------------------------------- initialize per check diff --git a/src/theory/sets/theory_sets.cpp b/src/theory/sets/theory_sets.cpp index 718077888..23ac08749 100644 --- a/src/theory/sets/theory_sets.cpp +++ b/src/theory/sets/theory_sets.cpp @@ -27,17 +27,12 @@ namespace cvc5 { namespace theory { namespace sets { -TheorySets::TheorySets(context::Context* c, - context::UserContext* u, - OutputChannel& out, - Valuation valuation, - const LogicInfo& logicInfo, - ProofNodeManager* pnm) - : Theory(THEORY_SETS, c, u, out, valuation, logicInfo, pnm), +TheorySets::TheorySets(Env& env, OutputChannel& out, Valuation valuation) + : Theory(THEORY_SETS, env, out, valuation), d_skCache(), - d_state(c, u, valuation, d_skCache), - d_im(*this, d_state, pnm), - d_internal(new TheorySetsPrivate(*this, d_state, d_im, d_skCache, pnm)), + d_state(env, valuation, d_skCache), + d_im(*this, d_state, d_pnm), + d_internal(new TheorySetsPrivate(*this, d_state, d_im, d_skCache, d_pnm)), d_notify(*d_internal.get(), d_im) { // use the official theory state and inference manager objects diff --git a/src/theory/sets/theory_sets.h b/src/theory/sets/theory_sets.h index e99d25d36..e9510d70e 100644 --- a/src/theory/sets/theory_sets.h +++ b/src/theory/sets/theory_sets.h @@ -41,12 +41,7 @@ class TheorySets : public Theory friend class TheorySetsRels; public: /** Constructs a new instance of TheorySets w.r.t. the provided contexts. */ - TheorySets(context::Context* c, - context::UserContext* u, - OutputChannel& out, - Valuation valuation, - const LogicInfo& logicInfo, - ProofNodeManager* pnm); + TheorySets(Env& env, OutputChannel& out, Valuation valuation); ~TheorySets() override; //--------------------------------- initialization diff --git a/src/theory/strings/infer_info.cpp b/src/theory/strings/infer_info.cpp index 432aa39d0..aabefe74e 100644 --- a/src/theory/strings/infer_info.cpp +++ b/src/theory/strings/infer_info.cpp @@ -17,6 +17,7 @@ #include "theory/strings/inference_manager.h" #include "theory/strings/theory_strings_utils.h" +#include "theory/theory.h" namespace cvc5 { namespace theory { @@ -60,8 +61,8 @@ bool InferInfo::isFact() const // we could process inferences with conjunctive conclusions as facts, where // the explanation is copied. However, for simplicity, we always send these // as lemmas. This case happens very infrequently. - return !atom.isConst() && atom.getKind() != kind::OR - && atom.getKind() != kind::AND && d_noExplain.empty(); + return !atom.isConst() && Theory::theoryOf(atom) == THEORY_STRINGS + && d_noExplain.empty(); } Node InferInfo::getPremises() const diff --git a/src/theory/strings/solver_state.cpp b/src/theory/strings/solver_state.cpp index 1ddf2af58..32ed6896c 100644 --- a/src/theory/strings/solver_state.cpp +++ b/src/theory/strings/solver_state.cpp @@ -28,10 +28,11 @@ namespace cvc5 { namespace theory { namespace strings { -SolverState::SolverState(context::Context* c, - context::UserContext* u, - Valuation& v) - : TheoryState(c, u, v), d_eeDisequalities(c), d_pendingConflictSet(c, false), d_pendingConflict(InferenceId::UNKNOWN) +SolverState::SolverState(Env& env, Valuation& v) + : TheoryState(env, v), + d_eeDisequalities(env.getContext()), + d_pendingConflictSet(env.getContext(), false), + d_pendingConflict(InferenceId::UNKNOWN) { d_zero = NodeManager::currentNM()->mkConst(Rational(0)); d_false = NodeManager::currentNM()->mkConst(false); @@ -64,7 +65,7 @@ EqcInfo* SolverState::getOrMakeEqcInfo(Node eqc, bool doMake) } if (doMake) { - EqcInfo* ei = new EqcInfo(d_context); + EqcInfo* ei = new EqcInfo(d_env.getContext()); d_eqcInfo[eqc] = ei; return ei; } diff --git a/src/theory/strings/solver_state.h b/src/theory/strings/solver_state.h index 422c29760..bbeb470f7 100644 --- a/src/theory/strings/solver_state.h +++ b/src/theory/strings/solver_state.h @@ -48,8 +48,7 @@ class SolverState : public TheoryState typedef context::CDList<Node> NodeList; public: - SolverState(context::Context* c, - context::UserContext* u, + SolverState(Env& env, Valuation& v); ~SolverState(); //-------------------------------------- disequality information diff --git a/src/theory/strings/theory_strings.cpp b/src/theory/strings/theory_strings.cpp index c526decf1..8b71df31b 100644 --- a/src/theory/strings/theory_strings.cpp +++ b/src/theory/strings/theory_strings.cpp @@ -50,21 +50,16 @@ struct SeqModelVarAttributeId }; using SeqModelVarAttribute = expr::Attribute<SeqModelVarAttributeId, Node>; -TheoryStrings::TheoryStrings(context::Context* c, - context::UserContext* u, - OutputChannel& out, - Valuation valuation, - const LogicInfo& logicInfo, - ProofNodeManager* pnm) - : Theory(THEORY_STRINGS, c, u, out, valuation, logicInfo, pnm), +TheoryStrings::TheoryStrings(Env& env, OutputChannel& out, Valuation valuation) + : Theory(THEORY_STRINGS, env, out, valuation), d_notify(*this), d_statistics(), - d_state(c, u, d_valuation), + d_state(env, d_valuation), d_eagerSolver(d_state), - d_termReg(d_state, d_statistics, pnm), + d_termReg(d_state, d_statistics, d_pnm), d_extTheoryCb(), - d_extTheory(d_extTheoryCb, c, u, out), - d_im(*this, d_state, d_termReg, d_extTheory, d_statistics, pnm), + d_im(*this, d_state, d_termReg, d_extTheory, d_statistics, d_pnm), + d_extTheory(d_extTheoryCb, getSatContext(), getUserContext(), d_im), d_rewriter(&d_statistics.d_rewrites), d_bsolver(d_state, d_im), d_csolver(d_state, d_im, d_termReg, d_bsolver), @@ -82,8 +77,8 @@ TheoryStrings::TheoryStrings(context::Context* c, d_csolver, d_esolver, d_statistics), - d_regexp_elim(options::regExpElimAgg(), pnm, u), - d_stringsFmf(c, u, valuation, d_termReg) + d_regexp_elim(options::regExpElimAgg(), d_pnm, getUserContext()), + d_stringsFmf(getSatContext(), getUserContext(), valuation, d_termReg) { d_termReg.finishInit(&d_im); diff --git a/src/theory/strings/theory_strings.h b/src/theory/strings/theory_strings.h index fc5e47194..8f0205b48 100644 --- a/src/theory/strings/theory_strings.h +++ b/src/theory/strings/theory_strings.h @@ -64,12 +64,7 @@ class TheoryStrings : public Theory { typedef context::CDHashSet<TypeNode, std::hash<TypeNode>> TypeNodeSet; public: - TheoryStrings(context::Context* c, - context::UserContext* u, - OutputChannel& out, - Valuation valuation, - const LogicInfo& logicInfo, - ProofNodeManager* pnm); + TheoryStrings(Env& env, OutputChannel& out, Valuation valuation); ~TheoryStrings(); //--------------------------------- initialization /** get the official theory rewriter of this theory */ @@ -267,10 +262,10 @@ class TheoryStrings : public Theory { TermRegistry d_termReg; /** The extended theory callback */ StringsExtfCallback d_extTheoryCb; - /** Extended theory, responsible for context-dependent simplification. */ - ExtTheory d_extTheory; /** The (custom) output channel of the theory of strings */ InferenceManager d_im; + /** Extended theory, responsible for context-dependent simplification. */ + ExtTheory d_extTheory; /** The theory rewriter for this theory. */ StringsRewriter d_rewriter; /** The proof rule checker */ diff --git a/src/theory/theory.cpp b/src/theory/theory.cpp index 96bc85336..04bab16e2 100644 --- a/src/theory/theory.cpp +++ b/src/theory/theory.cpp @@ -60,27 +60,22 @@ std::ostream& operator<<(std::ostream& os, Theory::Effort level){ }/* ostream& operator<<(ostream&, Theory::Effort) */ Theory::Theory(TheoryId id, - context::Context* satContext, - context::UserContext* userContext, + Env& env, OutputChannel& out, Valuation valuation, - const LogicInfo& logicInfo, - ProofNodeManager* pnm, std::string name) : d_id(id), - d_satContext(satContext), - d_userContext(userContext), - d_logicInfo(logicInfo), - d_facts(satContext), - d_factsHead(satContext, 0), - d_sharedTermsIndex(satContext, 0), + d_env(env), + d_facts(d_env.getContext()), + d_factsHead(d_env.getContext(), 0), + d_sharedTermsIndex(d_env.getContext(), 0), d_careGraph(nullptr), d_instanceName(name), d_checkTime(smtStatisticsRegistry().registerTimer(getStatsPrefix(id) + name + "checkTime")), d_computeCareGraphTime(smtStatisticsRegistry().registerTimer( getStatsPrefix(id) + name + "computeCareGraphTime")), - d_sharedTerms(satContext), + d_sharedTerms(d_env.getContext()), d_out(&out), d_valuation(valuation), d_equalityEngine(nullptr), @@ -88,7 +83,8 @@ Theory::Theory(TheoryId id, d_theoryState(nullptr), d_inferManager(nullptr), d_quantEngine(nullptr), - d_pnm(pnm) + d_pnm(d_env.isTheoryProofProducing() ? d_env.getProofNodeManager() + : nullptr) { } @@ -135,9 +131,12 @@ void Theory::finishInitStandalone() EeSetupInfo esi; if (needsEqualityEngine(esi)) { - // always associated with the same SAT context as the theory (d_satContext) - d_allocEqualityEngine.reset(new eq::EqualityEngine( - *esi.d_notify, d_satContext, esi.d_name, esi.d_constantsAreTriggers)); + // always associated with the same SAT context as the theory + d_allocEqualityEngine.reset( + new eq::EqualityEngine(*esi.d_notify, + getSatContext(), + esi.d_name, + esi.d_constantsAreTriggers)); // use it as the official equality engine setEqualityEngine(d_allocEqualityEngine.get()); } @@ -339,7 +338,7 @@ bool Theory::isLegalElimination(TNode x, TNode val) { return false; } - if (!options::produceModels() && !d_logicInfo.isQuantified()) + if (!options::produceModels() && !getLogicInfo().isQuantified()) { // Don't care about the model and logic is not quantified, we can eliminate. return true; @@ -467,7 +466,7 @@ void Theory::getCareGraph(CareGraph* careGraph) { bool Theory::proofsEnabled() const { - return d_pnm != nullptr; + return d_env.getProofNodeManager() != nullptr; } EqualityStatus Theory::getEqualityStatus(TNode a, TNode b) @@ -621,7 +620,7 @@ bool Theory::usesCentralEqualityEngine(TheoryId id) } return id == THEORY_UF || id == THEORY_DATATYPES || id == THEORY_BAGS || id == THEORY_FP || id == THEORY_SETS || id == THEORY_STRINGS - || id == THEORY_SEP || id == THEORY_ARRAYS; + || id == THEORY_SEP || id == THEORY_ARRAYS || id == THEORY_BV; } bool Theory::expUsingCentralEqualityEngine(TheoryId id) diff --git a/src/theory/theory.h b/src/theory/theory.h index 41f35601b..a857931a8 100644 --- a/src/theory/theory.h +++ b/src/theory/theory.h @@ -29,6 +29,7 @@ #include "expr/node.h" #include "options/theory_options.h" #include "proof/trust_node.h" +#include "smt/env.h" #include "theory/assertion.h" #include "theory/care_graph.h" #include "theory/logic_info.h" @@ -105,14 +106,8 @@ class Theory { /** An integer identifying the type of the theory. */ TheoryId d_id; - /** The SAT search context for the Theory. */ - context::Context* d_satContext; - - /** The user level assertion context for the Theory. */ - context::UserContext* d_userContext; - - /** Information about the logic we're operating within. */ - const LogicInfo& d_logicInfo; + /** The environment class */ + Env& d_env; /** * The assertFact() queue. @@ -169,12 +164,9 @@ class Theory { * w.r.t. the SmtEngine. */ Theory(TheoryId id, - context::Context* satContext, - context::UserContext* userContext, + Env& env, OutputChannel& out, Valuation valuation, - const LogicInfo& logicInfo, - ProofNodeManager* pnm, std::string instance = ""); // taking : No default. /** @@ -241,9 +233,7 @@ class Theory { */ inline Assertion get(); - const LogicInfo& getLogicInfo() const { - return d_logicInfo; - } + const LogicInfo& getLogicInfo() const { return d_env.getLogicInfo(); } /** * Set separation logic heap. This is called when the location and data @@ -455,17 +445,20 @@ class Theory { } /** + * Get a reference to the environment. + */ + Env& getEnv() const { return d_env; } + + /** * Get the SAT context associated to this Theory. */ - context::Context* getSatContext() const { - return d_satContext; - } + context::Context* getSatContext() const { return d_env.getContext(); } /** * Get the context associated to this Theory. */ context::UserContext* getUserContext() const { - return d_userContext; + return d_env.getUserContext(); } /** @@ -512,7 +505,7 @@ class Theory { */ void assertFact(TNode assertion, bool isPreregistered) { Trace("theory") << "Theory<" << getId() << ">::assertFact[" - << d_satContext->getLevel() << "](" << assertion << ", " + << getSatContext()->getLevel() << "](" << assertion << ", " << (isPreregistered ? "true" : "false") << ")" << std::endl; d_facts.push_back(Assertion(assertion, isPreregistered)); } diff --git a/src/theory/theory_engine.cpp b/src/theory/theory_engine.cpp index 233ea64ed..21c22586b 100644 --- a/src/theory/theory_engine.cpp +++ b/src/theory/theory_engine.cpp @@ -218,12 +218,12 @@ context::UserContext* TheoryEngine::getUserContext() const return d_env.getUserContext(); } -TheoryEngine::TheoryEngine(Env& env, - ProofNodeManager* pnm) +TheoryEngine::TheoryEngine(Env& env) : d_propEngine(nullptr), d_env(env), d_logicInfo(env.getLogicInfo()), - d_pnm(pnm), + d_pnm(d_env.isTheoryProofProducing() ? d_env.getProofNodeManager() + : nullptr), d_lazyProof(d_pnm != nullptr ? new LazyCDProof(d_pnm, nullptr, diff --git a/src/theory/theory_engine.h b/src/theory/theory_engine.h index 0c4a80c98..1c42e336f 100644 --- a/src/theory/theory_engine.h +++ b/src/theory/theory_engine.h @@ -295,7 +295,7 @@ class TheoryEngine { public: /** Constructs a theory engine */ - TheoryEngine(Env& env, ProofNodeManager* pnm); + TheoryEngine(Env& env); /** Destroys a theory engine */ ~TheoryEngine(); @@ -314,12 +314,8 @@ class TheoryEngine { { Assert(d_theoryTable[theoryId] == NULL && d_theoryOut[theoryId] == NULL); d_theoryOut[theoryId] = new theory::EngineOutputChannel(this, theoryId); - d_theoryTable[theoryId] = new TheoryClass(getSatContext(), - getUserContext(), - *d_theoryOut[theoryId], - theory::Valuation(this), - d_logicInfo, - d_pnm); + d_theoryTable[theoryId] = + new TheoryClass(d_env, *d_theoryOut[theoryId], theory::Valuation(this)); theory::Rewriter::registerTheoryRewriter( theoryId, d_theoryTable[theoryId]->getTheoryRewriter()); } diff --git a/src/theory/theory_state.cpp b/src/theory/theory_state.cpp index 5ac5e6ae9..72ab24a7e 100644 --- a/src/theory/theory_state.cpp +++ b/src/theory/theory_state.cpp @@ -20,22 +20,25 @@ namespace cvc5 { namespace theory { -TheoryState::TheoryState(context::Context* c, - context::UserContext* u, - Valuation val) - : d_context(c), - d_ucontext(u), +TheoryState::TheoryState(Env& env, Valuation val) + : d_env(env), d_valuation(val), d_ee(nullptr), - d_conflict(c, false) + d_conflict(d_env.getContext(), false) { } void TheoryState::setEqualityEngine(eq::EqualityEngine* ee) { d_ee = ee; } -context::Context* TheoryState::getSatContext() const { return d_context; } +context::Context* TheoryState::getSatContext() const +{ + return d_env.getContext(); +} -context::UserContext* TheoryState::getUserContext() const { return d_ucontext; } +context::UserContext* TheoryState::getUserContext() const +{ + return d_env.getUserContext(); +} bool TheoryState::hasTerm(TNode a) const { diff --git a/src/theory/theory_state.h b/src/theory/theory_state.h index 2c7bad60b..58a66ef46 100644 --- a/src/theory/theory_state.h +++ b/src/theory/theory_state.h @@ -20,6 +20,7 @@ #include "context/cdo.h" #include "expr/node.h" +#include "smt/env.h" #include "theory/valuation.h" namespace cvc5 { @@ -32,7 +33,8 @@ class EqualityEngine; class TheoryState { public: - TheoryState(context::Context* c, context::UserContext* u, Valuation val); + TheoryState(Env& env, + Valuation val); virtual ~TheoryState() {} /** * Set equality engine, where ee is a pointer to the official equality engine @@ -43,6 +45,8 @@ class TheoryState context::Context* getSatContext() const; /** Get the user context */ context::UserContext* getUserContext() const; + /** Get the environment */ + Env& getEnv() const { return d_env; } //-------------------------------------- equality information /** Is t registered as a term in the equality engine of this class? */ virtual bool hasTerm(TNode a) const; @@ -111,10 +115,8 @@ class TheoryState Valuation& getValuation(); protected: - /** Pointer to the SAT context object used by the theory. */ - context::Context* d_context; - /** Pointer to the user context object used by the theory. */ - context::UserContext* d_ucontext; + /** Reference to the environment. */ + Env& d_env; /** * The valuation proxy for the Theory to communicate back with the * theory engine (and other theories). diff --git a/src/theory/uf/theory_uf.cpp b/src/theory/uf/theory_uf.cpp index 4224ec854..3525786d5 100644 --- a/src/theory/uf/theory_uf.cpp +++ b/src/theory/uf/theory_uf.cpp @@ -40,20 +40,17 @@ namespace theory { namespace uf { /** Constructs a new instance of TheoryUF w.r.t. the provided context.*/ -TheoryUF::TheoryUF(context::Context* c, - context::UserContext* u, +TheoryUF::TheoryUF(Env& env, OutputChannel& out, Valuation valuation, - const LogicInfo& logicInfo, - ProofNodeManager* pnm, std::string instanceName) - : Theory(THEORY_UF, c, u, out, valuation, logicInfo, pnm, instanceName), + : Theory(THEORY_UF, env, out, valuation, instanceName), d_thss(nullptr), d_ho(nullptr), - d_functionsTerms(c), - d_symb(u, instanceName), - d_state(c, u, valuation), - d_im(*this, d_state, pnm, "theory::uf::" + instanceName, false), + d_functionsTerms(getSatContext()), + d_symb(getUserContext(), instanceName), + d_state(env, valuation), + d_im(*this, d_state, d_pnm, "theory::uf::" + instanceName, false), d_notify(d_im, *this) { d_true = NodeManager::currentNM()->mkConst( true ); diff --git a/src/theory/uf/theory_uf.h b/src/theory/uf/theory_uf.h index c953cfe5c..6f04035ed 100644 --- a/src/theory/uf/theory_uf.h +++ b/src/theory/uf/theory_uf.h @@ -98,12 +98,9 @@ private: public: /** Constructs a new instance of TheoryUF w.r.t. the provided context.*/ - TheoryUF(context::Context* c, - context::UserContext* u, + TheoryUF(Env& env, OutputChannel& out, Valuation valuation, - const LogicInfo& logicInfo, - ProofNodeManager* pnm = nullptr, std::string instanceName = ""); ~TheoryUF(); |