mirror of
https://github.com/Z3Prover/z3
synced 2025-11-10 16:12:03 +00:00
Implement get_fresh_value algorithm for finite_set_value_factory
Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
This commit is contained in:
parent
d2d4113042
commit
e6b26d5df5
2 changed files with 28 additions and 20 deletions
|
|
@ -30,34 +30,40 @@ expr * finite_set_value_factory::get_some_value(sort * s) {
|
||||||
expr * finite_set_value_factory::get_fresh_value(sort * s) {
|
expr * finite_set_value_factory::get_fresh_value(sort * s) {
|
||||||
sort* elem_sort = nullptr;
|
sort* elem_sort = nullptr;
|
||||||
VERIFY(u.is_finite_set(s, elem_sort));
|
VERIFY(u.is_finite_set(s, elem_sort));
|
||||||
// Get a fresh value for a finite set sort
|
|
||||||
|
|
||||||
auto& [set, values] = get_value_set(s);
|
auto& [set, values] = get_value_set(s);
|
||||||
|
|
||||||
// If no values have been generated yet, use get_some_value
|
// Case 1: If no values have been generated yet, return empty set
|
||||||
if (set.empty()) {
|
if (values.size() == 0) {
|
||||||
auto r = u.mk_empty(s);
|
auto r = u.mk_empty(s);
|
||||||
register_value(r);
|
register_value(r);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
auto e = m_model.get_fresh_value(elem_sort);
|
|
||||||
if (e) {
|
// Helper lambda to check if a number is a power of 2
|
||||||
|
auto is_power_of_2 = [](unsigned n) {
|
||||||
|
return n > 0 && (n & (n - 1)) == 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Case 2: If values.size() is a power of 2, create a fresh singleton
|
||||||
|
if (is_power_of_2(values.size())) {
|
||||||
|
auto e = m_model.get_fresh_value(elem_sort);
|
||||||
|
if (!e)
|
||||||
|
return nullptr;
|
||||||
|
register_value(e);
|
||||||
auto r = u.mk_singleton(e);
|
auto r = u.mk_singleton(e);
|
||||||
register_value(e); // register e so we can access the finite domain within this class
|
|
||||||
register_value(r);
|
register_value(r);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
auto& [set_e, values_e] = get_value_set(elem_sort);
|
|
||||||
unsigned next_index = values.size();
|
// Case 3: Find greatest power of 2 N < values.size() and create union
|
||||||
SASSERT(next_index >= 1 + values_e.size()); // we already generated the empty set and all singletons
|
// Find the greatest N that is a power of 2 and N < values.size()
|
||||||
|
unsigned N = 1;
|
||||||
// Course Task of 10-16-25:
|
while (N * 2 < values.size()) {
|
||||||
// For finite domains, we may not be able to generate fresh values
|
N *= 2;
|
||||||
// if all values have been exhausted
|
}
|
||||||
// create sets based on next_index
|
|
||||||
// assume that values_e contains all the values of the element sort
|
auto r = u.mk_union(values.get(values.size() - N), values.back());
|
||||||
// and they have already been generated.
|
register_value(r);
|
||||||
// Figure out if we are creating two, three, or more element sets
|
return r;
|
||||||
// and map next_index into the elements in a uniqe way.
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
@ -200,6 +200,8 @@ static void tst_finite_set_is_fully_interp() {
|
||||||
ast_manager m;
|
ast_manager m;
|
||||||
reg_decl_plugins(m);
|
reg_decl_plugins(m);
|
||||||
|
|
||||||
|
finite_set_util fsets(m);
|
||||||
|
|
||||||
// Test with Bool sort (should be fully interpreted)
|
// Test with Bool sort (should be fully interpreted)
|
||||||
sort_ref bool_sort(m.mk_bool_sort(), m);
|
sort_ref bool_sort(m.mk_bool_sort(), m);
|
||||||
parameter bool_param(bool_sort.get());
|
parameter bool_param(bool_sort.get());
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue