mirror of
https://github.com/Z3Prover/z3
synced 2026-06-19 23:26:30 +00:00
fix edge case in algebraic number comparison (#9498)
So far, `algebraic_numbers compare_core ` handles an edge case incorrectly: - If the two compared numbers (`a`, `b`) are different, - the intervals still overlap after refinements, and - both a and b are a root of the second polynomial (`cell_b->m_p`), e.g. they are the first and second root then the method would return `sign_zero` (i.e. "equal"). This behavior can be replicated with the provided test case (before the fix). This requires `algebraic.factor=false`, though i first encountered it during solver runs on QF_NRA instances with the default `algebraic.factor=true`, which apparently means that the polynomials for anums are still not always factored. The fix is to compare the interval bounds of b to a and vice versa. Then the Sturm-Tarski check is only run if `a` and `b` both lie in the intersection of the intervals, because only then is it guaranteed to be correct.
This commit is contained in:
parent
316d249b3f
commit
f124cacf1e
2 changed files with 57 additions and 0 deletions
|
|
@ -2028,6 +2028,20 @@ namespace algebraic_numbers {
|
|||
}
|
||||
IF_VERBOSE(9, verbose_stream() << "sturm 1\n");
|
||||
|
||||
|
||||
// Check whether a can be separated from b's interval and vice versa
|
||||
// this recognizes the case where the intervals overlap,
|
||||
// but the anums do not lie in the intersection of the intervals.
|
||||
mpq l_a, u_a, l_b, u_b;
|
||||
to_mpq(qm(), la, l_a);
|
||||
to_mpq(qm(), ua, u_a);
|
||||
to_mpq(qm(), lb, l_b);
|
||||
to_mpq(qm(), ub, u_b);
|
||||
if (compare(cell_a, l_b) == sign_neg) return sign_neg;
|
||||
if (compare(cell_a, u_b) == sign_pos) return sign_pos;
|
||||
if (compare(cell_b, l_a) == sign_neg) return sign_pos;
|
||||
if (compare(cell_b, u_a) == sign_pos) return sign_neg;
|
||||
|
||||
//
|
||||
// EXPENSIVE CASE
|
||||
// Let seq be the Sturm-Tarski sequence for
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue