summaryrefslogtreecommitdiff
path: root/src/theory
diff options
context:
space:
mode:
authorAndrew Reynolds <andrew.j.reynolds@gmail.com>2020-08-11 22:53:58 -0500
committerGitHub <noreply@github.com>2020-08-11 22:53:58 -0500
commitb5b2858807d48136807aba29bb53a1e91cfacc6e (patch)
tree037748e29a31a352b86bcf8103002dc5850f164d /src/theory
parent8b1f36ef24beaf3fa0708c28c53042a5c823c79c (diff)
Prepare theory of sets for dynamic allocation of equality engine (#4868)
In forthcoming PRs, Theory objects will be assigned equality engine objects dynamically. This PR prepares the theory of sets for this update, which involves refactoring of its internal members.
Diffstat (limited to 'src/theory')
-rw-r--r--src/theory/sets/cardinality_extension.cpp16
-rw-r--r--src/theory/sets/cardinality_extension.h3
-rw-r--r--src/theory/sets/inference_manager.cpp2
-rw-r--r--src/theory/sets/inference_manager.h3
-rw-r--r--src/theory/sets/solver_state.cpp50
-rw-r--r--src/theory/sets/solver_state.h23
-rw-r--r--src/theory/sets/theory_sets.cpp115
-rw-r--r--src/theory/sets/theory_sets.h40
-rw-r--r--src/theory/sets/theory_sets_private.cpp207
-rw-r--r--src/theory/sets/theory_sets_private.h39
-rw-r--r--src/theory/sets/theory_sets_rels.cpp28
-rw-r--r--src/theory/sets/theory_sets_rels.h3
12 files changed, 276 insertions, 253 deletions
diff --git a/src/theory/sets/cardinality_extension.cpp b/src/theory/sets/cardinality_extension.cpp
index dc3c77353..1c12c71e4 100644
--- a/src/theory/sets/cardinality_extension.cpp
+++ b/src/theory/sets/cardinality_extension.cpp
@@ -31,19 +31,15 @@ namespace sets {
CardinalityExtension::CardinalityExtension(SolverState& s,
InferenceManager& im,
- eq::EqualityEngine& e,
context::Context* c,
context::UserContext* u)
: d_state(s),
d_im(im),
- d_ee(e),
d_card_processed(u),
d_finite_type_constants_processed(false)
{
d_true = NodeManager::currentNM()->mkConst(true);
d_zero = NodeManager::currentNM()->mkConst(Rational(0));
- // we do congruence over cardinality
- d_ee.addFunctionKind(CARD);
}
void CardinalityExtension::reset()
@@ -60,7 +56,7 @@ void CardinalityExtension::registerTerm(Node n)
Assert(n.getKind() == CARD);
TypeNode tnc = n[0].getType().getSetElementType();
d_t_card_enabled[tnc] = true;
- Node r = d_ee.getRepresentative(n[0]);
+ Node r = d_state.getRepresentative(n[0]);
if (d_eqc_to_card_term.find(r) == d_eqc_to_card_term.end())
{
d_eqc_to_card_term[r] = n;
@@ -144,7 +140,7 @@ void CardinalityExtension::checkCardinalityExtended(TypeNode& t)
for (Node& representative : representatives)
{
// the universe set is a subset of itself
- if (representative != d_ee.getRepresentative(univ))
+ if (representative != d_state.getRepresentative(univ))
{
// here we only add representatives with variables to avoid adding
// infinite equivalent generated terms to the cardinality graph
@@ -399,7 +395,7 @@ void CardinalityExtension::checkCardCyclesRec(Node eqc,
true_sib = 1;
}
Node u = Rewriter::rewrite(nm->mkNode(UNION, n[0], n[1]));
- if (!d_ee.hasTerm(u))
+ if (!d_state.hasTerm(u))
{
u = Node::null();
}
@@ -413,7 +409,7 @@ void CardinalityExtension::checkCardCyclesRec(Node eqc,
// parent equal siblings
for (unsigned e = 0; e < true_sib; e++)
{
- if (d_ee.hasTerm(sib[e]) && !d_state.areEqual(n[e], sib[e]))
+ if (d_state.hasTerm(sib[e]) && !d_state.areEqual(n[e], sib[e]))
{
conc.push_back(n[e].eqNode(sib[e]));
}
@@ -518,7 +514,7 @@ void CardinalityExtension::checkCardCyclesRec(Node eqc,
for (unsigned k = 0, numcp = card_parents.size(); k < numcp; k++)
{
Node cpk = card_parents[k];
- Node eqcc = d_ee.getRepresentative(cpk);
+ Node eqcc = d_state.getRepresentative(cpk);
Trace("sets-debug") << "Check card parent " << k << "/"
<< card_parents.size() << std::endl;
@@ -833,7 +829,7 @@ void CardinalityExtension::checkNormalForm(Node eqc,
Trace("sets-nf") << " Intro split : " << o0 << " against " << o1
<< ", term is " << intro << std::endl;
intro_sets.push_back(intro);
- Assert(!d_ee.hasTerm(intro));
+ Assert(!d_state.hasTerm(intro));
return;
}
}
diff --git a/src/theory/sets/cardinality_extension.h b/src/theory/sets/cardinality_extension.h
index 570530108..b71af8a43 100644
--- a/src/theory/sets/cardinality_extension.h
+++ b/src/theory/sets/cardinality_extension.h
@@ -69,7 +69,6 @@ class CardinalityExtension
*/
CardinalityExtension(SolverState& s,
InferenceManager& im,
- eq::EqualityEngine& e,
context::Context* c,
context::UserContext* u);
@@ -164,8 +163,6 @@ class CardinalityExtension
SolverState& d_state;
/** Reference to the inference manager for the theory of sets */
InferenceManager& d_im;
- /** Reference to the equality engine of theory of sets */
- eq::EqualityEngine& d_ee;
/** register cardinality term
*
* This method add lemmas corresponding to the definition of
diff --git a/src/theory/sets/inference_manager.cpp b/src/theory/sets/inference_manager.cpp
index ac0a8205b..f99dad91e 100644
--- a/src/theory/sets/inference_manager.cpp
+++ b/src/theory/sets/inference_manager.cpp
@@ -27,12 +27,10 @@ namespace sets {
InferenceManager::InferenceManager(TheorySetsPrivate& p,
SolverState& s,
- eq::EqualityEngine& e,
context::Context* c,
context::UserContext* u)
: d_parent(p),
d_state(s),
- d_ee(e),
d_sentLemma(false),
d_addedFact(false),
d_lemmas_produced(u),
diff --git a/src/theory/sets/inference_manager.h b/src/theory/sets/inference_manager.h
index 2a5a7703c..ba6be9905 100644
--- a/src/theory/sets/inference_manager.h
+++ b/src/theory/sets/inference_manager.h
@@ -40,7 +40,6 @@ class InferenceManager
public:
InferenceManager(TheorySetsPrivate& p,
SolverState& s,
- eq::EqualityEngine& e,
context::Context* c,
context::UserContext* u);
/** reset
@@ -118,8 +117,6 @@ class InferenceManager
TheorySetsPrivate& d_parent;
/** Reference to the state object for the theory of sets */
SolverState& d_state;
- /** Reference to the equality engine of theory of sets */
- eq::EqualityEngine& d_ee;
/** pending lemmas */
std::vector<Node> d_pendingLemmas;
/** sent lemma
diff --git a/src/theory/sets/solver_state.cpp b/src/theory/sets/solver_state.cpp
index d3c23454e..f3371cf61 100644
--- a/src/theory/sets/solver_state.cpp
+++ b/src/theory/sets/solver_state.cpp
@@ -26,15 +26,20 @@ namespace theory {
namespace sets {
SolverState::SolverState(TheorySetsPrivate& p,
- eq::EqualityEngine& e,
context::Context* c,
context::UserContext* u)
- : d_conflict(c), d_parent(p), d_ee(e), d_proxy(u), d_proxy_to_term(u)
+ : d_conflict(c), d_parent(p), d_ee(nullptr), d_proxy(u), d_proxy_to_term(u)
{
d_true = NodeManager::currentNM()->mkConst(true);
d_false = NodeManager::currentNM()->mkConst(false);
}
+void SolverState::finishInit(eq::EqualityEngine* ee)
+{
+ Assert(ee != nullptr);
+ d_ee = ee;
+}
+
void SolverState::reset()
{
d_set_eqc.clear();
@@ -69,8 +74,8 @@ void SolverState::registerTerm(Node r, TypeNode tnn, Node n)
{
if (r.isConst())
{
- Node s = d_ee.getRepresentative(n[1]);
- Node x = d_ee.getRepresentative(n[0]);
+ Node s = d_ee->getRepresentative(n[1]);
+ Node x = d_ee->getRepresentative(n[0]);
int pindex = r == d_true ? 0 : (r == d_false ? 1 : -1);
if (pindex != -1)
{
@@ -99,7 +104,7 @@ void SolverState::registerTerm(Node r, TypeNode tnn, Node n)
{
// singleton lemma
getProxy(n);
- Node re = d_ee.getRepresentative(n[0]);
+ Node re = d_ee->getRepresentative(n[0]);
if (d_singleton_index.find(re) == d_singleton_index.end())
{
d_singleton_index[re] = n;
@@ -122,8 +127,8 @@ void SolverState::registerTerm(Node r, TypeNode tnn, Node n)
}
else
{
- Node r1 = d_ee.getRepresentative(n[0]);
- Node r2 = d_ee.getRepresentative(n[1]);
+ Node r1 = d_ee->getRepresentative(n[0]);
+ Node r2 = d_ee->getRepresentative(n[1]);
std::map<Node, Node>& binr1 = d_bop_index[nk][r1];
std::map<Node, Node>::iterator itb = binr1.find(r2);
if (itb == binr1.end())
@@ -164,15 +169,26 @@ void SolverState::registerTerm(Node r, TypeNode tnn, Node n)
}
}
+Node SolverState::getRepresentative(Node a) const
+{
+ if (d_ee->hasTerm(a))
+ {
+ return d_ee->getRepresentative(a);
+ }
+ return a;
+}
+
+bool SolverState::hasTerm(Node a) const { return d_ee->hasTerm(a); }
+
bool SolverState::areEqual(Node a, Node b) const
{
if (a == b)
{
return true;
}
- if (d_ee.hasTerm(a) && d_ee.hasTerm(b))
+ if (d_ee->hasTerm(a) && d_ee->hasTerm(b))
{
- return d_ee.areEqual(a, b);
+ return d_ee->areEqual(a, b);
}
return false;
}
@@ -183,13 +199,15 @@ bool SolverState::areDisequal(Node a, Node b) const
{
return false;
}
- else if (d_ee.hasTerm(a) && d_ee.hasTerm(b))
+ else if (d_ee->hasTerm(a) && d_ee->hasTerm(b))
{
- return d_ee.areDisequal(a, b, false);
+ return d_ee->areDisequal(a, b, false);
}
return a.isConst() && b.isConst();
}
+eq::EqualityEngine* SolverState::getEqualityEngine() const { return d_ee; }
+
void SolverState::setConflict() { d_conflict = true; }
void SolverState::setConflict(Node conf)
{
@@ -279,9 +297,9 @@ bool SolverState::isEntailed(Node n, bool polarity) const
return true;
}
// check members cache
- if (polarity && d_ee.hasTerm(n[1]))
+ if (polarity && d_ee->hasTerm(n[1]))
{
- Node r = d_ee.getRepresentative(n[1]);
+ Node r = d_ee->getRepresentative(n[1]);
if (d_parent.isMember(n[0], r))
{
return true;
@@ -310,8 +328,8 @@ bool SolverState::isEntailed(Node n, bool polarity) const
bool SolverState::isSetDisequalityEntailed(Node r1, Node r2) const
{
- Assert(d_ee.hasTerm(r1) && d_ee.getRepresentative(r1) == r1);
- Assert(d_ee.hasTerm(r2) && d_ee.getRepresentative(r2) == r2);
+ Assert(d_ee->hasTerm(r1) && d_ee->getRepresentative(r1) == r1);
+ Assert(d_ee->hasTerm(r2) && d_ee->getRepresentative(r2) == r2);
TypeNode tn = r1.getType();
Node re = getEmptySetEqClass(tn);
for (unsigned e = 0; e < 2; e++)
@@ -433,7 +451,7 @@ Node SolverState::getProxy(Node n)
Node SolverState::getCongruent(Node n) const
{
- Assert(d_ee.hasTerm(n));
+ Assert(d_ee->hasTerm(n));
std::map<Node, Node>::const_iterator it = d_congruent.find(n);
if (it == d_congruent.end())
{
diff --git a/src/theory/sets/solver_state.h b/src/theory/sets/solver_state.h
index 0b301dbb7..dce90c2d3 100644
--- a/src/theory/sets/solver_state.h
+++ b/src/theory/sets/solver_state.h
@@ -48,17 +48,21 @@ class SolverState
public:
SolverState(TheorySetsPrivate& p,
- eq::EqualityEngine& e,
context::Context* c,
context::UserContext* u);
- //-------------------------------- initialize
+ /**
+ * Finish initialize, there ee is a pointer to the official equality engine
+ * of theory of strings.
+ */
+ void finishInit(eq::EqualityEngine* ee);
+ //-------------------------------- initialize per check
/** reset, clears the data structures maintained by this class. */
void reset();
/** register equivalence class whose type is tn */
void registerEqc(TypeNode tn, Node r);
/** register term n of type tnn in the equivalence class of r */
void registerTerm(Node r, TypeNode tnn, Node n);
- //-------------------------------- end initialize
+ //-------------------------------- end initialize per check
/** Are we currently in conflict? */
bool isInConflict() const { return d_conflict; }
/**
@@ -68,10 +72,19 @@ class SolverState
void setConflict();
/** Set conf is a conflict node to be sent on the output channel. */
void setConflict(Node conf);
+ /**
+ * Get the representative of a in the equality engine of this class, or a
+ * itself if it is not registered as a term.
+ */
+ Node getRepresentative(Node a) const;
+ /** Is a registered as a term in the equality engine of this class? */
+ bool hasTerm(Node a) const;
/** Is a=b according to equality reasoning in the current context? */
bool areEqual(Node a, Node b) const;
/** Is a!=b according to equality reasoning in the current context? */
bool areDisequal(Node a, Node b) const;
+ /** get equality engine */
+ eq::EqualityEngine* getEqualityEngine() const;
/** add equality to explanation
*
* This adds a = b to exp if a and b are syntactically disequal. The equality
@@ -220,8 +233,8 @@ class SolverState
context::CDO<bool> d_conflict;
/** Reference to the parent theory of sets */
TheorySetsPrivate& d_parent;
- /** Reference to the equality engine of theory of sets */
- eq::EqualityEngine& d_ee;
+ /** Pointer to the official equality engine of theory of sets */
+ eq::EqualityEngine* d_ee;
/** The list of all equivalence classes of type set in the current context */
std::vector<Node> d_set_eqc;
/** Maps types to the equivalence class containing empty set of that type */
diff --git a/src/theory/sets/theory_sets.cpp b/src/theory/sets/theory_sets.cpp
index 9c680cc64..17caac4f7 100644
--- a/src/theory/sets/theory_sets.cpp
+++ b/src/theory/sets/theory_sets.cpp
@@ -34,7 +34,9 @@ TheorySets::TheorySets(context::Context* c,
const LogicInfo& logicInfo,
ProofNodeManager* pnm)
: Theory(THEORY_SETS, c, u, out, valuation, logicInfo, pnm),
- d_internal(new TheorySetsPrivate(*this, c, u))
+ d_internal(new TheorySetsPrivate(*this, c, u)),
+ d_notify(*d_internal.get()),
+ d_equalityEngine(d_notify, c, "theory::sets::ee", true)
{
// Do not move me to the header.
// The constructor + destructor are not in the header as d_internal is a
@@ -57,6 +59,27 @@ void TheorySets::finishInit()
d_valuation.setUnevaluatedKind(COMPREHENSION);
// choice is used to eliminate witness
d_valuation.setUnevaluatedKind(WITNESS);
+
+ // functions we are doing congruence over
+ d_equalityEngine.addFunctionKind(kind::SINGLETON);
+ d_equalityEngine.addFunctionKind(kind::UNION);
+ d_equalityEngine.addFunctionKind(kind::INTERSECTION);
+ d_equalityEngine.addFunctionKind(kind::SETMINUS);
+ d_equalityEngine.addFunctionKind(kind::MEMBER);
+ d_equalityEngine.addFunctionKind(kind::SUBSET);
+ // relation operators
+ d_equalityEngine.addFunctionKind(PRODUCT);
+ d_equalityEngine.addFunctionKind(JOIN);
+ d_equalityEngine.addFunctionKind(TRANSPOSE);
+ d_equalityEngine.addFunctionKind(TCLOSURE);
+ d_equalityEngine.addFunctionKind(JOIN_IMAGE);
+ d_equalityEngine.addFunctionKind(IDEN);
+ d_equalityEngine.addFunctionKind(APPLY_CONSTRUCTOR);
+ // we do congruence over cardinality
+ d_equalityEngine.addFunctionKind(CARD);
+
+ // finish initialization internally
+ d_internal->finishInit();
}
void TheorySets::addSharedTerm(TNode n) {
@@ -171,14 +194,96 @@ void TheorySets::propagate(Effort e) {
d_internal->propagate(e);
}
-void TheorySets::setMasterEqualityEngine(eq::EqualityEngine* eq) {
- d_internal->setMasterEqualityEngine(eq);
-}
-
bool TheorySets::isEntailed( Node n, bool pol ) {
return d_internal->isEntailed( n, pol );
}
+eq::EqualityEngine* TheorySets::getEqualityEngine()
+{
+ return &d_equalityEngine;
+}
+
+/**************************** eq::NotifyClass *****************************/
+
+bool TheorySets::NotifyClass::eqNotifyTriggerEquality(TNode equality,
+ bool value)
+{
+ Debug("sets-eq") << "[sets-eq] eqNotifyTriggerEquality: equality = "
+ << equality << " value = " << value << std::endl;
+ if (value)
+ {
+ return d_theory.propagate(equality);
+ }
+ else
+ {
+ // We use only literal triggers so taking not is safe
+ return d_theory.propagate(equality.notNode());
+ }
+}
+
+bool TheorySets::NotifyClass::eqNotifyTriggerPredicate(TNode predicate,
+ bool value)
+{
+ Debug("sets-eq") << "[sets-eq] eqNotifyTriggerPredicate: predicate = "
+ << predicate << " value = " << value << std::endl;
+ if (value)
+ {
+ return d_theory.propagate(predicate);
+ }
+ else
+ {
+ return d_theory.propagate(predicate.notNode());
+ }
+}
+
+bool TheorySets::NotifyClass::eqNotifyTriggerTermEquality(TheoryId tag,
+ TNode t1,
+ TNode t2,
+ bool value)
+{
+ Debug("sets-eq") << "[sets-eq] eqNotifyTriggerTermEquality: tag = " << tag
+ << " t1 = " << t1 << " t2 = " << t2 << " value = " << value
+ << std::endl;
+ d_theory.propagate(value ? t1.eqNode(t2) : t1.eqNode(t2).negate());
+ return true;
+}
+
+void TheorySets::NotifyClass::eqNotifyConstantTermMerge(TNode t1, TNode t2)
+{
+ Debug("sets-eq") << "[sets-eq] eqNotifyConstantTermMerge "
+ << " t1 = " << t1 << " t2 = " << t2 << std::endl;
+ d_theory.conflict(t1, t2);
+}
+
+void TheorySets::NotifyClass::eqNotifyNewClass(TNode t)
+{
+ Debug("sets-eq") << "[sets-eq] eqNotifyNewClass:"
+ << " t = " << t << std::endl;
+ d_theory.eqNotifyNewClass(t);
+}
+
+void TheorySets::NotifyClass::eqNotifyPreMerge(TNode t1, TNode t2)
+{
+ Debug("sets-eq") << "[sets-eq] eqNotifyPreMerge:"
+ << " t1 = " << t1 << " t2 = " << t2 << std::endl;
+ d_theory.eqNotifyPreMerge(t1, t2);
+}
+
+void TheorySets::NotifyClass::eqNotifyPostMerge(TNode t1, TNode t2)
+{
+ Debug("sets-eq") << "[sets-eq] eqNotifyPostMerge:"
+ << " t1 = " << t1 << " t2 = " << t2 << std::endl;
+ d_theory.eqNotifyPostMerge(t1, t2);
+}
+
+void TheorySets::NotifyClass::eqNotifyDisequal(TNode t1, TNode t2, TNode reason)
+{
+ Debug("sets-eq") << "[sets-eq] eqNotifyDisequal:"
+ << " t1 = " << t1 << " t2 = " << t2 << " reason = " << reason
+ << std::endl;
+ d_theory.eqNotifyDisequal(t1, t2, reason);
+}
+
}/* CVC4::theory::sets namespace */
}/* CVC4::theory namespace */
}/* CVC4 namespace */
diff --git a/src/theory/sets/theory_sets.h b/src/theory/sets/theory_sets.h
index e81412ba9..f1b59e419 100644
--- a/src/theory/sets/theory_sets.h
+++ b/src/theory/sets/theory_sets.h
@@ -33,6 +33,8 @@ class TheorySetsScrutinize;
class TheorySets : public Theory
{
+ friend class TheorySetsPrivate;
+ friend class TheorySetsRels;
public:
/** Constructs a new instance of TheorySets w.r.t. the provided contexts. */
TheorySets(context::Context* c,
@@ -43,10 +45,13 @@ class TheorySets : public Theory
ProofNodeManager* pnm);
~TheorySets() override;
+ //--------------------------------- initialization
+ /** get the official theory rewriter of this theory */
TheoryRewriter* getTheoryRewriter() override;
-
/** finish initialization */
void finishInit() override;
+ //--------------------------------- end initialization
+
void addSharedTerm(TNode) override;
void check(Effort) override;
bool collectModelInfo(TheoryModel* m) override;
@@ -60,15 +65,36 @@ class TheorySets : public Theory
PPAssertStatus ppAssert(TNode in, SubstitutionMap& outSubstitutions) override;
void presolve() override;
void propagate(Effort) override;
- void setMasterEqualityEngine(eq::EqualityEngine* eq) override;
bool isEntailed(Node n, bool pol);
-
+ /* equality engine */
+ virtual eq::EqualityEngine* getEqualityEngine() override;
private:
- friend class TheorySetsPrivate;
- friend class TheorySetsScrutinize;
- friend class TheorySetsRels;
-
+ /** Functions to handle callbacks from equality engine */
+ class NotifyClass : public eq::EqualityEngineNotify
+ {
+ public:
+ NotifyClass(TheorySetsPrivate& theory) : d_theory(theory) {}
+ bool eqNotifyTriggerEquality(TNode equality, bool value) override;
+ bool eqNotifyTriggerPredicate(TNode predicate, bool value) override;
+ bool eqNotifyTriggerTermEquality(TheoryId tag,
+ TNode t1,
+ TNode t2,
+ bool value) override;
+ void eqNotifyConstantTermMerge(TNode t1, TNode t2) override;
+ void eqNotifyNewClass(TNode t) override;
+ void eqNotifyPreMerge(TNode t1, TNode t2) override;
+ void eqNotifyPostMerge(TNode t1, TNode t2) override;
+ void eqNotifyDisequal(TNode t1, TNode t2, TNode reason) override;
+
+ private:
+ TheorySetsPrivate& d_theory;
+ };
+ /** The internal theory */
std::unique_ptr<TheorySetsPrivate> d_internal;
+ /** Instance of the above class */
+ NotifyClass d_notify;
+ /** Equality engine */
+ eq::EqualityEngine d_equalityEngine;
}; /* class TheorySets */
}/* CVC4::theory::sets namespace */
diff --git a/src/theory/sets/theory_sets_private.cpp b/src/theory/sets/theory_sets_private.cpp
index 4c3affe99..25ee3167e 100644
--- a/src/theory/sets/theory_sets_private.cpp
+++ b/src/theory/sets/theory_sets_private.cpp
@@ -43,27 +43,16 @@ TheorySetsPrivate::TheorySetsPrivate(TheorySets& external,
d_keep(c),
d_full_check_incomplete(false),
d_external(external),
- d_notify(*this),
- d_equalityEngine(d_notify, c, "theory::sets::ee", true),
- d_state(*this, d_equalityEngine, c, u),
- d_im(*this, d_state, d_equalityEngine, c, u),
- d_rels(new TheorySetsRels(d_state, d_im, d_equalityEngine, u)),
- d_cardSolver(
- new CardinalityExtension(d_state, d_im, d_equalityEngine, c, u)),
+ d_state(*this, c, u),
+ d_im(*this, d_state, c, u),
+ d_rels(new TheorySetsRels(d_state, d_im, u)),
+ d_cardSolver(new CardinalityExtension(d_state, d_im, c, u)),
d_rels_enabled(false),
d_card_enabled(false)
{
d_true = NodeManager::currentNM()->mkConst(true);
d_false = NodeManager::currentNM()->mkConst(false);
d_zero = NodeManager::currentNM()->mkConst(Rational(0));
-
- d_equalityEngine.addFunctionKind(kind::SINGLETON);
- d_equalityEngine.addFunctionKind(kind::UNION);
- d_equalityEngine.addFunctionKind(kind::INTERSECTION);
- d_equalityEngine.addFunctionKind(kind::SETMINUS);
-
- d_equalityEngine.addFunctionKind(kind::MEMBER);
- d_equalityEngine.addFunctionKind(kind::SUBSET);
}
TheorySetsPrivate::~TheorySetsPrivate()
@@ -74,6 +63,13 @@ TheorySetsPrivate::~TheorySetsPrivate()
}
}
+void TheorySetsPrivate::finishInit()
+{
+ d_equalityEngine = d_external.getEqualityEngine();
+ Assert(d_equalityEngine != nullptr);
+ d_state.finishInit(d_equalityEngine);
+}
+
void TheorySetsPrivate::eqNotifyNewClass(TNode t)
{
if (t.getKind() == kind::SINGLETON || t.getKind() == kind::EMPTYSET)
@@ -240,13 +236,13 @@ TheorySetsPrivate::EqcInfo* TheorySetsPrivate::getOrMakeEqcInfo(TNode n,
bool TheorySetsPrivate::areCareDisequal(Node a, Node b)
{
- if (d_equalityEngine.isTriggerTerm(a, THEORY_SETS)
- && d_equalityEngine.isTriggerTerm(b, THEORY_SETS))
+ if (d_equalityEngine->isTriggerTerm(a, THEORY_SETS)
+ && d_equalityEngine->isTriggerTerm(b, THEORY_SETS))
{
TNode a_shared =
- d_equalityEngine.getTriggerTermRepresentative(a, THEORY_SETS);
+ d_equalityEngine->getTriggerTermRepresentative(a, THEORY_SETS);
TNode b_shared =
- d_equalityEngine.getTriggerTermRepresentative(b, THEORY_SETS);
+ d_equalityEngine->getTriggerTermRepresentative(b, THEORY_SETS);
EqualityStatus eqStatus =
d_external.d_valuation.getEqualityStatus(a_shared, b_shared);
if (eqStatus == EQUALITY_FALSE_AND_PROPAGATED || eqStatus == EQUALITY_FALSE
@@ -260,8 +256,8 @@ bool TheorySetsPrivate::areCareDisequal(Node a, Node b)
bool TheorySetsPrivate::isMember(Node x, Node s)
{
- Assert(d_equalityEngine.hasTerm(s)
- && d_equalityEngine.getRepresentative(s) == s);
+ Assert(d_equalityEngine->hasTerm(s)
+ && d_equalityEngine->getRepresentative(s) == s);
NodeIntMap::iterator mem_i = d_members.find(s);
if (mem_i != d_members.end())
{
@@ -286,18 +282,18 @@ bool TheorySetsPrivate::assertFact(Node fact, Node exp)
{
if (atom.getKind() == kind::EQUAL)
{
- d_equalityEngine.assertEquality(atom, polarity, exp);
+ d_equalityEngine->assertEquality(atom, polarity, exp);
}
else
{
- d_equalityEngine.assertPredicate(atom, polarity, exp);
+ d_equalityEngine->assertPredicate(atom, polarity, exp);
}
if (!d_state.isInConflict())
{
if (atom.getKind() == kind::MEMBER && polarity)
{
// check if set has a value, if so, we can propagate
- Node r = d_equalityEngine.getRepresentative(atom[1]);
+ Node r = d_equalityEngine->getRepresentative(atom[1]);
EqcInfo* e = getOrMakeEqcInfo(r, true);
if (e)
{
@@ -354,7 +350,7 @@ bool TheorySetsPrivate::assertFact(Node fact, Node exp)
void TheorySetsPrivate::fullEffortReset()
{
- Assert(d_equalityEngine.consistent());
+ Assert(d_equalityEngine->consistent());
d_full_check_incomplete = false;
d_most_common_type.clear();
d_most_common_type_term.clear();
@@ -380,7 +376,7 @@ void TheorySetsPrivate::fullEffortCheck()
Trace("sets-eqc") << "Equality Engine:" << std::endl;
std::map<TypeNode, unsigned> eqcTypeCount;
- eq::EqClassesIterator eqcs_i = eq::EqClassesIterator(&d_equalityEngine);
+ eq::EqClassesIterator eqcs_i = eq::EqClassesIterator(d_equalityEngine);
while (!eqcs_i.isFinished())
{
Node eqc = (*eqcs_i);
@@ -398,7 +394,7 @@ void TheorySetsPrivate::fullEffortCheck()
tnct = eqc;
}
Trace("sets-eqc") << "[" << eqc << "] : ";
- eq::EqClassIterator eqc_i = eq::EqClassIterator(eqc, &d_equalityEngine);
+ eq::EqClassIterator eqc_i = eq::EqClassIterator(eqc, d_equalityEngine);
while (!eqc_i.isFinished())
{
Node n = (*eqc_i);
@@ -624,7 +620,7 @@ void TheorySetsPrivate::checkDownwardsClosure()
{
Node mem = it2.second;
Node eq_set = nv;
- Assert(d_equalityEngine.areEqual(mem[1], eq_set));
+ Assert(d_equalityEngine->areEqual(mem[1], eq_set));
if (mem[1] != eq_set)
{
Trace("sets-debug") << "Downwards closure based on " << mem
@@ -761,7 +757,7 @@ void TheorySetsPrivate::checkUpwardsClosure()
}
if (valid)
{
- Node rr = d_equalityEngine.getRepresentative(term);
+ Node rr = d_equalityEngine->getRepresentative(term);
if (!isMember(x, rr))
{
Node kk = d_state.getProxy(term);
@@ -785,7 +781,7 @@ void TheorySetsPrivate::checkUpwardsClosure()
for (const std::pair<const Node, Node>& itm2m : r2mem)
{
Node x = itm2m.second[0];
- Node rr = d_equalityEngine.getRepresentative(term);
+ Node rr = d_equalityEngine->getRepresentative(term);
if (!isMember(x, rr))
{
std::vector<Node> exp;
@@ -882,10 +878,10 @@ void TheorySetsPrivate::checkDisequalities()
}
Node deq = (*it).first;
// check if it is already satisfied
- Assert(d_equalityEngine.hasTerm(deq[0])
- && d_equalityEngine.hasTerm(deq[1]));
- Node r1 = d_equalityEngine.getRepresentative(deq[0]);
- Node r2 = d_equalityEngine.getRepresentative(deq[1]);
+ Assert(d_equalityEngine->hasTerm(deq[0])
+ && d_equalityEngine->hasTerm(deq[1]));
+ Node r1 = d_equalityEngine->getRepresentative(deq[0]);
+ Node r2 = d_equalityEngine->getRepresentative(deq[1]);
bool is_sat = d_state.isSetDisequalityEntailed(r1, r2);
Trace("sets-debug") << "Check disequality " << deq
<< ", is_sat = " << is_sat << std::endl;
@@ -1005,7 +1001,7 @@ void TheorySetsPrivate::addSharedTerm(TNode n)
{
Debug("sets") << "[sets] TheorySetsPrivate::addSharedTerm( " << n << ")"
<< std::endl;
- d_equalityEngine.addTriggerTerm(n, THEORY_SETS);
+ d_equalityEngine->addTriggerTerm(n, THEORY_SETS);
}
void TheorySetsPrivate::addCarePairs(TNodeTrie* t1,
@@ -1028,21 +1024,21 @@ void TheorySetsPrivate::addCarePairs(TNodeTrie* t1,
{
TNode x = f1[k];
TNode y = f2[k];
- Assert(d_equalityEngine.hasTerm(x));
- Assert(d_equalityEngine.hasTerm(y));
+ Assert(d_equalityEngine->hasTerm(x));
+ Assert(d_equalityEngine->hasTerm(y));
Assert(!d_state.areDisequal(x, y));
Assert(!areCareDisequal(x, y));
- if (!d_equalityEngine.areEqual(x, y))
+ if (!d_equalityEngine->areEqual(x, y))
{
Trace("sets-cg")
<< "Arg #" << k << " is " << x << " " << y << std::endl;
- if (d_equalityEngine.isTriggerTerm(x, THEORY_SETS)
- && d_equalityEngine.isTriggerTerm(y, THEORY_SETS))
+ if (d_equalityEngine->isTriggerTerm(x, THEORY_SETS)
+ && d_equalityEngine->isTriggerTerm(y, THEORY_SETS))
{
- TNode x_shared =
- d_equalityEngine.getTriggerTermRepresentative(x, THEORY_SETS);
- TNode y_shared =
- d_equalityEngine.getTriggerTermRepresentative(y, THEORY_SETS);
+ TNode x_shared = d_equalityEngine->getTriggerTermRepresentative(
+ x, THEORY_SETS);
+ TNode y_shared = d_equalityEngine->getTriggerTermRepresentative(
+ y, THEORY_SETS);
currentPairs.push_back(make_pair(x_shared, y_shared));
}
else if (isCareArg(f1, k) && isCareArg(f2, k))
@@ -1092,7 +1088,7 @@ void TheorySetsPrivate::addCarePairs(TNodeTrie* t1,
++it2;
for (; it2 != t1->d_data.end(); ++it2)
{
- if (!d_equalityEngine.areDisequal(it->first, it2->first, false))
+ if (!d_equalityEngine->areDisequal(it->first, it2->first, false))
{
if (!areCareDisequal(it->first, it2->first))
{
@@ -1110,7 +1106,7 @@ void TheorySetsPrivate::addCarePairs(TNodeTrie* t1,
{
for (std::pair<const TNode, TNodeTrie>& tt2 : t2->d_data)
{
- if (!d_equalityEngine.areDisequal(tt1.first, tt2.first, false))
+ if (!d_equalityEngine->areDisequal(tt1.first, tt2.first, false))
{
if (!areCareDisequal(tt1.first, tt2.first))
{
@@ -1140,9 +1136,9 @@ void TheorySetsPrivate::computeCareGraph()
// populate indices
for (TNode f1 : it.second)
{
- Assert(d_equalityEngine.hasTerm(f1));
+ Assert(d_equalityEngine->hasTerm(f1));
Trace("sets-cg-debug") << "...build for " << f1 << std::endl;
- Assert(d_equalityEngine.hasTerm(f1));
+ Assert(d_equalityEngine->hasTerm(f1));
// break into index based on operator, and type of first argument (since
// some operators are parametric)
TypeNode tn = f1[0].getType();
@@ -1150,7 +1146,7 @@ void TheorySetsPrivate::computeCareGraph()
bool hasCareArg = false;
for (unsigned j = 0; j < f1.getNumChildren(); j++)
{
- reps.push_back(d_equalityEngine.getRepresentative(f1[j]));
+ reps.push_back(d_equalityEngine->getRepresentative(f1[j]));
if (isCareArg(f1, j))
{
hasCareArg = true;
@@ -1184,7 +1180,7 @@ void TheorySetsPrivate::computeCareGraph()
bool TheorySetsPrivate::isCareArg(Node n, unsigned a)
{
- if (d_equalityEngine.isTriggerTerm(n[a], THEORY_SETS))
+ if (d_equalityEngine->isTriggerTerm(n[a], THEORY_SETS))
{
return true;
}
@@ -1201,13 +1197,13 @@ bool TheorySetsPrivate::isCareArg(Node n, unsigned a)
EqualityStatus TheorySetsPrivate::getEqualityStatus(TNode a, TNode b)
{
- Assert(d_equalityEngine.hasTerm(a) && d_equalityEngine.hasTerm(b));
- if (d_equalityEngine.areEqual(a, b))
+ Assert(d_equalityEngine->hasTerm(a) && d_equalityEngine->hasTerm(b));
+ if (d_equalityEngine->areEqual(a, b))
{
// The terms are implied to be equal
return EQUALITY_TRUE;
}
- if (d_equalityEngine.areDisequal(a, b, false))
+ if (d_equalityEngine->areDisequal(a, b, false))
{
// The terms are implied to be dis-equal
return EQUALITY_FALSE;
@@ -1272,7 +1268,7 @@ bool TheorySetsPrivate::collectModelInfo(TheoryModel* m)
d_external.computeRelevantTerms(termSet);
// Assert equalities and disequalities to the model
- if (!m->assertEqualityEngine(&d_equalityEngine, &termSet))
+ if (!m->assertEqualityEngine(d_equalityEngine, &termSet))
{
return false;
}
@@ -1429,11 +1425,6 @@ OutputChannel* TheorySetsPrivate::getOutputChannel()
Valuation& TheorySetsPrivate::getValuation() { return d_external.d_valuation; }
-void TheorySetsPrivate::setMasterEqualityEngine(eq::EqualityEngine* eq)
-{
- d_equalityEngine.setMasterEqualityEngine(eq);
-}
-
void TheorySetsPrivate::conflict(TNode a, TNode b)
{
Node conf = explain(a.eqNode(b));
@@ -1453,11 +1444,11 @@ Node TheorySetsPrivate::explain(TNode literal)
if (atom.getKind() == kind::EQUAL)
{
- d_equalityEngine.explainEquality(atom[0], atom[1], polarity, assumptions);
+ d_equalityEngine->explainEquality(atom[0], atom[1], polarity, assumptions);
}
else if (atom.getKind() == kind::MEMBER)
{
- d_equalityEngine.explainPredicate(atom, polarity, assumptions);
+ d_equalityEngine->explainPredicate(atom, polarity, assumptions);
}
else
{
@@ -1475,10 +1466,10 @@ void TheorySetsPrivate::preRegisterTerm(TNode node)
<< std::endl;
switch (node.getKind())
{
- case kind::EQUAL: d_equalityEngine.addTriggerEquality(node); break;
- case kind::MEMBER: d_equalityEngine.addTriggerPredicate(node); break;
- case kind::CARD: d_equalityEngine.addTriggerTerm(node, THEORY_SETS); break;
- default: d_equalityEngine.addTerm(node); break;
+ case kind::EQUAL: d_equalityEngine->addTriggerEquality(node); break;
+ case kind::MEMBER: d_equalityEngine->addTriggerPredicate(node); break;
+ case kind::CARD: d_equalityEngine->addTriggerTerm(node, THEORY_SETS); break;
+ default: d_equalityEngine->addTerm(node); break;
}
}
@@ -1538,92 +1529,6 @@ Node TheorySetsPrivate::getChooseFunction(const TypeNode& setType)
void TheorySetsPrivate::presolve() { d_state.reset(); }
-/**************************** eq::NotifyClass *****************************/
-/**************************** eq::NotifyClass *****************************/
-/**************************** eq::NotifyClass *****************************/
-
-bool TheorySetsPrivate::NotifyClass::eqNotifyTriggerEquality(TNode equality,
- bool value)
-{
- Debug("sets-eq") << "[sets-eq] eqNotifyTriggerEquality: equality = "
- << equality << " value = " << value << std::endl;
- if (value)
- {
- return d_theory.propagate(equality);
- }
- else
- {
- // We use only literal triggers so taking not is safe
- return d_theory.propagate(equality.notNode());
- }
-}
-
-bool TheorySetsPrivate::NotifyClass::eqNotifyTriggerPredicate(TNode predicate,
- bool value)
-{
- Debug("sets-eq") << "[sets-eq] eqNotifyTriggerPredicate: predicate = "
- << predicate << " value = " << value << std::endl;
- if (value)
- {
- return d_theory.propagate(predicate);
- }
- else
- {
- return d_theory.propagate(predicate.notNode());
- }
-}
-
-bool TheorySetsPrivate::NotifyClass::eqNotifyTriggerTermEquality(TheoryId tag,
- TNode t1,
- TNode t2,
- bool value)
-{
- Debug("sets-eq") << "[sets-eq] eqNotifyTriggerTermEquality: tag = " << tag
- << " t1 = " << t1 << " t2 = " << t2 << " value = " << value
- << std::endl;
- d_theory.propagate(value ? t1.eqNode(t2) : t1.eqNode(t2).negate());
- return true;
-}
-
-void TheorySetsPrivate::NotifyClass::eqNotifyConstantTermMerge(TNode t1,
- TNode t2)
-{
- Debug("sets-eq") << "[sets-eq] eqNotifyConstantTermMerge "
- << " t1 = " << t1 << " t2 = " << t2 << std::endl;
- d_theory.conflict(t1, t2);
-}
-
-void TheorySetsPrivate::NotifyClass::eqNotifyNewClass(TNode t)
-{
- Debug("sets-eq") << "[sets-eq] eqNotifyNewClass:"
- << " t = " << t << std::endl;
- d_theory.eqNotifyNewClass(t);
-}
-
-void TheorySetsPrivate::NotifyClass::eqNotifyPreMerge(TNode t1, TNode t2)
-{
- Debug("sets-eq") << "[sets-eq] eqNotifyPreMerge:"
- << " t1 = " << t1 << " t2 = " << t2 << std::endl;
- d_theory.eqNotifyPreMerge(t1, t2);
-}
-
-void TheorySetsPrivate::NotifyClass::eqNotifyPostMerge(TNode t1, TNode t2)
-{
- Debug("sets-eq") << "[sets-eq] eqNotifyPostMerge:"
- << " t1 = " << t1 << " t2 = " << t2 << std::endl;
- d_theory.eqNotifyPostMerge(t1, t2);
-}
-
-void TheorySetsPrivate::NotifyClass::eqNotifyDisequal(TNode t1,
- TNode t2,
- TNode reason)
-{
- Debug("sets-eq") << "[sets-eq] eqNotifyDisequal:"
- << " t1 = " << t1 << " t2 = " << t2 << " reason = " << reason
- << std::endl;
- d_theory.eqNotifyDisequal(t1, t2, reason);
-}
-
} // namespace sets
} // namespace theory
} // namespace CVC4
diff --git a/src/theory/sets/theory_sets_private.h b/src/theory/sets/theory_sets_private.h
index c65c86795..2779a42b7 100644
--- a/src/theory/sets/theory_sets_private.h
+++ b/src/theory/sets/theory_sets_private.h
@@ -163,7 +163,11 @@ class TheorySetsPrivate {
TheoryRewriter* getTheoryRewriter() { return &d_rewriter; }
- void setMasterEqualityEngine(eq::EqualityEngine* eq);
+ /**
+ * Finish initialize, called after the equality engine of theory sets has
+ * been determined.
+ */
+ void finishInit();
void addSharedTerm(TNode);
@@ -219,37 +223,18 @@ class TheorySetsPrivate {
/** get the valuation */
Valuation& getValuation();
- private:
- TheorySets& d_external;
-
- /** Functions to handle callbacks from equality engine */
- class NotifyClass : public eq::EqualityEngineNotify {
- TheorySetsPrivate& d_theory;
-
- public:
- NotifyClass(TheorySetsPrivate& theory): d_theory(theory) {}
- bool eqNotifyTriggerEquality(TNode equality, bool value) override;
- bool eqNotifyTriggerPredicate(TNode predicate, bool value) override;
- bool eqNotifyTriggerTermEquality(TheoryId tag,
- TNode t1,
- TNode t2,
- bool value) override;
- void eqNotifyConstantTermMerge(TNode t1, TNode t2) override;
- void eqNotifyNewClass(TNode t) override;
- void eqNotifyPreMerge(TNode t1, TNode t2) override;
- void eqNotifyPostMerge(TNode t1, TNode t2) override;
- void eqNotifyDisequal(TNode t1, TNode t2, TNode reason) override;
- } d_notify;
-
- /** Equality engine */
- eq::EqualityEngine d_equalityEngine;
-
/** Proagate out to output channel */
bool propagate(TNode);
/** generate and send out conflict node */
void conflict(TNode, TNode);
-
+
+ private:
+ TheorySets& d_external;
+
+ /** Pointer to the equality engine of theory of sets */
+ eq::EqualityEngine* d_equalityEngine;
+
bool isCareArg( Node n, unsigned a );
public:
diff --git a/src/theory/sets/theory_sets_rels.cpp b/src/theory/sets/theory_sets_rels.cpp
index f4b1d3be9..82f32337e 100644
--- a/src/theory/sets/theory_sets_rels.cpp
+++ b/src/theory/sets/theory_sets_rels.cpp
@@ -34,19 +34,11 @@ typedef std::map< Node, std::map< Node, std::unordered_set< Node, NodeHashFuncti
TheorySetsRels::TheorySetsRels(SolverState& s,
InferenceManager& im,
- eq::EqualityEngine& e,
context::UserContext* u)
- : d_state(s), d_im(im), d_ee(e), d_shared_terms(u)
+ : d_state(s), d_im(im), d_shared_terms(u)
{
d_trueNode = NodeManager::currentNM()->mkConst(true);
d_falseNode = NodeManager::currentNM()->mkConst(false);
- d_ee.addFunctionKind(PRODUCT);
- d_ee.addFunctionKind(JOIN);
- d_ee.addFunctionKind(TRANSPOSE);
- d_ee.addFunctionKind(TCLOSURE);
- d_ee.addFunctionKind(JOIN_IMAGE);
- d_ee.addFunctionKind(IDEN);
- d_ee.addFunctionKind(APPLY_CONSTRUCTOR);
}
TheorySetsRels::~TheorySetsRels() {}
@@ -185,10 +177,11 @@ void TheorySetsRels::check(Theory::Effort level)
void TheorySetsRels::collectRelsInfo() {
Trace("rels") << "[sets-rels] Start collecting relational terms..." << std::endl;
- eq::EqClassesIterator eqcs_i = eq::EqClassesIterator(&d_ee);
+ eq::EqualityEngine* ee = d_state.getEqualityEngine();
+ eq::EqClassesIterator eqcs_i = eq::EqClassesIterator(ee);
while( !eqcs_i.isFinished() ){
Node eqc_rep = (*eqcs_i);
- eq::EqClassIterator eqc_i = eq::EqClassIterator(eqc_rep, &d_ee);
+ eq::EqClassIterator eqc_i = eq::EqClassIterator(eqc_rep, ee);
TypeNode erType = eqc_rep.getType();
Trace("rels-ee") << "[sets-rels-ee] Eqc term representative: " << eqc_rep << " with type " << eqc_rep.getType() << std::endl;
@@ -1139,24 +1132,17 @@ void TheorySetsRels::check(Theory::Effort level)
}
Node TheorySetsRels::getRepresentative( Node t ) {
- if (d_ee.hasTerm(t))
- {
- return d_ee.getRepresentative(t);
- }
- else
- {
- return t;
- }
+ return d_state.getRepresentative(t);
}
- bool TheorySetsRels::hasTerm(Node a) { return d_ee.hasTerm(a); }
+ bool TheorySetsRels::hasTerm(Node a) { return d_state.hasTerm(a); }
bool TheorySetsRels::areEqual( Node a, Node b ){
Assert(a.getType() == b.getType());
Trace("rels-eq") << "[sets-rels]**** checking equality between " << a << " and " << b << std::endl;
if(a == b) {
return true;
} else if( hasTerm( a ) && hasTerm( b ) ){
- return d_ee.areEqual(a, b);
+ return d_state.areEqual(a, b);
} else if(a.getType().isTuple()) {
bool equal = true;
for(unsigned int i = 0; i < a.getType().getTupleLength(); i++) {
diff --git a/src/theory/sets/theory_sets_rels.h b/src/theory/sets/theory_sets_rels.h
index 0d8ace50f..60715ff57 100644
--- a/src/theory/sets/theory_sets_rels.h
+++ b/src/theory/sets/theory_sets_rels.h
@@ -67,7 +67,6 @@ class TheorySetsRels {
public:
TheorySetsRels(SolverState& s,
InferenceManager& im,
- eq::EqualityEngine& e,
context::UserContext* u);
~TheorySetsRels();
@@ -90,8 +89,6 @@ private:
SolverState& d_state;
/** Reference to the inference manager for the theory of sets */
InferenceManager& d_im;
- /** Reference to the equality engine of theory of sets */
- eq::EqualityEngine& d_ee;
/** A list of pending inferences to process */
std::vector<Node> d_pending;
NodeSet d_shared_terms;
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback