Skip to content

Commit 73ef5ef

Browse files
committed
Keep quantified symbols unique during symex_assume
1 parent 7e5d539 commit 73ef5ef

File tree

4 files changed

+36
-4
lines changed

4 files changed

+36
-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: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,12 +196,38 @@ void goto_symext::vcc(
196196
state.guard.as_expr(), guarded_condition, property_id, msg, state.source);
197197
}
198198

199+
void goto_symext::record_bounded_variables(exprt &expr, statet &state)
200+
{
201+
if(expr.id() == ID_forall || expr.id() == ID_exists)
202+
{
203+
auto &quant_expr = to_quantifier_expr(expr);
204+
symbol_exprt tmp0 =
205+
to_symbol_expr(to_ssa_expr(quant_expr.symbol()).get_original_expr());
206+
symex_decl(state, tmp0);
207+
instruction_local_symbols.push_back(tmp0);
208+
exprt tmp = quant_expr.where();
209+
record_bounded_variables(tmp, state);
210+
}
211+
else if(expr.id() == ID_or || expr.id() == ID_and)
212+
{
213+
for(auto &op : expr.operands())
214+
record_bounded_variables(op, state);
215+
}
216+
}
217+
199218
void goto_symext::symex_assume(statet &state, const exprt &cond)
200219
{
201220
exprt simplified_cond = clean_expr(cond, state, false);
202221
simplified_cond = state.rename(std::move(simplified_cond), ns).get();
203222
do_simplify(simplified_cond);
204223

224+
if(
225+
has_subexpr(simplified_cond, ID_exists) ||
226+
has_subexpr(simplified_cond, ID_forall))
227+
{
228+
record_bounded_variables(simplified_cond, state);
229+
}
230+
205231
// It would be better to call try_filter_value_sets after apply_condition,
206232
// but it is not currently possible. See the comment at the beginning of
207233
// \ref apply_goto_condition for more information.

0 commit comments

Comments
 (0)