Skip to content

Commit c2f4a7d

Browse files
committed
Folding context
1 parent 77fca53 commit c2f4a7d

3 files changed

Lines changed: 192 additions & 103 deletions

File tree

ArkLib/Data/CodingTheory/ProximityGap/Folding.lean

Lines changed: 68 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import ArkLib.Data.Polynomial.Bivariate
1111
import ArkLib.Data.Polynomial.FoldingPolynomial
1212
import ArkLib.Data.Polynomial.SplitFold
1313
import ArkLib.Data.CodingTheory.ProximityGap.Basic
14+
import ArkLib.Data.CodingTheory.ProximityGap.Folding.FoldingContext
1415
import ArkLib.Data.Finset.PickSubset
1516
import ArkLib.Data.CodingTheory.ProximityGap.BCIKS20.Curves
1617
import 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

269270
private 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

393381
private 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]
613601
private 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

778749
private lemma folded_rate_div_eq_helper {d : ℕ}
779750
(hkn : k ≤ n) (hkd : 2 ^ k ∣ d) :

0 commit comments

Comments
 (0)