z3-z3-4.13.0.src.solver.assertions.asserted_formulas.h Maven / Gradle / Ivy
The newest version!
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
asserted_formulas.h
Abstract:
Author:
Leonardo de Moura (leonardo) 2008-06-11.
Revision History:
--*/
#pragma once
#include "util/statistics.h"
#include "ast/static_features.h"
#include "ast/expr_substitution.h"
#include "ast/rewriter/th_rewriter.h"
#include "ast/rewriter/bit2int.h"
#include "ast/rewriter/maximize_ac_sharing.h"
#include "ast/rewriter/distribute_forall.h"
#include "ast/rewriter/push_app_ite.h"
#include "ast/rewriter/inj_axiom.h"
#include "ast/rewriter/bv_elim.h"
#include "ast/rewriter/der.h"
#include "ast/rewriter/elim_bounds.h"
#include "ast/rewriter/expr_safe_replace.h"
#include "ast/macros/macro_manager.h"
#include "ast/macros/macro_finder.h"
#include "ast/normal_forms/defined_names.h"
#include "ast/normal_forms/pull_quant.h"
#include "ast/normal_forms/elim_term_ite.h"
#include "ast/pattern/pattern_inference.h"
#include "smt/params/smt_params.h"
#include "qe/lite/qe_lite_tactic.h"
class asserted_formulas {
ast_manager & m;
smt_params & m_smt_params;
params_ref m_params;
th_rewriter m_rewriter;
expr_substitution m_substitution;
scoped_expr_substitution m_scoped_substitution;
defined_names m_defined_names;
static_features m_static_features;
vector m_formulas;
unsigned m_qhead;
bool m_elim_and;
macro_manager m_macro_manager;
scoped_ptr m_macro_finder;
maximize_bv_sharing_rw m_bv_sharing;
bool m_inconsistent;
bool m_has_quantifiers;
struct scope {
unsigned m_formulas_lim;
bool m_inconsistent_old;
};
svector m_scopes;
obj_map m_expr2depth;
class simplify_fmls {
protected:
asserted_formulas& af;
ast_manager& m;
char const* m_id;
public:
simplify_fmls(asserted_formulas& af, char const* id): af(af), m(af.m), m_id(id) {}
virtual ~simplify_fmls() = default;
char const* id() const { return m_id; }
virtual void simplify(justified_expr const& j, expr_ref& n, proof_ref& p) = 0;
virtual bool should_apply() const { return true;}
virtual void post_op() {}
virtual void operator()();
};
class reduce_asserted_formulas_fn : public simplify_fmls {
public:
reduce_asserted_formulas_fn(asserted_formulas& af): simplify_fmls(af, "reduce-asserted") {}
void simplify(justified_expr const& j, expr_ref& n, proof_ref& p) override { af.m_rewriter(j.get_fml(), n, p); }
};
class find_macros_fn : public simplify_fmls {
public:
find_macros_fn(asserted_formulas& af): simplify_fmls(af, "find-macros") {}
void operator()() override { af.find_macros_core(); }
bool should_apply() const override { return (af.m_smt_params.m_quasi_macros || af.m_smt_params.m_macro_finder) && af.has_quantifiers(); }
void simplify(justified_expr const& j, expr_ref& n, proof_ref& p) override { UNREACHABLE(); }
};
class apply_quasi_macros_fn : public simplify_fmls {
public:
apply_quasi_macros_fn(asserted_formulas& af): simplify_fmls(af, "find-quasi-macros") {}
void operator()() override { af.apply_quasi_macros(); }
bool should_apply() const override { return af.m_smt_params.m_quasi_macros && af.has_quantifiers(); }
void simplify(justified_expr const& j, expr_ref& n, proof_ref& p) override { UNREACHABLE(); }
};
class nnf_cnf_fn : public simplify_fmls {
public:
nnf_cnf_fn(asserted_formulas& af): simplify_fmls(af, "nnf-cnf") {}
void operator()() override { af.nnf_cnf(); }
bool should_apply() const override { return af.m_smt_params.m_nnf_cnf || af.has_quantifiers(); }
void simplify(justified_expr const& j, expr_ref& n, proof_ref& p) override { UNREACHABLE(); }
};
class propagate_values_fn : public simplify_fmls {
public:
propagate_values_fn(asserted_formulas& af): simplify_fmls(af, "propagate-values") {}
void operator()() override { af.propagate_values(); }
bool should_apply() const override { return af.m_smt_params.m_propagate_values; }
void simplify(justified_expr const& j, expr_ref& n, proof_ref& p) override { UNREACHABLE(); }
};
class distribute_forall_fn : public simplify_fmls {
distribute_forall m_functor;
public:
distribute_forall_fn(asserted_formulas& af): simplify_fmls(af, "distribute-forall"), m_functor(af.m) {}
void simplify(justified_expr const& j, expr_ref& n, proof_ref& p) override { m_functor(j.get_fml(), n); }
bool should_apply() const override { return af.m_smt_params.m_distribute_forall && af.has_quantifiers(); }
void post_op() override { af.reduce_and_solve(); TRACE("asserted_formulas", af.display(tout);); }
};
class pattern_inference_fn : public simplify_fmls {
pattern_inference_rw m_infer;
public:
pattern_inference_fn(asserted_formulas& af): simplify_fmls(af, "pattern-inference"), m_infer(af.m, af.m_smt_params) {}
void simplify(justified_expr const& j, expr_ref& n, proof_ref& p) override { m_infer(j.get_fml(), n, p); }
bool should_apply() const override { return af.m_smt_params.m_ematching && af.has_quantifiers(); }
};
class refine_inj_axiom_fn : public simplify_fmls {
public:
refine_inj_axiom_fn(asserted_formulas& af): simplify_fmls(af, "refine-injectivity") {}
void simplify(justified_expr const& j, expr_ref& n, proof_ref& p) override;
bool should_apply() const override { return af.m_smt_params.m_refine_inj_axiom && af.has_quantifiers(); }
};
class max_bv_sharing_fn : public simplify_fmls {
public:
max_bv_sharing_fn(asserted_formulas& af): simplify_fmls(af, "maximizing-bv-sharing") {}
void simplify(justified_expr const& j, expr_ref& n, proof_ref& p) override { af.m_bv_sharing(j.get_fml(), n, p); }
bool should_apply() const override { return af.m_smt_params.m_max_bv_sharing; }
void post_op() override { af.m_reduce_asserted_formulas(); }
};
class bv_size_reduce_fn : public simplify_fmls {
expr_safe_replace m_sub;
public:
bv_size_reduce_fn(asserted_formulas& af): simplify_fmls(af, "bv-size-reduce"), m_sub(af.m) {}
bool should_apply() const override { return af.m_smt_params.m_bv_size_reduce; }
void simplify(justified_expr const& j, expr_ref& n, proof_ref& p) override;
void push_scope();
void pop_scope(unsigned n);
};
class elim_term_ite_fn : public simplify_fmls {
elim_term_ite_rw m_elim;
public:
elim_term_ite_fn(asserted_formulas& af): simplify_fmls(af, "elim-term-ite"), m_elim(af.m, af.m_defined_names) {}
void simplify(justified_expr const& j, expr_ref& n, proof_ref& p) override { m_elim(j.get_fml(), n, p); }
bool should_apply() const override { return af.m_smt_params.m_eliminate_term_ite && af.m_smt_params.m_lift_ite != lift_ite_kind::LI_FULL; }
void post_op() override { af.m_formulas.append(m_elim.new_defs()); af.reduce_and_solve(); m_elim.reset(); }
void push() { m_elim.push(); }
void pop(unsigned n) { m_elim.pop(n); }
};
class flatten_clauses_fn : public simplify_fmls {
public:
flatten_clauses_fn(asserted_formulas& af): simplify_fmls(af, "flatten-clauses") {}
void operator()() override { af.flatten_clauses(); }
bool should_apply() const override { return true; }
void simplify(justified_expr const& j, expr_ref& n, proof_ref& p) override { UNREACHABLE(); }
};
void flatten_clauses();
#define MK_SIMPLIFIERA(NAME, FUNCTOR, MSG, APP, ARG, REDUCE) \
class NAME : public simplify_fmls { \
public: \
FUNCTOR m_functor; \
NAME(asserted_formulas& af):simplify_fmls(af, MSG), m_functor ARG {} \
virtual void simplify(justified_expr const& j, expr_ref& n, proof_ref& p) { \
m_functor(j.get_fml(), n, p); \
} \
virtual void post_op() { if (REDUCE) af.reduce_and_solve(); } \
virtual bool should_apply() const { return APP; } \
}; \
#define MK_SIMPLIFIERF(NAME, FUNCTOR, MSG, APP, REDUCE) MK_SIMPLIFIERA(NAME, FUNCTOR, MSG, APP, (af.m), REDUCE)
MK_SIMPLIFIERF(pull_nested_quantifiers, pull_nested_quant, "pull-nested-quantifiers", af.m_smt_params.m_pull_nested_quantifiers && af.has_quantifiers(), false);
MK_SIMPLIFIERF(cheap_quant_fourier_motzkin, elim_bounds_rw, "cheap-fourier-motzkin", af.m_smt_params.m_eliminate_bounds && af.has_quantifiers(), true);
MK_SIMPLIFIERF(elim_bvs_from_quantifiers, bv_elim_rw, "eliminate-bit-vectors-from-quantifiers", af.m_smt_params.m_bb_quantifiers, true);
MK_SIMPLIFIERF(apply_bit2int, bit2int, "propagate-bit-vector-over-integers", af.m_smt_params.m_simplify_bit2int, true);
MK_SIMPLIFIERF(lift_ite, push_app_ite_rw, "lift-ite", af.m_smt_params.m_lift_ite != lift_ite_kind::LI_NONE, true);
MK_SIMPLIFIERF(ng_lift_ite, ng_push_app_ite_rw, "lift-ite", af.m_smt_params.m_ng_lift_ite != lift_ite_kind::LI_NONE, true);
MK_SIMPLIFIERA(qe_lite_fn, qe_lite, "qe-lite", af.m_smt_params.m_qe_lite && af.has_quantifiers(), (af.m, af.m_params), true);
reduce_asserted_formulas_fn m_reduce_asserted_formulas;
distribute_forall_fn m_distribute_forall;
pattern_inference_fn m_pattern_inference;
refine_inj_axiom_fn m_refine_inj_axiom;
max_bv_sharing_fn m_max_bv_sharing_fn;
elim_term_ite_fn m_elim_term_ite;
qe_lite_fn m_qe_lite;
pull_nested_quantifiers m_pull_nested_quantifiers;
elim_bvs_from_quantifiers m_elim_bvs_from_quantifiers;
cheap_quant_fourier_motzkin m_cheap_quant_fourier_motzkin;
apply_bit2int m_apply_bit2int;
bv_size_reduce_fn m_bv_size_reduce;
lift_ite m_lift_ite;
ng_lift_ite m_ng_lift_ite;
find_macros_fn m_find_macros;
propagate_values_fn m_propagate_values;
nnf_cnf_fn m_nnf_cnf;
apply_quasi_macros_fn m_apply_quasi_macros;
flatten_clauses_fn m_flatten_clauses;
unsigned m_lazy_scopes;
void force_push();
void push_scope_core();
bool invoke(simplify_fmls& s);
void swap_asserted_formulas(vector& new_fmls);
void push_assertion(expr * e, proof * pr, vector& result);
bool canceled() { return !m.inc(); }
bool check_well_sorted() const;
unsigned get_total_size() const;
void find_macros_core();
void expand_macros();
void apply_quasi_macros();
void nnf_cnf();
void reduce_and_solve();
void flush_cache() { m_rewriter.reset(); m_rewriter.set_substitution(&m_substitution); }
void set_eliminate_and(bool flag);
void propagate_values();
unsigned propagate_values(unsigned i);
bool update_substitution(expr* n, proof* p);
bool is_gt(expr* lhs, expr* rhs);
void compute_depth(expr* e);
unsigned depth(expr* e) { return m_expr2depth[e]; }
void init(unsigned num_formulas, expr * const * formulas, proof * const * prs);
public:
asserted_formulas(ast_manager & m, smt_params & smtp, params_ref const& p);
~asserted_formulas();
void finalize();
void updt_params(params_ref const& p);
bool has_quantifiers() const { return m_has_quantifiers; }
void setup();
void assert_expr(expr * e, proof * in_pr);
void assert_expr(expr * e);
void reset();
void push_scope();
void pop_scope(unsigned num_scopes);
bool inconsistent() const { return m_inconsistent; }
proof * get_inconsistency_proof() const;
void reduce();
unsigned get_num_formulas() const { return m_formulas.size(); }
unsigned get_formulas_last_level() const;
unsigned get_qhead() const { return m_qhead; }
void commit();
void commit(unsigned new_qhead);
expr * get_formula(unsigned idx) const { return m_formulas[idx].get_fml(); }
proof * get_formula_proof(unsigned idx) const { return m_formulas[idx].get_proof(); }
params_ref const& get_params() const { return m_params; }
void get_assertions(ptr_vector & result) const;
bool empty() const { return m_formulas.empty(); }
void display(std::ostream & out) const;
void display_ll(std::ostream & out, ast_mark & pp_visited) const;
void collect_statistics(statistics & st) const;
// -----------------------------------
//
// Macros
//
// -----------------------------------
macro_manager& get_macro_manager() { return m_macro_manager; }
unsigned get_num_macros() const { return m_macro_manager.get_num_macros(); }
unsigned get_first_macro_last_level() const { return m_macro_manager.get_first_macro_last_level(); }
func_decl * get_macro_func_decl(unsigned i) const { return m_macro_manager.get_macro_func_decl(i); }
func_decl * get_macro_interpretation(unsigned i, expr_ref & interp) const { return m_macro_manager.get_macro_interpretation(i, interp); }
quantifier * get_macro_quantifier(func_decl * f) const { return m_macro_manager.get_macro_quantifier(f); }
// auxiliary function used to create a logic context based on a model.
void insert_macro(func_decl * f, quantifier * m, proof * pr) { force_push(); m_macro_manager.insert(f, m, pr); }
void insert_macro(func_decl * f, quantifier * m, proof * pr, expr_dependency* dep) { force_push(); m_macro_manager.insert(f, m, pr, dep); }
};