Skip to content

Commit e575257

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 Also added `preprocess` as an alias to `simplifyFormulas`
1 parent 94b8573 commit e575257

File tree

2 files changed

+121
-44
lines changed

2 files changed

+121
-44
lines changed

src/api/MainSolver.cc

Lines changed: 111 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -140,63 +140,126 @@ bool MainSolver::tryAddTermNameFor(PTRef fla, std::string const & name) {
140140

141141
sstat MainSolver::simplifyFormulas() {
142142
status = s_Undef;
143-
for (std::size_t i = firstNotSimplifiedFrame; i < frames.frameCount() && status != s_False; i++) {
143+
for (std::size_t i = firstNotSimplifiedFrame; i < frames.frameCount(); ++i) {
144+
auto & frame = frames[i];
145+
FrameId const frameId = frame.getId();
144146
PreprocessingContext context{.frameCount = i, .perPartition = trackPartitions()};
145147
preprocessor.prepareForProcessingFrame(i);
146148
firstNotSimplifiedFrame = i + 1;
147-
if (context.perPartition) {
148-
vec<PTRef> frameFormulas;
149-
for (PTRef fla : frames[i].formulas) {
150-
PTRef processed = theory->preprocessAfterSubstitutions(fla, context);
151-
pmanager.transferPartitionMembership(fla, processed);
152-
frameFormulas.push(processed);
153-
preprocessor.addPreprocessedFormula(processed);
154-
}
155-
if (frameFormulas.size() == 0 or std::all_of(frameFormulas.begin(), frameFormulas.end(),
156-
[&](PTRef fla) { return fla == logic.getTerm_true(); })) {
157-
continue;
158-
}
159-
theory->afterPreprocessing(preprocessor.getPreprocessedFormulas());
160-
for (PTRef fla : frameFormulas) {
161-
if (fla == logic.getTerm_true()) { continue; }
162-
assert(pmanager.getPartitionIndex(fla) != -1);
163-
// Optimize the dag for cnfization
164-
if (logic.isBooleanOperator(fla)) {
165-
PTRef old = fla;
166-
fla = rewriteMaxArity(fla);
167-
pmanager.transferPartitionMembership(old, fla);
168-
}
169-
assert(pmanager.getPartitionIndex(fla) != -1);
170-
pmanager.propagatePartitionMask(fla);
171-
status = giveToSolver(fla, frames[i].getId());
172-
if (status == s_False) { break; }
173-
}
149+
150+
if (not context.perPartition) {
151+
PTRef frameFormula = preprocessFormulasDefault(frame.formulas, context);
152+
status = giveToSolver(frameFormula, frameId);
174153
} else {
175-
PTRef frameFormula = logic.mkAnd(frames[i].formulas);
176-
if (context.frameCount > 0) { frameFormula = applyLearntSubstitutions(frameFormula); }
177-
frameFormula = theory->preprocessBeforeSubstitutions(frameFormula, context);
178-
frameFormula = substitutionPass(frameFormula, context);
179-
frameFormula = theory->preprocessAfterSubstitutions(frameFormula, context);
180-
181-
if (logic.isFalse(frameFormula)) {
182-
giveToSolver(logic.getTerm_false(), frames[i].getId());
183-
status = s_False;
184-
break;
154+
vec<PTRef> processedFormulas = preprocessFormulasPerPartition(frame.formulas, context);
155+
for (PTRef fla : processedFormulas) {
156+
status = giveToSolver(fla, frameId);
157+
if (status == s_False) { break; }
185158
}
186-
preprocessor.addPreprocessedFormula(frameFormula);
187-
theory->afterPreprocessing(preprocessor.getPreprocessedFormulas());
188-
// Optimize the dag for cnfization
189-
if (logic.isBooleanOperator(frameFormula)) { frameFormula = rewriteMaxArity(frameFormula); }
190-
status = giveToSolver(frameFormula, frames[i].getId());
191159
}
160+
if (status == s_False) { break; }
192161
}
162+
193163
if (status == s_False) {
194164
assert(firstNotSimplifiedFrame > 0);
195165
rememberUnsatFrame(firstNotSimplifiedFrame - 1);
196166
}
167+
197168
return status;
198169
}
199170

171+
PTRef MainSolver::preprocessFormulasDefault(vec<PTRef> const & frameFormulas, PreprocessingContext const & context) {
172+
assert(not context.perPartition);
173+
174+
if (frameFormulas.size() == 0) { return logic.getTerm_true(); }
175+
176+
PTRef frameFormula = logic.mkAnd(frameFormulas);
177+
return preprocessFormula(frameFormula, context);
178+
}
179+
180+
vec<PTRef> MainSolver::preprocessFormulasPerPartition(vec<PTRef> const & frameFormulas,
181+
PreprocessingContext const & context) {
182+
assert(context.perPartition);
183+
184+
if (frameFormulas.size() == 0) { return {}; }
185+
186+
vec<PTRef> processedFormulas;
187+
for (PTRef fla : frameFormulas) {
188+
PTRef processed = preprocessFormulaBeforeFinalTheoryPreprocessing(fla, context);
189+
processedFormulas.push(processed);
190+
}
191+
192+
assert(processedFormulas.size() == frameFormulas.size());
193+
assert(processedFormulas.size() > 0);
194+
if (std::all_of(processedFormulas.begin(), processedFormulas.end(),
195+
[&](PTRef fla) { return fla == logic.getTerm_true(); })) {
196+
return {};
197+
}
198+
199+
preprocessFormulaDoFinalTheoryPreprocessing(context);
200+
201+
for (PTRef & fla : processedFormulas) {
202+
if (fla == logic.getTerm_true()) { continue; }
203+
fla = preprocessFormulaAfterFinalTheoryPreprocessing(fla, context);
204+
}
205+
206+
return processedFormulas;
207+
}
208+
209+
PTRef MainSolver::preprocessFormula(PTRef fla, PreprocessingContext const & context) {
210+
PTRef processed = preprocessFormulaBeforeFinalTheoryPreprocessing(fla, context);
211+
preprocessFormulaDoFinalTheoryPreprocessing(context);
212+
processed = preprocessFormulaAfterFinalTheoryPreprocessing(processed, context);
213+
return processed;
214+
}
215+
216+
PTRef MainSolver::preprocessFormulaBeforeFinalTheoryPreprocessing(PTRef fla, PreprocessingContext const & context) {
217+
bool const perPartition = context.perPartition;
218+
PTRef processed = fla;
219+
220+
if (not perPartition) {
221+
if (context.frameCount > 0) { processed = applyLearntSubstitutions(processed); }
222+
processed = theory->preprocessBeforeSubstitutions(processed, context);
223+
processed = substitutionPass(processed, context);
224+
}
225+
226+
processed = theory->preprocessAfterSubstitutions(processed, context);
227+
228+
if (perPartition) {
229+
pmanager.transferPartitionMembership(fla, processed);
230+
} else if (logic.isFalse(processed)) {
231+
return logic.getTerm_false();
232+
}
233+
234+
preprocessor.addPreprocessedFormula(processed);
235+
236+
return processed;
237+
}
238+
239+
void MainSolver::preprocessFormulaDoFinalTheoryPreprocessing(PreprocessingContext const &) {
240+
theory->afterPreprocessing(preprocessor.getPreprocessedFormulas());
241+
}
242+
243+
PTRef MainSolver::preprocessFormulaAfterFinalTheoryPreprocessing(PTRef fla, PreprocessingContext const & context) {
244+
bool const perPartition = context.perPartition;
245+
PTRef processed = fla;
246+
247+
assert(not perPartition or pmanager.getPartitionIndex(processed) != -1);
248+
249+
// Optimize the dag for cnfization
250+
if (logic.isBooleanOperator(processed)) {
251+
processed = rewriteMaxArity(processed);
252+
if (perPartition) { pmanager.transferPartitionMembership(fla, processed); }
253+
}
254+
255+
if (perPartition) {
256+
assert(pmanager.getPartitionIndex(processed) != -1);
257+
pmanager.propagatePartitionMask(processed);
258+
}
259+
260+
return processed;
261+
}
262+
200263
vec<PTRef> MainSolver::getCurrentAssertions() const {
201264
vec<PTRef> assertions;
202265
size_t const cnt = frames.frameCount();
@@ -316,11 +379,15 @@ sstat MainSolver::giveToSolver(PTRef root, FrameId push_id) {
316379
std::vector<vec<Lit>> clauses;
317380
void operator()(vec<Lit> && c) override { clauses.push_back(std::move(c)); }
318381
};
382+
383+
if (root == logic.getTerm_true()) { return s_Undef; }
384+
319385
ClauseCallBack callBack;
320386
ts.setClauseCallBack(&callBack);
321387
ts.Cnfizer::cnfize(root, push_id);
322388
bool const keepPartitionsSeparate = trackPartitions();
323-
Lit frameLit = push_id == 0 ? Lit{} : term_mapper->getOrCreateLit(frameTerms[push_id]);
389+
Lit frameLit;
390+
if (push_id != 0) { frameLit = term_mapper->getOrCreateLit(frameTerms[push_id]); }
324391
int partitionIndex = keepPartitionsSeparate ? pmanager.getPartitionIndex(root) : -1;
325392
for (auto & clause : callBack.clauses) {
326393
if (push_id != 0) { clause.push(frameLit); }

src/api/MainSolver.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ class MainSolver {
105105
// Simplify formulas until all are simplified or the instance is detected unsat
106106
// Skip assertion levels that have already been simplified
107107
sstat simplifyFormulas();
108+
// Alias for `simplifyFormulas`, reserved for future use
109+
sstat preprocess() { return simplifyFormulas(); }
108110

109111
[[nodiscard]] sstat getStatus() const { return status; }
110112

@@ -289,6 +291,14 @@ class MainSolver {
289291

290292
inline bool trackPartitions() const;
291293

294+
virtual PTRef preprocessFormulasDefault(vec<PTRef> const & frameFormulas, PreprocessingContext const &);
295+
virtual vec<PTRef> preprocessFormulasPerPartition(vec<PTRef> const & frameFormulas, PreprocessingContext const &);
296+
297+
virtual PTRef preprocessFormula(PTRef, PreprocessingContext const &);
298+
virtual PTRef preprocessFormulaBeforeFinalTheoryPreprocessing(PTRef, PreprocessingContext const &);
299+
virtual void preprocessFormulaDoFinalTheoryPreprocessing(PreprocessingContext const &);
300+
virtual PTRef preprocessFormulaAfterFinalTheoryPreprocessing(PTRef, PreprocessingContext const &);
301+
292302
PTRef rewriteMaxArity(PTRef root);
293303

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

0 commit comments

Comments
 (0)