@@ -71,6 +71,7 @@ static std::vector<exprt> gather_dependent_expressions(const exprt &expr)
7171 if (
7272 can_cast_expr<symbol_exprt>(expr_node) ||
7373 can_cast_expr<array_exprt>(expr_node) ||
74+ can_cast_expr<array_of_exprt>(expr_node) ||
7475 can_cast_expr<nondet_symbol_exprt>(expr_node))
7576 {
7677 dependent_expressions.push_back (expr_node);
@@ -79,17 +80,10 @@ static std::vector<exprt> gather_dependent_expressions(const exprt &expr)
7980 return dependent_expressions;
8081}
8182
82- void smt2_incremental_decision_proceduret::define_array_function (
83- const array_exprt &array)
83+ void smt2_incremental_decision_proceduret::initialize_array_elements (
84+ const array_exprt &array,
85+ const smt_identifier_termt &array_identifier)
8486{
85- const smt_sortt array_sort = convert_type_to_smt_sort (array.type ());
86- INVARIANT (
87- array_sort.cast <smt_array_sortt>(),
88- " Converting array typed expression to SMT should result in a term of array "
89- " sort." );
90- const smt_identifier_termt array_identifier = smt_identifier_termt{
91- " array_" + std::to_string (array_sequence ()), array_sort};
92- solver_process->send (smt_declare_function_commandt{array_identifier, {}});
9387 const std::vector<exprt> &elements = array.operands ();
9488 const typet &index_type = array.type ().index_type ();
9589 for (std::size_t i = 0 ; i < elements.size (); ++i)
@@ -100,6 +94,46 @@ void smt2_incremental_decision_proceduret::define_array_function(
10094 convert_expr_to_smt (elements.at (i)))};
10195 solver_process->send (element_definition);
10296 }
97+ }
98+
99+ void smt2_incremental_decision_proceduret::initialize_array_elements (
100+ const array_of_exprt &array,
101+ const smt_identifier_termt &array_identifier)
102+ {
103+ const smt_sortt index_type =
104+ convert_type_to_smt_sort (array.type ().index_type ());
105+ const smt_identifier_termt array_index_identifier = smt_identifier_termt{
106+ id2string (array_identifier.identifier ()) + " _index" , index_type};
107+ const std::vector<exprt> &elements = array.operands ();
108+ INVARIANT (elements.size () == 1 , " array_of_exprt must have only one operand." );
109+ const smt_termt element_value = convert_expr_to_smt (elements.front ());
110+
111+ const smt_assert_commandt elements_definition{smt_forall_termt{
112+ {array_index_identifier},
113+ smt_core_theoryt::equal (
114+ smt_array_theoryt::select (array_identifier, array_index_identifier),
115+ element_value)}};
116+ solver_process->send (elements_definition);
117+ }
118+
119+ template <typename EXPRT>
120+ void smt2_incremental_decision_proceduret::define_array_function (
121+ const EXPRT &array)
122+ {
123+ static_assert (
124+ std::is_same<EXPRT, array_exprt>::value ||
125+ std::is_same<EXPRT, array_of_exprt>::value,
126+ " smt2_incremental_decision_proceduret::define_array_function can be "
127+ " applied only to array_exprt and array_of_exprt arguments." );
128+ const smt_sortt array_sort = convert_type_to_smt_sort (array.type ());
129+ INVARIANT (
130+ array_sort.cast <smt_array_sortt>(),
131+ " Converting array typed expression to SMT should result in a term of array "
132+ " sort." );
133+ const smt_identifier_termt array_identifier = smt_identifier_termt{
134+ " array_" + std::to_string (array_sequence ()), array_sort};
135+ solver_process->send (smt_declare_function_commandt{array_identifier, {}});
136+ initialize_array_elements (array, array_identifier);
103137 expression_identifiers.emplace (array, array_identifier);
104138}
105139
@@ -168,9 +202,14 @@ void smt2_incremental_decision_proceduret::define_dependent_functions(
168202 solver_process->send (function);
169203 }
170204 }
171- if (const auto array_expr = expr_try_dynamic_cast<array_exprt>(current))
205+ else if (const auto array_expr = expr_try_dynamic_cast<array_exprt>(current))
172206 define_array_function (*array_expr);
173- if (
207+ else if (
208+ const auto array_of_expr = expr_try_dynamic_cast<array_of_exprt>(current))
209+ {
210+ define_array_function (*array_of_expr);
211+ }
212+ else if (
174213 const auto nondet_symbol =
175214 expr_try_dynamic_cast<nondet_symbol_exprt>(current))
176215 {
@@ -213,8 +252,7 @@ smt2_incremental_decision_proceduret::smt2_incremental_decision_proceduret(
213252{
214253 solver_process->send (
215254 smt_set_option_commandt{smt_option_produce_modelst{true }});
216- solver_process->send (smt_set_logic_commandt{
217- smt_logic_quantifier_free_arrays_uninterpreted_functions_bit_vectorst{}});
255+ solver_process->send (smt_set_logic_commandt{smt_logic_allt{}});
218256 solver_process->send (object_size_function.declaration );
219257}
220258
0 commit comments