mirror of
https://github.com/Z3Prover/z3
synced 2026-03-17 02:30:01 +00:00
Fix #7507: simplify (>= product_of_consecutive_ints 0) to true
The arith rewriter now recognizes that x * (x + 1) >= 0 for all integers, since no integer lies strictly between -1 and 0. Two changes: 1. is_non_negative: detect products where unpaired factors are consecutive integer expressions (differ by exactly 1), handling both +1 and -1 offsets and n-ary additions 2. is_separated: return true for (>= non_negative_mul 0), restricted to multiplication expressions to avoid disrupting other theories Also adds regression tests for the new simplification. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
parent
070f760501
commit
21c23e78db
2 changed files with 66 additions and 0 deletions
|
|
@ -33,6 +33,21 @@ static expr_ref parse_fml(ast_manager& m, char const* str) {
|
|||
static char const* example1 = "(<= (+ (* 1.3 x y) (* 2.3 y y) (* (- 1.1 x x))) 2.2)";
|
||||
static char const* example2 = "(= (+ 4 3 (- (* 3 x x) (* 5 y)) y) 0)";
|
||||
|
||||
static expr_ref parse_int_fml(ast_manager& m, char const* str) {
|
||||
expr_ref result(m);
|
||||
cmd_context ctx(false, &m);
|
||||
ctx.set_ignore_check(true);
|
||||
std::ostringstream buffer;
|
||||
buffer << "(declare-const I Int)\n"
|
||||
<< "(declare-const S Int)\n"
|
||||
<< "(assert " << str << ")\n";
|
||||
std::istringstream is(buffer.str());
|
||||
VERIFY(parse_smt2_commands(ctx, is));
|
||||
ENSURE(!ctx.assertions().empty());
|
||||
result = ctx.assertions().get(0);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void tst_arith_rewriter() {
|
||||
ast_manager m;
|
||||
|
|
@ -56,4 +71,16 @@ void tst_arith_rewriter() {
|
|||
fml = parse_fml(m, example2);
|
||||
rw(fml);
|
||||
std::cout << mk_pp(fml, m) << "\n";
|
||||
|
||||
// Issue #7507: (>= (* I (+ I 1)) 0) should simplify to true
|
||||
fml = parse_int_fml(m, "(>= (* I (+ I 1)) 0)");
|
||||
rw(fml);
|
||||
std::cout << "consecutive product >= 0: " << mk_pp(fml, m) << "\n";
|
||||
ENSURE(m.is_true(fml));
|
||||
|
||||
// (>= (* I (+ I (- 1))) 0) should also simplify to true (x*(x-1))
|
||||
fml = parse_int_fml(m, "(>= (* I (+ I (- 1))) 0)");
|
||||
rw(fml);
|
||||
std::cout << "consecutive product (minus) >= 0: " << mk_pp(fml, m) << "\n";
|
||||
ENSURE(m.is_true(fml));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue