Skip to content

Commit 4b6bfb9

Browse files
NikolajBjornerhgvk94
authored andcommitted
add constructor preservation axiom to update-field
1 parent 771e071 commit 4b6bfb9

File tree

1 file changed

+24
-21
lines changed

1 file changed

+24
-21
lines changed

src/smt/theory_datatype.cpp

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,17 @@ namespace smt {
8484
*/
8585
void theory_datatype::assert_eq_axiom(enode * lhs, expr * rhs, literal antecedent) {
8686
ast_manager & m = get_manager();
87+
88+
if (antecedent != null_literal) {
89+
std::function<void(void)> fn = [&]() {
90+
app_ref body(m);
91+
body = m.mk_eq(lhs->get_owner(), rhs);
92+
body = m.mk_implies(get_context().bool_var2expr(antecedent.var()), body);
93+
log_axiom_instantiation(body, 1, &lhs);
94+
};
95+
scoped_trace_stream _st(m, fn);
96+
}
97+
8798
context & ctx = get_context();
8899
if (m.proofs_enabled()) {
89100
literal l(mk_eq(lhs->get_owner(), rhs, true));
@@ -146,15 +157,6 @@ namespace smt {
146157
}
147158
expr_ref mk(m.mk_app(c, args), m);
148159

149-
std::function<void(void)> fn = [&]() {
150-
app_ref body(m);
151-
body = m.mk_eq(e, mk);
152-
if (antecedent != null_literal) {
153-
body = m.mk_implies(get_context().bool_var2expr(antecedent.var()), body);
154-
}
155-
log_axiom_instantiation(body, 1, &n);
156-
};
157-
scoped_trace_stream _st(m, fn);
158160
assert_eq_axiom(n, mk, antecedent);
159161
}
160162

@@ -183,13 +185,14 @@ namespace smt {
183185
for (func_decl * acc : accessors) {
184186
app_ref acc_app(m.mk_app(acc, n->get_owner()), m);
185187
enode * arg = n->get_arg(i);
186-
if (m.has_trace_stream()) {
188+
189+
std::function<void(void)> fn = [&]() {
187190
app_ref body(m);
188191
body = m.mk_eq(arg->get_owner(), acc_app);
189192
log_axiom_instantiation(body, base_id + 3*i, bindings.size(), bindings.c_ptr(), base_id - 3, used_enodes);
190-
}
193+
};
194+
scoped_trace_stream _st(m, fn);
191195
assert_eq_axiom(arg, acc_app, null_literal);
192-
if (m.has_trace_stream()) m.trace_stream() << "[end-of-instance]\n";
193196
++i;
194197
}
195198
}
@@ -220,6 +223,7 @@ namespace smt {
220223
(=> (is-C r) (= (acc_j n) (acc_j r))) for acc_j != field
221224
(=> (is-C r) (= (field n) v)) for acc_j != field
222225
(=> (not (is-C r)) (= n r))
226+
(=> (is-C r) (is-C n))
223227
*/
224228
void theory_datatype::assert_update_field_axioms(enode * n) {
225229
m_stats.m_assert_update_field++;
@@ -236,7 +240,7 @@ namespace smt {
236240
app_ref rec_app(m.mk_app(rec, arg1), m);
237241
app_ref acc_app(m);
238242
ctx.internalize(rec_app, false);
239-
literal is_con(ctx.get_bool_var(rec_app));
243+
literal is_con(ctx.get_bool_var(rec_app));
240244
for (func_decl* acc1 : accessors) {
241245
enode* arg;
242246
if (acc1 == acc) {
@@ -248,19 +252,18 @@ namespace smt {
248252
arg = ctx.get_enode(acc_app);
249253
}
250254
app_ref acc_own(m.mk_app(acc1, own), m);
251-
if (m.has_trace_stream()) {
252-
app_ref body(m);
253-
body = m.mk_implies(rec_app, m.mk_eq(arg->get_owner(), acc_own));
254-
log_axiom_instantiation(body, 1, &n);
255-
}
256255
assert_eq_axiom(arg, acc_own, is_con);
257-
if (m.has_trace_stream()) m.trace_stream() << "[end-of-instance]\n";
258256
}
259257
// update_field is identity if 'n' is not created by a matching constructor.
260258
app_ref imp(m.mk_implies(m.mk_not(rec_app), m.mk_eq(n->get_owner(), arg1)), m);
261-
if (m.has_trace_stream()) log_axiom_instantiation(imp, 1, &n);
262259
assert_eq_axiom(n, arg1, ~is_con);
263-
if (m.has_trace_stream()) m.trace_stream() << "[end-of-instance]\n";
260+
261+
app_ref n_is_con(m.mk_app(rec, own), m);
262+
ctx.internalize(n_is_con, false);
263+
literal lits[2] = { ~is_con, literal(ctx.get_bool_var(n_is_con)) };
264+
std::function<literal_vector(void)> fn = [&]() { return literal_vector(2, lits); };
265+
scoped_trace_stream _st(*this, fn);
266+
ctx.mk_th_axiom(get_id(), 2, lits);
264267
}
265268

266269
theory_var theory_datatype::mk_var(enode * n) {

0 commit comments

Comments
 (0)