3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-04-09 22:15:32 +00:00

Implement multivariate polynomial factorization via Hensel lifting

Replace the stub factor_n_sqf_pp (TODO: invoke Dejan's procedure) with a
working implementation using bivariate Hensel lifting:

- Evaluate away extra variables to reduce to bivariate
- Factor the univariate specialization
- Lift univariate factors to bivariate via linear Hensel lifting in Zp[x]
- Verify lifted factors multiply to original over Z[x,y]
- For >2 variables, check bivariate factors divide the original polynomial

Tests: (x0+x1)(x0+2x1)(x0+3x1) now correctly factors into 3 linear factors.
All 89 unit tests pass in both release and debug builds.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Lev Nachmanson 2026-03-21 12:27:02 -10:00 committed by Lev Nachmanson
parent a00ac9be84
commit 3e5e9026d8
3 changed files with 437 additions and 22 deletions

View file

@ -337,15 +337,7 @@ void test_factorization_large_multivariate_missing_factors() {
factors fs(m);
factor(p, fs);
VERIFY(fs.distinct_factors() == 2); // indeed there are 3 factors, that is demonstrated by the loop
for (unsigned i = 0; i < fs.distinct_factors(); ++i) {
polynomial_ref f(m);
f = fs[i];
if (degree(f, x1)<= 1) continue;
factors fs0(m);
factor(f, fs0);
VERIFY(fs0.distinct_factors() >= 2);
}
VERIFY(fs.distinct_factors() >= 3);
polynomial_ref reconstructed(m);
fs.multiply(reconstructed);
@ -370,17 +362,8 @@ void test_factorization_multivariate_missing_factors() {
factors fs(m);
factor(p, fs);
// Multivariate factorization stops after returning the whole polynomial.
VERIFY(fs.distinct_factors() == 1);
VERIFY(m.degree(fs[0], 0) == 3);
factors fs_refined(m);
polynomial_ref residual = fs[0];
factor(residual, fs_refined);
// A second attempt still fails to expose the linear factors.
VERIFY(fs_refined.distinct_factors() == 1); // actually we need 3 factors
VERIFY(m.degree(fs_refined[0], 0) == 3); // actually we need degree 1
// Multivariate factorization should find 3 linear factors
VERIFY(fs.distinct_factors() == 3);
polynomial_ref reconstructed(m);
fs.multiply(reconstructed);