summaryrefslogtreecommitdiff
path: root/src/smt/process_assertions.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/smt/process_assertions.cpp')
-rw-r--r--src/smt/process_assertions.cpp165
1 files changed, 106 insertions, 59 deletions
diff --git a/src/smt/process_assertions.cpp b/src/smt/process_assertions.cpp
index 47deddac3..468b754cc 100644
--- a/src/smt/process_assertions.cpp
+++ b/src/smt/process_assertions.cpp
@@ -27,11 +27,9 @@
#include "options/strings_options.h"
#include "options/uf_options.h"
#include "preprocessing/assertion_pipeline.h"
-#include "preprocessing/preprocessing_pass.h"
#include "preprocessing/preprocessing_pass_registry.h"
#include "printer/printer.h"
#include "smt/assertions.h"
-#include "smt/dump.h"
#include "smt/expand_definitions.h"
#include "smt/print_benchmark.h"
#include "smt/solver_engine_stats.h"
@@ -98,7 +96,8 @@ bool ProcessAssertions::apply(Assertions& as)
AssertionPipeline& assertions = as.getAssertionPipeline();
Assert(d_preprocessingPassContext != nullptr);
// Dump the assertions
- dumpAssertions("pre-everything", as);
+ dumpAssertions("assertions::pre-everything", as);
+ Trace("assertions::pre-everything") << std::endl;
Trace("smt-proc") << "ProcessAssertions::processAssertions() begin" << endl;
Trace("smt") << "ProcessAssertions::processAssertions()" << endl;
@@ -114,7 +113,7 @@ bool ProcessAssertions::apply(Assertions& as)
if (options().bv.bvGaussElim)
{
- d_passes["bv-gauss"]->apply(&assertions);
+ applyPass("bv-gauss", as);
}
// Add dummy assertion in last position - to be used as a
@@ -129,44 +128,42 @@ bool ProcessAssertions::apply(Assertions& as)
Trace("smt-proc")
<< "ProcessAssertions::processAssertions() : pre-definition-expansion"
<< endl;
- dumpAssertions("pre-definition-expansion", as);
// Apply substitutions first. If we are non-incremental, this has only the
// effect of replacing defined functions with their definitions.
// We do not call theory-specific expand definitions here, since we want
// to give the opportunity to rewrite/preprocess terms before expansion.
- d_passes["apply-substs"]->apply(&assertions);
+ applyPass("apply-substs", as);
Trace("smt-proc")
<< "ProcessAssertions::processAssertions() : post-definition-expansion"
<< endl;
- dumpAssertions("post-definition-expansion", as);
Debug("smt") << " assertions : " << assertions.size() << endl;
if (options().quantifiers.globalNegate)
{
// global negation of the formula
- d_passes["global-negate"]->apply(&assertions);
+ applyPass("global-negate", as);
as.flipGlobalNegated();
}
if (options().arith.nlExtPurify)
{
- d_passes["nl-ext-purify"]->apply(&assertions);
+ applyPass("nl-ext-purify", as);
}
if (options().smt.solveRealAsInt)
{
- d_passes["real-to-int"]->apply(&assertions);
+ applyPass("real-to-int", as);
}
if (options().smt.solveIntAsBV > 0)
{
- d_passes["int-to-bv"]->apply(&assertions);
+ applyPass("int-to-bv", as);
}
if (options().smt.ackermann)
{
- d_passes["ackermann"]->apply(&assertions);
+ applyPass("ackermann", as);
}
Debug("smt") << " assertions : " << assertions.size() << endl;
@@ -175,92 +172,93 @@ bool ProcessAssertions::apply(Assertions& as)
if (options().smt.extRewPrep)
{
- d_passes["ext-rew-pre"]->apply(&assertions);
+ applyPass("ext-rew-pre", as);
}
// Unconstrained simplification
if (options().smt.unconstrainedSimp)
{
- d_passes["rewrite"]->apply(&assertions);
- d_passes["unconstrained-simplifier"]->apply(&assertions);
+ applyPass("rewrite", as);
+ applyPass("unconstrained-simplifier", as);
}
if (options().bv.bvIntroducePow2)
{
- d_passes["bv-intro-pow2"]->apply(&assertions);
+ applyPass("bv-intro-pow2", as);
}
// Lift bit-vectors of size 1 to bool
if (options().bv.bitvectorToBool)
{
- d_passes["bv-to-bool"]->apply(&assertions);
+ applyPass("bv-to-bool", as);
}
if (options().smt.solveBVAsInt != options::SolveBVAsIntMode::OFF)
{
- d_passes["bv-to-int"]->apply(&assertions);
+ applyPass("bv-to-int", as);
}
if (options().smt.foreignTheoryRewrite)
{
- d_passes["foreign-theory-rewrite"]->apply(&assertions);
+ applyPass("foreign-theory-rewrite", as);
}
// Since this pass is not robust for the information tracking necessary for
// unsat cores, it's only applied if we are not doing unsat core computation
- d_passes["apply-substs"]->apply(&assertions);
+ applyPass("apply-substs", as);
// Assertions MUST BE guaranteed to be rewritten by this point
- d_passes["rewrite"]->apply(&assertions);
+ applyPass("rewrite", as);
// Convert non-top-level Booleans to bit-vectors of size 1
if (options().bv.boolToBitvector != options::BoolToBVMode::OFF)
{
- d_passes["bool-to-bv"]->apply(&assertions);
+ applyPass("bool-to-bv", as);
}
if (options().sep.sepPreSkolemEmp)
{
- d_passes["sep-skolem-emp"]->apply(&assertions);
+ applyPass("sep-skolem-emp", as);
}
if (logicInfo().isQuantified())
{
// remove rewrite rules, apply pre-skolemization to existential quantifiers
- d_passes["quantifiers-preprocess"]->apply(&assertions);
+ applyPass("quantifiers-preprocess", as);
// fmf-fun : assume admissible functions, applying preprocessing reduction
// to FMF
if (options().quantifiers.fmfFunWellDefined)
{
- d_passes["fun-def-fmf"]->apply(&assertions);
+ applyPass("fun-def-fmf", as);
}
}
if (!options().strings.stringLazyPreproc)
{
- d_passes["strings-eager-pp"]->apply(&assertions);
+ applyPass("strings-eager-pp", as);
}
if (options().smt.sortInference || options().uf.ufssFairnessMonotone)
{
- d_passes["sort-inference"]->apply(&assertions);
+ applyPass("sort-inference", as);
}
if (options().arith.pbRewrites)
{
- d_passes["pseudo-boolean-processor"]->apply(&assertions);
+ applyPass("pseudo-boolean-processor", as);
}
// rephrasing normal inputs as sygus problems
if (options().quantifiers.sygusInference)
{
- d_passes["sygus-infer"]->apply(&assertions);
+ applyPass("sygus-infer", as);
}
else if (options().quantifiers.sygusRewSynthInput)
{
// do candidate rewrite rule synthesis
- d_passes["synth-rr"]->apply(&assertions);
+ applyPass("synth-rr", as);
}
Trace("smt-proc") << "ProcessAssertions::processAssertions() : pre-simplify"
<< endl;
- dumpAssertions("pre-simplify", as);
+ dumpAssertions("assertions::pre-simplify", as);
+ Trace("assertions::pre-simplify") << std::endl;
Chat() << "simplifying assertions..." << endl;
noConflict = simplifyAssertions(as);
if (!noConflict)
@@ -269,31 +267,33 @@ bool ProcessAssertions::apply(Assertions& as)
}
Trace("smt-proc") << "ProcessAssertions::processAssertions() : post-simplify"
<< endl;
- dumpAssertions("post-simplify", as);
+ dumpAssertions("assertions::post-simplify", as);
+ Trace("assertions::post-simplify") << std::endl;
if (options().smt.doStaticLearning)
{
- d_passes["static-learning"]->apply(&assertions);
+ applyPass("static-learning", as);
}
Debug("smt") << " assertions : " << assertions.size() << endl;
if (options().smt.learnedRewrite)
{
- d_passes["learned-rewrite"]->apply(&assertions);
+ applyPass("learned-rewrite", as);
}
if (options().smt.earlyIteRemoval)
{
d_slvStats.d_numAssertionsPre += assertions.size();
- d_passes["ite-removal"]->apply(&assertions);
+ applyPass("ite-removal", as);
// This is needed because when solving incrementally, removeITEs may
// introduce skolems that were solved for earlier and thus appear in the
// substitution map.
- d_passes["apply-substs"]->apply(&assertions);
+ applyPass("apply-substs", as);
d_slvStats.d_numAssertionsPost += assertions.size();
}
- dumpAssertions("pre-repeat-simplify", as);
+ dumpAssertions("assertions::pre-repeat-simplify", as);
+ Trace("assertions::pre-repeat-simplify") << std::endl;
if (options().smt.repeatSimp)
{
Trace("smt-proc")
@@ -306,11 +306,12 @@ bool ProcessAssertions::apply(Assertions& as)
<< "ProcessAssertions::processAssertions() : post-repeat-simplify"
<< endl;
}
- dumpAssertions("post-repeat-simplify", as);
+ dumpAssertions("assertions::post-repeat-simplify", as);
+ Trace("assertions::post-repeat-simplify") << std::endl;
if (logicInfo().isHigherOrder())
{
- d_passes["ho-elim"]->apply(&assertions);
+ applyPass("ho-elim", as);
}
// begin: INVARIANT to maintain: no reordering of assertions or
@@ -323,21 +324,22 @@ bool ProcessAssertions::apply(Assertions& as)
Debug("smt") << " assertions : " << assertions.size() << endl;
// ensure rewritten
- d_passes["rewrite"]->apply(&assertions);
+ applyPass("rewrite", as);
// rewrite equalities based on theory-specific rewriting
- d_passes["theory-rewrite-eq"]->apply(&assertions);
+ applyPass("theory-rewrite-eq", as);
// apply theory preprocess, which includes ITE removal
- d_passes["theory-preprocess"]->apply(&assertions);
+ applyPass("theory-preprocess", as);
// notice that we do not apply substitutions as a last step here, since
// the range of substitutions is not theory-preprocessed.
if (options().bv.bitblastMode == options::BitblastMode::EAGER)
{
- d_passes["bv-eager-atoms"]->apply(&assertions);
+ applyPass("bv-eager-atoms", as);
}
Trace("smt-proc") << "ProcessAssertions::apply() end" << endl;
- dumpAssertions("post-everything", as);
+ dumpAssertions("assertions::post-everything", as);
+ Trace("assertions::post-everything") << std::endl;
return noConflict;
}
@@ -356,8 +358,7 @@ bool ProcessAssertions::simplifyAssertions(Assertions& as)
if (options().smt.simplificationMode != options::SimplificationMode::NONE)
{
// Perform non-clausal simplification
- PreprocessingPassResult res =
- d_passes["non-clausal-simp"]->apply(&assertions);
+ PreprocessingPassResult res = applyPass("non-clausal-simp", as);
if (res == PreprocessingPassResult::CONFLICT)
{
return false;
@@ -374,7 +375,7 @@ bool ProcessAssertions::simplifyAssertions(Assertions& as)
// re-simplification, which we don't expect to be useful anyway)
assertions.getRealAssertionsEnd() == assertions.size())
{
- d_passes["miplib-trick"]->apply(&assertions);
+ applyPass("miplib-trick", as);
}
else
{
@@ -389,7 +390,7 @@ bool ProcessAssertions::simplifyAssertions(Assertions& as)
if (options().smt.doITESimp
&& (d_simplifyAssertionsDepth <= 1 || options().smt.doITESimpOnRepeat))
{
- PreprocessingPassResult res = d_passes["ite-simp"]->apply(&assertions);
+ PreprocessingPassResult res = applyPass("ite-simp", as);
if (res == PreprocessingPassResult::CONFLICT)
{
Chat() << "...ITE simplification found unsat..." << endl;
@@ -402,15 +403,14 @@ bool ProcessAssertions::simplifyAssertions(Assertions& as)
// Unconstrained simplification
if (options().smt.unconstrainedSimp)
{
- d_passes["unconstrained-simplifier"]->apply(&assertions);
+ applyPass("unconstrained-simplifier", as);
}
if (options().smt.repeatSimp
&& options().smt.simplificationMode
!= options::SimplificationMode::NONE)
{
- PreprocessingPassResult res =
- d_passes["non-clausal-simp"]->apply(&assertions);
+ PreprocessingPassResult res = applyPass("non-clausal-simp", as);
if (res == PreprocessingPassResult::CONFLICT)
{
return false;
@@ -435,18 +435,65 @@ bool ProcessAssertions::simplifyAssertions(Assertions& as)
return true;
}
-void ProcessAssertions::dumpAssertions(const char* key, Assertions& as)
+void ProcessAssertions::dumpAssertions(const std::string& key, Assertions& as)
{
- if (Dump.isOn("assertions") && Dump.isOn(string("assertions:") + key))
- {
- const AssertionPipeline& assertionList = as.getAssertionPipeline();
- // Push the simplified assertions to the dump output stream
- for (unsigned i = 0; i < assertionList.size(); ++i)
+ bool isTraceOn = Trace.isOn(key);
+ if (!isTraceOn)
+ {
+ return;
+ }
+ // Cannot print unless produce assertions is enabled. Otherwise, the printing
+ // is misleading, since it does not capture what symbols were provided
+ // as definitions.
+ if (!options().smt.produceAssertions)
+ {
+ Warning()
+ << "Assertions not available for dumping (use --produce-assertions)."
+ << std::endl;
+ return;
+ }
+ PrintBenchmark pb(&d_env.getPrinter());
+ std::vector<Node> assertions;
+ // Notice that the following list covers define-fun and define-fun-rec
+ // from input. The former does not impact the assertions since define-fun are
+ // added as top-level substitutions. The latter do get added to the list
+ // of assertions. Since we are interested in printing the result of
+ // preprocessed quantified formulas corresponding to recursive function
+ // definitions and not the original definitions, we discard the latter
+ // in the loop below.
+ //
+ // In summary, this means that define-fun-rec are expanded to
+ // (declare-fun ...) + (assert (forall ...)) in the printing below, whereas
+ // define-fun are preserved.
+ const context::CDList<Node>& asld = as.getAssertionListDefinitions();
+ std::vector<Node> defs;
+ for (const Node& d : asld)
+ {
+ if (d.getKind() != FORALL)
{
- TNode n = assertionList[i];
- d_env.getPrinter().toStreamCmdAssert(d_env.getDumpOut(), n);
+ defs.push_back(d);
}
}
+ AssertionPipeline& ap = as.getAssertionPipeline();
+ for (size_t i = 0, size = ap.size(); i < size; i++)
+ {
+ assertions.push_back(ap[i]);
+ }
+ std::stringstream ss;
+ pb.printBenchmark(ss, logicInfo().getLogicString(), defs, assertions);
+ Trace(key) << ";;; " << key << " start" << std::endl;
+ Trace(key) << ss.str();
+ Trace(key) << ";;; " << key << " end " << std::endl;
+}
+
+PreprocessingPassResult ProcessAssertions::applyPass(const std::string& pname,
+ Assertions& as)
+{
+ dumpAssertions("assertions::pre-" + pname, as);
+ AssertionPipeline& assertions = as.getAssertionPipeline();
+ PreprocessingPassResult res = d_passes[pname]->apply(&assertions);
+ dumpAssertions("assertions::post-" + pname, as);
+ return res;
}
} // namespace smt
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback