z3-z3-4.13.0.src.ast.macros.macro_util.h Maven / Gradle / Ivy
The newest version!
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
macro_util.h
Abstract:
Macro finding goodies.
They are used during preprocessing (MACRO_FINDER=true), and model building.
Author:
Leonardo de Moura (leonardo) 2010-12-15.
Revision History:
--*/
#pragma once
#include "ast/ast.h"
#include "util/obj_hashtable.h"
#include "ast/rewriter/arith_rewriter.h"
#include "ast/rewriter/bv_rewriter.h"
class macro_util {
public:
/**
\brief See collect_macro_candidates.
*/
class macro_candidates {
ptr_vector m_fs;
expr_ref_vector m_defs;
expr_ref_vector m_conds;
bool_vector m_ineq; // true if the macro is based on an inequality instead of equality.
bool_vector m_satisfy;
bool_vector m_hint; // macro did not contain all universal variables in the quantifier.
friend class macro_util;
ast_manager & get_manager() { return m_conds.get_manager(); }
public:
macro_candidates(ast_manager & m);
~macro_candidates() { reset(); }
void reset();
void insert(func_decl * f, expr * def, expr * cond, bool ineq, bool satisfy_atom, bool hint);
bool empty() const { return m_fs.empty(); }
unsigned size() const { return m_fs.size(); }
func_decl * get_f(unsigned i) const { return m_fs[i]; }
expr * get_def(unsigned i) const { return m_defs.get(i); }
expr * get_cond(unsigned i) const { return m_conds.get(i); }
bool ineq(unsigned i) const { return m_ineq[i]; }
bool satisfy_atom(unsigned i) const { return m_satisfy[i]; }
bool hint(unsigned i) const { return m_hint[i]; }
};
private:
ast_manager & m;
bv_util m_bv;
arith_util m_arith;
mutable arith_rewriter m_arith_rw;
mutable bv_rewriter m_bv_rw;
obj_hashtable * m_forbidden_set;
bool is_forbidden(func_decl * f) const { return m_forbidden_set != nullptr && m_forbidden_set->contains(f); }
bool poly_contains_head(expr * n, func_decl * f, expr * exception) const;
void collect_arith_macros(expr * n, unsigned num_decls, unsigned max_macros, bool allow_cond_macros,
macro_candidates & r);
void normalize_expr(app * head, unsigned num_decls, expr * t, expr_ref & norm_t) const;
void insert_macro(app * head, unsigned num_decls, expr * def, expr * cond, bool ineq, bool satisfy_atom, bool hint, macro_candidates & r);
void insert_quasi_macro(app * head, unsigned num_decls, expr * def, expr * cond, bool ineq, bool satisfy_atom, bool hint,
macro_candidates & r);
expr * m_curr_clause; // auxiliary var used in collect_macro_candidates.
// Return true if m_curr_clause contains f in a literal different from except_lit
bool rest_contains_decl(func_decl * f, expr * except_lit);
// Store in extra_cond (and (not l_1) ... (not l_n)) where l_i's are the literals of m_curr_clause that are different from except_lit.
void get_rest_clause_as_cond(expr * except_lit, expr_ref & extra_cond);
void collect_poly_args(expr * n, expr * exception, ptr_buffer & args);
void add_arith_macro_candidate(app * head, unsigned num_decls, expr * def, expr * atom, bool ineq, bool hint, macro_candidates & r);
void collect_arith_macro_candidates(expr * lhs, expr * rhs, expr * atom, unsigned num_decls, bool ineq, macro_candidates & r);
void collect_arith_macro_candidates(expr * atom, unsigned num_decls, macro_candidates & r);
void collect_macro_candidates_core(expr * atom, unsigned num_decls, macro_candidates & r);
bool is_poly_hint(expr * n, app * head, expr * exception);
public:
macro_util(ast_manager & m);
void set_forbidden_set(obj_hashtable * s) { m_forbidden_set = s; }
bool is_macro_head(expr * n, unsigned num_decls) const;
bool is_left_simple_macro(expr * n, unsigned num_decls, app_ref & head, expr_ref & def) const;
bool is_right_simple_macro(expr * n, unsigned num_decls, app_ref & head, expr_ref & def) const;
bool is_simple_macro(expr * n, unsigned num_decls, app_ref& head, expr_ref & def) const {
return is_left_simple_macro(n, num_decls, head, def) || is_right_simple_macro(n, num_decls, head, def);
}
bool is_arith_macro(expr * n, unsigned num_decls, app_ref & head, expr_ref & def, bool & inv) const;
bool is_arith_macro(expr * n, unsigned num_decls, app_ref & head, expr_ref & def) const {
bool inv;
return is_arith_macro(n, num_decls, head, def, inv);
}
bool is_zero_safe(expr * n) const;
bool is_var_plus_ground(expr * n, bool & inv, var * & v, expr_ref & t);
bool is_pseudo_head(expr * n, unsigned num_decls, app_ref & head, app_ref & t);
bool is_pseudo_predicate_macro(expr * n, app_ref & head, app_ref & t, expr_ref & def);
bool is_quasi_macro_head(expr * n, unsigned num_decls) const;
bool is_quasi_macro_ok(expr * n, unsigned num_decls, expr * def) const;
void quasi_macro_head_to_macro_head(app * qhead, unsigned & num_decls, app_ref & head, expr_ref & cond) const;
void mk_macro_interpretation(app * head, unsigned num_decls, expr * def, expr_ref & interp) const;
void collect_macro_candidates(expr * atom, unsigned num_decls, macro_candidates & r);
void collect_macro_candidates(quantifier * q, macro_candidates & r);
//
// Auxiliary goodness that allows us to manipulate BV and Arith polynomials.
//
bool is_bv(expr * n) const;
bool is_bv_sort(sort * s) const;
app * mk_zero(sort * s) const;
bool is_add(expr * n) const;
bool is_times_minus_one(expr * n, expr * & arg) const;
bool is_le(expr * n) const;
bool is_le_ge(expr * n) const;
void mk_sub(expr * t1, expr * t2, expr_ref & r) const;
void mk_add(expr * t1, expr * t2, expr_ref & r) const;
void mk_add(unsigned num_args, expr * const * args, sort * s, expr_ref & r) const;
};