Skip to content

Commit 3cde7f1

Browse files
committed
Keep quantified symbols unique during symex_assume
1 parent 7e5d539 commit 3cde7f1

File tree

4 files changed

+32
-4
lines changed

4 files changed

+32
-4
lines changed

regression/contracts-dfcc/quantifiers-loop-fail/main.c renamed to regression/contracts-dfcc/quantifiers-loop-05/main.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,13 @@ void main()
99
a[10] = 0;
1010
bool flag = true;
1111
for(int j = 0; j < N; ++j)
12+
// clang-format off
1213
__CPROVER_loop_invariant(j <= N)
14+
__CPROVER_loop_invariant((j != 0) ==> __CPROVER_forall {
15+
int k;
16+
(0 <= k && k < N) ==> (a[k] == 1)
17+
})
18+
// clang-format on
1319
{
1420
for(int i = 0; i < N; ++i)
1521
// clang-format off

regression/contracts-dfcc/quantifiers-loop-fail/test.desc renamed to regression/contracts-dfcc/quantifiers-loop-05/test.desc

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
CORE dfcc-only
22
main.c
33
--dfcc main --apply-loop-contracts _ --smt2
4-
^EXIT=6$
4+
^EXIT=0$
55
^SIGNAL=0$
6-
^SMT2 solver returned error message:$
7-
^.*\"line \d+ column \d+: unknown constant .*$
8-
^VERIFICATION ERROR$
6+
^VERIFICATION SUCCESSFUL$
97
--
108
^warning: ignoring
119
--

src/goto-symex/goto_symex.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -802,6 +802,8 @@ class goto_symext
802802
virtual void symex_output(statet &state, const codet &code);
803803

804804
void rewrite_quantifiers(exprt &, statet &);
805+
/// We record all bounded variable and keep unique by means of L2 renaming
806+
void record_bounded_variables(exprt &, statet &);
805807

806808
/// \brief Symbolic execution paths to be resumed later
807809
/// \remarks

src/goto-symex/symex_main.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,12 +195,34 @@ void goto_symext::vcc(
195195
target.assertion(
196196
state.guard.as_expr(), guarded_condition, property_id, msg, state.source);
197197
}
198+
void goto_symext::record_bounded_variables(exprt &expr, statet &state)
199+
{
200+
if(
201+
expr.id() == ID_forall ||
202+
expr.id() == ID_exists)
203+
{
204+
auto &quant_expr = to_quantifier_expr(expr);
205+
symbol_exprt tmp0 =
206+
to_symbol_expr(to_ssa_expr(quant_expr.symbol()).get_original_expr());
207+
symex_decl(state, tmp0);
208+
instruction_local_symbols.push_back(tmp0);
209+
exprt tmp = quant_expr.where();
210+
record_bounded_variables(tmp, state);
211+
}
212+
else if(expr.id() == ID_or || expr.id() == ID_and)
213+
{
214+
for(auto &op : expr.operands())
215+
record_bounded_variables(op, state);
216+
}
217+
}
198218

199219
void goto_symext::symex_assume(statet &state, const exprt &cond)
200220
{
201221
exprt simplified_cond = clean_expr(cond, state, false);
202222
simplified_cond = state.rename(std::move(simplified_cond), ns).get();
203223
do_simplify(simplified_cond);
224+
if(has_subexpr(simplified_cond, ID_exists) || has_subexpr(simplified_cond, ID_forall))
225+
record_bounded_variables( simplified_cond, state);
204226

205227
// It would be better to call try_filter_value_sets after apply_condition,
206228
// but it is not currently possible. See the comment at the beginning of

0 commit comments

Comments
 (0)