File tree Expand file tree Collapse file tree
regression/smt2_solver/let-array Expand file tree Collapse file tree Original file line number Diff line number Diff line change 1+ CORE
2+ let-array.smt2
3+
4+ ^EXIT=0$
5+ ^SIGNAL=0$
6+ ^unsat$
7+ --
8+ ^sat$
9+ --
10+ Let-bound arrays must be connected to the original array in the
11+ array theory so that element-wise constraints propagate correctly.
Original file line number Diff line number Diff line change 1+ ; Test that let-bound arrays are properly connected to the original
2+ ; array in the array theory. A let binding creates a fresh symbol
3+ ; internally; without proper connection, the element-wise constraints
4+ ; on the original array don't propagate to the let-bound copy.
5+ (set-option :produce-models true )
6+ (declare-fun arr () (Array (_ BitVec 32 ) (_ BitVec 32 )))
7+ (assert (= (select arr (_ bv0 32 )) (_ bv42 32 )))
8+ (assert (= (select arr (_ bv1 32 )) (_ bv99 32 )))
9+ (assert (not (= (let ((?a arr)) (select ?a (_ bv1 32 ))) (_ bv99 32 ))))
10+ (check-sat )
11+ (exit )
Original file line number Diff line number Diff line change @@ -80,6 +80,19 @@ literalt arrayst::record_array_equality(
8080 return array_equalities.back ().l ;
8181}
8282
83+ void arrayst::record_array_let_binding (
84+ const symbol_exprt &symbol,
85+ const exprt &value)
86+ {
87+ DATA_INVARIANT (
88+ symbol.type ().id () == ID_array,
89+ " record_array_let_binding parameter should be array-typed" );
90+
91+ const equal_exprt eq{symbol, value};
92+ const literalt eq_lit = record_array_equality (eq);
93+ prop.l_set_to_true (eq_lit);
94+ }
95+
8396void arrayst::collect_indices ()
8497{
8598 for (std::size_t i=0 ; i<arrays.size (); i++)
Original file line number Diff line number Diff line change @@ -26,6 +26,7 @@ class array_of_exprt;
2626class equal_exprt ;
2727class if_exprt ;
2828class index_exprt ;
29+ class symbol_exprt ;
2930class with_exprt ;
3031class update_exprt ;
3132
@@ -52,6 +53,12 @@ class arrayst:public equalityt
5253 literalt record_array_equality (const equal_exprt &expr);
5354 void record_array_index (const index_exprt &expr);
5455
56+ // / Record that \p symbol is equal to \p value for the purposes of the
57+ // / array theory. For unbounded-array-typed bindings this connects the
58+ // / two expressions in the union-find so that element-wise constraints
59+ // / propagate correctly.
60+ void record_array_let_binding (const symbol_exprt &symbol, const exprt &value);
61+
5562protected:
5663 const namespacet &ns;
5764 messaget log;
Original file line number Diff line number Diff line change @@ -6,12 +6,13 @@ Author: Daniel Kroening, kroening@kroening.com
66
77\*******************************************************************/
88
9- #include " boolbv.h"
10-
9+ #include < util/byte_operators.h>
1110#include < util/range.h>
1211#include < util/replace_symbol.h>
1312#include < util/std_expr.h>
1413
14+ #include " boolbv.h"
15+
1516bvt boolbvt::convert_let (const let_exprt &expr)
1617{
1718 const auto &variables = expr.variables ();
@@ -69,6 +70,20 @@ bvt boolbvt::convert_let(const let_exprt &expr)
6970 for (const auto &pair : make_range (variables).zip (fresh_variables))
7071 replace_symbol.insert (pair.first , pair.second );
7172
73+ // Connect fresh let-bound symbols to their values in the array theory.
74+ for (const auto &pair : make_range (fresh_variables).zip (values))
75+ {
76+ if (
77+ pair.first .type ().id () == ID_array &&
78+ is_unbounded_array (to_array_type (pair.first .type ())))
79+ {
80+ const exprt lowered_value = has_byte_operator (pair.second )
81+ ? lower_byte_operators (pair.second , ns)
82+ : pair.second ;
83+ record_array_let_binding (pair.first , pair.second );
84+ }
85+ }
86+
7287 // rename the bound symbols in 'where'
7388 exprt where_renamed = expr.where ();
7489 replace_symbol (where_renamed);
You can’t perform that action at this time.
0 commit comments