3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-03-07 22:04:53 +00:00

Integrate rw_table into th_rewriter_cfg and expand populate_rules()

Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot] 2026-02-27 04:36:28 +00:00
parent 57c9987d25
commit a4ccb6390d
3 changed files with 239 additions and 0 deletions

View file

@ -352,6 +352,186 @@ static void test_compound() {
check(m, "(0+x)+(1*x)", result, expected);
}
// ---------------------------------------------------------------------------
// New rules: Bool idempotency, complementation, eq simplification, ITE Bool
// ---------------------------------------------------------------------------
static void test_bool_idempotency() {
ast_manager m;
reg_decl_plugins(m);
rw_evaluator ev(m);
expr_ref result(m);
sort * bool_sort = m.mk_bool_sort();
expr_ref bx(m.mk_const(symbol("bx"), bool_sort), m);
// x /\ x -> x
ev(m.mk_and(bx, bx), result);
check(m, "x /\\ x", result, bx);
// x \/ x -> x
ev(m.mk_or(bx, bx), result);
check(m, "x \\/ x", result, bx);
}
static void test_bool_complementation() {
ast_manager m;
reg_decl_plugins(m);
rw_evaluator ev(m);
expr_ref result(m);
sort * bool_sort = m.mk_bool_sort();
expr_ref bx(m.mk_const(symbol("bx"), bool_sort), m);
// x /\ not(x) -> false
ev(m.mk_and(bx, m.mk_not(bx)), result);
check_false(m, "x /\\ not(x)", result);
// not(x) /\ x -> false
ev(m.mk_and(m.mk_not(bx), bx), result);
check_false(m, "not(x) /\\ x", result);
// x \/ not(x) -> true
ev(m.mk_or(bx, m.mk_not(bx)), result);
check_true(m, "x \\/ not(x)", result);
// not(x) \/ x -> true
ev(m.mk_or(m.mk_not(bx), bx), result);
check_true(m, "not(x) \\/ x", result);
}
static void test_bool_eq_simplification() {
ast_manager m;
reg_decl_plugins(m);
rw_evaluator ev(m);
expr_ref result(m);
sort * bool_sort = m.mk_bool_sort();
expr_ref bx(m.mk_const(symbol("bx"), bool_sort), m);
// (= true x) -> x
ev(m.mk_eq(m.mk_true(), bx), result);
check(m, "(= true bx)", result, bx);
// (= x true) -> x
ev(m.mk_eq(bx, m.mk_true()), result);
check(m, "(= bx true)", result, bx);
// (= false x) -> not(x)
ev(m.mk_eq(m.mk_false(), bx), result);
{
expr_ref not_bx(m.mk_not(bx), m);
check(m, "(= false bx)", result, not_bx);
}
// (= x false) -> not(x)
ev(m.mk_eq(bx, m.mk_false()), result);
{
expr_ref not_bx(m.mk_not(bx), m);
check(m, "(= bx false)", result, not_bx);
}
}
static void test_ite_bool_special() {
ast_manager m;
reg_decl_plugins(m);
rw_evaluator ev(m);
expr_ref result(m);
sort * bool_sort = m.mk_bool_sort();
expr_ref c(m.mk_const(symbol("c"), bool_sort), m);
// ite(c, true, false) -> c
ev(m.mk_ite(c, m.mk_true(), m.mk_false()), result);
check(m, "ite(c,true,false)", result, c);
// ite(c, false, true) -> not(c)
ev(m.mk_ite(c, m.mk_false(), m.mk_true()), result);
{
expr_ref not_c(m.mk_not(c), m);
check(m, "ite(c,false,true)", result, not_c);
}
}
static void test_arith_div_mod() {
ast_manager m;
reg_decl_plugins(m);
arith_util arith(m);
rw_evaluator ev(m);
expr_ref result(m);
sort * int_sort = arith.mk_int();
expr_ref x(m.mk_const(symbol("x"), int_sort), m);
// idiv(x, 1) -> x
ev(arith.mk_idiv(x, arith.mk_int(1)), result);
check(m, "x div 1", result, x);
// mod(x, 1) -> 0
ev(arith.mk_mod(x, arith.mk_int(1)), result);
ENSURE(arith.is_zero(result));
std::cout << "x mod 1: " << mk_pp(result, m) << " [OK]\n";
// rem(x, 1) -> 0
ev(arith.mk_rem(x, arith.mk_int(1)), result);
ENSURE(arith.is_zero(result));
std::cout << "x rem 1: " << mk_pp(result, m) << " [OK]\n";
}
static void test_arith_uminus_zero() {
ast_manager m;
reg_decl_plugins(m);
arith_util arith(m);
rw_evaluator ev(m);
expr_ref result(m);
// -(0_i) -> 0_i
ev(arith.mk_uminus(arith.mk_int(0)), result);
ENSURE(arith.is_zero(result) && arith.is_int(result));
std::cout << "-(0_i): " << mk_pp(result, m) << " [OK]\n";
// -(0_r) -> 0_r
ev(arith.mk_uminus(arith.mk_real(0)), result);
ENSURE(arith.is_zero(result) && !arith.is_int(result));
std::cout << "-(0_r): " << mk_pp(result, m) << " [OK]\n";
}
static void test_arith_le_ge_reflexivity() {
ast_manager m;
reg_decl_plugins(m);
arith_util arith(m);
rw_evaluator ev(m);
expr_ref result(m);
sort * int_sort = arith.mk_int();
sort * real_sort = arith.mk_real();
expr_ref xi(m.mk_const(symbol("xi"), int_sort), m);
expr_ref xr(m.mk_const(symbol("xr"), real_sort), m);
// xi <= xi -> true
ev(arith.mk_le(xi, xi), result);
check_true(m, "xi <= xi", result);
// xi >= xi -> true
ev(arith.mk_ge(xi, xi), result);
check_true(m, "xi >= xi", result);
// xr <= xr -> true
ev(arith.mk_le(xr, xr), result);
check_true(m, "xr <= xr", result);
// xr >= xr -> true
ev(arith.mk_ge(xr, xr), result);
check_true(m, "xr >= xr", result);
}
// ---------------------------------------------------------------------------
// Direct rw_table API test (no evaluator)
// ---------------------------------------------------------------------------
@ -399,5 +579,13 @@ void tst_rw_rule() {
test_eq_reflexivity();
test_compound();
test_table_direct();
// new-rule tests
test_bool_idempotency();
test_bool_complementation();
test_bool_eq_simplification();
test_ite_bool_special();
test_arith_div_mod();
test_arith_uminus_zero();
test_arith_le_ge_reflexivity();
std::cout << "=== rw_rule: all tests passed ===\n";
}