Skip to content

Commit f6ad64c

Browse files
committed
Split simplifyFormulas to sub-functions
This makes the preprocessing more maintainable, allows overriding particular parts and also allows preprocessing single formulas without necessarily giving them to the SMT solver
1 parent a320bc0 commit f6ad64c

File tree

2 files changed

+116
-44
lines changed

2 files changed

+116
-44
lines changed

src/api/MainSolver.cc

Lines changed: 108 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -213,68 +213,130 @@ Lit MainSolver::giveAnyDecisionPreferenceToSMTSolver(PTRef pref, FrameId frameId
213213

214214
sstat MainSolver::simplifyFormulas() {
215215
status = s_Undef;
216-
for (std::size_t i = firstNotSimplifiedFrame; i < frames.frameCount() && status != s_False; i++) {
216+
for (std::size_t i = firstNotSimplifiedFrame; i < frames.frameCount(); ++i) {
217+
auto & frame = frames[i];
218+
FrameId const frameId = frame.getId();
217219
PreprocessingContext context{.frameCount = i, .perPartition = trackPartitions()};
218220
preprocessor.prepareForProcessingFrame(i);
219221
firstNotSimplifiedFrame = i + 1;
220-
if (context.perPartition) {
221-
vec<PTRef> frameFormulas;
222-
for (PTRef fla : frames[i].formulas) {
223-
PTRef processed = theory->preprocessAfterSubstitutions(fla, context);
224-
pmanager.transferPartitionMembership(fla, processed);
225-
frameFormulas.push(processed);
226-
preprocessor.addPreprocessedFormula(processed);
227-
}
228-
if (frameFormulas.size() == 0 or std::all_of(frameFormulas.begin(), frameFormulas.end(),
229-
[&](PTRef fla) { return fla == logic.getTerm_true(); })) {
230-
continue;
231-
}
232-
theory->afterPreprocessing(preprocessor.getPreprocessedFormulas());
233-
assert(frameFormulas.size() == frames[i].formulas.size());
234-
for (PTRef & fla : frameFormulas) {
235-
if (fla == logic.getTerm_true()) { continue; }
236-
assert(pmanager.getPartitionIndex(fla) != -1);
237-
// Optimize the dag for cnfization
238-
if (logic.isBooleanOperator(fla)) {
239-
PTRef old = fla;
240-
fla = rewriteMaxArity(fla);
241-
pmanager.transferPartitionMembership(old, fla);
242-
}
243-
assert(pmanager.getPartitionIndex(fla) != -1);
244-
pmanager.propagatePartitionMask(fla);
245-
status = giveToSolver(fla, frames[i].getId());
246-
if (status == s_False) { break; }
247-
}
222+
223+
if (not context.perPartition) {
224+
PTRef frameFormula = preprocessFormulasDefault(frame.formulas, context);
225+
status = giveToSolver(frameFormula, frameId);
248226
} else {
249-
PTRef frameFormula = logic.mkAnd(frames[i].formulas);
250-
if (context.frameCount > 0) { frameFormula = applyLearntSubstitutions(frameFormula); }
251-
frameFormula = theory->preprocessBeforeSubstitutions(frameFormula, context);
252-
frameFormula = substitutionPass(frameFormula, context);
253-
frameFormula = theory->preprocessAfterSubstitutions(frameFormula, context);
254-
255-
if (logic.isFalse(frameFormula)) {
256-
giveToSolver(logic.getTerm_false(), frames[i].getId());
257-
status = s_False;
258-
break;
227+
vec<PTRef> processedFormulas = preprocessFormulasPerPartition(frame.formulas, context);
228+
for (PTRef fla : processedFormulas) {
229+
status = giveToSolver(fla, frameId);
230+
if (status == s_False) { break; }
259231
}
260-
preprocessor.addPreprocessedFormula(frameFormula);
261-
theory->afterPreprocessing(preprocessor.getPreprocessedFormulas());
262-
// Optimize the dag for cnfization
263-
if (logic.isBooleanOperator(frameFormula)) { frameFormula = rewriteMaxArity(frameFormula); }
264-
status = giveToSolver(frameFormula, frames[i].getId());
265232
}
233+
if (status == s_False) { break; }
266234

267235
for (PTRef pref : decisionPreferences.scope(i)) {
268236
giveDecisionPreferenceToSMTSolver(pref, frames[i].getId());
269237
}
270238
}
239+
271240
if (status == s_False) {
272241
assert(firstNotSimplifiedFrame > 0);
273242
rememberUnsatFrame(firstNotSimplifiedFrame - 1);
274243
}
244+
275245
return status;
276246
}
277247

248+
PTRef MainSolver::preprocessFormulasDefault(vec<PTRef> const & frameFormulas, PreprocessingContext const & context) {
249+
assert(not context.perPartition);
250+
251+
if (frameFormulas.size() == 0) { return logic.getTerm_true(); }
252+
253+
PTRef frameFormula = logic.mkAnd(frameFormulas);
254+
return preprocessFormula(frameFormula, context);
255+
}
256+
257+
vec<PTRef> MainSolver::preprocessFormulasPerPartition(vec<PTRef> const & frameFormulas,
258+
PreprocessingContext const & context) {
259+
assert(context.perPartition);
260+
261+
if (frameFormulas.size() == 0) { return {}; }
262+
263+
vec<PTRef> processedFormulas;
264+
for (PTRef fla : frameFormulas) {
265+
PTRef processed = preprocessFormulaBeforeFinalTheoryPreprocessing(fla, context);
266+
processedFormulas.push(processed);
267+
}
268+
269+
assert(processedFormulas.size() == frameFormulas.size());
270+
assert(processedFormulas.size() > 0);
271+
if (std::all_of(processedFormulas.begin(), processedFormulas.end(),
272+
[&](PTRef fla) { return fla == logic.getTerm_true(); })) {
273+
return {};
274+
}
275+
276+
preprocessFormulaDoFinalTheoryPreprocessing(context);
277+
278+
for (PTRef & fla : processedFormulas) {
279+
if (fla == logic.getTerm_true()) { continue; }
280+
fla = preprocessFormulaAfterFinalTheoryPreprocessing(fla, context);
281+
}
282+
283+
return processedFormulas;
284+
}
285+
286+
PTRef MainSolver::preprocessFormula(PTRef fla, PreprocessingContext const & context) {
287+
PTRef processed = preprocessFormulaBeforeFinalTheoryPreprocessing(fla, context);
288+
preprocessFormulaDoFinalTheoryPreprocessing(context);
289+
processed = preprocessFormulaAfterFinalTheoryPreprocessing(processed, context);
290+
return processed;
291+
}
292+
293+
PTRef MainSolver::preprocessFormulaBeforeFinalTheoryPreprocessing(PTRef fla, PreprocessingContext const & context) {
294+
bool const perPartition = context.perPartition;
295+
PTRef processed = fla;
296+
297+
if (not perPartition) {
298+
if (context.frameCount > 0) { processed = applyLearntSubstitutions(processed); }
299+
processed = theory->preprocessBeforeSubstitutions(processed, context);
300+
processed = substitutionPass(processed, context);
301+
}
302+
303+
processed = theory->preprocessAfterSubstitutions(processed, context);
304+
305+
if (perPartition) {
306+
pmanager.transferPartitionMembership(fla, processed);
307+
} else if (logic.isFalse(processed)) {
308+
return logic.getTerm_false();
309+
}
310+
311+
preprocessor.addPreprocessedFormula(processed);
312+
313+
return processed;
314+
}
315+
316+
void MainSolver::preprocessFormulaDoFinalTheoryPreprocessing(PreprocessingContext const &) {
317+
theory->afterPreprocessing(preprocessor.getPreprocessedFormulas());
318+
}
319+
320+
PTRef MainSolver::preprocessFormulaAfterFinalTheoryPreprocessing(PTRef fla, PreprocessingContext const & context) {
321+
bool const perPartition = context.perPartition;
322+
PTRef processed = fla;
323+
324+
assert(not perPartition or pmanager.getPartitionIndex(processed) != -1);
325+
326+
// Optimize the dag for cnfization
327+
if (logic.isBooleanOperator(processed)) {
328+
processed = rewriteMaxArity(processed);
329+
if (perPartition) { pmanager.transferPartitionMembership(fla, processed); }
330+
}
331+
332+
if (perPartition) {
333+
assert(pmanager.getPartitionIndex(processed) != -1);
334+
pmanager.propagatePartitionMask(processed);
335+
}
336+
337+
return processed;
338+
}
339+
278340
vec<PTRef> MainSolver::getCurrentAssertions() const {
279341
vec<PTRef> assertions;
280342
size_t const cnt = frames.frameCount();
@@ -390,6 +452,8 @@ sstat MainSolver::giveToSolver(PTRef root, FrameId push_id) {
390452
void operator()(vec<Lit> && c) override { clauses.push_back(std::move(c)); }
391453
};
392454

455+
if (root == logic.getTerm_true()) { return s_Undef; }
456+
393457
ClauseCallBack callBack;
394458
ts.setClauseCallBack(&callBack);
395459
ts.Cnfizer::cnfize(root, push_id);

src/api/MainSolver.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,14 @@ class MainSolver {
300300
Lit giveBoolVarDecisionPreferenceToSMTSolver(PTRef);
301301
Lit giveAnyDecisionPreferenceToSMTSolver(PTRef, FrameId);
302302

303+
virtual PTRef preprocessFormulasDefault(vec<PTRef> const & frameFormulas, PreprocessingContext const &);
304+
virtual vec<PTRef> preprocessFormulasPerPartition(vec<PTRef> const & frameFormulas, PreprocessingContext const &);
305+
306+
virtual PTRef preprocessFormula(PTRef, PreprocessingContext const &);
307+
virtual PTRef preprocessFormulaBeforeFinalTheoryPreprocessing(PTRef, PreprocessingContext const &);
308+
virtual void preprocessFormulaDoFinalTheoryPreprocessing(PreprocessingContext const &);
309+
virtual PTRef preprocessFormulaAfterFinalTheoryPreprocessing(PTRef, PreprocessingContext const &);
310+
303311
PTRef rewriteMaxArity(PTRef root);
304312

305313
virtual sstat solve_(vec<FrameId> const & enabledFrames);

0 commit comments

Comments
 (0)