mirror of
https://github.com/Z3Prover/z3
synced 2026-02-22 16:27:37 +00:00
commit
8314aecb44
73 changed files with 5720 additions and 117 deletions
|
|
@ -56,6 +56,8 @@ add_executable(test-z3
|
|||
expr_substitution.cpp
|
||||
ext_numeral.cpp
|
||||
f2n.cpp
|
||||
finite_set.cpp
|
||||
finite_set_rewriter.cpp
|
||||
factor_rewriter.cpp
|
||||
finder.cpp
|
||||
fixed_bit_vector.cpp
|
||||
|
|
|
|||
286
src/test/finite_set.cpp
Normal file
286
src/test/finite_set.cpp
Normal file
|
|
@ -0,0 +1,286 @@
|
|||
/*++
|
||||
Copyright (c) 2025 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
tst_finite_set.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Test finite sets decl plugin
|
||||
|
||||
Author:
|
||||
|
||||
GitHub Copilot Agent 2025
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include "ast/ast.h"
|
||||
#include "ast/finite_set_decl_plugin.h"
|
||||
#include "ast/reg_decl_plugins.h"
|
||||
#include "ast/arith_decl_plugin.h"
|
||||
#include "ast/array_decl_plugin.h"
|
||||
|
||||
static void tst_finite_set_basic() {
|
||||
ast_manager m;
|
||||
reg_decl_plugins(m);
|
||||
|
||||
finite_set_util fsets(m);
|
||||
arith_util arith(m);
|
||||
|
||||
// Test creating a finite set sort
|
||||
sort_ref int_sort(arith.mk_int(), m);
|
||||
parameter param(int_sort.get());
|
||||
sort_ref finite_set_int(m.mk_sort(fsets.get_family_id(), FINITE_SET_SORT, 1, ¶m), m);
|
||||
|
||||
ENSURE(fsets.is_finite_set(finite_set_int.get()));
|
||||
|
||||
// Test creating empty set
|
||||
app_ref empty_set(fsets.mk_empty(finite_set_int), m);
|
||||
ENSURE(fsets.is_empty(empty_set.get()));
|
||||
ENSURE(empty_set->get_sort() == finite_set_int.get());
|
||||
|
||||
// Test set.singleton
|
||||
expr_ref five(arith.mk_int(5), m);
|
||||
app_ref singleton_set(fsets.mk_singleton(five), m);
|
||||
ENSURE(fsets.is_singleton(singleton_set.get()));
|
||||
ENSURE(singleton_set->get_sort() == finite_set_int.get());
|
||||
|
||||
// Test set.range
|
||||
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(fsets.is_range(range_set.get()));
|
||||
ENSURE(range_set->get_sort() == finite_set_int.get());
|
||||
|
||||
// Test set.union
|
||||
app_ref union_set(fsets.mk_union(empty_set, range_set), m);
|
||||
ENSURE(fsets.is_union(union_set.get()));
|
||||
ENSURE(union_set->get_sort() == finite_set_int.get());
|
||||
|
||||
// Test set.intersect
|
||||
app_ref intersect_set(fsets.mk_intersect(range_set, range_set), m);
|
||||
ENSURE(fsets.is_intersect(intersect_set.get()));
|
||||
ENSURE(intersect_set->get_sort() == finite_set_int.get());
|
||||
|
||||
// Test set.difference
|
||||
app_ref diff_set(fsets.mk_difference(range_set, empty_set), m);
|
||||
ENSURE(fsets.is_difference(diff_set.get()));
|
||||
ENSURE(diff_set->get_sort() == finite_set_int.get());
|
||||
|
||||
// Test set.in
|
||||
app_ref in_expr(fsets.mk_in(five, range_set), m);
|
||||
ENSURE(fsets.is_in(in_expr.get()));
|
||||
ENSURE(m.is_bool(in_expr->get_sort()));
|
||||
|
||||
// Test set.size
|
||||
app_ref size_expr(fsets.mk_size(range_set), m);
|
||||
ENSURE(fsets.is_size(size_expr.get()));
|
||||
ENSURE(arith.is_int(size_expr->get_sort()));
|
||||
|
||||
// Test set.subset
|
||||
app_ref subset_expr(fsets.mk_subset(empty_set, range_set), m);
|
||||
ENSURE(fsets.is_subset(subset_expr.get()));
|
||||
ENSURE(m.is_bool(subset_expr->get_sort()));
|
||||
}
|
||||
|
||||
static void tst_finite_set_map_filter() {
|
||||
ast_manager m;
|
||||
reg_decl_plugins(m);
|
||||
|
||||
finite_set_util fsets(m);
|
||||
arith_util arith(m);
|
||||
array_util autil(m);
|
||||
|
||||
// Create Int and Bool sorts
|
||||
sort_ref int_sort(arith.mk_int(), m);
|
||||
sort_ref bool_sort(m.mk_bool_sort(), m);
|
||||
|
||||
// Create finite set sorts
|
||||
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);
|
||||
|
||||
// Create Array (Int Int) sort for map
|
||||
sort_ref arr_int_int(autil.mk_array_sort(int_sort, int_sort), m);
|
||||
|
||||
// Create a const array (conceptually represents the function)
|
||||
app_ref arr_map(autil.mk_const_array(arr_int_int, arith.mk_int(42)), m);
|
||||
|
||||
// Create a set and test map
|
||||
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);
|
||||
|
||||
app_ref mapped_set(fsets.mk_map(arr_map, range_set), m);
|
||||
ENSURE(fsets.is_map(mapped_set.get()));
|
||||
ENSURE(fsets.is_finite_set(mapped_set->get_sort()));
|
||||
|
||||
// Create Array (Int Bool) sort for filter
|
||||
sort_ref arr_int_bool(autil.mk_array_sort(int_sort, bool_sort), m);
|
||||
|
||||
// Create a const array for filter (conceptually represents predicate)
|
||||
app_ref arr_filter(autil.mk_const_array(arr_int_bool, m.mk_true()), m);
|
||||
|
||||
app_ref filtered_set(fsets.mk_filter(arr_filter, range_set), m);
|
||||
ENSURE(fsets.is_filter(filtered_set.get()));
|
||||
ENSURE(filtered_set->get_sort() == finite_set_int.get());
|
||||
}
|
||||
|
||||
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 a value
|
||||
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 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 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);
|
||||
|
||||
finite_set_util fsets(m);
|
||||
|
||||
// Test with Bool sort (should be fully interpreted)
|
||||
sort_ref bool_sort(m.mk_bool_sort(), m);
|
||||
parameter bool_param(bool_sort.get());
|
||||
sort_ref finite_set_bool(m.mk_sort(fsets.get_family_id(), FINITE_SET_SORT, 1, &bool_param), m);
|
||||
|
||||
ENSURE(m.is_fully_interp(bool_sort));
|
||||
ENSURE(m.is_fully_interp(finite_set_bool));
|
||||
|
||||
// Test with uninterpreted sort (should not be fully interpreted)
|
||||
sort_ref uninterp_sort(m.mk_uninterpreted_sort(symbol("U")), m);
|
||||
parameter uninterp_param(uninterp_sort.get());
|
||||
sort_ref finite_set_uninterp(m.mk_sort(fsets.get_family_id(), FINITE_SET_SORT, 1, &uninterp_param), m);
|
||||
|
||||
ENSURE(!m.is_fully_interp(uninterp_sort));
|
||||
ENSURE(!m.is_fully_interp(finite_set_uninterp));
|
||||
}
|
||||
|
||||
static void tst_finite_set_sort_size() {
|
||||
ast_manager m;
|
||||
reg_decl_plugins(m);
|
||||
|
||||
finite_set_util fsets(m);
|
||||
|
||||
// Test 1: Bool sort (size 2) -> FiniteSet(Bool) should have size 2^2 = 4
|
||||
sort_ref bool_sort(m.mk_bool_sort(), m);
|
||||
parameter bool_param(bool_sort.get());
|
||||
sort_ref finite_set_bool(m.mk_sort(fsets.get_family_id(), FINITE_SET_SORT, 1, &bool_param), m);
|
||||
|
||||
sort_size const& bool_set_sz = finite_set_bool->get_num_elements();
|
||||
ENSURE(bool_set_sz.is_finite());
|
||||
ENSURE(!bool_set_sz.is_very_big());
|
||||
ENSURE(bool_set_sz.size() == 4); // 2^2 = 4
|
||||
|
||||
// Test 2: Create a finite sort with known size (e.g., BV with size 3)
|
||||
// BV[3] has 2^3 = 8 elements, so FiniteSet(BV[3]) should have 2^8 = 256 elements
|
||||
parameter bv_param(3);
|
||||
sort_ref bv3_sort(m.mk_sort(m.mk_family_id("bv"), 0, 1, &bv_param), m);
|
||||
parameter bv3_param(bv3_sort.get());
|
||||
sort_ref finite_set_bv3(m.mk_sort(fsets.get_family_id(), FINITE_SET_SORT, 1, &bv3_param), m);
|
||||
|
||||
sort_size const& bv3_set_sz = finite_set_bv3->get_num_elements();
|
||||
ENSURE(bv3_set_sz.is_finite());
|
||||
ENSURE(!bv3_set_sz.is_very_big());
|
||||
ENSURE(bv3_set_sz.size() == 256); // 2^8 = 256
|
||||
|
||||
// Test 3: BV with size 5 -> BV[5] has 2^5 = 32 elements
|
||||
// Since 32 > 30, FiniteSet(BV[5]) should be marked as very_big
|
||||
parameter bv5_param(5);
|
||||
sort_ref bv5_sort(m.mk_sort(m.mk_family_id("bv"), 0, 1, &bv5_param), m);
|
||||
parameter bv5_set_param(bv5_sort.get());
|
||||
sort_ref finite_set_bv5(m.mk_sort(fsets.get_family_id(), FINITE_SET_SORT, 1, &bv5_set_param), m);
|
||||
|
||||
sort_size const& bv5_set_sz = finite_set_bv5->get_num_elements();
|
||||
ENSURE(bv5_set_sz.is_very_big());
|
||||
|
||||
// Test 4: Int sort (infinite) -> FiniteSet(Int) should be infinite
|
||||
arith_util arith(m);
|
||||
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);
|
||||
|
||||
sort_size const& int_set_sz = finite_set_int->get_num_elements();
|
||||
ENSURE(int_set_sz.is_infinite());
|
||||
|
||||
// Test 5: BV with size 4 -> BV[4] has 2^4 = 16 elements
|
||||
// FiniteSet(BV[4]) should have 2^16 = 65536 elements
|
||||
parameter bv4_param(4);
|
||||
sort_ref bv4_sort(m.mk_sort(m.mk_family_id("bv"), 0, 1, &bv4_param), m);
|
||||
parameter bv4_set_param(bv4_sort.get());
|
||||
sort_ref finite_set_bv4(m.mk_sort(fsets.get_family_id(), FINITE_SET_SORT, 1, &bv4_set_param), m);
|
||||
|
||||
sort_size const& bv4_set_sz = finite_set_bv4->get_num_elements();
|
||||
ENSURE(bv4_set_sz.is_finite());
|
||||
ENSURE(!bv4_set_sz.is_very_big());
|
||||
ENSURE(bv4_set_sz.size() == 65536); // 2^16 = 65536
|
||||
}
|
||||
|
||||
void tst_finite_set() {
|
||||
tst_finite_set_basic();
|
||||
tst_finite_set_map_filter();
|
||||
tst_finite_set_is_value();
|
||||
tst_finite_set_is_fully_interp();
|
||||
tst_finite_set_sort_size();
|
||||
}
|
||||
350
src/test/finite_set_rewriter.cpp
Normal file
350
src/test/finite_set_rewriter.cpp
Normal file
|
|
@ -0,0 +1,350 @@
|
|||
/*++
|
||||
Copyright (c) 2025 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
finite_set_rewriter.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Test finite set rewriter
|
||||
|
||||
Author:
|
||||
|
||||
GitHub Copilot Agent 2025
|
||||
|
||||
--*/
|
||||
|
||||
#include "ast/ast.h"
|
||||
#include "ast/finite_set_decl_plugin.h"
|
||||
#include "ast/reg_decl_plugins.h"
|
||||
#include "ast/arith_decl_plugin.h"
|
||||
#include "ast/rewriter/finite_set_rewriter.h"
|
||||
|
||||
class finite_set_rewriter_test {
|
||||
public:
|
||||
void test_union_idempotent() {
|
||||
ast_manager m;
|
||||
reg_decl_plugins(m);
|
||||
|
||||
finite_set_util fsets(m);
|
||||
finite_set_rewriter rw(m);
|
||||
arith_util arith(m);
|
||||
|
||||
// Create a set
|
||||
sort_ref int_sort(arith.mk_int(), m);
|
||||
expr_ref zero(arith.mk_int(0), m);
|
||||
expr_ref ten(arith.mk_int(10), m);
|
||||
app_ref s1(fsets.mk_range(zero, ten), m);
|
||||
|
||||
// Test set.union(s1, s1) -> s1
|
||||
app_ref union_app(fsets.mk_union(s1, s1), m);
|
||||
expr_ref result(m);
|
||||
br_status st = rw.mk_app_core(union_app->get_decl(), union_app->get_num_args(), union_app->get_args(), result);
|
||||
|
||||
ENSURE(st == BR_DONE);
|
||||
ENSURE(result == s1);
|
||||
}
|
||||
|
||||
void test_intersect_idempotent() {
|
||||
ast_manager m;
|
||||
reg_decl_plugins(m);
|
||||
|
||||
finite_set_util fsets(m);
|
||||
finite_set_rewriter rw(m);
|
||||
arith_util arith(m);
|
||||
|
||||
// Create a set
|
||||
sort_ref int_sort(arith.mk_int(), m);
|
||||
expr_ref zero(arith.mk_int(0), m);
|
||||
expr_ref ten(arith.mk_int(10), m);
|
||||
app_ref s1(fsets.mk_range(zero, ten), m);
|
||||
|
||||
// Test set.intersect(s1, s1) -> s1
|
||||
app_ref intersect_app(fsets.mk_intersect(s1, s1), m);
|
||||
expr_ref result(m);
|
||||
br_status st =
|
||||
rw.mk_app_core(intersect_app->get_decl(), intersect_app->get_num_args(), intersect_app->get_args(), result);
|
||||
|
||||
ENSURE(st == BR_DONE);
|
||||
ENSURE(result == s1);
|
||||
}
|
||||
|
||||
void test_difference_same() {
|
||||
ast_manager m;
|
||||
reg_decl_plugins(m);
|
||||
|
||||
finite_set_util fsets(m);
|
||||
finite_set_rewriter rw(m);
|
||||
arith_util arith(m);
|
||||
|
||||
// Create a set
|
||||
sort_ref int_sort(arith.mk_int(), m);
|
||||
expr_ref zero(arith.mk_int(0), m);
|
||||
expr_ref ten(arith.mk_int(10), m);
|
||||
app_ref s1(fsets.mk_range(zero, ten), m);
|
||||
|
||||
// Test set.difference(s1, s1) -> empty
|
||||
app_ref diff_app(fsets.mk_difference(s1, s1), m);
|
||||
expr_ref result(m);
|
||||
br_status st = rw.mk_app_core(diff_app->get_decl(), diff_app->get_num_args(), diff_app->get_args(), result);
|
||||
|
||||
ENSURE(st == BR_DONE);
|
||||
ENSURE(fsets.is_empty(result));
|
||||
}
|
||||
|
||||
void test_subset_rewrite() {
|
||||
ast_manager m;
|
||||
reg_decl_plugins(m);
|
||||
|
||||
finite_set_util fsets(m);
|
||||
finite_set_rewriter rw(m);
|
||||
arith_util arith(m);
|
||||
|
||||
// Create two sets
|
||||
sort_ref int_sort(arith.mk_int(), m);
|
||||
expr_ref zero(arith.mk_int(0), m);
|
||||
expr_ref ten(arith.mk_int(10), m);
|
||||
expr_ref twenty(arith.mk_int(20), m);
|
||||
app_ref s1(fsets.mk_range(zero, ten), m);
|
||||
app_ref s2(fsets.mk_range(zero, twenty), m);
|
||||
|
||||
// Test set.subset(s1, s2) -> set.intersect(s1, s2) = s1
|
||||
app_ref subset_app(fsets.mk_subset(s1, s2), m);
|
||||
expr_ref result(m);
|
||||
br_status st =
|
||||
rw.mk_app_core(subset_app->get_decl(), subset_app->get_num_args(), subset_app->get_args(), result);
|
||||
|
||||
ENSURE(st == BR_REWRITE3);
|
||||
ENSURE(m.is_eq(result));
|
||||
|
||||
// Check that result is an equality
|
||||
app *eq = to_app(result);
|
||||
ENSURE(eq->get_num_args() == 2);
|
||||
|
||||
// The left side should be set.intersect(s1, s2)
|
||||
expr *lhs = eq->get_arg(0);
|
||||
ENSURE(fsets.is_intersect(lhs));
|
||||
|
||||
// The right side should be s1
|
||||
expr *rhs = eq->get_arg(1);
|
||||
ENSURE(rhs == s1);
|
||||
}
|
||||
|
||||
void test_mk_app_core() {
|
||||
ast_manager m;
|
||||
reg_decl_plugins(m);
|
||||
|
||||
finite_set_util fsets(m);
|
||||
finite_set_rewriter rw(m);
|
||||
arith_util arith(m);
|
||||
|
||||
// Create sets
|
||||
sort_ref int_sort(arith.mk_int(), m);
|
||||
expr_ref zero(arith.mk_int(0), m);
|
||||
expr_ref ten(arith.mk_int(10), m);
|
||||
app_ref s1(fsets.mk_range(zero, ten), m);
|
||||
|
||||
// Test union through mk_app_core
|
||||
app_ref union_app(fsets.mk_union(s1, s1), m);
|
||||
expr_ref result(m);
|
||||
br_status st = rw.mk_app_core(union_app->get_decl(), union_app->get_num_args(), union_app->get_args(), result);
|
||||
|
||||
ENSURE(st == BR_DONE);
|
||||
ENSURE(result == s1);
|
||||
}
|
||||
|
||||
void test_union_with_empty() {
|
||||
ast_manager m;
|
||||
reg_decl_plugins(m);
|
||||
|
||||
finite_set_util fsets(m);
|
||||
finite_set_rewriter rw(m);
|
||||
arith_util arith(m);
|
||||
|
||||
// Create a set and empty set
|
||||
sort_ref int_sort(arith.mk_int(), m);
|
||||
expr_ref zero(arith.mk_int(0), m);
|
||||
expr_ref ten(arith.mk_int(10), m);
|
||||
app_ref s1(fsets.mk_range(zero, ten), m);
|
||||
app_ref empty_set(fsets.mk_empty(s1->get_sort()), m);
|
||||
|
||||
// Test set.union(s1, empty) -> s1
|
||||
app_ref union_app1(fsets.mk_union(s1, empty_set), m);
|
||||
expr_ref result1(m);
|
||||
br_status st1 =
|
||||
rw.mk_app_core(union_app1->get_decl(), union_app1->get_num_args(), union_app1->get_args(), result1);
|
||||
ENSURE(st1 == BR_DONE);
|
||||
ENSURE(result1 == s1);
|
||||
|
||||
// Test set.union(empty, s1) -> s1
|
||||
app_ref union_app2(fsets.mk_union(empty_set, s1), m);
|
||||
expr_ref result2(m);
|
||||
br_status st2 =
|
||||
rw.mk_app_core(union_app2->get_decl(), union_app2->get_num_args(), union_app2->get_args(), result2);
|
||||
ENSURE(st2 == BR_DONE);
|
||||
ENSURE(result2 == s1);
|
||||
}
|
||||
|
||||
void test_intersect_with_empty() {
|
||||
ast_manager m;
|
||||
reg_decl_plugins(m);
|
||||
|
||||
finite_set_util fsets(m);
|
||||
finite_set_rewriter rw(m);
|
||||
arith_util arith(m);
|
||||
|
||||
// Create a set and empty set
|
||||
sort_ref int_sort(arith.mk_int(), m);
|
||||
expr_ref zero(arith.mk_int(0), m);
|
||||
expr_ref ten(arith.mk_int(10), m);
|
||||
app_ref s1(fsets.mk_range(zero, ten), m);
|
||||
app_ref empty_set(fsets.mk_empty(s1->get_sort()), m);
|
||||
|
||||
// Test set.intersect(s1, empty) -> empty
|
||||
app_ref intersect_app1(fsets.mk_intersect(s1, empty_set), m);
|
||||
expr_ref result1(m);
|
||||
br_status st1 = rw.mk_app_core(intersect_app1->get_decl(), intersect_app1->get_num_args(),
|
||||
intersect_app1->get_args(), result1);
|
||||
ENSURE(st1 == BR_DONE);
|
||||
ENSURE(result1 == empty_set);
|
||||
|
||||
// Test set.intersect(empty, s1) -> empty
|
||||
app_ref intersect_app2(fsets.mk_intersect(empty_set, s1), m);
|
||||
expr_ref result2(m);
|
||||
br_status st2 = rw.mk_app_core(intersect_app2->get_decl(), intersect_app2->get_num_args(),
|
||||
intersect_app2->get_args(), result2);
|
||||
ENSURE(st2 == BR_DONE);
|
||||
ENSURE(result2 == empty_set);
|
||||
}
|
||||
|
||||
void test_difference_with_empty() {
|
||||
ast_manager m;
|
||||
reg_decl_plugins(m);
|
||||
|
||||
finite_set_util fsets(m);
|
||||
finite_set_rewriter rw(m);
|
||||
arith_util arith(m);
|
||||
|
||||
// Create a set and empty set
|
||||
sort_ref int_sort(arith.mk_int(), m);
|
||||
expr_ref zero(arith.mk_int(0), m);
|
||||
expr_ref ten(arith.mk_int(10), m);
|
||||
app_ref s1(fsets.mk_range(zero, ten), m);
|
||||
app_ref empty_set(fsets.mk_empty(s1->get_sort()), m);
|
||||
|
||||
// Test set.difference(s1, empty) -> s1
|
||||
app_ref diff_app1(fsets.mk_difference(s1, empty_set), m);
|
||||
expr_ref result1(m);
|
||||
br_status st1 =
|
||||
rw.mk_app_core(diff_app1->get_decl(), diff_app1->get_num_args(), diff_app1->get_args(), result1);
|
||||
ENSURE(st1 == BR_DONE);
|
||||
ENSURE(result1 == s1);
|
||||
|
||||
// Test set.difference(empty, s1) -> empty
|
||||
app_ref diff_app2(fsets.mk_difference(empty_set, s1), m);
|
||||
expr_ref result2(m);
|
||||
br_status st2 =
|
||||
rw.mk_app_core(diff_app2->get_decl(), diff_app2->get_num_args(), diff_app2->get_args(), result2);
|
||||
ENSURE(st2 == BR_DONE);
|
||||
ENSURE(result2 == empty_set);
|
||||
}
|
||||
|
||||
void test_subset_with_empty() {
|
||||
ast_manager m;
|
||||
reg_decl_plugins(m);
|
||||
|
||||
finite_set_util fsets(m);
|
||||
finite_set_rewriter rw(m);
|
||||
arith_util arith(m);
|
||||
|
||||
// Create a set and empty set
|
||||
sort_ref int_sort(arith.mk_int(), m);
|
||||
expr_ref zero(arith.mk_int(0), m);
|
||||
expr_ref ten(arith.mk_int(10), m);
|
||||
app_ref s1(fsets.mk_range(zero, ten), m);
|
||||
app_ref empty_set(fsets.mk_empty(s1->get_sort()), m);
|
||||
|
||||
// Test set.subset(empty, s1) -> true
|
||||
app_ref subset_app1(fsets.mk_subset(empty_set, s1), m);
|
||||
expr_ref result1(m);
|
||||
br_status st1 =
|
||||
rw.mk_app_core(subset_app1->get_decl(), subset_app1->get_num_args(), subset_app1->get_args(), result1);
|
||||
ENSURE(st1 == BR_DONE);
|
||||
ENSURE(m.is_true(result1));
|
||||
|
||||
// Test set.subset(s1, s1) -> true
|
||||
app_ref subset_app2(fsets.mk_subset(s1, s1), m);
|
||||
expr_ref result2(m);
|
||||
br_status st2 =
|
||||
rw.mk_app_core(subset_app2->get_decl(), subset_app2->get_num_args(), subset_app2->get_args(), result2);
|
||||
ENSURE(st2 == BR_DONE);
|
||||
ENSURE(m.is_true(result2));
|
||||
}
|
||||
|
||||
void test_in_singleton() {
|
||||
ast_manager m;
|
||||
reg_decl_plugins(m);
|
||||
|
||||
finite_set_util fsets(m);
|
||||
finite_set_rewriter rw(m);
|
||||
arith_util arith(m);
|
||||
|
||||
// Create elements and singleton
|
||||
expr_ref five(arith.mk_int(5), m);
|
||||
expr_ref ten(arith.mk_int(10), m);
|
||||
app_ref singleton_five(fsets.mk_singleton(five), m);
|
||||
|
||||
// Test set.in(five, singleton(five)) -> true
|
||||
app_ref in_app1(fsets.mk_in(five, singleton_five), m);
|
||||
expr_ref result1(m);
|
||||
br_status st1 = rw.mk_app_core(in_app1->get_decl(), in_app1->get_num_args(), in_app1->get_args(), result1);
|
||||
ENSURE(st1 == BR_DONE);
|
||||
ENSURE(m.is_true(result1));
|
||||
|
||||
// Test set.in(ten, singleton(five)) -> ten = five
|
||||
app_ref in_app2(fsets.mk_in(ten, singleton_five), m);
|
||||
expr_ref result2(m);
|
||||
br_status st2 = rw.mk_app_core(in_app2->get_decl(), in_app2->get_num_args(), in_app2->get_args(), result2);
|
||||
ENSURE(st2 == BR_REWRITE1);
|
||||
ENSURE(m.is_eq(result2));
|
||||
}
|
||||
|
||||
void test_in_empty() {
|
||||
ast_manager m;
|
||||
reg_decl_plugins(m);
|
||||
|
||||
finite_set_util fsets(m);
|
||||
finite_set_rewriter rw(m);
|
||||
arith_util arith(m);
|
||||
|
||||
// Create element and empty set
|
||||
sort_ref int_sort(arith.mk_int(), m);
|
||||
expr_ref five(arith.mk_int(5), m);
|
||||
parameter param(int_sort.get());
|
||||
sort_ref set_sort(m.mk_sort(fsets.get_family_id(), FINITE_SET_SORT, 1, ¶m), m);
|
||||
app_ref empty_set(fsets.mk_empty(set_sort), m);
|
||||
|
||||
// Test set.in(five, empty) -> false
|
||||
app_ref in_app(fsets.mk_in(five, empty_set), m);
|
||||
expr_ref result(m);
|
||||
br_status st = rw.mk_app_core(in_app->get_decl(), in_app->get_num_args(), in_app->get_args(), result);
|
||||
ENSURE(st == BR_DONE);
|
||||
ENSURE(m.is_false(result));
|
||||
}
|
||||
};
|
||||
|
||||
void tst_finite_set_rewriter() {
|
||||
finite_set_rewriter_test test;
|
||||
test.test_union_idempotent();
|
||||
test.test_intersect_idempotent();
|
||||
test.test_difference_same();
|
||||
test.test_subset_rewrite();
|
||||
test.test_mk_app_core();
|
||||
test.test_union_with_empty();
|
||||
test.test_intersect_with_empty();
|
||||
test.test_difference_with_empty();
|
||||
test.test_subset_with_empty();
|
||||
test.test_in_singleton();
|
||||
test.test_in_empty();
|
||||
}
|
||||
|
|
@ -285,4 +285,6 @@ int main(int argc, char ** argv) {
|
|||
TST(scoped_vector);
|
||||
TST(sls_seq_plugin);
|
||||
TST(ho_matcher);
|
||||
TST(finite_set);
|
||||
TST(finite_set_rewriter);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue