From: Andrew Reynolds Date: Wed, 4 May 2022 16:46:55 +0000 (-0500) Subject: Add declareOracleFun interface to SolverEngine (#8622) X-Git-Tag: cvc5-1.0.1~173 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=4ca5ef61d3ab4a9bdd60936e5d20ca371a87d011;p=cvc5.git Add declareOracleFun interface to SolverEngine (#8622) After this PR, declare-oracle-fun will be added to the API and parser. --- diff --git a/src/smt/solver_engine.cpp b/src/smt/solver_engine.cpp index 44014d174..2e11da69e 100644 --- a/src/smt/solver_engine.cpp +++ b/src/smt/solver_engine.cpp @@ -58,6 +58,7 @@ #include "smt/sygus_solver.h" #include "smt/unsat_core_manager.h" #include "theory/quantifiers/instantiation_list.h" +#include "theory/quantifiers/oracle_engine.h" #include "theory/quantifiers/quantifiers_attributes.h" #include "theory/quantifiers_engine.h" #include "theory/rewriter.h" @@ -943,6 +944,53 @@ void SolverEngine::declarePool(const Node& p, qe->declarePool(p, initValue); } +void SolverEngine::declareOracleFun( + Node var, std::function(const std::vector&)> fn) +{ + finishInit(); + d_state->doPendingPops(); + QuantifiersEngine* qe = getAvailableQuantifiersEngine("declareOracleFun"); + qe->declareOracleFun(var); + NodeManager* nm = NodeManager::currentNM(); + std::vector inputs; + std::vector outputs; + TypeNode tn = var.getType(); + Node app; + if (tn.isFunction()) + { + const std::vector& argTypes = tn.getArgTypes(); + for (const TypeNode& t : argTypes) + { + inputs.push_back(nm->mkBoundVar(t)); + } + outputs.push_back(nm->mkBoundVar(tn.getRangeType())); + std::vector appc; + appc.push_back(var); + appc.insert(appc.end(), inputs.begin(), inputs.end()); + app = nm->mkNode(kind::APPLY_UF, appc); + } + else + { + outputs.push_back(nm->mkBoundVar(tn.getRangeType())); + app = var; + } + // makes equality assumption + Node assume = nm->mkNode(kind::EQUAL, app, outputs[0]); + // no constraints + Node constraint = nm->mkConst(true); + // make the oracle constant which carries the method implementation + Oracle oracle(fn); + Node o = NodeManager::currentNM()->mkOracle(oracle); + // set the attribute, which ensures we remember the method implementation for + // the oracle function + var.setAttribute(theory::OracleInterfaceAttribute(), o); + // define the oracle interface + Node q = quantifiers::OracleEngine::mkOracleInterface( + inputs, outputs, assume, constraint, o); + // assert it + assertFormula(q); +} + Node SolverEngine::simplify(const Node& ex) { SolverEngineScope smts(this); diff --git a/src/smt/solver_engine.h b/src/smt/solver_engine.h index 156dbc5cc..8b19e664e 100644 --- a/src/smt/solver_engine.h +++ b/src/smt/solver_engine.h @@ -326,6 +326,7 @@ class CVC5_EXPORT SolverEngine const std::vector& formals, Node formula, bool global = false); + /** * Add a formula to the current context: preprocess, do per-theory * setup, use processAssertionList(), asserting to T-solver for @@ -460,6 +461,16 @@ class CVC5_EXPORT SolverEngine * of type T. */ void declarePool(const Node& p, const std::vector& initValue); + + /** + * Add an oracle function to the state, also adds an oracle interface + * defining it. + * + * @param var The oracle function symbol + * @param fn The method for the oracle + */ + void declareOracleFun( + Node var, std::function(const std::vector&)> fn); /** * Simplify a formula without doing "much" work. Does not involve * the SAT Engine in the simplification, but uses the current @@ -1015,7 +1026,6 @@ class CVC5_EXPORT SolverEngine void debugCheckFunctionBody(Node formula, const std::vector& formals, Node func); - /** * 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 @@ -1047,7 +1057,6 @@ class CVC5_EXPORT SolverEngine /** Vector version of above. */ void ensureWellFormedTerms(const std::vector& ns, const std::string& src) const; - /* Members -------------------------------------------------------------- */ /** Solver instance that owns this SolverEngine instance. */