Skip to content

Commit a5a819c

Browse files
port updates to egraph from poly
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
1 parent 24ffef8 commit a5a819c

11 files changed

+89
-52
lines changed

src/ast/euf/euf_ac_plugin.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ namespace euf {
109109
m_shared_nodes.setx(n->get_id(), true, false);
110110
sort(monomial(m));
111111
m_shared_todo.insert(m_shared.size());
112-
m_shared.push_back({ n, m, justification::axiom() });
112+
m_shared.push_back({ n, m, justification::axiom(get_id()) });
113113
push_undo(is_register_shared);
114114
}
115115

src/ast/euf/euf_ac_plugin.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ namespace euf {
137137
}
138138
};
139139

140-
unsigned m_fid = 0;
140+
theory_id m_fid = 0;
141141
unsigned m_op = null_decl_kind;
142142
func_decl* m_decl = nullptr;
143143
vector<eq> m_eqs;
@@ -273,7 +273,7 @@ namespace euf {
273273

274274
~ac_plugin() override {}
275275

276-
unsigned get_id() const override { return m_fid; }
276+
theory_id get_id() const override { return m_fid; }
277277

278278
void register_node(enode* n) override;
279279

src/ast/euf/euf_arith_plugin.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ namespace euf {
3535

3636
~arith_plugin() override {}
3737

38-
unsigned get_id() const override { return a.get_family_id(); }
38+
theory_id get_id() const override { return a.get_family_id(); }
3939

4040
void register_node(enode* n) override;
4141

src/ast/euf/euf_bv_plugin.cpp

+59-35
Original file line numberDiff line numberDiff line change
@@ -161,20 +161,27 @@ namespace euf {
161161
void bv_plugin::propagate_values(enode* x) {
162162
if (!is_value(x))
163163
return;
164-
164+
165+
auto val_x = get_value(x);
165166
enode* a, * b;
166-
for (enode* p : enode_parents(x))
167-
if (is_concat(p, a, b) && is_value(a) && is_value(b) && !is_value(p))
167+
unsigned lo, hi;
168+
for (enode* p : enode_parents(x)) {
169+
if (is_concat(p, a, b) && is_value(a) && is_value(b))
168170
push_merge(mk_concat(a->get_interpreted(), b->get_interpreted()), mk_value_concat(a, b));
169-
171+
172+
if (is_extract(p, lo, hi)) {
173+
auto val_p = mod2k(machine_div2k(val_x, lo), hi - lo + 1);
174+
auto ix = x->get_interpreted();
175+
auto ex = mk(bv.mk_extract(hi, lo, ix->get_expr()), 1, &ix);
176+
push_merge(ex, mk_value(val_p, width(p)));
177+
}
178+
}
179+
170180
for (enode* sib : enode_class(x)) {
171181
if (is_concat(sib, a, b)) {
172-
if (!is_value(a) || !is_value(b)) {
173-
auto val = get_value(x);
174-
auto val_a = machine_div2k(val, width(b));
175-
auto val_b = mod2k(val, width(b));
176-
push_merge(mk_concat(mk_value(val_a, width(a)), mk_value(val_b, width(b))), x->get_interpreted());
177-
}
182+
auto val_a = machine_div2k(val_x, width(b));
183+
auto val_b = mod2k(val_x, width(b));
184+
push_merge(mk_concat(mk_value(val_a, width(a)), mk_value(val_b, width(b))), x->get_interpreted());
178185
}
179186
}
180187
}
@@ -198,7 +205,9 @@ namespace euf {
198205
enode* arg_r = arg->get_root();
199206
enode* n_r = n->get_root();
200207

208+
m_ensure_concat.reset();
201209
auto ensure_concat = [&](unsigned lo, unsigned mid, unsigned hi) {
210+
// verbose_stream() << lo << " " << mid << " " << hi << "\n";
202211
TRACE("bv", tout << "ensure-concat " << lo << " " << mid << " " << hi << "\n");
203212
unsigned lo_, hi_;
204213
for (enode* p1 : enode_parents(n))
@@ -212,14 +221,14 @@ namespace euf {
212221
TRACE("bv", tout << "propagate-above " << g.bpp(b) << "\n");
213222
for (enode* sib : enode_class(b))
214223
if (is_extract(sib, lo2, hi2) && sib->get_arg(0)->get_root() == arg_r && hi1 + 1 == lo2)
215-
ensure_concat(lo1, hi1, hi2);
224+
m_ensure_concat.push_back({lo1, hi1, hi2});
216225
};
217226

218227
auto propagate_below = [&](enode* a) {
219228
TRACE("bv", tout << "propagate-below " << g.bpp(a) << "\n");
220229
for (enode* sib : enode_class(a))
221230
if (is_extract(sib, lo2, hi2) && sib->get_arg(0)->get_root() == arg_r && hi2 + 1 == lo1)
222-
ensure_concat(lo2, hi2, hi1);
231+
m_ensure_concat.push_back({lo2, hi2, hi1});
223232
};
224233

225234
for (enode* p : enode_parents(n)) {
@@ -230,6 +239,10 @@ namespace euf {
230239
propagate_above(a);
231240
}
232241
}
242+
243+
for (auto [lo, mid, hi] : m_ensure_concat)
244+
ensure_concat(lo, mid, hi);
245+
233246
}
234247

235248
class bv_plugin::undo_split : public trail {
@@ -432,13 +445,14 @@ namespace euf {
432445
delta += width(arg);
433446
}
434447
}
435-
}
436-
for (auto p : euf::enode_parents(n->get_root())) {
437-
if (bv.is_extract(p->get_expr(), lo, hi, e)) {
438-
SASSERT(g.find(e)->get_root() == n->get_root());
439-
m_todo.push_back({ p, offset + lo });
448+
for (auto p : euf::enode_parents(sib)) {
449+
if (bv.is_extract(p->get_expr(), lo, hi, e)) {
450+
SASSERT(g.find(e)->get_root() == n->get_root());
451+
m_todo.push_back({ p, offset + lo });
452+
}
440453
}
441454
}
455+
442456
}
443457
clear_offsets();
444458
}
@@ -462,17 +476,17 @@ namespace euf {
462476
auto child = g.find(e);
463477
m_todo.push_back({ child, offset + lo });
464478
}
465-
}
466-
for (auto p : euf::enode_parents(n->get_root())) {
467-
if (bv.is_concat(p->get_expr())) {
468-
unsigned delta = 0;
469-
for (unsigned j = p->num_args(); j-- > 0; ) {
470-
auto arg = p->get_arg(j);
471-
if (arg->get_root() == n->get_root())
472-
m_todo.push_back({ p, offset + delta });
473-
delta += width(arg);
479+
for (auto p : euf::enode_parents(sib)) {
480+
if (bv.is_concat(p->get_expr())) {
481+
unsigned delta = 0;
482+
for (unsigned j = p->num_args(); j-- > 0; ) {
483+
auto arg = p->get_arg(j);
484+
if (arg->get_root() == n->get_root())
485+
m_todo.push_back({ p, offset + delta });
486+
delta += width(arg);
487+
}
474488
}
475-
}
489+
}
476490
}
477491
}
478492
clear_offsets();
@@ -511,6 +525,9 @@ namespace euf {
511525
m_offsets.reserve(n->get_root_id() + 1);
512526
m_offsets[n->get_root_id()].reset();
513527
}
528+
for (auto const& off : m_offsets) {
529+
SASSERT(off.empty());
530+
}
514531
m_jtodo.reset();
515532
return;
516533
}
@@ -521,20 +538,27 @@ namespace euf {
521538
just.push_back({ n, sib, j });
522539
for (unsigned j = sib->num_args(); j-- > 0; ) {
523540
auto arg = sib->get_arg(j);
524-
m_jtodo.push_back({ arg, offset + delta, j2 });
541+
m_jtodo.push_back({ arg, offs + delta, j2 });
525542
delta += width(arg);
526543
}
527544
}
528-
}
529-
for (auto p : euf::enode_parents(n->get_root())) {
530-
if (bv.is_extract(p->get_expr(), lo, hi, e)) {
531-
SASSERT(g.find(e)->get_root() == n->get_root());
532-
unsigned j2 = just.size();
533-
just.push_back({ g.find(e), n, j});
534-
m_jtodo.push_back({ p, offset + lo, j2});
545+
for (auto p : euf::enode_parents(sib)) {
546+
if (bv.is_extract(p->get_expr(), lo, hi, e)) {
547+
SASSERT(g.find(e)->get_root() == n->get_root());
548+
unsigned j2 = just.size();
549+
just.push_back({ g.find(e), n, j });
550+
m_jtodo.push_back({ p, offs + lo, j2 });
551+
}
535552
}
536553
}
554+
537555
}
556+
IF_VERBOSE(0,
557+
g.display(verbose_stream());
558+
verbose_stream() << g.bpp(a) << " offset " << offset << " " << g.bpp(b) << "\n";
559+
for (auto const& [n, offset, j] : m_jtodo)
560+
verbose_stream() << g.bpp(n) << " offset " << offset << " " << g.bpp(n->get_root()) << "\n";
561+
);
538562
UNREACHABLE();
539563
}
540564

src/ast/euf/euf_bv_plugin.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ namespace euf {
7272
bool unfold_width(enode* x, enode_vector& xs, enode* y, enode_vector& ys);
7373
bool unfold_sub(enode* x, enode_vector& xs);
7474
void merge(enode_vector& xs, enode_vector& ys, justification j);
75+
svector<std::tuple<unsigned, unsigned, unsigned>> m_ensure_concat;
7576
void propagate_extract(enode* n);
7677
void propagate_values(enode* n);
7778

@@ -96,7 +97,7 @@ namespace euf {
9697

9798
~bv_plugin() override {}
9899

99-
unsigned get_id() const override { return bv.get_family_id(); }
100+
theory_id get_id() const override { return bv.get_family_id(); }
100101

101102
void register_node(enode* n) override;
102103

src/ast/euf/euf_enode.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ namespace euf {
135135
enode* prev = this;
136136
justification js = m_justification;
137137
prev->m_target = nullptr;
138-
prev->m_justification = justification::axiom();
138+
prev->m_justification = justification::axiom(null_theory_id);
139139
while (curr != nullptr) {
140140
enode* new_curr = curr->m_target;
141141
justification new_js = curr->m_justification;

src/ast/euf/euf_enode.h

-4
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,6 @@ namespace euf {
3636
typedef std::pair<enode*,bool> enode_bool_pair;
3737
typedef svector<enode_bool_pair> enode_bool_pair_vector;
3838
typedef id_var_list<> th_var_list;
39-
typedef int theory_var;
40-
typedef int theory_id;
41-
const theory_var null_theory_var = -1;
42-
const theory_id null_theory_id = -1;
4339

4440
class enode {
4541
expr* m_expr = nullptr;

src/ast/euf/euf_justification.h

+19-4
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ namespace euf {
2828

2929
class enode;
3030

31+
typedef int theory_var;
32+
typedef int theory_id;
33+
const theory_var null_theory_var = -1;
34+
const theory_id null_theory_id = -1;
35+
3136
class justification {
3237
public:
3338
typedef stacked_dependency_manager<justification> dependency_manager;
@@ -42,6 +47,7 @@ namespace euf {
4247
};
4348
kind_t m_kind;
4449
union {
50+
int m_theory_id;
4551
bool m_comm;
4652
enode* m_n1;
4753
};
@@ -76,19 +82,27 @@ namespace euf {
7682
m_n2(n2)
7783
{}
7884

85+
justification(int theory_id):
86+
m_kind(kind_t::axiom_t),
87+
m_theory_id(theory_id),
88+
m_external(nullptr)
89+
{}
90+
7991
public:
92+
8093
justification():
8194
m_kind(kind_t::axiom_t),
82-
m_comm(false),
95+
m_theory_id(null_theory_id),
8396
m_external(nullptr)
8497
{}
8598

86-
static justification axiom() { return justification(); }
99+
static justification axiom(int theory_id) { return justification(theory_id); }
87100
static justification congruence(bool c, uint64_t ts) { return justification(c, ts); }
88101
static justification external(void* ext) { return justification(ext); }
89102
static justification dependent(dependency* d) { return justification(d, 1); }
90103
static justification equality(enode* a, enode* b) { return justification(a, b); }
91104

105+
bool is_axiom() const { return m_kind == kind_t::axiom_t; }
92106
bool is_external() const { return m_kind == kind_t::external_t; }
93107
bool is_congruence() const { return m_kind == kind_t::congruence_t; }
94108
bool is_commutative() const { return m_comm; }
@@ -98,6 +112,7 @@ namespace euf {
98112
enode* lhs() const { SASSERT(is_equality()); return m_n1; }
99113
enode* rhs() const { SASSERT(is_equality()); return m_n2; }
100114
uint64_t timestamp() const { SASSERT(is_congruence()); return m_timestamp; }
115+
theory_id get_theory_id() const { SASSERT(is_axiom()); return m_theory_id; }
101116
template <typename T>
102117
T* ext() const { SASSERT(is_external()); return static_cast<T*>(m_external); }
103118

@@ -106,15 +121,15 @@ namespace euf {
106121
case kind_t::external_t:
107122
return external(copy_justification(m_external));
108123
case kind_t::axiom_t:
109-
return axiom();
124+
return axiom(m_theory_id);
110125
case kind_t::congruence_t:
111126
return congruence(m_comm, m_timestamp);
112127
case kind_t::dependent_t:
113128
NOT_IMPLEMENTED_YET();
114129
return dependent(m_dependency);
115130
default:
116131
UNREACHABLE();
117-
return axiom();
132+
return axiom(-1);
118133
}
119134
}
120135

src/ast/euf/euf_plugin.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,13 @@ namespace euf {
2626
}
2727

2828
void plugin::push_merge(enode* a, enode* b, justification j) {
29+
TRACE("euf", tout << "push-merge " << g.bpp(a) << " == " << g.bpp(b) << " " << j << "\n");
2930
g.push_merge(a, b, j);
3031
}
3132

3233
void plugin::push_merge(enode* a, enode* b) {
3334
TRACE("plugin", tout << g.bpp(a) << " == " << g.bpp(b) << "\n");
34-
g.push_merge(a, b, justification::axiom());
35+
g.push_merge(a, b, justification::axiom(get_id()));
3536
}
3637

3738
enode* plugin::mk(expr* e, unsigned n, enode* const* args) {

src/ast/euf/euf_plugin.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ namespace euf {
4040

4141
virtual ~plugin() {}
4242

43-
virtual unsigned get_id() const = 0;
43+
virtual theory_id get_id() const = 0;
4444

4545
virtual void register_node(enode* n) = 0;
4646

src/ast/euf/euf_specrel_plugin.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ namespace euf {
3737

3838
~specrel_plugin() override {}
3939

40-
unsigned get_id() const override { return sp.get_family_id(); }
40+
theory_id get_id() const override { return sp.get_family_id(); }
4141

4242
void register_node(enode* n) override;
4343

0 commit comments

Comments
 (0)