z3-z3-4.13.0.src.ast.pb_decl_plugin.h Maven / Gradle / Ivy
The newest version!
/*++
Copyright (c) 2013 Microsoft Corporation
Module Name:
pb_decl_plugin.h
Abstract:
Pseudo-Boolean and Cardinality Constraints plugin
Author:
Nikolaj Bjorner (nbjorner) 2013-05-11
Notes:
(at-most-k x1 .... x_n) means x1 + ... + x_n <= k
hence:
(not (at-most-k x1 .... x_n)) means x1 + ... + x_n >= k + 1
--*/
#pragma once
#include "ast/ast.h"
enum pb_op_kind {
OP_AT_MOST_K, // at most K Booleans are true.
OP_AT_LEAST_K, // at least K Booleans are true.
OP_PB_LE, // pseudo-Boolean <= (generalizes at_most_k)
OP_PB_GE, // pseudo-Boolean >=
OP_PB_EQ, // equality
OP_PB_AUX_BOOL, // auxiliary internal Boolean variable.
LAST_PB_OP
};
class pb_decl_plugin : public decl_plugin {
symbol m_at_most_sym;
symbol m_at_least_sym;
symbol m_pble_sym;
symbol m_pbge_sym;
symbol m_pbeq_sym;
func_decl * mk_at_most(unsigned arity, unsigned k);
func_decl * mk_at_least(unsigned arity, unsigned k);
func_decl * mk_le(unsigned arity, rational const* coeffs, int k);
func_decl * mk_ge(unsigned arity, rational const* coeffs, int k);
func_decl * mk_eq(unsigned arity, rational const* coeffs, int k);
public:
pb_decl_plugin();
sort * mk_sort(decl_kind k, unsigned num_parameters, parameter const * parameters) override {
UNREACHABLE();
return nullptr;
}
decl_plugin * mk_fresh() override {
return alloc(pb_decl_plugin);
}
//
// Contract for func_decl:
// parameters[0] - integer (at most k elements)
// all sorts are Booleans
// parameters[1] .. parameters[arity] - coefficients
func_decl * mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters,
unsigned arity, sort * const * domain, sort * range) override;
void get_op_names(svector & op_names, symbol const & logic) override;
bool is_considered_uninterpreted(func_decl * f) override { return false; }
};
class pb_util {
ast_manager & m;
family_id m_fid;
vector m_coeffs;
vector m_params;
rational m_k;
void normalize(unsigned num_args, rational const* coeffs, rational const& k);
public:
pb_util(ast_manager& m):m(m), m_fid(m.mk_family_id("pb")) {}
ast_manager & get_manager() const { return m; }
family_id get_family_id() const { return m_fid; }
app * mk_at_most_k(unsigned num_args, expr * const * args, unsigned k);
app * mk_at_least_k(unsigned num_args, expr * const * args, unsigned k);
app * mk_at_most_k(expr_ref_vector const& args, unsigned k) { return mk_at_most_k(args.size(), args.data(), k); }
app * mk_at_least_k(expr_ref_vector const& args, unsigned k) { return mk_at_least_k(args.size(), args.data(), k); }
app * mk_le(unsigned num_args, rational const * coeffs, expr * const * args, rational const& k);
app * mk_ge(unsigned num_args, rational const * coeffs, expr * const * args, rational const& k);
app * mk_eq(unsigned num_args, rational const * coeffs, expr * const * args, rational const& k);
app * mk_lt(unsigned num_args, rational const * coeffs, expr * const * args, rational const& k);
bool is_pb(expr* t) const { return is_app(t) && to_app(t)->get_family_id() == get_family_id(); }
bool is_at_most_k(func_decl *a) const;
bool is_at_most_k(expr *a) const { return is_app(a) && is_at_most_k(to_app(a)->get_decl()); }
bool is_at_most_k(expr *a, rational& k) const;
bool is_at_least_k(func_decl *a) const;
bool is_at_least_k(expr *a) const { return is_app(a) && is_at_least_k(to_app(a)->get_decl()); }
bool is_at_least_k(expr *a, rational& k) const;
rational get_k(func_decl *a) const;
rational get_k(expr *a) const { return get_k(to_app(a)->get_decl()); }
bool is_le(func_decl *a) const;
bool is_le(expr *a) const { return is_app(a) && is_le(to_app(a)->get_decl()); }
bool is_le(expr* a, rational& k) const;
bool is_ge(func_decl* a) const;
bool is_ge(expr* a) const { return is_app(a) && is_ge(to_app(a)->get_decl()); }
bool is_ge(expr* a, rational& k) const;
bool is_aux_bool(func_decl* f) const { return is_decl_of(f, m_fid, OP_PB_AUX_BOOL); }
bool is_aux_bool(expr* e) const { return is_app_of(e, m_fid, OP_PB_AUX_BOOL); }
rational get_coeff(expr* a, unsigned index) const { return get_coeff(to_app(a)->get_decl(), index); }
rational get_coeff(func_decl* a, unsigned index) const;
bool has_unit_coefficients(func_decl* f) const;
bool has_unit_coefficients(expr* f) const { return is_app(f) && has_unit_coefficients(to_app(f)->get_decl()); }
bool is_eq(func_decl* f) const;
bool is_eq(expr* e) const { return is_app(e) && is_eq(to_app(e)->get_decl()); }
bool is_eq(expr* e, rational& k) const;
app* mk_fresh_bool();
private:
rational to_rational(parameter const& p) const;
};