summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/CMakeLists.txt4
-rw-r--r--src/theory/shared_solver.cpp116
-rw-r--r--src/theory/shared_solver.h133
-rw-r--r--src/theory/shared_solver_distributed.cpp95
-rw-r--r--src/theory/shared_solver_distributed.h64
-rw-r--r--src/theory/shared_terms_database.cpp12
-rw-r--r--src/theory/shared_terms_database.h11
-rw-r--r--src/theory/theory_engine.h2
8 files changed, 437 insertions, 0 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index e6cb97894..5695e271e 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -732,6 +732,10 @@ libcvc4_add_sources(
theory/sets/theory_sets_type_enumerator.cpp
theory/sets/theory_sets_type_enumerator.h
theory/sets/theory_sets_type_rules.h
+ theory/shared_solver.cpp
+ theory/shared_solver.h
+ theory/shared_solver_distributed.cpp
+ theory/shared_solver_distributed.h
theory/shared_terms_database.cpp
theory/shared_terms_database.h
theory/smt_engine_subsolver.cpp
diff --git a/src/theory/shared_solver.cpp b/src/theory/shared_solver.cpp
new file mode 100644
index 000000000..794d3ca7c
--- /dev/null
+++ b/src/theory/shared_solver.cpp
@@ -0,0 +1,116 @@
+/********************* */
+/*! \file shared_solver.cpp
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Andrew Reynolds
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2020 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** \brief The shared solver base class
+ **/
+
+#include "theory/shared_solver.h"
+
+#include "expr/node_visitor.h"
+#include "theory/theory_engine.h"
+
+namespace CVC4 {
+namespace theory {
+
+// Always creates shared terms database. In all cases, shared terms
+// database is used as a way of tracking which calls to Theory::addSharedTerm
+// we need to make in preNotifySharedFact.
+// In distributed equality engine management, shared terms database also
+// maintains an equality engine. In central equality engine management,
+// it does not.
+SharedSolver::SharedSolver(TheoryEngine& te)
+ : d_te(te),
+ d_logicInfo(te.getLogicInfo()),
+ d_sharedTerms(&d_te, d_te.getSatContext()),
+ d_sharedTermsVisitor(d_sharedTerms)
+{
+}
+
+bool SharedSolver::needsEqualityEngine(theory::EeSetupInfo& esi)
+{
+ return false;
+}
+
+void SharedSolver::preRegisterShared(TNode t, bool multipleTheories)
+{
+ // register it with the equality engine manager if sharing is enabled
+ if (d_logicInfo.isSharingEnabled())
+ {
+ preRegisterSharedInternal(t);
+ }
+ // if multiple theories are present in t
+ if (multipleTheories)
+ {
+ // Collect the shared terms if there are multiple theories
+ // This calls Theory::addSharedTerm, possibly multiple times
+ NodeVisitor<SharedTermsVisitor>::run(d_sharedTermsVisitor, t);
+ }
+}
+
+void SharedSolver::preNotifySharedFact(TNode atom)
+{
+ if (d_sharedTerms.hasSharedTerms(atom))
+ {
+ // Always notify the theories of the shared terms, which is independent of
+ // the architecture currently.
+ SharedTermsDatabase::shared_terms_iterator it = d_sharedTerms.begin(atom);
+ SharedTermsDatabase::shared_terms_iterator it_end = d_sharedTerms.end(atom);
+ for (; it != it_end; ++it)
+ {
+ TNode term = *it;
+ TheoryIdSet theories = d_sharedTerms.getTheoriesToNotify(atom, term);
+ for (TheoryId id = THEORY_FIRST; id != THEORY_LAST; ++id)
+ {
+ if (TheoryIdSetUtil::setContains(id, theories))
+ {
+ Theory* t = d_te.theoryOf(id);
+ // call the add shared term method
+ t->addSharedTerm(term);
+ }
+ }
+ d_sharedTerms.markNotified(term, theories);
+ }
+ }
+}
+
+EqualityStatus SharedSolver::getEqualityStatus(TNode a, TNode b)
+{
+ return EQUALITY_UNKNOWN;
+}
+
+void SharedSolver::sendLemma(TrustNode trn, TheoryId atomsTo)
+{
+ d_te.lemma(trn, LemmaProperty::NONE, atomsTo);
+}
+
+bool SharedSolver::propagateSharedEquality(theory::TheoryId theory,
+ TNode a,
+ TNode b,
+ bool value)
+{
+ // Propagate equality between shared terms to the one who asked for it
+ Node equality = a.eqNode(b);
+ if (value)
+ {
+ d_te.assertToTheory(equality, equality, theory, THEORY_BUILTIN);
+ }
+ else
+ {
+ d_te.assertToTheory(
+ equality.notNode(), equality.notNode(), theory, THEORY_BUILTIN);
+ }
+ return true;
+}
+
+bool SharedSolver::isShared(TNode t) const { return d_sharedTerms.isShared(t); }
+
+} // namespace theory
+} // namespace CVC4
diff --git a/src/theory/shared_solver.h b/src/theory/shared_solver.h
new file mode 100644
index 000000000..d3604faca
--- /dev/null
+++ b/src/theory/shared_solver.h
@@ -0,0 +1,133 @@
+/********************* */
+/*! \file shared_solver.h
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Andrew Reynolds
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2020 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** \brief Base class for shared solver
+ **/
+
+#include "cvc4_private.h"
+
+#ifndef CVC4__THEORY__SHARED_SOLVER__H
+#define CVC4__THEORY__SHARED_SOLVER__H
+
+#include "expr/node.h"
+#include "theory/ee_setup_info.h"
+#include "theory/logic_info.h"
+#include "theory/shared_terms_database.h"
+#include "theory/term_registration_visitor.h"
+#include "theory/valuation.h"
+
+namespace CVC4 {
+
+class TheoryEngine;
+
+namespace theory {
+
+/**
+ * A base class for shared solver. The shared solver is the component of theory
+ * engine that behaves like a theory solver, and whose purpose is to ensure the
+ * main theory combination method can be performed in CombinationEngine.
+ * Its role is to:
+ * (1) Notify the individual theories of shared terms via addSharedTerms,
+ * (2) Be the official interface for equality statuses,
+ * (3) Propagate equalities to TheoryEngine when necessary and explain them.
+ */
+class SharedSolver
+{
+ public:
+ SharedSolver(TheoryEngine& te);
+ virtual ~SharedSolver() {}
+ //------------------------------------- initialization
+ /**
+ * Returns true if we need an equality engine, this has the same contract
+ * as Theory::needsEqualityEngine.
+ */
+ virtual bool needsEqualityEngine(theory::EeSetupInfo& esi);
+ /**
+ * Set the equality engine. This should be called by equality engine manager
+ * during EqEngineManager::initializeTheories.
+ */
+ virtual void setEqualityEngine(eq::EqualityEngine* ee) = 0;
+ //------------------------------------- end initialization
+ /**
+ * Called when the given term t is pre-registered in TheoryEngine.
+ *
+ * This adds t as an equality to propagate in the shared terms database
+ * if it is an equality, or adds its shared terms if it involves multiple
+ * theories.
+ *
+ * @param t The term to preregister
+ * @param multipleTheories Whether multiple theories are present in t.
+ */
+ void preRegisterShared(TNode t, bool multipleTheories);
+ /**
+ * Pre-notify assertion fact with the given atom. This is called when any
+ * fact is asserted in TheoryEngine, just before it is dispatched to the
+ * appropriate theory.
+ *
+ * This calls Theory::notifySharedTerm for the shared terms of the atom.
+ */
+ void preNotifySharedFact(TNode atom);
+ /**
+ * Get the equality status of a and b.
+ *
+ * This method is used by theories via Valuation mostly for determining their
+ * care graph.
+ */
+ virtual EqualityStatus getEqualityStatus(TNode a, TNode b);
+ /**
+ * Explain literal, which returns a conjunction of literals that entail
+ * the given one.
+ */
+ virtual TrustNode explain(TNode literal, TheoryId id) = 0;
+ /**
+ * Assert equality to the shared terms database.
+ *
+ * This method is called by TheoryEngine when a fact has been marked to
+ * send to THEORY_BUILTIN, meaning that shared terms database should
+ * maintain this fact. This is the case when either an equality is
+ * asserted from the SAT solver or a theory propagates an equality between
+ * shared terms.
+ */
+ virtual void assertSharedEquality(TNode equality,
+ bool polarity,
+ TNode reason) = 0;
+ /** Is term t a shared term? */
+ virtual bool isShared(TNode t) const;
+
+ /**
+ * Method called by equalityEngine when a becomes (dis-)equal to b and a and b
+ * are shared with the theory. Returns false if there is a direct conflict
+ * (via rewrite for example).
+ */
+ bool propagateSharedEquality(theory::TheoryId theory,
+ TNode a,
+ TNode b,
+ bool value);
+ /** Send lemma to the theory engine, atomsTo is the theory to send atoms to */
+ void sendLemma(TrustNode trn, TheoryId atomsTo);
+
+ protected:
+ /** Solver-specific pre-register shared */
+ virtual void preRegisterSharedInternal(TNode t) = 0;
+ /** Reference to the theory engine */
+ TheoryEngine& d_te;
+ /** Logic info of theory engine (cached) */
+ const LogicInfo& d_logicInfo;
+ /** The database of shared terms.*/
+ SharedTermsDatabase d_sharedTerms;
+ /** Visitor for collecting shared terms */
+ SharedTermsVisitor d_sharedTermsVisitor;
+};
+
+} // namespace theory
+} // namespace CVC4
+
+#endif /* CVC4__THEORY__SHARED_SOLVER__H */
diff --git a/src/theory/shared_solver_distributed.cpp b/src/theory/shared_solver_distributed.cpp
new file mode 100644
index 000000000..873c81db1
--- /dev/null
+++ b/src/theory/shared_solver_distributed.cpp
@@ -0,0 +1,95 @@
+/********************* */
+/*! \file shared_solver_distributed.cpp
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Andrew Reynolds
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2020 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** \brief Shared solver in the distributed architecture
+ **/
+
+#include "theory/shared_solver_distributed.h"
+
+#include "theory/theory_engine.h"
+
+namespace CVC4 {
+namespace theory {
+
+SharedSolverDistributed::SharedSolverDistributed(TheoryEngine& te)
+ : SharedSolver(te)
+{
+}
+
+bool SharedSolverDistributed::needsEqualityEngine(theory::EeSetupInfo& esi)
+{
+ return d_sharedTerms.needsEqualityEngine(esi);
+}
+
+void SharedSolverDistributed::setEqualityEngine(eq::EqualityEngine* ee)
+{
+ d_sharedTerms.setEqualityEngine(ee);
+}
+
+void SharedSolverDistributed::preRegisterSharedInternal(TNode t)
+{
+ if (t.getKind() == kind::EQUAL)
+ {
+ // When sharing is enabled, we propagate from the shared terms manager also
+ d_sharedTerms.addEqualityToPropagate(t);
+ }
+}
+
+EqualityStatus SharedSolverDistributed::getEqualityStatus(TNode a, TNode b)
+{
+ // if we're using a shared terms database, ask its status if a and b are
+ // shared.
+ if (d_sharedTerms.isShared(a) && d_sharedTerms.isShared(b))
+ {
+ if (d_sharedTerms.areEqual(a, b))
+ {
+ return EQUALITY_TRUE_AND_PROPAGATED;
+ }
+ else if (d_sharedTerms.areDisequal(a, b))
+ {
+ return EQUALITY_FALSE_AND_PROPAGATED;
+ }
+ }
+ // otherwise, ask the theory
+ return d_te.theoryOf(Theory::theoryOf(a.getType()))->getEqualityStatus(a, b);
+}
+
+TrustNode SharedSolverDistributed::explain(TNode literal, TheoryId id)
+{
+ TrustNode texp;
+ if (id == THEORY_BUILTIN)
+ {
+ // explanation using the shared terms database
+ Node exp = d_sharedTerms.explain(literal);
+ texp = TrustNode::mkTrustPropExp(literal, exp, nullptr);
+ Trace("shared-solver")
+ << "\tTerm was propagated by THEORY_BUILTIN. Explanation: "
+ << texp.getNode() << std::endl;
+ }
+ else
+ {
+ // By default, we ask the individual theory for the explanation.
+ texp = d_te.theoryOf(id)->explain(literal);
+ Trace("shared-solver") << "\tTerm was propagated by owner theory: " << id
+ << ". Explanation: " << texp.getNode() << std::endl;
+ }
+ return texp;
+}
+
+void SharedSolverDistributed::assertSharedEquality(TNode equality,
+ bool polarity,
+ TNode reason)
+{
+ d_sharedTerms.assertEquality(equality, polarity, reason);
+}
+
+} // namespace theory
+} // namespace CVC4
diff --git a/src/theory/shared_solver_distributed.h b/src/theory/shared_solver_distributed.h
new file mode 100644
index 000000000..45c7eafb3
--- /dev/null
+++ b/src/theory/shared_solver_distributed.h
@@ -0,0 +1,64 @@
+/********************* */
+/*! \file shared_solver_distributed.h
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Andrew Reynolds
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2020 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** \brief Shared solver in the distributed architecture.
+ **/
+
+#include "cvc4_private.h"
+
+#ifndef CVC4__THEORY__SHARED_SOLVER_DISTRIBUTED__H
+#define CVC4__THEORY__SHARED_SOLVER_DISTRIBUTED__H
+
+#include "expr/node.h"
+#include "theory/shared_solver.h"
+
+namespace CVC4 {
+namespace theory {
+
+/**
+ * The shared solver in the distributed architecture. This class uses the
+ * SharedTermsDatabase for implementing the core methods of a shared solver.
+ */
+class SharedSolverDistributed : public SharedSolver
+{
+ public:
+ SharedSolverDistributed(TheoryEngine& te);
+ virtual ~SharedSolverDistributed() {}
+ //------------------------------------- initialization
+ /**
+ * Returns true if we need an equality engine, this has the same contract
+ * as Theory::needsEqualityEngine.
+ */
+ bool needsEqualityEngine(theory::EeSetupInfo& esi) override;
+ /** Set equality engine in the shared terms database */
+ void setEqualityEngine(eq::EqualityEngine* ee) override;
+ //------------------------------------- end initialization
+ /** Assert equality to the shared terms database. */
+ void assertSharedEquality(TNode equality,
+ bool polarity,
+ TNode reason) override;
+ /**
+ * Get equality status based on the equality engine of shared terms database
+ */
+ EqualityStatus getEqualityStatus(TNode a, TNode b) override;
+ /** Explain literal that was propagated by a theory or using shared terms
+ * database */
+ TrustNode explain(TNode literal, TheoryId id) override;
+
+ protected:
+ /** If t is an equality, add it as one that may be propagated */
+ void preRegisterSharedInternal(TNode t) override;
+};
+
+} // namespace theory
+} // namespace CVC4
+
+#endif /* CVC4__THEORY__SHARED_SOLVER_DISTRIBUTED__H */
diff --git a/src/theory/shared_terms_database.cpp b/src/theory/shared_terms_database.cpp
index b01cef377..034401b9a 100644
--- a/src/theory/shared_terms_database.cpp
+++ b/src/theory/shared_terms_database.cpp
@@ -44,6 +44,18 @@ SharedTermsDatabase::~SharedTermsDatabase()
smtStatisticsRegistry()->unregisterStat(&d_statSharedTerms);
}
+void SharedTermsDatabase::setEqualityEngine(eq::EqualityEngine* ee)
+{
+ // TODO (project #39): dynamic allocation of equality engine here
+}
+
+bool SharedTermsDatabase::needsEqualityEngine(EeSetupInfo& esi)
+{
+ esi.d_notify = &d_EENotify;
+ esi.d_name = "SharedTermsDatabase";
+ return true;
+}
+
void SharedTermsDatabase::addEqualityToPropagate(TNode equality) {
d_registeredEqualities.insert(equality);
d_equalityEngine.addTriggerPredicate(equality);
diff --git a/src/theory/shared_terms_database.h b/src/theory/shared_terms_database.h
index ca4f6c183..1a50224e1 100644
--- a/src/theory/shared_terms_database.h
+++ b/src/theory/shared_terms_database.h
@@ -21,6 +21,7 @@
#include "context/cdhashset.h"
#include "expr/node.h"
+#include "theory/ee_setup_info.h"
#include "theory/theory_id.h"
#include "theory/uf/equality_engine.h"
#include "util/statistics_registry.h"
@@ -158,6 +159,16 @@ public:
SharedTermsDatabase(TheoryEngine* theoryEngine, context::Context* context);
~SharedTermsDatabase();
+ //-------------------------------------------- initialization
+ /** Called to set the equality engine. */
+ void setEqualityEngine(theory::eq::EqualityEngine* ee);
+ /**
+ * Returns true if we need an equality engine, this has the same contract
+ * as Theory::needsEqualityEngine.
+ */
+ bool needsEqualityEngine(theory::EeSetupInfo& esi);
+ //-------------------------------------------- end initialization
+
/**
* Asserts the equality to the shared terms database,
*/
diff --git a/src/theory/theory_engine.h b/src/theory/theory_engine.h
index a6258b7d6..fda32206b 100644
--- a/src/theory/theory_engine.h
+++ b/src/theory/theory_engine.h
@@ -87,6 +87,7 @@ struct NodeTheoryPairHashFunction {
namespace theory {
class TheoryModel;
class CombinationEngine;
+class SharedSolver;
class DecisionManager;
class RelevanceManager;
@@ -113,6 +114,7 @@ class TheoryEngine {
friend class theory::CombinationEngine;
friend class theory::EngineOutputChannel;
friend class theory::CombinationEngine;
+ friend class theory::SharedSolver;
/** Associated PropEngine engine */
prop::PropEngine* d_propEngine;
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback