Skip to content

Commit 3892c55

Browse files
Factor out bmct building blocks int bmc_util
This is an intermediate step in order to reuse the building blocks in the new implementation of bmct. The old implementation is functional until it can be replaced by the new one.
1 parent 0eeb495 commit 3892c55

File tree

7 files changed

+373
-276
lines changed

7 files changed

+373
-276
lines changed

src/cbmc/all_properties.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ Author: Daniel Kroening, [email protected]
1414
#include <algorithm>
1515
#include <chrono>
1616

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

@@ -55,7 +57,8 @@ 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(bmc.equation, bmc.prop_conv, get_message_handler());
61+
bmc.freeze_program_variables();
5962

6063
// Collect _all_ goals in `goal_map'.
6164
// This maps property IDs to 'goalt'
@@ -144,9 +147,9 @@ safety_checkert::resultt bmc_all_propertiest::operator()()
144147
bool safe=(cover_goals.number_covered()==0);
145148

146149
if(safe)
147-
bmc.report_success(); // legacy, might go away
150+
report_success(bmc.ui_message_handler); // legacy, might go away
148151
else
149-
bmc.report_failure(); // legacy, might go away
152+
report_failure(bmc.ui_message_handler); // legacy, might go away
150153

151154
return safe?safety_checkert::resultt::SAFE:safety_checkert::resultt::UNSAFE;
152155
}

src/cbmc/bmc.cpp

Lines changed: 17 additions & 254 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,14 @@ Author: Daniel Kroening, [email protected]
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

3527
#include <goto-checker/solver_factory.h>
3628

29+
#include "bmc_util.h"
3730
#include "counterexample_beautification.h"
3831
#include "fault_localization.h"
3932

@@ -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
13045
bmct::run_decision_procedure(prop_convt &prop_conv)
13146
{
@@ -136,7 +51,10 @@ bmct::run_decision_procedure(prop_convt &prop_conv)
13651

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

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

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

@@ -152,105 +70,6 @@ bmct::run_decision_procedure(prop_convt &prop_conv)
15270
return dec_result;
15371
}
15472

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

299-
slice();
118+
slice(symex, equation, ns, options, ui_message_handler);
300119

301120
// coverage report
302121
std::string cov_out=options.get_option("symex-coverage-report");
@@ -333,8 +152,8 @@ safety_checkert::resultt bmct::execute(
333152
{
334153
if(options.is_set("paths"))
335154
return safety_checkert::resultt::PAUSED;
336-
report_success();
337-
output_graphml(resultt::SAFE);
155+
report_success(ui_message_handler);
156+
output_graphml(resultt::SAFE, error_trace, equation, ns, options);
338157
return safety_checkert::resultt::SAFE;
339158
}
340159

@@ -375,55 +194,11 @@ safety_checkert::resultt bmct::execute(
375194
}
376195
}
377196

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

423198
safety_checkert::resultt bmct::run(
424199
abstract_goto_modelt &goto_model)
425200
{
426-
setup();
201+
setup_symex(symex, ns, options, ui_message_handler);
427202

428203
return execute(goto_model);
429204
}
@@ -440,26 +215,13 @@ safety_checkert::resultt bmct::decide(
440215
return all_properties(goto_functions, prop_conv);
441216
}
442217

443-
void bmct::show()
444-
{
445-
if(options.get_bool_option("show-vcc"))
446-
{
447-
show_vcc(options, ui_message_handler, equation);
448-
}
449-
450-
if(options.get_bool_option("program-only"))
451-
{
452-
show_program(ns, equation);
453-
}
454-
}
455-
456218
safety_checkert::resultt bmct::stop_on_fail(prop_convt &prop_conv)
457219
{
458220
switch(run_decision_procedure(prop_conv))
459221
{
460222
case decision_proceduret::resultt::D_UNSATISFIABLE:
461-
report_success();
462-
output_graphml(resultt::SAFE);
223+
report_success(ui_message_handler);
224+
output_graphml(resultt::SAFE, error_trace, equation, ns, options);
463225
return resultt::SAFE;
464226

465227
case decision_proceduret::resultt::D_SATISFIABLE:
@@ -469,11 +231,12 @@ safety_checkert::resultt bmct::stop_on_fail(prop_convt &prop_conv)
469231
counterexample_beautificationt()(
470232
dynamic_cast<boolbvt &>(prop_conv), equation);
471233

472-
error_trace();
473-
output_graphml(resultt::UNSAFE);
234+
build_error_trace(error_trace, ns, equation, prop_conv, ui_message_handler);
235+
output_error_trace(error_trace, ns, trace_options(), ui_message_handler);
236+
output_graphml(resultt::UNSAFE, error_trace, equation, ns, options);
474237
}
475238

476-
report_failure();
239+
report_failure(ui_message_handler);
477240
return resultt::UNSAFE;
478241

479242
default:
@@ -622,11 +385,11 @@ int bmct::do_language_agnostic_bmc(
622385
{
623386
case safety_checkert::resultt::SAFE:
624387
if(opts.is_set("paths"))
625-
report_success(message, ui);
388+
report_success(ui);
626389
return CPROVER_EXIT_VERIFICATION_SAFE;
627390
case safety_checkert::resultt::UNSAFE:
628391
if(opts.is_set("paths"))
629-
report_failure(message, ui);
392+
report_failure(ui);
630393
return CPROVER_EXIT_VERIFICATION_UNSAFE;
631394
case safety_checkert::resultt::ERROR:
632395
return CPROVER_EXIT_INTERNAL_ERROR;

0 commit comments

Comments
 (0)