diff options
author | Andrew Reynolds <andrew.j.reynolds@gmail.com> | 2020-08-26 20:24:28 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-08-26 20:24:28 -0500 |
commit | 00c9ae6e2796c45d821ea9dd45ff7c33a5770922 (patch) | |
tree | 814c741134a68a23679adc23a9597bde5d12ec6f /src/theory/uf/theory_uf.cpp | |
parent | a407bd70c09724dc20af3241775abedd3a73ec67 (diff) |
(new theory) Update TheoryUF to new interface (#4944)
This updates TheoryUF to use the 4 check callbacks instead of implementing check, and uses the official TheoryState object instead of its context::CDO<bool> d_conflict field.
It also makes a minor change to collectModelValues for const and to preNotifyFact to include an isInternal flag.
Diffstat (limited to 'src/theory/uf/theory_uf.cpp')
-rw-r--r-- | src/theory/uf/theory_uf.cpp | 171 |
1 files changed, 81 insertions, 90 deletions
diff --git a/src/theory/uf/theory_uf.cpp b/src/theory/uf/theory_uf.cpp index 7d554c613..f94cc36af 100644 --- a/src/theory/uf/theory_uf.cpp +++ b/src/theory/uf/theory_uf.cpp @@ -54,7 +54,6 @@ TheoryUF::TheoryUF(context::Context* c, * so make sure it's initialized first. */ d_thss(nullptr), d_ho(nullptr), - d_conflict(c, false), d_functionsTerms(c), d_symb(u, instanceName), d_state(c, u, valuation) @@ -89,7 +88,7 @@ void TheoryUF::finishInit() { // Initialize the cardinality constraints solver if the logic includes UF, // finite model finding is enabled, and it is not disabled by // options::ufssMode(). - if (getLogicInfo().isTheoryEnabled(THEORY_UF) && options::finiteModelFind() + if (options::finiteModelFind() && options::ufssMode() != options::UfssMode::NONE) { d_thss.reset(new CardinalityExtension( @@ -100,7 +99,7 @@ void TheoryUF::finishInit() { if (options::ufHo()) { d_equalityEngine->addFunctionKind(kind::HO_APPLY); - d_ho.reset(new HoExtension(*this, getSatContext(), getUserContext())); + d_ho.reset(new HoExtension(*this, d_state)); } } @@ -126,79 +125,87 @@ static Node mkAnd(const std::vector<TNode>& conjunctions) { return conjunction; }/* mkAnd() */ -void TheoryUF::check(Effort level) { - if (done() && !fullEffort(level)) { +//--------------------------------- standard check + +void TheoryUF::postCheck(Effort level) +{ + if (d_state.isInConflict()) + { return; } - getOutputChannel().spendResource(ResourceManager::Resource::TheoryCheckStep); - TimerStat::CodeTimer checkTimer(d_checkTime); - - while (!done() && !d_conflict) + // check with the cardinality constraints extension + if (d_thss != nullptr) { - // Get all the assertions - Assertion assertion = get(); - TNode fact = assertion.d_assertion; - - Debug("uf") << "TheoryUF::check(): processing " << fact << std::endl; - Debug("uf") << "Term's theory: " << theory::Theory::theoryOf(fact.toExpr()) << std::endl; - - if (d_thss != NULL) { - bool isDecision = d_valuation.isSatLiteral(fact) && d_valuation.isDecision(fact); - d_thss->assertNode(fact, isDecision); - if( d_thss->isConflict() ){ - d_conflict = true; - return; - } + d_thss->check(level); + if (d_thss->isConflict()) + { + d_state.notifyInConflict(); } + } + // check with the higher-order extension + if (!d_state.isInConflict() && fullEffort(level)) + { + if (options::ufHo()) + { + d_ho->check(); + } + } +} - // Do the work - bool polarity = fact.getKind() != kind::NOT; - TNode atom = polarity ? fact : fact[0]; - if (atom.getKind() == kind::EQUAL) { - d_equalityEngine->assertEquality(atom, polarity, fact); - if( options::ufHo() && options::ufHoExt() ){ - if( !polarity && !d_conflict && atom[0].getType().isFunction() ){ - // apply extensionality eagerly using the ho extension - d_ho->applyExtensionality(fact); - } - } - } else if (atom.getKind() == kind::CARDINALITY_CONSTRAINT || atom.getKind() == kind::COMBINED_CARDINALITY_CONSTRAINT) { - if( d_thss == NULL ){ - if( !getLogicInfo().hasCardinalityConstraints() ){ - std::stringstream ss; - ss << "Cardinality constraint " << atom << " was asserted, but the logic does not allow it." << std::endl; - ss << "Try using a logic containing \"UFC\"." << std::endl; - throw Exception( ss.str() ); - }else{ - // support for cardinality constraints is not enabled, set incomplete - d_out->setIncomplete(); - } +bool TheoryUF::preNotifyFact( + TNode atom, bool pol, TNode fact, bool isPrereg, bool isInternal) +{ + if (d_thss != nullptr) + { + bool isDecision = + d_valuation.isSatLiteral(fact) && d_valuation.isDecision(fact); + d_thss->assertNode(fact, isDecision); + if (d_thss->isConflict()) + { + d_state.notifyInConflict(); + return true; + } + } + if (atom.getKind() == kind::CARDINALITY_CONSTRAINT + || atom.getKind() == kind::COMBINED_CARDINALITY_CONSTRAINT) + { + if (d_thss == nullptr) + { + if (!getLogicInfo().hasCardinalityConstraints()) + { + std::stringstream ss; + ss << "Cardinality constraint " << atom + << " was asserted, but the logic does not allow it." << std::endl; + ss << "Try using a logic containing \"UFC\"." << std::endl; + throw Exception(ss.str()); } - //needed for models - if( options::produceModels() ){ - d_equalityEngine->assertPredicate(atom, polarity, fact); + else + { + // support for cardinality constraints is not enabled, set incomplete + d_out->setIncomplete(); } - } else { - d_equalityEngine->assertPredicate(atom, polarity, fact); } + // don't need to assert cardinality constraints if not producing models + return !options::produceModels(); } + return false; +} - if(! d_conflict ){ - // check with the cardinality constraints extension - if (d_thss != NULL) { - d_thss->check(level); - if( d_thss->isConflict() ){ - d_conflict = true; - } - } - // check with the higher-order extension - if(! d_conflict && fullEffort(level) ){ - if( options::ufHo() ){ - d_ho->check(); +void TheoryUF::notifyFact(TNode atom, bool pol, TNode fact, bool isInternal) +{ + if (!d_state.isInConflict() && atom.getKind() == kind::EQUAL) + { + if (options::ufHo() && options::ufHoExt()) + { + if (!pol && !d_state.isInConflict() && atom[0].getType().isFunction()) + { + // apply extensionality eagerly using the ho extension + d_ho->applyExtensionality(fact); } } } -}/* TheoryUF::check() */ +} +//--------------------------------- end standard check TrustNode TheoryUF::expandDefinition(Node node) { @@ -221,7 +228,8 @@ TrustNode TheoryUF::expandDefinition(Node node) return TrustNode::null(); } -void TheoryUF::preRegisterTerm(TNode node) { +void TheoryUF::preRegisterTerm(TNode node) +{ Debug("uf") << "TheoryUF::preRegisterTerm(" << node << ")" << std::endl; if (d_thss != NULL) { @@ -259,14 +267,15 @@ void TheoryUF::preRegisterTerm(TNode node) { d_equalityEngine->addTerm(node); break; } -}/* TheoryUF::preRegisterTerm() */ +} bool TheoryUF::propagateLit(TNode literal) { Debug("uf::propagate") << "TheoryUF::propagateLit(" << literal << ")" << std::endl; // If already in conflict, no more propagation - if (d_conflict) { + if (d_state.isInConflict()) + { Debug("uf::propagate") << "TheoryUF::propagateLit(" << literal << "): already in conflict" << std::endl; return false; @@ -274,7 +283,7 @@ bool TheoryUF::propagateLit(TNode literal) // Propagate out bool ok = d_out->propagate(literal); if (!ok) { - d_conflict = true; + d_state.notifyInConflict(); } return ok; }/* TheoryUF::propagate(TNode) */ @@ -314,24 +323,12 @@ Node TheoryUF::explain(TNode literal, eq::EqProof* pf) { return mkAnd(assumptions); } -bool TheoryUF::collectModelInfo(TheoryModel* m) +bool TheoryUF::collectModelValues(TheoryModel* m, const std::set<Node>& termSet) { - Debug("uf") << "UF : collectModelInfo " << std::endl; - set<Node> termSet; - - // Compute terms appearing in assertions and shared terms - computeRelevantTerms(termSet); - - if (!m->assertEqualityEngine(d_equalityEngine, &termSet)) - { - Trace("uf") << "Collect model info fail UF" << std::endl; - return false; - } - if( options::ufHo() ){ // must add extensionality disequalities for all pairs of (non-disequal) // function equivalence classes. - if (!d_ho->collectModelInfoHo(termSet, m)) + if (!d_ho->collectModelInfoHo(m, termSet)) { Trace("uf") << "Collect model info fail HO" << std::endl; return false; @@ -503,12 +500,6 @@ EqualityStatus TheoryUF::getEqualityStatus(TNode a, TNode b) { return EQUALITY_FALSE_IN_MODEL; } -void TheoryUF::notifySharedTerm(TNode t) -{ - Debug("uf::sharing") << "TheoryUF::addSharedTerm(" << t << ")" << std::endl; - d_equalityEngine->addTriggerTerm(t, THEORY_UF); -} - bool TheoryUF::areCareDisequal(TNode x, TNode y){ Assert(d_equalityEngine->hasTerm(x)); Assert(d_equalityEngine->hasTerm(y)); @@ -674,10 +665,10 @@ void TheoryUF::computeCareGraph() { void TheoryUF::conflict(TNode a, TNode b) { std::shared_ptr<eq::EqProof> pf = d_proofsEnabled ? std::make_shared<eq::EqProof>() : nullptr; - d_conflictNode = explain(a.eqNode(b), pf.get()); + Node conf = explain(a.eqNode(b), pf.get()); std::unique_ptr<ProofUF> puf(d_proofsEnabled ? new ProofUF(pf) : nullptr); - d_out->conflict(d_conflictNode, std::move(puf)); - d_conflict = true; + d_out->conflict(conf, std::move(puf)); + d_state.notifyInConflict(); } void TheoryUF::eqNotifyNewClass(TNode t) { |