This breaks the circular dependency of preprocessing pass context of solver engine.
It also moves the preprocessor to be owned by SMT solver, instead of Solver engine.
It also changes the behavior of reset assertions: now, the preprocessing pass context is reset, whereas previously it was not. I believe this is the right behavior, as it eliminates stale data (e.g. learned literals, symbols in assertion cache).
#include "expr/node_algorithm.h"
#include "smt/env.h"
-#include "smt/solver_engine.h"
#include "theory/theory_engine.h"
#include "theory/theory_model.h"
namespace preprocessing {
PreprocessingPassContext::PreprocessingPassContext(
- SolverEngine* slv,
Env& env,
+ TheoryEngine* te,
+ prop::PropEngine* pe,
theory::booleans::CircuitPropagator* circuitPropagator)
: EnvObj(env),
- d_slv(slv),
+ d_theoryEngine(te),
+ d_propEngine(pe),
d_circuitPropagator(circuitPropagator),
d_llm(
env.getTopLevelSubstitutions(), userContext(), getProofNodeManager()),
TheoryEngine* PreprocessingPassContext::getTheoryEngine() const
{
- return d_slv->getTheoryEngine();
+ return d_theoryEngine;
}
prop::PropEngine* PreprocessingPassContext::getPropEngine() const
{
- return d_slv->getPropEngine();
+ return d_propEngine;
}
void PreprocessingPassContext::spendResource(Resource r)
namespace cvc5 {
class Env;
-class SolverEngine;
class TheoryEngine;
namespace theory::booleans {
public:
/** Constructor. */
PreprocessingPassContext(
- SolverEngine* smt,
Env& env,
+ TheoryEngine* te,
+ prop::PropEngine* pe,
theory::booleans::CircuitPropagator* circuitPropagator);
/** Get the associated Environment. */
ProofNodeManager* getProofNodeManager() const;
private:
- /** Pointer to the SolverEngine that this context was created in. */
- SolverEngine* d_slv;
+ /** Pointer to the theory engine associated with this context. */
+ TheoryEngine* d_theoryEngine;
+ /** Pointer to the prop engine associated with this context. */
+ prop::PropEngine* d_propEngine;
/** Instance of the circuit propagator */
theory::booleans::CircuitPropagator* d_circuitPropagator;
/**
}
}
-void Preprocessor::finishInit(SolverEngine* slv)
+void Preprocessor::finishInit(TheoryEngine* te, prop::PropEngine* pe)
{
- d_ppContext.reset(
- new preprocessing::PreprocessingPassContext(slv, d_env, &d_propagator));
+ d_ppContext.reset(new preprocessing::PreprocessingPassContext(
+ d_env, te, pe, &d_propagator));
// initialize the preprocessing passes
d_processor.finishInit(d_ppContext.get());
namespace cvc5 {
-class SolverEngine;
+class TheoryEngine;
namespace preprocessing {
class PreprocessingPassContext;
}
+namespace prop {
+class PropEngine;
+}
+
namespace smt {
class AbstractValues;
/**
* Finish initialization
*/
- void finishInit(SolverEngine* slv);
+ void finishInit(TheoryEngine* te, prop::PropEngine* pe);
/**
* Process the assertions that have been asserted in argument as. Returns
* true if no conflict was discovered while preprocessing them.
void ProcessAssertions::finishInit(PreprocessingPassContext* pc)
{
- Assert(d_preprocessingPassContext == nullptr);
+ // note that we may be replacing a stale preprocessing pass context here
d_preprocessingPassContext = pc;
PreprocessingPassRegistry& ppReg = PreprocessingPassRegistry::getInstance();
SmtSolver::SmtSolver(Env& env,
SmtEngineState& state,
- Preprocessor& pp,
+ AbstractValues& abs,
SmtEngineStatistics& stats)
: d_env(env),
d_state(state),
- d_pp(pp),
+ d_pp(env, abs, stats),
d_stats(stats),
d_theoryEngine(nullptr),
d_propEngine(nullptr)
Trace("smt-debug") << "Finishing init for theory engine..." << std::endl;
d_theoryEngine->finishInit();
d_propEngine->finishInit();
+
+ d_pp.finishInit(d_theoryEngine.get(), d_propEngine.get());
}
void SmtSolver::resetAssertions()
// finishInit again. In particular, TheoryEngine::finishInit does not
// depend on knowing the associated PropEngine.
d_propEngine->finishInit();
+ // must reset the preprocessor as well
+ d_pp.finishInit(d_theoryEngine.get(), d_propEngine.get());
}
void SmtSolver::interrupt()
#include <vector>
#include "expr/node.h"
+#include "smt/preprocessor.h"
#include "theory/logic_info.h"
#include "util/result.h"
class Assertions;
class SmtEngineState;
-class Preprocessor;
struct SmtEngineStatistics;
/**
public:
SmtSolver(Env& env,
SmtEngineState& state,
- Preprocessor& pp,
+ AbstractValues& abs,
SmtEngineStatistics& stats);
~SmtSolver();
/**
Env& d_env;
/** Reference to the state of the SolverEngine */
SmtEngineState& d_state;
- /** Reference to the preprocessor of SolverEngine */
- Preprocessor& d_pp;
+ /** The preprocessor of this SMT solver */
+ Preprocessor d_pp;
/** Reference to the statistics of SolverEngine */
SmtEngineStatistics& d_stats;
/** The theory engine */
d_isInternalSubsolver(false),
d_stats(nullptr),
d_outMgr(this),
- d_pp(nullptr),
d_scope(nullptr)
{
// !!!!!!!!!!!!!!!!!!!!!! temporary hack: this makes the current SolverEngine
getResourceManager()->registerListener(d_routListener.get());
// make statistics
d_stats.reset(new SmtEngineStatistics());
- // reset the preprocessor
- d_pp.reset(new smt::Preprocessor(*d_env, *d_absValues, *d_stats));
// make the SMT solver
- d_smtSolver.reset(new SmtSolver(*d_env, *d_state, *d_pp, *d_stats));
+ d_smtSolver.reset(new SmtSolver(*d_env, *d_state, *d_absValues, *d_stats));
// make the SyGuS solver
- d_sygusSolver.reset(new SygusSolver(*d_env.get(), *d_smtSolver, *d_pp));
+ d_sygusSolver.reset(new SygusSolver(*d_env.get(), *d_smtSolver));
// make the quantifier elimination solver
d_quantElimSolver.reset(new QuantElimSolver(*d_env.get(), *d_smtSolver));
}
// enable it in the assertions pipeline
d_asserts->setProofGenerator(pppg);
// enabled proofs in the preprocessor
- d_pp->setProofGenerator(pppg);
+ d_smtSolver->getPreprocessor()->setProofGenerator(pppg);
}
Trace("smt-debug") << "SolverEngine::finishInit" << std::endl;
d_interpolSolver.reset(new InterpolationSolver(*d_env));
}
- d_pp->finishInit(this);
-
AlwaysAssert(getPropEngine()->getAssertionLevel() == 0)
<< "The PropEngine has pushed but the SolverEngine "
"hasn't finished initializing!";
d_state->cleanup();
// destroy all passes before destroying things that they refer to
- d_pp->cleanup();
+ d_smtSolver->getPreprocessor()->cleanup();
d_pfManager.reset(nullptr);
d_ucManager.reset(nullptr);
getNodeManager()->unsubscribeEvents(d_snmListener.get());
d_snmListener.reset(nullptr);
d_routListener.reset(nullptr);
- d_pp.reset(nullptr);
// destroy the state
d_state.reset(nullptr);
// destroy the environment
d_state->doPendingPops();
// ensure we've processed assertions
d_smtSolver->processAssertions(*d_asserts);
- return d_pp->simplify(ex);
+ return d_smtSolver->getPreprocessor()->simplify(ex);
}
Node SolverEngine::expandDefinitions(const Node& ex)
SmtScope smts(this);
finishInit();
d_state->doPendingPops();
- return d_pp->expandDefinitions(ex);
+ return d_smtSolver->getPreprocessor()->expandDefinitions(ex);
}
// TODO(#1108): Simplify the error reporting of this method.
TypeNode expectedType = ex.getType();
// Substitute out any abstract values in ex and expand
- Node n = d_pp->expandDefinitions(ex);
+ Node n = d_smtSolver->getPreprocessor()->expandDefinitions(ex);
Trace("smt") << "--- getting value of " << n << endl;
// There are two ways model values for terms are computed (for historical
// we get the assertions using the getAssertionsInternal, which does not
// impact whether we are in "sat" mode
std::vector<Node> asserts = getAssertionsInternal();
- d_pp->expandDefinitions(asserts);
+ d_smtSolver->getPreprocessor()->expandDefinitions(asserts);
ModelCoreBuilder mcb(*d_env.get());
mcb.setModelCore(asserts, tm, opts.smt.modelCoresMode);
}
{
std::vector<Node> easserts = getAssertions();
// must expand definitions
- d_pp->expandDefinitions(easserts);
+ d_smtSolver->getPreprocessor()->expandDefinitions(easserts);
return easserts;
}
Env& SolverEngine::getEnv() { return *d_env.get(); }
// Clear out assertion queues etc., in case anything is still in there
d_asserts->clearCurrent();
// clear the learned literals from the preprocessor
- d_pp->clearLearnedLiterals();
+ d_smtSolver->getPreprocessor()->clearLearnedLiterals();
Trace("userpushpop") << "SolverEngine: popped to level "
<< getUserContext()->getLevel() << endl;
/** the output manager for commands */
mutable OutputManager d_outMgr;
- /**
- * The preprocessor.
- */
- std::unique_ptr<smt::Preprocessor> d_pp;
/**
* The global scope object. Upon creation of this SolverEngine, it becomes the
* SolverEngine in scope. It says the SolverEngine in scope until it is
namespace cvc5 {
namespace smt {
-SygusSolver::SygusSolver(Env& env, SmtSolver& sms, Preprocessor& pp)
- : EnvObj(env),
- d_smtSolver(sms),
- d_pp(pp),
- d_sygusConjectureStale(userContext(), true)
+SygusSolver::SygusSolver(Env& env, SmtSolver& sms)
+ : EnvObj(env), d_smtSolver(sms), d_sygusConjectureStale(userContext(), true)
{
}
<< assertion << std::endl;
Trace("check-synth-sol") << "Retrieving assertion " << assertion << "\n";
// Apply any define-funs from the problem.
- Node n = d_pp.expandDefinitions(assertion, cache);
+ Node n = d_smtSolver.getPreprocessor()->expandDefinitions(assertion, cache);
Notice() << "SygusSolver::checkSynthSolution(): -- expands to " << n
<< std::endl;
Trace("check-synth-sol") << "Expanded assertion " << n << "\n";
// ensures we don't try to expand e.g. bitvector extract operators,
// whose type is undefined, and thus should not be passed to
// expandDefinitions.
- Node eop = op.isConst() ? op : d_pp.expandDefinitions(op);
+ Node eop = op.isConst()
+ ? op
+ : d_smtSolver.getPreprocessor()->expandDefinitions(op);
datatypes::utils::setExpandedDefinitionForm(op, eop);
// also must consider the arguments
for (unsigned j = 0, nargs = c->getNumArgs(); j < nargs; ++j)
namespace smt {
-class Preprocessor;
class SmtSolver;
/**
class SygusSolver : protected EnvObj
{
public:
- SygusSolver(Env& env, SmtSolver& sms, Preprocessor& pp);
+ SygusSolver(Env& env, SmtSolver& sms);
~SygusSolver();
/**
void expandDefinitionsSygusDt(TypeNode tn) const;
/** The SMT solver, which is used during checkSynth. */
SmtSolver& d_smtSolver;
- /** The preprocessor, used for checkSynthSolution. */
- Preprocessor& d_pp;
/**
* sygus variables declared (from "declare-var" and "declare-fun" commands)
*
TestSmt::SetUp();
d_preprocContext.reset(new preprocessing::PreprocessingPassContext(
- d_slvEngine.get(), d_slvEngine->getEnv(), nullptr));
+ d_slvEngine->getEnv(),
+ d_slvEngine->getTheoryEngine(),
+ d_slvEngine->getPropEngine(),
+ nullptr));
d_bv_gauss.reset(new BVGauss(d_preprocContext.get()));