model_converter* local_model_converter() const { if (m_rewriter.enum2def().empty() && m_rewriter.enum2bv().empty()) { return nullptr; } generic_model_converter* mc = alloc(generic_model_converter, m, "enum2bv"); for (auto const& kv : m_rewriter.enum2bv()) mc->hide(kv.m_value); for (auto const& kv : m_rewriter.enum2def()) mc->add(kv.m_key, kv.m_value); return mc; }
void filter_model(model_ref& mdl) { filter_model_converter filter(m); obj_map<func_decl, func_decl*>::iterator it = m_rewriter.enum2bv().begin(), end = m_rewriter.enum2bv().end(); for (; it != end; ++it) { filter.insert(it->m_value); } filter(mdl, 0); }
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; }