Skip to content

Commit acc1496

Browse files
Factor out property decider utilities
so that they can be reused across goto checker implementations and in unit tests.
1 parent 804efea commit acc1496

File tree

5 files changed

+125
-101
lines changed

5 files changed

+125
-101
lines changed

src/goto-checker/bmc_util.cpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ Author: Daniel Kroening, Peter Schrammel
3030
#include <util/make_unique.h>
3131
#include <util/ui_message.h>
3232

33+
#include "goto_symex_property_decider.h"
3334
#include "symex_bmc.h"
3435

3536
void message_building_error_trace(messaget &log)
@@ -358,3 +359,63 @@ void postprocess_equation(
358359
symex.validate(validation_modet::INVARIANT);
359360
}
360361
}
362+
363+
std::chrono::duration<double> prepare_property_decider(
364+
propertiest &properties,
365+
symex_target_equationt &equation,
366+
goto_symex_property_decidert &property_decider,
367+
ui_message_handlert &ui_message_handler)
368+
{
369+
auto solver_start = std::chrono::steady_clock::now();
370+
371+
messaget log(ui_message_handler);
372+
log.status() << "Passing problem to "
373+
<< property_decider.get_solver().decision_procedure_text()
374+
<< messaget::eom;
375+
376+
convert_symex_target_equation(
377+
equation, property_decider.get_solver(), ui_message_handler);
378+
property_decider.update_properties_goals_from_symex_target_equation(
379+
properties);
380+
property_decider.convert_goals();
381+
property_decider.freeze_goal_variables();
382+
383+
auto solver_stop = std::chrono::steady_clock::now();
384+
return std::chrono::duration<double>(solver_stop - solver_start);
385+
}
386+
387+
void run_property_decider(
388+
incremental_goto_checkert::resultt &result,
389+
propertiest &properties,
390+
goto_symex_property_decidert &property_decider,
391+
ui_message_handlert &ui_message_handler,
392+
std::chrono::duration<double> solver_runtime,
393+
bool set_pass)
394+
{
395+
auto solver_start = std::chrono::steady_clock::now();
396+
397+
messaget log(ui_message_handler);
398+
log.status() << "Running "
399+
<< property_decider.get_solver().decision_procedure_text()
400+
<< messaget::eom;
401+
402+
property_decider.add_constraint_from_goals(
403+
[&properties](const irep_idt &property_id) {
404+
return is_property_to_check(properties.at(property_id).status);
405+
});
406+
407+
decision_proceduret::resultt dec_result = property_decider.solve();
408+
409+
property_decider.update_properties_status_from_goals(
410+
properties, result.updated_properties, dec_result, set_pass);
411+
412+
auto solver_stop = std::chrono::steady_clock::now();
413+
solver_runtime += std::chrono::duration<double>(solver_stop - solver_start);
414+
log.status() << "Runtime decision procedure: " << solver_runtime.count()
415+
<< "s" << messaget::eom;
416+
417+
if(dec_result == decision_proceduret::resultt::D_SATISFIABLE)
418+
{
419+
result.progress = incremental_goto_checkert::resultt::progresst::FOUND_FAIL;
420+
}
421+
}

src/goto-checker/bmc_util.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,17 @@ Author: Daniel Kroening, Peter Schrammel
1212
#ifndef CPROVER_GOTO_CHECKER_BMC_UTIL_H
1313
#define CPROVER_GOTO_CHECKER_BMC_UTIL_H
1414

15+
#include <chrono>
1516
#include <memory>
1617

1718
#include <goto-programs/safety_checker.h>
1819
#include <goto-symex/build_goto_trace.h>
1920
#include <goto-symex/path_storage.h>
2021

22+
#include "incremental_goto_checker.h"
2123
#include "properties.h"
2224

25+
class goto_symex_property_decidert;
2326
class goto_tracet;
2427
class memory_model_baset;
2528
class message_handlert;
@@ -136,6 +139,39 @@ void update_status_of_unknown_properties(
136139
propertiest &properties,
137140
std::unordered_set<irep_idt> &updated_properties);
138141

142+
/// Converts the equation and sets up the property decider,
143+
/// but does not call solve.
144+
/// \param [in,out] properties: Sets the status of properties to be checked to
145+
/// UNKNOWN
146+
/// \param [in,out] equation: The equation that will be converted
147+
/// \param [in,out] property_decider: The property decider that we are going to
148+
/// set up
149+
/// \param [in,out] ui_message_handler: For logging
150+
/// \return The runtime for converting the equation
151+
std::chrono::duration<double> prepare_property_decider(
152+
propertiest &properties,
153+
symex_target_equationt &equation,
154+
goto_symex_property_decidert &property_decider,
155+
ui_message_handlert &ui_message_handler);
156+
157+
/// Runs the property decider to solve the equation
158+
/// \param [in,out] result: For recording the progress and the updated
159+
/// properties
160+
/// \param [in,out] properties: The status will be updated
161+
/// \param [in,out] property_decider: The property decider that will solve the
162+
/// equation
163+
/// \param [in,out] ui_message_handler: For logging
164+
/// \param solver_runtime: The solver runtime will be added and output
165+
/// \param set_pass: If true then update UNKNOWN properties to PASS
166+
/// if the solver returns UNSATISFIABLE
167+
void run_property_decider(
168+
incremental_goto_checkert::resultt &result,
169+
propertiest &properties,
170+
goto_symex_property_decidert &property_decider,
171+
ui_message_handlert &ui_message_handler,
172+
std::chrono::duration<double> solver_runtime,
173+
bool set_pass = true);
174+
139175
// clang-format off
140176
#define OPT_BMC \
141177
"(program-only)" \

src/goto-checker/multi_path_symex_checker.cpp

Lines changed: 4 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -65,51 +65,18 @@ operator()(propertiest &properties)
6565
if(!has_properties_to_check(properties))
6666
return result;
6767

68-
log.status() << "Passing problem to "
69-
<< property_decider.get_solver().decision_procedure_text()
70-
<< messaget::eom;
71-
72-
const auto solver_start = std::chrono::steady_clock::now();
73-
74-
convert_symex_target_equation(
75-
equation, property_decider.get_solver(), ui_message_handler);
76-
property_decider.update_properties_goals_from_symex_target_equation(
77-
properties);
78-
property_decider.convert_goals();
79-
property_decider.freeze_goal_variables();
68+
solver_runtime += prepare_property_decider(
69+
properties, equation, property_decider, ui_message_handler);
8070

8171
if(options.get_bool_option("localize-faults"))
8272
freeze_guards(equation, property_decider.get_solver());
8373

84-
const auto solver_stop = std::chrono::steady_clock::now();
85-
solver_runtime += std::chrono::duration<double>(solver_stop - solver_start);
86-
87-
log.status() << "Running "
88-
<< property_decider.get_solver().decision_procedure_text()
89-
<< messaget::eom;
9074
equation_generated = true;
9175
}
9276

93-
const auto solver_start = std::chrono::steady_clock::now();
94-
95-
property_decider.add_constraint_from_goals(
96-
[&properties](const irep_idt &property_id) {
97-
return is_property_to_check(properties.at(property_id).status);
98-
});
99-
100-
decision_proceduret::resultt dec_result = property_decider.solve();
101-
102-
property_decider.update_properties_status_from_goals(
103-
properties, result.updated_properties, dec_result);
104-
105-
const auto solver_stop = std::chrono::steady_clock::now();
106-
solver_runtime += std::chrono::duration<double>(solver_stop - solver_start);
107-
log.status() << "Runtime decision procedure: " << solver_runtime.count()
108-
<< "s" << messaget::eom;
77+
run_property_decider(
78+
result, properties, property_decider, ui_message_handler, solver_runtime);
10979

110-
result.progress = dec_result == decision_proceduret::resultt::D_SATISFIABLE
111-
? resultt::progresst::FOUND_FAIL
112-
: resultt::progresst::DONE;
11380
return result;
11481
}
11582

src/goto-checker/single_path_symex_checker.cpp

Lines changed: 24 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,14 @@ operator()(propertiest &properties)
3333
// There might be more solutions from the previous equation.
3434
if(property_decider)
3535
{
36-
decide(result, properties);
36+
run_property_decider(
37+
result,
38+
properties,
39+
*property_decider,
40+
ui_message_handler,
41+
std::chrono::duration<double>(0),
42+
false);
43+
3744
if(result.progress == resultt::progresst::FOUND_FAIL)
3845
return result;
3946
}
@@ -91,8 +98,22 @@ operator()(propertiest &properties)
9198

9299
if(symex.get_remaining_vccs() > 0)
93100
{
94-
prepare(result, properties, resume.equation);
95-
decide(result, properties);
101+
update_properties_status_from_symex_target_equation(
102+
properties, result.updated_properties, resume.equation);
103+
104+
property_decider = util_make_unique<goto_symex_property_decidert>(
105+
options, ui_message_handler, resume.equation, ns);
106+
107+
const auto solver_runtime = prepare_property_decider(
108+
properties, resume.equation, *property_decider, ui_message_handler);
109+
110+
run_property_decider(
111+
result,
112+
properties,
113+
*property_decider,
114+
ui_message_handler,
115+
solver_runtime,
116+
false);
96117

97118
if(result.progress == resultt::progresst::FOUND_FAIL)
98119
return result;
@@ -175,58 +196,3 @@ void single_path_symex_checkert::output_proof()
175196
const path_storaget::patht &resume = worklist->peek();
176197
output_graphml(resume.equation, ns, options);
177198
}
178-
179-
void single_path_symex_checkert::prepare(
180-
resultt &result,
181-
propertiest &properties,
182-
symex_target_equationt &equation)
183-
{
184-
update_properties_status_from_symex_target_equation(
185-
properties, result.updated_properties, equation);
186-
187-
property_decider = util_make_unique<goto_symex_property_decidert>(
188-
options, ui_message_handler, equation, ns);
189-
190-
log.status() << "Passing problem to "
191-
<< property_decider->get_solver().decision_procedure_text()
192-
<< messaget::eom;
193-
194-
convert_symex_target_equation(
195-
equation, property_decider->get_solver(), ui_message_handler);
196-
property_decider->update_properties_goals_from_symex_target_equation(
197-
properties);
198-
property_decider->convert_goals();
199-
property_decider->freeze_goal_variables();
200-
}
201-
202-
void single_path_symex_checkert::decide(
203-
resultt &result,
204-
propertiest &properties)
205-
{
206-
auto solver_start = std::chrono::steady_clock::now();
207-
208-
log.status() << "Running "
209-
<< property_decider->get_solver().decision_procedure_text()
210-
<< messaget::eom;
211-
212-
property_decider->add_constraint_from_goals(
213-
[&properties](const irep_idt &property_id) {
214-
return is_property_to_check(properties.at(property_id).status);
215-
});
216-
217-
decision_proceduret::resultt dec_result = property_decider->solve();
218-
219-
property_decider->update_properties_status_from_goals(
220-
properties, result.updated_properties, dec_result, false);
221-
222-
auto solver_stop = std::chrono::steady_clock::now();
223-
log.status()
224-
<< "Runtime decision procedure: "
225-
<< std::chrono::duration<double>(solver_stop - solver_start).count() << "s"
226-
<< messaget::eom;
227-
228-
if(dec_result == decision_proceduret::resultt::D_SATISFIABLE)
229-
{
230-
result.progress = resultt::progresst::FOUND_FAIL;
231-
}
232-
}

src/goto-checker/single_path_symex_checker.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,6 @@ class single_path_symex_checkert : public single_path_symex_only_checkert,
4747
protected:
4848
bool symex_initialized = false;
4949
std::unique_ptr<goto_symex_property_decidert> property_decider;
50-
51-
void prepare(
52-
resultt &result,
53-
propertiest &properties,
54-
symex_target_equationt &equation);
55-
void decide(resultt &result, propertiest &properties);
5650
};
5751

5852
#endif // CPROVER_GOTO_CHECKER_SINGLE_PATH_SYMEX_CHECKER_H

0 commit comments

Comments
 (0)