3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-22 16:45:31 +00:00

add API and example for one dimensional algebraic datatype #6179

This commit is contained in:
Nikolaj Bjorner 2022-07-20 19:43:18 -07:00
parent 81cb575c22
commit 2e13c0bf41
2 changed files with 117 additions and 1 deletions

View file

@ -57,6 +57,8 @@ namespace z3 {
class param_descrs;
class ast;
class sort;
class constructors;
class constructor_list;
class func_decl;
class expr;
class solver;
@ -313,6 +315,24 @@ namespace z3 {
*/
func_decl tuple_sort(char const * name, unsigned n, char const * const * names, sort const* sorts, func_decl_vector & projs);
/**
\brief Create a recursive datatype over a single sort.
\c name is the name of the recursive datatype
\c n - the numer of constructors of the datatype
\c cs - the \c n constructors used to define the datatype
References to the datatype can be created using \ref datatype_sort.
*/
sort datatype(symbol const& name, constructors const& cs);
/**
\brief a reference to a recursively defined datatype.
Expect that it gets defined as a \ref datatype.
*/
sort datatype_sort(symbol const& name);
/**
\brief create an uninterpreted sort with the name given by the string or symbol.
*/
@ -3330,6 +3350,80 @@ namespace z3 {
return func_decl(*this, tuple);
}
class constructor_list {
context& ctx;
Z3_constructor_list clist;
public:
constructor_list(context& ctx, unsigned n, Z3_constructor const* cons): ctx(ctx) {
clist = Z3_mk_constructor_list(ctx, n, cons);
}
~constructor_list() {
Z3_del_constructor_list(ctx, clist);
}
};
class constructors {
context& ctx;
std::vector<Z3_constructor> cons;
std::vector<unsigned> num_fields;
public:
constructors(context& ctx): ctx(ctx) {}
~constructors() {
for (auto con : cons)
Z3_del_constructor(ctx, con);
}
void add(symbol const& name, symbol const& rec, unsigned n, symbol const* names, sort const* fields) {
array<unsigned> sort_refs(n);
array<Z3_sort> sorts(n);
array<Z3_symbol> _names(n);
for (unsigned i = 0; i < n; ++i) sorts[i] = fields[i], _names[i] = names[i];
cons.push_back(Z3_mk_constructor(ctx, name, rec, n, _names.ptr(), sorts.ptr(), sort_refs.ptr()));
num_fields.push_back(n);
}
Z3_constructor operator[](unsigned i) const { return cons[i]; }
unsigned size() const { return (unsigned)cons.size(); }
constructor_list get_constructors() const {
return constructor_list(ctx, (unsigned)cons.size(), cons.data());
}
void query(unsigned i, func_decl& constructor, func_decl& test, func_decl_vector& accs) {
Z3_func_decl _constructor;
Z3_func_decl _test;
array<Z3_func_decl> accessors(num_fields[i]);
Z3_query_constructor(ctx,
cons[i],
num_fields[i],
&_constructor,
&_test,
accessors.ptr());
constructor = func_decl(ctx, _constructor);
test = func_decl(ctx, _test);
for (unsigned j = 0; j < num_fields[i]; ++j)
accs.push_back(func_decl(ctx, accessors[j]));
}
};
inline sort context::datatype(symbol const& name, constructors const& cs) {
array<Z3_constructor> _cs(cs.size());
for (unsigned i = 0; i < cs.size(); ++i) _cs[i] = cs[i];
Z3_sort s = Z3_mk_datatype(*this, name, cs.size(), _cs.ptr());
check_error();
return sort(*this, s);
}
inline sort context::datatype_sort(symbol const& name) {
Z3_sort s = Z3_mk_datatype_sort(*this, name);
check_error();
return sort(*this, s);
}
inline sort context::uninterpreted_sort(char const* name) {
Z3_symbol _name = Z3_mk_string_symbol(*this, name);
return to_sort(*this, Z3_mk_uninterpreted_sort(*this, _name));