mirror of
https://github.com/Z3Prover/z3
synced 2026-02-19 23:14:40 +00:00
add functions that create unique sets for model construction based on solving cardinality constraints
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
1d3f6a7c70
commit
ba13460511
6 changed files with 108 additions and 23 deletions
|
|
@ -40,6 +40,7 @@ finite_set_decl_plugin::finite_set_decl_plugin():
|
|||
m_names[OP_FINITE_SET_RANGE] = "set.range";
|
||||
m_names[OP_FINITE_SET_EXT] = "set.diff";
|
||||
m_names[OP_FINITE_SET_MAP_INVERSE] = "set.map.inverse";
|
||||
m_names[OP_FINITE_SET_UNIQUE_SET] = "set.unique";
|
||||
}
|
||||
|
||||
finite_set_decl_plugin::~finite_set_decl_plugin() {
|
||||
|
|
@ -87,6 +88,7 @@ void finite_set_decl_plugin::init() {
|
|||
m_sigs[OP_FINITE_SET_RANGE] = alloc(polymorphism::psig, m, m_names[OP_FINITE_SET_RANGE], 0, 2, intintT, setInt);
|
||||
m_sigs[OP_FINITE_SET_EXT] = alloc(polymorphism::psig, m, m_names[OP_FINITE_SET_EXT], 1, 2, setAsetA, A);
|
||||
m_sigs[OP_FINITE_SET_MAP_INVERSE] = alloc(polymorphism::psig, m, m_names[OP_FINITE_SET_MAP_INVERSE], 2, 3, arrABBsetA, A);
|
||||
m_sigs[OP_FINITE_SET_UNIQUE_SET] = alloc(polymorphism::psig, m, m_names[OP_FINITE_SET_UNIQUE_SET], 1, 2, intintT, setA);
|
||||
}
|
||||
|
||||
sort * finite_set_decl_plugin::mk_sort(decl_kind k, unsigned num_parameters, parameter const * parameters) {
|
||||
|
|
@ -183,6 +185,15 @@ func_decl * finite_set_decl_plugin::mk_func_decl(decl_kind k, unsigned num_param
|
|||
range = to_sort(parameters[0].get_ast());
|
||||
}
|
||||
return mk_empty(range);
|
||||
case OP_FINITE_SET_UNIQUE_SET:
|
||||
if (!range) {
|
||||
if ((num_parameters != 1 || !parameters[0].is_ast() || !is_sort(parameters[0].get_ast()))) {
|
||||
m_manager->raise_exception("set.unique requires one sort parameter");
|
||||
return nullptr;
|
||||
}
|
||||
range = to_sort(parameters[0].get_ast());
|
||||
}
|
||||
return mk_finite_set_op(k, arity, domain, range);
|
||||
case OP_FINITE_SET_UNION:
|
||||
case OP_FINITE_SET_INTERSECT:
|
||||
return mk_finite_set_op(k, 2, domain, range);
|
||||
|
|
@ -204,7 +215,7 @@ func_decl * finite_set_decl_plugin::mk_func_decl(decl_kind k, unsigned num_param
|
|||
|
||||
void finite_set_decl_plugin::get_op_names(svector<builtin_name>& op_names, symbol const & logic) {
|
||||
for (unsigned i = 0; i < m_names.size(); ++i)
|
||||
if (m_names[i])
|
||||
if (m_names[i] && i != OP_FINITE_SET_UNIQUE_SET)
|
||||
op_names.push_back(builtin_name(std::string(m_names[i]), i));
|
||||
}
|
||||
|
||||
|
|
@ -326,3 +337,9 @@ func_decl *finite_set_util::mk_range_decl() {
|
|||
return m_manager.mk_func_decl(m_fid, OP_FINITE_SET_RANGE, 0, nullptr, 2, domain, nullptr);
|
||||
}
|
||||
|
||||
app* finite_set_util::mk_unique_set(expr* index, expr* cardinality, sort* s) {
|
||||
parameter params[1] = { parameter(s) };
|
||||
expr *args[2] = {index, cardinality};
|
||||
return m_manager.mk_app(m_fid, OP_FINITE_SET_UNIQUE_SET, 1, params, 2, args);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ enum finite_set_op_kind {
|
|||
OP_FINITE_SET_RANGE,
|
||||
OP_FINITE_SET_EXT,
|
||||
OP_FINITE_SET_MAP_INVERSE,
|
||||
OP_FINITE_SET_UNIQUE_SET,
|
||||
LAST_FINITE_SET_OP
|
||||
};
|
||||
|
||||
|
|
@ -134,6 +135,7 @@ public:
|
|||
bool is_map(expr const* n) const { return is_app_of(n, m_fid, OP_FINITE_SET_MAP); }
|
||||
bool is_filter(expr const* n) const { return is_app_of(n, m_fid, OP_FINITE_SET_FILTER); }
|
||||
bool is_range(expr const* n) const { return is_app_of(n, m_fid, OP_FINITE_SET_RANGE); }
|
||||
bool is_unique_set(expr const *n) const { return is_app_of(n, m_fid, OP_FINITE_SET_UNIQUE_SET); }
|
||||
|
||||
MATCH_UNARY(is_singleton);
|
||||
MATCH_UNARY(is_size);
|
||||
|
|
@ -145,6 +147,7 @@ public:
|
|||
MATCH_BINARY(is_map);
|
||||
MATCH_BINARY(is_filter);
|
||||
MATCH_BINARY(is_range);
|
||||
MATCH_BINARY(is_unique_set);
|
||||
};
|
||||
|
||||
class finite_set_util : public finite_set_recognizers {
|
||||
|
|
@ -211,7 +214,9 @@ public:
|
|||
|
||||
func_decl *mk_range_decl();
|
||||
|
||||
app * mk_range(expr* low, expr* high) {
|
||||
app *mk_range(expr *low, expr *high) {
|
||||
return m_manager.mk_app(m_fid, OP_FINITE_SET_RANGE, low, high);
|
||||
}
|
||||
|
||||
app *mk_unique_set(expr *s1, expr *s2, sort *s);
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue