-
Notifications
You must be signed in to change notification settings - Fork 19
Split simplifyFormulas to sub-functions
#888
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -93,7 +93,7 @@ bool MainSolver::pop() { | |
| frames.pop(); | ||
| preprocessor.pop(); | ||
| termNames.popScope(); | ||
| firstNotSimplifiedFrame = std::min(firstNotSimplifiedFrame, frames.frameCount()); | ||
| firstNotPreprocessedFrame = std::min(firstNotPreprocessedFrame, frames.frameCount()); | ||
| if (not isLastFrameUnsat()) { getSMTSolver().restoreOK(); } | ||
| return true; | ||
| } | ||
|
|
@@ -115,15 +115,15 @@ void MainSolver::insertFormula(PTRef fla) { | |
| // formulas, | ||
| // thus we need the old value of count. TODO: Find a good interface for this so it cannot be broken this | ||
| // easily | ||
| unsigned int partition_index = insertedFormulasCount++; | ||
| unsigned int partition_index = insertedAssertionsCount++; | ||
| pmanager.assignTopLevelPartitionIndex(partition_index, fla); | ||
| assert(pmanager.getPartitionIndex(fla) != -1); | ||
| } else { | ||
| ++insertedFormulasCount; | ||
| ++insertedAssertionsCount; | ||
| } | ||
|
|
||
| frames.add(fla); | ||
| firstNotSimplifiedFrame = std::min(firstNotSimplifiedFrame, frames.frameCount() - 1); | ||
| firstNotPreprocessedFrame = std::min(firstNotPreprocessedFrame, frames.frameCount() - 1); | ||
| } | ||
|
|
||
| bool MainSolver::tryAddNamedAssertion(PTRef fla, std::string const & name) { | ||
|
|
@@ -140,63 +140,138 @@ bool MainSolver::tryAddTermNameFor(PTRef fla, std::string const & name) { | |
|
|
||
| sstat MainSolver::simplifyFormulas() { | ||
| status = s_Undef; | ||
| for (std::size_t i = firstNotSimplifiedFrame; i < frames.frameCount() && status != s_False; i++) { | ||
| PreprocessingContext context{.frameCount = i, .perPartition = trackPartitions()}; | ||
| preprocessor.prepareForProcessingFrame(i); | ||
| firstNotSimplifiedFrame = i + 1; | ||
| if (context.perPartition) { | ||
| vec<PTRef> frameFormulas; | ||
| for (PTRef fla : frames[i].formulas) { | ||
| PTRef processed = theory->preprocessAfterSubstitutions(fla, context); | ||
| pmanager.transferPartitionMembership(fla, processed); | ||
| frameFormulas.push(processed); | ||
| preprocessor.addPreprocessedFormula(processed); | ||
| } | ||
| if (frameFormulas.size() == 0 or std::all_of(frameFormulas.begin(), frameFormulas.end(), | ||
| [&](PTRef fla) { return fla == logic.getTerm_true(); })) { | ||
| continue; | ||
| } | ||
| theory->afterPreprocessing(preprocessor.getPreprocessedFormulas()); | ||
| for (PTRef fla : frameFormulas) { | ||
| if (fla == logic.getTerm_true()) { continue; } | ||
| assert(pmanager.getPartitionIndex(fla) != -1); | ||
| // Optimize the dag for cnfization | ||
| if (logic.isBooleanOperator(fla)) { | ||
| PTRef old = fla; | ||
| fla = rewriteMaxArity(fla); | ||
| pmanager.transferPartitionMembership(old, fla); | ||
| } | ||
| assert(pmanager.getPartitionIndex(fla) != -1); | ||
| pmanager.propagatePartitionMask(fla); | ||
| status = giveToSolver(fla, frames[i].getId()); | ||
| if (status == s_False) { break; } | ||
| } | ||
| } else { | ||
| PTRef frameFormula = logic.mkAnd(frames[i].formulas); | ||
| if (context.frameCount > 0) { frameFormula = applyLearntSubstitutions(frameFormula); } | ||
| frameFormula = theory->preprocessBeforeSubstitutions(frameFormula, context); | ||
| frameFormula = substitutionPass(frameFormula, context); | ||
| frameFormula = theory->preprocessAfterSubstitutions(frameFormula, context); | ||
|
|
||
| if (logic.isFalse(frameFormula)) { | ||
| giveToSolver(logic.getTerm_false(), frames[i].getId()); | ||
| status = s_False; | ||
| break; | ||
| } | ||
| preprocessor.addPreprocessedFormula(frameFormula); | ||
| theory->afterPreprocessing(preprocessor.getPreprocessedFormulas()); | ||
| // Optimize the dag for cnfization | ||
| if (logic.isBooleanOperator(frameFormula)) { frameFormula = rewriteMaxArity(frameFormula); } | ||
| status = giveToSolver(frameFormula, frames[i].getId()); | ||
| } | ||
| for (std::size_t i = firstNotPreprocessedFrame; i < frames.frameCount(); ++i) { | ||
| assert(status != s_False); | ||
| if (tryPreprocessFormulasOfFrame(i)) { continue; } | ||
| assert(status == s_False); | ||
| break; | ||
| } | ||
|
|
||
| if (status == s_False) { | ||
| assert(firstNotSimplifiedFrame > 0); | ||
| rememberUnsatFrame(firstNotSimplifiedFrame - 1); | ||
| assert(firstNotPreprocessedFrame > 0); | ||
| rememberUnsatFrame(firstNotPreprocessedFrame - 1); | ||
| } | ||
|
|
||
| return status; | ||
| } | ||
|
|
||
| bool MainSolver::tryPreprocessFormulasOfFrame(std::size_t i) { | ||
| auto & frame = frames[i]; | ||
| FrameId const frameId = frame.getId(); | ||
| PreprocessingContext context{.frameCount = i, .perPartition = trackPartitions()}; | ||
| preprocessor.prepareForProcessingFrame(i); | ||
| firstNotPreprocessedFrame = i + 1; | ||
|
|
||
| assert(status != s_False); | ||
|
|
||
| if (not context.perPartition) { | ||
| PTRef frameFormula = preprocessFormulasDefault(frame.formulas, context); | ||
| status = giveToSolver(frameFormula, frameId); | ||
| return status != s_False; | ||
| } | ||
|
|
||
| vec<PTRef> processedFormulas = preprocessFormulasPerPartition(frame.formulas, context); | ||
| for (PTRef fla : processedFormulas) { | ||
| status = giveToSolver(fla, frameId); | ||
| if (status == s_False) { return false; } | ||
| } | ||
|
|
||
| assert(status != s_False); | ||
| return true; | ||
| } | ||
|
|
||
| PTRef MainSolver::preprocessFormulasDefault(vec<PTRef> const & frameFormulas, PreprocessingContext const & context) { | ||
| assert(not context.perPartition); | ||
|
|
||
| if (frameFormulas.size() == 0) { return logic.getTerm_true(); } | ||
|
|
||
| PTRef frameFormula = logic.mkAnd(frameFormulas); | ||
| return preprocessFormula(frameFormula, context); | ||
| } | ||
|
|
||
| vec<PTRef> MainSolver::preprocessFormulasPerPartition(vec<PTRef> const & frameFormulas, | ||
| PreprocessingContext const & context) { | ||
| assert(context.perPartition); | ||
|
|
||
| if (frameFormulas.size() == 0) { return {}; } | ||
|
|
||
| vec<PTRef> processedFormulas; | ||
| for (PTRef fla : frameFormulas) { | ||
| PTRef processed = preprocessFormulaBeforeFinalTheoryPreprocessing(fla, context); | ||
| processedFormulas.push(processed); | ||
| } | ||
|
|
||
| assert(processedFormulas.size() == frameFormulas.size()); | ||
| assert(processedFormulas.size() > 0); | ||
| if (std::all_of(processedFormulas.begin(), processedFormulas.end(), | ||
| [&](PTRef fla) { return fla == logic.getTerm_true(); })) { | ||
| return {}; | ||
| } | ||
|
|
||
| preprocessFormulaDoFinalTheoryPreprocessing(context); | ||
|
|
||
| for (PTRef & fla : processedFormulas) { | ||
| if (fla == logic.getTerm_true()) { continue; } | ||
| fla = preprocessFormulaAfterFinalTheoryPreprocessing(fla, context); | ||
| } | ||
|
|
||
| return processedFormulas; | ||
| } | ||
|
|
||
| PTRef MainSolver::preprocessFormula(PTRef fla, PreprocessingContext const & context) { | ||
| PTRef processed = preprocessFormulaBeforeFinalTheoryPreprocessing(fla, context); | ||
| preprocessFormulaDoFinalTheoryPreprocessing(context); | ||
| processed = preprocessFormulaAfterFinalTheoryPreprocessing(processed, context); | ||
| return processed; | ||
| } | ||
|
|
||
| PTRef MainSolver::preprocessFormulaBeforeFinalTheoryPreprocessing(PTRef fla, PreprocessingContext const & context) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's too big of a name... I see that there is a naming convention, but that can be a pain to use inside the code... Why not
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wanted to use sth. like that, but I do not like that What could potentially work is
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like your idea here! |
||
| bool const perPartition = context.perPartition; | ||
| PTRef processed = fla; | ||
|
|
||
| if (not perPartition) { | ||
| if (context.frameCount > 0) { processed = applyLearntSubstitutions(processed); } | ||
| processed = theory->preprocessBeforeSubstitutions(processed, context); | ||
| processed = substitutionPass(processed, context); | ||
| } | ||
|
|
||
| processed = theory->preprocessAfterSubstitutions(processed, context); | ||
|
|
||
| if (perPartition) { | ||
| pmanager.transferPartitionMembership(fla, processed); | ||
| } else if (logic.isFalse(processed)) { | ||
| return logic.getTerm_false(); | ||
| } | ||
|
|
||
| preprocessor.addPreprocessedFormula(processed); | ||
|
|
||
| return processed; | ||
| } | ||
|
|
||
| void MainSolver::preprocessFormulaDoFinalTheoryPreprocessing(PreprocessingContext const &) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is a function which calls one function, why not use original function call?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This way, it is clearer that this part must not be omitted. Without the auxiliary function, it could be missed. Besides, connecting the
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure I understand 🤔 Why would one assume this part can be ommited? It can also be highlighted by the comment in the code, what Can you elaborate on code duplication point? Because as I understand a single function function call is being replaced by a different function call + additional lines of code in |
||
| theory->afterPreprocessing(preprocessor.getPreprocessedFormulas()); | ||
| } | ||
|
|
||
| PTRef MainSolver::preprocessFormulaAfterFinalTheoryPreprocessing(PTRef fla, PreprocessingContext const & context) { | ||
| bool const perPartition = context.perPartition; | ||
| PTRef processed = fla; | ||
|
|
||
| assert(not perPartition or pmanager.getPartitionIndex(processed) != -1); | ||
|
|
||
| // Optimize the dag for cnfization | ||
| if (logic.isBooleanOperator(processed)) { | ||
| processed = rewriteMaxArity(processed); | ||
| if (perPartition) { pmanager.transferPartitionMembership(fla, processed); } | ||
| } | ||
|
|
||
| if (perPartition) { | ||
| assert(pmanager.getPartitionIndex(processed) != -1); | ||
| pmanager.propagatePartitionMask(processed); | ||
| } | ||
|
|
||
| return processed; | ||
| } | ||
|
|
||
| vec<PTRef> MainSolver::getCurrentAssertions() const { | ||
| vec<PTRef> assertions; | ||
| size_t const cnt = frames.frameCount(); | ||
|
|
@@ -316,11 +391,15 @@ sstat MainSolver::giveToSolver(PTRef root, FrameId push_id) { | |
| std::vector<vec<Lit>> clauses; | ||
| void operator()(vec<Lit> && c) override { clauses.push_back(std::move(c)); } | ||
| }; | ||
|
|
||
| if (root == logic.getTerm_true()) { return s_Undef; } | ||
|
|
||
| ClauseCallBack callBack; | ||
| ts.setClauseCallBack(&callBack); | ||
| ts.Cnfizer::cnfize(root, push_id); | ||
| bool const keepPartitionsSeparate = trackPartitions(); | ||
| Lit frameLit = push_id == 0 ? Lit{} : term_mapper->getOrCreateLit(frameTerms[push_id]); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not lambda?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To not use the variable at all if
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, wouldn't it get optimized by compiler? |
||
| Lit frameLit; | ||
| if (push_id != 0) { frameLit = term_mapper->getOrCreateLit(frameTerms[push_id]); } | ||
| int partitionIndex = keepPartitionsSeparate ? pmanager.getPartitionIndex(root) : -1; | ||
| for (auto & clause : callBack.clauses) { | ||
| if (push_id != 0) { clause.push(frameLit); } | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.