Skip to content

Commit 387834c

Browse files
Merge pull request #3565 from peterschrammel/factor-out-bmc-utils
Rip out the heart of bmct [depends: 3557, blocks: 3578, 3580, 3581]
2 parents 30e5339 + c343989 commit 387834c

File tree

9 files changed

+391
-275
lines changed

9 files changed

+391
-275
lines changed

src/cbmc/all_properties.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ Author: Daniel Kroening, kroening@kroening.com
1414
#include <algorithm>
1515
#include <chrono>
1616

17+
#include <goto-checker/bmc_util.h>
18+
1719
#include <util/xml.h>
1820
#include <util/json.h>
1921

@@ -55,7 +57,9 @@ safety_checkert::resultt bmc_all_propertiest::operator()()
5557

5658
auto solver_start=std::chrono::steady_clock::now();
5759

58-
bmc.do_conversion();
60+
convert_symex_target_equation(
61+
bmc.equation, bmc.prop_conv, get_message_handler());
62+
bmc.freeze_program_variables();
5963

6064
// Collect _all_ goals in `goal_map'.
6165
// This maps property IDs to 'goalt'
@@ -144,9 +148,9 @@ safety_checkert::resultt bmc_all_propertiest::operator()()
144148
bool safe=(cover_goals.number_covered()==0);
145149

146150
if(safe)
147-
bmc.report_success(); // legacy, might go away
151+
report_success(bmc.ui_message_handler); // legacy, might go away
148152
else
149-
bmc.report_failure(); // legacy, might go away
153+
report_failure(bmc.ui_message_handler); // legacy, might go away
150154

151155
return safe?safety_checkert::resultt::SAFE:safety_checkert::resultt::UNSAFE;
152156
}

src/cbmc/bmc.cpp

Lines changed: 19 additions & 252 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,12 @@ Author: Daniel Kroening, kroening@kroening.com
1919

2020
#include <langapi/language_util.h>
2121

22-
#include <goto-programs/graphml_witness.h>
23-
#include <goto-programs/json_goto_trace.h>
24-
#include <goto-programs/xml_goto_trace.h>
25-
26-
#include <goto-symex/build_goto_trace.h>
27-
#include <goto-symex/memory_model_pso.h>
2822
#include <goto-symex/show_program.h>
2923
#include <goto-symex/show_vcc.h>
30-
#include <goto-symex/slice.h>
31-
#include <goto-symex/slice_by_trace.h>
3224

3325
#include <linking/static_lifetime_init.h>
3426

27+
#include <goto-checker/bmc_util.h>
3528
#include <goto-checker/solver_factory.h>
3629

3730
#include "counterexample_beautification.h"
@@ -48,84 +41,6 @@ void bmct::freeze_program_variables()
4841
// this is a hook for cegis
4942
}
5043

51-
void bmct::error_trace()
52-
{
53-
status() << "Building error trace" << eom;
54-
55-
goto_tracet &goto_trace=safety_checkert::error_trace;
56-
build_goto_trace(equation, prop_conv, ns, goto_trace);
57-
58-
switch(ui_message_handler.get_ui())
59-
{
60-
case ui_message_handlert::uit::PLAIN:
61-
result() << "Counterexample:" << eom;
62-
show_goto_trace(result(), ns, goto_trace, trace_options());
63-
result() << eom;
64-
break;
65-
66-
case ui_message_handlert::uit::XML_UI:
67-
{
68-
xmlt xml;
69-
convert(ns, goto_trace, xml);
70-
status() << xml;
71-
}
72-
break;
73-
74-
case ui_message_handlert::uit::JSON_UI:
75-
{
76-
if(status().tellp() > 0)
77-
status() << eom; // force end of previous message
78-
json_stream_objectt &json_result =
79-
ui_message_handler.get_json_stream().push_back_stream_object();
80-
const goto_trace_stept &step=goto_trace.steps.back();
81-
json_result["property"] =
82-
json_stringt(step.pc->source_location.get_property_id());
83-
json_result["description"] =
84-
json_stringt(step.pc->source_location.get_comment());
85-
json_result["status"]=json_stringt("failed");
86-
json_stream_arrayt &json_trace =
87-
json_result.push_back_stream_array("trace");
88-
convert<json_stream_arrayt>(ns, goto_trace, json_trace, trace_options());
89-
}
90-
break;
91-
}
92-
}
93-
94-
/// outputs witnesses in graphml format
95-
void bmct::output_graphml(resultt result)
96-
{
97-
const std::string graphml=options.get_option("graphml-witness");
98-
if(graphml.empty())
99-
return;
100-
101-
graphml_witnesst graphml_witness(ns);
102-
if(result==resultt::UNSAFE)
103-
graphml_witness(safety_checkert::error_trace);
104-
else if(result==resultt::SAFE)
105-
graphml_witness(equation);
106-
else
107-
return;
108-
109-
if(graphml=="-")
110-
write_graphml(graphml_witness.graph(), std::cout);
111-
else
112-
{
113-
std::ofstream out(graphml);
114-
write_graphml(graphml_witness.graph(), out);
115-
}
116-
}
117-
118-
void bmct::do_conversion()
119-
{
120-
status() << "converting SSA" << eom;
121-
122-
// convert SSA
123-
equation.convert(prop_conv);
124-
125-
// hook for cegis to freeze synthesis program vars
126-
freeze_program_variables();
127-
}
128-
12944
decision_proceduret::resultt bmct::run_decision_procedure()
13045
{
13146
status() << "Passing problem to "
@@ -135,7 +50,10 @@ decision_proceduret::resultt bmct::run_decision_procedure()
13550

13651
auto solver_start = std::chrono::steady_clock::now();
13752

138-
do_conversion();
53+
convert_symex_target_equation(equation, prop_conv, get_message_handler());
54+
55+
// hook for cegis to freeze synthesis program vars
56+
freeze_program_variables();
13957

14058
status() << "Running " << prop_conv.decision_procedure_text() << eom;
14159

@@ -151,103 +69,6 @@ decision_proceduret::resultt bmct::run_decision_procedure()
15169
return dec_result;
15270
}
15371

154-
void bmct::report_success()
155-
{
156-
report_success(*this, ui_message_handler);
157-
}
158-
159-
void bmct::report_success(messaget &log, ui_message_handlert &handler)
160-
{
161-
log.result() << log.bold << "VERIFICATION SUCCESSFUL" << log.reset << log.eom;
162-
163-
switch(handler.get_ui())
164-
{
165-
case ui_message_handlert::uit::PLAIN:
166-
break;
167-
168-
case ui_message_handlert::uit::XML_UI:
169-
{
170-
xmlt xml("cprover-status");
171-
xml.data="SUCCESS";
172-
log.result() << xml;
173-
}
174-
break;
175-
176-
case ui_message_handlert::uit::JSON_UI:
177-
{
178-
json_objectt json_result({{"cProverStatus", json_stringt("success")}});
179-
log.result() << json_result;
180-
}
181-
break;
182-
}
183-
}
184-
185-
void bmct::report_failure()
186-
{
187-
report_failure(*this, ui_message_handler);
188-
}
189-
190-
void bmct::report_failure(messaget &log, ui_message_handlert &handler)
191-
{
192-
log.result() << log.bold << "VERIFICATION FAILED" << log.reset << log.eom;
193-
194-
switch(handler.get_ui())
195-
{
196-
case ui_message_handlert::uit::PLAIN:
197-
break;
198-
199-
case ui_message_handlert::uit::XML_UI:
200-
{
201-
xmlt xml("cprover-status");
202-
xml.data="FAILURE";
203-
log.result() << xml;
204-
}
205-
break;
206-
207-
case ui_message_handlert::uit::JSON_UI:
208-
{
209-
json_objectt json_result({{"cProverStatus", json_stringt("failure")}});
210-
log.result() << json_result;
211-
}
212-
break;
213-
}
214-
}
215-
216-
void bmct::get_memory_model()
217-
{
218-
const std::string mm=options.get_option("mm");
219-
220-
if(mm.empty() || mm=="sc")
221-
memory_model=util_make_unique<memory_model_sct>(ns);
222-
else if(mm=="tso")
223-
memory_model=util_make_unique<memory_model_tsot>(ns);
224-
else if(mm=="pso")
225-
memory_model=util_make_unique<memory_model_psot>(ns);
226-
else
227-
{
228-
throw invalid_command_line_argument_exceptiont(
229-
"invalid parameter " + mm, "--mm", "try values of sc, tso, pso");
230-
}
231-
}
232-
233-
void bmct::setup()
234-
{
235-
get_memory_model();
236-
237-
{
238-
const symbolt *init_symbol;
239-
if(!ns.lookup(INITIALIZE_FUNCTION, init_symbol))
240-
symex.language_mode=init_symbol->mode;
241-
}
242-
243-
status() << "Starting Bounded Model Checking" << eom;
244-
245-
symex.last_source_location.make_nil();
246-
247-
symex.unwindset.parse_unwind(options.get_option("unwind"));
248-
symex.unwindset.parse_unwindset(options.get_option("unwindset"));
249-
}
250-
25172
safety_checkert::resultt bmct::execute(
25273
abstract_goto_modelt &goto_model)
25374
{
@@ -293,7 +114,7 @@ safety_checkert::resultt bmct::execute(
293114
<< equation.SSA_steps.size()
294115
<< " steps" << eom;
295116

296-
slice();
117+
slice(symex, equation, ns, options, ui_message_handler);
297118

298119
// coverage report
299120
std::string cov_out=options.get_option("symex-coverage-report");
@@ -330,8 +151,8 @@ safety_checkert::resultt bmct::execute(
330151
{
331152
if(options.is_set("paths"))
332153
return safety_checkert::resultt::PAUSED;
333-
report_success();
334-
output_graphml(resultt::SAFE);
154+
report_success(ui_message_handler);
155+
output_graphml(resultt::SAFE, error_trace, equation, ns, options);
335156
return safety_checkert::resultt::SAFE;
336157
}
337158

@@ -372,55 +193,12 @@ safety_checkert::resultt bmct::execute(
372193
}
373194
}
374195

375-
void bmct::slice()
376-
{
377-
if(options.get_option("slice-by-trace")!="")
378-
{
379-
symex_slice_by_tracet symex_slice_by_trace(ns);
380-
381-
symex_slice_by_trace.slice_by_trace
382-
(options.get_option("slice-by-trace"),
383-
equation);
384-
}
385-
// any properties to check at all?
386-
if(equation.has_threads())
387-
{
388-
// we should build a thread-aware SSA slicer
389-
statistics() << "no slicing due to threads" << eom;
390-
}
391-
else
392-
{
393-
if(options.get_bool_option("slice-formula"))
394-
{
395-
::slice(equation);
396-
statistics() << "slicing removed "
397-
<< equation.count_ignored_SSA_steps()
398-
<< " assignments"<<eom;
399-
}
400-
else
401-
{
402-
if(options.get_list_option("cover").empty())
403-
{
404-
simple_slice(equation);
405-
statistics() << "simple slicing removed "
406-
<< equation.count_ignored_SSA_steps()
407-
<< " assignments"<<eom;
408-
}
409-
}
410-
}
411-
statistics() << "Generated " << symex.get_total_vccs() << " VCC(s), "
412-
<< symex.get_remaining_vccs()
413-
<< " remaining after simplification" << eom;
414-
415-
if(options.is_set("paths"))
416-
statistics() << "Generated " << symex.path_segment_vccs
417-
<< " new VCC(s) along current path segment" << eom;
418-
}
419196

420197
safety_checkert::resultt bmct::run(
421198
abstract_goto_modelt &goto_model)
422199
{
423-
setup();
200+
memory_model = get_memory_model(options, ns);
201+
setup_symex(symex, ns, options, ui_message_handler);
424202

425203
return execute(goto_model);
426204
}
@@ -435,26 +213,13 @@ safety_checkert::resultt bmct::decide(const goto_functionst &goto_functions)
435213
return all_properties(goto_functions);
436214
}
437215

438-
void bmct::show()
439-
{
440-
if(options.get_bool_option("show-vcc"))
441-
{
442-
show_vcc(options, ui_message_handler, equation);
443-
}
444-
445-
if(options.get_bool_option("program-only"))
446-
{
447-
show_program(ns, equation);
448-
}
449-
}
450-
451216
safety_checkert::resultt bmct::stop_on_fail()
452217
{
453218
switch(run_decision_procedure())
454219
{
455220
case decision_proceduret::resultt::D_UNSATISFIABLE:
456-
report_success();
457-
output_graphml(resultt::SAFE);
221+
report_success(ui_message_handler);
222+
output_graphml(resultt::SAFE, error_trace, equation, ns, options);
458223
return resultt::SAFE;
459224

460225
case decision_proceduret::resultt::D_SATISFIABLE:
@@ -464,11 +229,13 @@ safety_checkert::resultt bmct::stop_on_fail()
464229
counterexample_beautificationt()(
465230
dynamic_cast<boolbvt &>(prop_conv), equation);
466231

467-
error_trace();
468-
output_graphml(resultt::UNSAFE);
232+
build_error_trace(
233+
error_trace, ns, equation, prop_conv, ui_message_handler);
234+
output_error_trace(error_trace, ns, trace_options(), ui_message_handler);
235+
output_graphml(resultt::UNSAFE, error_trace, equation, ns, options);
469236
}
470237

471-
report_failure();
238+
report_failure(ui_message_handler);
472239
return resultt::UNSAFE;
473240

474241
default:
@@ -619,11 +386,11 @@ int bmct::do_language_agnostic_bmc(
619386
{
620387
case safety_checkert::resultt::SAFE:
621388
if(opts.is_set("paths"))
622-
report_success(message, ui);
389+
report_success(ui);
623390
return CPROVER_EXIT_VERIFICATION_SAFE;
624391
case safety_checkert::resultt::UNSAFE:
625392
if(opts.is_set("paths"))
626-
report_failure(message, ui);
393+
report_failure(ui);
627394
return CPROVER_EXIT_VERIFICATION_UNSAFE;
628395
case safety_checkert::resultt::ERROR:
629396
return CPROVER_EXIT_INTERNAL_ERROR;

0 commit comments

Comments
 (0)