3131bool is_subsumed (
3232 const std::unordered_set<exprt, irep_hash> &a1,
3333 const std::unordered_set<exprt, irep_hash> &a2,
34+ const std::unordered_set<exprt, irep_hash> &a3,
3435 const exprt &b,
3536 const std::unordered_set<symbol_exprt, irep_hash> &address_taken,
3637 bool verbose,
@@ -64,6 +65,9 @@ bool is_subsumed(
6465 for (auto &a_conjunct : a2)
6566 axioms << a_conjunct;
6667
68+ for (auto &a_conjunct : a3)
69+ axioms << a_conjunct;
70+
6771 axioms.set_to_false (b);
6872
6973 // instantiate our axioms
@@ -136,14 +140,21 @@ inductiveness_resultt inductiveness_check(
136140
137141 if (solver_options.verbose )
138142 {
139- // print the current invariants in the frame
143+ // print the current invariants and obligations in the frame
140144 for (const auto &invariant : f.invariants )
141145 {
142146 std::cout << consolet::faint << consolet::blue;
143147 std::cout << ' I' << std::setw (2 ) << frame_ref.index << ' ' ;
144148 std::cout << format (invariant);
145149 std::cout << consolet::reset << ' \n ' ;
146150 }
151+ for (const auto &obligation : f.obligations )
152+ {
153+ std::cout << consolet::faint << consolet::blue;
154+ std::cout << ' O' << std::setw (2 ) << frame_ref.index << ' ' ;
155+ std::cout << format (obligation);
156+ std::cout << consolet::reset << ' \n ' ;
157+ }
147158 }
148159
149160 if (solver_options.verbose )
@@ -158,6 +169,7 @@ inductiveness_resultt inductiveness_check(
158169 }
159170 else if (is_subsumed (
160171 f.invariants_set ,
172+ f.obligations_set ,
161173 f.auxiliaries_set ,
162174 invariant,
163175 address_taken,
@@ -182,7 +194,7 @@ inductiveness_resultt inductiveness_check(
182194 std::cout << format (invariant) << ' \n ' ;
183195
184196 // store in frame
185- frames[frame_ref.index ].add_invariant (invariant);
197+ frames[frame_ref.index ].add_obligation (invariant);
186198
187199 // add to queue
188200 auto new_path = path;
@@ -191,14 +203,21 @@ inductiveness_resultt inductiveness_check(
191203 }
192204 };
193205
194- // stick non-true frames into the queue
206+ // stick invariants into the queue
195207 for (std::size_t frame_index = 0 ; frame_index < frames.size (); frame_index++)
196208 {
197209 frame_reft frame_ref (frame_index);
198210 for (auto &cond : frames[frame_index].invariants )
199211 queue.emplace_back (frame_ref, cond, workt::patht{frame_ref});
200212 }
201213
214+ // clean up the obligations
215+ for (auto &frame : frames)
216+ {
217+ frame.obligations .clear ();
218+ frame.obligations_set .clear ();
219+ }
220+
202221 while (!queue.empty ())
203222 {
204223 auto work = queue.back ();
@@ -218,16 +237,17 @@ inductiveness_resultt inductiveness_check(
218237 if (counterexample_found)
219238 {
220239 property.trace = counterexample_found.value ();
221- return inductiveness_resultt::BASE_CASE_FAIL ;
240+ return inductiveness_resultt::base_case_fail ( std::move (work)) ;
222241 }
223242
224243 propagate (
225244 frames, work, address_taken, solver_options.verbose , ns, propagator);
245+
246+ // did we drop anything?
247+ if (!dropped.empty ())
248+ return inductiveness_resultt::step_case_fail (std::move (dropped.front ()));
226249 }
227250
228- // did we drop anything?
229- if (dropped.empty ())
230- return inductiveness_resultt::INDUCTIVE;
231- else
232- return inductiveness_resultt::STEP_CASE_FAIL;
251+ // done, saturated
252+ return inductiveness_resultt::inductive ();
233253}
0 commit comments