3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-10-08 00:41:56 +00:00

Implement finite_sets_decl_plugin with all specified operations

Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot] 2025-10-05 00:47:18 +00:00
parent 008c921dbf
commit d8beab9e1d
4 changed files with 525 additions and 0 deletions

View file

@ -24,3 +24,157 @@ Operators:
set.range : Int Int -> (FiniteSet Int)
--*/
#pragma once
#include "ast/ast.h"
enum finite_sets_sort_kind {
FINITE_SET_SORT
};
enum finite_sets_op_kind {
OP_FINITE_SET_EMPTY,
OP_FINITE_SET_UNION,
OP_FINITE_SET_INTERSECT,
OP_FINITE_SET_DIFFERENCE,
OP_FINITE_SET_IN,
OP_FINITE_SET_SIZE,
OP_FINITE_SET_SUBSET,
OP_FINITE_SET_MAP,
OP_FINITE_SET_FILTER,
OP_FINITE_SET_RANGE,
LAST_FINITE_SET_OP
};
class finite_sets_decl_plugin : public decl_plugin {
symbol m_empty_sym;
symbol m_union_sym;
symbol m_intersect_sym;
symbol m_difference_sym;
symbol m_in_sym;
symbol m_size_sym;
symbol m_subset_sym;
symbol m_map_sym;
symbol m_filter_sym;
symbol m_range_sym;
func_decl * mk_empty(sort* element_sort);
func_decl * mk_union(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_in(unsigned arity, sort * const * domain);
func_decl * mk_size(unsigned arity, sort * const * domain);
func_decl * mk_subset(unsigned arity, sort * const * domain);
func_decl * mk_map(func_decl* f, unsigned arity, sort* const* domain);
func_decl * mk_filter(func_decl* f, unsigned arity, sort* const* domain);
func_decl * mk_range(unsigned arity, sort * const * domain);
bool check_finite_set_arguments(unsigned arity, sort * const * domain);
sort * get_element_sort(sort* finite_set_sort) const;
public:
finite_sets_decl_plugin();
decl_plugin * mk_fresh() override {
return alloc(finite_sets_decl_plugin);
}
//
// Contract for sort:
// parameters[0] - element sort
//
sort * mk_sort(decl_kind k, unsigned num_parameters, parameter const * parameters) override;
//
// Contract for func_decl:
// For OP_FINITE_SET_MAP and OP_FINITE_SET_FILTER:
// parameters[0] - function declaration
// For others:
// no parameters
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<builtin_name> & op_names, symbol const & logic) override;
void get_sort_names(svector<builtin_name> & sort_names, symbol const & logic) override;
expr * get_some_value(sort * s) override;
bool is_fully_interp(sort * s) const override;
bool is_value(app * e) const override;
bool is_unique_value(app* e) const override;
};
class finite_sets_recognizers {
protected:
family_id m_fid;
public:
finite_sets_recognizers(family_id fid):m_fid(fid) {}
family_id get_family_id() const { return m_fid; }
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_empty(expr* n) const { return is_app_of(n, m_fid, OP_FINITE_SET_EMPTY); }
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_difference(expr* n) const { return is_app_of(n, m_fid, OP_FINITE_SET_DIFFERENCE); }
bool is_in(expr* n) const { return is_app_of(n, m_fid, OP_FINITE_SET_IN); }
bool is_size(expr* n) const { return is_app_of(n, m_fid, OP_FINITE_SET_SIZE); }
bool is_subset(expr* n) const { return is_app_of(n, m_fid, OP_FINITE_SET_SUBSET); }
bool is_map(expr* n) const { return is_app_of(n, m_fid, OP_FINITE_SET_MAP); }
bool is_filter(expr* n) const { return is_app_of(n, m_fid, OP_FINITE_SET_FILTER); }
bool is_range(expr* n) const { return is_app_of(n, m_fid, OP_FINITE_SET_RANGE); }
};
class finite_sets_util : public finite_sets_recognizers {
ast_manager& m_manager;
public:
finite_sets_util(ast_manager& m):
finite_sets_recognizers(m.mk_family_id("finite_sets")), m_manager(m) {}
ast_manager& get_manager() const { return m_manager; }
app * mk_empty(sort* element_sort) {
parameter param(element_sort);
return m_manager.mk_app(m_fid, OP_FINITE_SET_EMPTY, 1, &param, 0, nullptr);
}
app * mk_union(expr* s1, expr* s2) {
return m_manager.mk_app(m_fid, OP_FINITE_SET_UNION, s1, s2);
}
app * mk_intersect(expr* s1, expr* s2) {
return m_manager.mk_app(m_fid, OP_FINITE_SET_INTERSECT, s1, s2);
}
app * mk_difference(expr* s1, expr* s2) {
return m_manager.mk_app(m_fid, OP_FINITE_SET_DIFFERENCE, s1, s2);
}
app * mk_in(expr* elem, expr* set) {
return m_manager.mk_app(m_fid, OP_FINITE_SET_IN, elem, set);
}
app * mk_size(expr* set) {
return m_manager.mk_app(m_fid, OP_FINITE_SET_SIZE, set);
}
app * mk_subset(expr* s1, expr* s2) {
return m_manager.mk_app(m_fid, OP_FINITE_SET_SUBSET, s1, s2);
}
app * mk_map(func_decl* f, expr* set) {
parameter param(f);
return m_manager.mk_app(m_fid, OP_FINITE_SET_MAP, 1, &param, 1, &set);
}
app * mk_filter(func_decl* f, expr* set) {
parameter param(f);
return m_manager.mk_app(m_fid, OP_FINITE_SET_FILTER, 1, &param, 1, &set);
}
app * mk_range(expr* low, expr* high) {
return m_manager.mk_app(m_fid, OP_FINITE_SET_RANGE, low, high);
}
};