3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-02-19 23:14:40 +00:00

Extend finite_set_decl_plugin::is_value to support unions of empty/singleton sets (#7980)

* Initial plan

* Initial state - all tests passing

Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>

* Implement is_value for unions of empty/singleton sets

Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
Co-authored-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Copilot 2025-10-16 13:36:55 +02:00 committed by GitHub
parent 1536b4fde3
commit 0371bbd192
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 114 additions and 2 deletions

View file

@ -127,20 +127,78 @@ static void tst_finite_set_map_select() {
ENSURE(selected_set->get_sort() == finite_set_int.get());
}
static void tst_finite_set_is_fully_interp() {
static void tst_finite_set_is_value() {
ast_manager m;
reg_decl_plugins(m);
finite_set_util fsets(m);
arith_util arith(m);
finite_set_decl_plugin* plugin = static_cast<finite_set_decl_plugin*>(m.get_plugin(fsets.get_family_id()));
// Create Int sort and finite set sort
// Test with Int sort (should be fully interpreted)
sort_ref int_sort(arith.mk_int(), m);
parameter int_param(int_sort.get());
sort_ref finite_set_int(m.mk_sort(fsets.get_family_id(), FINITE_SET_SORT, 1, &int_param), m);
// Test 1: Empty set is a value
app_ref empty_set(fsets.mk_empty(finite_set_int), m);
ENSURE(plugin->is_value(empty_set.get()));
// Test 2: Singleton with value element is a value
expr_ref five(arith.mk_int(5), m);
app_ref singleton_five(fsets.mk_singleton(five), m);
ENSURE(plugin->is_value(singleton_five.get()));
// Test 3: Union of empty and singleton is a value
app_ref union_empty_singleton(fsets.mk_union(empty_set, singleton_five), m);
ENSURE(plugin->is_value(union_empty_singleton.get()));
// Test 4: Union of two singletons with value elements is a value
expr_ref seven(arith.mk_int(7), m);
app_ref singleton_seven(fsets.mk_singleton(seven), m);
app_ref union_two_singletons(fsets.mk_union(singleton_five, singleton_seven), m);
ENSURE(plugin->is_value(union_two_singletons.get()));
// Test 5: Nested union of singletons and empty sets is a value
app_ref union_nested(fsets.mk_union(union_empty_singleton, singleton_seven), m);
ENSURE(plugin->is_value(union_nested.get()));
// Test 6: Union with empty set is a value
app_ref union_empty_empty(fsets.mk_union(empty_set, empty_set), m);
ENSURE(plugin->is_value(union_empty_empty.get()));
// Test 7: Triple union is a value
expr_ref nine(arith.mk_int(9), m);
app_ref singleton_nine(fsets.mk_singleton(nine), m);
app_ref union_temp(fsets.mk_union(singleton_five, singleton_seven), m);
app_ref union_triple(fsets.mk_union(union_temp, singleton_nine), m);
ENSURE(plugin->is_value(union_triple.get()));
// Test 8: Range is NOT a value (it's not a union of empty/singletons)
expr_ref zero(arith.mk_int(0), m);
expr_ref ten(arith.mk_int(10), m);
app_ref range_set(fsets.mk_range(zero, ten), m);
ENSURE(!plugin->is_value(range_set.get()));
// Test 9: Union with range is NOT a value
app_ref union_with_range(fsets.mk_union(singleton_five, range_set), m);
ENSURE(!plugin->is_value(union_with_range.get()));
// Test 10: Intersect is NOT a value
app_ref intersect_set(fsets.mk_intersect(singleton_five, singleton_seven), m);
ENSURE(!plugin->is_value(intersect_set.get()));
ENSURE(m.is_fully_interp(int_sort));
ENSURE(m.is_fully_interp(finite_set_int));
}
static void tst_finite_set_is_fully_interp() {
ast_manager m;
reg_decl_plugins(m);
// Test with Bool sort (should be fully interpreted)
sort_ref bool_sort(m.mk_bool_sort(), m);
@ -162,5 +220,6 @@ static void tst_finite_set_is_fully_interp() {
void tst_finite_set() {
tst_finite_set_basic();
tst_finite_set_map_select();
tst_finite_set_is_value();
tst_finite_set_is_fully_interp();
}