summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/smt/abduction_solver.cpp202
-rw-r--r--src/smt/abduction_solver.h120
-rw-r--r--src/smt/command.cpp18
-rw-r--r--src/smt/smt_engine.cpp198
-rw-r--r--src/smt/smt_engine.h100
-rw-r--r--src/theory/datatypes/sygus_datatype_utils.cpp3
7 files changed, 391 insertions, 252 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 199c14330..28d943ced 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -219,6 +219,8 @@ libcvc4_add_sources(
prop/sat_solver_types.h
prop/theory_proxy.cpp
prop/theory_proxy.h
+ smt/abduction_solver.cpp
+ smt/abduction_solver.h
smt/command.cpp
smt/command.h
smt/command_list.cpp
diff --git a/src/smt/abduction_solver.cpp b/src/smt/abduction_solver.cpp
new file mode 100644
index 000000000..adb80b719
--- /dev/null
+++ b/src/smt/abduction_solver.cpp
@@ -0,0 +1,202 @@
+/********************* */
+/*! \file abduction_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 solver for abduction queries
+ **/
+
+#include "smt/abduction_solver.h"
+
+#include "options/smt_options.h"
+#include "smt/smt_engine.h"
+#include "theory/quantifiers/quantifiers_attributes.h"
+#include "theory/quantifiers/sygus/sygus_abduct.h"
+#include "theory/quantifiers/sygus/sygus_grammar_cons.h"
+#include "theory/smt_engine_subsolver.h"
+
+using namespace CVC4::theory;
+
+namespace CVC4 {
+namespace smt {
+
+AbductionSolver::AbductionSolver(SmtEngine* parent) : d_parent(parent) {}
+
+AbductionSolver::~AbductionSolver() {}
+bool AbductionSolver::getAbduct(const Node& goal,
+ const TypeNode& grammarType,
+ Node& abd)
+{
+ if (!options::produceAbducts())
+ {
+ const char* msg = "Cannot get abduct when produce-abducts options is off.";
+ throw ModalException(msg);
+ }
+ Trace("sygus-abduct") << "SmtEngine::getAbduct: goal " << goal << std::endl;
+ std::vector<Expr> easserts = d_parent->getExpandedAssertions();
+ std::vector<Node> axioms;
+ for (unsigned i = 0, size = easserts.size(); i < size; i++)
+ {
+ axioms.push_back(Node::fromExpr(easserts[i]));
+ }
+ std::vector<Node> asserts(axioms.begin(), axioms.end());
+ // must expand definitions
+ Node conjn = d_parent->expandDefinitions(goal);
+ // now negate
+ conjn = conjn.negate();
+ d_abdConj = conjn;
+ asserts.push_back(conjn);
+ std::string name("A");
+ Node aconj = quantifiers::SygusAbduct::mkAbductionConjecture(
+ name, asserts, axioms, grammarType);
+ // should be a quantified conjecture with one function-to-synthesize
+ Assert(aconj.getKind() == kind::FORALL && aconj[0].getNumChildren() == 1);
+ // remember the abduct-to-synthesize
+ d_sssf = aconj[0][0];
+ Trace("sygus-abduct") << "SmtEngine::getAbduct: made conjecture : " << aconj
+ << ", solving for " << d_sssf << std::endl;
+ // we generate a new smt engine to do the abduction query
+ initializeSubsolver(d_subsolver);
+ // get the logic
+ LogicInfo l = d_subsolver->getLogicInfo().getUnlockedCopy();
+ // enable everything needed for sygus
+ l.enableSygus();
+ d_subsolver->setLogic(l);
+ // assert the abduction query
+ d_subsolver->assertFormula(aconj.toExpr());
+ return getAbductInternal(abd);
+}
+
+bool AbductionSolver::getAbduct(const Node& goal, Node& abd)
+{
+ TypeNode grammarType;
+ return getAbduct(goal, grammarType, abd);
+}
+
+bool AbductionSolver::getAbductInternal(Node& abd)
+{
+ // should have initialized the subsolver by now
+ Assert(d_subsolver != nullptr);
+ Trace("sygus-abduct") << " SmtEngine::getAbduct check sat..." << std::endl;
+ Result r = d_subsolver->checkSat();
+ Trace("sygus-abduct") << " SmtEngine::getAbduct result: " << r << std::endl;
+ if (r.asSatisfiabilityResult().isSat() == Result::UNSAT)
+ {
+ // get the synthesis solution
+ std::map<Expr, Expr> sols;
+ d_subsolver->getSynthSolutions(sols);
+ Assert(sols.size() == 1);
+ Expr essf = d_sssf.toExpr();
+ std::map<Expr, Expr>::iterator its = sols.find(essf);
+ if (its != sols.end())
+ {
+ Trace("sygus-abduct")
+ << "SmtEngine::getAbduct: solution is " << its->second << std::endl;
+ abd = Node::fromExpr(its->second);
+ if (abd.getKind() == kind::LAMBDA)
+ {
+ abd = abd[1];
+ }
+ // get the grammar type for the abduct
+ Node agdtbv = d_sssf.getAttribute(SygusSynthFunVarListAttribute());
+ Assert(!agdtbv.isNull());
+ Assert(agdtbv.getKind() == kind::BOUND_VAR_LIST);
+ // convert back to original
+ // must replace formal arguments of abd with the free variables in the
+ // input problem that they correspond to.
+ std::vector<Node> vars;
+ std::vector<Node> syms;
+ SygusVarToTermAttribute sta;
+ for (const Node& bv : agdtbv)
+ {
+ vars.push_back(bv);
+ syms.push_back(bv.hasAttribute(sta) ? bv.getAttribute(sta) : bv);
+ }
+ abd = abd.substitute(vars.begin(), vars.end(), syms.begin(), syms.end());
+
+ // if check abducts option is set, we check the correctness
+ if (options::checkAbducts())
+ {
+ checkAbduct(abd);
+ }
+ return true;
+ }
+ Trace("sygus-abduct") << "SmtEngine::getAbduct: could not find solution!"
+ << std::endl;
+ throw RecoverableModalException("Could not find solution for get-abduct.");
+ }
+ return false;
+}
+
+void AbductionSolver::checkAbduct(Node a)
+{
+ Assert(a.getType().isBoolean());
+ Trace("check-abduct") << "SmtEngine::checkAbduct: get expanded assertions"
+ << std::endl;
+
+ std::vector<Expr> asserts = d_parent->getExpandedAssertions();
+ asserts.push_back(a.toExpr());
+
+ // two checks: first, consistent with assertions, second, implies negated goal
+ // is unsatisfiable.
+ for (unsigned j = 0; j < 2; j++)
+ {
+ Trace("check-abduct") << "SmtEngine::checkAbduct: phase " << j
+ << ": make new SMT engine" << std::endl;
+ // Start new SMT engine to check solution
+ std::unique_ptr<SmtEngine> abdChecker;
+ initializeSubsolver(abdChecker);
+ Trace("check-abduct") << "SmtEngine::checkAbduct: phase " << j
+ << ": asserting formulas" << std::endl;
+ for (const Expr& e : asserts)
+ {
+ abdChecker->assertFormula(e);
+ }
+ Trace("check-abduct") << "SmtEngine::checkAbduct: phase " << j
+ << ": check the assertions" << std::endl;
+ Result r = abdChecker->checkSat();
+ Trace("check-abduct") << "SmtEngine::checkAbduct: phase " << j
+ << ": result is " << r << std::endl;
+ std::stringstream serr;
+ bool isError = false;
+ if (j == 0)
+ {
+ if (r.asSatisfiabilityResult().isSat() != Result::SAT)
+ {
+ isError = true;
+ serr << "SmtEngine::checkAbduct(): produced solution cannot be shown "
+ "to be consisconsistenttent with assertions, result was "
+ << r;
+ }
+ Trace("check-abduct")
+ << "SmtEngine::checkAbduct: goal is " << d_abdConj << std::endl;
+ // add the goal to the set of assertions
+ Assert(!d_abdConj.isNull());
+ asserts.push_back(d_abdConj.toExpr());
+ }
+ else
+ {
+ if (r.asSatisfiabilityResult().isSat() != Result::UNSAT)
+ {
+ isError = true;
+ serr << "SmtEngine::checkAbduct(): negated goal cannot be shown "
+ "unsatisfiable with produced solution, result was "
+ << r;
+ }
+ }
+ // did we get an unexpected result?
+ if (isError)
+ {
+ InternalError() << serr.str();
+ }
+ }
+}
+
+} // namespace smt
+} // namespace CVC4
diff --git a/src/smt/abduction_solver.h b/src/smt/abduction_solver.h
new file mode 100644
index 000000000..2041b961d
--- /dev/null
+++ b/src/smt/abduction_solver.h
@@ -0,0 +1,120 @@
+/********************* */
+/*! \file abduction_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 The solver for abduction queries
+ **/
+
+#include "cvc4_private.h"
+
+#ifndef CVC4__SMT__ABDUCTION_SOLVER_H
+#define CVC4__SMT__ABDUCTION_SOLVER_H
+
+#include "expr/node.h"
+#include "expr/type_node.h"
+
+namespace CVC4 {
+
+class SmtEngine;
+
+namespace smt {
+
+/**
+ * A solver for abduction queries.
+ *
+ * This class is responsible for responding to get-abduct commands. It spawns
+ * a subsolver SmtEngine for a sygus conjecture that captures the abduction
+ * query, and implements supporting utility methods such as checkAbduct.
+ */
+class AbductionSolver
+{
+ public:
+ AbductionSolver(SmtEngine* parent);
+ ~AbductionSolver();
+ /**
+ * This method asks this SMT engine to find an abduct with respect to the
+ * current assertion stack (call it A) and the goal (call it B).
+ * If this method returns true, then abd is set to a formula C such that
+ * A ^ C is satisfiable, and A ^ ~B ^ C is unsatisfiable.
+ *
+ * @param goal The goal of the abduction problem.
+ * @param grammarType A sygus datatype type that encodes the syntax
+ * restrictions on the shape of possible solutions.
+ * @param abd This argument is updated to contain the solution to the
+ * abduction problem. Notice that this is a formula whose free symbols
+ * are contained in goal + the parent's current assertion stack.
+ *
+ * This method invokes a separate copy of the SMT engine for solving the
+ * corresponding sygus problem for generating such a solution.
+ */
+ bool getAbduct(const Node& goal, const TypeNode& grammarType, Node& abd);
+
+ /**
+ * Same as above, but without user-provided grammar restrictions. A default
+ * grammar is chosen internally using the sygus grammar constructor utility.
+ */
+ bool getAbduct(const Node& goal, Node& abd);
+
+ /**
+ * Check that a solution to an abduction conjecture is indeed a solution.
+ *
+ * The check is made by determining that the assertions conjoined with the
+ * solution to the abduction problem (a) is SAT, and the assertions conjoined
+ * with the abduct and the goal is UNSAT. If these criteria are not met, an
+ * internal error is thrown.
+ */
+ void checkAbduct(Node a);
+
+ private:
+ /**
+ * Get abduct internal.
+ *
+ * Get the next abduct from the internal subsolver d_subsolver. If
+ * successful, this method returns true and sets abd to that abduct.
+ *
+ * This method assumes d_subsolver has been initialized to do abduction
+ * problems.
+ */
+ bool getAbductInternal(Node& abd);
+ /** The parent SMT engine */
+ SmtEngine* d_parent;
+ /** The SMT engine subsolver
+ *
+ * This is a separate copy of the SMT engine which is used for making
+ * calls that cannot be answered by this copy of the SMT engine. An example
+ * of invoking this subsolver is the get-abduct command, where we wish to
+ * solve a sygus conjecture based on the current assertions. In particular,
+ * consider the input:
+ * (assert A)
+ * (get-abduct B)
+ * In the copy of the SMT engine where these commands are issued, we maintain
+ * A in the assertion stack. To solve the abduction problem, instead of
+ * modifying the assertion stack to remove A and add the sygus conjecture
+ * (exists I. ...), we invoke a fresh copy of the SMT engine and leave the
+ * assertion stack unchaged. This copy of the SMT engine can be further
+ * queried for information regarding further solutions.
+ */
+ std::unique_ptr<SmtEngine> d_subsolver;
+ /**
+ * The conjecture of the current abduction problem. This expression is only
+ * valid while the parent SmtEngine is in mode SMT_MODE_ABDUCT.
+ */
+ Node d_abdConj;
+ /**
+ * If applicable, the function-to-synthesize that the subsolver is solving
+ * for. This is used for the get-abduct command.
+ */
+ Node d_sssf;
+};
+
+} // namespace smt
+} // namespace CVC4
+
+#endif /* CVC4__SMT__ABDUCTION_SOLVER_H */
diff --git a/src/smt/command.cpp b/src/smt/command.cpp
index e60f223b4..2e36190b4 100644
--- a/src/smt/command.cpp
+++ b/src/smt/command.cpp
@@ -1555,7 +1555,8 @@ ExpandDefinitionsCommand::ExpandDefinitionsCommand(Expr term) : d_term(term) {}
Expr ExpandDefinitionsCommand::getTerm() const { return d_term; }
void ExpandDefinitionsCommand::invoke(SmtEngine* smtEngine)
{
- d_result = smtEngine->expandDefinitions(d_term);
+ Node t = Node::fromExpr(d_term);
+ d_result = smtEngine->expandDefinitions(t).toExpr();
d_commandStatus = CommandSuccess::instance();
}
@@ -1623,9 +1624,11 @@ void GetValueCommand::invoke(SmtEngine* smtEngine)
for (int i = 0, size = d_terms.size(); i < size; i++)
{
Expr e = d_terms[i];
+ Node eNode = Node::fromExpr(e);
Assert(nm == NodeManager::fromExprManager(e.getExprManager()));
- Node request = Node::fromExpr(
- options::expandDefinitions() ? smtEngine->expandDefinitions(e) : e);
+ Node request = options::expandDefinitions()
+ ? smtEngine->expandDefinitions(eNode)
+ : eNode;
Node value = Node::fromExpr(result[i]);
if (value.getType().isInteger() && request.getType() == nm->realType())
{
@@ -2199,15 +2202,18 @@ void GetAbductCommand::invoke(SmtEngine* smtEngine)
{
try
{
+ Node conjNode = Node::fromExpr(d_conj);
+ Node resn;
if (d_sygus_grammar_type.isNull())
{
- d_resultStatus = smtEngine->getAbduct(d_conj, d_result);
+ d_resultStatus = smtEngine->getAbduct(conjNode, resn);
}
else
{
- d_resultStatus =
- smtEngine->getAbduct(d_conj, d_sygus_grammar_type, d_result);
+ TypeNode gtype = TypeNode::fromType(d_sygus_grammar_type);
+ d_resultStatus = smtEngine->getAbduct(conjNode, gtype, resn);
}
+ d_result = resn.toExpr();
d_commandStatus = CommandSuccess::instance();
}
catch (exception& e)
diff --git a/src/smt/smt_engine.cpp b/src/smt/smt_engine.cpp
index 12e0f443e..380878e41 100644
--- a/src/smt/smt_engine.cpp
+++ b/src/smt/smt_engine.cpp
@@ -81,6 +81,7 @@
#include "proof/theory_proof.h"
#include "proof/unsat_core.h"
#include "prop/prop_engine.h"
+#include "smt/abduction_solver.h"
#include "smt/command.h"
#include "smt/command_list.h"
#include "smt/defined_function.h"
@@ -101,7 +102,6 @@
#include "theory/logic_info.h"
#include "theory/quantifiers/fun_def_process.h"
#include "theory/quantifiers/single_inv_partition.h"
-#include "theory/quantifiers/sygus/sygus_abduct.h"
#include "theory/quantifiers/sygus/synth_engine.h"
#include "theory/quantifiers/term_util.h"
#include "theory/quantifiers_engine.h"
@@ -642,6 +642,7 @@ SmtEngine::SmtEngine(ExprManager* em, Options* optr)
d_proofManager(nullptr),
d_rewriter(new theory::Rewriter()),
d_definedFunctions(nullptr),
+ d_abductSolver(nullptr),
d_assertionList(nullptr),
d_assignments(nullptr),
d_modelGlobalCommands(),
@@ -817,6 +818,12 @@ void SmtEngine::finishInit()
}
d_dumpCommands.clear();
+ // subsolvers
+ if (options::produceAbducts())
+ {
+ d_abductSolver.reset(new AbductionSolver(this));
+ }
+
PROOF( ProofManager::currentPM()->setLogic(d_logic); );
PROOF({
for(TheoryId id = theory::THEORY_FIRST; id < theory::THEORY_LAST; ++id) {
@@ -2161,18 +2168,17 @@ Expr SmtEngine::simplify(const Expr& ex)
return n.toExpr();
}
-Expr SmtEngine::expandDefinitions(const Expr& ex)
+Node SmtEngine::expandDefinitions(const Node& ex)
{
d_private->spendResource(ResourceManager::Resource::PreprocessStep);
- Assert(ex.getExprManager() == d_exprManager);
SmtScope smts(this);
finalOptionsAreSet();
doPendingPops();
Trace("smt") << "SMT expandDefinitions(" << ex << ")" << endl;
// Substitute out any abstract values in ex.
- Expr e = d_private->substituteAbstractValues(Node::fromExpr(ex)).toExpr();
+ Node e = d_private->substituteAbstractValues(ex);
if(options::typeChecking()) {
// Ensure expr is type-checked at this point.
e.getType(true);
@@ -2180,10 +2186,10 @@ Expr SmtEngine::expandDefinitions(const Expr& ex)
unordered_map<Node, Node, NodeHashFunction> cache;
Node n = d_private->getProcessAssertions()->expandDefinitions(
- Node::fromExpr(e), cache, /* expandOnly = */ true);
- n = postprocess(n, TypeNode::fromType(e.getType()));
+ e, cache, /* expandOnly = */ true);
+ n = postprocess(n, e.getType());
- return n.toExpr();
+ return n;
}
// TODO(#1108): Simplify the error reporting of this method.
@@ -2985,69 +2991,11 @@ void SmtEngine::checkInterpol(Expr interpol,
{
}
-void SmtEngine::checkAbduct(Expr a)
+void SmtEngine::checkAbduct(Node a)
{
Assert(a.getType().isBoolean());
- Trace("check-abduct") << "SmtEngine::checkAbduct: get expanded assertions"
- << std::endl;
-
- std::vector<Expr> asserts = getExpandedAssertions();
- asserts.push_back(a);
-
- // two checks: first, consistent with assertions, second, implies negated goal
- // is unsatisfiable.
- for (unsigned j = 0; j < 2; j++)
- {
- Trace("check-abduct") << "SmtEngine::checkAbduct: phase " << j
- << ": make new SMT engine" << std::endl;
- // Start new SMT engine to check solution
- SmtEngine abdChecker(d_exprManager, &d_options);
- abdChecker.setIsInternalSubsolver();
- abdChecker.setLogic(getLogicInfo());
- Trace("check-abduct") << "SmtEngine::checkAbduct: phase " << j
- << ": asserting formulas" << std::endl;
- for (const Expr& e : asserts)
- {
- abdChecker.assertFormula(e);
- }
- Trace("check-abduct") << "SmtEngine::checkAbduct: phase " << j
- << ": check the assertions" << std::endl;
- Result r = abdChecker.checkSat();
- Trace("check-abduct") << "SmtEngine::checkAbduct: phase " << j
- << ": result is " << r << endl;
- std::stringstream serr;
- bool isError = false;
- if (j == 0)
- {
- if (r.asSatisfiabilityResult().isSat() != Result::SAT)
- {
- isError = true;
- serr << "SmtEngine::checkAbduct(): produced solution cannot be shown "
- "to be consisconsistenttent with assertions, result was "
- << r;
- }
- Trace("check-abduct")
- << "SmtEngine::checkAbduct: goal is " << d_abdConj << std::endl;
- // add the goal to the set of assertions
- Assert(!d_abdConj.isNull());
- asserts.push_back(d_abdConj);
- }
- else
- {
- if (r.asSatisfiabilityResult().isSat() != Result::UNSAT)
- {
- isError = true;
- serr << "SmtEngine::checkAbduct(): negated goal cannot be shown "
- "unsatisfiable with produced solution, result was "
- << r;
- }
- }
- // did we get an unexpected result?
- if (isError)
- {
- InternalError() << serr.str();
- }
- }
+ // check it with the abduction solver
+ return d_abductSolver->checkAbduct(a);
}
// TODO(#1108): Simplify the error reporting of this method.
@@ -3217,54 +3165,11 @@ bool SmtEngine::getInterpol(const Expr& conj, Expr& interpol)
return getInterpol(conj, grammarType, interpol);
}
-bool SmtEngine::getAbduct(const Expr& conj, const Type& grammarType, Expr& abd)
+bool SmtEngine::getAbduct(const Node& conj,
+ const TypeNode& grammarType,
+ Node& abd)
{
- SmtScope smts(this);
-
- if (!options::produceAbducts())
- {
- const char* msg = "Cannot get abduct when produce-abducts options is off.";
- throw ModalException(msg);
- }
- Trace("sygus-abduct") << "SmtEngine::getAbduct: conjecture " << conj
- << std::endl;
- std::vector<Expr> easserts = getExpandedAssertions();
- std::vector<Node> axioms;
- for (unsigned i = 0, size = easserts.size(); i < size; i++)
- {
- axioms.push_back(Node::fromExpr(easserts[i]));
- }
- std::vector<Node> asserts(axioms.begin(), axioms.end());
- // negate the conjecture
- Node conjn = Node::fromExpr(conj);
- // must expand definitions
- std::unordered_map<Node, Node, NodeHashFunction> cache;
- conjn = d_private->getProcessAssertions()->expandDefinitions(conjn, cache);
- // now negate
- conjn = conjn.negate();
- d_abdConj = conjn.toExpr();
- asserts.push_back(conjn);
- std::string name("A");
- Node aconj = theory::quantifiers::SygusAbduct::mkAbductionConjecture(
- name, asserts, axioms, TypeNode::fromType(grammarType));
- // should be a quantified conjecture with one function-to-synthesize
- Assert(aconj.getKind() == kind::FORALL && aconj[0].getNumChildren() == 1);
- // remember the abduct-to-synthesize
- d_sssf = aconj[0][0].toExpr();
- Trace("sygus-abduct") << "SmtEngine::getAbduct: made conjecture : " << aconj
- << ", solving for " << d_sssf << std::endl;
- // we generate a new smt engine to do the abduction query
- d_subsolver.reset(
- new SmtEngine(NodeManager::currentNM()->toExprManager(), &d_options));
- d_subsolver->setIsInternalSubsolver();
- // get the logic
- LogicInfo l = d_logic.getUnlockedCopy();
- // enable everything needed for sygus
- l.enableSygus();
- d_subsolver->setLogic(l);
- // assert the abduction query
- d_subsolver->assertFormula(aconj.toExpr());
- if (getAbductInternal(abd))
+ if (d_abductSolver->getAbduct(conj, grammarType, abd))
{
// successfully generated an abduct, update to abduct state
d_smtMode = SMT_MODE_ABDUCT;
@@ -3275,68 +3180,9 @@ bool SmtEngine::getAbduct(const Expr& conj, const Type& grammarType, Expr& abd)
return false;
}
-bool SmtEngine::getAbductInternal(Expr& abd)
+bool SmtEngine::getAbduct(const Node& conj, Node& abd)
{
- // should have initialized the subsolver by now
- Assert(d_subsolver != nullptr);
- Trace("sygus-abduct") << " SmtEngine::getAbduct check sat..." << std::endl;
- Result r = d_subsolver->checkSat();
- Trace("sygus-abduct") << " SmtEngine::getAbduct result: " << r << std::endl;
- if (r.asSatisfiabilityResult().isSat() == Result::UNSAT)
- {
- // get the synthesis solution
- std::map<Expr, Expr> sols;
- d_subsolver->getSynthSolutions(sols);
- Assert(sols.size() == 1);
- std::map<Expr, Expr>::iterator its = sols.find(d_sssf);
- if (its != sols.end())
- {
- Trace("sygus-abduct")
- << "SmtEngine::getAbduct: solution is " << its->second << std::endl;
- Node abdn = Node::fromExpr(its->second);
- if (abdn.getKind() == kind::LAMBDA)
- {
- abdn = abdn[1];
- }
- // get the grammar type for the abduct
- Node af = Node::fromExpr(d_sssf);
- Node agdtbv = af.getAttribute(theory::SygusSynthFunVarListAttribute());
- Assert(!agdtbv.isNull());
- Assert(agdtbv.getKind() == kind::BOUND_VAR_LIST);
- // convert back to original
- // must replace formal arguments of abd with the free variables in the
- // input problem that they correspond to.
- std::vector<Node> vars;
- std::vector<Node> syms;
- SygusVarToTermAttribute sta;
- for (const Node& bv : agdtbv)
- {
- vars.push_back(bv);
- syms.push_back(bv.hasAttribute(sta) ? bv.getAttribute(sta) : bv);
- }
- abdn =
- abdn.substitute(vars.begin(), vars.end(), syms.begin(), syms.end());
-
- // convert to expression
- abd = abdn.toExpr();
-
- // if check abducts option is set, we check the correctness
- if (options::checkAbducts())
- {
- checkAbduct(abd);
- }
- return true;
- }
- Trace("sygus-abduct") << "SmtEngine::getAbduct: could not find solution!"
- << std::endl;
- throw RecoverableModalException("Could not find solution for get-abduct.");
- }
- return false;
-}
-
-bool SmtEngine::getAbduct(const Expr& conj, Expr& abd)
-{
- Type grammarType;
+ TypeNode grammarType;
return getAbduct(conj, grammarType, abd);
}
diff --git a/src/smt/smt_engine.h b/src/smt/smt_engine.h
index 8db8eadd5..f6b1d08bf 100644
--- a/src/smt/smt_engine.h
+++ b/src/smt/smt_engine.h
@@ -91,23 +91,25 @@ namespace prop {
/* -------------------------------------------------------------------------- */
namespace smt {
- /**
- * Representation of a defined function. We keep these around in
- * SmtEngine to permit expanding definitions late (and lazily), to
- * support getValue() over defined functions, to support user output
- * in terms of defined functions, etc.
- */
- class DefinedFunction;
-
- struct SmtEngineStatistics;
- class SmtEnginePrivate;
- class SmtScope;
- class ProcessAssertions;
-
- ProofManager* currentProofManager();
-
- struct CommandCleanup;
- typedef context::CDList<Command*, CommandCleanup> CommandList;
+/** Subsolvers */
+class AbductionSolver;
+/**
+ * Representation of a defined function. We keep these around in
+ * SmtEngine to permit expanding definitions late (and lazily), to
+ * support getValue() over defined functions, to support user output
+ * in terms of defined functions, etc.
+ */
+class DefinedFunction;
+
+struct SmtEngineStatistics;
+class SmtEnginePrivate;
+class SmtScope;
+class ProcessAssertions;
+
+ProofManager* currentProofManager();
+
+struct CommandCleanup;
+typedef context::CDList<Command*, CommandCleanup> CommandList;
}/* CVC4::smt namespace */
/* -------------------------------------------------------------------------- */
@@ -508,7 +510,7 @@ class CVC4_PUBLIC SmtEngine
*
* @throw TypeCheckingException, LogicException, UnsafeInterruptException
*/
- Expr expandDefinitions(const Expr& e);
+ Node expandDefinitions(const Node& e);
/**
* Get the assigned value of an expr (only if immediately preceded by a SAT
@@ -660,10 +662,10 @@ class CVC4_PUBLIC SmtEngine
* This method invokes a separate copy of the SMT engine for solving the
* corresponding sygus problem for generating such a solution.
*/
- bool getAbduct(const Expr& conj, const Type& grammarType, Expr& abd);
+ bool getAbduct(const Node& conj, const TypeNode& grammarType, Node& abd);
/** Same as above, but without user-provided grammar restrictions */
- bool getAbduct(const Expr& conj, Expr& abd);
+ bool getAbduct(const Node& conj, Node& abd);
/**
* Get list of quantified formulas that were instantiated on the last call
@@ -898,6 +900,13 @@ class CVC4_PUBLIC SmtEngine
/** Get the resource manager of this SMT engine */
ResourceManager* getResourceManager();
+
+ /**
+ * Get expanded assertions.
+ *
+ * Return the set of assertions, after expanding definitions.
+ */
+ std::vector<Expr> getExpandedAssertions();
/* ....................................................................... */
private:
/* ....................................................................... */
@@ -994,7 +1003,7 @@ class CVC4_PUBLIC SmtEngine
* with the abduct and the goal is UNSAT. If these criteria are not met, an
* internal error is thrown.
*/
- void checkAbduct(Expr a);
+ void checkAbduct(Node a);
/**
* Postprocess a value for output to the user. Involves doing things
@@ -1111,30 +1120,12 @@ class CVC4_PUBLIC SmtEngine
Expr func);
/**
- * Get abduct internal.
- *
- * Get the next abduct from the internal subsolver d_subsolver. If
- * successful, this method returns true and sets abd to that abduct.
- *
- * This method assumes d_subsolver has been initialized to do abduction
- * problems.
- */
- bool getAbductInternal(Expr& abd);
-
- /**
* Helper method to obtain both the heap and nil from the solver. Returns a
* std::pair where the first element is the heap expression and the second
* element is the nil expression.
*/
std::pair<Expr, Expr> getSepHeapAndNilExpr();
- /**
- * Get expanded assertions.
- *
- * Return the set of assertions, after expanding definitions.
- */
- std::vector<Expr> getExpandedAssertions();
-
/* Members -------------------------------------------------------------- */
/** Solver instance that owns this SmtEngine instance. */
@@ -1171,35 +1162,8 @@ class CVC4_PUBLIC SmtEngine
/** An index of our defined functions */
DefinedFunctionMap* d_definedFunctions;
- /** The SMT engine subsolver
- *
- * This is a separate copy of the SMT engine which is used for making
- * calls that cannot be answered by this copy of the SMT engine. An example
- * of invoking this subsolver is the get-abduct command, where we wish to
- * solve a sygus conjecture based on the current assertions. In particular,
- * consider the input:
- * (assert A)
- * (get-abduct B)
- * In the copy of the SMT engine where these commands are issued, we maintain
- * A in the assertion stack. To solve the abduction problem, instead of
- * modifying the assertion stack to remove A and add the sygus conjecture
- * (exists I. ...), we invoke a fresh copy of the SMT engine and leave the
- * assertion stack unchaged. This copy of the SMT engine can be further
- * queried for information regarding further solutions.
- */
- std::unique_ptr<SmtEngine> d_subsolver;
-
- /**
- * If applicable, the function-to-synthesize that the subsolver is solving
- * for. This is used for the get-abduct command.
- */
- Expr d_sssf;
-
- /**
- * The conjecture of the current abduction problem. This expression is only
- * valid while we are in mode SMT_MODE_ABDUCT.
- */
- Expr d_abdConj;
+ /** The solver for abduction queries */
+ std::unique_ptr<smt::AbductionSolver> d_abductSolver;
/**
* The assertion list (before any conversion) for supporting
diff --git a/src/theory/datatypes/sygus_datatype_utils.cpp b/src/theory/datatypes/sygus_datatype_utils.cpp
index e95b66bd7..8ff0f8db2 100644
--- a/src/theory/datatypes/sygus_datatype_utils.cpp
+++ b/src/theory/datatypes/sygus_datatype_utils.cpp
@@ -232,8 +232,7 @@ Node mkSygusTerm(const DType& dt,
// ensures we don't try to expand e.g. bitvector extract operators,
// whose type is undefined, and thus should not be passed to
// expandDefinitions.
- opn = Node::fromExpr(
- smt::currentSmtEngine()->expandDefinitions(op.toExpr()));
+ opn = smt::currentSmtEngine()->expandDefinitions(op);
opn = Rewriter::rewrite(opn);
opn = eliminatePartialOperators(opn);
SygusOpRewrittenAttribute sora;
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback