mirror of
https://github.com/Z3Prover/z3
synced 2025-10-08 00:41:56 +00:00
Add set.singleton operator to finite_sets_decl_plugin
Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
This commit is contained in:
parent
12173923a0
commit
980ea35b0e
3 changed files with 36 additions and 1 deletions
|
@ -23,6 +23,7 @@ Revision History:
|
||||||
|
|
||||||
finite_sets_decl_plugin::finite_sets_decl_plugin():
|
finite_sets_decl_plugin::finite_sets_decl_plugin():
|
||||||
m_empty_sym("set.empty"),
|
m_empty_sym("set.empty"),
|
||||||
|
m_singleton_sym("set.singleton"),
|
||||||
m_union_sym("set.union"),
|
m_union_sym("set.union"),
|
||||||
m_intersect_sym("set.intersect"),
|
m_intersect_sym("set.intersect"),
|
||||||
m_difference_sym("set.difference"),
|
m_difference_sym("set.difference"),
|
||||||
|
@ -96,6 +97,23 @@ func_decl * finite_sets_decl_plugin::mk_empty(sort* element_sort) {
|
||||||
func_decl_info(m_family_id, OP_FINITE_SET_EMPTY, 1, ¶m));
|
func_decl_info(m_family_id, OP_FINITE_SET_EMPTY, 1, ¶m));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func_decl * finite_sets_decl_plugin::mk_singleton(unsigned arity, sort * const * domain) {
|
||||||
|
if (arity != 1) {
|
||||||
|
m_manager->raise_exception("set.singleton takes exactly one argument");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The element sort is the domain
|
||||||
|
sort* element_sort = domain[0];
|
||||||
|
|
||||||
|
// Create the result sort: FiniteSet of the element type
|
||||||
|
parameter param(element_sort);
|
||||||
|
sort* finite_set_sort = m_manager->mk_sort(m_family_id, FINITE_SET_SORT, 1, ¶m);
|
||||||
|
|
||||||
|
return m_manager->mk_func_decl(m_singleton_sym, arity, domain, finite_set_sort,
|
||||||
|
func_decl_info(m_family_id, OP_FINITE_SET_SINGLETON));
|
||||||
|
}
|
||||||
|
|
||||||
func_decl * finite_sets_decl_plugin::mk_union(unsigned arity, sort * const * domain) {
|
func_decl * finite_sets_decl_plugin::mk_union(unsigned arity, sort * const * domain) {
|
||||||
if (arity != 2) {
|
if (arity != 2) {
|
||||||
m_manager->raise_exception("set.union takes exactly two arguments");
|
m_manager->raise_exception("set.union takes exactly two arguments");
|
||||||
|
@ -291,6 +309,8 @@ func_decl * finite_sets_decl_plugin::mk_func_decl(decl_kind k, unsigned num_para
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return mk_empty(to_sort(parameters[0].get_ast()));
|
return mk_empty(to_sort(parameters[0].get_ast()));
|
||||||
|
case OP_FINITE_SET_SINGLETON:
|
||||||
|
return mk_singleton(arity, domain);
|
||||||
case OP_FINITE_SET_UNION:
|
case OP_FINITE_SET_UNION:
|
||||||
return mk_union(arity, domain);
|
return mk_union(arity, domain);
|
||||||
case OP_FINITE_SET_INTERSECT:
|
case OP_FINITE_SET_INTERSECT:
|
||||||
|
@ -324,6 +344,7 @@ func_decl * finite_sets_decl_plugin::mk_func_decl(decl_kind k, unsigned num_para
|
||||||
|
|
||||||
void finite_sets_decl_plugin::get_op_names(svector<builtin_name>& op_names, symbol const & logic) {
|
void finite_sets_decl_plugin::get_op_names(svector<builtin_name>& op_names, symbol const & logic) {
|
||||||
op_names.push_back(builtin_name("set.empty", OP_FINITE_SET_EMPTY));
|
op_names.push_back(builtin_name("set.empty", OP_FINITE_SET_EMPTY));
|
||||||
|
op_names.push_back(builtin_name("set.singleton", OP_FINITE_SET_SINGLETON));
|
||||||
op_names.push_back(builtin_name("set.union", OP_FINITE_SET_UNION));
|
op_names.push_back(builtin_name("set.union", OP_FINITE_SET_UNION));
|
||||||
op_names.push_back(builtin_name("set.intersect", OP_FINITE_SET_INTERSECT));
|
op_names.push_back(builtin_name("set.intersect", OP_FINITE_SET_INTERSECT));
|
||||||
op_names.push_back(builtin_name("set.difference", OP_FINITE_SET_DIFFERENCE));
|
op_names.push_back(builtin_name("set.difference", OP_FINITE_SET_DIFFERENCE));
|
||||||
|
|
|
@ -13,6 +13,7 @@ Sort:
|
||||||
|
|
||||||
Operators:
|
Operators:
|
||||||
set.empty : (FiniteSet S)
|
set.empty : (FiniteSet S)
|
||||||
|
set.singleton : S -> (FiniteSet S)
|
||||||
set.union : (FiniteSet S) (FiniteSet S) -> (FiniteSet S)
|
set.union : (FiniteSet S) (FiniteSet S) -> (FiniteSet S)
|
||||||
set.intersect : (FiniteSet S) (FiniteSet S) -> (FiniteSet S)
|
set.intersect : (FiniteSet S) (FiniteSet S) -> (FiniteSet S)
|
||||||
set.difference : (FiniteSet S) (FiniteSet S) -> (FiniteSet S)
|
set.difference : (FiniteSet S) (FiniteSet S) -> (FiniteSet S)
|
||||||
|
@ -34,6 +35,7 @@ enum finite_sets_sort_kind {
|
||||||
|
|
||||||
enum finite_sets_op_kind {
|
enum finite_sets_op_kind {
|
||||||
OP_FINITE_SET_EMPTY,
|
OP_FINITE_SET_EMPTY,
|
||||||
|
OP_FINITE_SET_SINGLETON,
|
||||||
OP_FINITE_SET_UNION,
|
OP_FINITE_SET_UNION,
|
||||||
OP_FINITE_SET_INTERSECT,
|
OP_FINITE_SET_INTERSECT,
|
||||||
OP_FINITE_SET_DIFFERENCE,
|
OP_FINITE_SET_DIFFERENCE,
|
||||||
|
@ -48,6 +50,7 @@ enum finite_sets_op_kind {
|
||||||
|
|
||||||
class finite_sets_decl_plugin : public decl_plugin {
|
class finite_sets_decl_plugin : public decl_plugin {
|
||||||
symbol m_empty_sym;
|
symbol m_empty_sym;
|
||||||
|
symbol m_singleton_sym;
|
||||||
symbol m_union_sym;
|
symbol m_union_sym;
|
||||||
symbol m_intersect_sym;
|
symbol m_intersect_sym;
|
||||||
symbol m_difference_sym;
|
symbol m_difference_sym;
|
||||||
|
@ -59,6 +62,7 @@ class finite_sets_decl_plugin : public decl_plugin {
|
||||||
symbol m_range_sym;
|
symbol m_range_sym;
|
||||||
|
|
||||||
func_decl * mk_empty(sort* element_sort);
|
func_decl * mk_empty(sort* element_sort);
|
||||||
|
func_decl * mk_singleton(unsigned arity, sort * const * domain);
|
||||||
func_decl * mk_union(unsigned arity, sort * const * domain);
|
func_decl * mk_union(unsigned arity, sort * const * domain);
|
||||||
func_decl * mk_intersect(unsigned arity, sort * const * domain);
|
func_decl * mk_intersect(unsigned arity, sort * const * domain);
|
||||||
func_decl * mk_difference(unsigned arity, sort * const * domain);
|
func_decl * mk_difference(unsigned arity, sort * const * domain);
|
||||||
|
@ -116,6 +120,7 @@ public:
|
||||||
bool is_finite_set(sort* s) const { return is_sort_of(s, m_fid, FINITE_SET_SORT); }
|
bool is_finite_set(sort* s) const { return is_sort_of(s, m_fid, FINITE_SET_SORT); }
|
||||||
bool is_finite_set(expr* n) const { return is_finite_set(n->get_sort()); }
|
bool is_finite_set(expr* n) const { return is_finite_set(n->get_sort()); }
|
||||||
bool is_empty(expr* n) const { return is_app_of(n, m_fid, OP_FINITE_SET_EMPTY); }
|
bool is_empty(expr* n) const { return is_app_of(n, m_fid, OP_FINITE_SET_EMPTY); }
|
||||||
|
bool is_singleton(expr* n) const { return is_app_of(n, m_fid, OP_FINITE_SET_SINGLETON); }
|
||||||
bool is_union(expr* n) const { return is_app_of(n, m_fid, OP_FINITE_SET_UNION); }
|
bool is_union(expr* n) const { return is_app_of(n, m_fid, OP_FINITE_SET_UNION); }
|
||||||
bool is_intersect(expr* n) const { return is_app_of(n, m_fid, OP_FINITE_SET_INTERSECT); }
|
bool is_intersect(expr* n) const { return is_app_of(n, m_fid, OP_FINITE_SET_INTERSECT); }
|
||||||
bool is_difference(expr* n) const { return is_app_of(n, m_fid, OP_FINITE_SET_DIFFERENCE); }
|
bool is_difference(expr* n) const { return is_app_of(n, m_fid, OP_FINITE_SET_DIFFERENCE); }
|
||||||
|
@ -140,6 +145,10 @@ public:
|
||||||
return m_manager.mk_app(m_fid, OP_FINITE_SET_EMPTY, 1, ¶m, 0, nullptr);
|
return m_manager.mk_app(m_fid, OP_FINITE_SET_EMPTY, 1, ¶m, 0, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
app * mk_singleton(expr* elem) {
|
||||||
|
return m_manager.mk_app(m_fid, OP_FINITE_SET_SINGLETON, elem);
|
||||||
|
}
|
||||||
|
|
||||||
app * mk_union(expr* s1, expr* s2) {
|
app * mk_union(expr* s1, expr* s2) {
|
||||||
return m_manager.mk_app(m_fid, OP_FINITE_SET_UNION, s1, s2);
|
return m_manager.mk_app(m_fid, OP_FINITE_SET_UNION, s1, s2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,12 @@ static void tst_finite_sets_basic() {
|
||||||
ENSURE(fsets.is_empty(empty_set.get()));
|
ENSURE(fsets.is_empty(empty_set.get()));
|
||||||
ENSURE(empty_set->get_sort() == finite_set_int.get());
|
ENSURE(empty_set->get_sort() == finite_set_int.get());
|
||||||
|
|
||||||
|
// Test set.singleton
|
||||||
|
expr_ref five(arith.mk_int(5), m);
|
||||||
|
app_ref singleton_set(fsets.mk_singleton(five), m);
|
||||||
|
ENSURE(fsets.is_singleton(singleton_set.get()));
|
||||||
|
ENSURE(singleton_set->get_sort() == finite_set_int.get());
|
||||||
|
|
||||||
// Test set.range
|
// Test set.range
|
||||||
expr_ref zero(arith.mk_int(0), m);
|
expr_ref zero(arith.mk_int(0), m);
|
||||||
expr_ref ten(arith.mk_int(10), m);
|
expr_ref ten(arith.mk_int(10), m);
|
||||||
|
@ -63,7 +69,6 @@ static void tst_finite_sets_basic() {
|
||||||
ENSURE(diff_set->get_sort() == finite_set_int.get());
|
ENSURE(diff_set->get_sort() == finite_set_int.get());
|
||||||
|
|
||||||
// Test set.in
|
// Test set.in
|
||||||
expr_ref five(arith.mk_int(5), m);
|
|
||||||
app_ref in_expr(fsets.mk_in(five, range_set), m);
|
app_ref in_expr(fsets.mk_in(five, range_set), m);
|
||||||
ENSURE(fsets.is_in(in_expr.get()));
|
ENSURE(fsets.is_in(in_expr.get()));
|
||||||
ENSURE(m.is_bool(in_expr->get_sort()));
|
ENSURE(m.is_bool(in_expr->get_sort()));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue