Skip to content

Commit b6469e8

Browse files
feat: statement of FRI-Binius
1 parent 7cc7b42 commit b6469e8

21 files changed

Lines changed: 6575 additions & 48 deletions

ArkLib.lean

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,22 @@ import ArkLib.OracleReduction.Security.RoundByRound
127127
import ArkLib.OracleReduction.Security.SpecialSoundness
128128
import ArkLib.OracleReduction.Security.StateRestoration
129129
import ArkLib.OracleReduction.VectorIOR
130-
import ArkLib.ProofSystem.Binius.Basic
130+
import ArkLib.ProofSystem.Binius.BinaryBasefold.CommitmentPhase
131+
import ArkLib.ProofSystem.Binius.BinaryBasefold.CoreInteractionPhase
132+
import ArkLib.ProofSystem.Binius.BinaryBasefold.General
133+
import ArkLib.ProofSystem.Binius.BinaryBasefold.Prelude
134+
import ArkLib.ProofSystem.Binius.BinaryBasefold.QueryPhase
135+
import ArkLib.ProofSystem.Binius.FRIBinius.BatchingPhase
136+
import ArkLib.ProofSystem.Binius.FRIBinius.CoreInteractionPhase
137+
import ArkLib.ProofSystem.Binius.FRIBinius.FinalizationPhase
138+
import ArkLib.ProofSystem.Binius.FRIBinius.General
139+
import ArkLib.ProofSystem.Binius.FRIBinius.Prelude
140+
import ArkLib.ProofSystem.Binius.FRIBinius.QueryPhase
141+
import ArkLib.ProofSystem.Binius.RingSwitching.BatchingPhase
142+
import ArkLib.ProofSystem.Binius.RingSwitching.CoreInteractionPhase
143+
import ArkLib.ProofSystem.Binius.RingSwitching.FinalizationPhase
144+
import ArkLib.ProofSystem.Binius.RingSwitching.General
145+
import ArkLib.ProofSystem.Binius.RingSwitching.Prelude
131146
import ArkLib.ProofSystem.Component.CheckClaim
132147
import ArkLib.ProofSystem.Component.DoNothing
133148
import ArkLib.ProofSystem.Component.NoInteraction

ArkLib/Data/FieldTheory/AdditiveNTT/AdditiveNTT.lean

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,24 @@ noncomputable def sDomain_basis (i : Fin r) (h_i : i < ℓ + R_rate) :
666666
-- We map the basis of Vᵢ through our isomorphism to get the desired basis for S⁽ⁱ⁾.
667667
exact V_i_basis.map iso
668668

669+
noncomputable instance fintype_sDomain (i : Fin r) : Fintype (sDomain 𝔽q h_Fq_char_prime h_Fq_card_gt_1 β hβ_lin_indep ℓ R_rate h_ℓ_add_R_rate i) := by
670+
exact Fintype.ofFinite (sDomain 𝔽q h_Fq_char_prime h_Fq_card_gt_1 β hβ_lin_indep ℓ R_rate h_ℓ_add_R_rate i)
671+
672+
-- The cardinality of the subspace `S⁽ⁱ⁾` is `|𝔽q|^(l + R - i)`, which follows from its dimension.
673+
lemma sDomain_card (hβ_lin_indep : LinearIndependent 𝔽q β)
674+
(i : Fin r) (h_i : i < ℓ + R_rate):
675+
Fintype.card (sDomain 𝔽q h_Fq_char_prime h_Fq_card_gt_1 β hβ_lin_indep ℓ R_rate h_ℓ_add_R_rate i) = (Fintype.card 𝔽q)^(ℓ + R_rate - i) := by
676+
-- The cardinality of a vector space V is |F|^(dim V).
677+
rw [Module.card_eq_pow_finrank (K := 𝔽q) (V := sDomain 𝔽q h_Fq_char_prime h_Fq_card_gt_1 β hβ_lin_indep ℓ R_rate h_ℓ_add_R_rate i)]
678+
-- We need to show that the finrank of sDomain is ℓ + R_rate - i
679+
-- This follows from the fact that sDomain has a basis of size ℓ + R_rate - i
680+
-- We can use the basis we constructed
681+
let b := sDomain_basis 𝔽q h_Fq_char_prime h_Fq_card_gt_1 β hβ_lin_indep ℓ R_rate h_ℓ_add_R_rate i h_i
682+
-- The finrank equals the cardinality of the basis
683+
rw [Module.finrank_eq_card_basis b]
684+
-- The basis has cardinality ℓ + R_rate - i
685+
simp only [Fintype.card_fin]
686+
669687
/-! ### 2. Intermediate Novel Polynomial Bases `Xⱼ⁽ⁱ⁾` and evaluation polynomials `P⁽ⁱ⁾`-/
670688

671689
/-- `∀ i ∈ {0, ..., ℓ}`, The `i`-th order subspace vanishing polynomials `Ŵₖ⁽ⁱ⁾`,
@@ -2257,4 +2275,67 @@ theorem additiveNTT_correctness
22572275
simp_rw [Nat.sub_right_comm] -- ℓ - 1 - ↑i = ℓ - ↑i - 1
22582276

22592277
end AlgorithmCorrectness
2278+
2279+
section DomainBijection
2280+
/-!
2281+
## Domain-Index Bijections
2282+
2283+
Bijections between elements in `S^(i)` and `Fin (2^(ℓ + R_rate - i))` for use in
2284+
Binary Basefold protocol implementations.
2285+
-/
2286+
2287+
/-- Convert an element of `S^(i)` to its index in `Fin (2^(ℓ + R_rate - i))`.
2288+
This uses the basis representation of elements in the domain. -/
2289+
noncomputable def sDomainToFin (i : Fin r) (h_i : i < ℓ + R_rate)
2290+
(x : sDomain 𝔽q h_Fq_char_prime h_Fq_card_gt_1 β hβ_lin_indep ℓ R_rate h_ℓ_add_R_rate i) :
2291+
Fin (2^(ℓ + R_rate - i.val)) := by
2292+
-- Get the basis representation of x
2293+
let basis := sDomain_basis 𝔽q h_Fq_char_prime h_Fq_card_gt_1 β hβ_lin_indep ℓ R_rate h_ℓ_add_R_rate i h_i
2294+
let coeffs := basis.repr x
2295+
-- Convert the coefficients to a natural number (binary interpretation)
2296+
let nat_val: ℕ := Finsupp.sum coeffs (fun j c =>
2297+
sorry -- if c = 0 then 0 else 2^j.val
2298+
)
2299+
-- Return as Fin
2300+
exact ⟨nat_val % (2^(ℓ + R_rate - i.val)), by
2301+
apply Nat.mod_lt
2302+
apply Nat.pow_pos
2303+
norm_num⟩
2304+
2305+
/-- Convert an index in `Fin (2^(ℓ + R_rate - i))` to an element of `S^(i)`.
2306+
This is the inverse of `sDomainToFin`. -/
2307+
noncomputable def finToSDomain (i : Fin r) (h_i : i < ℓ + R_rate)
2308+
(idx : Fin (2^(ℓ + R_rate - i.val))) :
2309+
sDomain 𝔽q h_Fq_char_prime h_Fq_card_gt_1 β hβ_lin_indep ℓ R_rate h_ℓ_add_R_rate i := by
2310+
-- Get the basis
2311+
let basis := sDomain_basis 𝔽q h_Fq_char_prime h_Fq_card_gt_1 β hβ_lin_indep ℓ R_rate h_ℓ_add_R_rate i h_i
2312+
-- Convert the index to binary coefficients
2313+
let coeffs : Fin (ℓ + R_rate - i.val) → 𝔽q := fun j =>
2314+
if (idx.val / 2^j.val) % 2 = 1 then 1 else 0
2315+
-- Construct the element using the basis
2316+
exact basis (by
2317+
sorry
2318+
-- Finsupp.ofSupportFinite coeffs (by
2319+
-- The support is finite since we're working with Fin
2320+
-- apply Set.finite_lt_nat))
2321+
)
2322+
2323+
/-- The bijection between `S^(i)` and `Fin (2^(ℓ + R_rate - i))`. -/
2324+
noncomputable def sDomainFinEquiv (i : Fin r) (h_i : i < ℓ + R_rate) :
2325+
(sDomain 𝔽q h_Fq_char_prime h_Fq_card_gt_1 β hβ_lin_indep ℓ R_rate h_ℓ_add_R_rate i) ≃
2326+
Fin (2^(ℓ + R_rate - i.val)) := {
2327+
toFun := sDomainToFin 𝔽q h_Fq_char_prime h_Fq_card_gt_1 β hβ_lin_indep ℓ R_rate h_ℓ_add_R_rate i h_i,
2328+
invFun := finToSDomain 𝔽q h_Fq_char_prime h_Fq_card_gt_1 β hβ_lin_indep ℓ R_rate h_ℓ_add_R_rate i h_i,
2329+
left_inv := by
2330+
intro x
2331+
-- This requires proving that finToSDomain (sDomainToFin x) = x
2332+
sorry,
2333+
right_inv := by
2334+
intro idx
2335+
-- This requires proving that sDomainToFin (finToSDomain idx) = idx
2336+
sorry
2337+
}
2338+
2339+
end DomainBijection
2340+
22602341
end AdditiveNTT

ArkLib/Data/FieldTheory/AdditiveNTT/NovelPolynomialBasis.lean

Lines changed: 115 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1419,7 +1419,7 @@ def toCoeffsVec (ℓ : Nat) : L⦃<2^ℓ⦄[X] →ₗ[L] CoeffVecSpace L ℓ whe
14191419
non-zero diagonal entries are linearly independent. -/
14201420
lemma linearIndependent_rows_of_lower_triangular_ne_zero_diag
14211421
{n : ℕ} {R : Type*} [Field R] (A : Matrix (Fin n) (Fin n) R)
1422-
(h_lower_triangular: A.BlockTriangular ⇑OrderDual.toDual) (h_diag: ∀ i, A i i ≠ 0) :
1422+
(h_lower_triangular : A.BlockTriangular ⇑OrderDual.toDual) (h_diag : ∀ i, A i i ≠ 0) :
14231423
LinearIndependent R A := by -- This follows from the fact that such a matrix is invertible
14241424
-- because its determinant is non-zero.
14251425
have h_det : A.det ≠ 0 := by
@@ -1428,12 +1428,65 @@ lemma linearIndependent_rows_of_lower_triangular_ne_zero_diag
14281428
intro i _; exact h_diag i
14291429
exact Matrix.linearIndependent_rows_of_det_ne_zero (A := A) h_det
14301430

1431+
/-- The change-of-basis matrix from the novel basis to the monomial basis.
1432+
Aⱼᵢ = coeff of Xⁱ in novel basis vector 𝕏ⱼ. novel_coeffs * A = monomial_coeffs -/
14311433
noncomputable def changeOfBasisMatrix (hF₂ : Fintype.card 𝔽q = 2)
14321434
(hβ_lin_indep : LinearIndependent 𝔽q β)
14331435
(ℓ : Nat) (h_ℓ : ℓ ≤ r) : Matrix (Fin (2^ℓ)) (Fin (2^ℓ)) L :=
14341436
fun j i => (toCoeffsVec (L := L) (ℓ := ℓ) (
14351437
basisVectors 𝔽q β hβ_lin_indep hF₂ ℓ h_ℓ j)) i
14361438

1439+
theorem changeOfBasisMatrix_lower_triangular (hF₂ : Fintype.card 𝔽q = 2)
1440+
(hβ_lin_indep : LinearIndependent 𝔽q β) (ℓ : Nat) (h_ℓ : ℓ ≤ r) :
1441+
(changeOfBasisMatrix 𝔽q β hF₂ hβ_lin_indep ℓ h_ℓ).BlockTriangular ⇑OrderDual.toDual := by
1442+
intro i j hij
1443+
dsimp only [toCoeffsVec, basisVectors, LinearMap.coe_mk, AddHom.coe_mk, changeOfBasisMatrix]
1444+
-- ⊢ (Xⱼ β ℓ ↑i).coeff ↑j = 0
1445+
have deg_X : (Xⱼ 𝔽q β ℓ h_ℓ i).degree = i :=
1446+
degree_Xⱼ 𝔽q β hβ_lin_indep hF₂ ℓ h_ℓ i
1447+
have h_i_lt_j : i < j := by
1448+
simp only [OrderDual.toDual_lt_toDual] at hij
1449+
exact hij
1450+
have h_res: (Xⱼ 𝔽q β ℓ h_ℓ i).coeff j = 0 := by
1451+
apply coeff_eq_zero_of_natDegree_lt -- we don't use coeff_eq_zero_of_degree_lt
1452+
-- because p.natDegree returns a value of type ℕ instead of WithBot ℕ as in p.degree
1453+
rw [natDegree_eq_of_degree_eq_some (degree_Xⱼ 𝔽q β hβ_lin_indep hF₂ ℓ h_ℓ i)]
1454+
norm_cast -- auto resolve via h_i_lt_j
1455+
exact h_res
1456+
1457+
theorem changeOfBasisMatrix_diag_ne_zero (hF₂ : Fintype.card 𝔽q = 2)
1458+
(hβ_lin_indep : LinearIndependent 𝔽q β) (ℓ : Nat) (h_ℓ : ℓ ≤ r) :
1459+
(∀ i, (changeOfBasisMatrix 𝔽q β hF₂ hβ_lin_indep ℓ h_ℓ) i i ≠ 0) := by
1460+
intro i
1461+
dsimp [changeOfBasisMatrix, toCoeffsVec, basisVectors]
1462+
have h_deg : (Xⱼ 𝔽q β ℓ h_ℓ i).degree = i := degree_Xⱼ 𝔽q β hβ_lin_indep hF₂ ℓ h_ℓ i
1463+
apply coeff_ne_zero_of_eq_degree
1464+
norm_cast
1465+
1466+
/-- The determinant of the change-of-basis matrix is non-zero. -/
1467+
theorem changeOfBasisMatrix_det_ne_zero (hF₂ : Fintype.card 𝔽q = 2)
1468+
(hβ_lin_indep : LinearIndependent 𝔽q β) (ℓ : Nat) (h_ℓ : ℓ ≤ r) :
1469+
(changeOfBasisMatrix 𝔽q β hF₂ hβ_lin_indep ℓ h_ℓ).det ≠ 0 := by
1470+
let A := changeOfBasisMatrix 𝔽q β hF₂ hβ_lin_indep ℓ h_ℓ
1471+
-- Use the fact that A is lower-triangular with non-zero diagonal
1472+
rw [Matrix.det_of_lowerTriangular A]
1473+
· -- The determinant of a lower-triangular matrix is
1474+
-- the product of diagonal entries: ⊢ ∏ i, A i i ≠ 0
1475+
let res := changeOfBasisMatrix_diag_ne_zero 𝔽q β hF₂ hβ_lin_indep ℓ h_ℓ
1476+
exact prod_ne_zero_iff.mpr fun a a_1 ↦ res a
1477+
· -- A is lower-triangular
1478+
exact changeOfBasisMatrix_lower_triangular 𝔽q β hF₂ hβ_lin_indep ℓ h_ℓ
1479+
1480+
/-- The change-of-basis matrix is invertible, this is required by the proofs
1481+
of inversion between monomial and novel polynomial basis coefficients. -/
1482+
noncomputable instance changeOfBasisMatrix_invertible (hF₂ : Fintype.card 𝔽q = 2)
1483+
(hβ_lin_indep : LinearIndependent 𝔽q β) (ℓ : Nat) (h_ℓ : ℓ ≤ r) :
1484+
Invertible (changeOfBasisMatrix 𝔽q β hF₂ hβ_lin_indep ℓ h_ℓ) := by
1485+
let h_A_invertible: Invertible (changeOfBasisMatrix 𝔽q β hF₂ hβ_lin_indep ℓ h_ℓ) := by
1486+
refine (changeOfBasisMatrix 𝔽q β hF₂ hβ_lin_indep ℓ h_ℓ).invertibleOfIsUnitDet ?_
1487+
(expose_names; exact Ne.isUnit (changeOfBasisMatrix_det_ne_zero 𝔽q β hF₂ hβ_lin_indep ℓ h_ℓ))
1488+
exact h_A_invertible
1489+
14371490
/--
14381491
The coefficient vectors of the novel basis polynomials are linearly independent.
14391492
This is proven by showing that the change-of-basis matrix to the monomial basis
@@ -1448,29 +1501,9 @@ lemma coeff_vectors_linear_independent (hF₂ : Fintype.card 𝔽q = 2)
14481501
-- Apply the lemma about triangular matrices.
14491502
apply linearIndependent_rows_of_lower_triangular_ne_zero_diag A
14501503
· -- ⊢ A.BlockTriangular ⇑OrderDual.toDual => Prove the matrix A is lower-triangular.
1451-
intro i j hij
1452-
dsimp only [toCoeffsVec, basisVectors, LinearMap.coe_mk, AddHom.coe_mk, A]
1453-
-- ⊢ (Xⱼ β ℓ ↑i).coeff ↑j = 0
1454-
have deg_X : (Xⱼ 𝔽q β ℓ h_ℓ i).degree = i :=
1455-
degree_Xⱼ 𝔽q β hβ_lin_indep hF₂ ℓ h_ℓ i
1456-
have h_i_lt_j : i < j := by
1457-
simp only [OrderDual.toDual_lt_toDual] at hij
1458-
exact hij
1459-
have h_res: (Xⱼ 𝔽q β ℓ h_ℓ i).coeff j = 0 := by
1460-
apply coeff_eq_zero_of_natDegree_lt -- we don't use coeff_eq_zero_of_degree_lt
1461-
-- because p.natDegree returns a value of type ℕ instead of WithBot ℕ as in p.degree
1462-
rw [natDegree_eq_of_degree_eq_some (degree_Xⱼ 𝔽q β hβ_lin_indep hF₂ ℓ h_ℓ i)]
1463-
norm_cast -- auto resolve via h_i_lt_j
1464-
exact h_res
1504+
exact changeOfBasisMatrix_lower_triangular 𝔽q β hF₂ hβ_lin_indep ℓ h_ℓ
14651505
· -- ⊢ ∀ (i : Fin (2 ^ ℓ)), A i i ≠ 0 => All diagonal entries are non-zero.
1466-
intro i
1467-
dsimp [A, toCoeffsVec, basisVectors]
1468-
-- `A i i` is the `i`-th (also the leading) coefficient of `Xⱼ`, which is non-zero.
1469-
have h_deg : (Xⱼ 𝔽q β ℓ h_ℓ i).degree = i := degree_Xⱼ 𝔽q β hβ_lin_indep hF₂ ℓ h_ℓ i
1470-
have h_natDegree : (Xⱼ 𝔽q β ℓ h_ℓ i).natDegree = i := natDegree_eq_of_degree_eq_some h_deg
1471-
have deg_X : (Xⱼ 𝔽q β ℓ h_ℓ i).degree = i := degree_Xⱼ 𝔽q β hβ_lin_indep hF₂ ℓ h_ℓ i
1472-
apply coeff_ne_zero_of_eq_degree -- (hn : degree p = n) : coeff p n ≠ 0
1473-
norm_cast
1506+
exact fun i ↦ changeOfBasisMatrix_diag_ne_zero 𝔽q β hF₂ hβ_lin_indep ℓ h_ℓ i
14741507

14751508
/-- The basis vectors are linearly independent over `L`. -/
14761509
theorem basisVectors_linear_independent (hF₂ : Fintype.card 𝔽q = 2) (ℓ : Nat) (h_ℓ : ℓ ≤ r) :
@@ -1524,4 +1557,63 @@ theorem novelPolynomialBasis_is_basisVectors (hF₂ : Fintype.card 𝔽q = 2) (
15241557
= basisVectors 𝔽q β hβ_lin_indep hF₂ ℓ h_ℓ := by
15251558
simp only [novelPolynomialBasis, Basis.coe_mk]
15261559

1560+
/-- Convert monomial coefficients to novel polynomial basis coefficients.
1561+
Using row vectors: n = m * A⁻¹.
1562+
-/
1563+
noncomputable def monomialToNovelCoeffs (hF₂ : Fintype.card 𝔽q = 2)
1564+
(hβ_lin_indep : LinearIndependent 𝔽q β)
1565+
(ℓ : ℕ) (h_ℓ : ℓ ≤ r) (monomial_coeffs : Fin (2 ^ ℓ) → L) : Fin (2^ℓ) → L :=
1566+
let A := changeOfBasisMatrix 𝔽q β hF₂ hβ_lin_indep ℓ h_ℓ
1567+
-- We need A to be invertible to use A⁻¹. This is implicitly handled by Lean
1568+
-- when A⁻¹ is used, but we will rely on the determinant proof later.
1569+
Matrix.vecMul monomial_coeffs A⁻¹
1570+
1571+
/-- Convert novel polynomial basis coefficients to monomial coefficients.
1572+
Using row vectors: m = n * A.
1573+
-/
1574+
noncomputable def novelToMonomialCoeffs (hF₂ : Fintype.card 𝔽q = 2)
1575+
(hβ_lin_indep : LinearIndependent 𝔽q β)
1576+
(ℓ : ℕ) (h_ℓ : ℓ ≤ r) (novel_coeffs : Fin (2 ^ ℓ) → L) : Fin (2^ℓ) → L :=
1577+
let A := changeOfBasisMatrix 𝔽q β hF₂ hβ_lin_indep ℓ h_ℓ
1578+
Matrix.vecMul novel_coeffs A
1579+
1580+
/-- The conversion functions are inverses of each other. (Monomial -> Novel -> Monomial) -/
1581+
theorem monomialToNovel_novelToMonomial_inverse (hF₂ : Fintype.card 𝔽q = 2)
1582+
(hβ_lin_indep : LinearIndependent 𝔽q β) (ℓ : ℕ) (h_ℓ : ℓ ≤ r) :
1583+
∀ coeffs : Fin (2^ℓ) → L,
1584+
novelToMonomialCoeffs 𝔽q β hF₂ hβ_lin_indep ℓ h_ℓ
1585+
(monomialToNovelCoeffs 𝔽q β hF₂ hβ_lin_indep ℓ h_ℓ coeffs) = coeffs := by
1586+
intro coeffs
1587+
-- Unfold the definitions and the let bindings.
1588+
unfold monomialToNovelCoeffs novelToMonomialCoeffs
1589+
dsimp only
1590+
-- Let A be the change of basis matrix.
1591+
let A := changeOfBasisMatrix 𝔽q β hF₂ hβ_lin_indep ℓ h_ℓ
1592+
-- Goal: (coeffs * A⁻¹) * A = coeffs
1593+
-- Use associativity of vecMul: (v * M) * N = v * (M * N).
1594+
rw [Matrix.vecMul_vecMul]
1595+
-- Goal: coeffs * (A⁻¹ * A) = coeffs, We need A⁻¹ * A = I. This requires det(A) ≠ 0.
1596+
-- Use Matrix.nonsing_inv_mul (A⁻¹ * A = I).
1597+
rw [Matrix.nonsing_inv_mul A (Matrix.isUnit_det_of_invertible A)]
1598+
-- Goal: coeffs * 1 = coeffs
1599+
rw [Matrix.vecMul_one]
1600+
1601+
/-- The conversion functions are inverses of each other. (Novel -> Monomial -> Novel) -/
1602+
theorem novelToMonomial_monomialToNovel_inverse (hF₂ : Fintype.card 𝔽q = 2)
1603+
(hβ_lin_indep : LinearIndependent 𝔽q β) (ℓ : ℕ) (h_ℓ : ℓ ≤ r) :
1604+
∀ coeffs : Fin (2^ℓ) → L,
1605+
monomialToNovelCoeffs 𝔽q β hF₂ hβ_lin_indep ℓ h_ℓ
1606+
(novelToMonomialCoeffs 𝔽q β hF₂ hβ_lin_indep ℓ h_ℓ coeffs) = coeffs := by
1607+
intro coeffs
1608+
-- Unfold the definitions and the let bindings.
1609+
unfold novelToMonomialCoeffs monomialToNovelCoeffs
1610+
dsimp only
1611+
let A := changeOfBasisMatrix 𝔽q β hF₂ hβ_lin_indep ℓ h_ℓ
1612+
-- Goal: (coeffs * A) * A⁻¹ = coeffs
1613+
rw [Matrix.vecMul_vecMul]
1614+
-- Goal: coeffs * (A * A⁻¹) = coeffs, we need A * A⁻¹ = I.
1615+
rw [Matrix.mul_nonsing_inv A (Matrix.isUnit_det_of_invertible A)]
1616+
-- Goal: coeffs * 1 = coeffs
1617+
rw [Matrix.vecMul_one]
1618+
15271619
end AdditiveNTT

ArkLib/Data/Nat/Bitwise.lean

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1203,4 +1203,48 @@ lemma getBit_of_binaryFinMapToNat {n : ℕ} (m : Fin n → ℕ) (h_binary: ∀ j
12031203
simp only [ite_eq_right_iff, one_ne_zero, imp_false, ne_eq]
12041204
omega
12051205

1206+
/-- Middle bits: take `len` bits starting at `offset` from `n`. -/
1207+
def getMiddleBits (offset len n : ℕ) : ℕ :=
1208+
getLowBits (numLowBits:=len) (n:=n >>> offset)
1209+
1210+
/-- Bit-level characterization of middle bits. -/
1211+
lemma getBit_of_middleBits {n offset len k : ℕ} :
1212+
getBit k (getMiddleBits offset len n) =
1213+
if k < len then getBit (k + offset) n else 0 := by
1214+
unfold getMiddleBits
1215+
-- use existing lemmas
1216+
rw [getBit_of_lowBits, getBit_of_shiftRight]
1217+
1218+
/-- Middle bits are strictly less than `2^len`. -/
1219+
lemma getMiddleBits_lt_two_pow {n offset len : ℕ} :
1220+
getMiddleBits offset len n < 2 ^ len := by
1221+
unfold getMiddleBits
1222+
exact getLowBits_lt_two_pow (n := n >>> offset) len
1223+
1224+
/-- Middle bits as a modulus form. -/
1225+
lemma getMiddleBits_eq_mod {n offset len : ℕ} :
1226+
getMiddleBits offset len n = (n >>> offset) % (2 ^ len) := by
1227+
unfold getMiddleBits
1228+
exact getLowBits_eq_mod_two_pow (n := n >>> offset) (numLowBits := len)
1229+
1230+
/-- Concatenate high (length m) and low (length n) using shifts. -/
1231+
def joinBits {n m : ℕ} (low : Fin (2 ^ n)) (high : Fin (2 ^ m)) : Fin (2 ^ (m+n)) :=
1232+
⟨(high.val <<< n) ||| low.val, by sorry
1233+
1234+
/-- Low n bits of joinBits are exactly low. -/
1235+
lemma getLowBits_joinBits {n m : ℕ} (low : Fin (2 ^ n)) (high : Fin (2 ^ m)) :
1236+
getLowBits n (joinBits low high).val = low.val := by
1237+
sorry
1238+
1239+
/-- Dropping low n bits by shifting right recovers high. -/
1240+
lemma getHighBits_no_shl_joinBits {n m : ℕ} (low : Fin (2 ^ n)) (high : Fin (2 ^ m)) :
1241+
getHighBits_no_shl n (joinBits low high).val = high.val := by
1242+
sorry
1243+
1244+
/-- Bit characterization: below cut use low, above cut use high. -/
1245+
lemma getBit_joinBits {n m k : ℕ} (low : Fin (2 ^ n)) (high : Fin (2 ^ m)) :
1246+
getBit k (joinBits low high).val =
1247+
if k < n then getBit k low.val else getBit (k - n) high.val := by
1248+
sorry
1249+
12061250
end Nat

ArkLib/ProofSystem/Binius/Basic.lean

Lines changed: 0 additions & 24 deletions
This file was deleted.

0 commit comments

Comments
 (0)