@@ -71,6 +71,7 @@ static std::vector<exprt> gather_dependent_expressions(const exprt &expr)
71
71
if (
72
72
can_cast_expr<symbol_exprt>(expr_node) ||
73
73
can_cast_expr<array_exprt>(expr_node) ||
74
+ can_cast_expr<array_of_exprt>(expr_node) ||
74
75
can_cast_expr<nondet_symbol_exprt>(expr_node))
75
76
{
76
77
dependent_expressions.push_back (expr_node);
@@ -79,17 +80,10 @@ static std::vector<exprt> gather_dependent_expressions(const exprt &expr)
79
80
return dependent_expressions;
80
81
}
81
82
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)
84
86
{
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, {}});
93
87
const std::vector<exprt> &elements = array.operands ();
94
88
const typet &index_type = array.type ().index_type ();
95
89
for (std::size_t i = 0 ; i < elements.size (); ++i)
@@ -100,6 +94,46 @@ void smt2_incremental_decision_proceduret::define_array_function(
100
94
convert_expr_to_smt (elements.at (i)))};
101
95
solver_process->send (element_definition);
102
96
}
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);
103
137
expression_identifiers.emplace (array, array_identifier);
104
138
}
105
139
@@ -168,9 +202,14 @@ void smt2_incremental_decision_proceduret::define_dependent_functions(
168
202
solver_process->send (function);
169
203
}
170
204
}
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))
172
206
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 (
174
213
const auto nondet_symbol =
175
214
expr_try_dynamic_cast<nondet_symbol_exprt>(current))
176
215
{
@@ -213,8 +252,7 @@ smt2_incremental_decision_proceduret::smt2_incremental_decision_proceduret(
213
252
{
214
253
solver_process->send (
215
254
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{}});
218
256
solver_process->send (object_size_function.declaration );
219
257
}
220
258
0 commit comments