Documentation

HexBerlekampZassenhaus.BhksCandidates

theorem Hex.BHKS.abs_cldCoeffs_le_bhksCoeffBound (f g : ZPoly) (p a j : Nat) (y : Int) (hp : 2 p) (hbound : y.natAbs bhksCoeffBound f j) (hsep_a : 2 * bhksCoeffBound f j < p ^ a) (hcongr : y % ↑(p ^ a) = DensePoly.coeff (cldQuotientMod f g p a) j % ↑(p ^ a)) :
((cldCoeffs f p a g).getD j 0).natAbs bhksCoeffBound f j

BHKS Lemma 5.1 column bound for the executable cldCoeffs.

If there exists an exact integer y (morally [x^j] (f * g'.derivative / g') for a true integer factor g' of f that Hensel-lifts to g) congruent to (cldQuotientMod f g p a).coeff j modulo p^a and satisfying |y| ≤ bhksCoeffBound f j, then under the Hensel precision hypothesis 2 * bhksCoeffBound f j < p^a and p ≥ 2, the executable cldCoeffs entry at index j is bounded by bhksCoeffBound f j.

The executable cut must be re-centered at the ambient modulus for this column bound to hold. Hex.psiCut performs that recentering; the bound is then a direct consequence of abs_psiCut_le_of_natAbs_le plus precisionForCoeffBound_spec for the lower cut threshold.

Lift the projected integer rows of L into a rational row-basis matrix sized n × r, with n := L.projectedRows.size and r := L.factorCount. The matrix is the input to BHKS Lemma 3.3 RREF-based equivalence-class identification.

Equations
Instances For
    def Hex.bhksColumnSignature (echelonRows : Array (Array Rat)) (j : Nat) :

    The entries in column j of a row-reduced projected matrix.

    Equations
    Instances For

      Add a column index to the class with the same signature, or start a new class.

      Equations
      Instances For
        def Hex.bhksClassIndicator (r : Nat) (members : List Nat) :

        The zero-one indicator vector of a class of column indices.

        Equations
        Instances For

          BHKS equivalence-class indicator vectors over the projected lattice rows of L.

          Lifts the projected integer rows into a rational row-basis matrix, runs Matrix.rowReduce over Q, and groups column indices 0, …, r - 1 by their echelon-column signature: indices i and j are equivalent iff every echelon row agrees at positions i and j (BHKS Lemma 3.3 / FLINT Algorithm 8). Each equivalence class produces one compact 0/1 indicator of length r. Classes are emitted in the order they are first observed by ascending column index.

          Equations
          • One or more equations did not get rendered due to their size.
          Instances For

            The prime-power modulus of a Hensel lift.

            Equations
            Instances For

              Replace every coefficient by its centred representative modulo m.

              Equations
              Instances For

                Coefficientwise description of centeredLiftPoly.

                theorem Hex.centeredLiftPoly_reduceModPow_eq_of_coeff_natAbs_le (g : ZPoly) (p k B : Nat) (hbound : ∀ (i : Nat), (DensePoly.coeff g i).natAbs B) (hsep : 2 * B < p ^ k) :

                A sufficiently large modulus makes centred coefficient recovery exact.

                theorem Hex.centeredLiftPoly_eq_of_reduceModPow_eq (g h : ZPoly) (p k B : Nat) (hbound : ∀ (i : Nat), (DensePoly.coeff g i).natAbs B) (hsep : 2 * B < p ^ k) (hreduce : h.reduceModPow p k = g.reduceModPow p k) :

                Equal sufficiently precise residues recover the same coefficient-bounded polynomial.

                Normalize a candidate integer factor by extracting its primitive part and flipping sign so the leading coefficient is non-negative. Used by bhksIndicatorCandidate? to produce a canonical witness from the centred lift of a scaled lifted-factor product.

                Equations
                Instances For

                  normalizeCandidateFactor g = g when g is already primitive (content 1) and has non-negative leading coefficient. This is the A2 reconstruction step that asserts the canonical witness produced by bhksIndicatorCandidate? agrees with the expected true factor under those normalization assumptions.

                  def Hex.bhksIndicatorSelectedFactors (liftedFactors : Array ZPoly) (indicator : Array Int) :

                  Select the lifted factors marked by a nonempty zero-one indicator.

                  Equations
                  • One or more equations did not get rendered due to their size.
                  Instances For

                    The array selected by a 0/1 BHKS indicator row.

                    Equations
                    • One or more equations did not get rendered due to their size.
                    Instances For
                      theorem Hex.bhksIndicatorSelectedFactors_eq_some_selectedArray_of_getD (liftedFactors : Array ZPoly) (indicator : Array Int) (hsize : indicator.size = liftedFactors.size) (hbits : ∀ (i : Nat), i < indicator.sizeindicator.getD i 0 = 0 indicator.getD i 0 = 1) (hnonempty : (i : Nat), i < indicator.size indicator.getD i 0 = 1) :
                      bhksIndicatorSelectedFactors liftedFactors indicator = some (bhksIndicatorSelectedFactorsArray liftedFactors indicator)

                      Successful branch of bhksIndicatorSelectedFactors for well-formed 0/1 indicator rows, returning the canonical selected-factor array.

                      theorem Hex.bhksIndicatorSelectedFactors_eq_some_of_getD (liftedFactors : Array ZPoly) (indicator : Array Int) (selected : Array ZPoly) (hsize : indicator.size = liftedFactors.size) (hbits : ∀ (i : Nat), i < indicator.sizeindicator.getD i 0 = 0 indicator.getD i 0 = 1) (hnonempty : (i : Nat), i < indicator.size indicator.getD i 0 = 1) (hselected : selected = bhksIndicatorSelectedFactorsArray liftedFactors indicator) :
                      bhksIndicatorSelectedFactors liftedFactors indicator = some selected

                      Successful branch of bhksIndicatorSelectedFactors, stated with an explicit name for the selected-factor array chosen by the caller.

                      Reconstruct and verify one BHKS equivalence-class indicator.

                      The indicator row is supplied by the later RREF recovery stage. This helper only checks that the row is a nonempty 0/1 vector over the lifted factors, forms the selected lifted-factor product, scales it by f's leading coefficient in the same coordinate, applies the centred integer lift, normalizes content and sign, and accepts the candidate only when exact division of f succeeds.

                      Equations
                      • One or more equations did not get rendered due to their size.
                      Instances For
                        theorem Hex.bhksIndicatorCandidate?_dvd {f : ZPoly} {d : LiftData} {indicator : Array Int} {candidate quotient : ZPoly} (h : bhksIndicatorCandidate? f d indicator = some (candidate, quotient)) :
                        candidate f

                        A successful BHKS indicator candidate divides f. The executable bhksIndicatorCandidate? only returns some (candidate, _) after exactQuotient? f candidate succeeds, so the candidate is a verified integer divisor of f.

                        theorem Hex.bhksIndicatorCandidate?_primitive {f : ZPoly} {d : LiftData} {indicator : Array Int} {candidate quotient : ZPoly} (h : bhksIndicatorCandidate? f d indicator = some (candidate, quotient)) :
                        candidate.Primitive

                        A successful BHKS indicator candidate is primitive: the candidate equals normalizeFactorSign (normalizeCandidateFactor _), and shouldRecord = true forces the inner factor to be nonzero, hence primitive.

                        theorem Hex.bhksIndicatorCandidate?_eq_normalized_directLift {f : ZPoly} {d : LiftData} {indicator : Array Int} {candidate quotient : ZPoly} {selected : Array ZPoly} (h : bhksIndicatorCandidate? f d indicator = some (candidate, quotient)) (hselected : bhksIndicatorSelectedFactors d.liftedFactors indicator = some selected) :

                        The candidate returned by a successful bhksIndicatorCandidate? call is exactly the canonical normalization of the direct-coordinate scaled centred lift. This is a Mathlib-free surface lemma that avoids exposing the private liftModulus definition.

                        theorem Hex.bhksIndicatorCandidate?_eq_some_of_directLift (f : ZPoly) (d : LiftData) (indicator : Array Int) (selected : Array ZPoly) (expectedFactor : ZPoly) (hselected : bhksIndicatorSelectedFactors d.liftedFactors indicator = some selected) (hdvd : expectedFactor f) (hexpected_prim : expectedFactor.Primitive) (hexpected_sign : 0 DensePoly.leadingCoeff expectedFactor) (hexpected_pos_lc : 0 < DensePoly.leadingCoeff expectedFactor) (hexpected_degree : 0 < DensePoly.natDegree expectedFactor) (hrecovered : centeredLiftPoly (DensePoly.scale (DensePoly.leadingCoeff f) selected.polyProduct) (d.p ^ d.k) = expectedFactor) :
                        (quotient : ZPoly), bhksIndicatorCandidate? f d indicator = some (expectedFactor, quotient)

                        A2 reconstruction surface for a single direct-coordinate BHKS indicator.

                        theorem Hex.bhksIndicatorCandidate?_eq_some_of_scaledCandidate (f : ZPoly) (d : LiftData) (indicator : Array Int) (selected : Array ZPoly) (expectedFactor selectedProduct : ZPoly) (hselected : bhksIndicatorSelectedFactors d.liftedFactors indicator = some selected) (hproduct : selected.polyProduct = selectedProduct) (hdvd : expectedFactor f) (hexpected_pos_lc : 0 < DensePoly.leadingCoeff expectedFactor) (hexpected_degree : 0 < DensePoly.natDegree expectedFactor) (hrecovered : normalizeFactorSign (centeredLiftPoly (DensePoly.scale (DensePoly.leadingCoeff f) selectedProduct) (d.p ^ d.k)).primitivePart = expectedFactor) :
                        (quotient : ZPoly), bhksIndicatorCandidate? f d indicator = some (expectedFactor, quotient)

                        Reconstruct one direct-coordinate BHKS indicator when the canonical scaled recombination candidate is already known exactly.

                        theorem Hex.bhksIndicatorCandidate?_eq_some_of_directRecovery (f : ZPoly) (d : LiftData) (indicator : Array Int) (selected : Array ZPoly) (expectedFactor : ZPoly) (hselected : bhksIndicatorSelectedFactors d.liftedFactors indicator = some selected) (hdvd : expectedFactor f) (hexpected_sign : 0 DensePoly.leadingCoeff expectedFactor) (hexpected_pos_lc : 0 < DensePoly.leadingCoeff expectedFactor) (hexpected_degree : 0 < DensePoly.natDegree expectedFactor) (hrecovered : (centeredLiftPoly (DensePoly.scale (DensePoly.leadingCoeff f) selected.polyProduct) (d.p ^ d.k)).primitivePart = expectedFactor) :
                        (quotient : ZPoly), bhksIndicatorCandidate? f d indicator = some (expectedFactor, quotient)

                        Reconstruct one direct-coordinate BHKS indicator from its primitive-part recovery identity.

                        def Hex.bhksIndicatorOneCount (r : Nat) (indicator : Array Int) :

                        Count the entries equal to one among the first r indicator entries.

                        Equations
                        Instances For
                          def Hex.bhksIndicatorAllOnes (r : Nat) (indicator : Array Int) :

                          Test whether an indicator has width r and consists entirely of ones.

                          Equations
                          Instances For
                            theorem Hex.bhksIndicatorAllOnes_eq_true_of_getD (r : Nat) (indicator : Array Int) (hsize : indicator.size = r) (hones : ∀ (i : Nat), i < rindicator.getD i 0 = 1) :

                            An indicator of the expected width whose every coordinate is one passes the executable all-ones check.

                            The recovery early-bailout predicate: the projected lattice is empty, the indicator partition is empty, or the indicator partition is the trivial all-ones single class.

                            Equations
                            Instances For
                              theorem Hex.bhksDegenerateIndicatorPartition_eq_false (L : BhksProjectedRows) (indicators : Array (Array Int)) (hindicators : indicators.isEmpty = false) (hrows : L.projectedRows.isEmpty = false) (hsize : (indicators.size == 1) = false) :

                              The proof-facing successful branch of the BHKS degeneracy guard.

                              Reconstruct and verify every BHKS equivalence-class indicator candidate.

                              Folds bhksIndicatorCandidate? over the list of indicator vectors, pushing the verified candidate factor onto the accumulator on success and short-circuiting to none on the first reconstruction failure.

                              Equations
                              Instances For
                                theorem Hex.bhksIndicatorCandidates?_dvd {f : ZPoly} {d : LiftData} {indicators : Array (Array Int)} {candidates : Array ZPoly} (h : bhksIndicatorCandidates? f d indicators = some candidates) (factor : ZPoly) :
                                factor candidates.toListfactor f

                                Every candidate emitted by bhksIndicatorCandidates? divides the input polynomial; this is the per-candidate version of the verified exact-division check performed inside bhksIndicatorCandidate?.

                                theorem Hex.bhksIndicatorCandidates?_primitive {f : ZPoly} {d : LiftData} {indicators : Array (Array Int)} {candidates : Array ZPoly} (h : bhksIndicatorCandidates? f d indicators = some candidates) (factor : ZPoly) :
                                factor candidates.toListfactor.Primitive

                                Every candidate emitted by bhksIndicatorCandidates? is primitive. This is the array-level form of the per-candidate primitivity guarantee from normalizeCandidateFactor plus sign normalisation.

                                theorem Hex.bhksIndicatorCandidates?_leadingCoeff_nonneg {f : ZPoly} {d : LiftData} {indicators : Array (Array Int)} {candidates : Array ZPoly} (h : bhksIndicatorCandidates? f d indicators = some candidates) (factor : ZPoly) :
                                factor candidates.toList0 DensePoly.leadingCoeff factor

                                Every candidate emitted by bhksIndicatorCandidates? has nonnegative leading coefficient; this is the array-level form of the per-candidate sign normalisation guarantee.

                                theorem Hex.bhksIndicatorCandidates?_positive_degree {f : ZPoly} {d : LiftData} {indicators : Array (Array Int)} {candidates : Array ZPoly} (h : bhksIndicatorCandidates? f d indicators = some candidates) (factor : ZPoly) :
                                factor candidates.toList0 < DensePoly.natDegree factor

                                Every candidate emitted by bhksIndicatorCandidates? has positive degree; this is the array-level form of the per-candidate nonconstant guarantee.

                                theorem Hex.bhksIndicatorCandidates?_eq_some_of_forall_candidate (f : ZPoly) (d : LiftData) (indicators : Array (Array Int)) (candidates quotients : Array ZPoly) (hsize : candidates.size = indicators.size) (hcandidate : ∀ (i : Nat), i < indicators.sizebhksIndicatorCandidate? f d (indicators.getD i #[]) = some (candidates.getD i 0, quotients.getD i 0)) :
                                bhksIndicatorCandidates? f d indicators = some candidates

                                If each BHKS equivalence-class indicator reconstructs and verifies to the corresponding candidate factor, the executable candidate fold returns the whole candidate array.

                                The quotients array records the exact-division witnesses returned by bhksIndicatorCandidate?; only the first component is accumulated by bhksIndicatorCandidates?.

                                theorem Hex.bhksIndicatorCandidates?_eq_some_of_getD (f : ZPoly) (d : LiftData) (indicators : Array (Array Int)) (candidates : Array ZPoly) (hsize : candidates.size = indicators.size) (hcandidate : ∀ (i : Nat), i < indicators.size (quotient : ZPoly), bhksIndicatorCandidate? f d (indicators.getD i #[]) = some (candidates.getD i 0, quotient)) :
                                bhksIndicatorCandidates? f d indicators = some candidates

                                Assemble the BHKS candidate fold from per-indicator reconstruction facts.

                                This is the proof-facing surface for callers that know every indicator row reconstructs and exactly divides f: with a size agreement and one quotient witness for each row, the executable fold returns the requested candidate array.

                                theorem Hex.bhksIndicatorCandidates?_size_eq {f : ZPoly} {d : LiftData} {indicators : Array (Array Int)} {candidates : Array ZPoly} (h : bhksIndicatorCandidates? f d indicators = some candidates) :
                                candidates.size = indicators.size

                                A successful BHKS indicator-candidate fold produces a candidate array of the same size as the input indicator array. This is the size identity used by ExpectedTrueFactors-shaped consumers that need to align the per-index indicator and factor views.

                                theorem Hex.ZPoly.ToMonicData.transformedCore_coeff (core : ZPoly) (degree n : Nat) :
                                DensePoly.coeff (transformedCore core degree) n = if n < degree then DensePoly.coeff core n * DensePoly.leadingCoeff core ^ (degree - 1 - n) else if n = degree then 1 else 0

                                General coefficient law for the monic transform transformedCore. Below the top degree the coefficient is core.coeff n scaled by a power of the leading coefficient; the top coefficient is 1; higher coefficients vanish.

                                theorem Hex.ZPoly.ToMonicData.dilate_transformedCore (core : ZPoly) (degree : Nat) (hdeg : 1 degree) (hcore : DensePoly.natDegree core = degree) :

                                Keystone for toMonic inverse recovery. Dilating the monic transform transformedCore core degree by the leading coefficient recovers core scaled by leadingCoeff core ^ (degree - 1). The 1 ≤ degree hypothesis is essential: for a constant core the identity fails unless the leading coefficient is 1. Composed with dilate_mul, this is the inverse-factor correspondence the recombination recovery proof rests on.

                                Public face of the inverse-recovery keystone, stated on the toMonic monic field rather than the private transformedCore. For a square-free part of degree ≥ 1, dilating (toMonic core).monic by the leading coefficient recovers core scaled by leadingCoeff core ^ (degree - 1). Holds in both the already-monic and the genuine transform branch.

                                Coefficient law for the monic transform (toMonic core).monic in the genuine-transform branch (leading coefficient ≠ 1). Public face of the private ToMonicData.transformedCore_coeff: below the top degree the coefficient is core.coeff i scaled by a power of the leading coefficient, the top coefficient is 1, and higher coefficients vanish.

                                The monic transform preserves the recorded degree in all cases (sign-free, unconditional companion to toMonic_monic_degree_eq_of_pos_degree).

                                Stored size of the monic transform of a positive-degree square-free part: one more than the square-free part degree, in both the already-monic and genuine-transform branches.