mirror of
https://github.com/Z3Prover/z3
synced 2025-04-23 09:05:31 +00:00
bapa
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
a27f083177
commit
1123b47fb7
13 changed files with 613 additions and 4 deletions
|
@ -21,6 +21,7 @@ Revision History:
|
|||
#include "util/warning.h"
|
||||
#include "ast/ast_pp.h"
|
||||
#include "ast/ast_ll_pp.h"
|
||||
#include "ast/arith_decl_plugin.h"
|
||||
|
||||
array_decl_plugin::array_decl_plugin():
|
||||
m_store_sym("store"),
|
||||
|
@ -34,7 +35,8 @@ array_decl_plugin::array_decl_plugin():
|
|||
m_set_complement_sym("complement"),
|
||||
m_set_subset_sym("subset"),
|
||||
m_array_ext_sym("array-ext"),
|
||||
m_as_array_sym("as-array") {
|
||||
m_as_array_sym("as-array"),
|
||||
m_set_has_size_sym("set-has-size") {
|
||||
}
|
||||
|
||||
#define ARRAY_SORT_STR "Array"
|
||||
|
@ -438,6 +440,25 @@ func_decl * array_decl_plugin::mk_set_subset(unsigned arity, sort * const * doma
|
|||
func_decl_info(m_family_id, OP_SET_SUBSET));
|
||||
}
|
||||
|
||||
func_decl * array_decl_plugin::mk_set_has_size(unsigned arity, sort * const* domain) {
|
||||
if (arity != 2) {
|
||||
m_manager->raise_exception("set-has-size takes two arguments");
|
||||
return nullptr;
|
||||
}
|
||||
// domain[0] is a Boolean array,
|
||||
// domain[1] is Int
|
||||
arith_util arith(*m_manager);
|
||||
if (!arith.is_int(domain[1])) {
|
||||
m_manager->raise_exception("set-has-size expects second argument to be an integer");
|
||||
}
|
||||
if (!is_array_sort(domain[0]) || !m_manager->is_bool(get_array_range(domain[0]))) {
|
||||
m_manager->raise_exception("set-has-size expects first argument to be an array of Booleans");
|
||||
}
|
||||
sort * bool_sort = m_manager->mk_bool_sort();
|
||||
return m_manager->mk_func_decl(m_set_has_size_sym, arity, domain, bool_sort,
|
||||
func_decl_info(m_family_id, OP_SET_HAS_SIZE));
|
||||
}
|
||||
|
||||
func_decl * array_decl_plugin::mk_as_array(func_decl * f) {
|
||||
vector<parameter> parameters;
|
||||
for (unsigned i = 0; i < f->get_arity(); i++) {
|
||||
|
@ -502,6 +523,8 @@ func_decl * array_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters
|
|||
return mk_set_complement(arity, domain);
|
||||
case OP_SET_SUBSET:
|
||||
return mk_set_subset(arity, domain);
|
||||
case OP_SET_HAS_SIZE:
|
||||
return mk_set_has_size(arity, domain);
|
||||
case OP_AS_ARRAY: {
|
||||
if (num_parameters != 1 ||
|
||||
!parameters[0].is_ast() ||
|
||||
|
@ -544,6 +567,7 @@ void array_decl_plugin::get_op_names(svector<builtin_name>& op_names, symbol con
|
|||
op_names.push_back(builtin_name("subset",OP_SET_SUBSET));
|
||||
op_names.push_back(builtin_name("as-array", OP_AS_ARRAY));
|
||||
op_names.push_back(builtin_name("array-ext", OP_ARRAY_EXT));
|
||||
op_names.push_back(builtin_name("set-has-size", OP_SET_HAS_SIZE));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ enum array_op_kind {
|
|||
OP_SET_DIFFERENCE,
|
||||
OP_SET_COMPLEMENT,
|
||||
OP_SET_SUBSET,
|
||||
OP_SET_HAS_SIZE,
|
||||
OP_AS_ARRAY, // used for model construction
|
||||
LAST_ARRAY_OP
|
||||
};
|
||||
|
@ -68,6 +69,7 @@ class array_decl_plugin : public decl_plugin {
|
|||
symbol m_set_subset_sym;
|
||||
symbol m_array_ext_sym;
|
||||
symbol m_as_array_sym;
|
||||
symbol m_set_has_size_sym;
|
||||
|
||||
bool check_set_arguments(unsigned arity, sort * const * domain);
|
||||
|
||||
|
@ -95,6 +97,8 @@ class array_decl_plugin : public decl_plugin {
|
|||
|
||||
func_decl * mk_as_array(func_decl * f);
|
||||
|
||||
func_decl* mk_set_has_size(unsigned arity, sort * const* domain);
|
||||
|
||||
bool is_array_sort(sort* s) const;
|
||||
public:
|
||||
array_decl_plugin();
|
||||
|
@ -144,11 +148,13 @@ public:
|
|||
bool is_map(expr* n) const { return is_app_of(n, m_fid, OP_ARRAY_MAP); }
|
||||
bool is_as_array(expr * n) const { return is_app_of(n, m_fid, OP_AS_ARRAY); }
|
||||
bool is_as_array(expr * n, func_decl*& f) const { return is_as_array(n) && (f = get_as_array_func_decl(n), true); }
|
||||
bool is_set_has_size(expr* e) const { return is_app_of(e, m_fid, OP_SET_HAS_SIZE); }
|
||||
bool is_select(func_decl* f) const { return is_decl_of(f, m_fid, OP_SELECT); }
|
||||
bool is_store(func_decl* f) const { return is_decl_of(f, m_fid, OP_STORE); }
|
||||
bool is_const(func_decl* f) const { return is_decl_of(f, m_fid, OP_CONST_ARRAY); }
|
||||
bool is_map(func_decl* f) const { return is_decl_of(f, m_fid, OP_ARRAY_MAP); }
|
||||
bool is_as_array(func_decl* f) const { return is_decl_of(f, m_fid, OP_AS_ARRAY); }
|
||||
bool is_set_has_size(func_decl* f) const { return is_decl_of(f, m_fid, OP_SET_HAS_SIZE); }
|
||||
bool is_as_array(func_decl* f, func_decl*& g) const { return is_decl_of(f, m_fid, OP_AS_ARRAY) && (g = get_as_array_func_decl(f), true); }
|
||||
func_decl * get_as_array_func_decl(expr * n) const;
|
||||
func_decl * get_as_array_func_decl(func_decl* f) const;
|
||||
|
@ -189,6 +195,10 @@ public:
|
|||
return mk_const_array(s, m_manager.mk_true());
|
||||
}
|
||||
|
||||
app* mk_has_size(expr* set, expr* n) {
|
||||
return m_manager.mk_app(m_fid, OP_SET_HAS_SIZE, set, n);
|
||||
}
|
||||
|
||||
func_decl * mk_array_ext(sort* domain, unsigned i);
|
||||
|
||||
sort * mk_array_sort(sort* dom, sort* range) { return mk_array_sort(1, &dom, range); }
|
||||
|
|
|
@ -17,6 +17,7 @@ Revision History:
|
|||
|
||||
--*/
|
||||
#include "ast/ast_util.h"
|
||||
#include "ast/arith_decl_plugin.h"
|
||||
|
||||
app * mk_list_assoc_app(ast_manager & m, func_decl * f, unsigned num_args, expr * const * args) {
|
||||
SASSERT(f->is_associative());
|
||||
|
@ -361,3 +362,18 @@ void flatten_or(expr* fml, expr_ref_vector& result) {
|
|||
result.push_back(fml);
|
||||
flatten_or(result);
|
||||
}
|
||||
|
||||
static app_ref plus(ast_manager& m, expr* a, expr* b) {
|
||||
arith_util arith(m);
|
||||
return app_ref(arith.mk_add(a, b), m);
|
||||
}
|
||||
|
||||
static app_ref plus(ast_manager& m, expr* a, int i) {
|
||||
arith_util arith(m);
|
||||
return app_ref(arith.mk_add(a, arith.mk_int(i)), m);
|
||||
}
|
||||
|
||||
app_ref operator+(expr_ref& a, expr* b) { return plus(a.m(), a, b); }
|
||||
app_ref operator+(app_ref& a, expr* b) { return plus(a.m(), a, b); }
|
||||
app_ref operator+(expr_ref& a, int i) { return plus(a.m(), a, i); }
|
||||
app_ref operator+(app_ref& a, int i) { return plus(a.m(), a, i); }
|
||||
|
|
|
@ -120,7 +120,10 @@ inline app_ref operator|(expr_ref& a, expr* b) { return app_ref(a.m().mk_or(a, b
|
|||
inline app_ref operator|(app_ref& a, expr* b) { return app_ref(a.m().mk_or(a, b), a.m()); }
|
||||
inline app_ref operator|(var_ref& a, expr* b) { return app_ref(a.m().mk_or(a, b), a.m()); }
|
||||
inline app_ref operator|(quantifier_ref& a, expr* b) { return app_ref(a.m().mk_or(a, b), a.m()); }
|
||||
|
||||
app_ref operator+(expr_ref& a, expr* b);
|
||||
app_ref operator+(app_ref& a, expr* b);
|
||||
app_ref operator+(expr_ref& a, int i);
|
||||
app_ref operator+(app_ref& a, int i);
|
||||
|
||||
/**
|
||||
Return (or args[0] ... args[num_args-1]) if num_args >= 2
|
||||
|
|
|
@ -69,6 +69,20 @@ public:
|
|||
br_status mk_set_difference(expr * arg1, expr * arg2, expr_ref & result);
|
||||
br_status mk_set_subset(expr * arg1, expr * arg2, expr_ref & result);
|
||||
br_status mk_eq_core(expr * lhs, expr * rhs, expr_ref & result);
|
||||
|
||||
expr_ref mk_set_difference(expr* a, expr* b) {
|
||||
expr_ref result(m());
|
||||
mk_set_difference(a, b, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
expr_ref mk_set_intersect(expr* a, expr* b) {
|
||||
expr_ref result(m());
|
||||
expr* args[2] = { a, b };
|
||||
mk_set_intersect(2, args, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue