bool solve_arith_core(app * lhs, expr * rhs, expr * eq, app_ref & var, expr_ref & def, proof_ref & pr) { SASSERT(m_a_util.is_add(lhs)); bool is_int = m_a_util.is_int(lhs); expr * a = nullptr; expr * v = nullptr; rational a_val; unsigned num = lhs->get_num_args(); unsigned i; for (i = 0; i < num; i++) { expr * arg = lhs->get_arg(i); if (is_uninterp_const(arg) && !m_candidate_vars.is_marked(arg) && check_occs(arg) && !occurs(arg, rhs) && !occurs_except(arg, lhs, i)) { a_val = rational(1); v = arg; break; } else if (m_a_util.is_mul(arg, a, v) && is_uninterp_const(v) && !m_candidate_vars.is_marked(v) && m_a_util.is_numeral(a, a_val) && !a_val.is_zero() && (!is_int || a_val.is_minus_one()) && check_occs(v) && !occurs(v, rhs) && !occurs_except(v, lhs, i)) { break; } } if (i == num) return false; var = to_app(v); expr_ref inv_a(m()); if (!a_val.is_one()) { inv_a = m_a_util.mk_numeral(rational(1)/a_val, is_int); rhs = m_a_util.mk_mul(inv_a, rhs); } ptr_buffer<expr> other_args; for (unsigned j = 0; j < num; j++) { if (i != j) { if (inv_a) other_args.push_back(m_a_util.mk_mul(inv_a, lhs->get_arg(j))); else other_args.push_back(lhs->get_arg(j)); } } switch (other_args.size()) { case 0: def = rhs; break; case 1: def = m_a_util.mk_sub(rhs, other_args[0]); break; default: def = m_a_util.mk_sub(rhs, m_a_util.mk_add(other_args.size(), other_args.c_ptr())); break; } if (m_produce_proofs) pr = m().mk_rewrite(eq, m().mk_eq(var, def)); return true; }
bool is_x_minus_y_eq_0(expr * t, expr * & x, expr * & y) { expr * lhs, * rhs, * m1, * m2; if (m.is_eq(t, lhs, rhs) && m_util.is_zero(rhs) && m_util.is_add(lhs, m1, m2)) { if (m_util.is_times_minus_one(m2, y) && is_uninterp_const(m1)) { x = m1; return true; } if (m_util.is_times_minus_one(m1, y) && is_uninterp_const(m2)) { x = m2; return true; } } return false; }
void set_value_p(app* e, expr* v) { SASSERT(e->get_num_args() == 0); SASSERT(is_uninterp_const(e)); m_const.push_back(std::make_pair(e, v)); m_refs.push_back(e); m_refs.push_back(v); }
func_decl_ref bvarray2uf_rewriter_cfg::mk_uf_for_array(expr * e) { SASSERT(is_bv_array(e)); if (m_array_util.is_as_array(e)) return func_decl_ref(static_cast<func_decl*>(to_app(e)->get_decl()->get_parameter(0).get_ast()), m_manager); else { app * a = to_app(e); func_decl * bv_f = 0; if (!m_arrays_fs.find(e, bv_f)) { sort * domain = get_index_sort(a); sort * range = get_value_sort(a); bv_f = m_manager.mk_fresh_func_decl("f_t", "", 1, &domain, range); if (is_uninterp_const(e)) { if (m_emc) m_emc->insert(to_app(e)->get_decl(), m_array_util.mk_as_array(m_manager.get_sort(e), bv_f)); } else if (m_fmc) m_fmc->insert(bv_f); m_arrays_fs.insert(e, bv_f); m_manager.inc_ref(bv_f); } return func_decl_ref(bv_f, m_manager); } }
void collect_bounds(goal const & g) { unsigned sz = g.size(); numeral val; unsigned bv_sz; expr * f, * lhs, * rhs; for (unsigned i = 0; i < sz; i++) { bool negated = false; f = g.form(i); if (m.is_not(f)) { negated = true; f = to_app(f)->get_arg(0); } if (m_util.is_bv_sle(f, lhs, rhs)) { bv_sz = m_util.get_bv_size(lhs); if (is_uninterp_const(lhs) && m_util.is_numeral(rhs, val, bv_sz)) { TRACE("bv_size_reduction", tout << (negated?"not ":"") << mk_ismt2_pp(f, m) << std::endl; ); // v <= k val = m_util.norm(val, bv_sz, true); if (negated) { val += numeral(1); if (m_util.norm(val, bv_sz, true) != val) { // bound is infeasible. } else { update_signed_lower(to_app(lhs), val); } } else update_signed_upper(to_app(lhs), val); }
void operator()(app * n) { if (!compatible_sort(n)) throw found(); family_id fid = n->get_family_id(); if (fid == m.get_basic_family_id()) return; if (fid == u.get_family_id()) { switch (n->get_decl_kind()) { case OP_LE: case OP_GE: case OP_LT: case OP_GT: case OP_ADD: case OP_NUM: return; case OP_MUL: if (n->get_num_args() != 2) throw found(); if (!u.is_numeral(n->get_arg(0))) throw found(); return; case OP_TO_REAL: if (!m_real) throw found(); break; default: throw found(); } return; } if (is_uninterp_const(n)) return; throw found(); }
void process(expr * f) { if (fvisited.is_marked(f)) return; fvisited.mark(f); todo.push_back(f); while (!todo.empty()) { expr * t = todo.back(); todo.pop_back(); if (is_uninterp_const(t)) continue; if (is_app(t) && to_app(t)->get_family_id() == m.get_basic_family_id() && to_app(t)->get_num_args() > 0) { decl_kind k = to_app(t)->get_decl_kind(); if (k == OP_OR || k == OP_NOT || k == OP_IFF || ((k == OP_EQ || k == OP_ITE) && m.is_bool(to_app(t)->get_arg(1)))) { unsigned num = to_app(t)->get_num_args(); for (unsigned i = 0; i < num; i++) { expr * arg = to_app(t)->get_arg(i); if (fvisited.is_marked(arg)) continue; fvisited.mark(arg); todo.push_back(arg); } } } else { quick_for_each_expr(proc, tvisited, t); } } }
lbool get_consequences_core(expr_ref_vector const& asms, expr_ref_vector const& vars, expr_ref_vector& consequences) override { datatype_util dt(m); bv_util bv(m); expr_ref_vector bvars(m), conseq(m), bounds(m); // ensure that enumeration variables that // don't occur in the constraints // are also internalized. for (expr* v : vars) { expr_ref tmp(m.mk_eq(v, v), m); proof_ref proof(m); m_rewriter(tmp, tmp, proof); } m_rewriter.flush_side_constraints(bounds); m_solver->assert_expr(bounds); // translate enumeration constants to bit-vectors. for (expr* v : vars) { func_decl* f = nullptr; if (is_app(v) && is_uninterp_const(v) && m_rewriter.enum2bv().find(to_app(v)->get_decl(), f)) { bvars.push_back(m.mk_const(f)); } else { bvars.push_back(v); } } lbool r = m_solver->get_consequences(asms, bvars, consequences); // translate bit-vector consequences back to enumeration types for (unsigned i = 0; i < consequences.size(); ++i) { expr* a = nullptr, *b = nullptr, *u = nullptr, *v = nullptr; func_decl* f; rational num; unsigned bvsize; VERIFY(m.is_implies(consequences[i].get(), a, b)); if (m.is_eq(b, u, v) && is_uninterp_const(u) && m_rewriter.bv2enum().find(to_app(u)->get_decl(), f) && bv.is_numeral(v, num, bvsize)) { SASSERT(num.is_unsigned()); expr_ref head(m); ptr_vector<func_decl> const& enums = *dt.get_datatype_constructors(f->get_range()); if (enums.size() > num.get_unsigned()) { head = m.mk_eq(m.mk_const(f), m.mk_const(enums[num.get_unsigned()])); consequences[i] = m.mk_implies(a, head); } } } return r; }
bool utvpi_tester::linearize() { m_weight.reset(); m_coeff_map.reset(); while (!m_terms.empty()) { expr* e1, *e2; rational num; rational mul = m_terms.back().second; expr* e = m_terms.back().first; m_terms.pop_back(); if (a.is_add(e)) { for (unsigned i = 0; i < to_app(e)->get_num_args(); ++i) { m_terms.push_back(std::make_pair(to_app(e)->get_arg(i), mul)); } } else if (a.is_mul(e, e1, e2) && a.is_numeral(e1, num)) { m_terms.push_back(std::make_pair(e2, mul*num)); } else if (a.is_mul(e, e2, e1) && a.is_numeral(e1, num)) { m_terms.push_back(std::make_pair(e2, mul*num)); } else if (a.is_sub(e, e1, e2)) { m_terms.push_back(std::make_pair(e1, mul)); m_terms.push_back(std::make_pair(e2, -mul)); } else if (a.is_uminus(e, e1)) { m_terms.push_back(std::make_pair(e1, -mul)); } else if (a.is_numeral(e, num)) { m_weight += num*mul; } else if (a.is_to_real(e, e1)) { m_terms.push_back(std::make_pair(e1, mul)); } else if (!is_uninterp_const(e)) { return false; } else { m_coeff_map.insert_if_not_there2(e, rational(0))->get_data().m_value += mul; } } obj_map<expr, rational>::iterator it = m_coeff_map.begin(); obj_map<expr, rational>::iterator end = m_coeff_map.end(); for (; it != end; ++it) { rational r = it->m_value; if (r.is_zero()) { continue; } m_terms.push_back(std::make_pair(it->m_key, r)); if (m_terms.size() > 2) { return false; } if (!r.is_one() && !r.is_minus_one()) { return false; } } return true; }
bool is_target(expr * var, rational & val) { bool strict; return is_uninterp_const(var) && (!m_normalize_int_only || m_util.is_int(var)) && m_bm.has_lower(var, val, strict) && !val.is_zero(); }
void process_le(expr * lhs, expr * rhs) { if (!u.is_int(lhs)) throw_not_supported(); rational k; if (is_uninterp_const(lhs) && u.is_numeral(rhs, k) && m_max_neg_k <= k && k <= m_max_k) { var x = mk_var(lhs); int _k = static_cast<int>(k.get_int64()); m_upper[x] = _k; } else if (is_uninterp_const(rhs) && u.is_numeral(lhs, k) && m_max_neg_k <= k && k <= m_max_k) { var x = mk_var(rhs); int _k = static_cast<int>(k.get_int64()); m_lower[x] = _k; } else { throw_not_supported(); } }
void extract_clauses_and_dependencies(goal_ref const& g, expr_ref_vector& clauses, ptr_vector<expr>& assumptions, expr2expr_map& bool2dep, ref<filter_model_converter>& fmc) { expr2expr_map dep2bool; ptr_vector<expr> deps; ast_manager& m = g->m(); expr_ref_vector clause(m); unsigned sz = g->size(); for (unsigned i = 0; i < sz; i++) { expr * f = g->form(i); expr_dependency * d = g->dep(i); if (d == 0 || !g->unsat_core_enabled()) { clauses.push_back(f); } else { // create clause (not d1 \/ ... \/ not dn \/ f) when the d's are the assumptions/dependencies of f. clause.reset(); clause.push_back(f); deps.reset(); m.linearize(d, deps); SASSERT(!deps.empty()); // d != 0, then deps must not be empty ptr_vector<expr>::iterator it = deps.begin(); ptr_vector<expr>::iterator end = deps.end(); for (; it != end; ++it) { expr * d = *it; if (is_uninterp_const(d) && m.is_bool(d)) { // no need to create a fresh boolean variable for d if (!bool2dep.contains(d)) { assumptions.push_back(d); bool2dep.insert(d, d); } clause.push_back(m.mk_not(d)); } else { // must normalize assumption expr * b = 0; if (!dep2bool.find(d, b)) { b = m.mk_fresh_const(0, m.mk_bool_sort()); dep2bool.insert(d, b); bool2dep.insert(b, d); assumptions.push_back(b); if (!fmc) { fmc = alloc(filter_model_converter, m); } fmc->insert(to_app(b)->get_decl()); } clause.push_back(m.mk_not(b)); } } SASSERT(clause.size() > 1); expr_ref cls(m); cls = mk_or(m, clause.size(), clause.c_ptr()); clauses.push_back(cls); } } }
app* itp_solver::mk_proxy (expr *v) { { expr *e = v; m.is_not (v, e); if (is_uninterp_const(e)) { return to_app(v); } } def_manager &def = m_defs.size () > 0 ? m_defs.back () : m_base_defs; return def.mk_proxy (v); }
void inc_occ(expr * n, bool nested) { if (is_uninterp_const(n) && is_arith(n)) { obj_map<app, unsigned>::obj_map_entry * entry = m_occs.insert_if_not_there2(to_app(n), 0); entry->get_data().m_value++; if (!nested) { entry = m_non_nested_occs.insert_if_not_there2(to_app(n), 0); entry->get_data().m_value++; } } }
void operator()(app * t) { if (is_uninterp_const(t) && (m_util.is_int(t) || m_util.is_real(t))) { if (!m_bm.has_lower(t)) { m_goal.assert_expr(m_util.mk_le(t, m_util.mk_numeral(m_upper, m_util.is_int(t)))); m_num_bounds++; } if (!m_bm.has_upper(t)) { m_goal.assert_expr(m_util.mk_ge(t, m_util.mk_numeral(m_lower, m_util.is_int(t)))); m_num_bounds++; } } }
/** \brief Little HACK for simplifying injectivity axioms \remark It is not covering all possible cases. */ bool simplify_inj_axiom(ast_manager & m, quantifier * q, expr_ref & result) { expr * n = q->get_expr(); if (q->is_forall() && m.is_or(n) && to_app(n)->get_num_args() == 2) { expr * arg1 = to_app(n)->get_arg(0); expr * arg2 = to_app(n)->get_arg(1); if (m.is_not(arg2)) std::swap(arg1, arg2); if (m.is_not(arg1) && m.is_eq(to_app(arg1)->get_arg(0)) && m.is_eq(arg2)) { expr * app1 = to_app(to_app(arg1)->get_arg(0))->get_arg(0); expr * app2 = to_app(to_app(arg1)->get_arg(0))->get_arg(1); expr * var1 = to_app(arg2)->get_arg(0); expr * var2 = to_app(arg2)->get_arg(1); if (is_app(app1) && is_app(app2) && to_app(app1)->get_decl() == to_app(app2)->get_decl() && to_app(app1)->get_num_args() == to_app(app2)->get_num_args() && to_app(app1)->get_family_id() == null_family_id && to_app(app1)->get_num_args() > 0 && is_var(var1) && is_var(var2) && var1 != var2) { app * f1 = to_app(app1); app * f2 = to_app(app2); bool found_vars = false; unsigned num = f1->get_num_args(); unsigned idx = UINT_MAX; unsigned num_vars = 1; for (unsigned i = 0; i < num; i++) { expr * c1 = f1->get_arg(i); expr * c2 = f2->get_arg(i); if (!is_var(c1) && !is_uninterp_const(c1)) return false; if ((c1 == var1 && c2 == var2) || (c1 == var2 && c2 == var1)) { if (found_vars) return false; found_vars = true; idx = i; } else if (c1 == c2 && c1 != var1 && c1 != var2) { if (is_var(c1)) { ++num_vars; } } else { return false; } } if (found_vars && !has_free_vars(q)) { TRACE("inj_axiom", tout << "Cadidate for simplification:\n" << mk_ll_pp(q, m) << mk_pp(app1, m) << "\n" << mk_pp(app2, m) << "\n" << mk_pp(var1, m) << "\n" << mk_pp(var2, m) << "\nnum_vars: " << num_vars << "\n";);
bool trivial_solve1(expr * lhs, expr * rhs, app_ref & var, expr_ref & def, proof_ref & pr) { if (is_uninterp_const(lhs) && !m_candidate_vars.is_marked(lhs) && !occurs(lhs, rhs) && check_occs(lhs)) { var = to_app(lhs); def = rhs; pr = nullptr; return true; } else { return false; } }
void process_neq(expr * lhs, expr * rhs) { if (!u.is_int(lhs)) throw_not_supported(); if (is_uninterp_const(lhs) && is_uninterp_const(rhs)) { process_neq_core(lhs, rhs, 0); return; } if (u.is_numeral(lhs)) std::swap(lhs, rhs); rational k; if (!u.is_numeral(rhs, k)) throw_not_supported(); if (!(m_max_neg_k <= k && k <= m_max_k)) throw_not_supported(); int _k = static_cast<int>(k.get_int64()); expr * t1, * t2, * mt1, * mt2; if (u.is_add(lhs, t1, t2)) { if (is_uninterp_const(t1) && u.is_times_minus_one(t2, mt2) && is_uninterp_const(mt2)) process_neq_core(t1, mt2, _k); else if (is_uninterp_const(t2) && u.is_times_minus_one(t1, mt1) && is_uninterp_const(mt1)) process_neq_core(t2, mt1, _k); else throw_not_supported(); } else { throw_not_supported(); } }
bool reduce_arg(expr* a, expr_ref& result) { sort* s = get_sort(a); if (!m_imp.is_fd(s)) { return false; } unsigned bv_size = get_bv_size(s); if (is_var(a)) { result = m.mk_var(to_var(a)->get_idx(), m_bv.mk_sort(bv_size)); return true; } SASSERT(is_app(a)); func_decl* f = to_app(a)->get_decl(); if (m_dt.is_constructor(f)) { unsigned idx = m_dt.get_constructor_idx(f); result = m_bv.mk_numeral(idx, bv_size); } else if (is_uninterp_const(a)) { func_decl* f_fresh; if (m_imp.m_enum2bv.find(f, f_fresh)) { result = m.mk_const(f_fresh); return true; } // create a fresh variable, add bounds constraints for it. unsigned nc = m_dt.get_datatype_num_constructors(s); result = m.mk_fresh_const(f->get_name().str().c_str(), m_bv.mk_sort(bv_size)); f_fresh = to_app(result)->get_decl(); if (!is_power_of_two(nc) || nc == 1) { m_imp.m_bounds.push_back(m_bv.mk_ule(result, m_bv.mk_numeral(nc-1, bv_size))); } expr_ref f_def(m); ptr_vector<func_decl> const& cs = *m_dt.get_datatype_constructors(s); f_def = m.mk_const(cs[nc-1]); for (unsigned i = nc - 1; i > 0; ) { --i; f_def = m.mk_ite(m.mk_eq(result, m_bv.mk_numeral(i,bv_size)), m.mk_const(cs[i]), f_def); } m_imp.m_enum2def.insert(f, f_def); m_imp.m_enum2bv.insert(f, f_fresh); m_imp.m_bv2enum.insert(f_fresh, f); m_imp.m_enum_consts.push_back(f); m_imp.m_enum_bvs.push_back(f_fresh); m_imp.m_enum_defs.push_back(f_def); } else { throw_non_fd(a); } ++m_imp.m_num_translated; return true; }
void operator()(app * n) { if (!m.is_bool(n) && !u.is_bv(n)) throw found(); family_id fid = n->get_family_id(); if (fid == m.get_basic_family_id()) return; if (fid == u.get_family_id()) return; if (is_uninterp_const(n)) return; throw found(); }
void solver_na2as::assert_expr(expr * t, expr * a) { if (a == nullptr) { assert_expr(t); } else { SASSERT(is_uninterp_const(a)); SASSERT(m.is_bool(a)); TRACE("solver_na2as", tout << "asserting\n" << mk_ismt2_pp(t, m) << "\n" << mk_ismt2_pp(a, m) << "\n";); m_assumptions.push_back(a); expr_ref new_t(m); new_t = m.mk_implies(a, t); assert_expr(new_t); }
var mk_var(expr * t) { SASSERT(is_uninterp_const(t)); var x; if (m_expr2var.find(t, x)) return x; x = m_upper.size(); m_expr2var.insert(t, x); m_var2expr.push_back(t); m_lower.push_back(INT_MIN); // unknown m_upper.push_back(INT_MAX); // unknown m_var_diseqs.push_back(diseqs()); return x; }
bool is_target_core(expr * n, rational & u) { if (!is_uninterp_const(n)) return false; rational l; bool s; if (m_bm.has_lower(n, l, s) && m_bm.has_upper(n, u, s) && l.is_zero() && !u.is_neg() && u.get_num_bits() <= m_max_bits) { return true; } return false; }
void operator()(app * n) { if (!compatible_sort(n)) throw_found(); family_id fid = n->get_family_id(); if (fid == m.get_basic_family_id()) return; if (fid == u.get_family_id()) { switch (n->get_decl_kind()) { case OP_LE: case OP_GE: case OP_LT: case OP_GT: case OP_ADD: case OP_UMINUS: case OP_SUB: case OP_ABS: case OP_NUM: return; case OP_MUL: if (m_linear) { if (n->get_num_args() != 2) throw_found(); if (!u.is_numeral(n->get_arg(0))) throw_found(); } return; case OP_IDIV: case OP_DIV: case OP_REM: case OP_MOD: if (m_linear && !u.is_numeral(n->get_arg(1))) throw_found(); return; case OP_IS_INT: if (m_real) throw_found(); return; case OP_TO_INT: case OP_TO_REAL: return; case OP_POWER: if (m_linear) throw_found(); return; case OP_IRRATIONAL_ALGEBRAIC_NUM: if (m_linear || !m_real) throw_found(); return; default: throw_found(); } return; } if (is_uninterp_const(n)) return; throw_found(); }
bool itp_solver::is_proxy(expr *e, app_ref &def) { if (!is_uninterp_const(e)) { return false; } app *a = to_app (e); for (int i = m_defs.size (); i > 0; --i) if (m_defs[i-1].is_proxy (a, def)) { return true; } if (m_base_defs.is_proxy (a, def)) { return true; } return false; }
void operator()(app * n) { sort * s = get_sort(n); if (!m.is_bool(s) && !fu.is_float(s) && !fu.is_rm(s) && !bu.is_bv_sort(s) && !au.is_real(s)) throw found(); family_id fid = n->get_family_id(); if (fid == m.get_basic_family_id()) return; if (fid == fu.get_family_id() || fid == bu.get_family_id()) return; if (is_uninterp_const(n)) return; if (au.is_real(s) && au.is_numeral(n)) return; throw found(); }
// (ite c (= x t1) (= x t2)) --> (= x (ite c t1 t2)) bool solve_ite_core(app * ite, expr * lhs1, expr * rhs1, expr * lhs2, expr * rhs2, app_ref & var, expr_ref & def, proof_ref & pr) { if (lhs1 != lhs2) return false; if (!is_uninterp_const(lhs1) || m_candidate_vars.is_marked(lhs1)) return false; if (occurs(lhs1, ite->get_arg(0)) || occurs(lhs1, rhs1) || occurs(lhs1, rhs2)) return false; if (!check_occs(lhs1)) return false; var = to_app(lhs1); def = m().mk_ite(ite->get_arg(0), rhs1, rhs2); if (m_produce_proofs) pr = m().mk_rewrite(ite, m().mk_eq(var, def)); return true; }
bool utvpi_tester::operator()(expr* e) { m_todo.reset(); m_mark.reset(); m_todo.push_back(e); expr* e1, *e2; while (!m_todo.empty()) { expr* e = m_todo.back(); m_todo.pop_back(); if (!m_mark.is_marked(e)) { m_mark.mark(e, true); if (is_var(e)) { continue; } if (!is_app(e)) { return false; } app* ap = to_app(e); if (m.is_eq(ap, e1, e2)) { if (!linearize(e1, e2)) { return false; } } else if (ap->get_family_id() == m.get_basic_family_id()) { continue; } else if (a.is_le(e, e1, e2) || a.is_ge(e, e2, e1) || a.is_lt(e, e1, e2) || a.is_gt(e, e2, e1)) { if (!linearize(e1, e2)) { return false; } } else if (is_uninterp_const(e)) { continue; } else { return false; } } } return true; }
unsigned aig_exporter::expr_to_aig(const expr *e) { unsigned id; if (m_aig_expr_id_map.find(e, id)) return id; if (is_uninterp_const(e)) return get_var(e); switch (e->get_kind()) { case AST_APP: { const app *a = to_app(e); switch (a->get_decl_kind()) { case OP_OR: SASSERT(a->get_num_args() > 0); id = expr_to_aig(a->get_arg(0)); for (unsigned i = 1; i < a->get_num_args(); ++i) { id = mk_or(id, expr_to_aig(a->get_arg(i))); } m_aig_expr_id_map.insert(e, id); return id; case OP_NOT: return neg(expr_to_aig(a->get_arg(0))); case OP_FALSE: return 0; case OP_TRUE: return 1; } break;} case AST_VAR: return get_var(e); default: UNREACHABLE(); } UNREACHABLE(); return 0; }
pb2bv_model_converter::pb2bv_model_converter(ast_manager & _m, obj_map<func_decl, expr*> const & c2bit, bound_manager const & bm): m(_m) { obj_map<func_decl, expr*>::iterator it = c2bit.begin(); obj_map<func_decl, expr*>::iterator end = c2bit.end(); for ( ; it != end; it++) { m_c2bit.push_back(func_decl_pair(it->m_key, to_app(it->m_value)->get_decl())); m.inc_ref(it->m_key); m.inc_ref(to_app(it->m_value)->get_decl()); } bound_manager::iterator it2 = bm.begin(); bound_manager::iterator end2 = bm.end(); for (; it2 != end2; ++it2) { expr * c = *it2; SASSERT(is_uninterp_const(c)); func_decl * d = to_app(c)->get_decl(); if (!c2bit.contains(d)) { SASSERT(d->get_arity() == 0); m.inc_ref(d); m_c2bit.push_back(func_decl_pair(d, static_cast<func_decl*>(nullptr))); } } }