Polynomials over F_2, packed into 64-bit words. Bit j of words[i]
stores the coefficient of x^(64 * i + j).
The packed coefficient words: bit
jofwords[i]is the coefficient ofx^(64 * i + j).- normalized : GF2PolyNormalized self.words
Instances For
Remove trailing zero words without disturbing the lower-degree prefix.
Equations
Instances For
Normalize a word array by discarding trailing zero words.
Equations
Instances For
Trailing-zero normalization preserves packed coefficients.
Equations
- Hex.GF2Poly.highestSetBitBelow? 0 w = none
- Hex.GF2Poly.highestSetBitBelow? fuel'.succ w = if Hex.GF2Poly.wordBitIsSet w fuel' = true then some fuel' else Hex.GF2Poly.highestSetBitBelow? fuel' w
Instances For
The index of the highest set bit in a machine word, if any.
Equations
Instances For
A returned highest-bit index is one of the 64 word-bit positions.
The one-hot word used by monomial has its highest set bit at the
requested in-word position.
Build a normalized packed polynomial from a raw word array.
Equations
- Hex.GF2Poly.ofWords words = { words := Hex.GF2Poly.normalizeWords words, normalized := ⋯ }
Instances For
The zero polynomial.
Equations
Instances For
Equations
- Hex.GF2Poly.instZero = { zero := Hex.GF2Poly.zero }
The constant polynomial 1.
Equations
Instances For
Equations
- Hex.GF2Poly.instOne = { one := Hex.GF2Poly.one }
Build a packed polynomial from a single machine word.
Equations
Instances For
The monomial x^n.
Equations
- Hex.GF2Poly.monomial n = Hex.GF2Poly.ofWords ((Array.replicate (n / 64) 0).push (1 <<< (n % 64).toUInt64))
Instances For
Coefficients of a raw word array are unchanged by ofWords normalization.
Input 0 to ofUInt64 is the zero polynomial.
Input 1 to ofUInt64 is the unit polynomial.
The packed single-word constructor preserves the underlying machine word.
The degree of a nonzero polynomial, if any.
Equations
- One or more equations did not get rendered due to their size.
Instances For
A normalized packed polynomial is isZero iff its stored word array is empty.
This is the representation-level characterisation. It is kept out of the simp
set, where it would compete with the propositional form below for the same
left-hand side, but it keeps its grind trigger: grind = registers an
E-matching theorem rather than an oriented rewrite, so two triggers on one term
let congruence closure learn both consequences instead of racing.
A normalized packed polynomial is non-isZero iff its stored word array is
nonempty. The representation-level counterpart of the propositional form below:
out of simp for the same reason, and a grind trigger for the same reason.
isZero agrees with propositional equality to the zero polynomial.
This is the simp normal form for a successful isZero check; the
representation-level Hex.GF2Poly.isZero_eq_true_iff_words_eq_empty
shares its left-hand side and is deliberately not a simp lemma.
A failing isZero check agrees with propositional inequality to the zero
polynomial. The simp normal form for a failing check, matching
Hex.GF2Poly.isZero_iff_eq_zero on the successful one.
The default-0 degree extracts the witness of a successful degree search.
Not a simp lemma: its left-hand side p.natDegree does not determine d, so
simp would have to guess the witness before it could discharge the
hypothesis. Apply it to an explicit degree? equation instead.
If a coefficient is set and every higher coefficient is clear, the packed degree search returns exactly that coefficient index.
The zero polynomial stores no machine words.
The zero polynomial has no degree witness.
The default-0 degree of the zero polynomial is 0.
The in-place worker: fold over the shorter array's indices, XOR-ing each of
its words into the accumulator (the longer array). Index i is read (a[i]!)
before being written, and each index is written exactly once, so position i
ends up as the original acc[i] XOR short[i].
Equations
- Hex.GF2Poly.xorWordsAux short acc = List.foldl (fun (a : Array UInt64) (i : Nat) => a.setIfInBounds i (a[i]! ^^^ short[i]!)) acc (List.range short.size)
Instances For
Word-wise XOR of packed coefficient arrays: copy the longer array and XOR
the shorter array's words into its matching prefix in place. This does strictly
less work than rebuilding max entries (only the min-prefix is touched, in
place; the longer tail is left as-is) and, unlike Array.ofFn, reduces under
decide.
Equations
- Hex.GF2Poly.xorWords xs ys = if xs.size ≤ ys.size then Hex.GF2Poly.xorWordsAux xs ys else Hex.GF2Poly.xorWordsAux ys xs
Instances For
Elementwise characterization of the XOR fold over List.range m: in-range
positions are XOR-updated against the original accumulator; the rest unchanged.
Addition in F_2[x] is coefficientwise XOR.
Equations
- p.add q = Hex.GF2Poly.ofWords (Hex.GF2Poly.xorWords p.words q.words)
Instances For
Equations
- Hex.GF2Poly.instAdd = { add := Hex.GF2Poly.add }
Coefficient lookup sees the raw packed sum of an array with itself as zero.
Normalization wipes an all-zero packed word array down to the canonical empty array.
Raw packed XOR of a word array with itself produces the all-zero array of the same size.
Every element of F_2[x] is its own additive inverse: p + p = 0.
Equations
- Hex.GF2Poly.instNeg = { neg := Hex.GF2Poly.neg }
Equations
- Hex.GF2Poly.instSub = { sub := Hex.GF2Poly.sub }
Zero is the left identity for F_2[x] addition.
Zero is the right identity for F_2[x] addition.
Shift a normalized word list left by bitShift ∈ [1, 63].
Equations
Instances For
Sub-word shiftLeftBitsList preserves the source coefficient when the
shifted bit stays inside the same machine word.
Sub-word shiftLeftBitsList preserves the source coefficient when the
shifted bit crosses into the next machine word.
Sub-word shiftLeftBitsList preserves every source coefficient stored in
the input words.
The full shift-left assembly preserves the source coefficient at every in-bounds index when the bit-shift component is nonzero.
The full shift-left assembly returns a clear coefficient at any index whose source word lies above the stored input.
The full shift-left assembly returns a clear coefficient strictly below the
shift amount: indices below k are zero-padded.
Shift packed words right by bitShift ∈ [1, 63], reading the input from
high degree to low degree.
Equations
Instances For
Divide by x^k, discarding the remainder.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Monomial coefficients reduce to the coefficient lookup on its packed word array.
The monomial x^n is distinct from the zero polynomial.
Shift-left coefficients reduce to the coefficient lookup on the shifted packed words.
Alias for exact division by a power of x when the low coefficients vanish;
otherwise this drops the discarded remainder.
Equations
- p.divXk k = p.shiftRight k
Instances For
Normalization never increases the number of stored machine words.