@@ -13,14 +13,12 @@ Module Name:
13
13
14
14
Hari Govind V K (hgvk94) 2023-03-07
15
15
16
- Revision History:
17
-
18
16
--*/
19
17
20
- #include " qe/mbp/mbp_arrays_tg.h"
21
18
#include " ast/array_decl_plugin.h"
22
19
#include " ast/array_peq.h"
23
20
#include " qe/mbp/mbp_qel_util.h"
21
+ #include " qe/mbp/mbp_arrays_tg.h"
24
22
#include " util/obj_hashtable.h"
25
23
#include " util/obj_pair_hashtable.h"
26
24
@@ -83,8 +81,10 @@ struct mbp_array_tg::impl {
83
81
// Returns true if e has a subterm store(v) where v is a variable to be
84
82
// eliminated. Recurses on subexpressions of ee
85
83
bool has_stores (expr *e) {
86
- if (m_has_stores.is_marked (e)) return true ;
87
- if (!is_app (e)) return false ;
84
+ if (m_has_stores.is_marked (e))
85
+ return true ;
86
+ if (!is_app (e))
87
+ return false ;
88
88
if (m_array_util.is_store (e) && is_var (to_app (e)->get_arg (0 ))) {
89
89
m_has_stores.mark (e, true );
90
90
return true ;
@@ -94,7 +94,7 @@ struct mbp_array_tg::impl {
94
94
return true ;
95
95
}
96
96
// recurse
97
- for (auto c : *(to_app (e))) {
97
+ for (auto c : *(to_app (e))) {
98
98
if (has_stores (c)) {
99
99
m_has_stores.mark (e, true );
100
100
return true ;
@@ -166,56 +166,73 @@ struct mbp_array_tg::impl {
166
166
}
167
167
168
168
// rewrite store(x, j, elem) \peq_{indices} y
169
- // into either j = i && x \peq_{indices} y (for some i in
170
- // indices) or &&_{i \in indices} j \neq i &&
169
+ // into either j = i && x \peq_{indices} y (for some i in indices)
170
+ // or &&_{i \in indices} j \neq i &&
171
171
// x \peq_{indices, j} y &&
172
172
// select(y, j) = elem
173
173
// rewrite negation !(store(x, j, elem) \peq_{indices} y) into
174
- // into either j = i && !(x \peq_{indices} y) (for some i in
175
- // indices) or &&_{i \in indices} j \neq i &&
174
+ // into either j = i && !(x \peq_{indices} y) (for some i in indices)
175
+ // or &&_{i \in indices} j \neq i &&
176
176
// !(x \peq_{indices, j} y) &&
177
- // or &&_{i \in indices} j \neq i &&
177
+ // or &&_{i \in indices} j \neq i &&
178
178
// !(select(y, j) = elem)
179
179
void elimwreq (peq p, bool is_neg) {
180
- expr* a = nullptr , *j = nullptr , *elem = nullptr ;
181
- VERIFY (is_arr_write (p.lhs (), a, j, elem)); // TDOO: make this work with multi-arity arrays
180
+
181
+ SASSERT (m_array_util.is_store (p.lhs ()));
182
+ expr* a = to_app (p.lhs ())->get_arg (0 );
183
+ auto js = array_store_indices (to_app (p.lhs ()));
184
+ auto elem = array_store_elem (to_app (p.lhs ()));
185
+
182
186
TRACE (" mbp_tg" ,
183
187
tout << " applying elimwreq on " << expr_ref (p.mk_peq (), m) << " is neg: " << is_neg << " \n " );
184
188
vector<expr_ref_vector> indices;
185
189
bool in = false ;
186
- p.get_diff_indices (indices);
187
- expr_ref eq_index (m) ;
188
- expr_ref_vector deq (m) ;
190
+ p.get_diff_indices (indices);
191
+ unsigned eq_index = UINT_MAX, idx = 0 ;
192
+ svector<std::pair<expr*, expr*>> deq;
189
193
for (expr_ref_vector &e : indices) {
190
- for (expr *i : e) {
191
- if (m_mdl. are_equal (j, i)) {
192
- in = true ;
193
- // save for later
194
- eq_index = i;
195
- break ;
196
- }
197
- else
198
- deq. push_back (i) ;
194
+ auto jit = js. begin ();
195
+ bool is_eq = true ;
196
+ for (expr* i : e) {
197
+ if (!m_mdl. are_equal (*jit, i)) {
198
+ if (is_eq)
199
+ deq. push_back ({ *jit, i }) ;
200
+ is_eq = false ;
201
+ }
202
+ ++jit ;
199
203
}
204
+ if (is_eq) {
205
+ in = true ;
206
+ eq_index = idx;
207
+ break ;
208
+ }
200
209
}
201
210
if (in) {
202
- SASSERT (m_mdl.are_equal (j, eq_index));
203
- peq p_new =
204
- mk_wr_peq (a, p.rhs (), indices);
205
- m_tg.add_eq (j, eq_index);
211
+ peq p_new = mk_wr_peq (a, p.rhs (), indices);
212
+ auto jit = js.begin ();
213
+ for (expr* i : indices[eq_index]) {
214
+ m_tg.add_eq (*jit, i);
215
+ ++jit;
216
+ }
206
217
expr_ref p_new_expr (m);
207
218
p_new_expr = is_neg ? m.mk_not (p_new.mk_peq ()) : p_new.mk_peq ();
208
219
m_tg.add_lit (p_new_expr);
209
220
m_tg.add_eq (p_new.mk_peq (), p.mk_peq ());
210
221
return ;
211
222
}
212
- for (expr *d : deq)
213
- m_tg.add_deq (j, d);
223
+ for (auto [i, j] : deq)
224
+ m_tg.add_deq (i, j);
225
+
214
226
expr_ref_vector setOne (m);
215
- setOne.push_back (j);
227
+ for (auto j : js)
228
+ setOne.push_back (j);
216
229
indices.push_back (setOne);
217
230
peq p_new = mk_wr_peq (a, p.rhs (), indices);
218
- expr_ref rd (m_array_util.mk_select (p.rhs (), j), m);
231
+ ptr_buffer<expr> args;
232
+ args.push_back (p.rhs ());
233
+ for (auto j : js)
234
+ args.push_back (j);
235
+ expr_ref rd (m_array_util.mk_select (args), m);
219
236
if (!is_neg) {
220
237
m_tg.add_lit (p_new.mk_peq ());
221
238
m_tg.add_eq (rd, elem);
@@ -273,8 +290,7 @@ struct mbp_array_tg::impl {
273
290
}
274
291
275
292
// rewrite select(store(a, i, k), j) into either select(a, j) or k
276
- void elimrdwr (expr *_term) {
277
- app* term = to_app (_term);
293
+ void elimrdwr (app *term) {
278
294
TRACE (" mbp_tg" , tout << " applying elimrdwr on " << expr_ref (term, m););
279
295
auto rd_indices = array_select_indices (term);
280
296
auto store_term = to_app (term->get_arg (0 ));
@@ -370,11 +386,10 @@ struct mbp_array_tg::impl {
370
386
continue ;
371
387
}
372
388
}
373
- TRACE (" mbp_tg" , tout << " not applying any rules on " << expr_ref (nt, m) << " " << is_rd_wr (nt) << " " << m_use_mdl << " \n " ;);
374
389
if (m_use_mdl && is_rd_wr (nt)) {
375
390
mark_seen (term);
376
391
progress = true ;
377
- elimrdwr (nt );
392
+ elimrdwr (to_app (nt) );
378
393
continue ;
379
394
}
380
395
}
0 commit comments