@@ -425,10 +425,24 @@ dfcc_instrument_loopt::add_step_instructions(
425425 const irep_idt &language_mode =
426426 dfcc_utilst::get_function_symbol (symbol_table, function_id).mode ;
427427 {
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+ }
432446 }
433447
434448 {
@@ -506,10 +520,24 @@ void dfcc_instrument_loopt::add_body_instructions(
506520 " Check invariant after step for loop " +
507521 id2string (check_location.get_function ()) + " ." +
508522 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+ }
513541 }
514542
515543 {
0 commit comments