summaryrefslogtreecommitdiff
path: root/src/smt/smt_engine.cpp
diff options
context:
space:
mode:
authorAndrew Reynolds <andrew.j.reynolds@gmail.com>2021-04-30 14:12:56 -0500
committerGitHub <noreply@github.com>2021-04-30 19:12:56 +0000
commit327a24508ed1d02a3fa233e680ffd0b30aa685a9 (patch)
treed130a4b5afcf34383b6bdf38c433d77c5911709d /src/smt/smt_engine.cpp
parent38a45651953d3bcfe67cb80b4f2ba2d1b278f7ba (diff)
Use substitutions for implementing defined functions (#6437)
This eliminates explicit tracking of defined functions, and instead makes define-fun add to preprocessing substitutions. In other words, the effect of: (define-fun f X t) is to add f -> (lambda X t) to the set of substitutions known by the preprocessor. This is essentially the same as when (= f (lambda X t)) was an equality solved by non-clausal simplification The motivation for this change is both uniformity and for performance, as fewer traversals of the input formula. In this PR: define-fun are now conceptually higher-order equalities provided to smt::Assertions. These assertions are always added as substitutions instead of being pushed to AssertionPipeline. Top-level substitutions are moved from PreprocessingContext to Env, since they must be accessed by Assertions. Proofs for this class are enabled dynamically during SmtEngine::finishInit. The expandDefinitions preprocessing step is replaced by apply-substs. The process assertions module no longer needs access to expand definitions. The proof manager does not require a special case of using the define-function maps. Define-function maps are eliminated from SmtEngine. Further work will reorganize the relationship between the expand definitions module and the rewriter, after which global calls to SmtEngine::expandDefinitions can be cleaned up. There is also further work necessary to better integrate theory expand definitions and top-level substitutions, which will be done on a followup PR.
Diffstat (limited to 'src/smt/smt_engine.cpp')
-rw-r--r--src/smt/smt_engine.cpp64
1 files changed, 21 insertions, 43 deletions
diff --git a/src/smt/smt_engine.cpp b/src/smt/smt_engine.cpp
index ef338fdfe..cee07a3dc 100644
--- a/src/smt/smt_engine.cpp
+++ b/src/smt/smt_engine.cpp
@@ -40,7 +40,6 @@
#include "smt/abstract_values.h"
#include "smt/assertions.h"
#include "smt/check_models.h"
-#include "smt/defined_function.h"
#include "smt/dump.h"
#include "smt/dump_manager.h"
#include "smt/env.h"
@@ -88,7 +87,7 @@ SmtEngine::SmtEngine(NodeManager* nm, Options* optr)
: d_env(new Env(nm, optr)),
d_state(new SmtEngineState(getContext(), getUserContext(), *this)),
d_absValues(new AbstractValues(getNodeManager())),
- d_asserts(new Assertions(getUserContext(), *d_absValues.get())),
+ d_asserts(new Assertions(*d_env.get(), *d_absValues.get())),
d_routListener(new ResourceOutListener(*this)),
d_snmListener(new SmtNodeManagerListener(*getDumpManager(), d_outMgr)),
d_smtSolver(nullptr),
@@ -97,7 +96,6 @@ SmtEngine::SmtEngine(NodeManager* nm, Options* optr)
d_checkModels(nullptr),
d_pfManager(nullptr),
d_ucManager(nullptr),
- d_definedFunctions(nullptr),
d_sygusSolver(nullptr),
d_abductSolver(nullptr),
d_interpolSolver(nullptr),
@@ -131,8 +129,8 @@ SmtEngine::SmtEngine(NodeManager* nm, Options* optr)
// make statistics
d_stats.reset(new SmtEngineStatistics());
// reset the preprocessor
- d_pp.reset(new smt::Preprocessor(
- *this, getUserContext(), *d_absValues.get(), *d_stats));
+ d_pp.reset(
+ new smt::Preprocessor(*this, *d_env.get(), *d_absValues.get(), *d_stats));
// make the SMT solver
d_smtSolver.reset(
new SmtSolver(*this, *d_state, getResourceManager(), *d_pp, *d_stats));
@@ -151,8 +149,6 @@ SmtEngine::SmtEngine(NodeManager* nm, Options* optr)
// being parsed from the input file. Because of this, we cannot trust
// that d_env->getOption(options::unsatCores) is set correctly yet.
d_proofManager.reset(new ProofManager(getUserContext()));
-
- d_definedFunctions = new (true) DefinedFunctionMap(getUserContext());
}
bool SmtEngine::isFullyInited() const { return d_state->isFullyInited(); }
@@ -318,8 +314,6 @@ SmtEngine::~SmtEngine()
// of context-dependent data structures
d_state->cleanup();
- d_definedFunctions->deleteSelf();
-
//destroy all passes before destroying things that they refer to
d_pp->cleanup();
@@ -646,36 +640,26 @@ void SmtEngine::defineFunction(Node func,
ss << language::SetLanguage(
language::SetLanguage::getLanguage(Dump.getStream()))
<< func;
- std::vector<Node> nFormals;
- nFormals.reserve(formals.size());
- for (const Node& formal : formals)
- {
- nFormals.push_back(formal);
- }
-
- DefineFunctionNodeCommand nc(ss.str(), func, nFormals, formula);
+ DefineFunctionNodeCommand nc(ss.str(), func, formals, formula);
getDumpManager()->addToDump(nc, "declarations");
// type check body
debugCheckFunctionBody(formula, formals, func);
// Substitute out any abstract values in formula
- Node formNode = d_absValues->substituteAbstractValues(formula);
- DefinedFunction def(func, formals, formNode);
- // Permit (check-sat) (define-fun ...) (get-value ...) sequences.
- // Otherwise, (check-sat) (get-value ((! foo :named bar))) breaks
- // d_haveAdditions = true;
- Debug("smt") << "definedFunctions insert " << func << " " << formNode << endl;
-
- if (global)
- {
- d_definedFunctions->insertAtContextLevelZero(func, def);
- }
- else
+ Node def = d_absValues->substituteAbstractValues(formula);
+ if (!formals.empty())
{
- d_definedFunctions->insert(func, def);
+ NodeManager* nm = NodeManager::currentNM();
+ def = nm->mkNode(
+ kind::LAMBDA, nm->mkNode(kind::BOUND_VAR_LIST, formals), def);
}
+ // A define-fun is treated as a (higher-order) assertion. It is provided
+ // to the assertions object. It will be added as a top-level substitution
+ // within this class, possibly multiple times if global is true.
+ Node feq = func.eqNode(def);
+ d_asserts->addDefineFunDefinition(feq, global);
}
void SmtEngine::defineFunctionsRec(
@@ -748,7 +732,7 @@ void SmtEngine::defineFunctionsRec(
// notice we don't call assertFormula directly, since this would
// duplicate the output on raw-benchmark.
// add define recursive definition to the assertions
- d_asserts->addDefineFunRecDefinition(lem, global);
+ d_asserts->addDefineFunDefinition(lem, global);
}
}
@@ -766,12 +750,6 @@ void SmtEngine::defineFunctionRec(Node func,
defineFunctionsRec(funcs, formals_multi, formulas, global);
}
-bool SmtEngine::isDefinedFunction(Node func)
-{
- Debug("smt") << "isDefined function " << func << "?" << std::endl;
- return d_definedFunctions->find(func) != d_definedFunctions->end();
-}
-
Result SmtEngine::quickCheck() {
Assert(d_state->isFullyInited());
Trace("smt") << "SMT quickCheck()" << endl;
@@ -1295,6 +1273,7 @@ Result SmtEngine::blockModel()
ModelBlocker::getModelBlocker(eassertsProc,
m->getTheoryModel(),
d_env->getOption(options::blockModelsMode));
+ Trace("smt") << "Block formula: " << eblocker << std::endl;
return assertFormula(eblocker);
}
@@ -1402,7 +1381,7 @@ void SmtEngine::checkProof()
std::shared_ptr<ProofNode> pePfn = pe->getProof();
if (d_env->getOption(options::checkProofs))
{
- d_pfManager->checkProof(pePfn, *d_asserts, *d_definedFunctions);
+ d_pfManager->checkProof(pePfn, *d_asserts);
}
}
@@ -1445,8 +1424,7 @@ UnsatCore SmtEngine::getUnsatCoreInternal()
pepf = pe->getProof();
}
Assert(pepf != nullptr);
- std::shared_ptr<ProofNode> pfn =
- d_pfManager->getFinalProof(pepf, *d_asserts, *d_definedFunctions);
+ std::shared_ptr<ProofNode> pfn = d_pfManager->getFinalProof(pepf, *d_asserts);
std::vector<Node> core;
d_ucManager->getUnsatCore(pfn, *d_asserts, core);
return UnsatCore(core);
@@ -1539,8 +1517,8 @@ void SmtEngine::getRelevantInstantiationTermVectors(
PropEngine* pe = getPropEngine();
Assert(pe != nullptr);
Assert(pe->getProof() != nullptr);
- std::shared_ptr<ProofNode> pfn = d_pfManager->getFinalProof(
- pe->getProof(), *d_asserts, *d_definedFunctions);
+ std::shared_ptr<ProofNode> pfn =
+ d_pfManager->getFinalProof(pe->getProof(), *d_asserts);
d_ucManager->getRelevantInstantiations(pfn, insts);
}
@@ -1569,7 +1547,7 @@ std::string SmtEngine::getProof()
Assert(pe->getProof() != nullptr);
Assert(d_pfManager);
std::ostringstream ss;
- d_pfManager->printProof(ss, pe->getProof(), *d_asserts, *d_definedFunctions);
+ d_pfManager->printProof(ss, pe->getProof(), *d_asserts);
return ss.str();
}
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback