bool detect_equivalences(expr_ref_vector& v, bool inside_disjunction) { bool have_pair = false; unsigned prev_pair_idx = 0; arg_pair ap; unsigned read_idx = 0; unsigned write_idx = 0; while(read_idx<v.size()) { expr * e = v[read_idx].get(); arg_pair new_ap; if (match_arg_pair(e, new_ap, inside_disjunction)) { app * neq = nullptr; if (have_pair) { neq = detect_equivalence(ap, new_ap, inside_disjunction); } if (neq) { have_pair = false; v[prev_pair_idx] = neq; read_idx++; continue; } else { have_pair = true; prev_pair_idx = write_idx; ap = new_ap; } } else { have_pair = false; } if (write_idx!=read_idx) { v[write_idx] = e; } read_idx++; write_idx++; } v.shrink(write_idx); return read_idx!=write_idx; }
void arith_simplifier_plugin::get_monomial_gcd(expr_ref_vector& monomials, numeral& g) { g = numeral::zero(); numeral n; for (unsigned i = 0; !g.is_one() && i < monomials.size(); ++i) { expr* e = monomials[i].get(); if (is_numeral(e, n)) { g = gcd(abs(n), g); } else if (is_mul(e) && is_numeral(to_app(e)->get_arg(0), n)) { g = gcd(abs(n), g); } else { g = numeral::one(); return; } } if (g.is_zero()) { g = numeral::one(); } }
void project_plugin::partition_values(model& model, expr_ref_vector const& vals, expr_ref_vector& lits) { ast_manager& m = vals.get_manager(); expr_ref val(m); expr_ref_vector trail(m), reps(m); obj_map<expr, expr*> roots; for (unsigned i = 0; i < vals.size(); ++i) { expr* v = vals[i], *root; VERIFY (model.eval(v, val)); if (roots.find(val, root)) { lits.push_back(m.mk_eq(v, root)); } else { roots.insert(val, v); trail.push_back(val); reps.push_back(v); } } if (reps.size() > 1) { lits.push_back(mk_distinct(reps)); } }
void operator()(expr * n, proof* p, expr_ref_vector& result, proof_ref_vector& ps) { if (is_horn(n)) { result.push_back(n); ps.push_back(p); return; } expr_ref fml(m); proof_ref pr(m); m_todo.reset(); m_proofs.reset(); m_refs.reset(); m_memoize_disj.reset(); m_memoize_proof.reset(); m_fresh_predicates.reset(); m_todo.push_back(n); m_proofs.push_back(p); m_produce_proofs = p != nullptr; while (!m_todo.empty() && checkpoint()) { fml = m_todo.back(); pr = m_proofs.back(); m_todo.pop_back(); m_proofs.pop_back(); mk_horn(fml, pr); if (fml) { result.push_back(fml); ps.push_back(pr); } } TRACE("hnf", tout << mk_pp(n, m) << "\n==>\n"; for (unsigned i = 0; i < result.size(); ++i) { tout << mk_pp(result[i].get(), m) << "\n"; });
/** Factors input vector v into equivalence classes and the rest */ void factor_eqs(expr_ref_vector &v, expr_equiv_class &equiv) { ast_manager &m = v.get_manager(); arith_util arith(m); expr *e1 = 0, *e2 = 0; flatten_and(v); unsigned j = 0; for (unsigned i = 0; i < v.size(); ++i) { if (m.is_eq(v.get(i), e1, e2)) { if (arith.is_zero(e1)) { std::swap(e1, e2); } // y + -1*x == 0 expr* a0 = 0, *a1 = 0, *x = 0; if (arith.is_zero(e2) && arith.is_add(e1, a0, a1)) { if (arith.is_times_minus_one(a1, x)) { e1 = a0; e2 = x; } else if (arith.is_times_minus_one(a0, x)) { e1 = a1; e2 = x; } } equiv.merge(e1, e2); } else { if (j < i) { v[j] = v.get(i); } j++; } } v.shrink(j); }
static void test_c(app* x, expr_ref_vector const& c) { ast_manager& m = c.get_manager(); expr_ref fml(m); fml = m.mk_and(c.size(), c.c_ptr()); test(x, fml); }
br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result, proof_ref & result_pr) { if (m.is_not(f) && (m.is_and(args[0]) || m.is_or(args[0]))) { SASSERT(num == 1); expr_ref tmp(m); app* a = to_app(args[0]); m_app_args.reset(); for (expr* arg : *a) { m_brwr.mk_not(arg, tmp); m_app_args.push_back(tmp); } if (m.is_and(args[0])) { result = mk_or(m_app_args); } else { result = mk_and(m_app_args); } return BR_REWRITE2; } if (!m.is_and(f) && !m.is_or(f)) { return BR_FAILED; } if (num == 0) { if (m.is_and(f)) { result = m.mk_true(); } else { result = m.mk_false(); } return BR_DONE; } if (num == 1) { result = args[0]; return BR_DONE; } m_app_args.reset(); m_app_args.append(num, args); std::sort(m_app_args.c_ptr(), m_app_args.c_ptr()+m_app_args.size(), m_expr_cmp); remove_duplicates(m_app_args); bool have_rewritten_args = false; have_rewritten_args = detect_equivalences(m_app_args, m.is_or(f)); if (m_app_args.size()==1) { result = m_app_args[0].get(); } else { if (m.is_and(f)) { result = m.mk_and(m_app_args.size(), m_app_args.c_ptr()); } else { SASSERT(m.is_or(f)); result = m.mk_or(m_app_args.size(), m_app_args.c_ptr()); } } if (have_rewritten_args) { return BR_REWRITE1; } return BR_DONE; }
void tactic2solver::push_core() { m_scopes.push_back(m_assertions.size()); m_result = 0; }
unsigned get_num_names() const { return m_names.size(); }
lbool solver::get_consequences_core(expr_ref_vector const& asms, expr_ref_vector const& vars, expr_ref_vector& consequences) { ast_manager& m = asms.get_manager(); lbool is_sat = check_sat(asms); if (is_sat != l_true) { return is_sat; } model_ref model; get_model(model); expr_ref tmp(m), nlit(m), lit(m), val(m); expr_ref_vector asms1(asms); model_evaluator eval(*model.get()); unsigned k = 0; for (unsigned i = 0; i < vars.size(); ++i) { expr_ref_vector core(m); tmp = vars[i]; val = eval(tmp); if (!m.is_value(val)) { continue; } if (m.is_bool(tmp) && is_uninterp_const(tmp)) { if (m.is_true(val)) { nlit = m.mk_not(tmp); lit = tmp; } else if (m.is_false(val)) { nlit = tmp; lit = m.mk_not(tmp); } else { continue; } scoped_assumption_push _scoped_push(asms1, nlit); is_sat = check_sat(asms1); switch (is_sat) { case l_undef: return is_sat; case l_true: break; case l_false: get_unsat_core(core); k = 0; for (unsigned j = 0; j < core.size(); ++j) { if (core[j].get() != nlit) { core[k] = core[j].get(); ++k; } } core.resize(k); consequences.push_back(m.mk_implies(mk_and(core), lit)); break; } } else { lit = m.mk_eq(tmp, val); nlit = m.mk_not(lit); scoped_push _scoped_push(*this); assert_expr(nlit); is_sat = check_sat(asms); switch (is_sat) { case l_undef: return is_sat; case l_true: break; case l_false: get_unsat_core(core); consequences.push_back(m.mk_implies(mk_and(core), lit)); break; } } } return l_true; }
bool contains_unsupported(expr_ref_vector & b2a, expr_ref_vector & x2t) { for (unsigned x = 0; x < x2t.size(); x++) { if (!is_uninterp_const(x2t.get(x))) { TRACE("unsupported", tout << "unsupported atom:\n" << mk_ismt2_pp(x2t.get(x), m) << "\n";); return true; }
expr_ref mk_or(expr_ref_vector const& fmls) { ast_manager& m = fmls.get_manager(); expr_ref result(m); bool_rewriter(m).mk_or(fmls.size(), fmls.c_ptr(), result); return result; }
void project_plugin::mark_rec(expr_mark& visited, expr_ref_vector const& es) { for (unsigned i = 0; i < es.size(); ++i) { mark_rec(visited, es[i]); } }