@@ -11,6 +11,7 @@ import ArkLib.Data.Polynomial.Bivariate
1111import ArkLib.Data.Polynomial.FoldingPolynomial
1212import ArkLib.Data.Polynomial.SplitFold
1313import ArkLib.Data.CodingTheory.ProximityGap.Basic
14+ import ArkLib.Data.CodingTheory.ProximityGap.Folding.FoldingContext
1415import ArkLib.Data.Finset.PickSubset
1516import ArkLib.Data.CodingTheory.ProximityGap.BCIKS20.Curves
1617import ArkLib.Data.Domain.CosetFftDomain.Block
@@ -267,7 +268,7 @@ private lemma eval_comm {f : Polynomial (Polynomial F)} {a x : F} :
267268 Polynomial.eval₂_eq_sum, Polynomial.sum_def]
268269
269270private lemma interpolate_eq_folding_poly_eval
270- (hk : k ≤ n)
271+ [FoldingContextMiddle k n]
271272 (hx : x ∈ domain.subdomain k) :
272273 ((Lagrange.interpolate (blockIdx domain k x) domain)
273274 f) =
@@ -308,87 +309,74 @@ private lemma interpolate_eq_folding_poly_eval
308309/-- Perfect completeness of folding: folding a codeword is the same as
309310 applying `polyFold` and then encoding.
310311-/
311- theorem foldWord_codeword {d : ℕ}
312+ theorem foldWord_codeword {d : ℕ} [FoldingContext k d n]
312313 {α : F}
313- (hk : k ≤ n)
314- {p : ReedSolomon.code (domain : Fin (2 ^ n) ↪ F) d} :
314+ {p : ReedSolomon.code (domain : Fin (2 ^ n) ↪ F) (2 ^ d)} :
315315 foldWord domain p k α =
316316 evalOnPoints (domain.subdomain k)
317317 (FoldingPolynomial.polyFold (ReedSolomon.toPolynomial p) (2 ^ k) α) := by
318318 ext x
319319 simp only [foldWord, foldValue, foldWordAux, evalOnPoints,
320320 Embedding.coeFn_mk, toPolynomial, LinearMap.coe_mk, AddHom.coe_mk,
321321 FoldingPolynomial.polyFold]
322- rw [eval_comm, interpolate_eq_folding_poly_eval hk (by simp)]
322+ rw [eval_comm, interpolate_eq_folding_poly_eval (by simp)]
323323 aesop
324324
325- theorem foldWord_evalOnPoints {α : F} {p : Polynomial F}
326- (hk : k ≤ n) (hp_deg : p.degree < 2 ^ n) :
325+ theorem foldWord_evalOnPoints [FoldingContextMiddle k n]
326+ {α : F} {p : Polynomial F}
327+ (hp_deg : p.degree < 2 ^ n) :
327328 foldWord domain (evalOnPoints domain p) k α =
328329 evalOnPoints (domain.subdomain k)
329330 (FoldingPolynomial.polyFold p (2 ^ k) α) := by
331+ have : FoldingContext k n n := FoldingContext.ofMiddle
330332 let f := evalOnPoints (domain : Fin (2 ^ n) ↪ F) p
331333 have hcode : f ∈ code domain (2 ^ n) := by simp_all [evalOnPoints_mem_code_of_degree_lt, f]
332- rw [show evalOnPoints _ _ = (⟨f, hcode⟩ : code _ _) by rfl, foldWord_codeword hk ]
334+ rw [show evalOnPoints _ _ = (⟨f, hcode⟩ : code _ _) by rfl, foldWord_codeword]
333335 simp_all [toPolynomial_evalWord_of_degree_lt, f]
334336
335337/-- Perfect completeness of folding: if a word belongs to an RS-code
336338 then its `foldWord` belongs to a folded RS-code.
337339-/
338- theorem foldWord_mem_code_of_mem_code {d : ℕ}
340+ theorem foldWord_mem_code_of_mem_code {d : ℕ} [FoldingContext k d n]
339341 {α : F}
340- (hk : k ≤ n)
341- (hk_d_dvd : 2 ^ k ∣ d)
342342 {f : Word F (Fin (2 ^ n))}
343- (hf : f ∈ ReedSolomon.code (domain : Fin (2 ^ n) ↪ F) d ) :
343+ (hf : f ∈ ReedSolomon.code (domain : Fin (2 ^ n) ↪ F) ( 2 ^ d) ) :
344344 foldWord domain f k α ∈
345- ReedSolomon.code (domain.subdomain k : Fin (2 ^ (n - k)) ↪ F) (d / (2 ^ k)) := by
346- by_cases hd : d = 0
347- · aesop
348- · have hf' :=
349- ReedSolomon.mem_code_iff_exists_polynomial'.mp hf
350- obtain ⟨p, hf'⟩ := hf'
351- have hk_d_le : 2 ^ k ≤ d := Nat.le_of_dvd (by omega) hk_d_dvd
352- apply ReedSolomon.mem_code_of_polynomial_of_natDegree_lt_of_eval
353- (p := FoldingPolynomial.polyFold p (2 ^ k) α)
354- · exact lt_of_le_of_lt FoldingPolynomial.polyFold_natDegree_le <| by
355- by_cases hp : p = 0
356- · aesop (add safe (by omega))
357- · rw [Nat.div_lt_iff_lt_mul (by simp)]
358- by_cases hd : d ≤ 2 ^ n
359- · have : p.natDegree < d := by
360- rw [←Polynomial.natDegree_lt_iff_degree_lt hp] at hf'
361- aesop
362- exact lt_of_lt_of_le this <| by
363- rw [Nat.div_mul_cancel hk_d_dvd]
364- · have : p.degree < d := lt_trans hf'.1 <| by
365- aesop (add unsafe (by rw [WithBot.lt_def]))
366- rw [Nat.div_mul_cancel hk_d_dvd]
367- aesop
368- (add simp [Polynomial.natDegree_lt_iff_degree_lt])
369- · intro i
370- have := foldWord_codeword (α := α) hk (p := ⟨f, hf⟩)
371- simp only at this
372- simp only [this, evalOnPoints, Embedding.coeFn_mk,
373- LinearMap.coe_mk, AddHom.coe_mk]
374- obtain ⟨hp_deg, hf'⟩ := hf'
375- subst hf'
376- congr
377- apply Polynomial.eq_of_degrees_lt_of_eval_index_eq
378- (v := domain) (s := univ) (by simp)
379- · exact lt_of_lt_of_le (ReedSolomon.toPolynomial_lt_min_deg_card _) <| by
380- by_cases hd : d ≤ 2 ^ n
381- · aesop (add unsafe (by rw [WithBot.le_def]))
382- · simp [min, hd]
383- · exact lt_of_lt_of_le hp_deg <| by
384- by_cases hd : d ≤ 2 ^ n
385- · aesop (add unsafe (by rw [WithBot.le_def]))
386- · simp [min, hd]
387- · intro i _
388- conv_lhs =>
389- rw [show domain i = (domain : (Fin (2 ^ n)) ↪ F) i by rfl]
390- rw [ReedSolomon.toPolynomial_eval_at_domain]
391- simp [evalOnPoints]
345+ ReedSolomon.code (domain.subdomain k : Fin (2 ^ (n - k)) ↪ F) (2 ^ (d - k)) := by
346+ have hf' :=
347+ ReedSolomon.mem_code_iff_exists_polynomial'.mp hf
348+ obtain ⟨p, hf'⟩ := hf'
349+ apply ReedSolomon.mem_code_of_polynomial_of_natDegree_lt_of_eval
350+ (p := FoldingPolynomial.polyFold p (2 ^ k) α)
351+ · exact lt_of_le_of_lt FoldingPolynomial.polyFold_natDegree_le <| by
352+ by_cases hp : p = 0
353+ · aesop (add safe (by omega))
354+ · rw [Nat.div_lt_iff_lt_mul (by simp)]
355+ have : p.natDegree < 2 ^ d := by
356+ rw [←Polynomial.natDegree_lt_iff_degree_lt hp] at hf'
357+ aesop
358+ simp [this]
359+ · intro i
360+ have := foldWord_codeword (α := α) (p := ⟨f, hf⟩)
361+ simp only at this
362+ simp only [this, evalOnPoints, Embedding.coeFn_mk,
363+ LinearMap.coe_mk, AddHom.coe_mk]
364+ obtain ⟨hp_deg, hf'⟩ := hf'
365+ subst hf'
366+ congr
367+ apply Polynomial.eq_of_degrees_lt_of_eval_index_eq
368+ (v := domain) (s := univ) (by simp)
369+ · exact lt_of_lt_of_le (ReedSolomon.toPolynomial_lt_min_deg_card _) <| by
370+ norm_cast
371+ simp
372+ · exact lt_of_lt_of_le hp_deg <| by
373+ norm_cast
374+ simp
375+ · intro i _
376+ conv_lhs =>
377+ rw [show domain i = (domain : (Fin (2 ^ n)) ↪ F) i by rfl]
378+ rw [ReedSolomon.toPolynomial_eval_at_domain]
379+ simp [evalOnPoints]
392380
393381private noncomputable def foldWordAuxCoeff (domain : SmoothCosetFftDomain n F)
394382 (f : Word F (Fin (2 ^ n))) (k : ℕ) (i : Fin (2 ^ k)) (x : F) : F :=
@@ -611,10 +599,8 @@ private lemma contradictory_hamming_dist_zero :
611599
612600@[simp]
613601private lemma contradictory_hamming_dist_formula {s : Finset F}
614- {d : ℕ}
615- (h_s : s ⊆ (domain.subdomain k).toFinset)
616- (h_k_d : 2 ^ k ≤ d)
617- (h_d : d ≤ 2 ^ n) :
602+ {d : ℕ} [FoldingContext k d n]
603+ (h_s : s ⊆ (domain.subdomain k).toFinset) :
618604 hammingDistBound k domain s =
619605 2 ^ n - 2 ^ k * (Finset.card s) := by
620606 unfold hammingDistBound hammingDistComplementBound
@@ -643,7 +629,7 @@ private lemma contradictory_hamming_dist_formula {s : Finset F}
643629 aesop (add safe (by apply Finset.card_bij (fun a _ ↦ a.1 )))
644630 ]
645631 rw [Finset.sum_bij (t := s)
646- (g := fun x ↦ Finset.card {j | domain j ^ ( 2 ^ k) = x})
632+ (g := fun x ↦ Finset.card {j | domain j ^ 2 ^ k = x})
647633 (i := fun i _ ↦ domain.subdomain k i)
648634 (by aesop)
649635 CosetFftDomain.injOn
@@ -666,10 +652,7 @@ private lemma contradictory_hamming_dist_formula {s : Finset F}
666652 rw [
667653 show ({j | domain j ^ 2 ^ k = a} : Finset _) = blockIdx domain k a by rfl,
668654 card_blockIdx,
669- card_block_of_mem_subdomain' (by {
670- rw [←Nat.pow_le_pow_iff_right (a := 2 ) (by simp)]
671- omega
672- }) (by {
655+ card_block_of_mem_subdomain' (by simp) (by {
673656 rw [←CosetFftDomainClass.mem_toFinset_iff_mem]
674657 exact h_s ha
675658 })]
@@ -683,12 +666,11 @@ private lemma correlated_agreement_implies_contradictory_hamm_dist
683666 {u : Fin (2 ^ k) → Polynomial F}
684667 (h_u : ∀ i, ∀ x ∈ s, (u i).eval x =
685668 foldWordAuxCoeff domain f k i x)
686- {d : ℕ}
687- (h_d : 2 ^ k ≤ d)
669+ {d : ℕ} [FoldingContextLeft k d]
688670 (h_k_card : (2 ^ k) ≤ Fintype.card F)
689- (h_u_deg : ∀ i, (u i).natDegree < d / ( 2 ^ k)) :
671+ (h_u_deg : ∀ i, (u i).natDegree < 2 ^ (d - k)) :
690672 ∃ f' : Polynomial F,
691- f'.natDegree < d ∧
673+ f'.natDegree < 2 ^ d ∧
692674 hammingDist f (fun x => f'.eval (domain x)) ≤
693675 hammingDistBound k domain s := by
694676 by_cases h_empty : s = ∅
@@ -697,21 +679,16 @@ private lemma correlated_agreement_implies_contradictory_hamm_dist
697679 (add safe (by grind))
698680 (add unsafe (by rw [←Finset.compl_filter, Finset.card_compl]))
699681 (add simp [hammingDist, Finset.card_sdiff])
700- · let s' := s.pickSubset (d / ( 2 ^ k))
682+ · let s' := s.pickSubset (2 ^ (d - k))
701683 have h_nonempty : s.Nonempty := by grind
702- have h_s'_card : s'.card = min s.card (d / (2 ^ k)) := by simp [s']
703- have h_s'_non_empty : s'.Nonempty := by
704- simp_all only [card_pick_subset, ne_eq,
705- Nat.div_eq_zero_iff, Nat.pow_eq_zero, OfNat.ofNat_ne_zero, false_and,
706- false_or, not_lt, nonempty_pick_subset_of_nonempty_of_ne, s']
684+ have h_s'_card : s'.card = min s.card (2 ^ (d - k)) := by simp [s']
685+ have h_s'_non_empty : s'.Nonempty := by aesop
707686 exists ((Polynomial.map (Polynomial.compRingHom (Polynomial.X ^ (2 ^ k))) <|
708687 indicatedPolynomial domain f k s').eval Polynomial.X)
709688 constructor
710689 · exact lt_of_lt_of_le
711690 (indicated_polynomial_comp_x_k_natDegree h_s'_non_empty)
712- (le_trans
713- (Nat.mul_le_mul_left (m := d / (2 ^ k)) _ (by omega))
714- (Nat.mul_div_le _ _))
691+ (by aesop)
715692 · simp only [hammingDist, ne_eq, hammingDistBound, Fintype.card_fin]
716693 rw [←Finset.compl_filter, Finset.card_compl, Fintype.card_fin]
717694 apply Nat.sub_le_sub_left
@@ -750,30 +727,24 @@ private lemma dist_from_code_bound_of_correlated_agreement
750727 {u : Fin (2 ^ k) → Polynomial F}
751728 (h_u : ∀ i, ∀ x ∈ s, (u i).eval x =
752729 foldWordAuxCoeff domain f k i x)
753- {d : ℕ}
754- (h_k_d : 2 ^ k ≤ d)
755- (h_d : d ≤ 2 ^ n)
756- (h_u_deg : ∀ i, (u i).natDegree < d / (2 ^ k)) :
757- Δ₀(f, ReedSolomon.code (domain : Fin (2 ^ n) ↪ F) d)
730+ {d : ℕ} [FoldingContext k d n]
731+ (h_u_deg : ∀ i, (u i).natDegree < (2 ^ (d - k))) :
732+ Δ₀(f, ReedSolomon.code (domain : Fin (2 ^ n) ↪ F) (2 ^ d))
758733 ≤ 2 ^ n -
759734 2 ^ k * (Finset.card s) := by
760735 simp only [distFromCode, SetLike.mem_coe]
761736 exact sInf_le_of_le
762737 (b := ↑(hammingDistBound k domain s))
763738 (h := by
764- aesop
765- (add safe
766- (by rw [contradictory_hamming_dist_formula]))
767- ) <| by
739+ aesop
740+ (add safe (by rw [contradictory_hamming_dist_formula]))) <| by
768741 obtain ⟨f', h_f'_deg, hdist⟩ :=
769- correlated_agreement_implies_contradictory_hamm_dist h_s h_u h_k_d (by {
770- exact le_trans h_k_d <| by
771- exact le_trans h_d <| by
772- rw [show 2 ^ n = Finset.card domain.toFinset by simp]
773- simp only [CosetFftDomain.toFinset]
774- exact Finset.card_le_card (by simp)
742+ correlated_agreement_implies_contradictory_hamm_dist h_s h_u (by {
743+ exact le_trans (b := 2 ^ n) (by simp) <| by
744+ convert card_toFinset_le_fintype_card (ω := domain) <;> aesop
775745 }) h_u_deg
776- aesop (add safe [mem_code_of_polynomial_of_natDegree_lt_of_eval])
746+ simp only [Set.mem_setOf_eq, Nat.cast_le]
747+ aesop (add safe [evalOnPoints_mem_code_of_natDegree_lt])
777748
778749private lemma folded_rate_div_eq_helper {d : ℕ}
779750 (hkn : k ≤ n) (hkd : 2 ^ k ∣ d) :
0 commit comments