@@ -425,10 +425,24 @@ dfcc_instrument_loopt::add_step_instructions(
425
425
const irep_idt &language_mode =
426
426
dfcc_utilst::get_function_symbol (symbol_table, function_id).mode ;
427
427
{
428
- // Assume the loop invariant after havocing the state.
429
- code_assumet assumption{invariant};
430
- assumption.add_source_location () = loop_head_location;
431
- converter.goto_convert (assumption, step_instrs, language_mode);
428
+ // Assume the loop invariant after havocing the state; produce one
429
+ // assumption per conjunct to ease analysis of counterexamples, and possibly
430
+ // also improve solver performance (observed with Bitwuzla)
431
+ if (invariant.id () == ID_and)
432
+ {
433
+ for (const auto &op : invariant.operands ())
434
+ {
435
+ code_assumet assumption{op};
436
+ assumption.add_source_location () = loop_head_location;
437
+ converter.goto_convert (assumption, step_instrs, language_mode);
438
+ }
439
+ }
440
+ else
441
+ {
442
+ code_assumet assumption{invariant};
443
+ assumption.add_source_location () = loop_head_location;
444
+ converter.goto_convert (assumption, step_instrs, language_mode);
445
+ }
432
446
}
433
447
434
448
{
@@ -506,10 +520,24 @@ void dfcc_instrument_loopt::add_body_instructions(
506
520
" Check invariant after step for loop " +
507
521
id2string (check_location.get_function ()) + " ." +
508
522
std::to_string (cbmc_loop_id));
509
- // Assume the loop invariant after havocing the state.
510
- code_assertt assertion{invariant};
511
- assertion.add_source_location () = check_location;
512
- converter.goto_convert (assertion, pre_loop_latch_instrs, language_mode);
523
+ // Assert the loop invariant after havocing the state; produce one assertion
524
+ // per conjunct to ease analysis of counterexamples, and possibly also
525
+ // improve solver performance (observed with Bitwuzla)
526
+ if (invariant.id () == ID_and)
527
+ {
528
+ for (const auto &op : invariant.operands ())
529
+ {
530
+ code_assertt assertion{op};
531
+ assertion.add_source_location () = check_location;
532
+ converter.goto_convert (assertion, pre_loop_latch_instrs, language_mode);
533
+ }
534
+ }
535
+ else
536
+ {
537
+ code_assertt assertion{invariant};
538
+ assertion.add_source_location () = check_location;
539
+ converter.goto_convert (assertion, pre_loop_latch_instrs, language_mode);
540
+ }
513
541
}
514
542
515
543
{
0 commit comments