summaryrefslogtreecommitdiff
path: root/src/theory/uf/theory_uf.cpp
diff options
context:
space:
mode:
authorAndrew Reynolds <andrew.j.reynolds@gmail.com>2020-08-26 20:24:28 -0500
committerGitHub <noreply@github.com>2020-08-26 20:24:28 -0500
commit00c9ae6e2796c45d821ea9dd45ff7c33a5770922 (patch)
tree814c741134a68a23679adc23a9597bde5d12ec6f /src/theory/uf/theory_uf.cpp
parenta407bd70c09724dc20af3241775abedd3a73ec67 (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.cpp171
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) {
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback