@@ -32,9 +32,10 @@ namespace euf {
32
32
* retrieve extension that is associated with Boolean variable.
33
33
*/
34
34
sat::th_solver* solver::get_solver (sat::bool_var v) {
35
- if (v >= m_var2node.size ())
35
+ unsigned idx = literal (v, false ).index ();
36
+ if (idx >= m_lit2node.size ())
36
37
return nullptr ;
37
- euf::enode* n = m_var2node[v]. first ;
38
+ euf::enode* n = m_lit2node[idx] ;
38
39
if (!n)
39
40
return nullptr ;
40
41
return get_solver (n->get_owner ());
@@ -53,6 +54,8 @@ namespace euf {
53
54
auto * ext = m_id2solver.get (fid, nullptr );
54
55
if (ext)
55
56
return ext;
57
+ if (fid == m.get_basic_family_id ())
58
+ return nullptr ;
56
59
pb_util pb (m);
57
60
if (pb.get_family_id () == fid) {
58
61
ext = alloc (sat::ba_solver, m, si);
@@ -74,8 +77,11 @@ namespace euf {
74
77
}
75
78
76
79
void solver::unhandled_function (func_decl* f) {
80
+ if (m_unhandled_functions.contains (f))
81
+ return ;
82
+ m_unhandled_functions.push_back (f);
83
+ m_trail.push_back (new (m_region) push_back_vector<solver, func_decl_ref_vector>(m_unhandled_functions));
77
84
IF_VERBOSE (0 , verbose_stream () << mk_pp (f, m) << " not handled\n " );
78
- // TBD: set some state with the unhandled function.
79
85
}
80
86
81
87
bool solver::propagate (literal l, ext_constraint_idx idx) {
@@ -88,16 +94,14 @@ namespace euf {
88
94
void solver::get_antecedents (literal l, ext_justification_idx idx, literal_vector& r) {
89
95
auto * ext = sat::constraint_base::to_extension (idx);
90
96
if (ext == this )
91
- get_antecedents (l, * constraint::from_idx (idx), r);
97
+ get_antecedents (l, constraint::from_idx (idx), r);
92
98
else
93
99
ext->get_antecedents (l, idx, r);
94
100
}
95
101
96
102
void solver::get_antecedents (literal l, constraint& j, literal_vector& r) {
97
103
m_explain.reset ();
98
104
euf::enode* n = nullptr ;
99
- bool sign = false ;
100
- enode_bool_pair p;
101
105
102
106
// init_ackerman();
103
107
@@ -107,20 +111,19 @@ namespace euf {
107
111
m_egraph.explain <unsigned >(m_explain);
108
112
break ;
109
113
case constraint::kind_t ::eq:
110
- n = m_var2node [l.var ()]. first ;
114
+ n = m_lit2node [l.index ()];
111
115
SASSERT (n);
112
116
SASSERT (m_egraph.is_equality (n));
113
117
m_egraph.explain_eq <unsigned >(m_explain, n->get_arg (0 ), n->get_arg (1 ), n->commutative ());
114
118
break ;
115
119
case constraint::kind_t ::lit:
116
- p = m_var2node[l.var ()];
117
- n = p.first ;
118
- sign = l.sign () != p.second ;
120
+ n = m_lit2node[l.index ()];
119
121
SASSERT (n);
120
122
SASSERT (m.is_bool (n->get_owner ()));
121
- m_egraph.explain_eq <unsigned >(m_explain, n, (sign ? mk_false () : mk_true ()), false );
123
+ m_egraph.explain_eq <unsigned >(m_explain, n, (l. sign () ? mk_false () : mk_true ()), false );
122
124
break ;
123
125
default :
126
+ std::cout << (unsigned )j.kind () << " \n " ;
124
127
UNREACHABLE ();
125
128
}
126
129
for (unsigned * idx : m_explain)
@@ -135,20 +138,22 @@ namespace euf {
135
138
return ;
136
139
}
137
140
138
- auto p = m_var2node.get (l.var (), enode_bool_pair (nullptr , false ));
139
- if (!p.first )
141
+ bool sign = l.sign ();
142
+ unsigned idx = sat::literal (l.var (), false ).index ();
143
+ auto n = m_lit2node.get (idx, nullptr );
144
+ if (!n)
140
145
return ;
141
146
force_push ();
142
- bool sign = p.second != l.sign ();
143
- euf::enode* n = p.first ;
147
+
144
148
expr* e = n->get_owner ();
145
149
if (m.is_eq (e) && !sign) {
146
150
euf::enode* na = n->get_arg (0 );
147
151
euf::enode* nb = n->get_arg (1 );
148
152
m_egraph.merge (na, nb, base_ptr () + l.index ());
149
153
}
150
- else {
154
+ else {
151
155
euf::enode* nb = sign ? mk_false () : mk_true ();
156
+ std::cout << " merge " << n->get_owner_id () << " " << sign << " " << nb->get_owner_id () << " \n " ;
152
157
m_egraph.merge (n, nb, base_ptr () + l.index ());
153
158
}
154
159
// TBD: delay propagation?
@@ -216,39 +221,36 @@ namespace euf {
216
221
}
217
222
218
223
void solver::push () {
219
- ++m_num_scopes;
224
+ scope s;
225
+ s.m_lit_lim = m_lit_trail.size ();
226
+ s.m_trail_lim = m_trail.size ();
227
+ m_scopes.push_back (s);
228
+ m_region.push_scope ();
229
+ for (auto * e : m_solvers)
230
+ e->push ();
231
+ m_egraph.push ();
220
232
}
221
233
222
234
void solver::force_push () {
223
235
for (; m_num_scopes > 0 ; --m_num_scopes) {
224
- scope s;
225
- s.m_bool_var_lim = m_bool_var_trail.size ();
226
- s.m_trail_lim = m_trail.size ();
227
- m_scopes.push_back (s);
228
- for (auto * e : m_solvers)
229
- e->push ();
230
- m_egraph.push ();
236
+
231
237
}
232
238
}
233
239
234
240
void solver::pop (unsigned n) {
235
- if (n <= m_num_scopes) {
236
- m_num_scopes -= n;
237
- return ;
238
- }
239
- n -= m_num_scopes;
240
241
m_egraph.pop (n);
241
242
for (auto * e : m_solvers)
242
243
e->pop (n);
243
244
244
- scope & s = m_scopes[m_scopes.size () - n];
245
+ scope const & s = m_scopes[m_scopes.size () - n];
245
246
246
- for (unsigned i = m_bool_var_trail .size (); i-- > s.m_bool_var_lim ; )
247
- m_var2node[m_bool_var_trail [i]] = enode_bool_pair ( nullptr , false ) ;
248
- m_bool_var_trail .shrink (s.m_bool_var_lim );
247
+ for (unsigned i = m_lit_trail .size (); i-- > s.m_lit_lim ; )
248
+ m_lit2node[m_lit_trail [i]] = nullptr ;
249
+ m_lit_trail .shrink (s.m_lit_lim );
249
250
250
251
undo_trail_stack (*this , m_trail, s.m_trail_lim );
251
-
252
+
253
+ m_region.pop_scope (n);
252
254
m_scopes.shrink (m_scopes.size () - n);
253
255
}
254
256
@@ -278,6 +280,10 @@ namespace euf {
278
280
279
281
std::ostream& solver::display (std::ostream& out) const {
280
282
m_egraph.display (out);
283
+ for (unsigned idx : m_lit_trail) {
284
+ euf::enode* n = m_lit2node[idx];
285
+ out << sat::to_literal (idx) << " : " << m_egraph.pp (n);
286
+ }
281
287
for (auto * e : m_solvers)
282
288
e->display (out);
283
289
return out;
@@ -363,8 +369,8 @@ namespace euf {
363
369
unsigned solver::max_var (unsigned w) const {
364
370
for (auto * e : m_solvers)
365
371
w = e->max_var (w);
366
- for (unsigned sz = m_var2node .size (); sz-- > 0 ; ) {
367
- euf::enode* n = m_var2node [sz]. first ;
372
+ for (unsigned sz = m_lit2node .size (); sz-- > 0 ; ) {
373
+ euf::enode* n = m_lit2node [sz];
368
374
if (n && m.is_bool (n->get_owner ())) {
369
375
w = std::max (w, sz);
370
376
break ;
@@ -452,13 +458,12 @@ namespace euf {
452
458
return n;
453
459
if (si.is_bool_op (e)) {
454
460
sat::literal lit = si.internalize (e);
455
- enode_bool_pair bp (nullptr , false );
456
- n = m_var2node.get (lit.var (), bp).first ;
461
+ n = m_lit2node.get (lit.index (), nullptr );
457
462
if (n)
458
463
return n;
459
464
460
465
n = m_egraph.mk (e, 0 , nullptr );
461
- attach_bool_var (lit. var (), lit. sign () , n);
466
+ attach_lit (lit, n);
462
467
if (!m.is_true (e) && !m.is_false (e))
463
468
s ().set_external (lit.var ());
464
469
return n;
@@ -476,15 +481,16 @@ namespace euf {
476
481
expr* e = n->get_owner ();
477
482
if (m.is_bool (e)) {
478
483
sat::bool_var v = si.add_bool_var (e);
479
- attach_bool_var ( v, false , n);
484
+ attach_lit ( literal ( v, false ), n);
480
485
}
481
486
}
482
487
483
- void solver::attach_bool_var (sat::bool_var v, bool sign, euf::enode* n) {
484
- m_var2node.reserve (v + 1 , enode_bool_pair (nullptr , false ));
485
- SASSERT (m_var2node[v].first == nullptr );
486
- m_var2node[v] = euf::enode_bool_pair (n, sign);
487
- m_bool_var_trail.push_back (v);
488
+ void solver::attach_lit (literal lit, euf::enode* n) {
489
+ unsigned v = lit.index ();
490
+ m_lit2node.reserve (v + 1 , nullptr );
491
+ SASSERT (m_lit2node[v] == nullptr );
492
+ m_lit2node[v] = n;
493
+ m_lit_trail.push_back (v);
488
494
}
489
495
490
496
bool solver::to_formulas (std::function<expr_ref(sat::literal)>& l2e, expr_ref_vector& fmls) {
0 commit comments