summaryrefslogtreecommitdiff
path: root/src/smt
diff options
context:
space:
mode:
authorAndres Noetzli <andres.noetzli@gmail.com>2018-08-16 18:57:24 -0700
committerGitHub <noreply@github.com>2018-08-16 18:57:24 -0700
commite6fd3c70f8651c6a9055fad8933caf2596b2b651 (patch)
tree4cc0809a2aa4fed311bca9f41eee04c935578eb7 /src/smt
parent7fc04bf78c6c20f3711d14425469eef2e0c2cd60 (diff)
Refactor IteRemoval preprocessing pass (#1793)
This commit refactors the IteRemoval pass to follow the new format. In addition to moving the code, this entails the following changes: - The timer for the ITE removal is now called differently (the default timer of PreprocessingPass is used) and measures just the preprocessing pass without applySubstitutions(). It also measures the time used by both invocations of the ITE removal pass. - Debug output will be slightly different because we now just rely on the default functionality of PreprocessingPass. - d_iteRemover is now passed into the PreprocessingPassContext. - AssertionPipeline now owns the d_iteSkolemMap, which makes it accessible by preprocessing passes. The idea behind this is that the preprocessing passes collect information in AssertionPipeline and d_iteSkolemMap fits that pattern.
Diffstat (limited to 'src/smt')
-rw-r--r--src/smt/smt_engine.cpp85
1 files changed, 29 insertions, 56 deletions
diff --git a/src/smt/smt_engine.cpp b/src/smt/smt_engine.cpp
index b5d758bca..d2e9c2f36 100644
--- a/src/smt/smt_engine.cpp
+++ b/src/smt/smt_engine.cpp
@@ -79,6 +79,7 @@
#include "preprocessing/passes/bv_to_bool.h"
#include "preprocessing/passes/extended_rewriter_pass.h"
#include "preprocessing/passes/int_to_bv.h"
+#include "preprocessing/passes/ite_removal.h"
#include "preprocessing/passes/pseudo_boolean_processor.h"
#include "preprocessing/passes/real_to_int.h"
#include "preprocessing/passes/rewrite.h"
@@ -204,8 +205,6 @@ struct SmtEngineStatistics {
TimerStat d_simpITETime;
/** time spent in simplifying ITEs */
TimerStat d_unconstrainedSimpTime;
- /** time spent removing ITEs */
- TimerStat d_iteRemovalTime;
/** time spent in theory preprocessing */
TimerStat d_theoryPreprocessTime;
/** time spent in theory preprocessing */
@@ -243,7 +242,6 @@ struct SmtEngineStatistics {
d_numConstantProps("smt::SmtEngine::numConstantProps", 0),
d_simpITETime("smt::SmtEngine::simpITETime"),
d_unconstrainedSimpTime("smt::SmtEngine::unconstrainedSimpTime"),
- d_iteRemovalTime("smt::SmtEngine::iteRemovalTime"),
d_theoryPreprocessTime("smt::SmtEngine::theoryPreprocessTime"),
d_rewriteApplyToConstTime("smt::SmtEngine::rewriteApplyToConstTime"),
d_cnfConversionTime("smt::SmtEngine::cnfConversionTime"),
@@ -267,7 +265,6 @@ struct SmtEngineStatistics {
smtStatisticsRegistry()->registerStat(&d_numConstantProps);
smtStatisticsRegistry()->registerStat(&d_simpITETime);
smtStatisticsRegistry()->registerStat(&d_unconstrainedSimpTime);
- smtStatisticsRegistry()->registerStat(&d_iteRemovalTime);
smtStatisticsRegistry()->registerStat(&d_theoryPreprocessTime);
smtStatisticsRegistry()->registerStat(&d_rewriteApplyToConstTime);
smtStatisticsRegistry()->registerStat(&d_cnfConversionTime);
@@ -292,7 +289,6 @@ struct SmtEngineStatistics {
smtStatisticsRegistry()->unregisterStat(&d_numConstantProps);
smtStatisticsRegistry()->unregisterStat(&d_simpITETime);
smtStatisticsRegistry()->unregisterStat(&d_unconstrainedSimpTime);
- smtStatisticsRegistry()->unregisterStat(&d_iteRemovalTime);
smtStatisticsRegistry()->unregisterStat(&d_theoryPreprocessTime);
smtStatisticsRegistry()->unregisterStat(&d_rewriteApplyToConstTime);
smtStatisticsRegistry()->unregisterStat(&d_cnfConversionTime);
@@ -563,12 +559,8 @@ class SmtEnginePrivate : public NodeManagerListener {
/** mapping from expressions to name */
context::CDHashMap< Node, std::string, NodeHashFunction > d_exprNames;
//------------------------------- end expression names
-public:
- /**
- * Map from skolem variables to index in d_assertions containing
- * corresponding introduced Boolean ite
- */
- IteSkolemMap d_iteSkolemMap;
+ public:
+ IteSkolemMap& getIteSkolemMap() { return d_assertions.getIteSkolemMap(); }
/** Instance of the ITE remover */
RemoveTermFormulas d_iteRemover;
@@ -595,11 +587,6 @@ public:
*/
void staticLearning();
- /**
- * Remove ITEs from the assertions.
- */
- void removeITEs();
-
Node realToInt(TNode n, NodeToNodeHashMap& cache, std::vector< Node >& var_eq);
Node purifyNlTerms(TNode n, NodeToNodeHashMap& cache, NodeToNodeHashMap& bcache, std::vector< Node >& var_eq, bool beneathMult = false);
@@ -638,8 +625,8 @@ public:
* Remove conjuncts in toRemove from conjunction n. Return # of removed
* conjuncts.
*/
- size_t removeFromConjunction(Node& n,
- const std::unordered_set<unsigned long>& toRemove);
+ size_t removeFromConjunction(
+ Node& n, const std::unordered_set<unsigned long>& toRemove);
/** Scrub miplib encodings. */
void doMiplibTrick();
@@ -673,7 +660,6 @@ public:
d_simplifyAssertionsDepth(0),
// d_needsExpandDefs(true), //TODO?
d_exprNames(smt.d_userContext),
- d_iteSkolemMap(),
d_iteRemover(smt.d_userContext)
{
d_smt.d_nodeManager->subscribeEvents(this);
@@ -839,7 +825,7 @@ public:
d_assertions.clear();
d_nonClausalLearnedLiterals.clear();
d_realAssertionsEnd = 0;
- d_iteSkolemMap.clear();
+ getIteSkolemMap().clear();
}
/**
@@ -988,7 +974,8 @@ SmtEngine::SmtEngine(ExprManager* em)
// We have mutual dependency here, so we add the prop engine to the theory
// engine later (it is non-essential there)
- d_theoryEngine = new TheoryEngine(d_context, d_userContext,
+ d_theoryEngine = new TheoryEngine(d_context,
+ d_userContext,
d_private->d_iteRemover,
const_cast<const LogicInfo&>(d_logic),
d_channels);
@@ -2654,7 +2641,7 @@ bool SmtEngine::isDefinedFunction( Expr func ){
void SmtEnginePrivate::finishInit()
{
d_preprocessingPassContext.reset(
- new PreprocessingPassContext(&d_smt, d_resourceManager));
+ new PreprocessingPassContext(&d_smt, d_resourceManager, &d_iteRemover));
// TODO: register passes here (this will likely change when we add support for
// actually assembling preprocessing pipelines).
std::unique_ptr<ApplySubsts> applySubsts(
@@ -2679,6 +2666,8 @@ void SmtEnginePrivate::finishInit()
new IntToBV(d_preprocessingPassContext.get()));
std::unique_ptr<PseudoBooleanProcessor> pbProc(
new PseudoBooleanProcessor(d_preprocessingPassContext.get()));
+ std::unique_ptr<IteRemoval> iteRemoval(
+ new IteRemoval(d_preprocessingPassContext.get()));
std::unique_ptr<RealToInt> realToInt(
new RealToInt(d_preprocessingPassContext.get()));
std::unique_ptr<Rewrite> rewrite(
@@ -2711,6 +2700,8 @@ void SmtEnginePrivate::finishInit()
d_preprocessingPassRegistry.registerPass("int-to-bv", std::move(intToBV));
d_preprocessingPassRegistry.registerPass("pseudo-boolean-processor",
std::move(pbProc));
+ d_preprocessingPassRegistry.registerPass("ite-removal",
+ std::move(iteRemoval));
d_preprocessingPassRegistry.registerPass("real-to-int", std::move(realToInt));
d_preprocessingPassRegistry.registerPass("rewrite", std::move(rewrite));
d_preprocessingPassRegistry.registerPass("sep-skolem-emp",
@@ -2968,20 +2959,6 @@ Node SmtEnginePrivate::purifyNlTerms(TNode n, NodeMap& cache, NodeMap& bcache, s
return ret;
}
-void SmtEnginePrivate::removeITEs() {
- d_smt.finalOptionsAreSet();
- spendResource(options::preprocessStep());
- Trace("simplify") << "SmtEnginePrivate::removeITEs()" << endl;
-
- // Remove all of the ITE occurrences and normalize
- d_iteRemover.run(d_assertions.ref(), d_iteSkolemMap, true);
- for (unsigned i = 0; i < d_assertions.size(); ++ i) {
- d_assertions.replace(i, Rewriter::rewrite(d_assertions[i]));
- }
-}
-
-
-
// do dumping (before/after any preprocessing pass)
static void dumpAssertions(const char* key,
const AssertionPipeline& assertionList) {
@@ -3937,7 +3914,8 @@ Result SmtEngine::check() {
(not d_logic.isQuantified() &&
d_logic.isPure(THEORY_ARITH) && d_logic.isLinear() && !d_logic.isDifferenceLogic() && !d_logic.areIntegersUsed()
)){
- if(d_private->d_iteSkolemMap.empty()){
+ if (d_private->getIteSkolemMap().empty())
+ {
options::decisionStopOnly.set(false);
d_decisionEngine->clearStrategies();
Trace("smt") << "SmtEngine::check(): turning off stop only" << endl;
@@ -3976,8 +3954,9 @@ void SmtEnginePrivate::collectSkolems(TNode n, set<TNode>& skolemSet, unordered_
size_t sz = n.getNumChildren();
if (sz == 0) {
- IteSkolemMap::iterator it = d_iteSkolemMap.find(n);
- if (it != d_iteSkolemMap.end()) {
+ IteSkolemMap::iterator it = getIteSkolemMap().find(n);
+ if (it != getIteSkolemMap().end())
+ {
skolemSet.insert(n);
}
cache[n] = true;
@@ -4002,9 +3981,10 @@ bool SmtEnginePrivate::checkForBadSkolems(TNode n, TNode skolem, unordered_map<N
size_t sz = n.getNumChildren();
if (sz == 0) {
- IteSkolemMap::iterator it = d_iteSkolemMap.find(n);
+ IteSkolemMap::iterator it = getIteSkolemMap().find(n);
bool bad = false;
- if (it != d_iteSkolemMap.end()) {
+ if (it != getIteSkolemMap().end())
+ {
if (!((*it).first < n)) {
bad = true;
}
@@ -4326,22 +4306,15 @@ void SmtEnginePrivate::processAssertions() {
}
Debug("smt") << " d_assertions : " << d_assertions.size() << endl;
- Trace("smt-proc") << "SmtEnginePrivate::processAssertions() : pre-ite-removal" << endl;
- dumpAssertions("pre-ite-removal", d_assertions);
{
- Chat() << "removing term ITEs..." << endl;
- TimerStat::CodeTimer codeTimer(d_smt.d_stats->d_iteRemovalTime);
- // Remove ITEs, updating d_iteSkolemMap
d_smt.d_stats->d_numAssertionsPre += d_assertions.size();
- removeITEs();
+ d_preprocessingPassRegistry.getPass("ite-removal")->apply(&d_assertions);
// This is needed because when solving incrementally, removeITEs may introduce
// skolems that were solved for earlier and thus appear in the substitution
// map.
d_preprocessingPassRegistry.getPass("apply-substs")->apply(&d_assertions);
d_smt.d_stats->d_numAssertionsPost += d_assertions.size();
}
- Trace("smt-proc") << "SmtEnginePrivate::processAssertions() : post-ite-removal" << endl;
- dumpAssertions("post-ite-removal", d_assertions);
dumpAssertions("pre-repeat-simplify", d_assertions);
if(options::repeatSimp()) {
@@ -4372,8 +4345,8 @@ void SmtEnginePrivate::processAssertions() {
// 1. iteExpr has the form (ite cond (sk = t) (sk = e))
// 2. if some sk' in Sk appears in cond, t, or e, then sk' <_sk sk
// If either of these is violated, we must add iteExpr as a proper assertion
- IteSkolemMap::iterator it = d_iteSkolemMap.begin();
- IteSkolemMap::iterator iend = d_iteSkolemMap.end();
+ IteSkolemMap::iterator it = getIteSkolemMap().begin();
+ IteSkolemMap::iterator iend = getIteSkolemMap().end();
NodeBuilder<> builder(kind::AND);
builder << d_assertions[d_realAssertionsEnd - 1];
vector<TNode> toErase;
@@ -4401,14 +4374,14 @@ void SmtEnginePrivate::processAssertions() {
}
if(builder.getNumChildren() > 1) {
while (!toErase.empty()) {
- d_iteSkolemMap.erase(toErase.back());
+ getIteSkolemMap().erase(toErase.back());
toErase.pop_back();
}
d_assertions[d_realAssertionsEnd - 1] = Rewriter::rewrite(Node(builder));
}
// TODO(b/1256): For some reason this is needed for some benchmarks, such as
// QF_AUFBV/dwp_formulas/try5_small_difret_functions_dwp_tac.re_node_set_remove_at.il.dwp.smt2
- removeITEs();
+ d_preprocessingPassRegistry.getPass("ite-removal")->apply(&d_assertions);
d_preprocessingPassRegistry.getPass("apply-substs")->apply(&d_assertions);
// Assert(iteRewriteAssertionsEnd == d_assertions.size());
}
@@ -4468,8 +4441,8 @@ void SmtEnginePrivate::processAssertions() {
if(noConflict) {
Chat() << "pushing to decision engine..." << endl;
Assert(iteRewriteAssertionsEnd == d_assertions.size());
- d_smt.d_decisionEngine->addAssertions
- (d_assertions.ref(), d_realAssertionsEnd, d_iteSkolemMap);
+ d_smt.d_decisionEngine->addAssertions(
+ d_assertions.ref(), d_realAssertionsEnd, getIteSkolemMap());
}
// end: INVARIANT to maintain: no reordering of assertions or
@@ -4491,7 +4464,7 @@ void SmtEnginePrivate::processAssertions() {
d_assertionsProcessed = true;
d_assertions.clear();
- d_iteSkolemMap.clear();
+ getIteSkolemMap().clear();
}
void SmtEnginePrivate::addFormula(TNode n, bool inUnsatCore, bool inInput)
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback