@@ -153,9 +153,14 @@ bmct::run_decision_procedure(prop_convt &prop_conv)
153153
154154void bmct::report_success ()
155155{
156- result () << bold << " VERIFICATION SUCCESSFUL" << reset << eom;
156+ report_success (*this , ui_message_handler);
157+ }
157158
158- switch (ui_message_handler.get_ui ())
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 ())
159164 {
160165 case ui_message_handlert::uit::PLAIN:
161166 break ;
@@ -164,25 +169,30 @@ void bmct::report_success()
164169 {
165170 xmlt xml (" cprover-status" );
166171 xml.data =" SUCCESS" ;
167- result () << xml;
172+ log. result () << xml;
168173 }
169174 break ;
170175
171176 case ui_message_handlert::uit::JSON_UI:
172177 {
173178 json_objectt json_result;
174179 json_result[" cProverStatus" ]=json_stringt (" success" );
175- result () << json_result;
180+ log. result () << json_result;
176181 }
177182 break ;
178183 }
179184}
180185
181186void bmct::report_failure ()
182187{
183- result () << bold << " VERIFICATION FAILED" << reset << eom;
188+ report_failure (*this , ui_message_handler);
189+ }
184190
185- switch (ui_message_handler.get_ui ())
191+ void bmct::report_failure (messaget &log, ui_message_handlert &handler)
192+ {
193+ log.result () << log.bold << " VERIFICATION FAILED" << log.reset << log.eom ;
194+
195+ switch (handler.get_ui ())
186196 {
187197 case ui_message_handlert::uit::PLAIN:
188198 break ;
@@ -191,15 +201,15 @@ void bmct::report_failure()
191201 {
192202 xmlt xml (" cprover-status" );
193203 xml.data =" FAILURE" ;
194- result () << xml;
204+ log. result () << xml;
195205 }
196206 break ;
197207
198208 case ui_message_handlert::uit::JSON_UI:
199209 {
200210 json_objectt json_result;
201211 json_result[" cProverStatus" ]=json_stringt (" failure" );
202- result () << json_result;
212+ log. result () << json_result;
203213 }
204214 break ;
205215 }
@@ -260,9 +270,6 @@ safety_checkert::resultt bmct::execute(
260270 const goto_functionst &goto_functions =
261271 goto_model.get_goto_functions ();
262272
263- if (symex.should_pause_symex )
264- return safety_checkert::resultt::PAUSED;
265-
266273 // This provides the driver program the opportunity to do things like a
267274 // symbol-table or goto-functions dump instead of actually running the
268275 // checker, like show-vcc except driver-program specific.
@@ -272,9 +279,14 @@ safety_checkert::resultt bmct::execute(
272279 if (driver_callback_after_symex && driver_callback_after_symex ())
273280 return safety_checkert::resultt::SAFE; // to indicate non-error
274281
275- // add a partial ordering, if required
276282 if (equation.has_threads ())
277283 {
284+ // When doing path exploration in a concurrent setting, we should avoid
285+ // model-checking the program until we reach the end of a path.
286+ if (symex.should_pause_symex )
287+ return safety_checkert::resultt::PAUSED;
288+
289+ // add a partial ordering, if required
278290 memory_model->set_message_handler (get_message_handler ());
279291 (*memory_model)(equation);
280292 }
@@ -318,6 +330,8 @@ safety_checkert::resultt bmct::execute(
318330 !options.get_bool_option (" program-only" ) &&
319331 symex.get_remaining_vccs () == 0 )
320332 {
333+ if (options.is_set (" paths" ))
334+ return safety_checkert::resultt::PAUSED;
321335 report_success ();
322336 output_graphml (resultt::SAFE);
323337 return safety_checkert::resultt::SAFE;
@@ -329,7 +343,10 @@ safety_checkert::resultt bmct::execute(
329343 return safety_checkert::resultt::SAFE;
330344 }
331345
332- return decide (goto_functions, prop_conv);
346+ if (!options.is_set (" paths" ) || symex.path_segment_vccs > 0 )
347+ return decide (goto_functions, prop_conv);
348+
349+ return safety_checkert::resultt::PAUSED;
333350 }
334351
335352 catch (const std::string &error_str)
@@ -396,6 +413,10 @@ void bmct::slice()
396413 statistics () << " Generated " << symex.get_total_vccs () << " VCC(s), "
397414 << symex.get_remaining_vccs ()
398415 << " remaining after simplification" << eom;
416+
417+ if (options.is_set (" paths" ))
418+ statistics () << " Generated " << symex.path_segment_vccs
419+ << " new VCC(s) along current path segment" << eom;
399420}
400421
401422safety_checkert::resultt bmct::run (
@@ -484,8 +505,8 @@ int bmct::do_language_agnostic_bmc(
484505 std::function<void (bmct &, const symbol_tablet &)> driver_configure_bmc,
485506 std::function<bool(void )> callback_after_symex)
486507{
487- safety_checkert::resultt final_result = safety_checkert::resultt::UNKNOWN ;
488- safety_checkert::resultt tmp_result = safety_checkert::resultt::UNKNOWN ;
508+ safety_checkert::resultt final_result = safety_checkert::resultt::SAFE ;
509+ safety_checkert::resultt tmp_result = safety_checkert::resultt::SAFE ;
489510 const symbol_tablet &symbol_table = model.get_symbol_table ();
490511 messaget message (ui);
491512 std::unique_ptr<path_storaget> worklist;
@@ -544,11 +565,6 @@ int bmct::do_language_agnostic_bmc(
544565
545566 while (!worklist->empty ())
546567 {
547- if (tmp_result != safety_checkert::resultt::PAUSED)
548- message.status () << " ___________________________\n "
549- << " Starting new path (" << worklist->size ()
550- << " to go)\n "
551- << message.eom ;
552568 cbmc_solverst solvers (
553569 opts,
554570 symbol_table,
@@ -603,13 +619,15 @@ int bmct::do_language_agnostic_bmc(
603619 switch (final_result)
604620 {
605621 case safety_checkert::resultt::SAFE:
622+ if (opts.is_set (" paths" ))
623+ report_success (message, ui);
606624 return CPROVER_EXIT_VERIFICATION_SAFE;
607625 case safety_checkert::resultt::UNSAFE:
626+ if (opts.is_set (" paths" ))
627+ report_failure (message, ui);
608628 return CPROVER_EXIT_VERIFICATION_UNSAFE;
609629 case safety_checkert::resultt::ERROR:
610630 return CPROVER_EXIT_INTERNAL_ERROR;
611- case safety_checkert::resultt::UNKNOWN:
612- return CPROVER_EXIT_INTERNAL_ERROR;
613631 case safety_checkert::resultt::PAUSED:
614632 UNREACHABLE;
615633 }
0 commit comments