Definitions bundle OAIQ3Cb002 of the split of OpenAI, Bounded-degree coboundary expanders in every dimension
DefinitionOAIQ3Cb002A definitions bundle of the split of OpenAI's proof of OAI.CoboundaryExpanders.main, carved from OpenAI's openai/math development (OpenAI, Bounded-degree coboundary expanders in every dimension, OpenAI Math Release, September 24, 2026, result family 177, github.com/openai/math at commit adc7f12, Apache License 2.0) and ported to Lean 4.33.1 and Mathlib 0df444a. The declarations and their proofs are OpenAI's.
Contents. It holds 471 declarations of OpenAI's Lean: 192 definitions, 1 inductive type or structure, 8 instances and 270 theorems. The definitions and types are OAI.CoboundaryExpanders.Construction.matrixKernelHomologyIso, OAI.CoboundaryExpanders.Construction.opposition, OAI.CoboundaryExpanders.Construction.oppositionVertex, OAI.CoboundaryExpanders.Construction.quotientLinkVertexModel, OAI.CoboundaryExpanders.Construction.reducedFlagEquiv, OAI.CoboundaryExpanders.Construction.reducedGenerated, OAI.CoboundaryExpanders.Construction.reducedLocalMap, OAI.CoboundaryExpanders.Construction.reducedRoot, OAI.CoboundaryExpanders.Construction.sphericalLinkModel, OAI.CoboundaryExpanders.Construction.truncatedIwahori, OAI.CoboundaryExpanders.Construction.uLocalEmbedding, OAI.CoboundaryExpanders.CosetConstruction.Walk, OAI.CoboundaryExpanders.CosetConstruction.typedChainIso, OAI.CoboundaryExpanders.CosetModules.base, OAI.CoboundaryExpanders.CosetModules.cosetToInd, OAI.CoboundaryExpanders.CosetModules.extend, OAI.CoboundaryExpanders.CosetModules.indCosetIso, OAI.CoboundaryExpanders.CosetModules.indToCoset, OAI.CoboundaryExpanders.CosetSums.descend, OAI.CoboundaryExpanders.CosetSums.inclusion, OAI.CoboundaryExpanders.CosetSums.projection, OAI.CoboundaryExpanders.FinitePivots.prefixFlag, OAI.CoboundaryExpanders.FinsuppPermutation.OrbitParam.H0Equiv, OAI.CoboundaryExpanders.FinsuppPermutation.coeffIso, OAI.CoboundaryExpanders.InfiniteChains.AllLinkCones, OAI.CoboundaryExpanders.InfiniteChains.Attachment.ExactIn, OAI.CoboundaryExpanders.InfiniteChains.Attachment.RelativeExactIn, OAI.CoboundaryExpanders.InfiniteChains.Attachment.joinFaces, OAI.CoboundaryExpanders.InfiniteChains.Attachment.oldFaces, OAI.CoboundaryExpanders.InfiniteChains.BadSimplex.BadFaces, OAI.CoboundaryExpanders.InfiniteChains.BadSimplex.goodLink, OAI.CoboundaryExpanders.InfiniteChains.BadSimplex.stage, OAI.CoboundaryExpanders.InfiniteChains.ChainTransport.relabel, OAI.CoboundaryExpanders.InfiniteChains.Complex.IsConePoint, OAI.CoboundaryExpanders.InfiniteChains.Complex.augmentedData, OAI.CoboundaryExpanders.InfiniteChains.Complex.cone, OAI.CoboundaryExpanders.InfiniteChains.Complex.faceLink, OAI.CoboundaryExpanders.InfiniteChains.Cone.BoundedCone.extend, OAI.CoboundaryExpanders.InfiniteChains.Cone.BoundedCone.initial, OAI.CoboundaryExpanders.InfiniteChains.Cone.BoundedCone.normalize and 153 more.
Sources. They come from these modules of lean/OAI/Combinatorics/Coboundary, in whole or in part: Coboundary_Averaging, Coboundary_Chains, Coboundary_ChamberCones, Coboundary_Chambers, Coboundary_Cones, Coboundary_Cosets, Coboundary_Expansion, Coboundary_Flags, Coboundary_Frames, Coboundary_Joins, Coboundary_LatticeCones, Coboundary_Lattices, Coboundary_LinkSpectrum, Coboundary_Links, Coboundary_Mixing, Coboundary_Polynomial, Coboundary_Realization, Coboundary_Windows, Congruence_Basic, Congruence_Coinvariants, Congruence_CongruenceFrames, Congruence_FrameHomology, Congruence_OddHomology, Congruence_Parabolic, Congruence_Patterns, Congruence_ProStability, Congruence_Resolution, Congruence_Transfer.
Imports. It imports the published bundle Def_CoboundaryExpanders; the bundles OAIQ3Cb000 and OAIQ3Cb001 of this split.
Imported by (directly, in this split): the proofs of OAI.CoboundaryExpanders.Construction.actual_uniform_cosystolic, OAI.CoboundaryExpanders.Construction.uniform_infinite_coset_positive, OAI.CoboundaryExpanders.main and OAI.CoboundaryExpanders.uniform_gamma_vanishing.
import Mathlib
import Definitions.Def_CoboundaryExpanders
import Definitions.Def_OAIQ3Cb000
import Definitions.Def_OAIQ3Cb001
section
-- module Solutions.OAIQ3_Cob.Coboundary_Chains
attribute [-instance] _root_.OAI.CoboundaryExpanders.InfiniteChains.Complex.faceMulAction
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
/-!
Augmented F2 simplicial chains, boundaries, exactness, and relative attachments.
-/
noncomputable section
open scoped BigOperators
namespace CoboundaryExpanders.InfiniteChains
section
variable {V : Type} [DecidableEq V]
lemma raw_contraction (a : V) :
rawBoundary.comp (rawCone a) + (rawCone a).comp rawBoundary = LinearMap.id := by
apply Finsupp.lhom_ext'
intro s
apply LinearMap.ext
intro r
simp only [LinearMap.add_apply, LinearMap.comp_apply, Finsupp.lsingle_apply,
LinearMap.id_apply, rawCone_single, rawBoundary_single, map_sum]
by_cases ha : a ∈ s
· rw [ite_eq_left ha, map_zero, zero_add]
rw [Finset.sum_eq_single a]
· simp [Finset.insert_erase ha]
· intro b hb hba
simp [Finset.mem_erase, Ne.symm hba, ha]
· exact fun h => (h ha).elim
· rw [ite_eq_right ha, rawBoundary_single, Finset.sum_insert ha, Finset.erase_insert ha]
have he : (∑ b ∈ s, Finsupp.single ((insert a s).erase b) r) =
∑ b ∈ s, Finsupp.single (insert a (s.erase b)) r := by
apply Finset.sum_congr rfl
intro b hb
rw [Finset.erase_insert_of_ne (show a ≠ b from by intro he; subst b; exact ha hb)]
rw [he]
have he' : (∑ b ∈ s, if a ∈ s.erase b then 0 else Finsupp.single (insert a (s.erase b)) r) =
∑ b ∈ s, Finsupp.single (insert a (s.erase b)) r := by
apply Finset.sum_congr rfl
intro b _
rw [ite_eq_right (fun h => ha (Finset.mem_of_mem_erase h))]
rw [he', add_assoc]
have hz : (∑ b ∈ s, Finsupp.single (insert a (s.erase b)) r) +
(∑ b ∈ s, Finsupp.single (insert a (s.erase b)) r) = 0 := by
ext z
exact CharTwo.add_self_eq_zero _
rw [hz, add_zero]
namespace Complex
variable (X : CoboundaryExpanders.InfiniteChains.Complex V)
instance instDecidableEqFace (n : ℕ) : DecidableEq (X.Face n) := Classical.decEq _
def IsConePoint (a : V) : Prop := ∀ σ ∈ X.faces, insert a σ ∈ X.faces
def cone (a : V) (ha : X.IsConePoint a) (n : ℕ) : X.Chains n →ₗ[k] X.Chains (n+1) :=
Finsupp.linearCombination k (fun s => if h : a ∈ s.val then 0 else
Finsupp.single ⟨insert a s.val, ha s.val s.property.1, by
rw [Finset.card_insert_of_notMem h, s.property.2]⟩ 1)
open CategoryTheory
end Complex
end
namespace Attachment
variable {V W : Type} [DecidableEq V] [DecidableEq W]
omit [DecidableEq V] in
lemma mem_supported (P : Set (Finset V)) (c : Raw V) :
c ∈ supported P ↔ ∀ s, c s ≠ 0 → s ∈ P := by
simp [supported, Finsupp.mem_supported, Set.subset_def, Finsupp.mem_support_iff]
lemma single_mem_supported {P : Set (Finset V)} {s : Finset V} (hs : s ∈ P) (a : k) :
Finsupp.single s a ∈ supported P := by
rw [mem_supported]
intro t ht
by_cases h : s = t
· simpa [← h] using hs
· exact (ht (Finsupp.single_eq_of_ne (Ne.symm h))).elim
omit [DecidableEq V] [DecidableEq W] in
lemma map_supported (T : Raw V →ₗ[k] Raw W) (P : Set (Finset V)) (Q : Set (Finset W))
(h : ∀ s ∈ P, ∀ a : k, T (Finsupp.single s a) ∈ supported Q)
(c : Raw V) (hc : c ∈ supported P) : T c ∈ supported Q := by
rw [← Finsupp.sum_single c, Finsupp.sum, map_sum]
apply Submodule.sum_mem
intro s hs
exact h s ((mem_supported P c).mp hc s (Finsupp.mem_support_iff.mp hs)) (c s)
def joinFaces (F : Finset W) (O : CoboundaryExpanders.InfiniteChains.Complex V) : Set (Finset (W ⊕ V)) :=
{s | s.toLeft ⊆ F ∧ s.toRight ∈ O.faces}
def oldFaces (F : Finset W) (O : CoboundaryExpanders.InfiniteChains.Complex V) : Set (Finset (W ⊕ V)) :=
{s | s ∈ joinFaces F O ∧ s.toLeft ≠ F}
lemma boundary_disjSum_single (A : Finset W) (B : Finset V) (a : k) :
rawBoundary (Finsupp.single (A.disjSum B) a) =
(∑ w ∈ A, Finsupp.single ((A.erase w).disjSum B) a) +
(∑ v ∈ B, Finsupp.single (A.disjSum (B.erase v)) a) := by
rw [rawBoundary_single, Finset.sum_disjSum]
simp only [erase_disjSum_inl, erase_disjSum_inr]
omit [DecidableEq V] in
lemma supported_mono {P Q : Set (Finset V)} (h : P ⊆ Q) :
supported P ≤ supported Q := by
intro c hc
rw [mem_supported] at hc ⊢
exact fun s hs => h (hc s hs)
lemma boundary_graded (P : Set (Finset V))
(hdown : ∀ {s t}, s ∈ P → t ⊆ s → t ∈ P) (n : ℕ)
(c : Raw V) (hc : c ∈ supported (graded P (n+1))) :
rawBoundary c ∈ supported (graded P n) := by
apply map_supported rawBoundary (graded P (n+1)) (graded P n) _ c hc
intro s hs a
rw [rawBoundary_single]
apply Submodule.sum_mem
intro v hv
apply single_mem_supported
refine ⟨hdown hs.1 (Finset.erase_subset v s), ?_⟩
rw [Finset.card_erase_of_mem hv, hs.2]
omega
def ExactIn (P : Set (Finset V)) (n : ℕ) : Prop :=
∀ c ∈ supported (graded P n), rawBoundary c = 0 →
∃ b ∈ supported (graded P (n+1)), rawBoundary b = c
def RelativeExactIn (P Q : Set (Finset V)) (n : ℕ) : Prop :=
∀ c ∈ supported (graded Q n), rawBoundary c ∈ supported P →
∃ b ∈ supported (graded Q (n+1)),
c - rawBoundary b ∈ supported (graded P n)
end Attachment
end CoboundaryExpanders.InfiniteChains
end
end OAI
end
section
-- module Solutions.OAIQ3_Cob.Coboundary_Cones
attribute [-instance] _root_.OAI.CoboundaryExpanders.InfiniteChains.Complex.faceMulAction
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
noncomputable section
/-!
Quantitative chain cones, face-model transport, relabeling, and exactness under retractions.
-/
section
open scoped BigOperators
namespace CoboundaryExpanders.InfiniteChains.Cone
open Attachment
variable {V W : Type} [DecidableEq V] [DecidableEq W]
omit [DecidableEq V] in
lemma twice (c : Raw V) : c + c = 0 := by
ext s
exact CharTwo.add_self_eq_zero _
lemma size_add_le (c d : Raw V) : size (c+d) ≤ size c + size d :=
(Finset.card_le_card Finsupp.support_add).trans (Finset.card_union_le _ _)
omit [DecidableEq V] in
lemma size_smul_le (a : k) (c : Raw V) : size (a • c) ≤ size c :=
Finset.card_le_card Finsupp.support_smul
omit [DecidableEq V] in
lemma size_single_le (s : Finset V) (a : k) : size (Finsupp.single s a) ≤ 1 := by
exact (Finset.card_le_card Finsupp.support_single_subset).trans (by simp)
lemma size_sum_le {ι : Type*} (S : Finset ι) (c : ι → Raw V) :
size (∑ i ∈ S, c i) ≤ ∑ i ∈ S, size (c i) :=
(Finset.card_le_card Finsupp.support_finsetSum).trans Finset.card_biUnion_le
omit [DecidableEq V] in
lemma size_map_le (T : Raw V →ₗ[k] Raw W) (P : Set (Finset V)) (C : ℕ)
(hT : ∀ s ∈ P, size (T (Finsupp.single s 1)) ≤ C)
(c : Raw V) (hc : c ∈ supported P) : size (T c) ≤ C * size c := by
conv_lhs => rw [← Finsupp.sum_single c, Finsupp.sum, map_sum]
calc
size (∑ s ∈ c.support, T (Finsupp.single s (c s))) ≤
∑ s ∈ c.support, size (T (Finsupp.single s (c s))) := size_sum_le _ _
_ ≤ ∑ _s ∈ c.support, C := by
apply Finset.sum_le_sum
intro s hs
have he : Finsupp.single s (c s) = c s • Finsupp.single s (1 : k) := by simp
rw [he, map_smul]
exact (size_smul_le _ _).trans
(hT s ((mem_supported P c).mp hc s (Finsupp.mem_support_iff.mp hs)))
_ = C * size c := by simp [size, Nat.mul_comm]
lemma size_rawCone_le (a : V) (c : Raw V) : size (rawCone a c) ≤ size c := by
have h := size_map_le (rawCone a) Set.univ 1 (fun s _ => by
rw [rawCone_single]
split_ifs
· simp
· exact size_single_le _ _) c (by rw [mem_supported]; simp)
simpa using h
lemma boundary_single_size (s : Finset V) (a : k) :
size (rawBoundary (Finsupp.single s a)) ≤ s.card := by
rw [rawBoundary_single]
calc
size (∑ v ∈ s, Finsupp.single (s.erase v) a) ≤
∑ v ∈ s, size (Finsupp.single (s.erase v) a) := size_sum_le _ _
_ ≤ ∑ _v ∈ s, 1 := Finset.sum_le_sum (fun _ _ => size_single_le _ _)
_ = s.card := by simp
omit [DecidableEq V] [DecidableEq W] in
lemma linear_eq_on_supported (A B : Raw V →ₗ[k] Raw W) (P : Set (Finset V))
(h : ∀ s ∈ P, A (Finsupp.single s 1) = B (Finsupp.single s 1))
(c : Raw V) (hc : c ∈ supported P) : A c = B c := by
conv_lhs => rw [← Finsupp.sum_single c, Finsupp.sum, map_sum]
conv_rhs => rw [← Finsupp.sum_single c, Finsupp.sum, map_sum]
apply Finset.sum_congr rfl
intro s hs
have he : Finsupp.single s (c s) = c s • Finsupp.single s (1 : k) := by simp
rw [he, map_smul, map_smul,
h s ((mem_supported P c).mp hc s (Finsupp.mem_support_iff.mp hs))]
namespace BoundedCone
variable {X : CoboundaryExpanders.InfiniteChains.Complex V} {n R : ℕ} (H : BoundedCone X n R)
lemma map_graded (r : ℕ) (hr : r ≤ n) (c : Raw V)
(hc : c ∈ supported (graded X.faces r)) :
H.hom c ∈ supported (graded X.faces (r+1)) := by
apply map_supported _ (graded X.faces r) _ _ c hc
intro s hs a
have he : Finsupp.single s a = a • Finsupp.single s (1 : k) := by simp
rw [he, map_smul]
apply Submodule.smul_mem
have h := H.support s hs.1 (hs.2.trans_le hr)
simpa only [hs.2] using h
lemma contraction_apply (r : ℕ) (hr : r ≤ n) (c : Raw V)
(hc : c ∈ supported (graded X.faces r)) :
rawBoundary (H.hom c) + H.hom (rawBoundary c) = c := by
apply linear_eq_on_supported
(rawBoundary.comp H.hom + H.hom.comp rawBoundary) LinearMap.id
(graded X.faces r) _ c hc
intro s hs
exact H.contraction s hs.1 (hs.2.trans_le hr)
lemma size_apply (r : ℕ) (hr : r ≤ n) (c : Raw V)
(hc : c ∈ supported (graded X.faces r)) : size (H.hom c) ≤ R * size c :=
size_map_le H.hom (graded X.faces r) R
(fun s hs => H.bound s hs.1 (hs.2.trans_le hr)) c hc
lemma newCycle_supported (s : Finset V) (hs : s ∈ X.faces) (hr : s.card = n+1) :
Finsupp.single s 1 + H.hom (rawBoundary (Finsupp.single s 1)) ∈
supported (graded X.faces (n+1)) := by
apply Submodule.add_mem
· exact single_mem_supported (P := graded X.faces (n+1)) ⟨hs, hr⟩ _
· apply H.map_graded n le_rfl
apply boundary_graded X.faces (fun {_ _} hs h => X.downward hs h) n
exact single_mem_supported (P := graded X.faces (n+1)) ⟨hs, hr⟩ _
lemma newCycle_cycle (s : Finset V) (hs : s ∈ X.faces) (hr : s.card = n+1) :
rawBoundary (Finsupp.single s 1 + H.hom (rawBoundary (Finsupp.single s 1))) = 0 := by
have hb : rawBoundary (Finsupp.single s 1) ∈ supported (graded X.faces n) := by
apply boundary_graded X.faces (fun {_ _} hs h => X.downward hs h) n
exact single_mem_supported (P := graded X.faces (n+1)) ⟨hs, hr⟩ _
have hd := LinearMap.congr_fun (rawBoundary_squared (V := V)) (Finsupp.single s 1)
have hh := H.contraction_apply n le_rfl _ hb
rw [show rawBoundary (rawBoundary (Finsupp.single s 1)) = 0 from hd, map_zero, add_zero] at hh
rw [map_add, hh, twice]
lemma newCycle_size (s : Finset V) (hs : s ∈ X.faces) (hr : s.card = n+1) :
size (Finsupp.single s 1 + H.hom (rawBoundary (Finsupp.single s 1))) ≤ 1+R*(n+1) := by
have hb : rawBoundary (Finsupp.single s 1) ∈ supported (graded X.faces n) := by
apply boundary_graded X.faces (fun {_ _} hs h => X.downward hs h) n
exact single_mem_supported (P := graded X.faces (n+1)) ⟨hs, hr⟩ _
exact (size_add_le _ _).trans (Nat.add_le_add (size_single_le _ _)
((H.size_apply n le_rfl _ hb).trans
(Nat.mul_le_mul_left R (by simpa [hr] using boundary_single_size s (1 : k)))))
noncomputable def extend (S : ℕ)
(fill : ∀ c : Raw V, c ∈ supported (graded X.faces (n+1)) →
rawBoundary c = 0 → size c ≤ 1+R*(n+1) →
∃ b : Raw V, b ∈ supported (graded X.faces (n+2)) ∧
rawBoundary b = c ∧ size b ≤ S) : BoundedCone X (n+1) (max R S) := by
classical
let z (s : Finset V) := Finsupp.single s 1 + H.hom (rawBoundary (Finsupp.single s 1))
have hex (s : Finset V) (hs : s ∈ X.faces ∧ s.card = n+1) :
∃ b : Raw V, b ∈ supported (graded X.faces (n+2)) ∧
rawBoundary b = z s ∧ size b ≤ S :=
fill (z s) (H.newCycle_supported s hs.1 hs.2)
(H.newCycle_cycle s hs.1 hs.2) (H.newCycle_size s hs.1 hs.2)
let f (s : Finset V) : Raw V :=
if hs : s ∈ X.faces ∧ s.card = n+1 then (hex s hs).choose
else H.hom (Finsupp.single s 1)
let T : Raw V →ₗ[k] Raw V := Finsupp.linearCombination k f
have hT (s : Finset V) : T (Finsupp.single s 1) = f s := by simp [T]
have hold (s : Finset V) (hs : s.card ≤ n) :
T (Finsupp.single s 1) = H.hom (Finsupp.single s 1) := by
rw [hT]
simp only [f, dite_eq_right (show ¬(s ∈ X.faces ∧ s.card = n+1) from by omega)]
have hboundary (s : Finset V) (hs : s.card ≤ n+1) :
T (rawBoundary (Finsupp.single s 1)) = H.hom (rawBoundary (Finsupp.single s 1)) := by
rw [rawBoundary_single, map_sum, map_sum]
apply Finset.sum_congr rfl
intro v hv
apply hold
rw [Finset.card_erase_of_mem hv]
omega
refine ⟨T, ?_, ?_, ?_⟩
· intro s hs hn
by_cases he : s.card = n+1
· rw [hT]
have hspec := (hex s ⟨hs, he⟩).choose_spec.1
dsimp only [f]
rw [dite_eq_left (show s ∈ X.faces ∧ s.card = n+1 from ⟨hs, he⟩)]
simpa only [he, Nat.add_assoc] using hspec
· rw [hold s (by omega)]
exact H.support s hs (by omega)
· intro s hs hn
rw [hboundary s hn]
by_cases he : s.card = n+1
· rw [hT]
have hb : rawBoundary (f s) = z s := by
dsimp only [f]
rw [dite_eq_left (show s ∈ X.faces ∧ s.card = n+1 from ⟨hs, he⟩)]
exact (hex s ⟨hs, he⟩).choose_spec.2.1
rw [hb]
dsimp [z]
rw [add_assoc, twice, add_zero]
· rw [hold s (by omega)]
exact H.contraction s hs (by omega)
· intro s hs hn
by_cases he : s.card = n+1
· rw [hT]
have hb : size (f s) ≤ S := by
dsimp only [f]
rw [dite_eq_left (show s ∈ X.faces ∧ s.card = n+1 from ⟨hs, he⟩)]
exact (hex s ⟨hs, he⟩).choose_spec.2.2
exact hb.trans (Nat.le_max_right _ _)
· rw [hold s (by omega)]
exact (H.bound s hs (by omega)).trans (Nat.le_max_left _ _)
noncomputable def initial (X : CoboundaryExpanders.InfiniteChains.Complex V) (a : V) (ha : {a} ∈ X.faces) :
BoundedCone X 0 1 where
hom := rawCone a
support := by
intro s hs hn
have he : s = ∅ := Finset.card_eq_zero.mp (Nat.eq_zero_of_le_zero hn)
subst s
simpa [rawCone_single] using
(single_mem_supported (P := graded X.faces 1) ⟨ha, by simp⟩ (1 : k))
contraction := by
intro s _ _
exact LinearMap.congr_fun (raw_contraction a) (Finsupp.single s 1)
bound := by
intro s _ _
exact (size_rawCone_le _ _).trans (size_single_le _ _)
end BoundedCone
def vertices (c : Raw V) : Finset V := c.support.biUnion id
def allowed (X : CoboundaryExpanders.InfiniteChains.Complex V) (bad : V → Prop) (A : Finset V) : CoboundaryExpanders.InfiniteChains.Complex V where
faces := {s | s ∈ X.faces ∧ ∀ v ∈ s, bad v → v ∈ A}
empty_mem := ⟨X.empty_mem, by simp⟩
downward := fun hs hts => ⟨X.downward hs.1 hts, fun v hv => hs.2 v (hts hv)⟩
omit [DecidableEq V] in
lemma relabel_size (f : V → W) (c : Raw V) : size (relabel f c) ≤ size c := by
have h := size_map_le (relabel f) Set.univ 1 (fun s _ => by
rw [relabel_single]; exact size_single_le _ _) c (by rw [mem_supported]; simp)
simpa using h
omit [DecidableEq V] in
lemma relabel_supported (f : V → W) (P : Set (Finset V)) (Q : Set (Finset W))
(h : ∀ s ∈ P, s.image f ∈ Q) (c : Raw V) (hc : c ∈ supported P) :
relabel f c ∈ supported Q := by
apply map_supported _ P Q _ c hc
intro s hs a
rw [relabel_single]
exact single_mem_supported (h s hs) a
omit [DecidableEq V] in
lemma relabel_graded (f : V → W) (P : Set (Finset V)) (Q : Set (Finset W)) (r : ℕ)
(h : ∀ s ∈ P, s.image f ∈ Q)
(hinj : ∀ s ∈ P, Set.InjOn f (s : Set V))
(c : Raw V) (hc : c ∈ supported (graded P r)) :
relabel f c ∈ supported (graded Q r) := by
apply relabel_supported f (graded P r) (graded Q r) _ c hc
intro s hs
exact ⟨h s hs.1, (Finset.card_image_of_injOn (hinj s hs.1)).trans hs.2⟩
lemma relabel_boundary (f : V → W) (hf : Function.Injective f) :
rawBoundary.comp (relabel f) = (relabel f).comp rawBoundary := by
apply Finsupp.lhom_ext'
intro s
apply LinearMap.ext
intro a
simp only [LinearMap.comp_apply, Finsupp.lsingle_apply, relabel_single,
rawBoundary_single, map_sum, Finset.sum_image, hf.injOn]
apply Finset.sum_congr rfl
intro v hv
rw [Finset.image_erase hf]
lemma relabel_retraction (f : V → W) (g : W → V) (P : Set (Finset W))
(h : ∀ s ∈ P, ∀ w ∈ s, f (g w) = w)
(c : Raw W) (hc : c ∈ supported P) : relabel f (relabel g c) = c := by
apply linear_eq_on_supported ((relabel f).comp (relabel g)) LinearMap.id P _ c hc
intro s hs
simp only [LinearMap.comp_apply, relabel_single, LinearMap.id_apply]
congr 1
rw [Finset.image_image]
calc
s.image (f ∘ g) = s.image id := Finset.image_congr (fun w hw => h s hs w hw)
_ = s := Finset.image_id
end CoboundaryExpanders.InfiniteChains.Cone
open scoped BigOperators
open scoped BigOperators Matrix
open scoped Matrix
namespace CoboundaryExpanders.InfiniteChains.Cone
open Attachment
variable {V W : Type} [DecidableEq V] [DecidableEq W]
omit [DecidableEq W] in
lemma unlabel_size (f : V → W) (hf : Function.Injective f) (c : Raw W) :
size (unlabel f hf c) ≤ size c := by
have h := size_map_le (unlabel f hf) Set.univ 1 (fun s _ => by
rw [unlabel_single]; exact size_single_le _ _) c (by rw [mem_supported]; simp)
simpa using h
namespace FaceModel
variable {X : CoboundaryExpanders.InfiniteChains.Complex V} {Y : CoboundaryExpanders.InfiniteChains.Complex W} (M : FaceModel X Y)
omit [DecidableEq V] in
lemma unlabel_face (t : Finset W) (ht : t ∈ Y.faces) :
t.preimage M.vertex M.injective.injOn ∈ X.faces ∧
(t.preimage M.vertex M.injective.injOn).image M.vertex = t ∧
(t.preimage M.vertex M.injective.injOn).card = t.card := by
obtain ⟨s,hs,he⟩ := M.cover t ht
subst t
rw [preimage_image M.vertex M.injective s]
exact ⟨hs,rfl,(Finset.card_image_of_injective s M.injective).symm⟩
lemma unlabel_graded (r : ℕ) (c : Raw W) (hc : c ∈ supported (graded Y.faces r)) :
unlabel M.vertex M.injective c ∈ supported (graded X.faces r) := by
apply map_supported _ (graded Y.faces r) (graded X.faces r) _ c hc
intro t ht a
rw [unlabel_single]
have hh := M.unlabel_face t ht.1
exact single_mem_supported (P := graded X.faces r) ⟨hh.1,hh.2.2.trans ht.2⟩ a
lemma unlabel_boundary (c : Raw W) (hc : c ∈ supported Y.faces) :
unlabel M.vertex M.injective (rawBoundary c) =
rawBoundary (unlabel M.vertex M.injective c) := by
apply linear_eq_on_supported ((unlabel M.vertex M.injective).comp rawBoundary)
(rawBoundary.comp (unlabel M.vertex M.injective)) Y.faces _ c hc
intro t ht
obtain ⟨s,hs,he⟩ := M.cover t ht
subst t
rw [← relabel_single M.vertex s 1]
change unlabel M.vertex M.injective (rawBoundary (relabel M.vertex (Finsupp.single s 1))) = _
have hb := LinearMap.congr_fun (Cone.relabel_boundary M.vertex M.injective) (Finsupp.single s 1)
change rawBoundary (relabel M.vertex (Finsupp.single s 1)) =
relabel M.vertex (rawBoundary (Finsupp.single s 1)) at hb
simp only [LinearMap.comp_apply] at *
rw [hb,unlabel_relabel,unlabel_relabel]
def pullCone {n R : ℕ} (H : BoundedCone Y n R) : BoundedCone X n R where
hom := (unlabel M.vertex M.injective).comp (H.hom.comp (relabel M.vertex))
support := by
intro s hs hn
change unlabel M.vertex M.injective (H.hom (relabel M.vertex (Finsupp.single s 1))) ∈ _
rw [relabel_single]
have hc := Finset.card_image_of_injective s M.injective
have hh := H.support (s.image M.vertex) ((M.face_iff s).mpr hs) (hc.trans_le hn)
rw [hc] at hh
exact M.unlabel_graded (s.card+1) _ hh
contraction := by
intro s hs hn
have hc := Finset.card_image_of_injective s M.injective
have hin := (M.face_iff s).mpr hs
have hsupport := H.support (s.image M.vertex) hin (hc.trans_le hn)
have hplain := supported_mono (P := graded Y.faces ((s.image M.vertex).card+1))
(Q := Y.faces) (fun _ ht => ht.1) hsupport
have hh := congrArg (unlabel M.vertex M.injective)
(H.contraction (s.image M.vertex) hin (hc.trans_le hn))
rw [map_add,M.unlabel_boundary _ hplain] at hh
have hb := LinearMap.congr_fun (Cone.relabel_boundary M.vertex M.injective) (Finsupp.single s 1)
change rawBoundary (relabel M.vertex (Finsupp.single s 1)) =
relabel M.vertex (rawBoundary (Finsupp.single s 1)) at hb
rw [relabel_single] at hb
rw [hb,unlabel_single,preimage_image M.vertex M.injective s] at hh
simpa only [LinearMap.comp_apply,relabel_single] using hh
bound := by
intro s hs hn
change size (unlabel M.vertex M.injective (H.hom (relabel M.vertex (Finsupp.single s 1)))) ≤ _
apply (unlabel_size _ _ _).trans
rw [relabel_single]
exact H.bound (s.image M.vertex) ((M.face_iff s).mpr hs)
((Finset.card_image_of_injective s M.injective).trans_le hn)
def pushCone {n R : ℕ} (H : BoundedCone X n R) : BoundedCone Y n R where
hom := (relabel M.vertex).comp (H.hom.comp (unlabel M.vertex M.injective))
support := by
intro t ht hn
obtain ⟨s,hs,he⟩ := M.cover t ht
subst t
rw [Finset.card_image_of_injective s M.injective] at hn ⊢
change relabel M.vertex (H.hom (unlabel M.vertex M.injective (Finsupp.single (s.image M.vertex) 1))) ∈ _
rw [unlabel_single,preimage_image M.vertex M.injective s]
exact Cone.relabel_graded M.vertex X.faces Y.faces (s.card+1)
(fun a ha => (M.face_iff a).mpr ha) (fun _ _ => M.injective.injOn)
_ (H.support s hs hn)
contraction := by
intro t ht hn
obtain ⟨s,hs,he⟩ := M.cover t ht
subst t
rw [Finset.card_image_of_injective s M.injective] at hn
change rawBoundary (relabel M.vertex (H.hom (unlabel M.vertex M.injective (Finsupp.single (s.image M.vertex) 1)))) +
relabel M.vertex (H.hom (unlabel M.vertex M.injective (rawBoundary (Finsupp.single (s.image M.vertex) 1)))) = _
rw [←relabel_single,unlabel_relabel]
have hb (c : Raw V) := LinearMap.congr_fun (Cone.relabel_boundary M.vertex M.injective) c
change ∀ c : Raw V, rawBoundary (relabel M.vertex c) = relabel M.vertex (rawBoundary c) at hb
rw [hb,hb,unlabel_relabel,←map_add,H.contraction s hs hn]
bound := by
intro t ht hn
obtain ⟨s,hs,he⟩ := M.cover t ht
subst t
rw [Finset.card_image_of_injective s M.injective] at hn
change size (relabel M.vertex (H.hom (unlabel M.vertex M.injective (Finsupp.single (s.image M.vertex) 1)))) ≤ _
rw [unlabel_single,preimage_image M.vertex M.injective s]
exact (relabel_size _ _).trans (H.bound s hs hn)
end FaceModel
end CoboundaryExpanders.InfiniteChains.Cone
end
section
open scoped BigOperators
open scoped BigOperators Matrix
open scoped Matrix
open scoped BigOperators InnerProductSpace
namespace CoboundaryExpanders.InfiniteChains.Cone
open Attachment
variable {V : Type} [DecidableEq V]
attribute [local instance] Classical.propDecidable
def VertexPath (X : CoboundaryExpanders.InfiniteChains.Complex V) (x y : V) : Prop :=
Relation.ReflTransGen (fun a b => ({a,b}:Finset V) ∈ X.faces) x y
end CoboundaryExpanders.InfiniteChains.Cone
end
open scoped Polynomial BigOperators
namespace CoboundaryExpanders.InfiniteChains.Cone
section
open Attachment
variable {V W : Type} [DecidableEq V] [DecidableEq W]
lemma relabel_boundary_on (f : V → W) (P : Set (Finset V))
(hf : ∀ s ∈ P, Set.InjOn f (s : Set V))
(c : Raw V) (hc : c ∈ supported P) :
rawBoundary (relabel f c) = relabel f (rawBoundary c) := by
apply linear_eq_on_supported (rawBoundary.comp (relabel f)) ((relabel f).comp rawBoundary) P _ c hc
intro s hs
simp only [LinearMap.comp_apply,relabel_single,rawBoundary_single,map_sum]
rw [Finset.sum_image]
· apply Finset.sum_congr rfl
intro v hv
rw [image_erase_of_injOn f s (hf s hs) v hv]
· exact hf s hs
noncomputable def BoundedCone.retract {X : CoboundaryExpanders.InfiniteChains.Complex V} {Y : CoboundaryExpanders.InfiniteChains.Complex W} {n R : ℕ}
(H : BoundedCone Y n R) (f : V → W) (g : W → V)
(hf : ∀ s ∈ X.faces, s.image f ∈ Y.faces)
(hg : ∀ s ∈ Y.faces, s.image g ∈ X.faces)
(hfi : ∀ s ∈ X.faces, Set.InjOn f (s : Set V))
(hgi : ∀ s ∈ Y.faces, Set.InjOn g (s : Set W))
(hret : ∀ s ∈ X.faces, ∀ v ∈ s, g (f v) = v) : BoundedCone X n R where
hom := (relabel g).comp (H.hom.comp (relabel f))
support := by
intro s hs hn
have hcard : (s.image f).card = s.card := Finset.card_image_of_injOn (hfi s hs)
have hH := H.support (s.image f) (hf s hs) (hcard.trans_le hn)
simpa only [LinearMap.comp_apply,relabel_single,hcard] using
relabel_graded g Y.faces X.faces ((s.image f).card+1) hg hgi _ hH
contraction := by
intro s hs hn
have hcard : (s.image f).card = s.card := Finset.card_image_of_injOn (hfi s hs)
have hH := H.support (s.image f) (hf s hs) (hcard.trans_le hn)
have hb := relabel_boundary_on g (graded Y.faces ((s.image f).card+1))
(fun t ht => hgi t ht.1) _ hH
have hc := congrArg (relabel g) (H.contraction (s.image f) (hf s hs) (hcard.trans_le hn))
have hbf := relabel_boundary_on f X.faces hfi (Finsupp.single s 1) (single_mem_supported hs 1)
simp only [LinearMap.comp_apply,relabel_single] at hbf ⊢
rw [hb,← hbf,← map_add,hc]
simpa only [relabel_single] using relabel_retraction g f X.faces hret _ (single_mem_supported hs 1)
bound := by
intro s hs hn
simp only [LinearMap.comp_apply,relabel_single]
apply (relabel_size g _).trans
exact H.bound (s.image f) (hf s hs) ((Finset.card_image_of_injOn (hfi s hs)).trans_le hn)
end
open Attachment
end CoboundaryExpanders.InfiniteChains.Cone
end
end OAI
end
section
-- module Solutions.OAIQ3_Cob.Coboundary_Joins
attribute [-instance] _root_.OAI.CoboundaryExpanders.InfiniteChains.Complex.faceMulAction
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
noncomputable section
/-!
Binary and finite joins, augmented exactness, and bounded cone constructions.
-/
section
open scoped BigOperators
open scoped BigOperators Matrix
open scoped Matrix
namespace CoboundaryExpanders.InfiniteChains.Join
section
open Attachment Cone
variable {V W : Type} [DecidableEq V] [DecidableEq W]
def complex (X : CoboundaryExpanders.InfiniteChains.Complex W) (Y : CoboundaryExpanders.InfiniteChains.Complex V) : CoboundaryExpanders.InfiniteChains.Complex (W ⊕ V) where
faces := {s | s.toLeft ∈ X.faces ∧ s.toRight ∈ Y.faces}
empty_mem := by simpa [Finset.toLeft, Finset.toRight] using And.intro X.empty_mem Y.empty_mem
downward := by
intro s t hs ht
exact ⟨X.downward hs.1 (by intro x hx; simpa using ht (by simpa using hx : Sum.inl x ∈ t)),
Y.downward hs.2 (by intro x hx; simpa using ht (by simpa using hx : Sum.inr x ∈ t))⟩
end
open Attachment Cone
variable {V W : Type} [DecidableEq V] [DecidableEq W]
def truncated (X : CoboundaryExpanders.InfiniteChains.Complex W) (Y : CoboundaryExpanders.InfiniteChains.Complex V) (M : ℕ) : Set (Finset (W ⊕ V)) :=
{s | s ∈ (complex X Y).faces ∧ s.toLeft.card ≤ M}
end CoboundaryExpanders.InfiniteChains.Join
namespace CoboundaryExpanders.InfiniteChains.Cone.BoundedCone
open Attachment
variable {V : Type} [DecidableEq V] {X : CoboundaryExpanders.InfiniteChains.Complex V} {n R : ℕ}
lemma cut_boundary (H : BoundedCone X n R) (s : Finset V) (hs : s.card ≤ n+1) :
H.cut (rawBoundary (Finsupp.single s 1)) = H.hom (rawBoundary (Finsupp.single s 1)) := by
simp only [rawBoundary_single, map_sum]
apply Finset.sum_congr rfl
intro v hv
rw [cut_single, ite_eq_left]
rw [Finset.card_erase_of_mem hv]
omega
def normalize (H : BoundedCone X n R) : BoundedCone X n R where
hom := H.cut
support := by
intro s hs hn
rw [cut_single, ite_eq_left hn]
exact H.support s hs hn
contraction := by
intro s hs hn
rw [cut_single, ite_eq_left hn, cut_boundary H s (by omega)]
exact H.contraction s hs hn
bound := by
intro s hs hn
rw [cut_single, ite_eq_left hn]
exact H.bound s hs hn
end CoboundaryExpanders.InfiniteChains.Cone.BoundedCone
namespace CoboundaryExpanders.InfiniteChains.Join
section
open Attachment Cone
variable {V W : Type} [DecidableEq V] [DecidableEq W]
omit [DecidableEq V] [DecidableEq W] in
lemma cross_add_left (c e : Raw W) (d : Raw V) : cross (c+e) d = cross c d + cross e d := by
simp [cross]
omit [DecidableEq V] [DecidableEq W] in
lemma cross_add_right (c : Raw W) (d e : Raw V) : cross c (d+e) = cross c d + cross c e := by
simp [cross]
omit [DecidableEq V] [DecidableEq W] in
lemma cross_sum_left {ι : Type*} (I : Finset ι) (c : ι → Raw W) (d : Raw V) :
cross (∑ i ∈ I, c i) d = ∑ i ∈ I, cross (c i) d := by simp [cross]
omit [DecidableEq V] [DecidableEq W] in
lemma cross_sum_right {ι : Type*} (I : Finset ι) (c : Raw W) (d : ι → Raw V) :
cross c (∑ i ∈ I, d i) = ∑ i ∈ I, cross c (d i) := by simp [cross]
lemma cross_boundary (c : Raw W) (d : Raw V) :
rawBoundary (cross c d) = cross (rawBoundary c) d + cross c (rawBoundary d) := by
induction c using Finsupp.induction_linear with
| zero => simp
| add c e hc he =>
simp only [cross_add_left, map_add, hc, he]
abel
| single A a =>
induction d using Finsupp.induction_linear with
| zero => simp
| add d e hd he =>
simp only [cross_add_right, map_add, hd, he]
abel
| single B b =>
simp only [map_smul, rawBoundary_single, cross_single_right, cross_sum_right]
simp [prepend_single, map_sum, Finset.smul_sum, mul_comm,
erase_disjSum_inl, erase_disjSum_inr]
lemma cross_graded (X : CoboundaryExpanders.InfiniteChains.Complex W) (Y : CoboundaryExpanders.InfiniteChains.Complex V) (a b : ℕ) (c : Raw W) (d : Raw V)
(hc : c ∈ supported (graded X.faces a)) (hd : d ∈ supported (graded Y.faces b)) :
cross c d ∈ supported (graded (complex X Y).faces (a+b)) := by
let T : Raw W →ₗ[k] Raw (W ⊕ V) := (LinearMap.applyₗ (R := k) d).comp crossLinear
change T c ∈ _
apply map_supported T _ _ _ c hc
intro A hA z
change cross (Finsupp.single A z) d ∈ _
rw [cross_single_left]
apply Submodule.smul_mem
apply map_supported (append A) (graded Y.faces b) _ _ d hd
intro B hB t
rw [append_single]
exact single_mem_supported (P := graded (complex X Y).faces (a+b)) ⟨⟨by simpa using hA.1, by simpa using hB.1⟩,
by rw [Finset.card_disjSum, hA.2, hB.2]⟩ t
lemma cross_size (c : Raw W) (d : Raw V) : size (cross c d) ≤ size c * size d := by
let T : Raw W →ₗ[k] Raw (W ⊕ V) := (LinearMap.applyₗ (R := k) d).comp crossLinear
have hT (A : Finset W) (_ : A ∈ Set.univ) : size (T (Finsupp.single A 1)) ≤ size d := by
change size (cross (Finsupp.single A 1) d) ≤ _
rw [cross_single_left, one_smul]
exact (size_map_le (append A) Set.univ 1 (fun B _ => by simpa using size_single_le (A.disjSum B) (1 : k))
d (by rw [mem_supported]; simp)).trans_eq (by omega)
exact (size_map_le T Set.univ (size d) hT c (by rw [mem_supported]; simp)).trans_eq (Nat.mul_comm _ _)
lemma operator_boundary (T : Raw W →ₗ[k] Raw W) (U : Raw V →ₗ[k] Raw V)
(A : Finset W) (B : Finset V) :
operator T U (rawBoundary (Finsupp.single (A.disjSum B) 1)) =
cross (T (rawBoundary (Finsupp.single A 1))) (U (Finsupp.single B 1)) +
cross (T (Finsupp.single A 1)) (U (rawBoundary (Finsupp.single B 1))) := by
rw [boundary_disjSum_single, map_add, map_sum, map_sum]
simp only [operator_single, rawBoundary_single, map_sum, cross_sum_left, cross_sum_right]
def residual (T : Raw V →ₗ[k] Raw V) : Raw V →ₗ[k] Raw V :=
LinearMap.id + rawBoundary.comp T + T.comp rawBoundary
lemma residual_eq (T : Raw V →ₗ[k] Raw V) (c : Raw V) :
residual T c = c + rawBoundary (T c) + T (rawBoundary c) := rfl
lemma residual_boundary (T : Raw V →ₗ[k] Raw V) (c : Raw V) :
rawBoundary (residual T c) = residual T (rawBoundary c) := by
have hh (x : Raw V) : rawBoundary (rawBoundary x) = 0 :=
LinearMap.congr_fun (rawBoundary_squared (V := V)) x
simp [residual_eq, map_add, hh]
def joinHom (T : Raw W →ₗ[k] Raw W) (U : Raw V →ₗ[k] Raw V) :
Raw (W ⊕ V) →ₗ[k] Raw (W ⊕ V) :=
operator T LinearMap.id + operator (residual T) U
lemma joinHom_contraction (T : Raw W →ₗ[k] Raw W) (U : Raw V →ₗ[k] Raw V)
(A : Finset W) (B : Finset V) :
rawBoundary (joinHom T U (Finsupp.single (A.disjSum B) 1)) +
joinHom T U (rawBoundary (Finsupp.single (A.disjSum B) 1)) =
Finsupp.single (A.disjSum B) 1 +
cross (residual T (Finsupp.single A 1)) (residual U (Finsupp.single B 1)) := by
simp only [joinHom, LinearMap.add_apply, operator_single, map_add, cross_boundary,
LinearMap.id_apply, operator_boundary, residual_boundary]
rw [residual_eq U, cross_add_right, cross_add_right]
have he := residual_eq T (Finsupp.single A 1)
have he' := congrArg (fun x => cross x (Finsupp.single B 1)) he
rw [cross_add_left, cross_add_left] at he'
have h0 : cross (Finsupp.single A 1) (Finsupp.single B 1) = Finsupp.single (A.disjSum B) 1 := by simp
rw [h0] at he'
have h2 (x : Raw (W ⊕ V)) : x+x = 0 := twice x
rw [he']
abel_nf
simp only [two_smul ℤ, twice, zero_add, add_zero]
end
open Attachment Cone
variable {V W : Type} [DecidableEq V] [DecidableEq W]
lemma cut_boundary_high {X : CoboundaryExpanders.InfiniteChains.Complex V} {n R : ℕ} (H : BoundedCone X n R)
(s : Finset V) (hs : n+1 < s.card) : H.cut (rawBoundary (Finsupp.single s 1)) = 0 := by
rw [rawBoundary_single, map_sum]
apply Finset.sum_eq_zero
intro v hv
rw [BoundedCone.cut_single, ite_eq_right]
rw [Finset.card_erase_of_mem hv]
omega
lemma residual_cut_low {X : CoboundaryExpanders.InfiniteChains.Complex V} {n R : ℕ} (H : BoundedCone X n R)
(s : Finset V) (hs : s ∈ X.faces) (hn : s.card ≤ n) :
residual H.cut (Finsupp.single s 1) = 0 := by
rw [residual_eq, add_assoc]
have he := H.normalize.contraction s hs hn
change rawBoundary (H.cut (Finsupp.single s 1)) + H.cut (rawBoundary (Finsupp.single s 1)) = _ at he
rw [he, twice]
lemma residual_cut_graded {X : CoboundaryExpanders.InfiniteChains.Complex V} {n R : ℕ} (H : BoundedCone X n R)
(s : Finset V) (hs : s ∈ X.faces) :
residual H.cut (Finsupp.single s 1) ∈ supported (graded X.faces s.card) := by
by_cases hn : s.card ≤ n
· rw [residual_cut_low H s hs hn]
exact Submodule.zero_mem _
rw [residual_eq, BoundedCone.cut_single, ite_eq_right hn, map_zero, add_zero]
apply Submodule.add_mem _ (single_mem_supported (P := graded X.faces s.card) ⟨hs, rfl⟩ _)
by_cases he : s.card = n+1
· rw [H.cut_boundary s (by omega)]
rw [he]
apply H.map_graded n le_rfl
apply boundary_graded X.faces (fun {_ _} ht h => X.downward ht h) n
exact single_mem_supported (P := graded X.faces (n+1)) ⟨hs, he⟩ _
· rw [cut_boundary_high H s (by omega)]
exact Submodule.zero_mem _
lemma residual_cut_size {X : CoboundaryExpanders.InfiniteChains.Complex V} {n R : ℕ} (H : BoundedCone X n R)
(s : Finset V) (hs : s ∈ X.faces) :
size (residual H.cut (Finsupp.single s 1)) ≤ 1+R*(n+1) := by
by_cases hn : s.card ≤ n
· rw [residual_cut_low H s hs hn, size_zero]
omega
rw [residual_eq, BoundedCone.cut_single, ite_eq_right hn, map_zero, add_zero]
by_cases he : s.card = n+1
· have hb : rawBoundary (Finsupp.single s 1) ∈ supported (graded X.faces n) := by
apply boundary_graded X.faces (fun {_ _} ht h => X.downward ht h) n
exact single_mem_supported (P := graded X.faces (n+1)) ⟨hs, he⟩ _
rw [H.cut_boundary s (by omega)]
exact (size_add_le _ _).trans (Nat.add_le_add (size_single_le s (1 : k))
((H.size_apply n le_rfl _ hb).trans (Nat.mul_le_mul_left R (by simpa [he] using boundary_single_size s (1 : k)))))
· rw [cut_boundary_high H s (by omega), add_zero]
exact (size_single_le s (1 : k)).trans (by omega)
def boundedCone {X : CoboundaryExpanders.InfiniteChains.Complex W} {Y : CoboundaryExpanders.InfiniteChains.Complex V} {n m R S : ℕ}
(H : BoundedCone X n R) (K : BoundedCone Y m S) :
BoundedCone (complex X Y) (n+m+1) (max R ((1+R*(n+1))*S)) where
hom := joinHom H.cut K.cut
support := by
intro s hs hn
rw [← Finset.toLeft_disjSum_toRight (u := s)]
simp only [joinHom, LinearMap.add_apply, operator_single, LinearMap.id_apply]
by_cases hA : s.toLeft.card ≤ n
· rw [residual_cut_low H s.toLeft hs.1 hA, cross_zero_left, add_zero]
have hg := cross_graded X Y (s.toLeft.card+1) s.toRight.card
(H.cut (Finsupp.single s.toLeft 1)) (Finsupp.single s.toRight 1)
(H.normalize.support s.toLeft hs.1 hA) (single_mem_supported (P := graded Y.faces s.toRight.card) ⟨hs.2, rfl⟩ _)
convert hg using 1
all_goals try with_reducible_and_instances rfl
simp [Finset.card_disjSum, Nat.add_assoc, Nat.add_comm, Nat.add_left_comm]
· have hB : s.toRight.card ≤ m := by
have hcard := Finset.card_toLeft_add_card_toRight (u := s)
omega
rw [BoundedCone.cut_single, ite_eq_right hA, cross_zero_left, zero_add]
have hg := cross_graded X Y s.toLeft.card (s.toRight.card+1)
(residual H.cut (Finsupp.single s.toLeft 1)) (K.cut (Finsupp.single s.toRight 1))
(residual_cut_graded H s.toLeft hs.1) (K.normalize.support s.toRight hs.2 hB)
convert hg using 1
all_goals try with_reducible_and_instances rfl
simp [Finset.card_disjSum, Nat.add_assoc]
contraction := by
intro s hs hn
rw [← Finset.toLeft_disjSum_toRight (u := s), joinHom_contraction]
by_cases hA : s.toLeft.card ≤ n
· rw [residual_cut_low H s.toLeft hs.1 hA, cross_zero_left, add_zero]
· have hB : s.toRight.card ≤ m := by
have hcard := Finset.card_toLeft_add_card_toRight (u := s)
omega
rw [residual_cut_low K s.toRight hs.2 hB, cross_zero_right, add_zero]
bound := by
intro s hs hn
rw [← Finset.toLeft_disjSum_toRight (u := s)]
simp only [joinHom, LinearMap.add_apply, operator_single, LinearMap.id_apply]
by_cases hA : s.toLeft.card ≤ n
· rw [residual_cut_low H s.toLeft hs.1 hA, cross_zero_left, add_zero]
exact ((cross_size _ _).trans (Nat.mul_le_mul
(H.normalize.bound s.toLeft hs.1 hA) (size_single_le s.toRight (1 : k)))).trans
(by simp)
· have hB : s.toRight.card ≤ m := by
have hcard := Finset.card_toLeft_add_card_toRight (u := s)
omega
rw [BoundedCone.cut_single, ite_eq_right hA, cross_zero_left, zero_add]
exact ((cross_size _ _).trans (Nat.mul_le_mul (residual_cut_size H s.toLeft hs.1)
(K.normalize.bound s.toRight hs.2 hB))).trans (Nat.le_max_right _ _)
end CoboundaryExpanders.InfiniteChains.Join
end
open scoped Polynomial BigOperators
namespace CoboundaryExpanders.InfiniteChains.Join
section
open Attachment Cone
open scoped BigOperators
variable {V : Type} [DecidableEq V]
def finiteComplex {L : ℕ} (X : Fin L → CoboundaryExpanders.InfiniteChains.Complex V) : InfiniteChains.Complex (Fin L × V) where
faces := {s | ∀ i, fiber s i ∈ (X i).faces}
empty_mem := by intro i; simpa only [fiber,Finset.filter_empty,Finset.image_empty] using (X i).empty_mem
downward := by
intro s t hs hts i
apply (X i).downward (hs i)
intro v hv
rw [mem_fiber] at hv ⊢
exact hts hv
end
open Attachment Cone
open scoped BigOperators
end CoboundaryExpanders.InfiniteChains.Join
end
end OAI
end
section
-- module Solutions.OAIQ3_Cob.Congruence_Basic
attribute [-instance] _root_.OAI.CoboundaryExpanders.Blocks.gammaNormal _root_.OAI.CoboundaryExpanders.CongruenceFrames.invariant
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
/-!
Polynomial congruence groups, truncation ideals, and finite nilpotent quotients.
-/
noncomputable section
open scoped BigOperators
open scoped BigOperators Matrix
namespace CoboundaryExpanders.Construction
section
instance normalDeeper (p a m n : ℕ) : (deeperCongruence p a m n).Normal :=
MonoidHom.normal_ker _
end
variable (p n : ℕ) [Fact p.Prime]
def uLocalEmbedding (hn : 1 ≤ n) (cut : Fin (n + 1)) :
uLocalGroup p n hn cut ↪ localGroup p n hn cut where
toFun g := ⟨g.val.val, g.property⟩
inj' := by
intro g h he
have hv : g.val.val = h.val.val := congrArg
(fun x : localGroup p n hn cut => (x : Matrix.SpecialLinearGroup (Fin (n + 1)) (R p))) he
exact Subtype.ext (Subtype.ext hv)
instance uLocalGroup_finite (hn : 1 ≤ n) (cut : Fin (n + 1)) :
Finite (uLocalGroup p n hn cut) :=
Finite.of_injective (uLocalEmbedding p n hn cut) (uLocalEmbedding p n hn cut).injective
def reducedLocalMap (hn : 1 ≤ n) (m : ℕ) (cut : Fin (n + 1)) :
uLocalGroup p n hn cut → reducedLocalGroup p n hn m cut :=
fun g => ⟨QuotientGroup.mk' (uReduction p (n + 1) m).ker g.val, ⟨g.val, g.property, rfl⟩⟩
def reducedRoot {a : ℕ} {i j : Fin a} (hij : i < j) (m : ℕ) (f : Trunc p m) :
(uReduction p a m).range :=
⟨Matrix.SpecialLinearGroup.transvection hij.ne f, by
obtain ⟨F, rfl⟩ := Ideal.Quotient.mk_surjective f
refine ⟨⟨Matrix.SpecialLinearGroup.transvection hij.ne F,
upper_transvection_mem_U p hij F⟩, ?_⟩
change Matrix.SpecialLinearGroup.map _ _ = _
exact map_transvection _ _ _⟩
end CoboundaryExpanders.Construction
end
end OAI
end
section
-- module Solutions.OAIQ3_Cob.Coboundary_Cosets
attribute [-instance] _root_.OAI.CoboundaryExpanders.TypedCosetFaces.complexInvariant _root_.OAI.CoboundaryExpanders.TypedCosetFaces.kernelInvariant _root_.OAI.CoboundaryExpanders.TypedCosetFaces.vertexAction _root_.OAI.CoboundaryExpanders.TypedCosetFaces.vertexMulAction
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
noncomputable section
/-!
Typed coset complexes, their links, face models, and connectedness from generation.
-/
section
open scoped BigOperators
open scoped BigOperators
open scoped BigOperators Matrix
open scoped Matrix
namespace CoboundaryExpanders.TypedCosetFaces
section
variable {G G' I I' : Type} [Group G] [Group G'] [DecidableEq I] [DecidableEq I']
(H : I → Subgroup G) (H' : I' → Subgroup G')
(e : G ≃* G') (r : I ≃ I')
(he : ∀ i g, g ∈ H i ↔ e g ∈ H' (r i))
omit [DecidableEq I] [DecidableEq I'] in
lemma isoVertex_surjective : Function.Surjective (isoVertex H H' e r he) := by
rintro ⟨i,q⟩
induction q using Quotient.inductionOn with | h q =>
refine ⟨vertex H (e.symm q) (r.symm i),?_⟩
simp only [isoVertex_vertex,e.apply_symm_apply,r.apply_symm_apply]
rfl
def vertexEquiv : Vertex H ≃ Vertex H' :=
Equiv.ofBijective (isoVertex H H' e r he)
⟨isoVertex_injective H H' e r he,isoVertex_surjective H H' e r he⟩
end
open InfiniteChains InfiniteChains.Cone
end CoboundaryExpanders.TypedCosetFaces
end
open scoped BigOperators
open scoped BigOperators Matrix
open scoped Matrix
open scoped BigOperators InnerProductSpace
end
end OAI
end
section
-- module Solutions.OAIQ3_Cob.Coboundary_Flags
attribute [-instance] _root_.OAI.CoboundaryExpanders.InfiniteChains.Complex.faceMulAction _root_.OAI.CoboundaryExpanders.TypedCosetFaces.complexInvariant _root_.OAI.CoboundaryExpanders.TypedCosetFaces.kernelInvariant _root_.OAI.CoboundaryExpanders.TypedCosetFaces.vertexAction _root_.OAI.CoboundaryExpanders.TypedCosetFaces.vertexMulAction
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
/-!
Complete flags, spherical opposition, unitriangular groups, and the flag-coset model.
-/
noncomputable section
open scoped BigOperators
namespace CoboundaryExpanders.SphericalOpposition
open Module
variable {K V : Type} [Field K] [AddCommGroup V] [Module K V]
variable {N : ℕ}
namespace CompleteFlag
variable [FiniteDimensional K V]
lemma space_zero (F : CompleteFlag K V N) : F.space 0 = ⊥ := by
apply Submodule.finrank_eq_zero.mp
exact F.rank 0
lemma space_last (F : CompleteFlag K V N) : F.space (Fin.last N) = ⊤ := by
apply Submodule.eq_top_of_finrank_eq
rw [F.rank, F.dimension]
rfl
def Opposed (F : CompleteFlag K V N) (W : Submodule K V) : Prop :=
IsCompl W (F.space ⟨N-finrank K W, by omega⟩)
def Good (F : CompleteFlag K V N) (W : Submodule K V) : Prop :=
0 < finrank K W ∧ finrank K W < N ∧ F.Opposed W
def complex (F : CompleteFlag K V N) : InfiniteChains.Complex (Submodule K V) where
faces := {s | (∀ W ∈ s, F.Good W) ∧ (s : Set (Submodule K V)).Pairwise (fun W W' => W ≤ W' ∨ W' ≤ W)}
empty_mem := by simp
downward := by
intro s t hs hts
exact ⟨fun W hW => hs.1 W (hts hW), hs.2.mono hts⟩
lemma rank_le (F : CompleteFlag K V N) (W : Submodule K V) : finrank K W ≤ N := by
simpa [F.dimension] using Submodule.finrank_le W
lemma opposed_iff_disjoint (F : CompleteFlag K V N) (W : Submodule K V) :
F.Opposed W ↔ Disjoint W (F.space ⟨N-finrank K W, by omega⟩) := by
apply Submodule.isCompl_iff_disjoint
rw [F.dimension, F.rank]
dsimp
have := F.rank_le W
omega
lemma opposed_disjoint_below (F : CompleteFlag K V N) (W : Submodule K V)
(hW : F.Opposed W) (i : Fin (N+1)) (hi : i.val ≤ N-finrank K W) :
Disjoint W (F.space i) := by
exact (F.opposed_iff_disjoint W).mp hW |>.mono_right (F.mono hi)
def forbidden (F : CompleteFlag K V N) (W : Submodule K V) : Submodule K V :=
W ⊔ F.space ⟨N-finrank K W-1, by omega⟩
omit [FiniteDimensional K V] in
lemma opposed_sup_above (F : CompleteFlag K V N) (W : Submodule K V)
(hW : F.Opposed W) (i : Fin (N+1)) (hi : N-finrank K W ≤ i.val) :
W ⊔ F.space i = ⊤ := by
apply top_unique
rw [← hW.sup_eq_top]
exact sup_le_sup_left (F.mono hi) W
lemma lower_rank (F : CompleteFlag K V N) (W : Submodule K V)
(hW : F.Opposed W) (i : Fin (finrank K W+1)) :
finrank K ((F.space ⟨N-finrank K W+i.val, by
have := F.rank_le W
omega⟩).comap W.subtype) = i.val := by
rw [← Submodule.finrank_map_subtype_eq W, Submodule.map_comap_subtype]
have he := Submodule.finrank_sup_add_finrank_inf_eq W
(F.space ⟨N-finrank K W+i.val, by have := F.rank_le W; omega⟩)
rw [F.opposed_sup_above W hW _ (by dsimp; omega), finrank_top,
F.dimension, F.rank] at he
dsimp only [Fin.val_mk] at he
have := F.rank_le W
omega
def lower (F : CompleteFlag K V N) (W : Submodule K V) (hW : F.Opposed W) :
CompleteFlag K W (finrank K W) where
space i := (F.space ⟨N-finrank K W+i.val, by have := F.rank_le W; omega⟩).comap W.subtype
mono := by
intro i j hij
apply Submodule.comap_mono
apply F.mono
change N-finrank K W+i.val ≤ N-finrank K W+j.val
omega
dimension := rfl
rank := F.lower_rank W hW
lemma opposed_lower_iff (F : CompleteFlag K V N) (W : Submodule K V)
(hW : F.Opposed W) (A : Submodule K W) :
(F.lower W hW).Opposed A ↔ F.Opposed (A.map W.subtype) := by
rw [(F.lower W hW).opposed_iff_disjoint, F.opposed_iff_disjoint,
disjoint_map_subtype_iff]
have ha := Submodule.finrank_le A
have hw := F.rank_le W
have eqi : (⟨N-finrank K W+(⟨finrank K W-finrank K A, by omega⟩ :
Fin (finrank K W+1)).val, by omega⟩ : Fin (N+1)) =
⟨N-finrank K (A.map W.subtype), by omega⟩ := by
apply Fin.ext
dsimp
rw [Submodule.finrank_map_subtype_eq]
omega
change Disjoint A ((F.space _).comap W.subtype) ↔ _
rw [eqi]
lemma face_has_greatest (F : CompleteFlag K V N) (s : Finset (Submodule K V))
(hs : s ∈ F.complex.faces) (hne : s.Nonempty) :
∃ W ∈ s, ∀ U ∈ s, U ≤ W := by
obtain ⟨W, hW, hmax⟩ := s.exists_max_image (fun U => finrank K U) hne
refine ⟨W, hW, fun U hU => ?_⟩
by_cases he : U = W
· exact he.le
· rcases hs.2 hU hW he with h | h
· exact h
· exact (Submodule.eq_of_le_of_finrank_le h (hmax U hU)).ge
def safeComplex (F : CompleteFlag K V N) (v : V) :
InfiniteChains.Complex (Submodule K V) where
faces := {s | s ∈ F.complex.faces ∧
∀ W ∈ s, finrank K W + 1 < N ∧ v ∉ F.forbidden W}
empty_mem := ⟨F.complex.empty_mem, by simp⟩
downward := fun hs hts => ⟨F.complex.downward hs.1 hts, fun W hW => hs.2 W (hts hW)⟩
def carrierApex (_ : CompleteFlag K V N) (v : V) (s : Finset (Submodule K V)) :
Submodule K V := s.sup id ⊔ Submodule.span K {v}
def carrier (F : CompleteFlag K V N) (v : V) (s : Finset (Submodule K V)) :
Set (Finset (Submodule K V)) :=
{t | t ∈ F.complex.faces ∧ ∀ W ∈ t, W ≤ F.carrierApex v s}
end CompleteFlag
end CoboundaryExpanders.SphericalOpposition
namespace CoboundaryExpanders.SphericalOpposition.CompleteFlag
open Module InfiniteChains InfiniteChains.Attachment InfiniteChains.Cone
variable {K V : Type} [Field K] [AddCommGroup V] [Module K V]
[FiniteDimensional K V] {N : ℕ}
def TopBad (F : CompleteFlag K V N) (W : Submodule K V) : Prop :=
F.Good W ∧ finrank K W = N-1
end CoboundaryExpanders.SphericalOpposition.CompleteFlag
namespace CoboundaryExpanders.SphericalOpposition.CompleteFlag
open Module Submodule
variable {K V : Type} [Field K] [AddCommGroup V] [Module K V]
[FiniteDimensional K V] {N : ℕ}
def Opposite (F E : CompleteFlag K V N) : Prop :=
∀ i : Fin (N+1), IsCompl (F.space i) (E.space ⟨N-i.val, by omega⟩)
omit [FiniteDimensional K V] in
lemma opposite_symm {F E : CompleteFlag K V N} (h : F.Opposite E) : E.Opposite F := by
intro i
have hh := (h ⟨N-i.val, by omega⟩).symm
convert hh using 1
all_goals try with_reducible_and_instances rfl
congr 1
apply Fin.ext
dsimp
omega
lemma opposite_line_rank {F E : CompleteFlag K V N} (h : F.Opposite E) (i : Fin N) :
finrank K (F.space i.succ ⊓ E.space ⟨N-i.val, by omega⟩ : Submodule K V) = 1 := by
have hs : F.space i.succ ⊔ E.space ⟨N-i.val, by omega⟩ = ⊤ := by
apply top_unique
rw [← (h i.castSucc).sup_eq_top]
exact sup_le_sup_right (F.mono (by simp [Fin.le_def])) _
have hh := Submodule.finrank_sup_add_finrank_inf_eq (F.space i.succ)
(E.space ⟨N-i.val, by omega⟩)
rw [hs, finrank_top, F.dimension, F.rank, E.rank] at hh
dsimp at hh
omega
lemma opposite_line_vector {F E : CompleteFlag K V N} (h : F.Opposite E) (i : Fin N) :
∃ v : V, v ∈ F.space i.succ ∧ v ∈ E.space ⟨N-i.val, by omega⟩ ∧
v ∉ F.space i.castSucc := by
have hn : (F.space i.succ ⊓ E.space ⟨N-i.val, by omega⟩ : Submodule K V) ≠ ⊥ := by
intro he
have hh := opposite_line_rank h i
rw [he, finrank_bot] at hh
omega
obtain ⟨v,hv,hv0⟩ := Submodule.exists_mem_ne_zero_of_ne_bot hn
refine ⟨v,hv.1,hv.2,?_⟩
intro hvF
have hz : v ∈ (F.space i.castSucc ⊓ E.space ⟨N-i.val, by omega⟩ : Submodule K V) :=
⟨hvF,hv.2⟩
have hb : F.space i.castSucc ⊓ E.space ⟨N-i.val, by omega⟩ = ⊥ :=
(h i.castSucc).inf_eq_bot
rw [hb] at hz
exact hv0 hz
lemma step_span (F : CompleteFlag K V N) (i : Fin N) {v : V}
(hv : v ∈ F.space i.succ) (hnot : v ∉ F.space i.castSucc) :
F.space i.succ = F.space i.castSucc ⊔ span K {v} := by
have hv0 : v ≠ 0 := fun he => hnot (he ▸ (F.space i.castSucc).zero_mem)
have hd : Disjoint (F.space i.castSucc) (span K {v}) := disjoint_span_singleton_of_notMem hnot
apply (Submodule.eq_of_le_of_finrank_eq
(sup_le (F.mono (by simp [Fin.le_def])) (span_le.mpr (by simpa using hv))) ?_).symm
have hh := finrank_sup_add_finrank_inf_eq (F.space i.castSucc) (span K {v})
rw [hd.eq_bot, finrank_bot, add_zero, finrank_span_singleton hv0, F.rank] at hh
simpa only [F.rank, Fin.val_succ, Fin.val_castSucc] using hh
theorem exists_adapted_basis {F E : CompleteFlag K V N} (h : F.Opposite E) :
∃ b : Basis (Fin N) K V, ∀ i : Fin N,
b i ∈ F.space i.succ ∧ b i ∈ E.space ⟨N-i.val, by omega⟩ := by
choose v hvF hvE hvnot using opposite_line_vector h
have hs : ∀ i : Fin (N+1), F.space i ≤ span K (Set.range v) := by
intro i
induction i using Fin.induction with
| zero => rw [F.space_zero]; exact bot_le
| succ i hi =>
rw [F.step_span i (hvF i) (hvnot i)]
exact sup_le hi (span_le.mpr (by
intro x hx
obtain rfl := Set.mem_singleton_iff.mp hx
exact subset_span (Set.mem_range_self i)))
have htop : ⊤ ≤ span K (Set.range v) := by simpa [F.space_last] using hs (Fin.last N)
let b := basisOfTopLeSpanOfCardEqFinrank v htop (by simpa using F.dimension.symm)
refine ⟨b, fun i => ?_⟩
simpa [b] using And.intro (hvF i) (hvE i)
end CoboundaryExpanders.SphericalOpposition.CompleteFlag
namespace CoboundaryExpanders.SphericalOpposition.CompleteFlag
open Module Submodule
variable {K V : Type} [Field K] [AddCommGroup V] [Module K V]
[FiniteDimensional K V] {N : ℕ}
lemma adapted_suffix (E : CompleteFlag K V N) (b : Basis (Fin N) K V)
(hb : ∀ j : Fin N, b j ∈ E.space ⟨N-j.val, by omega⟩) (i : Fin (N+1)) :
span K (Set.range (fun j : Fin (N-i.val) => b (suffixIndex i j))) =
E.space ⟨N-i.val, by omega⟩ := by
apply Submodule.eq_of_le_of_finrank_eq
· apply span_le.mpr
rintro _ ⟨j,rfl⟩
exact E.mono (by change N-(i.val+j.val) ≤ N-i.val; omega) (hb (suffixIndex i j))
· simpa only [Function.comp_def, Fintype.card_fin, E.rank] using
finrank_span_eq_card (b.linearIndependent.comp _ (suffixIndex_injective i))
end CoboundaryExpanders.SphericalOpposition.CompleteFlag
namespace CoboundaryExpanders.SphericalOpposition.CompleteFlag
open Module Submodule
variable {K V : Type} [Field K] [AddCommGroup V] [Module K V]
[FiniteDimensional K V] {N : ℕ}
lemma opposed_bot (F : CompleteFlag K V N) : F.Opposed ⊥ := by
unfold Opposed
simp only [finrank_bot, Nat.sub_zero]
have hh : (⟨N, by omega⟩ : Fin (N+1)) = Fin.last N := rfl
rw [hh, F.space_last]
exact isCompl_bot_top
lemma opposed_top (F : CompleteFlag K V N) : F.Opposed ⊤ := by
unfold Opposed
simp only [finrank_top, F.dimension, Nat.sub_self]
rw [show (⟨0, by omega⟩ : Fin (N+1)) = 0 from rfl, F.space_zero]
exact isCompl_top_bot
lemma extend_opposed (F : CompleteFlag K V N) (A : Submodule K V) (hA : F.Opposed A)
(j : ℕ) (hAj : finrank K A ≤ j) (hj : j ≤ N) :
∃ W : Submodule K V, A ≤ W ∧ finrank K W = j ∧ F.Opposed W := by
have hd := F.opposed_disjoint_below A hA ⟨N-j, by omega⟩ (by dsimp; omega)
obtain ⟨W,hAW,hW⟩ := hd.exists_isCompl
have hr : finrank K W = j := by
have hh := finrank_sup_add_finrank_inf_eq W (F.space ⟨N-j, by omega⟩)
rw [hW.sup_eq_top, hW.inf_eq_bot, finrank_bot, add_zero, finrank_top,
F.dimension, F.rank] at hh
dsimp at hh
omega
refine ⟨W,hAW,hr,?_⟩
unfold Opposed
simpa only [hr] using hW
lemma interval_opposed (F : CompleteFlag K V N) (A B : Submodule K V)
(hA : F.Opposed A) (hB : F.Opposed B) (hAB : A ≤ B)
(j : ℕ) (hAj : finrank K A ≤ j) (hjB : j ≤ finrank K B) :
∃ W : Submodule K V, A ≤ W ∧ W ≤ B ∧ finrank K W = j ∧ F.Opposed W := by
have hAc : (F.lower B hB).Opposed (A.comap B.subtype) := by
rw [F.opposed_lower_iff B hB, map_comap_lower B A hAB]
exact hA
obtain ⟨W,hAW,hr,hW⟩ := (F.lower B hB).extend_opposed (A.comap B.subtype) hAc j
(by simpa only [rank_comap_lower B A hAB] using hAj) hjB
refine ⟨W.map B.subtype, ?_, Submodule.map_subtype_le B W, ?_,
(F.opposed_lower_iff B hB W).mp hW⟩
· rw [← map_comap_lower B A hAB]
exact Submodule.map_mono hAW
· simpa only [Submodule.finrank_map_subtype_eq] using hr
lemma rank_injective_on_face (F : CompleteFlag K V N) (s : Finset (Submodule K V))
(hs : s ∈ F.complex.faces) : Set.InjOn (fun W : Submodule K V => finrank K W) s := by
intro A hA B hB hr
by_cases he : A = B
· exact he
· rcases hs.2 hA hB he with hAB | hBA
· exact Submodule.eq_of_le_of_finrank_eq hAB hr
· exact (Submodule.eq_of_le_of_finrank_eq hBA hr.symm).symm
lemma face_order_of_rank_le (F : CompleteFlag K V N) (s : Finset (Submodule K V))
(hs : s ∈ F.complex.faces) {A B : Submodule K V} (hA : A ∈ s) (hB : B ∈ s)
(hr : finrank K A ≤ finrank K B) : A ≤ B := by
by_cases he : A = B
· exact he.le
· rcases hs.2 hA hB he with hAB | hBA
· exact hAB
· exact (Submodule.eq_of_le_of_finrank_le hBA hr).ge
lemma face_has_least (F : CompleteFlag K V N) (s : Finset (Submodule K V))
(hs : s ∈ F.complex.faces) (hne : s.Nonempty) :
∃ W ∈ s, ∀ U ∈ s, W ≤ U := by
obtain ⟨W,hW,hmin⟩ := s.exists_min_image (fun U => finrank K U) hne
exact ⟨W,hW,fun U hU => F.face_order_of_rank_le s hs hW hU (hmin U hU)⟩
lemma face_lower_bound_at (F : CompleteFlag K V N) (s : Finset (Submodule K V))
(hs : s ∈ F.complex.faces) (j : ℕ) (hj : 0 < j) :
∃ A : Submodule K V, F.Opposed A ∧ finrank K A < j ∧
(∀ U ∈ s, finrank K U < j → U ≤ A) ∧ (∀ U ∈ s, j ≤ finrank K U → A ≤ U) ∧ (A = ⊥ ∨ A ∈ s) := by
classical
let t := s.filter (fun W : Submodule K V => finrank K W < j)
by_cases ht : t.Nonempty
· obtain ⟨A,hA,hmax⟩ := F.face_has_greatest t (F.complex.downward hs (Finset.filter_subset _ _)) ht
obtain ⟨hAs,hAr⟩ := Finset.mem_filter.mp hA
refine ⟨A,(hs.1 A hAs).2.2,hAr,fun U hU hr => hmax U (Finset.mem_filter.mpr ⟨hU,hr⟩),?_,Or.inr hAs⟩
intro U hU hr
exact F.face_order_of_rank_le s hs hAs hU (by omega)
· refine ⟨⊥,F.opposed_bot, by simpa only [finrank_bot], ?_, fun _ _ _ => bot_le, Or.inl rfl⟩
intro U hU hr
exact False.elim (ht ⟨U,Finset.mem_filter.mpr ⟨hU,hr⟩⟩)
lemma face_upper_bound_at (F : CompleteFlag K V N) (s : Finset (Submodule K V))
(hs : s ∈ F.complex.faces) (j : ℕ) (hj : j < N) :
∃ B : Submodule K V, F.Opposed B ∧ j < finrank K B ∧
(∀ U ∈ s, j < finrank K U → B ≤ U) ∧ (∀ U ∈ s, finrank K U ≤ j → U ≤ B) ∧ (B = ⊤ ∨ B ∈ s) := by
classical
let t := s.filter (fun W : Submodule K V => j < finrank K W)
by_cases ht : t.Nonempty
· obtain ⟨B,hB,hmin⟩ := F.face_has_least t (F.complex.downward hs (Finset.filter_subset _ _)) ht
obtain ⟨hBs,hBr⟩ := Finset.mem_filter.mp hB
refine ⟨B,(hs.1 B hBs).2.2,hBr,fun U hU hr => hmin U (Finset.mem_filter.mpr ⟨hU,hr⟩),?_,Or.inr hBs⟩
intro U hU hr
exact F.face_order_of_rank_le s hs hU hBs (by omega)
· refine ⟨⊤,F.opposed_top, by simpa only [finrank_top,F.dimension], ?_, fun _ _ _ => le_top, Or.inl rfl⟩
intro U hU hr
exact False.elim (ht ⟨U,Finset.mem_filter.mpr ⟨hU,hr⟩⟩)
end CoboundaryExpanders.SphericalOpposition.CompleteFlag
namespace CoboundaryExpanders.SphericalOpposition.CompleteFlag
open Module Submodule
variable {K V : Type} [Field K] [AddCommGroup V] [Module K V]
[FiniteDimensional K V] {N : ℕ}
lemma insert_rank (F : CompleteFlag K V N) (s : Finset (Submodule K V))
(hs : s ∈ F.complex.faces) (j : ℕ) (hj0 : 0 < j) (hjN : j < N) :
∃ t : Finset (Submodule K V), t ∈ F.complex.faces ∧ s ⊆ t ∧
∃ W ∈ t, finrank K W = j := by
classical
by_cases hex : ∃ W ∈ s, finrank K W = j
· exact ⟨s,hs,Finset.Subset.refl s,hex⟩
obtain ⟨A,hA,hrA,hAl,hAu,hlocA⟩ := F.face_lower_bound_at s hs j hj0
obtain ⟨B,hB,hrB,hBl,hBu,hlocB⟩ := F.face_upper_bound_at s hs j hjN
have hAB : A ≤ B := by
rcases hlocA with rfl | hAs
· exact bot_le
· exact hBu A hAs hrA.le
obtain ⟨W,hAW,hWB,hrW,hW⟩ := F.interval_opposed A B hA hB hAB j hrA.le hrB.le
have hcomp (U : Submodule K V) (hU : U ∈ s) : U ≤ W ∨ W ≤ U := by
rcases lt_trichotomy (finrank K U) j with hr | hr | hr
· exact Or.inl ((hAl U hU hr).trans hAW)
· exact False.elim (hex ⟨U,hU,hr⟩)
· exact Or.inr (hWB.trans (hBl U hU hr))
refine ⟨insert W s,?_,Finset.subset_insert _ _,W,Finset.mem_insert_self _ _,hrW⟩
constructor
· intro U hU
rcases Finset.mem_insert.mp hU with rfl | hU
· exact ⟨by omega,by omega,hW⟩
· exact hs.1 U hU
· intro U hU U' hU' hne
rcases Finset.mem_insert.mp hU with hUW | hUs
· subst U
rcases Finset.mem_insert.mp hU' with hU'W | hU's
· subst U'; exact False.elim (hne rfl)
· exact (hcomp U' hU's).symm
· rcases Finset.mem_insert.mp hU' with hU'W | hU's
· subst U'; exact hcomp U hUs
· exact hs.2 hUs hU's hne
lemma exists_extend_ranks (F : CompleteFlag K V N) (I : Finset ℕ)
(hI : ∀ j ∈ I, 0 < j ∧ j < N) (s : Finset (Submodule K V)) (hs : s ∈ F.complex.faces) :
∃ t : Finset (Submodule K V), t ∈ F.complex.faces ∧ s ⊆ t ∧
∀ j ∈ I, ∃ W ∈ t, finrank K W = j := by
classical
induction I using Finset.induction generalizing s with
| empty => exact ⟨s,hs,Finset.Subset.refl s,by simp⟩
| @insert a I ha ih =>
obtain ⟨t,ht,hst,hfull⟩ := ih (fun j hj => hI j (Finset.mem_insert_of_mem hj)) s hs
obtain ⟨u,hu,htu,hua⟩ := F.insert_rank t ht a
(hI a (Finset.mem_insert_self _ _)).1 (hI a (Finset.mem_insert_self _ _)).2
refine ⟨u,hu,hst.trans htu,?_⟩
intro j hj
rcases Finset.mem_insert.mp hj with rfl | hj
· exact hua
· obtain ⟨W,hW,hr⟩ := hfull j hj
exact ⟨W,htu hW,hr⟩
def FullFace (F : CompleteFlag K V N) (s : Finset (Submodule K V)) : Prop :=
s ∈ F.complex.faces ∧ ∀ j, 0 < j → j < N → ∃ W ∈ s, finrank K W = j
lemma exists_full_face (F : CompleteFlag K V N) (s : Finset (Submodule K V))
(hs : s ∈ F.complex.faces) : ∃ t, F.FullFace t ∧ s ⊆ t := by
obtain ⟨t,ht,hst,hfull⟩ := F.exists_extend_ranks (Finset.Ioo 0 N)
(fun _ hj => Finset.mem_Ioo.mp hj) s hs
exact ⟨t,⟨ht,fun j hj0 hjN => hfull j (Finset.mem_Ioo.mpr ⟨hj0,hjN⟩)⟩,hst⟩
end CoboundaryExpanders.SphericalOpposition.CompleteFlag
namespace CoboundaryExpanders.SphericalOpposition.CompleteFlag
open Module Submodule
variable {K V : Type} [Field K] [AddCommGroup V] [Module K V]
[FiniteDimensional K V] {N : ℕ}
lemma exists_flag_stages (F : CompleteFlag K V N) (s : Finset (Submodule K V))
(hs : F.FullFace s) (i : Fin (N+1)) :
∃ W : Submodule K V, finrank K W = i.val ∧ F.Opposed W ∧
(0 < i.val → i.val < N → W ∈ s) := by
by_cases hi0 : i.val = 0
· exact ⟨⊥,by simp [hi0],F.opposed_bot,by omega⟩
by_cases hiN : i.val = N
· exact ⟨⊤,by simp [F.dimension,hiN],F.opposed_top,by omega⟩
obtain ⟨W,hW,hr⟩ := hs.2 i.val (by omega) (by omega)
exact ⟨W,hr,(hs.1.1 W hW).2.2,fun _ _ => hW⟩
theorem exists_flag_from_face (F : CompleteFlag K V N) (s : Finset (Submodule K V))
(hs : F.FullFace s) :
∃ E : CompleteFlag K V N, F.Opposite E ∧
∀ W : Submodule K V, W ∈ s ↔
∃ i : Fin (N+1), 0 < i.val ∧ i.val < N ∧ E.space i = W := by
classical
choose f hr ho hm using F.exists_flag_stages s hs
have hmono : Monotone f := by
intro i j hij
by_cases hi : i.val = 0
· have hh : f i = ⊥ := Submodule.finrank_eq_zero.mp ((hr i).trans hi)
rw [hh]; exact bot_le
by_cases hj : j.val = N
· have hh : f j = ⊤ := Submodule.eq_top_of_finrank_eq ((hr j).trans (hj.trans F.dimension.symm))
rw [hh]; exact le_top
exact F.face_order_of_rank_le s hs.1 (hm i (by omega) (by omega))
(hm j (by omega) (by omega)) (by rw [hr,hr]; exact hij)
let E : CompleteFlag K V N := ⟨f,hmono,F.dimension,hr⟩
refine ⟨E,?_,?_⟩
· intro i
have hh := (ho ⟨N-i.val, by omega⟩).symm
simp only [hr] at hh
have he : (⟨N-(N-i.val), by omega⟩ : Fin (N+1)) = i := by apply Fin.ext; dsimp; omega
simpa only [he] using hh
· intro W
constructor
· intro hW
let i : Fin (N+1) := ⟨finrank K W, by have := (hs.1.1 W hW).2.1; omega⟩
have hi0 : 0 < i.val := (hs.1.1 W hW).1
have hiN : i.val < N := (hs.1.1 W hW).2.1
exact ⟨i,hi0,hiN,F.rank_injective_on_face s hs.1 (hm i hi0 hiN) hW (hr i)⟩
· rintro ⟨i,hi0,hiN,rfl⟩
exact hm i hi0 hiN
open scoped Pointwise
lemma flagStabilizer_good (F : CompleteFlag K V N) (e : F.flagStabilizer) (W : Submodule K V)
(hW : F.Good W) : F.Good (e • W) := by
have he := (F.mem_flagStabilizer e.val).mp e.property
change F.Good (W.map e.val.toLinearMap)
refine ⟨by simpa only [e.val.finrank_map_eq] using hW.1,
by simpa only [e.val.finrank_map_eq] using hW.2.1,?_⟩
rw [F.opposed_iff_disjoint]
simp only [e.val.finrank_map_eq]
rw [← he]
exact Submodule.disjoint_map e.val.injective hW.2.2.disjoint
end CoboundaryExpanders.SphericalOpposition.CompleteFlag
namespace CoboundaryExpanders.SphericalOpposition.CompleteFlag
open Module Submodule
variable {K V : Type} [Field K] [AddCommGroup V] [Module K V]
[FiniteDimensional K V] {N : ℕ}
omit [FiniteDimensional K V] in
lemma adapted_basis_not_mem_previous {F E : CompleteFlag K V N} (h : F.Opposite E)
(b : Basis (Fin N) K V)
(hb : ∀ i : Fin N, b i ∈ F.space i.succ ∧ b i ∈ E.space ⟨N-i.val, by omega⟩)
(i : Fin N) : b i ∉ F.space i.castSucc := by
intro hi
have hh : b i ∈ F.space i.castSucc ⊓ E.space ⟨N-i.val, by omega⟩ := ⟨hi,(hb i).2⟩
have he : F.space i.castSucc ⊓ E.space ⟨N-i.val, by omega⟩ = ⊥ := by
simpa only [Fin.val_castSucc] using (h i.castSucc).inf_eq_bot
rw [he] at hh
exact b.ne_zero i hh
lemma adapted_diagonal_ne_zero (F : CompleteFlag K V N)
(b c : Basis (Fin N) K V) (hb : ∀ i : Fin N, b i ∈ F.space i.succ)
(hc : ∀ i : Fin N, c i ∈ F.space i.succ)
(hnot : ∀ i : Fin N, c i ∉ F.space i.castSucc) (i : Fin N) :
b.repr (c i) i ≠ 0 := by
intro hi
apply hnot i
apply (F.mem_flag_iff_repr b hb i.castSucc (c i)).mpr
intro j hj
by_cases hji : j = i
· simpa [hji] using hi
· apply (F.mem_flag_iff_repr b hb i.succ (c i)).mp (hc i) j
change i.val+1 ≤ j.val
change i.val ≤ j.val at hj
have : j.val ≠ i.val := fun h => hji (Fin.ext h)
omega
theorem exists_normalized_adapted_basis {F E : CompleteFlag K V N} (h : F.Opposite E)
(b : Basis (Fin N) K V) (hb : ∀ i : Fin N, b i ∈ F.space i.succ) :
∃ c : Basis (Fin N) K V, ∀ i : Fin N,
c i ∈ F.space i.succ ∧ c i ∈ E.space ⟨N-i.val, by omega⟩ ∧ b.repr (c i) i = 1 := by
classical
obtain ⟨c,hc⟩ := exists_adapted_basis h
have hne := F.adapted_diagonal_ne_zero b c hb (fun i => (hc i).1)
(adapted_basis_not_mem_previous h c hc)
let u : Fin N → Kˣ := fun i => (Units.mk0 (b.repr (c i) i) (hne i))⁻¹
refine ⟨c.unitsSMul u,?_⟩
intro i
simp only [Basis.unitsSMul_apply, Units.smul_def]
refine ⟨(F.space i.succ).smul_mem _ (hc i).1,
(E.space ⟨N-i.val, by omega⟩).smul_mem _ (hc i).2,?_⟩
simp [u, map_smul, hne i]
theorem exists_unitriangular_equiv {F E E' : CompleteFlag K V N}
(b : Basis (Fin N) K V)
(hb : ∀ i : Fin N, b i ∈ F.space i.succ ∧ b i ∈ E.space ⟨N-i.val, by omega⟩)
(h' : F.Opposite E') :
∃ e : V ≃ₗ[K] V, Unitriangular b e ∧
(∀ i, (F.space i).map e.toLinearMap = F.space i) ∧
(∀ i, (E.space i).map e.toLinearMap = E'.space i) := by
classical
obtain ⟨c,hc⟩ := exists_normalized_adapted_basis h' b (fun i => (hb i).1)
let e := b.equiv c (Equiv.refl _)
refine ⟨e,?_,?_,?_⟩
· intro i j hij
dsimp [e]
rw [Basis.equiv_apply, Equiv.refl_apply]
by_cases hji : j = i
· simpa [hji] using (hc i).2.2
· rw [ite_eq_right hji]
apply (F.mem_flag_iff_repr b (fun i => (hb i).1) i.succ (c i)).mp (hc i).1 j
change i.val+1 ≤ j.val
have : j.val ≠ i.val := fun h => hji (Fin.ext h)
change i.val ≤ j.val at hij
omega
· intro i
calc
(F.space i).map e.toLinearMap =
(span K (Set.range (fun j : Fin i.val => b (prefixIndex i j)))).map e.toLinearMap := by
rw [adapted_prefix F b (fun i => (hb i).1)]
_ = span K (Set.range (fun j : Fin i.val => c (prefixIndex i j))) :=
basis_equiv_span_range b c _
_ = F.space i := adapted_prefix F c (fun i => (hc i).1) i
· intro i
let k : Fin (N+1) := ⟨N-i.val, by omega⟩
have he : (⟨N-k.val, by omega⟩ : Fin (N+1)) = i := by
apply Fin.ext; dsimp [k]; omega
rw [← he, ← adapted_suffix E b (fun i => (hb i).2) k,
basis_equiv_span_range b c, adapted_suffix E' c (fun i => (hc i).2.1), he]
end CoboundaryExpanders.SphericalOpposition.CompleteFlag
namespace CoboundaryExpanders.SphericalOpposition.CompleteFlag
open Module Submodule
variable {K V : Type} [Field K] [AddCommGroup V] [Module K V]
[FiniteDimensional K V] {N : ℕ}
lemma mem_opposite_flag_iff_repr (E : CompleteFlag K V N) (b : Basis (Fin N) K V)
(hb : ∀ j : Fin N, b j ∈ E.space ⟨N-j.val, by omega⟩) (i : Fin (N+1)) (v : V) :
v ∈ E.space ⟨N-i.val, by omega⟩ ↔
∀ j : Fin N, j.val < i.val → b.repr v j = 0 := by
rw [← E.adapted_suffix b hb i, suffix_span_image, b.mem_span_image]
constructor
· intro h j hj
by_contra hn
exact Nat.not_lt_of_ge (h (Finsupp.mem_support_iff.mpr hn)) hj
· intro h j hj
by_contra hn
exact (Finsupp.mem_support_iff.mp hj) (h j (Nat.lt_of_not_ge hn))
theorem unipotent_transitive {F E E' : CompleteFlag K V N}
(h : F.Opposite E) (h' : F.Opposite E') :
∃ e : F.unipotentFlagStabilizer, ∀ i,
(E.space i).map e.val.toLinearMap = E'.space i := by
obtain ⟨b,hb⟩ := exists_adapted_basis h
obtain ⟨e,he,heF,heE⟩ := exists_unitriangular_equiv b hb h'
exact ⟨⟨e,(F.mem_flagStabilizer e).mpr heF,
F.unitriangular_grading b (fun i => (hb i).1) e he⟩,heE⟩
end CoboundaryExpanders.SphericalOpposition.CompleteFlag
namespace CoboundaryExpanders.SphericalOpposition.CompleteFlag
open Module Submodule TypedCosetFaces
variable {K V : Type} [Field K] [AddCommGroup V] [Module K V]
[FiniteDimensional K V] {N : ℕ}
open scoped Pointwise
omit [FiniteDimensional K V] in
lemma opposed_of_opposite {F E : CompleteFlag K V N} (h : F.Opposite E) (i : Fin (N+1)) :
F.Opposed (E.space i) := by
unfold Opposed
simp only [E.rank]
exact opposite_symm h i
omit [FiniteDimensional K V] in
lemma baseSpace_good {F E : CompleteFlag K V N} (h : F.Opposite E) (i : Fin (N-1)) :
F.Good (E.baseSpace i) := by
refine ⟨by simp,by simp; omega,opposed_of_opposite h _⟩
omit [FiniteDimensional K V] in
lemma cosetVertexMap_rank (F E : CompleteFlag K V N) (x : Vertex (F.vertexStabilizers E)) :
finrank K (F.cosetVertexMap E x) = x.1.val+1 := by
rcases x with ⟨i,x⟩
induction x using Quotient.inductionOn with | h g =>
change finrank K ((E.baseSpace i).map g.val.toLinearMap) = i.val+1
rw [g.val.finrank_map_eq,baseSpace_rank]
omit [FiniteDimensional K V] in
lemma cosetVertexMap_injective (F E : CompleteFlag K V N) : Function.Injective (F.cosetVertexMap E) := by
rintro ⟨i,x⟩ ⟨j,y⟩ hxy
have hr := congrArg (fun W : Submodule K V => finrank K W) hxy
rw [cosetVertexMap_rank,cosetVertexMap_rank] at hr
have hij : i = j := Fin.ext (by dsimp at hr; omega)
subst j
congr 1
exact MulAction.injective_ofQuotientStabilizer F.unipotentFlagStabilizer (E.baseSpace i) hxy
lemma unipotent_good (F : CompleteFlag K V N) (g : F.unipotentFlagStabilizer)
(W : Submodule K V) (hW : F.Good W) : F.Good (g • W) :=
F.flagStabilizer_good ⟨g.val,g.property.1⟩ W hW
theorem cosetFace_opposed {F E : CompleteFlag K V N} (h : F.Opposite E)
(s : Finset (Vertex (F.vertexStabilizers E))) (hs : IsFace (F.vertexStabilizers E) s) :
s.image (F.cosetVertexMap E) ∈ F.complex.faces := by
classical
obtain ⟨g,A,rfl⟩ := hs
have he : (face (F.vertexStabilizers E) g A).image (F.cosetVertexMap E) =
A.image (fun i => g • E.baseSpace i) := by
simp only [face,Finset.image_image,Function.comp_def,cosetVertexMap_vertex]
rw [he]
constructor
· intro W hW
obtain ⟨i,_,rfl⟩ := Finset.mem_image.mp hW
exact F.unipotent_good g _ (baseSpace_good h i)
· intro W hW W' hW' _
obtain ⟨i,_,rfl⟩ := Finset.mem_image.mp hW
obtain ⟨j,_,rfl⟩ := Finset.mem_image.mp hW'
rcases le_total i j with hij | hji
· exact Or.inl (Submodule.map_mono (E.mono (by change i.val+1 ≤ j.val+1; exact Nat.add_le_add_right hij 1)))
· exact Or.inr (Submodule.map_mono (E.mono (by change j.val+1 ≤ i.val+1; exact Nat.add_le_add_right hji 1)))
theorem opposedFace_coset {F E : CompleteFlag K V N} (h : F.Opposite E)
(s : Finset (Submodule K V)) (hs : s ∈ F.complex.faces) :
∃ g : F.unipotentFlagStabilizer, ∃ A : Finset (Fin (N-1)),
(face (F.vertexStabilizers E) g A).image (F.cosetVertexMap E) = s := by
classical
obtain ⟨t,ht,hst⟩ := F.exists_full_face s hs
obtain ⟨E',hE',htE'⟩ := F.exists_flag_from_face t ht
obtain ⟨g,hg⟩ := unipotent_transitive h hE'
let A := Finset.univ.filter (fun i : Fin (N-1) => E'.baseSpace i ∈ s)
refine ⟨g,A,?_⟩
simp only [face,Finset.image_image,Function.comp_def,cosetVertexMap_vertex]
have hg' (i : Fin (N-1)) : g • E.baseSpace i = E'.baseSpace i := hg (properIndex (N:=N) i)
simp_rw [hg']
ext W
constructor
· intro hW
obtain ⟨i,hi,rfl⟩ := Finset.mem_image.mp hW
exact (Finset.mem_filter.mp hi).2
· intro hW
obtain ⟨i,hi0,hiN,hiW⟩ := (htE' W).mp (hst hW)
let j : Fin (N-1) := ⟨i.val-1,by omega⟩
have hji : properIndex (N:=N) j = i := by apply Fin.ext; dsimp [properIndex,j]; omega
have hjW : E'.baseSpace j = W := by rw [baseSpace,hji,hiW]
exact Finset.mem_image.mpr ⟨j,Finset.mem_filter.mpr ⟨Finset.mem_univ _,by rw [hjW]; exact hW⟩,hjW⟩
theorem cosetFace_iff {F E : CompleteFlag K V N} (h : F.Opposite E)
(s : Finset (Vertex (F.vertexStabilizers E))) :
IsFace (F.vertexStabilizers E) s ↔ s.image (F.cosetVertexMap E) ∈ F.complex.faces := by
classical
constructor
· exact cosetFace_opposed h s
· intro hs
obtain ⟨g,A,he⟩ := opposedFace_coset h _ hs
refine ⟨g,A,?_⟩
exact Finset.image_injective (F.cosetVertexMap_injective E) he
end CoboundaryExpanders.SphericalOpposition.CompleteFlag
namespace CoboundaryExpanders.SphericalOpposition.CompleteFlag
open Module Submodule
variable {K V : Type} [Field K] [AddCommGroup V] [Module K V]
[FiniteDimensional K V] {N : ℕ}
def oppositeBasisFlag (b : Basis (Fin N) K V) : CompleteFlag K V N where
space i := span K (Set.range (fun j : Fin i.val => b (tailIndex i j)))
mono := by
intro i j hij
apply span_mono
rintro v ⟨k,rfl⟩
refine ⟨⟨j.val-i.val+k.val,by omega⟩,?_⟩
apply congrArg b
apply Fin.ext
dsimp [tailIndex]
omega
dimension := by simpa using Module.finrank_eq_card_basis b
rank i := by
have hi : Function.Injective (tailIndex i) := by
intro j k he
apply Fin.ext
have hh := congrArg Fin.val he
dsimp [tailIndex] at hh
omega
simpa only [Function.comp_def, Fintype.card_fin] using finrank_span_eq_card (b.linearIndependent.comp _ hi)
omit [FiniteDimensional K V] in
lemma oppositeBasisFlag_adapted (b : Basis (Fin N) K V) (i : Fin N) :
b i ∈ (oppositeBasisFlag b).space ⟨N-i.val,by omega⟩ := by
apply Submodule.subset_span
refine ⟨⟨0,by change 0 < N-i.val; omega⟩,?_⟩
apply congrArg b
apply Fin.ext
dsimp [tailIndex]
omega
theorem basisFlags_opposite (b : Basis (Fin N) K V) :
(basisFlag b).Opposite (oppositeBasisFlag b) := by
intro i
apply (Submodule.isCompl_iff_disjoint _ _ (by
rw [(basisFlag b).rank,(oppositeBasisFlag b).rank,(basisFlag b).dimension]
dsimp; omega)).mpr
apply disjoint_def.mpr
intro x hx hy
apply b.repr.injective
ext j
rw [map_zero,Finsupp.zero_apply]
by_cases hji : j.val < i.val
· exact ((oppositeBasisFlag b).mem_opposite_flag_iff_repr b
(oppositeBasisFlag_adapted b) i x).mp hy j hji
· exact ((basisFlag b).mem_flag_iff_repr b (basisFlag_adapted b) i x).mp hx j (by omega)
end CoboundaryExpanders.SphericalOpposition.CompleteFlag
end
end OAI
end
section
-- module Solutions.OAIQ3_Cob.Congruence_Patterns
attribute [-instance] _root_.OAI.CoboundaryExpanders.Blocks.gammaNormal _root_.OAI.CoboundaryExpanders.CongruenceFrames.invariant _root_.OAI.CoboundaryExpanders.MatrixOpposition.cutDecidableEq _root_.OAI.CoboundaryExpanders.MatrixOpposition.cutFinite _root_.OAI.CoboundaryExpanders.MatrixOpposition.cutFintype
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
/-!
Pattern subgroups, matrix opposition, block decompositions, and suffix equivalences.
-/
noncomputable section
open scoped BigOperators
open scoped BigOperators Matrix
open scoped Matrix
namespace CoboundaryExpanders.Patterns
section
open CoboundaryExpanders.Construction CoboundaryExpanders.Elementary
variable {n : ℕ}
variable (p : ℕ) [Fact p.Prime]
theorem localGroup_le_cutUpper (hn : 1 ≤ n) (cut : Fin (n + 1)) :
localGroup p n hn cut ≤ cutUpper p cut := by
apply (Subgroup.closure_le _).mpr
rintro g ⟨j, hj, rfl⟩
change cycleRoot p n hn j ∈ cutUpper p cut
rw [cutUpper_iff]
have hlt : cutRank cut (edgeSource n j) < cutRank cut j := by
rw [cutRank_lt_iff _ _ _ (edgeSource_ne n hn j)]
by_cases h0 : j = 0
· subst j
have hc : 0 < cut.val := by
have : cut.val ≠ 0 := fun h => hj (Fin.ext h.symm)
omega
simp only [edgeSource, dite_eq_left rfl, Arc, Fin.val_last, Fin.val_zero,
Nat.not_lt_zero, ite_false]
omega
· have hj0 : 0 < j.val := by
have : j.val ≠ 0 := fun h => h0 (Fin.ext h)
omega
have hne : j.val ≠ cut.val := fun h => hj (Fin.ext h)
simp only [edgeSource, dite_eq_right h0, Arc, Fin.val_mk,
ite_eq_left (show j.val - 1 < j.val by omega)]
omega
intro a b hba
change (Matrix.transvection (edgeSource n j) j _) a b = _
have hne : ¬ (edgeSource n j = a ∧ j = b) := by
rintro ⟨rfl, rfl⟩
exact (not_lt_of_ge hba) hlt
simp [Matrix.transvection, hne]
end
section
open CoboundaryExpanders.Construction CoboundaryExpanders.Elementary
variable (p n : ℕ) [Fact p.Prime]
def intersectionGroup (hn : 1 ≤ n) (J : Set (Fin (n + 1))) :
Subgroup (Matrix.SpecialLinearGroup (Fin (n + 1)) (R p)) :=
⨅ cut, ⨅ (_ : cut ∉ J), localGroup p n hn cut
omit [Fact p.Prime] in
theorem mem_intersectionGroup (hn : 1 ≤ n) (J : Set (Fin (n + 1)))
(g : Matrix.SpecialLinearGroup (Fin (n + 1)) (R p)) :
g ∈ intersectionGroup p n hn J ↔ ∀ cut ∉ J, g ∈ localGroup p n hn cut := by
simp [intersectionGroup]
omit [Fact p.Prime] in
theorem rootGroup_le_intersection (hn : 1 ≤ n) (J : Set (Fin (n + 1))) :
rootGroup p n hn J ≤ intersectionGroup p n hn J := by
apply (Subgroup.closure_le _).mpr
rintro g ⟨j, hj, rfl⟩
change cycleRoot p n hn j ∈ intersectionGroup p n hn J
rw [mem_intersectionGroup]
intro cut hc
exact Subgroup.subset_closure ⟨j, by intro he; subst cut; contradiction, rfl⟩
end
open CoboundaryExpanders.Construction CoboundaryExpanders.Elementary
variable (p n : ℕ) [Fact p.Prime]
theorem entry_nonzero_path (hn : 1 ≤ n) (J : Set (Fin (n + 1)))
(g : Matrix.SpecialLinearGroup (Fin (n + 1)) (R p))
(hg : g ∈ intersectionGroup p n hn J) {a b : Fin (n + 1)} (hab : a ≠ b)
(hne : g a b ≠ 0) : ∀ j, Arc a b j → j ∈ J := by
intro j hj
by_contra hjJ
have hg' := (mem_intersectionGroup p n hn J g).mp hg j hjJ
have hupper := (cutUpper_iff p j g).mp (localGroup_le_cutUpper p hn j hg')
have hba : cutRank j b ≤ cutRank j a := by
apply le_of_not_gt
rwa [cutRank_lt_iff j a b hab, not_not]
exact hne ((hupper a b hba).trans (Matrix.one_apply_ne hab))
theorem local_entry_coefficient (hn : 1 ≤ n) (cut : Fin (n + 1))
(g : localGroup p n hn cut) {a b : Fin (n + 1)}
(hlt : cutRank cut a < cutRank cut b) :
∃ c : ZMod p, g.val a b = pathCoefficient (p := p) (n := n) (a := a) (b := b) c := by
obtain ⟨c, hc⟩ := localGroup_entry_equation p n hn cut g a b
refine ⟨c, ?_⟩
unfold cutPolynomial at hc
unfold pathCoefficient
change (if a.val < cut.val then a.val + (n + 1) - cut.val else a.val - cut.val) <
(if b.val < cut.val then b.val + (n + 1) - cut.val else b.val - cut.val) at hlt
by_cases ha : a.val < cut.val <;> by_cases hb : b.val < cut.val
· rw [ite_eq_left ha, ite_eq_left hb] at hc
have hab : a.val < b.val := by simp only [ite_eq_left ha, ite_eq_left hb] at hlt; omega
rw [ite_eq_left hab, mul_one]
apply mul_left_cancel₀ (Polynomial.X_ne_zero (R := ZMod p))
simpa only [mul_comm Polynomial.X (Polynomial.C c)] using hc
· simp only [ite_eq_left ha, ite_eq_right hb] at hlt
omega
· rw [ite_eq_right ha, ite_eq_left hb, one_mul] at hc
rw [ite_eq_right (by omega : ¬ a.val < b.val)]
exact hc
· rw [ite_eq_right ha, ite_eq_right hb, one_mul, mul_one] at hc
have hab : a.val < b.val := by simp only [ite_eq_right ha, ite_eq_right hb] at hlt; omega
rw [ite_eq_left hab, mul_one]
exact hc
theorem entry_root_mem (hn : 1 ≤ n) (J : Set (Fin (n + 1)))
(cut : Fin (n + 1)) (hcut : cut ∉ J)
(g : Matrix.SpecialLinearGroup (Fin (n + 1)) (R p))
(hg : g ∈ intersectionGroup p n hn J) {a b : Fin (n + 1)} (hab : a ≠ b) :
E hab (g a b) ∈ rootGroup p n hn J := by
by_cases hz : g a b = 0
· simp [hz, E]
· have hpath := entry_nonzero_path p n hn J g hg hab hz
have hlt : cutRank cut a < cutRank cut b := by
rw [cutRank_lt_iff cut a b hab]
exact fun h => hcut (hpath cut h)
have hg' := (mem_intersectionGroup p n hn J g).mp hg cut hcut
obtain ⟨c, hc⟩ := local_entry_coefficient p n hn cut ⟨g, hg'⟩ hlt
change g a b = _ at hc
rw [hc]
exact path_root_mem p n hn J hab hpath c
theorem rootGroup_eq_intersection (hn : 1 ≤ n) (J : Set (Fin (n + 1)))
(hJ : ∃ cut, cut ∉ J) : rootGroup p n hn J = intersectionGroup p n hn J := by
apply le_antisymm (rootGroup_le_intersection p n hn J)
obtain ⟨cut, hcut⟩ := hJ
let e := reindexSL (A := R p) (cutOrder cut)
let P := (intersectionGroup p n hn J).map e.toMonoidHom
let H := (rootGroup p n hn J).map e.toMonoidHom
have hHP : H ≤ P := Subgroup.map_mono (rootGroup_le_intersection p n hn J)
have hP : ∀ g ∈ P, Upper g := by
rintro _ ⟨g, hg, rfl⟩
have hg' := (mem_intersectionGroup p n hn J g).mp hg cut hcut
exact localGroup_le_cutUpper p hn cut hg'
have hE : ∀ g ∈ P, ∀ i j (h : i < j), E h.ne (g i j) ∈ H := by
rintro _ ⟨g, hg, rfl⟩ i j hij
obtain ⟨a, rfl⟩ := (cutOrder cut).surjective i
obtain ⟨b, rfl⟩ := (cutOrder cut).surjective j
have hab : a ≠ b := fun he => hij.ne (congrArg (cutOrder cut) he)
refine ⟨E hab (g a b), entry_root_mem p n hn J cut hcut g hg hab, ?_⟩
change reindexSL (cutOrder cut) _ = _
rw [reindexSL_E]
congr 1
exact (reindexSL_apply (cutOrder cut) g a b).symm
have hPH := upper_subgroup_le P H hHP hP hE
intro g hg
have : e g ∈ H := hPH ⟨g, hg, rfl⟩
obtain ⟨h, hh, he⟩ := this
exact e.injective he ▸ hh
theorem rootGroup_inter (hn : 1 ≤ n) (J K : Set (Fin (n + 1)))
(hJ : ∃ cut, cut ∉ J) (hK : ∃ cut, cut ∉ K) :
rootGroup p n hn J ⊓ rootGroup p n hn K = rootGroup p n hn (J ∩ K) := by
have hJK : ∃ cut, cut ∉ J ∩ K := by
obtain ⟨cut, hc⟩ := hJ
exact ⟨cut, fun h => hc h.1⟩
rw [rootGroup_eq_intersection p n hn J hJ, rootGroup_eq_intersection p n hn K hK,
rootGroup_eq_intersection p n hn (J ∩ K) hJK]
ext g
simp only [Subgroup.mem_inf, mem_intersectionGroup, Set.mem_inter_iff]
constructor
· rintro ⟨hJ', hK'⟩ cut hc
by_cases h : cut ∈ J
· exact hK' cut (fun hk => hc ⟨h, hk⟩)
· exact hJ' cut h
· intro h
exact ⟨fun cut hc => h cut (fun hjk => hc hjk.1),
fun cut hc => h cut (fun hjk => hc hjk.2)⟩
def standardLocalGroup (hn : 1 ≤ n) (J : Set (Fin (n + 1))) :
Subgroup (Matrix.SpecialLinearGroup (Fin (n + 1)) (ZMod p)) :=
Subgroup.closure {g | ∃ j ∈ J, g = E (edgeSource_ne n hn j) (1 : ZMod p)}
theorem rootGroup_image_eq_standard (hn : 1 ≤ n) (J : Set (Fin (n + 1)))
(cut : Fin (n + 1)) (hc : cut ∉ J) :
(rootGroup p n hn J).map (cutConjugation p n cut) =
(standardLocalGroup p n hn J).map (Matrix.SpecialLinearGroup.mapGL (Frac p)) := by
rw [rootGroup, standardLocalGroup, MonoidHom.map_closure, MonoidHom.map_closure]
congr 1
ext g
constructor
· rintro ⟨_, ⟨j, hj, rfl⟩, rfl⟩
refine ⟨E (edgeSource_ne n hn j) 1, ⟨j, hj, rfl⟩, ?_⟩
have hjc : j ≠ cut := by intro he; subst cut; contradiction
rw [cutConjugation_root p n hn cut j hjc]
apply Matrix.GeneralLinearGroup.ext
intro a b
rfl
· rintro ⟨_, ⟨j, hj, rfl⟩, rfl⟩
refine ⟨cycleRoot p n hn j, ⟨j, hj, rfl⟩, ?_⟩
have hjc : j ≠ cut := by intro he; subst cut; contradiction
rw [cutConjugation_root p n hn cut j hjc]
apply Matrix.GeneralLinearGroup.ext
intro a b
rfl
def localStandardEquiv (hn : 1 ≤ n) (J : Set (Fin (n + 1)))
(cut : Fin (n + 1)) (hc : cut ∉ J) :
rootGroup p n hn J ≃* standardLocalGroup p n hn J :=
((rootGroup p n hn J).equivMapOfInjective (cutConjugation p n cut)
(cutConjugation_injective p n cut)).trans
((MulEquiv.subgroupCongr (rootGroup_image_eq_standard p n hn J cut hc)).trans
((standardLocalGroup p n hn J).equivMapOfInjective
(Matrix.SpecialLinearGroup.mapGL (Frac p)) Matrix.SpecialLinearGroup.mapGL_injective).symm)
end CoboundaryExpanders.Patterns
namespace CoboundaryExpanders.MatrixOpposition
open Module Submodule SphericalOpposition SphericalOpposition.CompleteFlag Elementary
open scoped Matrix Pointwise
variable {K : Type} [Field K] {N : ℕ}
abbrev oppFlag (K : Type) [Field K] (N : ℕ) : CompleteFlag K (Fin N → K) N :=
oppositeBasisFlag (K:=K) (V:=Fin N → K) (Pi.basisFun K (Fin N))
lemma stdFlags_opposite : (stdFlag K N).Opposite (oppFlag K N) :=
basisFlags_opposite _
def upperToFlag : upperGroup K N →* (stdFlag K N).unipotentFlagStabilizer :=
{ toFun := fun g => ⟨Matrix.SpecialLinearGroup.toLin' g.val,g.property⟩
map_one' := by apply Subtype.ext; exact map_one _
map_mul' := fun g h => by apply Subtype.ext; exact map_mul _ _ _ }
lemma upperToFlag_injective : Function.Injective (upperToFlag (K:=K) (N:=N)) := by
intro g h he
apply Subtype.ext
exact Matrix.SpecialLinearGroup.toLin'_injective (congrArg Subtype.val he)
lemma upperToFlag_surjective : Function.Surjective (upperToFlag (K:=K) (N:=N)) := by
intro e
let M := LinearMap.toMatrix' e.val.toLinearMap
have he : Unitriangular (Pi.basisFun K (Fin N)) e.val :=
(mem_unipotent_iff_unitriangular _ _ (basisFlag_adapted _) _).mp e.property
have hM (i j : Fin N) (hji : j ≤ i) : M i j = if i = j then 1 else 0 := by
simpa only [M, LinearMap.toMatrix'_apply, Pi.basisFun_repr, Pi.basisFun_apply, LinearEquiv.coe_coe] using he j i hji
have ht : M.IsUpperTriangular := by
intro i j hji
change j < i at hji
rw [hM i j hji.le, ite_eq_right hji.ne.symm]
have hd : M.det = 1 := by
rw [Matrix.det_of_isUpperTriangular ht]
apply Finset.prod_eq_one
intro i hi
rw [hM i i le_rfl, ite_eq_left rfl]
let g : Matrix.SpecialLinearGroup (Fin N) K := ⟨M,hd⟩
have hge : Matrix.SpecialLinearGroup.toLin' g = e.val := by
apply LinearEquiv.toLinearMap_injective
change Matrix.toLin' (LinearMap.toMatrix' e.val.toLinearMap) = e.val.toLinearMap
exact Matrix.toLin'_toMatrix' _
have hg : g ∈ upperGroup K N := by
rw [mem_upperGroup]
intro i j hji
change M i j = _
simpa only [Matrix.one_apply] using hM i j hji
exact ⟨⟨g,hg⟩,Subtype.ext hge⟩
def upperFlagEquiv : upperGroup K N ≃* (stdFlag K N).unipotentFlagStabilizer :=
MulEquiv.ofBijective upperToFlag ⟨upperToFlag_injective, upperToFlag_surjective⟩
lemma upper_E {i j : Fin N} (hij : i < j) (c : K) : E hij.ne c ∈ upperGroup K N := by
rw [mem_upperGroup]
simpa only [mul_one] using upper_E_mul hij c (g:=1) (fun i j _ => rfl)
lemma preserves_suffix_iff (g : upperGroup K N) (k : Fin (N+1)) :
((oppFlag K N).space ⟨N-k.val,by omega⟩).map
(Matrix.SpecialLinearGroup.toLin' g.val).toLinearMap =
(oppFlag K N).space ⟨N-k.val,by omega⟩ ↔
∀ i j : Fin N, i.val < k.val → k.val ≤ j.val → g.val i j = 0 := by
let e := Matrix.SpecialLinearGroup.toLin' g.val
have hm := (oppFlag K N).mem_opposite_flag_iff_repr (Pi.basisFun K (Fin N))
(oppositeBasisFlag_adapted _) k
simp only [Pi.basisFun_repr] at hm
constructor
· intro h i j hi hj
have hb : Pi.single j (1:K) ∈ (oppFlag K N).space ⟨N-k.val,by omega⟩ := by
apply (hm _).mpr
intro a ha
simp only [Pi.single_apply, ite_eq_right (show a ≠ j by intro he; subst j; omega)]
have he' : e (Pi.single j 1) ∈ (oppFlag K N).space ⟨N-k.val,by omega⟩ := by
rw [← h]
exact ⟨_,hb,rfl⟩
have hh := (hm _).mp he' i hi
simpa only [e, Matrix.SpecialLinearGroup.toLin'_apply,Matrix.toLin'_apply,
Matrix.mulVec_single_one,Matrix.col_apply] using hh
· intro h
apply Submodule.eq_of_le_of_finrank_eq
· rintro _ ⟨v,hv,rfl⟩
apply (hm _).mpr
intro i hi
change (g.val.val *ᵥ v) i = 0
rw [Matrix.mulVec, dotProduct]
apply Finset.sum_eq_zero
intro j hj
by_cases hk : k.val ≤ j.val
· rw [h i j hi hk,zero_mul]
· rw [(hm v).mp hv j (by omega),mul_zero]
· exact e.finrank_map_eq _
def suffixStabilizer (K : Type) [Field K] (k : Fin N) :
Subgroup (Matrix.SpecialLinearGroup (Fin N) K) :=
(MulAction.stabilizer ((Fin N → K) ≃ₗ[K] (Fin N → K))
((oppFlag K N).space ⟨N-k.val,by omega⟩)).comap Matrix.SpecialLinearGroup.toLin'
def patternGroup (K : Type) [Field K] (J : Set (Fin N)) :
Subgroup (Matrix.SpecialLinearGroup (Fin N) K) :=
upperGroup K N ⊓ ⨅ k : Fin N, ⨅ (_ : k ∉ J), suffixStabilizer K k
lemma mem_suffixStabilizer (g : Matrix.SpecialLinearGroup (Fin N) K) (k : Fin N) :
g ∈ suffixStabilizer K k ↔
((oppFlag K N).space ⟨N-k.val,by omega⟩).map
(Matrix.SpecialLinearGroup.toLin' g).toLinearMap =
(oppFlag K N).space ⟨N-k.val,by omega⟩ := by
simp only [suffixStabilizer, Subgroup.mem_comap, MulAction.mem_stabilizer_iff]
rfl
lemma mem_patternGroup (J : Set (Fin N)) (g : Matrix.SpecialLinearGroup (Fin N) K) :
g ∈ patternGroup K J ↔ Upper g ∧
∀ k : Fin N, k ∉ J → ∀ i j : Fin N,
i.val < k.val → k.val ≤ j.val → g i j = 0 := by
simp only [patternGroup,Subgroup.mem_inf,Subgroup.mem_iInf,mem_upperGroup]
constructor
· rintro ⟨hg,hs⟩
refine ⟨hg,fun k hk => ?_⟩
exact (preserves_suffix_iff ⟨g,(mem_upperGroup g).mpr hg⟩ k.castSucc).mp
((mem_suffixStabilizer g k).mp (hs k hk))
· rintro ⟨hg,hs⟩
refine ⟨hg,fun k hk => (mem_suffixStabilizer g k).mpr ?_⟩
exact (preserves_suffix_iff ⟨g,(mem_upperGroup g).mpr hg⟩ k.castSucc).mpr (hs k hk)
def pathGroup (K : Type) [Field K] (J : Set (Fin N)) :
Subgroup (Matrix.SpecialLinearGroup (Fin N) K) :=
Subgroup.closure {g | ∃ i j : Fin N, ∃ h : i.val+1 = j.val,
j ∈ J ∧ g = E (show i ≠ j by intro he; subst j; omega) (1:K)}
lemma adjacent_mem_pathGroup (J : Set (Fin N)) {i j : Fin N}
(h : i.val+1 = j.val) (hj : j ∈ J) :
E (show i ≠ j by intro he; subst j; omega) (1:K) ∈ pathGroup K J :=
Subgroup.subset_closure ⟨i,j,h,hj,rfl⟩
lemma pathGroup_le_pattern (J : Set (Fin N)) : pathGroup K J ≤ patternGroup K J := by
apply (Subgroup.closure_le _).mpr
rintro g ⟨i,j,h,hj,rfl⟩
apply (mem_patternGroup J _).mpr
refine ⟨(mem_upperGroup _).mp (upper_E (show i < j by change i.val < j.val; omega) 1),?_⟩
intro k hk a b hak hkb
have hab : a ≠ b := by intro he; subst b; omega
have hn : ¬ (a = i ∧ b = j) := by
rintro ⟨hai,hbj⟩
have ha := congrArg Fin.val hai
have hb := congrArg Fin.val hbj
have he : k = j := by apply Fin.ext; omega
exact hk (he.symm ▸ hj)
have hn' : ¬ (i = a ∧ j = b) := fun h => hn ⟨h.1.symm,h.2.symm⟩
change (1 + Matrix.single i j (1:K)) a b = 0
simp [Matrix.add_apply,hab,hn']
lemma E_path_one_mem (J : Set (Fin N)) {i j : Fin N} (hij : i < j)
(hpath : ∀ k : Fin N, i.val < k.val → k.val ≤ j.val → k ∈ J) :
E hij.ne (1:K) ∈ pathGroup K J := by
generalize hdiff : j.val-i.val = r
induction r using Nat.strong_induction_on generalizing i j with
| h r ih =>
by_cases hadj : i.val+1 = j.val
· exact adjacent_mem_pathGroup J hadj (hpath j hij le_rfl)
· let c : Fin N := ⟨j.val-1,by omega⟩
have hic : i < c := by change i.val < j.val-1; omega
have hcj : c.val+1 = j.val := by dsimp [c]; omega
have hcj' : c < j := by change c.val < j.val; omega
have hc := ih (c.val-i.val) (by omega) hic
(fun k hi hk => hpath k hi (hk.trans hcj'.le)) rfl
simpa only [mul_one] using E_path_mem (pathGroup K J) hic.ne hcj'.ne hij.ne hc
(adjacent_mem_pathGroup J hcj (hpath j hij le_rfl))
variable (p : ℕ) [Fact p.Prime]
lemma E_path_mem_coeff (J : Set (Fin N)) {i j : Fin N} (hij : i < j)
(hpath : ∀ k : Fin N, i.val < k.val → k.val ≤ j.val → k ∈ J) (c : ZMod p) :
E hij.ne c ∈ pathGroup (ZMod p) J := by
have hc : E hij.ne c = E hij.ne (1:ZMod p) ^ c.val := by
rw [← E_natCast_mul, ZMod.natCast_zmod_val, mul_one]
rw [hc]
exact (pathGroup (ZMod p) J).pow_mem (E_path_one_mem J hij hpath) _
theorem pathGroup_eq_pattern (J : Set (Fin N)) :
pathGroup (ZMod p) J = patternGroup (ZMod p) J := by
apply le_antisymm (pathGroup_le_pattern J)
apply upper_subgroup_le _ _ (pathGroup_le_pattern J)
· intro g hg
exact ((mem_patternGroup J g).mp hg).1
· intro g hg i j hij
by_cases hzero : g i j = 0
· rw [hzero]
simpa only [E,Matrix.SpecialLinearGroup.transvection_coeff_zero] using (pathGroup (ZMod p) J).one_mem
· apply E_path_mem_coeff p J hij
intro k hik hkj
by_contra hk
exact hzero (((mem_patternGroup J g).mp hg).2 k hk i j hik hkj)
lemma pathGroup_inter (J L : Set (Fin N)) :
pathGroup (ZMod p) J ⊓ pathGroup (ZMod p) L = pathGroup (ZMod p) (J ∩ L) := by
simp only [pathGroup_eq_pattern]
ext g
simp only [Subgroup.mem_inf,mem_patternGroup,Set.mem_inter_iff,not_and_or]
constructor
· rintro ⟨⟨hu,hJ⟩,⟨_,hL⟩⟩
exact ⟨hu,fun k hk => hk.elim (hJ k) (hL k)⟩
· rintro ⟨hu,h⟩
exact ⟨⟨hu,fun k hk => h k (Or.inl hk)⟩,⟨hu,fun k hk => h k (Or.inr hk)⟩⟩
lemma pathGroup_delete (k : Fin N) :
pathGroup (ZMod p) ({k}ᶜ) = upperGroup (ZMod p) N ⊓ suffixStabilizer (ZMod p) k := by
rw [pathGroup_eq_pattern]
ext g
simp [patternGroup]
end CoboundaryExpanders.MatrixOpposition
namespace CoboundaryExpanders.Patterns
section
open Construction Elementary MatrixOpposition SphericalOpposition.CompleteFlag
open scoped Matrix Pointwise
variable {n : ℕ}
lemma cutOrder_edgeSource (cut j : Fin (n+1)) (hj : j ≠ cut) :
(cutOrder cut (edgeSource n j)).val + 1 = (cutOrder cut j).val := by
have hjc : j.val ≠ cut.val := fun h => hj (Fin.ext h)
by_cases hj0 : j = 0
· subst j
have hc : 0 < cut.val := Nat.pos_of_ne_zero (Ne.symm hjc)
change (cutRank cut (Fin.last n)).val + 1 = (cutRank cut 0).val
change (if n < cut.val then n+(n+1)-cut.val else n-cut.val)+1 =
(if 0 < cut.val then 0+(n+1)-cut.val else 0-cut.val)
rw [ite_eq_right (by omega),ite_eq_left hc]
omega
· have hjv : 0 < j.val := by apply Nat.pos_of_ne_zero; intro h; exact hj0 (Fin.ext h)
change (cutRank cut (edgeSource n j)).val + 1 = (cutRank cut j).val
simp only [edgeSource,dite_eq_right hj0,cutRank,Fin.val_mk]
split_ifs <;> omega
variable (p n : ℕ) [Fact p.Prime]
theorem standard_reindex_eq_path (hn : 1 ≤ n) (J : Set (Fin (n+1)))
(cut : Fin (n+1)) (hc : cut ∉ J) :
(standardLocalGroup p n hn J).map (reindexSL (cutOrder cut)).toMonoidHom =
pathGroup (ZMod p) ((cutOrder cut) '' J) := by
rw [standardLocalGroup,MonoidHom.map_closure,pathGroup]
congr 1
ext g
constructor
· rintro ⟨_,⟨j,hj,rfl⟩,rfl⟩
have hjc : j ≠ cut := by intro he; exact hc (he ▸ hj)
refine ⟨cutOrder cut (edgeSource n j),cutOrder cut j,cutOrder_edgeSource cut j hjc,
⟨j,hj,rfl⟩,?_⟩
exact reindexSL_E _ _ _
· rintro ⟨i,j,h,hj,rfl⟩
obtain ⟨k,hk,rfl⟩ := hj
have hkc : k ≠ cut := by intro he; exact hc (he ▸ hk)
have hi : i = cutOrder cut (edgeSource n k) := by
apply Fin.ext
have := cutOrder_edgeSource cut k hkc
omega
refine ⟨E (edgeSource_ne n hn k) 1,⟨k,hk,rfl⟩,?_⟩
change reindexSL (cutOrder cut) (E (edgeSource_ne n hn k) 1) = _
subst i
exact reindexSL_E _ _ _
lemma cutOrder_image_compl (cut : Fin (n+1)) :
(cutOrder cut) '' ({cut}ᶜ : Set (Fin (n+1))) = ({0}ᶜ : Set (Fin (n+1))) := by
ext j
constructor
· rintro ⟨i,hi,rfl⟩
simpa only [Set.mem_compl_iff,Set.mem_singleton_iff,← cutOrder_cut cut,
(cutOrder cut).injective.eq_iff] using hi
· intro hj
refine ⟨(cutOrder cut).symm j,?_,(cutOrder cut).apply_symm_apply j⟩
intro hi
have hh : j = 0 := by
have he := congrArg (cutOrder cut) hi
simpa using he
exact hj hh
lemma pathGroup_compl_zero :
pathGroup (ZMod p) ({(0:Fin (n+1))}ᶜ) = upperGroup (ZMod p) (n+1) := by
rw [pathGroup_eq_pattern]
ext g
simp [mem_patternGroup]
theorem standard_max_reindex (hn : 1 ≤ n) (cut : Fin (n+1)) :
(standardLocalGroup p n hn ({cut}ᶜ)).map (reindexSL (cutOrder cut)).toMonoidHom =
upperGroup (ZMod p) (n+1) := by
rw [standard_reindex_eq_path p n hn _ cut (by simp),cutOrder_image_compl,pathGroup_compl_zero]
def standardMaxFlagEquiv (hn : 1 ≤ n) (cut : Fin (n+1)) :
standardLocalGroup p n hn ({cut}ᶜ) ≃*
(stdFlag (ZMod p) (n+1)).unipotentFlagStabilizer :=
((standardLocalGroup p n hn ({cut}ᶜ)).equivMapOfInjective
(reindexSL (cutOrder cut)).toMonoidHom (reindexSL (cutOrder cut)).injective).trans
((MulEquiv.subgroupCongr (standard_max_reindex p n hn cut)).trans upperFlagEquiv)
def localFlagEquiv (hn : 1 ≤ n) (cut : Fin (n+1)) :
localGroup p n hn cut ≃* (stdFlag (ZMod p) (n+1)).unipotentFlagStabilizer :=
(MulEquiv.subgroupCongr (rootGroup_compl_singleton p n hn cut)).symm.trans
((localStandardEquiv p n hn ({cut}ᶜ) cut (by simp)).trans
(standardMaxFlagEquiv p n hn cut))
end
section
open Construction Elementary MatrixOpposition SphericalOpposition.CompleteFlag
open scoped Matrix Pointwise
variable (p n : ℕ) [Fact p.Prime]
lemma localStandardEquiv_equation (hn : 1 ≤ n) (J : Set (Fin (n+1)))
(cut : Fin (n+1)) (hc : cut ∉ J) (g : rootGroup p n hn J) :
Matrix.SpecialLinearGroup.mapGL (Frac p) (localStandardEquiv p n hn J cut hc g).val =
cutConjugation p n cut g.val := by
exact congrArg Subtype.val
(((standardLocalGroup p n hn J).equivMapOfInjective
(Matrix.SpecialLinearGroup.mapGL (Frac p)) Matrix.SpecialLinearGroup.mapGL_injective).apply_symm_apply _)
lemma localStandardEquiv_mem_iff (hn : 1 ≤ n) (J L : Set (Fin (n+1)))
(cut : Fin (n+1)) (hcJ : cut ∉ J) (hcL : cut ∉ L)
(g : rootGroup p n hn J) :
(localStandardEquiv p n hn J cut hcJ g).val ∈ standardLocalGroup p n hn L ↔
g.val ∈ rootGroup p n hn L := by
have he := localStandardEquiv_equation p n hn J cut hcJ g
have hm := rootGroup_image_eq_standard p n hn L cut hcL
constructor
· intro hg
have hh : cutConjugation p n cut g.val ∈
(standardLocalGroup p n hn L).map (Matrix.SpecialLinearGroup.mapGL (Frac p)) := by
rw [← he]
exact Subgroup.mem_map_of_mem _ hg
rw [← hm] at hh
obtain ⟨x,hx,hxg⟩ := hh
have hxg' := cutConjugation_injective p n cut hxg
exact hxg' ▸ hx
· intro hg
have hh : Matrix.SpecialLinearGroup.mapGL (Frac p)
(localStandardEquiv p n hn J cut hcJ g).val ∈
(rootGroup p n hn L).map (cutConjugation p n cut) := by
rw [he]
exact Subgroup.mem_map_of_mem _ hg
rw [hm] at hh
obtain ⟨x,hx,hxg⟩ := hh
have hxg' := Matrix.SpecialLinearGroup.mapGL_injective hxg
exact hxg' ▸ hx
lemma reindex_mem_iff (hn : 1 ≤ n) (J : Set (Fin (n+1))) (cut : Fin (n+1))
(hc : cut ∉ J) (g : Matrix.SpecialLinearGroup (Fin (n+1)) (ZMod p)) :
reindexSL (cutOrder cut) g ∈ pathGroup (ZMod p) ((cutOrder cut) '' J) ↔
g ∈ standardLocalGroup p n hn J := by
rw [← standard_reindex_eq_path p n hn J cut hc]
constructor
· rintro ⟨x,hx,hxg⟩
exact ((reindexSL (cutOrder cut)).injective hxg) ▸ hx
· intro hg
exact Subgroup.mem_map_of_mem _ hg
lemma two_cuts_image (cut j : Fin (n+1)) :
cutOrder cut '' (({cut}ᶜ ∩ {j}ᶜ : Set (Fin (n+1)))) =
({0}ᶜ ∩ {cutOrder cut j}ᶜ) := by
rw [Set.image_inter (cutOrder cut).injective,cutOrder_image_compl]
congr 1
rw [Set.image_compl_eq (cutOrder cut).bijective,Set.image_singleton]
lemma pathGroup_delete_zero (k : Fin (n+1)) :
pathGroup (ZMod p) (({0}ᶜ ∩ {k}ᶜ : Set (Fin (n+1)))) =
upperGroup (ZMod p) (n+1) ⊓ suffixStabilizer (ZMod p) k := by
rw [← pathGroup_inter,pathGroup_compl_zero,pathGroup_delete,inf_of_le_right inf_le_left]
lemma standardMaxFlagEquiv_value (hn : 1 ≤ n) (cut : Fin (n+1))
(g : standardLocalGroup p n hn ({cut}ᶜ)) :
(standardMaxFlagEquiv p n hn cut g).val =
Matrix.SpecialLinearGroup.toLin' (reindexSL (cutOrder cut) g.val) := rfl
theorem standardMaxFlagEquiv_stabilizer (hn : 1 ≤ n) (cut j : Fin (n+1))
(g : standardLocalGroup p n hn ({cut}ᶜ)) :
(standardMaxFlagEquiv p n hn cut g).val ∈
MulAction.stabilizer ((Fin (n+1) → ZMod p) ≃ₗ[ZMod p] (Fin (n+1) → ZMod p))
((oppFlag (ZMod p) (n+1)).space ⟨n+1-(cutOrder cut j).val,by omega⟩) ↔
g.val ∈ standardLocalGroup p n hn ({cut}ᶜ ∩ {j}ᶜ) := by
rw [standardMaxFlagEquiv_value]
change reindexSL (cutOrder cut) g.val ∈ suffixStabilizer (ZMod p) (cutOrder cut j) ↔ _
have hu : reindexSL (cutOrder cut) g.val ∈ upperGroup (ZMod p) (n+1) := by
rw [← standard_max_reindex p n hn cut]
exact Subgroup.mem_map_of_mem _ g.property
rw [← reindex_mem_iff p n hn _ cut (by simp),two_cuts_image,pathGroup_delete_zero]
exact (and_iff_right hu).symm
theorem localFlagEquiv_stabilizer (hn : 1 ≤ n) (cut j : Fin (n+1))
(g : localGroup p n hn cut) :
(localFlagEquiv p n hn cut g).val ∈
MulAction.stabilizer ((Fin (n+1) → ZMod p) ≃ₗ[ZMod p] (Fin (n+1) → ZMod p))
((oppFlag (ZMod p) (n+1)).space ⟨n+1-(cutOrder cut j).val,by omega⟩) ↔
g.val ∈ localGroup p n hn j := by
let gg : rootGroup p n hn ({cut}ᶜ) :=
(MulEquiv.subgroupCongr (rootGroup_compl_singleton p n hn cut)).symm g
change (standardMaxFlagEquiv p n hn cut
(localStandardEquiv p n hn ({cut}ᶜ) cut (by simp) gg)).val ∈ _ ↔ _
rw [standardMaxFlagEquiv_stabilizer,
localStandardEquiv_mem_iff p n hn _ _ cut (by simp) (by simp)]
change g.val ∈ rootGroup p n hn ({cut}ᶜ ∩ {j}ᶜ) ↔ _
rw [← rootGroup_inter p n hn ({cut}ᶜ) ({j}ᶜ) ⟨cut,by simp⟩ ⟨j,by simp⟩,
rootGroup_compl_singleton,rootGroup_compl_singleton]
exact and_iff_right g.property
end
variable {n : ℕ}
lemma cutOrder_pos (cut j : Fin (n+1)) (hj : j ≠ cut) : 0 < (cutOrder cut j).val := by
by_contra h
have he : cutOrder cut j = 0 := Fin.ext (Nat.eq_zero_of_not_pos h)
rw [← cutOrder_cut cut] at he
exact hj ((cutOrder cut).injective he)
def localTypeIndex (cut : Fin (n+1)) (j : {j : Fin (n+1) // j ≠ cut}) : Fin n :=
⟨n-(cutOrder cut j.val).val,by have := cutOrder_pos cut j.val j.property; omega⟩
lemma localTypeIndex_bijective (cut : Fin (n+1)) : Function.Bijective (localTypeIndex cut) := by
constructor
· intro i j he
have h := congrArg Fin.val he
apply Subtype.ext
apply (cutOrder cut).injective
apply Fin.ext
dsimp [localTypeIndex] at h
have hi := (cutOrder cut i.val).isLt
have hj := (cutOrder cut j.val).isLt
omega
· intro i
let k : Fin (n+1) := ⟨n-i.val,by omega⟩
have hk : k ≠ 0 := by intro he; have h := congrArg Fin.val he; dsimp [k] at h; omega
let j : Fin (n+1) := (cutOrder cut).symm k
have hj : j ≠ cut := by
intro he
have hh := congrArg (cutOrder cut) he
have hkj : cutOrder cut j = k := (cutOrder cut).apply_symm_apply k
rw [hkj,cutOrder_cut] at hh
exact hk hh
refine ⟨⟨j,hj⟩,?_⟩
apply Fin.ext
change n-(cutOrder cut ((cutOrder cut).symm k)).val = i.val
rw [(cutOrder cut).apply_symm_apply]
dsimp [k]
omega
def localTypeEquiv (cut : Fin (n+1)) : {j : Fin (n+1) // j ≠ cut} ≃ Fin n :=
Equiv.ofBijective (localTypeIndex cut) (localTypeIndex_bijective cut)
lemma localTypeEquiv_rank (cut : Fin (n+1)) (j : {j : Fin (n+1) // j ≠ cut}) :
(localTypeEquiv cut j).val+1 = n+1-(cutOrder cut j.val).val := by
change n-(cutOrder cut j.val).val+1 = _
have h := (cutOrder cut j.val).isLt
omega
end CoboundaryExpanders.Patterns
namespace CoboundaryExpanders.MatrixOpposition
section
open Elementary
open scoped Matrix BigOperators
variable {K : Type} [Field K] {a b : ℕ}
lemma blockMatrix_upper (g : upperGroup K a) (h : upperGroup K b) :
∀ i j : Fin (a+b), j ≤ i → blockMatrix g.val.val h.val.val i j = (1 : Matrix _ _ K) i j := by
have hg := (mem_upperGroup _).mp g.property
have hh := (mem_upperGroup _).mp h.property
intro i j
induction i using Fin.addCases <;> induction j using Fin.addCases
· intro hji
simpa [Matrix.one_apply] using hg _ _ (by simpa only [Fin.le_def,Fin.val_castAdd,Fin.val_natAdd,Nat.add_le_add_iff_left] using hji)
· intro hji
have hv := Fin.le_iff_val_le_val.mp hji
simp only [Fin.val_natAdd,Fin.val_castAdd] at hv
omega
· intro _
rw [blockMatrix_rl,Matrix.one_apply,ite_eq_right]
intro he
have hv := congrArg Fin.val he
simp only [Fin.val_natAdd,Fin.val_castAdd] at hv
omega
· intro hji
simpa [Matrix.one_apply] using hh _ _ (by simpa only [Fin.le_def,Fin.val_castAdd,Fin.val_natAdd,Nat.add_le_add_iff_left] using hji)
def blockUpper : upperGroup K a × upperGroup K b →* upperGroup K (a+b) where
toFun gh := ⟨⟨blockMatrix gh.1.val.val gh.2.val.val,by
rw [blockMatrix_det,gh.1.val.property,gh.2.val.property,mul_one]⟩,
(mem_upperGroup _).mpr (blockMatrix_upper gh.1 gh.2)⟩
map_one' := by apply Subtype.ext; apply Subtype.ext; exact blockMatrix_one
map_mul' g h := by apply Subtype.ext; apply Subtype.ext; exact blockMatrix_mul _ _ _ _
lemma blockUpper_injective : Function.Injective (blockUpper (K:=K) (a:=a) (b:=b)) := by
intro g h he
have hh := congrArg (fun x : upperGroup K (a+b) => x.val.val) he
change blockMatrix g.1.val.val g.2.val.val = blockMatrix h.1.val.val h.2.val.val at hh
apply Prod.ext
· apply Subtype.ext; apply Subtype.ext
ext i j
simpa only [blockMatrix_ll] using congrArg (fun M => M (i.castAdd b) (j.castAdd b)) hh
· apply Subtype.ext; apply Subtype.ext
ext i j
simpa only [blockMatrix_rr] using congrArg (fun M => M (i.natAdd a) (j.natAdd a)) hh
lemma upper_submatrix {c : ℕ} (g : upperGroup K (a+b)) (e : Fin c ↪o Fin (a+b)) :
∃ h : upperGroup K c, h.val.val = g.val.val.submatrix e e := by
let M := g.val.val.submatrix e e
have hg := (mem_upperGroup _).mp g.property
have hM (i j : Fin c) (hji : j ≤ i) : M i j = (1 : Matrix _ _ K) i j := by
simpa [M,Matrix.submatrix_apply,Matrix.one_apply,e.injective.eq_iff] using hg (e i) (e j) (e.monotone hji)
have ht : M.IsUpperTriangular := by
intro i j hji
change j < i at hji
rw [hM i j hji.le,Matrix.one_apply,ite_eq_right hji.ne.symm]
have hd : M.det = 1 := by
rw [Matrix.det_of_isUpperTriangular ht]
apply Finset.prod_eq_one
intro i _
rw [hM i i le_rfl,Matrix.one_apply,ite_eq_left rfl]
exact ⟨⟨⟨M,hd⟩,(mem_upperGroup _).mpr hM⟩,rfl⟩
theorem range_blockUpper (g : upperGroup K (a+b)) :
g ∈ (blockUpper (K:=K) (a:=a) (b:=b)).range ↔
∀ i j : Fin (a+b), i.val < a → a ≤ j.val → g.val i j = 0 := by
constructor
· rintro ⟨⟨g,h⟩,rfl⟩ i j hi hj
induction i using Fin.addCases <;> induction j using Fin.addCases
· simp only [Fin.val_castAdd] at hj; omega
· exact blockMatrix_lr _ _ _ _
· simp only [Fin.val_natAdd] at hi; omega
· simp only [Fin.val_natAdd] at hi; omega
· intro hx
let el : Fin a ↪o Fin (a+b) := ⟨⟨Fin.castAdd b,Fin.castAdd_injective a b⟩,by intro i j; rfl⟩
let er : Fin b ↪o Fin (a+b) := ⟨⟨Fin.natAdd a,Fin.natAdd_injective b a⟩,by intro i j; simp⟩
obtain ⟨gl,hgl⟩ := upper_submatrix g el
obtain ⟨gr,hgr⟩ := upper_submatrix g er
refine ⟨(gl,gr),?_⟩
apply Subtype.ext; apply Subtype.ext
ext i j
change blockMatrix gl.val.val gr.val.val i j = g.val.val i j
induction i using Fin.addCases <;> induction j using Fin.addCases
· rw [blockMatrix_ll,hgl]; rfl
· rw [blockMatrix_lr,hx _ _ (by simp) (by simp)]
· rw [blockMatrix_rl,(mem_upperGroup _).mp g.property _ _ (by
apply Fin.le_iff_val_le_val.mpr; simp only [Fin.val_natAdd,Fin.val_castAdd]; omega)]
rw [Matrix.one_apply,ite_eq_right]
intro he
have hv := congrArg Fin.val he
simp only [Fin.val_natAdd,Fin.val_castAdd] at hv
omega
· rw [blockMatrix_rr,hgr]; rfl
def blockRangeEquiv : (upperGroup K a × upperGroup K b) ≃* (blockUpper (K:=K) (a:=a) (b:=b)).range :=
MonoidHom.ofInjective blockUpper_injective
end
open Elementary SphericalOpposition SphericalOpposition.CompleteFlag
open scoped Matrix Pointwise
variable {K : Type} [Field K] {a b N : ℕ}
def suffixGroup (K : Type) [Field K] (N : ℕ) (cut : Fin (N+1)) : Subgroup (upperGroup K N) :=
(MulAction.stabilizer ( (Fin N → K) ≃ₗ[K] (Fin N → K))
((oppFlag K N).space ⟨N-cut.val,by omega⟩)).comap
(Matrix.SpecialLinearGroup.toLin'.comp (upperGroup K N).subtype)
@[simp] lemma mem_suffixGroup (g : upperGroup K N) (cut : Fin (N+1)) :
g ∈ suffixGroup K N cut ↔
∀ i j : Fin N, i.val < cut.val → cut.val ≤ j.val → g.val i j = 0 := by
change Matrix.SpecialLinearGroup.toLin' g.val •
((oppFlag K N).space ⟨N-cut.val,by omega⟩) = _ ↔ _
exact preserves_suffix_iff g cut
lemma range_blockUpper_eq_suffixGroup :
(blockUpper (K:=K) (a:=a) (b:=b)).range = suffixGroup K (a+b) ⟨a,by omega⟩ := by
ext g
rw [range_blockUpper,mem_suffixGroup]
def blockSuffixEquiv : (upperGroup K a × upperGroup K b) ≃*
suffixGroup K (a+b) ⟨a,by omega⟩ :=
blockRangeEquiv.trans (MulEquiv.subgroupCongr range_blockUpper_eq_suffixGroup)
@[simp] lemma blockSuffixEquiv_val (g : upperGroup K a × upperGroup K b) :
(blockSuffixEquiv g).val = blockUpper g := rfl
lemma blockUpper_suffix_left (g : upperGroup K a × upperGroup K b) (cut : Fin (a+1)) :
blockUpper g ∈ suffixGroup K (a+b) ⟨cut.val,by omega⟩ ↔
g.1 ∈ suffixGroup K a cut := by
simp only [mem_suffixGroup]
constructor
· intro h i j hi hj
have he := h (i.castAdd b) (j.castAdd b) hi hj
change blockMatrix g.1.val.val g.2.val.val (i.castAdd b) (j.castAdd b) = 0 at he
simpa only [blockMatrix_ll] using he
· intro h i j hi hj
change blockMatrix g.1.val.val g.2.val.val i j = 0
induction i using Fin.addCases <;> induction j using Fin.addCases
· rw [blockMatrix_ll]
exact h _ _ hi hj
· exact blockMatrix_lr _ _ _ _
· exact blockMatrix_rl _ _ _ _
· simp only [Fin.val_natAdd] at hi
omega
lemma blockUpper_suffix_right (g : upperGroup K a × upperGroup K b) (cut : Fin (b+1)) :
blockUpper g ∈ suffixGroup K (a+b) ⟨a+cut.val,by omega⟩ ↔
g.2 ∈ suffixGroup K b cut := by
simp only [mem_suffixGroup]
constructor
· intro h i j hi hj
have he := h (i.natAdd a) (j.natAdd a) (by simpa using hi) (by simpa using hj)
change blockMatrix g.1.val.val g.2.val.val (i.natAdd a) (j.natAdd a) = 0 at he
simpa only [blockMatrix_rr] using he
· intro h i j hi hj
change blockMatrix g.1.val.val g.2.val.val i j = 0
induction i using Fin.addCases <;> induction j using Fin.addCases
· simp only [Fin.val_castAdd] at hj
omega
· exact blockMatrix_lr _ _ _ _
· exact blockMatrix_rl _ _ _ _
· rw [blockMatrix_rr]
exact h _ _ (by simpa using hi) (by simpa using hj)
def cutGroups (K : Type) [Field K] (N : ℕ) (c : Cut N) : Subgroup (upperGroup K N) :=
suffixGroup K N ⟨c.val,by have h := c.property; omega⟩
def cutSplitEquiv : (Cut a ⊕ Cut b) ≃ {c : Cut (a+b) // c.val ≠ a} where
toFun := fun c => match c with
| Sum.inl c => ⟨⟨c.val,by have h := c.property; omega⟩,by change c.val ≠ a; have h := c.property; omega⟩
| Sum.inr c => ⟨⟨a+c.val,by have h := c.property; omega⟩,by change a+c.val ≠ a; have h := c.property; omega⟩
invFun := fun c => if h : c.val.val < a then
Sum.inl ⟨c.val.val, c.val.property.1,h⟩
else Sum.inr ⟨c.val.val-a,by have h' := c.val.property; have hn := c.property; omega⟩
left_inv := by
intro c
cases c with
| inl c =>
simp only [c.property.2,dite_eq_left]
| inr c =>
dsimp only
rw [dite_eq_right (by omega : ¬ a+c.val < a)]
congr 1
apply Subtype.ext
dsimp
omega
right_inv := by
intro c
dsimp only
split_ifs with h
· rfl
· apply Subtype.ext; apply Subtype.ext
have h' := c.val.property
have hn := c.property
dsimp
omega
lemma blockSuffix_system (g : upperGroup K a × upperGroup K b)
(c : Cut a ⊕ Cut b) :
blockSuffixEquiv g ∈ (cutGroups K (a+b) (cutSplitEquiv c).val).comap
(suffixGroup K (a+b) ⟨a,Nat.lt_succ_of_le (Nat.le_add_right a b)⟩).subtype ↔
match c with
| Sum.inl c => g.1 ∈ cutGroups K a c
| Sum.inr c => g.2 ∈ cutGroups K b c := by
cases c with
| inl c => exact blockUpper_suffix_left g ⟨c.val,by have h := c.property; omega⟩
| inr c => exact blockUpper_suffix_right g ⟨c.val,by have h := c.property; omega⟩
end CoboundaryExpanders.MatrixOpposition
end
end OAI
end
section
-- module Solutions.OAIQ3_Cob.Coboundary_Links
attribute [-instance] _root_.OAI.CoboundaryExpanders.Blocks.gammaNormal _root_.OAI.CoboundaryExpanders.CongruenceFrames.invariant _root_.OAI.CoboundaryExpanders.InfiniteChains.Complex.faceMulAction _root_.OAI.CoboundaryExpanders.TypedCosetFaces.complexInvariant _root_.OAI.CoboundaryExpanders.TypedCosetFaces.kernelInvariant _root_.OAI.CoboundaryExpanders.TypedCosetFaces.vertexMulAction
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
/-!
Coset-link identifications, product and cut models, and all proper-link cone bounds.
-/
noncomputable section
open scoped BigOperators
open scoped BigOperators Matrix
open scoped Matrix
namespace CoboundaryExpanders.Construction
section
open Patterns MatrixOpposition SphericalOpposition.CompleteFlag
open scoped Pointwise
variable (p n : ℕ) [Fact p.Prime]
def reducedFlagEquiv (hn : 1 ≤ n) {m : ℕ} (hm : 2 ≤ m) (cut : Fin (n+1)) :
reducedLocalGroup p n hn m cut ≃*
(stdFlag (ZMod p) (n+1)).unipotentFlagStabilizer :=
(localReducedEquiv p n hn hm cut).symm.trans (localFlagEquiv p n hn cut)
lemma reducedFlagEquiv_stabilizer (hn : 1 ≤ n) {m : ℕ} (hm : 2 ≤ m)
(cut j : Fin (n+1)) (q : reducedLocalGroup p n hn m cut) :
(reducedFlagEquiv p n hn hm cut q).val ∈
MulAction.stabilizer ((Fin (n+1) → ZMod p) ≃ₗ[ZMod p] (Fin (n+1) → ZMod p))
((oppFlag (ZMod p) (n+1)).space ⟨n+1-(cutOrder cut j).val,by omega⟩) ↔
q.val ∈ reducedLocalGroup p n hn m j := by
change (localFlagEquiv p n hn cut ((localReducedEquiv p n hn hm cut).symm q)).val ∈ _ ↔ _
rw [localFlagEquiv_stabilizer]
have he : (localReducedHom p n hn m cut ((localReducedEquiv p n hn hm cut).symm q)).val = q.val :=
congrArg Subtype.val ((localReducedEquiv p n hn hm cut).apply_symm_apply q)
exact (localReducedHom_mem_iff p n hn hm cut j
((localReducedEquiv p n hn hm cut).symm q)).symm.trans (by rw [he])
end
section
open Patterns MatrixOpposition TypedCosetFaces SphericalOpposition.CompleteFlag
open scoped Pointwise
variable (p n : ℕ) [Fact p.Prime]
lemma quotientLinkGroups_correspond (hn : 1 ≤ n) {m : ℕ} (hm : 2 ≤ m)
(cut : Fin (n+1)) (j : {j : Fin (n+1) // j ≠ cut})
(q : reducedLocalGroup p n hn m cut) :
q ∈ quotientLinkGroups p n hn m cut j ↔
reducedFlagEquiv p n hn hm cut q ∈
(stdFlag (ZMod p) (n+1)).vertexStabilizers (oppFlag (ZMod p) (n+1))
(localTypeEquiv cut j) := by
change q.val ∈ reducedLocalGroup p n hn m j.val ↔
reducedFlagEquiv p n hn hm cut q ∈ MulAction.stabilizer _
((oppFlag (ZMod p) (n+1)).baseSpace (localTypeEquiv cut j))
have hr : properIndex (N:=n+1) (localTypeEquiv cut j) =
(⟨n+1-(cutOrder cut j.val).val,by omega⟩ : Fin (n+2)) :=
Fin.ext (localTypeEquiv_rank cut j)
rw [baseSpace,hr]
rw [MulAction.mem_stabilizer_iff]
change q.val ∈ reducedLocalGroup p n hn m j.val ↔
(reducedFlagEquiv p n hn hm cut q).val •
(oppFlag (ZMod p) (n+1)).space ⟨n+1-(cutOrder cut j.val).val,by omega⟩ =
(oppFlag (ZMod p) (n+1)).space ⟨n+1-(cutOrder cut j.val).val,by omega⟩
exact (reducedFlagEquiv_stabilizer p n hn hm cut j.val q).symm
def quotientLinkVertexModel (hn : 1 ≤ n) {m : ℕ} (hm : 2 ≤ m) (cut : Fin (n+1)) :
Vertex (quotientLinkGroups p n hn m cut) → Submodule (ZMod p) (Fin (n+1) → ZMod p) :=
((stdFlag (ZMod p) (n+1)).cosetVertexMap (oppFlag (ZMod p) (n+1))) ∘
isoVertex (quotientLinkGroups p n hn m cut)
((stdFlag (ZMod p) (n+1)).vertexStabilizers (oppFlag (ZMod p) (n+1)))
(reducedFlagEquiv p n hn hm cut) (localTypeEquiv cut)
(quotientLinkGroups_correspond p n hn hm cut)
lemma quotientLinkVertexModel_injective (hn : 1 ≤ n) {m : ℕ} (hm : 2 ≤ m) (cut : Fin (n+1)) :
Function.Injective (quotientLinkVertexModel p n hn hm cut) :=
((stdFlag (ZMod p) (n+1)).cosetVertexMap_injective (oppFlag (ZMod p) (n+1))).comp
(isoVertex_injective _ _ _ _ _)
theorem quotientLinkFace_iff (hn : 1 ≤ n) {m : ℕ} (hm : 2 ≤ m) (cut : Fin (n+1))
(s : Finset (Vertex (quotientLinkGroups p n hn m cut))) :
IsFace (quotientLinkGroups p n hn m cut) s ↔
s.image (quotientLinkVertexModel p n hn hm cut) ∈
(stdFlag (ZMod p) (n+1)).complex.faces := by
unfold quotientLinkVertexModel
rw [← Finset.image_image,← cosetFace_iff stdFlags_opposite,isoFace_iff]
theorem quotientLinkFace_surjective (hn : 1 ≤ n) {m : ℕ} (hm : 2 ≤ m) (cut : Fin (n+1))
(s : Finset (Submodule (ZMod p) (Fin (n+1) → ZMod p)))
(hs : s ∈ (stdFlag (ZMod p) (n+1)).complex.faces) :
∃ t : Finset (Vertex (quotientLinkGroups p n hn m cut)),
IsFace (quotientLinkGroups p n hn m cut) t ∧
t.image (quotientLinkVertexModel p n hn hm cut) = s := by
obtain ⟨g,A,hg⟩ := opposedFace_coset stdFlags_opposite s hs
let e := reducedFlagEquiv p n hn hm cut
let r := localTypeEquiv cut
refine ⟨face (quotientLinkGroups p n hn m cut) (e.symm g) (A.image r.symm),⟨_,_,rfl⟩,?_⟩
unfold quotientLinkVertexModel
rw [← Finset.image_image,isoFace_image,e.apply_symm_apply]
have hi : (A.image r.symm).image r = A := by ext j; simp
rw [hi]
exact hg
end
open InfiniteChains InfiniteChains.Cone TypedCosetFaces SphericalOpposition.CompleteFlag
open Patterns MatrixOpposition
variable (p n : ℕ) [Fact p.Prime]
def sphericalLinkModel (hn : 1 ≤ n) {m : ℕ} (hm : 2 ≤ m) (cut : Fin (n+1)) :
FaceModel (TypedCosetFaces.complex (quotientLinkGroups p n hn m cut))
(stdFlag (ZMod p) (n+1)).complex where
vertex := quotientLinkVertexModel p n hn hm cut
injective := quotientLinkVertexModel_injective p n hn hm cut
face_iff := fun s => (quotientLinkFace_iff p n hn hm cut s).symm
cover := fun t ht => quotientLinkFace_surjective p n hn hm cut t ht
end CoboundaryExpanders.Construction
namespace CoboundaryExpanders.InfiniteChains
namespace Complex
variable {V : Type} [DecidableEq V] (X : CoboundaryExpanders.InfiniteChains.Complex V)
def faceLink (s : Finset V) (hs : s ∈ X.faces) : CoboundaryExpanders.InfiniteChains.Complex V where
faces := {a | Disjoint s a ∧ s ∪ a ∈ X.faces}
empty_mem := ⟨Finset.disjoint_empty_right _,by simpa using hs⟩
downward := by
intro a b ha hb
exact ⟨Finset.disjoint_left.mpr (fun v hv hv' => Finset.disjoint_left.mp ha.1 hv (hb hv')),
X.downward ha.2 (Finset.union_subset_union (Finset.Subset.refl _) hb)⟩
end Complex
open Cone
variable {V W : Type} [DecidableEq V] [DecidableEq W]
attribute [local instance] Classical.propDecidable
namespace Cone.FaceModel
variable {X : CoboundaryExpanders.InfiniteChains.Complex V} {Y : CoboundaryExpanders.InfiniteChains.Complex W} (M : FaceModel X Y)
def linkModel (s : Finset V) (hs : s ∈ X.faces) :
FaceModel (X.faceLink s hs) (Y.faceLink (s.image M.vertex) ((M.face_iff s).mpr hs)) where
vertex := M.vertex
injective := M.injective
face_iff := by
intro a
change Disjoint (s.image M.vertex) (a.image M.vertex) ∧
s.image M.vertex ∪ a.image M.vertex ∈ Y.faces ↔
Disjoint s a ∧ s ∪ a ∈ X.faces
rw [←Finset.image_union,M.face_iff,Finset.disjoint_image M.injective]
cover := by
intro t ht
obtain ⟨a,ha,he⟩ := M.cover t (Y.downward ht.2 Finset.subset_union_right)
refine ⟨a,⟨?_,?_⟩,he⟩
· rw [←Finset.disjoint_image M.injective,he]
exact ht.1
· apply (M.face_iff _).mp
rw [Finset.image_union,he]
exact ht.2
end Cone.FaceModel
namespace Join
def emptyLeftModel {X : CoboundaryExpanders.InfiniteChains.Complex W} {Y : CoboundaryExpanders.InfiniteChains.Complex V}
(hX : ∀ s ∈ X.faces, s = ∅) : FaceModel Y (complex X Y) where
vertex := Sum.inr
injective := Sum.inr_injective
face_iff := by
intro s
change (s.image Sum.inr).toLeft ∈ X.faces ∧ (s.image Sum.inr).toRight ∈ Y.faces ↔ _
have hL : (s.image (Sum.inr : V → W ⊕ V)).toLeft = ∅ := by ext a; simp
have hR : (s.image (Sum.inr : V → W ⊕ V)).toRight = s := by ext a; simp
rw [hL,hR]
simp only [X.empty_mem,true_and]
cover := by
intro t ht
refine ⟨t.toRight,ht.2,?_⟩
have he := Finset.toLeft_disjSum_toRight (u:=t)
rw [hX t.toLeft ht.1] at he
rw [Finset.empty_disjSum,Finset.map_eq_image] at he
exact he
end Join
end CoboundaryExpanders.InfiniteChains
namespace CoboundaryExpanders.TypedCosetFaces
variable {G K I J : Type} [Group G] [Group K] [DecidableEq I] [DecidableEq J]
(H : I → Subgroup G) (L : J → Subgroup K)
def embedLeft : Vertex H → Vertex (productGroups H L)
| ⟨i,q⟩ => Quotient.lift (fun g : G => vertex (productGroups H L) (g,1) (Sum.inl i)) (by
intro g h hgh
refine Sigma.ext (by rfl) (heq_of_eq ?_)
apply Quotient.sound
apply QuotientGroup.leftRel_apply.mpr
exact ⟨QuotientGroup.leftRel_apply.mp hgh,Subgroup.mem_top _⟩) q
def embedRight : Vertex L → Vertex (productGroups H L)
| ⟨j,q⟩ => Quotient.lift (fun g : K => vertex (productGroups H L) (1,g) (Sum.inr j)) (by
intro g h hgh
refine Sigma.ext (by rfl) (heq_of_eq ?_)
apply Quotient.sound
apply QuotientGroup.leftRel_apply.mpr
exact ⟨Subgroup.mem_top _,QuotientGroup.leftRel_apply.mp hgh⟩) q
def productVertexEquiv : Vertex (productGroups H L) ≃ Vertex H ⊕ Vertex L where
toFun := productVertex H L
invFun := Sum.elim (embedLeft H L) (embedRight H L)
left_inv := by
rintro ⟨i,q⟩
cases i with
| inl i =>
induction q using Quotient.inductionOn with | h g =>
refine Sigma.ext (by rfl) (heq_of_eq ?_)
apply Quotient.sound
apply QuotientGroup.leftRel_apply.mpr
change g.1⁻¹*g.1 ∈ H i ∧ _
simp
| inr j =>
induction q using Quotient.inductionOn with | h g =>
refine Sigma.ext (by rfl) (heq_of_eq ?_)
apply Quotient.sound
apply QuotientGroup.leftRel_apply.mpr
change _ ∧ g.2⁻¹*g.2 ∈ L j
simp
right_inv := by
intro x
cases x with
| inl x =>
rcases x with ⟨i,q⟩
induction q using Quotient.inductionOn with | h g => rfl
| inr x =>
rcases x with ⟨j,q⟩
induction q using Quotient.inductionOn with | h g => rfl
lemma productFace_image (g : G) (k : K) (A : Finset I) (B : Finset J) :
(face (productGroups H L) (g,k) (A.image Sum.inl ∪ B.image Sum.inr)).image
(productVertex H L) = (face H g A).image Sum.inl ∪ (face L k B).image Sum.inr := by
simp only [face,Finset.image_union,Finset.image_image,Function.comp_def,
productVertex_left,productVertex_right]
lemma productFace_image_general (g : G × K) (A : Finset (I ⊕ J)) :
∃ (B : Finset I) (C : Finset J),
(face (productGroups H L) g A).image (productVertex H L) =
(face H g.1 B).image Sum.inl ∪ (face L g.2 C).image Sum.inr := by
refine ⟨A.toLeft,A.toRight,?_⟩
have he : A.toLeft.image Sum.inl ∪ A.toRight.image Sum.inr = A := by ext x; cases x <;> simp
calc
_ = (face (productGroups H L) g (A.toLeft.image Sum.inl ∪ A.toRight.image Sum.inr)).image (productVertex H L) := by rw [he]
_ = _ := productFace_image H L g.1 g.2 A.toLeft A.toRight
theorem productFace_iff (s : Finset (Vertex (productGroups H L))) :
IsFace (productGroups H L) s ↔ ∃ (sL : Finset (Vertex H)) (sR : Finset (Vertex L)),
IsFace H sL ∧ IsFace L sR ∧
s.image (productVertex H L) = sL.image Sum.inl ∪ sR.image Sum.inr := by
constructor
· rintro ⟨g,A,rfl⟩
obtain ⟨B,C,h⟩ := productFace_image_general H L g A
exact ⟨face H g.1 B,face L g.2 C,⟨_,_,rfl⟩,⟨_,_,rfl⟩,h⟩
· rintro ⟨sL,sR,⟨g,A,rfl⟩,⟨k,B,rfl⟩,he⟩
refine ⟨(g,k),A.image Sum.inl ∪ B.image Sum.inr,?_⟩
apply Finset.image_injective (productVertexEquiv H L).injective
exact (productFace_image H L g k A B).trans he.symm
end CoboundaryExpanders.TypedCosetFaces
namespace CoboundaryExpanders.InfiniteChains.Cone.FaceModel
variable {V W Z : Type} [DecidableEq V] [DecidableEq W] [DecidableEq Z]
variable {X : CoboundaryExpanders.InfiniteChains.Complex V} {Y : CoboundaryExpanders.InfiniteChains.Complex W} {T : CoboundaryExpanders.InfiniteChains.Complex Z}
def trans (M : FaceModel X Y) (L : FaceModel Y T) : FaceModel X T where
vertex := L.vertex ∘ M.vertex
injective := L.injective.comp M.injective
face_iff := by intro s; rw [←Finset.image_image,L.face_iff,M.face_iff]
cover := by
intro t ht
obtain ⟨b,hb,he⟩ := L.cover t ht
obtain ⟨a,ha,hf⟩ := M.cover b hb
exact ⟨a,ha,by rw [←Finset.image_image,hf,he]⟩
end CoboundaryExpanders.InfiniteChains.Cone.FaceModel
namespace CoboundaryExpanders.TypedCosetFaces
open InfiniteChains Cone
variable {G G' I I' : Type} [Group G] [Group G'] [DecidableEq I] [DecidableEq I']
variable (H : I → Subgroup G) (H' : I' → Subgroup G')
variable (e : G ≃* G') (r : I ≃ I') (he : ∀ i g, g ∈ H i ↔ e g ∈ H' (r i))
def isoModel : FaceModel (complex H) (complex H') where
vertex := isoVertex H H' e r he
injective := isoVertex_injective H H' e r he
face_iff := isoFace_iff H H' e r he
cover := by
intro t ht
let a := t.image (vertexEquiv H H' e r he).symm
have ha : a.image (isoVertex H H' e r he) = t := by
change a.image (vertexEquiv H H' e r he) = t
simp only [a,Finset.image_image,Function.comp_def,Equiv.apply_symm_apply,Finset.image_id']
exact ⟨a,(isoFace_iff H H' e r he a).mp (by rwa [ha]),ha⟩
variable {K J : Type} [Group K] [DecidableEq J] (L : J → Subgroup K)
def productModel : FaceModel (complex (productGroups H L)) (Join.complex (complex H) (complex L)) where
vertex := productVertex H L
injective := (productVertexEquiv H L).injective
face_iff := by
intro s
change IsFace H (s.image (productVertex H L)).toLeft ∧
IsFace L (s.image (productVertex H L)).toRight ↔ IsFace (productGroups H L) s
rw [productFace_iff]
constructor
· rintro ⟨hL,hR⟩
refine ⟨_,_,hL,hR,?_⟩
ext v
cases v <;> simp
· rintro ⟨a,b,ha,hb,he⟩
rw [he]
have hL : (a.image (Sum.inl : Vertex H → Vertex H ⊕ Vertex L) ∪ b.image Sum.inr).toLeft = a := by ext v; simp
have hR : (a.image (Sum.inl : Vertex H → Vertex H ⊕ Vertex L) ∪ b.image Sum.inr).toRight = b := by ext v; simp
exact ⟨by rwa [hL],by rwa [hR]⟩
cover := by
intro t ht
let s := t.image (productVertexEquiv H L).symm
have he : s.image (productVertex H L) = t := by
change s.image (productVertexEquiv H L) = t
simp only [s,Finset.image_image,Function.comp_def,Equiv.apply_symm_apply,Finset.image_id']
refine ⟨s,(productFace_iff H L s).mpr ⟨t.toLeft,t.toRight,ht.1,ht.2,?_⟩,he⟩
rw [he]
ext v
cases v <;> simp
end CoboundaryExpanders.TypedCosetFaces
namespace CoboundaryExpanders.MatrixOpposition
open SphericalOpposition SphericalOpposition.CompleteFlag TypedCosetFaces InfiniteChains Cone
open scoped Pointwise
variable {K : Type} [Field K] {N : ℕ}
lemma cutGroups_correspond (c : Cut N) (g : upperGroup K N) :
upperFlagEquiv g ∈ (stdFlag K N).vertexStabilizers (oppFlag K N) (cutTypeEquiv c) ↔
g ∈ cutGroups K N c := by
change upperFlagEquiv g • (oppFlag K N).baseSpace (cutTypeEquiv c) = _ ↔ _
have he : properIndex (N:=N) (cutTypeEquiv c) = (⟨N-c.val,by have h:=c.property; omega⟩:Fin (N+1)) := by
apply Fin.ext
have h:=c.property
dsimp [properIndex,cutTypeEquiv]
omega
unfold baseSpace
rw [he]
rfl
def cutSphericalModel : FaceModel (TypedCosetFaces.complex (cutGroups K N)) (stdFlag K N).complex :=
(isoModel (cutGroups K N) ((stdFlag K N).vertexStabilizers (oppFlag K N))
upperFlagEquiv cutTypeEquiv (fun c g => (cutGroups_correspond c g).symm)).trans
{ vertex := (stdFlag K N).cosetVertexMap (oppFlag K N)
injective := (stdFlag K N).cosetVertexMap_injective (oppFlag K N)
face_iff := fun s => (cosetFace_iff stdFlags_opposite s).symm
cover := fun s hs => by
obtain ⟨g,A,he⟩ := opposedFace_coset stdFlags_opposite s hs
exact ⟨_,⟨g,A,rfl⟩,he⟩ }
end CoboundaryExpanders.MatrixOpposition
namespace CoboundaryExpanders.TypedCosetFaces
open InfiniteChains Cone
variable {G I : Type} [Group G] [DecidableEq I] (H : I → Subgroup G)
lemma standard_face_mem (A : Finset I) : face H 1 A ∈ (complex H).faces := ⟨1,A,rfl⟩
def singleLinkModel (i : I) :
FaceModel (complex (vertexLinkGroups H i)) (linkComplex H {i}) where
vertex := vertexLinkEmbedding H i
injective := vertexLinkEmbedding_injective H i
face_iff := fun s => (vertexLinkFace_iff H i s).symm
cover := fun t ht => vertexLinkFace_surjective H i t ht
end CoboundaryExpanders.TypedCosetFaces
namespace CoboundaryExpanders.MatrixOpposition
open SphericalOpposition SphericalOpposition.CompleteFlag TypedCosetFaces InfiniteChains Cone
variable {K : Type} [Field K] {a b : ℕ}
def cutLinkTypes (ha : 0 < a) (hb : 0 < b) : Cut a ⊕ Cut b ≃
{c : Cut (a+b) // c ≠ middleCut ha hb} := cutSplitEquiv.trans
{ toFun := fun c => ⟨c.val,fun h => c.property (congrArg Subtype.val h)⟩
invFun := fun c => ⟨c.val,fun h => c.property (Subtype.ext h)⟩
left_inv := fun _ => rfl
right_inv := fun _ => rfl }
lemma cutLinkGroups_correspond (ha : 0 < a) (hb : 0 < b) (c : Cut a ⊕ Cut b)
(g : upperGroup K a × upperGroup K b) :
g ∈ productGroups (cutGroups K a) (cutGroups K b) c ↔
blockSuffixEquiv g ∈ vertexLinkGroups (cutGroups K (a+b)) (middleCut ha hb) (cutLinkTypes ha hb c) := by
have h := (blockSuffix_system g c).symm
cases c with
| inl c =>
change (g.1 ∈ cutGroups K a c ∧ True) ↔
(blockSuffixEquiv g).val ∈ cutGroups K (a+b) (cutSplitEquiv (Sum.inl c)).val
rw [and_true]
exact h
| inr c =>
change (True ∧ g.2 ∈ cutGroups K b c) ↔
(blockSuffixEquiv g).val ∈ cutGroups K (a+b) (cutSplitEquiv (Sum.inr c)).val
rw [true_and]
exact h
def cutProductLinkModel (ha : 0 < a) (hb : 0 < b) :
FaceModel (TypedCosetFaces.complex (productGroups (cutGroups K a) (cutGroups K b)))
(TypedCosetFaces.complex (vertexLinkGroups (cutGroups K (a+b)) (middleCut ha hb))) :=
isoModel _ _ blockSuffixEquiv (cutLinkTypes ha hb) (cutLinkGroups_correspond ha hb)
end CoboundaryExpanders.MatrixOpposition
namespace CoboundaryExpanders.TypedCosetFaces
open InfiniteChains Cone
open scoped Pointwise
variable {G I : Type} [Group G] [DecidableEq I] (H : I → Subgroup G)
omit [DecidableEq I] in
lemma IsFace.smul {s : Finset (Vertex H)} (hs : IsFace H s) (g : G) : IsFace H (g • s) := by
obtain ⟨h,A,rfl⟩ := hs
rw [smul_face]
exact ⟨g*h,A,rfl⟩
end CoboundaryExpanders.TypedCosetFaces
namespace CoboundaryExpanders.InfiniteChains
section
open Cone
variable {V W : Type} [DecidableEq V] [DecidableEq W]
namespace Cone.BoundedCone
variable {X : CoboundaryExpanders.InfiniteChains.Complex V} {n R : ℕ}
def weaken (H : BoundedCone X n R) {m S : ℕ} (hm : m ≤ n) (hS : R ≤ S) : BoundedCone X m S where
hom := H.hom
support := fun s hs hn => H.support s hs (hn.trans hm)
contraction := fun s hs hn => H.contraction s hs (hn.trans hm)
bound := fun s hs hn => (H.bound s hs (hn.trans hm)).trans hS
end Cone.BoundedCone
def RankBound (X : CoboundaryExpanders.InfiniteChains.Complex V) (N : ℕ) : Prop := ∀ s ∈ X.faces, s.card ≤ N
def AllLinkCones (X : CoboundaryExpanders.InfiniteChains.Complex V) (N R : ℕ) : Prop :=
∀ s : Finset V, ∀ hs : s ∈ X.faces, s.card < N →
Nonempty (BoundedCone (X.faceLink s hs) (N-s.card-1) R)
namespace Join
def emptyRightModel {X : CoboundaryExpanders.InfiniteChains.Complex W} {Y : CoboundaryExpanders.InfiniteChains.Complex V}
(hY : ∀ s ∈ Y.faces, s = ∅) : FaceModel X (complex X Y) where
vertex := Sum.inl
injective := Sum.inl_injective
face_iff := by
intro s
change (s.image Sum.inl).toLeft ∈ X.faces ∧ (s.image Sum.inl).toRight ∈ Y.faces ↔ _
have hL : (s.image (Sum.inl : W → W ⊕ V)).toLeft = s := by ext a; simp
have hR : (s.image (Sum.inl : W → W ⊕ V)).toRight = ∅ := by ext a; simp
rw [hL,hR]
simp only [Y.empty_mem,and_true]
cover := by
intro t ht
refine ⟨t.toLeft,ht.1,?_⟩
have he := Finset.toLeft_disjSum_toRight (u:=t)
rw [hY t.toRight ht.2,Finset.disjSum_empty,Finset.map_eq_image] at he
exact he
end Join
end
open Cone
end CoboundaryExpanders.InfiniteChains
namespace CoboundaryExpanders.TypedCosetFaces
open InfiniteChains Cone
open scoped Pointwise
variable {G I : Type} [Group G] [DecidableEq I] (H : I → Subgroup G)
def actionModel (g : G) : FaceModel (complex H) (complex H) where
vertex := fun v => g • v
injective := MulAction.injective g
face_iff := by
intro s
change IsFace H (g • s) ↔ IsFace H s
constructor
· intro h
have hh := h.smul H g⁻¹
have he : g⁻¹ • (g • s) = s := inv_smul_smul g s
rw [he] at hh
exact hh
· exact fun h => h.smul H g
cover := by
intro t ht
refine ⟨g⁻¹ • t,ht.smul H g⁻¹,?_⟩
change g • (g⁻¹ • t) = t
exact smul_inv_smul g t
lemma standard_singleton_face (i : I) : {vertex H 1 i} ∈ (complex H).faces := by
exact ⟨1,{i},by simp [face]⟩
end CoboundaryExpanders.TypedCosetFaces
namespace CoboundaryExpanders.InfiniteChains
open Cone
variable {V : Type} [DecidableEq V]
def ProperLinkCones (X : CoboundaryExpanders.InfiniteChains.Complex V) (N R : ℕ) : Prop :=
∀ s : Finset V, s.Nonempty → ∀ hs : s ∈ X.faces, s.card < N →
Nonempty (BoundedCone (X.faceLink s hs) (N-s.card-1) R)
end CoboundaryExpanders.InfiniteChains
end
end OAI
end
section
-- module Solutions.OAIQ3_Cob.Coboundary_LinkSpectrum
attribute [-instance] _root_.OAI.CoboundaryExpanders.InfiniteChains.Complex.faceMulAction _root_.OAI.CoboundaryExpanders.TypedCosetFaces.complexInvariant _root_.OAI.CoboundaryExpanders.TypedCosetFaces.kernelInvariant _root_.OAI.CoboundaryExpanders.TypedCosetFaces.vertexMulAction
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
/-!
Rank-two incidence geometry, weighted Rayleigh inequalities, and spectral bounds for links.
-/
noncomputable section
open scoped BigOperators
open scoped BigOperators Matrix
open scoped Matrix
namespace CoboundaryExpanders.RankTwoGeometry
section
open MatrixOpposition TypedCosetFaces Elementary
open scoped Matrix
variable {K : Type} [Field K]
def upper3 (a b c : K) : upperGroup K 3 :=
⟨⟨matrix3 a b c,matrix3_det a b c⟩,by
apply (mem_upperGroup _).mpr
intro i j hji
fin_cases i <;> fin_cases j <;> norm_num [matrix3,Matrix.one_apply,Fin.le_iff_val_le_val] at *⟩
def ca (g : upperGroup K 3) : K := g.val 0 1
def cb (g : upperGroup K 3) : K := g.val 1 2
def cc (g : upperGroup K 3) : K := g.val 0 2
@[simp] lemma ca_upper3 (a b c : K) : ca (upper3 a b c) = a := rfl
@[simp] lemma cb_upper3 (a b c : K) : cb (upper3 a b c) = b := rfl
@[simp] lemma cc_upper3 (a b c : K) : cc (upper3 a b c) = c := rfl
lemma upper3_coords (g : upperGroup K 3) : upper3 (ca g) (cb g) (cc g) = g := by
apply Subtype.ext
apply Matrix.SpecialLinearGroup.ext
intro i j
have hg := (mem_upperGroup g.val).mp g.property
change matrix3 (ca g) (cb g) (cc g) i j = g.val i j
fin_cases i <;> fin_cases j <;>
first | rfl | rw [hg _ _ (by decide)]; rfl
@[ext] lemma upper_ext {g h : upperGroup K 3}
(ha : ca g = ca h) (hb : cb g = cb h) (hc : cc g = cc h) : g = h := by
rw [←upper3_coords g,←upper3_coords h,ha,hb,hc]
lemma upper3_mul (a b c a' b' c' : K) :
upper3 a b c * upper3 a' b' c' = upper3 (a+a') (b+b') (c+c'+a*b') := by
apply Subtype.ext
apply Matrix.SpecialLinearGroup.ext
intro i j
change (matrix3 a b c * matrix3 a' b' c') i j = matrix3 (a+a') (b+b') (c+c'+a*b') i j
fin_cases i <;> fin_cases j <;> simp [matrix3,Matrix.mul_apply,Fin.sum_univ_succ] <;> ring
@[simp] lemma ca_mul (g h : upperGroup K 3) : ca (g*h) = ca g+ca h := by
rw [←upper3_coords g,←upper3_coords h,upper3_mul]; rfl
@[simp] lemma cb_mul (g h : upperGroup K 3) : cb (g*h) = cb g+cb h := by
rw [←upper3_coords g,←upper3_coords h,upper3_mul]; rfl
@[simp] lemma cc_mul (g h : upperGroup K 3) : cc (g*h) = cc g+cc h+ca g*cb h := by
rw [←upper3_coords g,←upper3_coords h,upper3_mul]; rfl
@[simp] lemma ca_one : ca (1 : upperGroup K 3) = 0 := by simp [ca]
@[simp] lemma cb_one : cb (1 : upperGroup K 3) = 0 := by simp [cb]
@[simp] lemma cc_one : cc (1 : upperGroup K 3) = 0 := by simp [cc]
@[simp] lemma ca_inv (g : upperGroup K 3) : ca g⁻¹ = -ca g := by
have h := ca_mul g⁻¹ g
simp only [inv_mul_cancel,ca_one] at h
linear_combination -h
@[simp] lemma cb_inv (g : upperGroup K 3) : cb g⁻¹ = -cb g := by
have h := cb_mul g⁻¹ g
simp only [inv_mul_cancel,cb_one] at h
linear_combination -h
@[simp] lemma cc_inv (g : upperGroup K 3) : cc g⁻¹ = -cc g+ca g*cb g := by
have h := cc_mul g⁻¹ g
simp only [inv_mul_cancel,cc_one,ca_inv] at h
linear_combination -h
lemma mem_pointGroup (g : upperGroup K 3) :
g ∈ cutGroups K 3 pointCut ↔ cb g = 0 ∧ cc g = 0 := by
simp only [cutGroups,mem_suffixGroup,pointCut]
refine ⟨fun h => ⟨h 1 2 (by decide) (by decide), h 0 2 (by decide) (by decide)⟩,?_⟩
rintro ⟨hb,hc⟩ i j hi hj
fin_cases i <;> fin_cases j <;> simp_all [cb,cc]
lemma mem_lineGroup (g : upperGroup K 3) :
g ∈ cutGroups K 3 lineCut ↔ ca g = 0 ∧ cc g = 0 := by
simp only [cutGroups,mem_suffixGroup,lineCut]
refine ⟨fun h => ⟨h 0 1 (by decide) (by decide), h 0 2 (by decide) (by decide)⟩,?_⟩
rintro ⟨ha,hc⟩ i j hi hj
fin_cases i <;> fin_cases j <;> simp_all [ca,cc]
lemma point_rel (g h : upperGroup K 3) :
g⁻¹*h ∈ cutGroups K 3 pointCut ↔ cb g = cb h ∧ cc g = cc h := by
rw [mem_pointGroup]; simp only [cb_mul,cb_inv,cc_mul,cc_inv,ca_inv]
constructor
· rintro ⟨hb,hc⟩
have he : cb g = cb h := by linear_combination -hb
refine ⟨he,?_⟩
rw [he] at hc
linear_combination -hc
· rintro ⟨hb,hc⟩; rw [hb,hc]; constructor <;> ring
lemma line_rel (g h : upperGroup K 3) :
g⁻¹*h ∈ cutGroups K 3 lineCut ↔
ca g = ca h ∧ cc g-ca g*cb g = cc h-ca h*cb h := by
rw [mem_lineGroup]; simp only [ca_mul,ca_inv,cc_mul,cc_inv]
constructor
· rintro ⟨ha,hc⟩
have he : ca g = ca h := by linear_combination -ha
refine ⟨he,?_⟩
rw [he] at hc ⊢
linear_combination -hc
· rintro ⟨ha,hc⟩; rw [ha]; constructor
· ring
· rw [ha] at hc; linear_combination -hc
end
open MatrixOpposition TypedCosetFaces InfiniteChains Cone
variable {K : Type} [Field K]
def cosetVertex : Vert K → Vertex (cutGroups K 3)
| .inl P => vertex (cutGroups K 3) (upper3 0 P.1 P.2) pointCut
| .inr L => vertex (cutGroups K 3) (upper3 L.1 0 L.2) lineCut
lemma point_vertex (g : upperGroup K 3) :
cosetVertex (.inl (cb g,cc g)) = vertex (cutGroups K 3) g pointCut := by
dsimp only [cosetVertex,vertex]
apply congrArg (Sigma.mk _)
apply Quotient.sound
apply QuotientGroup.leftRel_apply.mpr
exact (point_rel _ _).mpr ⟨rfl,rfl⟩
lemma line_vertex (g : upperGroup K 3) :
cosetVertex (.inr (ca g,cc g-ca g*cb g)) = vertex (cutGroups K 3) g lineCut := by
dsimp only [cosetVertex,vertex]
apply congrArg (Sigma.mk _)
apply Quotient.sound
apply QuotientGroup.leftRel_apply.mpr
apply (line_rel _ _).mpr
simp
lemma cosetVertex_injective : Function.Injective (cosetVertex (K:=K)) := by
intro x y h
cases x with
| inl P =>
cases y with
| inl Q =>
have hh := QuotientGroup.leftRel_apply.mp
(Quotient.exact (eq_of_heq (Sigma.mk.inj_iff.mp h).2))
have he := (point_rel _ _).mp hh
congr 1
exact Prod.ext he.1 he.2
| inr L =>
have he := congrArg (fun v => v.1.val) h
norm_num [cosetVertex,vertex,pointCut,lineCut] at he
| inr L =>
cases y with
| inl P =>
have he := congrArg (fun v => v.1.val) h
norm_num [cosetVertex,vertex,pointCut,lineCut] at he
| inr M =>
have hh := QuotientGroup.leftRel_apply.mp
(Quotient.exact (eq_of_heq (Sigma.mk.inj_iff.mp h).2))
have he := (line_rel _ _).mp hh
congr 1
apply Prod.ext he.1
simpa using he.2
lemma cosetVertex_surjective : Function.Surjective (cosetVertex (K:=K)) := by
rintro ⟨i,q⟩
induction q using Quotient.inductionOn with | h g =>
rcases cuts3 i with rfl | rfl
· exact ⟨.inl (cb g,cc g),point_vertex g⟩
· exact ⟨.inr (ca g,cc g-ca g*cb g),line_vertex g⟩
def vertexEquiv : Vert K ≃ Vertex (cutGroups K 3) :=
Equiv.ofBijective cosetVertex ⟨cosetVertex_injective,cosetVertex_surjective⟩
attribute [local instance] OAI.CoboundaryExpanders.RankTwoGeometry.instDecidableEq_solutions
def incidenceComplex (K : Type) [Field K] : CoboundaryExpanders.InfiniteChains.Complex (Vert K) where
faces := {s | ∃ P L : K×K, incident P L ∧ s ⊆ {Sum.inl P,Sum.inr L}}
empty_mem := ⟨(0,0),(0,0),by simp [incident],Finset.empty_subset _⟩
downward := by
rintro s t ⟨P,L,hPL,hs⟩ ht
exact ⟨P,L,hPL,ht.trans hs⟩
lemma fullFace (g : upperGroup K 3) :
({Sum.inl (cb g,cc g),Sum.inr (ca g,cc g-ca g*cb g)} : Finset (Vert K)).image cosetVertex =
face (cutGroups K 3) g {pointCut,lineCut} := by
simp only [Finset.image_insert,Finset.image_singleton,point_vertex,line_vertex,face]
lemma face_subset_fullFace (g : upperGroup K 3) (A : Finset (Cut 3)) :
face (cutGroups K 3) g A ⊆ face (cutGroups K 3) g {pointCut,lineCut} := by
apply Finset.image_subset_image
intro i _
rcases cuts3 i with rfl | rfl <;> simp
lemma cosetVertex_face_iff (s : Finset (Vert K)) :
s.image cosetVertex ∈ (TypedCosetFaces.complex (cutGroups K 3)).faces ↔
s ∈ (incidenceComplex K).faces := by
constructor
· rintro ⟨g,A,hg⟩
refine ⟨(cb g,cc g),(ca g,cc g-ca g*cb g),?_,?_⟩
· dsimp [incident]; ring
· apply (Finset.image_subset_image_iff cosetVertex_injective).mp
rw [fullFace,←hg]
exact face_subset_fullFace g A
· rintro ⟨P,L,hPL,hs⟩
have he : (ca (upper3 L.1 P.1 P.2),cc (upper3 L.1 P.1 P.2)-
ca (upper3 L.1 P.1 P.2)*cb (upper3 L.1 P.1 P.2)) = L := by
apply Prod.ext
· rfl
· change P.2-L.1*P.1 = L.2
rw [hPL]; ring
have hf := fullFace (upper3 L.1 P.1 P.2)
simp only [ca_upper3,cb_upper3,cc_upper3] at he hf
rw [he] at hf
apply IsFace.downward (H:=cutGroups K 3) ⟨_,_,rfl⟩
rw [←hf]
exact Finset.image_subset_image hs
def incidenceModel : FaceModel (incidenceComplex K) (TypedCosetFaces.complex (cutGroups K 3)) where
vertex := cosetVertex
injective := cosetVertex_injective
face_iff := cosetVertex_face_iff
cover := by
intro t ht
let s := t.image vertexEquiv.symm
have he : s.image cosetVertex = t := by
change s.image vertexEquiv = t
simp only [s,Finset.image_image,Function.comp_def,Equiv.apply_symm_apply,Finset.image_id']
exact ⟨s,by rwa [←cosetVertex_face_iff,he],he⟩
end CoboundaryExpanders.RankTwoGeometry
namespace CoboundaryExpanders.InfiniteChains
namespace FiniteWeights
variable {V : Type} [Fintype V] [DecidableEq V]
def cofaces (X : CoboundaryExpanders.InfiniteChains.Complex V) (N : ℕ) (s : Finset V) : ℕ :=
((level X N).filter (fun t => s ⊆ t)).card
def Pure (X : CoboundaryExpanders.InfiniteChains.Complex V) (N : ℕ) : Prop :=
(level X N).Nonempty ∧ ∀ s ∈ X.faces, ∃ t ∈ level X N, s ⊆ t
lemma cofaces_zero_of_not_face (X : CoboundaryExpanders.InfiniteChains.Complex V) (N : ℕ) {s : Finset V} (hs : s ∉ X.faces) :
cofaces X N s = 0 := by
unfold cofaces
apply Finset.card_eq_zero.mpr
apply Finset.eq_empty_iff_forall_notMem.mpr
intro t ht
obtain ⟨ht,hst⟩ := Finset.mem_filter.mp ht
exact hs (X.downward ((mem_level X N t).mp ht).1 hst)
end FiniteWeights
open FiniteWeights
variable {V W : Type} [Fintype V] [Fintype W] [DecidableEq V] [DecidableEq W]
attribute [local instance] Classical.propDecidable
namespace Cone.FaceModel
variable {X : CoboundaryExpanders.InfiniteChains.Complex V} {Y : CoboundaryExpanders.InfiniteChains.Complex W} (M : FaceModel X Y)
lemma cofaces_image (N : ℕ) (s : Finset V) :
cofaces Y N (s.image M.vertex) = cofaces X N s := by
unfold cofaces
symm
apply Finset.card_bij (fun t _ => t.image M.vertex)
· intro t ht
obtain ⟨ht,hst⟩ := Finset.mem_filter.mp ht
obtain ⟨ht,hcard⟩ := (mem_level _ _ _).mp ht
exact Finset.mem_filter.mpr ⟨(mem_level _ _ _).mpr
⟨(M.face_iff t).mpr ht,by rwa [Finset.card_image_of_injective t M.injective]⟩,
Finset.image_subset_image hst⟩
· intro t ht u hu he
exact Finset.image_injective M.injective he
· intro t ht
obtain ⟨ht,hst⟩ := Finset.mem_filter.mp ht
obtain ⟨ht,hcard⟩ := (mem_level _ _ _).mp ht
obtain ⟨u,hu,he⟩ := M.cover t ht
refine ⟨u,Finset.mem_filter.mpr ⟨(mem_level _ _ _).mpr ⟨hu,?_⟩,?_⟩,he⟩
· rw [←he,Finset.card_image_of_injective u M.injective] at hcard
exact hcard
· rw [←he] at hst
exact (Finset.image_subset_image_iff M.injective).mp hst
omit [Fintype V] [Fintype W] [DecidableEq V] in
lemma vertex_in_range {y : W} (hy : ({y}:Finset W) ∈ Y.faces) : y ∈ Set.range M.vertex := by
obtain ⟨s,hs,he⟩ := M.cover {y} hy
have h : y ∈ s.image M.vertex := by rw [he]; simp
obtain ⟨x,hx,hxy⟩ := Finset.mem_image.mp h
exact ⟨x,hxy⟩
end Cone.FaceModel
namespace FiniteWeights
def edge (X : CoboundaryExpanders.InfiniteChains.Complex V) (N : ℕ) (x y : V) : ℝ :=
if x ≠ y then (cofaces X N {x,y}:ℝ) else 0
lemma edge_zero_of_not_face (X : CoboundaryExpanders.InfiniteChains.Complex V) (N : ℕ) {x : V} (hx : ({x}:Finset V) ∉ X.faces)
(y : V) : edge X N x y = 0 := by
unfold edge
split_ifs
· rw [cofaces_zero_of_not_face X N (fun h => hx (X.downward h (by simp))),Nat.cast_zero]
· rfl
end FiniteWeights
namespace Cone.FaceModel
variable {X : CoboundaryExpanders.InfiniteChains.Complex V} {Y : CoboundaryExpanders.InfiniteChains.Complex W} (M : FaceModel X Y)
def spectralEmbedding (N : ℕ) : EdgeMixing.Embedding (edge X N) (edge Y N) where
vertex := M.vertex
injective := M.injective
edge_eq := by
intro x y
simp only [edge,M.injective.ne_iff]
split_ifs
· have h := M.cofaces_image N {x,y}
simpa only [Finset.image_insert,Finset.image_singleton] using congrArg (fun a : ℕ => (a:ℝ)) h
· rfl
outside_zero := by
intro y hy z
apply edge_zero_of_not_face Y N
exact fun h => hy (M.vertex_in_range h)
end Cone.FaceModel
end CoboundaryExpanders.InfiniteChains
namespace CoboundaryExpanders.InfiniteChains.FiniteWeights
variable {V : Type} [Fintype V] [DecidableEq V]
attribute [local instance] Classical.propDecidable
lemma cofaces_top (X : CoboundaryExpanders.InfiniteChains.Complex V) (N : ℕ) (s : Finset V) (hs : s.card = N) :
cofaces X N s = if s ∈ X.faces then 1 else 0 := by
by_cases hf : s ∈ X.faces
· rw [ite_eq_left hf]
have he : (level X N).filter (fun t => s ⊆ t) = {s} := by
ext t
simp only [Finset.mem_filter,mem_level,Finset.mem_singleton]
constructor
· rintro ⟨⟨ht,hcard⟩,hst⟩
exact (Finset.eq_of_subset_of_card_le hst (by omega)).symm
· rintro rfl
exact ⟨⟨hf,hs⟩,Finset.Subset.refl _⟩
simp only [cofaces,he,Finset.card_singleton]
· rw [ite_eq_right hf,cofaces_zero_of_not_face X N hf]
end CoboundaryExpanders.InfiniteChains.FiniteWeights
namespace CoboundaryExpanders.MatrixOpposition
open InfiniteChains FiniteWeights TypedCosetFaces
variable {K : Type} [Field K] [Fintype K]
noncomputable instance cutVertexFintype (N : ℕ) : Fintype (Vertex (cutGroups K N)) := Fintype.ofFinite _
end CoboundaryExpanders.MatrixOpposition
namespace CoboundaryExpanders.InfiniteChains.Join
open Cone FiniteWeights
variable {V W : Type} [Fintype V] [Fintype W] [DecidableEq V] [DecidableEq W]
attribute [local instance] Classical.propDecidable
abbrev TrueVertex (X : CoboundaryExpanders.InfiniteChains.Complex V) := {x : V // ({x}:Finset V) ∈ X.faces}
def rankOneEmbedding {X : CoboundaryExpanders.InfiniteChains.Complex V} {Y : CoboundaryExpanders.InfiniteChains.Complex W}
(hX : RankBound X 1) (hY : RankBound Y 1) :
EdgeMixing.Embedding (EdgeMixing.bipartiteEdge (A:=TrueVertex X) (B:=TrueVertex Y))
(edge (complex X Y) 2) where
vertex := Sum.map Subtype.val Subtype.val
injective := Sum.map_injective.mpr ⟨Subtype.val_injective,Subtype.val_injective⟩
edge_eq := by
intro x y
cases x with
| inl a =>
cases y with
| inl b =>
change edge (complex X Y) 2 (Sum.inl a.val) (Sum.inl b.val) = 0
by_cases hab : a = b
· subst b; simp [edge]
· have hv : a.val ≠ b.val := fun h => hab (Subtype.ext h)
have hne : Sum.inl a.val ≠ (Sum.inl b.val : V ⊕ W) := fun h => hv (Sum.inl.inj h)
have hnot : ({Sum.inl a.val,Sum.inl b.val}:Finset (V ⊕ W)) ∉ (complex X Y).faces := by
intro h
have hh := hX {a.val,b.val} (by simpa [complex] using h.1)
rw [Finset.card_pair hv] at hh
omega
simp [edge,hne,cofaces_zero_of_not_face _ _ hnot]
| inr b =>
change edge (complex X Y) 2 (Sum.inl a.val) (Sum.inr b.val) = 1
rw [edge,ite_eq_left (by simp),cofaces_top _ _ _ (Finset.card_pair (by simp))]
have hf : ({Sum.inl a.val,Sum.inr b.val}:Finset (V ⊕ W)) ∈ (complex X Y).faces := by
simpa [complex] using And.intro a.property b.property
simp [hf]
| inr a =>
cases y with
| inl b =>
change edge (complex X Y) 2 (Sum.inr a.val) (Sum.inl b.val) = 1
rw [edge,ite_eq_left (by simp),cofaces_top _ _ _ (Finset.card_pair (by simp))]
have hf : ({Sum.inr a.val,Sum.inl b.val}:Finset (V ⊕ W)) ∈ (complex X Y).faces := by
simpa [complex] using And.intro b.property a.property
simp [hf]
| inr b =>
change edge (complex X Y) 2 (Sum.inr a.val) (Sum.inr b.val) = 0
by_cases hab : a = b
· subst b; simp [edge]
· have hv : a.val ≠ b.val := fun h => hab (Subtype.ext h)
have hne : Sum.inr a.val ≠ (Sum.inr b.val : V ⊕ W) := fun h => hv (Sum.inr.inj h)
have hnot : ({Sum.inr a.val,Sum.inr b.val}:Finset (V ⊕ W)) ∉ (complex X Y).faces := by
intro h
have hh := hY {a.val,b.val} (by simpa [complex] using h.2)
rw [Finset.card_pair hv] at hh
omega
simp [edge,hne,cofaces_zero_of_not_face _ _ hnot]
outside_zero := by
intro x hx y
apply edge_zero_of_not_face
intro h
cases x with
| inl a =>
have ha : ({a}:Finset V) ∈ X.faces := by simpa [complex] using h.1
exact hx ⟨Sum.inl ⟨a,ha⟩,rfl⟩
| inr b =>
have hb : ({b}:Finset W) ∈ Y.faces := by simpa [complex] using h.2
exact hx ⟨Sum.inr ⟨b,hb⟩,rfl⟩
end CoboundaryExpanders.InfiniteChains.Join
namespace CoboundaryExpanders.InfiniteChains
open Cone FiniteWeights
variable {V W : Type} [Fintype V] [Fintype W] [DecidableEq V] [DecidableEq W]
def TopSpectral (X : CoboundaryExpanders.InfiniteChains.Complex V) (N : ℕ) (lam : ℝ) : Prop :=
∀ s : Finset V, ∀ hs : s ∈ X.faces, s.card+2 = N →
EdgeMixing.Rayleigh (edge (X.faceLink s hs) 2) lam
end CoboundaryExpanders.InfiniteChains
end
end OAI
end
section
-- module Solutions.OAIQ3_Cob.Coboundary_Averaging
attribute [-instance] _root_.OAI.CoboundaryExpanders.InfiniteChains.Complex.faceMulAction
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
/-!
Finite F2 averaging and bounded-cone estimates for weighted local cochains.
-/
noncomputable section
open scoped BigOperators
open scoped BigOperators Matrix
open scoped Matrix
open scoped BigOperators InnerProductSpace
namespace CoboundaryExpanders.InfiniteChains.Cone
open Attachment
variable {V : Type} [DecidableEq V]
def correction (T : Raw V →ₗ[k] Raw V) (f : Finset V → k) (s : Finset V) : k :=
eval f (T (Finsupp.single s 1))
variable {G : Type} [Group G] [MulAction G V]
open scoped Pointwise
def movedCorrection (g : G) (T : Raw V →ₗ[k] Raw V) (f : Finset V → k) : Finset V → k :=
pull g⁻¹ (correction T (pull g f))
end CoboundaryExpanders.InfiniteChains.Cone
namespace CoboundaryExpanders.InfiniteChains.FiniteWeights
section
open Attachment Cone Averaging
open scoped BigOperators Pointwise
variable {V : Type} [Fintype V] [DecidableEq V]
def weight (X : CoboundaryExpanders.InfiniteChains.Complex V) (N r : ℕ) (s : Finset V) : ℝ :=
if s ∈ level X r then cofaces X N s / ((N.choose r : ℝ) * (level X N).card) else 0
end
open Attachment Cone Averaging
open scoped BigOperators Pointwise
variable {V : Type} [Fintype V] [DecidableEq V]
instance faceFintype (X : CoboundaryExpanders.InfiniteChains.Complex V) (r : ℕ) : Fintype (X.Face r) := Fintype.ofFinite _
end CoboundaryExpanders.InfiniteChains.FiniteWeights
end
end OAI
end
section
-- module Solutions.OAIQ3_Cob.Coboundary_Lattices
attribute [-instance] _root_.OAI.CoboundaryExpanders.InfiniteChains.Complex.faceMulAction _root_.OAI.CoboundaryExpanders.InfiniteChains.FiniteWeights.faceFintype
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
/-!
Affine and rational lattices, polynomial congruence actions, and lattice-chain geometry.
-/
noncomputable section
namespace CoboundaryExpanders.RationalLattices
open InfiniteChains InfiniteChains.Attachment
open scoped Polynomial
variable (K : Type) [Field K] (N : ℕ)
noncomputable abbrev building : InfiniteChains.Complex (Vertex K N) :=
AffineLattices.complex (shift K N) (standard K N)
end CoboundaryExpanders.RationalLattices
namespace CoboundaryExpanders.RationalLattices
open scoped Polynomial
variable (K : Type) [Field K] (N : ℕ)
noncomputable def baseChamber : Finset (Vertex K N) :=
Finset.univ.image (cutVertex K N)
end CoboundaryExpanders.RationalLattices
namespace CoboundaryExpanders.RationalLattices
open scoped Polynomial
open Module
variable (K : Type) [Field K] (N : ℕ)
lemma residueMap_apply (A : Vertex K N) (v : A.val) (i : Fin N) :
residueMap K N A v i = (((latticeBasis K N A).equivFun v) i).coeff 0 := rfl
lemma residueMap_surjective (A : Vertex K N) : Function.Surjective (residueMap K N A) := by
intro v
refine ⟨(latticeBasis K N A).equivFun.symm (fun i => Polynomial.C (v i)),?_⟩
ext i
simp only [residueMap_apply,LinearEquiv.apply_symm_apply,Polynomial.coeff_C_zero]
lemma residueMap_smul_polynomial (A : Vertex K N) (f : K[X]) (v : A.val) :
residueMap K N A (f • v) = f.coeff 0 • residueMap K N A v := by
ext i
simp only [residueMap_apply,map_smul,Pi.smul_apply,smul_eq_mul]
change Polynomial.constantCoeff (f * _) = Polynomial.constantCoeff f * Polynomial.constantCoeff _
exact map_mul _ _ _
lemma residueMap_eq_zero_iff (A : Vertex K N) (v : A.val) :
residueMap K N A v = 0 ↔ v.val ∈ shift K N A.val := by
constructor
· intro h
have hz : ∀ i, Polynomial.X ∣ (latticeBasis K N A).equivFun v i := by
intro i
apply Polynomial.X_dvd_iff.mpr
exact congr_fun h i
choose f hf using hz
let w : A.val := (latticeBasis K N A).equivFun.symm f
have he : (Polynomial.X : K[X]) • w = v := by
apply (latticeBasis K N A).equivFun.injective
simp only [map_smul,LinearEquiv.apply_symm_apply,w]
funext i
exact (hf i).symm
apply (mem_shift K N _ _).mpr
refine ⟨w.val,w.property,?_⟩
have hv := congrArg Subtype.val he
change (Polynomial.X : K[X]) • w.val = v.val at hv
simpa only [shiftLinear_eq_smul] using hv
· intro hv
obtain ⟨w,hw,he⟩ := (mem_shift K N _ _).mp hv
have he' : (Polynomial.X : K[X]) • (⟨w,hw⟩ : A.val) = v := by
apply Subtype.ext
change (Polynomial.X : K[X]) • w = v.val
simpa only [shiftLinear_eq_smul] using he
rw [← he',residueMap_smul_polynomial]
simp
end CoboundaryExpanders.RationalLattices
end
end OAI
end
section
-- module Solutions.OAIQ3_Cob.Coboundary_Polynomial
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
/-!
Polynomial-vector leading terms, degree reduction, and normalized rational lattice representatives.
-/
noncomputable section
open scoped Polynomial BigOperators
namespace CoboundaryExpanders.RationalLattices
open scoped Polynomial BigOperators
open AffineLattices
variable (K : Type) [Field K] (N : ℕ)
noncomputable def polynomialLattice (A : Vertex K N) : Submodule K[X] (Fin N → K[X]) :=
A.val.comap (polynomialEmbedding K N)
lemma polynomialLattice_map (A : Vertex K N) :
(polynomialLattice K N A).map (polynomialEmbedding K N) = A.val := by
apply le_antisymm
· rintro v ⟨w,hw,rfl⟩
exact hw
· intro v hv
obtain ⟨w,hw⟩ := (polynomialToStandard_bijective K N).2
⟨v,vertex_le (shift K N) (standard K N) A hv⟩
refine ⟨w,?_,?_⟩
· change polynomialEmbedding K N w ∈ A.val
have he := congrArg Subtype.val hw
change polynomialEmbedding K N w = v at he
exact he.symm ▸ hv
· exact congrArg Subtype.val hw
lemma polynomialLattice_bound (A : Vertex K N) :
∃ m : ℕ, ∀ i : Fin N, Pi.single i (Polynomial.X^m : K[X]) ∈ polynomialLattice K N A := by
classical
obtain ⟨m,hm⟩ := vertex_bounded (shift K N) (standard K N) A
refine ⟨m,fun i => ?_⟩
change polynomialEmbedding K N (Pi.single i (Polynomial.X^m : K[X])) ∈ A.val
apply hm
apply (mem_level K N _ _ _).mpr
refine ⟨Pi.single i (1 : RatFunc K),(by intro j; exact ⟨(if j = i then 1 else 0 : K[X]),by split_ifs <;> simp_all⟩),?_⟩
funext j
by_cases hij : j = i
· subst j; simp [Algebra.smul_def]
· simp [hij,Algebra.smul_def]
lemma polynomialHasPivots (A : Vertex K N) :
PolynomialVectors.HasPivots (polynomialLattice K N A) := by
obtain ⟨m,hm⟩ := polynomialLattice_bound K N A
exact PolynomialVectors.hasPivots_of_bound _ m hm
noncomputable def diagonalExponents (A : Vertex K N) : Fin N → ℕ :=
PolynomialVectors.pivotDegree (polynomialLattice K N A) (polynomialHasPivots K N A)
noncomputable def exponentLattice (a : Fin N → ℕ) : LatticeSpace K N :=
Submodule.span K[X] (Set.range fun i : Fin N => Pi.single i (uniformizer K ^ a i))
end CoboundaryExpanders.RationalLattices
namespace CoboundaryExpanders.RationalLattices
open scoped Polynomial BigOperators
open AffineLattices
variable (K : Type) [Field K] (N M : ℕ)
lemma polynomialLattice_mono {A B : Vertex K N} (hBA : B.val ≤ A.val) :
polynomialLattice K N B ≤ polynomialLattice K N A :=
Submodule.comap_mono hBA
lemma polynomialLattice_power_le {A B : Vertex K N}
(hAB : level (shift K N) A.val 1 ≤ B.val) :
PolynomialVectors.powerShift (polynomialLattice K N A) 1 ≤ polynomialLattice K N B := by
rintro v ⟨w,hw,rfl⟩
change polynomialEmbedding K N (PolynomialVectors.powerLinear 1 w) ∈ B.val
apply hAB
apply (mem_level K N _ _ _).mpr
refine ⟨polynomialEmbedding K N w,hw,?_⟩
funext i
simp [PolynomialVectors.powerLinear,Algebra.smul_def]
end CoboundaryExpanders.RationalLattices
end
end OAI
end
section
-- module Solutions.OAIQ3_Cob.Coboundary_Windows
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
/-!
Affine windows, residue chambers, lattice flags, and chamber parametrizations.
-/
noncomputable section
open scoped Polynomial BigOperators
namespace CoboundaryExpanders.PolynomialVectors
open scoped Polynomial BigOperators
variable {K : Type} [Field K] {N : ℕ}
namespace ResidueChamber
variable (C : ResidueChamber (K := K) (N := N))
lemma terminal : C.stage (Fin.last N) = powerShift C.top 1 := by
apply eq_of_le_same_pivots (C.hasStage (Fin.last N))
(powerShift_hasPivots C.top C.hasTop 1) (C.lower (Fin.last N))
intro i
rw [C.stage_degree,pivotDegree_powerShift C.top C.hasTop]
simp only [Fin.val_last,ite_eq_left (C.word.symm i).isLt]
noncomputable def length : ℕ := AffineWindow.inversion (N := N) (List.ofFn C.window)
end ResidueChamber
end CoboundaryExpanders.PolynomialVectors
namespace CoboundaryExpanders.RationalLattices
open scoped Polynomial BigOperators
open AffineLattices PolynomialVectors
variable (K : Type) [Field K] (N : ℕ)
lemma polynomialLattice_injective : Function.Injective (polynomialLattice K N) := by
intro A B he
apply Subtype.ext
have hh := congrArg (fun P => P.map (polynomialEmbedding K N)) he
simpa only [polynomialLattice_map] using hh
lemma polynomialLattice_strict {A B : Vertex K N} (hBA : B.val < A.val) :
polynomialLattice K N B < polynomialLattice K N A := by
apply lt_of_le_of_ne (polynomialLattice_mono K N hBA.le)
intro he
exact hBA.ne (congrArg Subtype.val (polynomialLattice_injective K N he))
lemma polynomialLattice_power_map (A : Vertex K N) (m : ℕ) :
(powerShift (polynomialLattice K N A) m).map (polynomialEmbedding K N) =
level (shift K N) A.val m := by
ext v
constructor
· rintro ⟨w,⟨z,hz,rfl⟩,rfl⟩
apply (mem_level K N _ _ _).mpr
exact ⟨polynomialEmbedding K N z,hz,by rw [← map_smul]; rfl⟩
· intro hv
obtain ⟨w,hw,rfl⟩ := (mem_level K N _ _ _).mp hv
have hw' : w ∈ (polynomialLattice K N A).map (polynomialEmbedding K N) := by
rwa [polynomialLattice_map]
obtain ⟨z,hz,rfl⟩ := hw'
exact ⟨powerLinear m z,⟨z,hz,rfl⟩,by change polynomialEmbedding K N ((Polynomial.X^m : K[X]) • z) = _; rw [map_smul]⟩
structure FullChamber (hN : 0 < N) where
vertex : Fin N → Vertex K N
strict : StrictAnti (fun r => (vertex r).val)
lower : ∀ r, shift K N (vertex ⟨0,hN⟩).val ≤ (vertex r).val
namespace FullChamber
variable {K N} {hN : 0 < N} (C : FullChamber K N hN)
def topIndex (_C : FullChamber K N hN) : Fin N := ⟨0,hN⟩
noncomputable def stage (r : Fin (N+1)) : Submodule K[X] (PolynomialVectors.V K N) :=
if hr : r.val < N then polynomialLattice K N (C.vertex ⟨r.val,hr⟩)
else powerShift (polynomialLattice K N (C.vertex C.topIndex)) 1
lemma hasStage (r : Fin (N+1)) : HasPivots (C.stage r) := by
unfold stage
split_ifs
· exact polynomialHasPivots K N _
· exact powerShift_hasPivots _ (polynomialHasPivots K N _) 1
lemma lower_stage (r : Fin (N+1)) : powerShift (polynomialLattice K N (C.vertex C.topIndex)) 1 ≤ C.stage r := by
unfold stage
split_ifs
· exact polynomialLattice_power_le K N (C.lower _)
· exact le_rfl
lemma stage_strict : StrictAnti C.stage := by
intro r s hrs
have hrN : r.val < N := by have hs := s.isLt; change r.val < s.val at hrs; omega
rw [show C.stage r = polynomialLattice K N (C.vertex ⟨r.val,hrN⟩) from dite_eq_left hrN]
unfold stage
split_ifs with hsN
· exact polynomialLattice_strict K N (C.strict (show (⟨r.val,hrN⟩ : Fin N) < ⟨s.val,hsN⟩ from hrs))
· apply lt_of_le_of_ne (polynomialLattice_power_le K N (C.lower _))
intro he
have hh := congrArg (fun P => P.map (polynomialEmbedding K N)) he
rw [polynomialLattice_power_map,polynomialLattice_map] at hh
have hle : (C.vertex ⟨r.val,hrN⟩).val ≤ shift K N (standard K N) := by
rw [← hh]
exact (shift K N).monotone (vertex_le (shift K N) (standard K N) _)
exact vertex_normalized (shift K N) (standard K N) _ hle
noncomputable def polynomialChamber : ResidueChamber (K := K) (N := N) where
top := polynomialLattice K N (C.vertex C.topIndex)
hasTop := polynomialHasPivots K N _
stage := C.stage
hasStage := C.hasStage
strict := C.stage_strict
initial := by
unfold stage
split_ifs with h
· rfl
· exact False.elim (h hN)
lower := C.lower_stage
noncomputable def length : ℕ := C.polynomialChamber.length
end FullChamber
end CoboundaryExpanders.RationalLattices
namespace CoboundaryExpanders.RationalLattices
open scoped Polynomial BigOperators
open AffineLattices PolynomialVectors
variable (K : Type) [Field K] (N : ℕ)
lemma powerShift_map_embedding (P : Submodule K[X] (PolynomialVectors.V K N)) (m : ℕ) :
(powerShift P m).map (polynomialEmbedding K N) =
level (shift K N) (P.map (polynomialEmbedding K N)) m := by
ext v
constructor
· rintro ⟨w,⟨z,hz,rfl⟩,rfl⟩
apply (mem_level K N _ _ _).mpr
refine ⟨polynomialEmbedding K N z,⟨z,hz,rfl⟩,?_⟩
rw [← map_smul]
rfl
· intro hv
obtain ⟨w,⟨z,hz,rfl⟩,rfl⟩ := (mem_level K N _ _ _).mp hv
refine ⟨powerLinear m z,⟨z,hz,rfl⟩,?_⟩
change polynomialEmbedding K N ((Polynomial.X^m : K[X]) • z) = _
rw [map_smul]
end CoboundaryExpanders.RationalLattices
namespace CoboundaryExpanders.RationalLattices
open scoped Polynomial BigOperators
open AffineLattices PolynomialVectors
variable (K : Type) [Field K] (N : ℕ)
def OpposedVertex (hN : 0 < N) (A : Vertex K N) : Prop :=
∃ g : Matrix.SpecialLinearGroup (Fin N) K[X],
(∀ i j : Fin N, j ≤ i → (g i j).coeff 0 = (1 : Matrix (Fin N) (Fin N) K) i j) ∧
∃ cut : Fin N, A = actVertex K N hN g (cutVertex K N cut)
end CoboundaryExpanders.RationalLattices
namespace CoboundaryExpanders.RationalLattices
open scoped Polynomial
variable (K : Type) [Field K] (N : ℕ)
attribute [local irreducible] residueMap latticeBasis
abbrev ResidueInterval (A : Vertex K N) := Set.Icc (shift K N A.val) A.val
noncomputable def liftResidue (A : Vertex K N) (W : Submodule K (Fin N → K)) : LatticeSpace K N where
carrier := {v | ∃ h : v ∈ A.val, residueMap K N A ⟨v,h⟩ ∈ W}
zero_mem' := by
refine ⟨A.val.zero_mem,?_⟩
change residueMap K N A (0 : A.val) ∈ W
rw [map_zero]
exact W.zero_mem
add_mem' := by
rintro v w ⟨hv,hv'⟩ ⟨hw,hw'⟩
refine ⟨A.val.add_mem hv hw,?_⟩
change residueMap K N A ((⟨v,hv⟩ : A.val) + ⟨w,hw⟩) ∈ W
exact ((residueMap K N A).map_add ⟨v,hv⟩ ⟨w,hw⟩).symm ▸ W.add_mem hv' hw'
smul_mem' := by
rintro f v ⟨hv,hv'⟩
refine ⟨A.val.smul_mem f hv,?_⟩
change residueMap K N A (f • (⟨v,hv⟩ : A.val)) ∈ W
rw [residueMap_smul_polynomial]
exact W.smul_mem _ hv'
lemma liftResidue_le (A : Vertex K N) (W : Submodule K (Fin N → K)) :
liftResidue K N A W ≤ A.val := fun _ hv => hv.choose
lemma shift_le_liftResidue (A : Vertex K N) (W : Submodule K (Fin N → K)) :
shift K N A.val ≤ liftResidue K N A W := by
intro v hv
have hvA := shift_le_self K N A.val hv
refine ⟨hvA,?_⟩
rw [(residueMap_eq_zero_iff K N A ⟨v,hvA⟩).mpr hv]
exact W.zero_mem
lemma mem_liftResidue (A : Vertex K N) (W : Submodule K (Fin N → K)) (v : A.val) :
v.val ∈ liftResidue K N A W ↔ residueMap K N A v ∈ W := by
constructor
· rintro ⟨hv,h⟩; exact h
· intro h; exact ⟨v.property,h⟩
noncomputable def intervalSubspace (A : Vertex K N) (B : ResidueInterval K N A) : Submodule K (Fin N → K) :=
(((B.val.restrictScalars K).comap (A.val.subtype.restrictScalars K)).map (residueMap K N A))
lemma mem_intervalSubspace (A : Vertex K N) (B : ResidueInterval K N A) (w : Fin N → K) :
w ∈ intervalSubspace K N A B ↔ ∃ v : A.val, v.val ∈ B.val ∧ residueMap K N A v = w := Iff.rfl
lemma lift_intervalSubspace (A : Vertex K N) (B : ResidueInterval K N A) :
liftResidue K N A (intervalSubspace K N A B) = B.val := by
ext v
constructor
· rintro ⟨hv,hv'⟩
obtain ⟨w,hw,he⟩ := (mem_intervalSubspace K N A B _).mp hv'
have hz : residueMap K N A ((⟨v,hv⟩ : A.val) - w) = 0 := by rw [map_sub,he,sub_self]
have hd : v - w.val ∈ B.val := B.property.1 ((residueMap_eq_zero_iff K N A _).mp hz)
have hh := B.val.add_mem hd hw
simpa only [sub_add_cancel] using hh
· intro hv
refine ⟨B.property.2 hv,?_⟩
exact (mem_intervalSubspace K N A B _).mpr ⟨⟨v,B.property.2 hv⟩,hv,rfl⟩
lemma intervalSubspace_lift (A : Vertex K N) (W : Submodule K (Fin N → K)) :
intervalSubspace K N A ⟨liftResidue K N A W,shift_le_liftResidue K N A W,liftResidue_le K N A W⟩ = W := by
ext w
rw [mem_intervalSubspace]
constructor
· rintro ⟨v,hv,rfl⟩
exact (mem_liftResidue K N A W v).mp hv
· intro hw
obtain ⟨v,rfl⟩ := residueMap_surjective K N A w
exact ⟨v,(mem_liftResidue K N A W v).mpr hw,rfl⟩
noncomputable def residueIntervalIso (A : Vertex K N) :
ResidueInterval K N A ≃o Submodule K (Fin N → K) where
toFun := intervalSubspace K N A
invFun W := ⟨liftResidue K N A W,shift_le_liftResidue K N A W,liftResidue_le K N A W⟩
left_inv B := Subtype.ext (lift_intervalSubspace K N A B)
right_inv := intervalSubspace_lift K N A
map_rel_iff' := by
intro B D
constructor
· intro h v hv
have hvA := B.property.2 hv
have hv' : residueMap K N A ⟨v,hvA⟩ ∈ intervalSubspace K N A D :=
h ((mem_intervalSubspace K N A B _).mpr ⟨⟨v,hvA⟩,hv,rfl⟩)
rw [← lift_intervalSubspace K N A D]
exact ⟨hvA,hv'⟩
· intro h w hw
obtain ⟨v,hv,rfl⟩ := (mem_intervalSubspace K N A B w).mp hw
exact (mem_intervalSubspace K N A D _).mpr ⟨v,h hv,rfl⟩
end CoboundaryExpanders.RationalLattices
namespace CoboundaryExpanders.RationalLattices
open scoped Polynomial
open AffineLattices
variable (K : Type) [Field K] (N : ℕ)
lemma interval_exists_normalized (hN : 0 < N) (A : Vertex K N) (B : ResidueInterval K N A) :
∃ D : Vertex K N, Homothetic (shift K N) B.val D.val := by
obtain ⟨m,hm⟩ := vertex_bounded (shift K N) (standard K N) A
obtain ⟨D,j,_,hj⟩ := exists_normalized (shift K N) (standard K N)
(shift_standard_le K N) (standard_not_le_shift K N hN) (m+1) B.val
(B.property.2.trans (vertex_le _ _ A))
((shift K N).monotone hm |>.trans B.property.1) (shift_le_self K N B.val)
exact ⟨D,0,j,hj⟩
noncomputable def intervalNormalize (hN : 0 < N) (A : Vertex K N) (B : ResidueInterval K N A) :
Vertex K N := (interval_exists_normalized K N hN A B).choose
end CoboundaryExpanders.RationalLattices
namespace CoboundaryExpanders.RationalLattices
open scoped Polynomial
open AffineLattices
variable (K : Type) [Field K] (N : ℕ)
namespace FullChamber
variable {K N} {hN : 0 < N} (C : FullChamber K N hN)
noncomputable def face : Finset (Vertex K N) := Finset.univ.image C.vertex
end FullChamber
def codistanceStage (hN : 0 < N) (m : ℕ) : Set (Finset (Vertex K N)) :=
{s | ∃ C : FullChamber K N hN, C.length ≤ m ∧ s ⊆ C.face}
end CoboundaryExpanders.RationalLattices
end
end OAI
end
section
-- module Solutions.OAIQ3_Cob.Coboundary_Chambers
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
/-!
Bounded and full chambers, codistance, descent cores, and their affine-window descriptions.
-/
noncomputable section
open scoped Polynomial BigOperators
namespace CoboundaryExpanders.PolynomialVectors
open scoped Polynomial BigOperators
variable {K : Type} [Field K] {N : ℕ}
namespace ResidueChamber
variable (C : ResidueChamber (K := K) (N := N))
lemma rotateStage_strict (hN : 0 < N) : StrictAnti (C.rotateStage hN) := by
intro r s hrs
have hr : r.val < N := by have := s.isLt; change r.val < s.val at hrs; omega
rw [show C.rotateStage hN r = C.stage ⟨r.val+1,by omega⟩ from dite_eq_left hr]
unfold rotateStage
split_ifs with hs
· exact C.strict (show (⟨r.val+1,by omega⟩ : Fin (N+1)) < ⟨s.val+1,by omega⟩ by
change r.val < s.val at hrs; change r.val+1 < s.val+1; omega)
· have hlt : powerShift (C.stage (C.nextIndex hN)) 1 < powerShift C.top 1 := by
rw [← C.initial]
apply powerShift_strictMono 1
exact C.strict (show (0 : Fin (N+1)) < C.nextIndex hN from by change 0 < 1; omega)
rw [← C.terminal] at hlt
exact hlt.trans_le (C.strict.antitone (Fin.le_last _))
noncomputable def rotate (hN : 0 < N) : ResidueChamber (K := K) (N := N) where
top := C.stage (C.nextIndex hN)
hasTop := C.hasStage _
stage := C.rotateStage hN
hasStage := C.rotateStage_has hN
strict := C.rotateStage_strict hN
initial := by
apply (dite_eq_left hN).trans
rfl
lower := C.rotateStage_lower hN
end ResidueChamber
end CoboundaryExpanders.PolynomialVectors
namespace CoboundaryExpanders.RationalLattices
open scoped Polynomial BigOperators
open AffineLattices PolynomialVectors
variable {K : Type} [Field K] {N : ℕ}
lemma polynomial_map_le_standard (A : Submodule K[X] (PolynomialVectors.V K N)) :
A.map (polynomialEmbedding K N) ≤ standard K N := by
rintro v ⟨w,hw,rfl⟩ i
exact ⟨w i,rfl⟩
def PolyBounded (A : Submodule K[X] (PolynomialVectors.V K N)) : Prop :=
∃ m, level (shift K N) (standard K N) m ≤ A.map (polynomialEmbedding K N)
lemma PolyBounded.mono {A B : Submodule K[X] (PolynomialVectors.V K N)}
(hA : PolyBounded A) (hAB : A ≤ B) : PolyBounded B := by
obtain ⟨m,hm⟩ := hA
exact ⟨m,hm.trans (Submodule.map_mono hAB)⟩
lemma PolyBounded.powerShift {A : Submodule K[X] (PolynomialVectors.V K N)}
(hA : PolyBounded A) (r : ℕ) : PolyBounded (powerShift A r) := by
obtain ⟨m,hm⟩ := hA
refine ⟨m+r,?_⟩
rw [powerShift_map_embedding,level_add]
exact level_mono _ _ hm
lemma polyBounded_vertex (A : Vertex K N) : PolyBounded (polynomialLattice K N A) := by
unfold PolyBounded
rw [polynomialLattice_map]
exact vertex_bounded _ _ A
lemma normalizedPolynomial_exists (hN : 0 < N)
(A : Submodule K[X] (PolynomialVectors.V K N)) (hA : PolyBounded A) :
∃ B : Vertex K N, ∃ m, A.map (polynomialEmbedding K N) = level (shift K N) B.val m := by
obtain ⟨m,hm⟩ := hA
obtain ⟨B,j,_,hj⟩ := exists_normalized (shift K N) (standard K N)
(shift_standard_le K N) (standard_not_le_shift K N hN) m
(A.map (polynomialEmbedding K N)) (polynomial_map_le_standard A) hm (shift_le_self K N _)
exact ⟨B,j,hj⟩
noncomputable def normalizedPolynomial (hN : 0 < N)
(A : Submodule K[X] (PolynomialVectors.V K N)) (hA : PolyBounded A) : Vertex K N :=
(normalizedPolynomial_exists hN A hA).choose
namespace BoundedChamber
variable (C : ResidueChamber (K := K) (N := N)) (hC : PolyBounded C.top)
include hC in
lemma stage_bounded (r : Fin (N+1)) : PolyBounded (C.stage r) :=
(hC.powerShift 1).mono (C.lower r)
noncomputable def vertex (hN : 0 < N) (r : Fin N) : Vertex K N :=
normalizedPolynomial hN (C.stage r.castSucc) (stage_bounded C hC r.castSucc)
noncomputable def face (hN : 0 < N) : Finset (Vertex K N) :=
Finset.univ.image (vertex C hC hN)
end BoundedChamber
end CoboundaryExpanders.RationalLattices
namespace CoboundaryExpanders.PolynomialVectors.ResidueChamber
open scoped Polynomial
variable {K : Type} [Field K] {N : ℕ}
noncomputable def reroot (C : ResidueChamber (K := K) (N := N)) (hN : 0 < N) (j : ℕ) :
ResidueChamber (K := K) (N := N) := (fun D : ResidueChamber (K := K) (N := N) => D.rotate hN)^[j] C
@[simp] lemma reroot_zero (C : ResidueChamber (K := K) (N := N)) (hN : 0 < N) : C.reroot hN 0 = C := rfl
lemma reroot_succ (C : ResidueChamber (K := K) (N := N)) (hN : 0 < N) (j : ℕ) :
C.reroot hN (j+1) = (C.reroot hN j).rotate hN := Function.iterate_succ_apply' _ _ _
end CoboundaryExpanders.PolynomialVectors.ResidueChamber
namespace CoboundaryExpanders.RationalLattices.BoundedChamber
open scoped Polynomial BigOperators
open AffineLattices PolynomialVectors
variable {K : Type} [Field K] {N M : ℕ}
variable (C : ResidueChamber (K := K) (N := N)) (hC : PolyBounded C.top)
include hC in
lemma rotate_bounded (hN : 0 < N) : PolyBounded (C.rotate hN).top := stage_bounded C hC _
include hC in
lemma reroot_bounded (hN : 0 < N) (j : ℕ) : PolyBounded (C.reroot hN j).top := by
induction j with
| zero => exact hC
| succ j ih => rw [C.reroot_succ]; exact rotate_bounded _ ih _
end CoboundaryExpanders.RationalLattices.BoundedChamber
namespace CoboundaryExpanders.RationalLattices.FullChamber
open scoped Polynomial BigOperators
open AffineLattices PolynomialVectors
variable {K : Type} [Field K] {M : ℕ}
noncomputable def descentCore (E : FullChamber K (M+2) (by omega)) : Finset (Vertex K (M+2)) :=
(AffineWindow.descents (by omega) E.polynomialChamber.window).image
(fun r => E.vertex (finRotate (M+2) r))
end CoboundaryExpanders.RationalLattices.FullChamber
namespace CoboundaryExpanders.RationalLattices.BoundedChamber
open scoped Polynomial BigOperators
open AffineLattices PolynomialVectors
variable {K : Type} [Field K] {N : ℕ}
noncomputable def descentCore {M : ℕ} (C : ResidueChamber (K := K) (N := M+2))
(hC : PolyBounded C.top) : Finset (Vertex K (M+2)) :=
(AffineWindow.descents (by omega) C.window).image
(fun r => vertex C hC (by omega) (finRotate (M+2) r))
end CoboundaryExpanders.RationalLattices.BoundedChamber
namespace CoboundaryExpanders.RationalLattices
open scoped Polynomial BigOperators
open AffineLattices PolynomialVectors
variable {K : Type} [Field K] {M : ℕ}
def codistanceBlock (m : ℕ) (A : Finset (Vertex K (M+2))) : Set (Finset (Vertex K (M+2))) :=
{s | ∃ C : FullChamber K (M+2) (by omega), C.length = m+1 ∧ C.descentCore = A ∧ s ⊆ C.face}
def codistanceLink (m : ℕ) (A : Finset (Vertex K (M+2))) :
Set (Finset (Vertex K (M+2))) := {s | Disjoint A s ∧ s ∈ codistanceBlock m A}
end CoboundaryExpanders.RationalLattices
end
end OAI
end
section
-- module Solutions.OAIQ3_Cob.Coboundary_ChamberCones
attribute [-instance] _root_.OAI.CoboundaryExpanders.InfiniteChains.Complex.faceMulAction _root_.OAI.CoboundaryExpanders.InfiniteChains.FiniteWeights.faceFintype
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
/-!
Finite pivots, polynomial residue-chamber links, and exactness via finite joins.
-/
noncomputable section
open scoped Polynomial BigOperators
namespace CoboundaryExpanders.PolynomialVectors
open scoped Polynomial BigOperators
variable {K : Type} [Field K] {N M : ℕ}
lemma constant_remainder_mem_diagonal (b : Fin N → V K N) (s : Finset (Fin N))
(f : Fin N → K[X]) :
(∑ i, (f i - if i ∈ s then Polynomial.C ((f i).coeff 0) else 0) • b i) ∈
diagonalModule b s := by
classical
apply Submodule.sum_mem
intro i _
by_cases hi : i ∈ s
· simp only [ite_eq_left hi]
have hd : Polynomial.X ∣ f i-Polynomial.C ((f i).coeff 0) := by
apply Polynomial.X_dvd_iff.mpr
simp
obtain ⟨q,hq⟩ := hd
rw [hq,mul_comm, mul_smul]
apply Submodule.smul_mem
exact Submodule.subset_span ⟨i,by simp [diagonalFamily,hi]⟩
· simp only [ite_eq_right hi,sub_zero]
apply Submodule.smul_mem
exact Submodule.subset_span ⟨i,by simp [diagonalFamily,hi]⟩
lemma selectedSection_mem_of_combination (b : Fin N → V K N) (σ : Fin M → Fin N)
(hσ : Function.Injective σ) (D : Submodule K[X] (V K N))
(hCD : diagonalModule b (Finset.univ.image σ) ≤ D)
(f : Fin N → K[X]) (hf : (∑ i, f i • b i) ∈ D) :
selectedSection b σ (fun r => (f (σ r)).coeff 0) ∈ D := by
classical
let s := Finset.univ.image σ
let g (i : Fin N) : K[X] := if i ∈ s then Polynomial.C ((f i).coeff 0) else 0
have hg : (∑ i, g i • b i) = selectedSection b σ (fun r => (f (σ r)).coeff 0) := by
rw [selectedSection_polynomial]
calc
(∑ i, g i • b i) = ∑ i ∈ s, Polynomial.C ((f i).coeff 0) • b i := by
simp only [g,ite_smul,zero_smul,← Finset.sum_filter]
simp
_ = ∑ r, Polynomial.C ((f (σ r)).coeff 0) • b (σ r) := Finset.sum_image hσ.injOn
have hc : (∑ i, (f i-g i) • b i) ∈ D := hCD (constant_remainder_mem_diagonal b s f)
have hh := D.sub_mem hf hc
have he : (∑ i, f i • b i) - (∑ i, (f i-g i) • b i) = ∑ i, g i • b i := by
simp only [sub_smul,Finset.sum_sub_distrib,sub_sub_cancel]
rw [he,hg] at hh
exact hh
end CoboundaryExpanders.PolynomialVectors
namespace CoboundaryExpanders.PolynomialVectors
open scoped Polynomial BigOperators
variable {K : Type} [Field K] {N M : ℕ}
lemma selectedSection_mem_diagonal_iff (b : Fin N → V K N) (a : Fin N → ℕ)
(hb : ∀ i, Leading (b i) i (a i)) (σ : Fin M → Fin N)
(hσ : StrictMono (fun r => N*a (σ r)+(σ r).val)) (x : Fin M → K) :
selectedSection b σ x ∈ diagonalModule b (Finset.univ.image σ) ↔ x = 0 := by
classical
constructor
· intro hx
by_contra hn
obtain ⟨r,hr⟩ := FinitePivots.exists_leading hn
have hl := selectedSection_leading b a hb σ hσ x r hr
have hh := pivotDegree_min _ (diagonal_hasPivots b a hb (Finset.univ.image σ)) (σ r) hx hl
rw [diagonal_pivotDegree b a hb] at hh
have hm : σ r ∈ Finset.univ.image σ := Finset.mem_image.mpr ⟨r,Finset.mem_univ _,rfl⟩
simp only [ite_eq_left hm] at hh
omega
· rintro rfl
rw [map_zero]
exact Submodule.zero_mem _
lemma combination_sub_selected_mem (b : Fin N → V K N) (σ : Fin M → Fin N)
(hσ : Function.Injective σ) (f : Fin N → K[X]) :
(∑ i, f i • b i) - selectedSection b σ (fun r => (f (σ r)).coeff 0) ∈
diagonalModule b (Finset.univ.image σ) := by
classical
let s := Finset.univ.image σ
let g (i : Fin N) : K[X] := if i ∈ s then Polynomial.C ((f i).coeff 0) else 0
have hg : (∑ i, g i • b i) = selectedSection b σ (fun r => (f (σ r)).coeff 0) := by
rw [selectedSection_polynomial]
calc
(∑ i, g i • b i) = ∑ i ∈ s, Polynomial.C ((f i).coeff 0) • b i := by
simp only [g,ite_smul,zero_smul,← Finset.sum_filter]
simp
_ = ∑ r, Polynomial.C ((f (σ r)).coeff 0) • b (σ r) := Finset.sum_image hσ.injOn
rw [← hg,← Finset.sum_sub_distrib]
simp only [← sub_smul]
exact constant_remainder_mem_diagonal b s f
lemma selectedResidue_liftSelected (b : Fin N → V K N) (a : Fin N → ℕ)
(hb : ∀ i, Leading (b i) i (a i)) (σ : Fin M → Fin N)
(hσ : StrictMono (fun r => N*a (σ r)+(σ r).val)) (W : Submodule K (Fin M → K)) :
selectedResidue b σ (liftSelected b σ W) = W := by
ext x
constructor
· rintro ⟨c,hc,y,hy,he⟩
have hh : selectedSection b σ (x-y) = c := by rw [map_sub,he]; abel
have hz := (selectedSection_mem_diagonal_iff b a hb σ hσ (x-y)).mp (hh ▸ hc)
have hxy := sub_eq_zero.mp hz
exact hxy ▸ hy
· intro hx
exact ⟨0,Submodule.zero_mem _,x,hx,by simp⟩
lemma liftSelected_selectedResidue (b : Fin N → V K N) (σ : Fin M → Fin N)
(hσ : Function.Injective σ) (D : Submodule K[X] (V K N))
(hCD : diagonalModule b (Finset.univ.image σ) ≤ D)
(hDA : D ≤ Submodule.span K[X] (Set.range b)) :
liftSelected b σ (selectedResidue b σ D) = D := by
apply le_antisymm
· rintro v ⟨c,hc,x,hx,rfl⟩
exact D.add_mem (hCD hc) hx
· intro v hv
obtain ⟨f,hf⟩ := (Submodule.mem_span_range_iff_exists_fun K[X]).mp (hDA hv)
let x := fun r => (f (σ r)).coeff 0
refine ⟨v-selectedSection b σ x,?_,x,?_,by abel⟩
· rw [← hf]
exact combination_sub_selected_mem b σ hσ f
· exact selectedSection_mem_of_combination b σ hσ D hCD f (hf ▸ hv)
noncomputable def selectedIntervalEquiv (b : Fin N → V K N) (a : Fin N → ℕ)
(hb : ∀ i, Leading (b i) i (a i)) (σ : Fin M → Fin N)
(hσ : StrictMono (fun r => N*a (σ r)+(σ r).val)) :
{D : Submodule K[X] (V K N) // diagonalModule b (Finset.univ.image σ) ≤ D ∧
D ≤ Submodule.span K[X] (Set.range b)} ≃o Submodule K (Fin M → K) where
toFun D := selectedResidue b σ D.val
invFun W := ⟨liftSelected b σ W,diagonal_le_liftSelected b σ W,liftSelected_le_span b σ W⟩
left_inv D := Subtype.ext (liftSelected_selectedResidue b σ
(fun i j he => hσ.injective (congrArg (fun t => N*a t+t.val) he)) D.val D.property.1 D.property.2)
right_inv W := selectedResidue_liftSelected b a hb σ hσ W
map_rel_iff' := by
intro D E
constructor
· intro h
change D.val ≤ E.val
rw [← liftSelected_selectedResidue b σ
(fun i j he => hσ.injective (congrArg (fun t => N*a t+t.val) he)) D.val D.property.1 D.property.2]
rintro v ⟨c,hc,x,hx,rfl⟩
exact E.val.add_mem (E.property.1 hc) (h hx)
· intro h x hx
exact h hx
end CoboundaryExpanders.PolynomialVectors
namespace CoboundaryExpanders.FinitePivots
open Module
variable {K : Type} [Field K] {N : ℕ}
noncomputable def prefixFlag (K : Type) [Field K] (N : ℕ) :
SphericalOpposition.CompleteFlag K (Fin N → K) N where
space i := prefSpace K N i.val
mono := by intro i j hij v hv l hl; exact hv l (le_trans hij hl)
dimension := by simp
rank i := prefSpace_finrank i.val (by omega)
end CoboundaryExpanders.FinitePivots
namespace CoboundaryExpanders.PolynomialVectors
open scoped Polynomial BigOperators
open Module InfiniteChains InfiniteChains.Attachment InfiniteChains.Cone
variable {K : Type} [Field K] {N M : ℕ}
def prefixPatternComplex (b : Fin N → V K N) (a : Fin N → ℕ)
(hb : ∀ i, Leading (b i) i (a i)) (σ : Fin M → Fin N) :
InfiniteChains.Complex (SelectedInterval b σ) where
faces := {s | (∀ D ∈ s, PrefixPattern b a hb σ D) ∧
(s : Set (SelectedInterval b σ)).Pairwise (fun D E => D ≤ E ∨ E ≤ D)}
empty_mem := by simp
downward := by intro s t hs hts; exact ⟨fun D hD => hs.1 D (hts hD),hs.2.mono hts⟩
end CoboundaryExpanders.PolynomialVectors
namespace CoboundaryExpanders.PolynomialVectors
open scoped Polynomial BigOperators
variable {K : Type} [Field K] {N : ℕ}
namespace ResidueChamber
variable (C : ResidueChamber (K := K) (N := N))
noncomputable def blockBasis (b : Fin N → V K N) (a : Fin (N+1)) : Fin N → V K N :=
diagonalFamily b (wordPrefix C.word a)
noncomputable def blockDegree (a : Fin (N+1)) (i : Fin N) : ℕ :=
pivotDegree C.top C.hasTop i + if (C.word.symm i).val < a.val then 1 else 0
lemma blockBasis_leading (b : Fin N → V K N)
(hb : ∀ i, Leading (b i) i (pivotDegree C.top C.hasTop i)) (a : Fin (N+1)) (i : Fin N) :
Leading (C.blockBasis b a i) i (C.blockDegree a i) := by
simpa only [blockBasis,blockDegree,wordPrefix,Finset.mem_filter,Finset.mem_univ,true_and] using
diagonal_leading b _ hb (wordPrefix C.word a) i
lemma block_upper (b : Fin N → V K N)
(hb : ∀ r, C.stage r = diagonalModule b (wordPrefix C.word r)) (a : Fin (N+1)) :
Submodule.span K[X] (Set.range (C.blockBasis b a)) = C.stage a := (hb a).symm
lemma block_lower (b : Fin N → V K N)
(hb : ∀ r, C.stage r = diagonalModule b (wordPrefix C.word r)) (a z : Fin (N+1)) (haz : a ≤ z) :
diagonalModule (C.blockBasis b a) (Finset.univ.image (wordSlice C.word a z)) = C.stage z := by
rw [blockBasis,diagonalModule_union b _ _ (wordPrefix_disjoint_slice C.word a z),
wordPrefix_union_slice C.word a z haz,← hb z]
end ResidueChamber
end CoboundaryExpanders.PolynomialVectors
namespace CoboundaryExpanders.PolynomialVectors.ResidueChamber
open scoped Polynomial BigOperators
variable {K : Type} [Field K] {N : ℕ}
variable (C : ResidueChamber (K := K) (N := N))
def HasProfile (D : Submodule K[X] (V K N)) (r : Fin (N+1)) : Prop :=
∃ hD : HasPivots D, ∀ i, pivotDegree D hD i = pivotDegree C.top C.hasTop i +
if (C.word.symm i).val < r.val then 1 else 0
lemma prefixPattern_iff_profile (b : Fin N → V K N)
(hb : ∀ i, Leading (b i) i (pivotDegree C.top C.hasTop i))
(a z : Fin (N+1)) (haz : a ≤ z)
(D : SelectedInterval (C.blockBasis b a) (wordSlice C.word a z)) :
PrefixPattern (C.blockBasis b a) (C.blockDegree a) (C.blockBasis_leading b hb a)
(wordSlice C.word a z) D ↔
∃ r : Fin (N+1), a < r ∧ r < z ∧ C.HasProfile D.val r := by
let hDP := selectedInterval_hasPivots (C.blockBasis b a) (C.blockDegree a)
(C.blockBasis_leading b hb a) (wordSlice C.word a z) D
constructor
· rintro ⟨k,hk0,hkz,hpat⟩
let r : Fin (N+1) := ⟨a.val+k,by have := z.isLt; omega⟩
refine ⟨r,(by change a.val < a.val+k; omega),(by change a.val+k < z.val; omega),hDP,?_⟩
intro i
have hp := selected_pivot_bounds (C.blockBasis b a) (C.blockDegree a)
(C.blockBasis_leading b hb a) (wordSlice C.word a z) D i
by_cases hi : i ∈ Finset.univ.image (wordSlice C.word a z)
· obtain ⟨s,_,rfl⟩ := Finset.mem_image.mp hi
have he := hpat s
have hb0 : C.blockDegree a (wordSlice C.word a z s) =
pivotDegree C.top C.hasTop (wordSlice C.word a z s) := by
simp only [blockDegree,wordSlice,Equiv.symm_apply_apply,Fin.val_mk]
rw [ite_eq_right (by omega),Nat.add_zero]
rw [hb0] at hp he
have hm : wordSlice C.word a z s ∈ Finset.univ.image (wordSlice C.word a z) :=
Finset.mem_image.mpr ⟨s,Finset.mem_univ _,rfl⟩
simp only [hm,ite_true] at hp
dsimp only [wordSlice] at hp he
simp only [wordSlice,Equiv.symm_apply_apply,Fin.val_mk]
change pivotDegree D.val hDP _ = pivotDegree C.top C.hasTop _ +
if a.val+s.val < a.val+k then 1 else 0
split_ifs <;> omega
· have hn := (mem_wordSlice_image C.word a z i).not.mp hi
simp only [hi,ite_false,Nat.add_zero] at hp
have he := le_antisymm hp.2 hp.1
rw [he]
dsimp only [blockDegree,r]
split_ifs <;> omega
· rintro ⟨r,har,hrz,hprof⟩
obtain ⟨hD,hdeg⟩ := hprof
refine ⟨r.val-a.val,(by change a.val < r.val at har; omega),?_,?_⟩
· change r.val < z.val at hrz
change a.val < r.val at har
omega
· intro s
rw [hdeg]
simp only [wordSlice,blockDegree,Equiv.symm_apply_apply,Fin.val_mk]
simp only [ite_eq_right (show ¬ a.val+s.val < a.val from by omega),Nat.add_zero]
change a.val < r.val at har
split_ifs <;> omega
end CoboundaryExpanders.PolynomialVectors.ResidueChamber
namespace CoboundaryExpanders.PolynomialVectors.ResidueChamber
open scoped Polynomial BigOperators
open InfiniteChains AffineWindow
variable {K : Type} [Field K] {N L : ℕ}
variable (C : ResidueChamber (K := K) (N := N))
noncomputable def fixedStages (c : Fin (L+1) → Fin (N+1)) : Finset (Submodule K[X] (V K N)) :=
Finset.univ.image (fun j => C.stage (c j))
def IntervalProfile (c : Fin (L+1) → Fin (N+1)) (D : Submodule K[X] (V K N)) : Prop :=
∃ j : Fin L, C.stage (c j.succ) ≤ D ∧ D ≤ C.stage (c j.castSucc) ∧
∃ r : Fin (N+1), c j.castSucc < r ∧ r < c j.succ ∧ C.HasProfile D r
def rootedMinimumLink (c : Fin (L+1) → Fin (N+1)) : InfiniteChains.Complex (Submodule K[X] (V K N)) where
faces := {s | Disjoint s (C.fixedStages c) ∧ ∃ E : ResidueChamber (K := K) (N := N),
E.top = C.top ∧ E.length = C.length ∧ (∀ j, E.stage (c j) = C.stage (c j)) ∧
∀ D ∈ s, ∃ r, E.stage r = D}
empty_mem := by exact ⟨Finset.disjoint_empty_left _,C,rfl,rfl,(fun _ => rfl),by simp⟩
downward := by
intro s t hs hts
obtain ⟨hd,E,ht,hl,hfix,hface⟩ := hs
exact ⟨hd.mono_left hts,E,ht,hl,hfix,fun D hD => hface D (hts hD)⟩
end CoboundaryExpanders.PolynomialVectors.ResidueChamber
namespace CoboundaryExpanders.PolynomialVectors.ResidueChamber
open scoped Polynomial BigOperators
open InfiniteChains InfiniteChains.Attachment InfiniteChains.Cone
variable {K : Type} [Field K] {N : ℕ}
variable (C : ResidueChamber (K := K) (N := N))
def ProfileBetween (a z : Fin (N+1)) (D : Submodule K[X] (V K N)) : Prop :=
C.stage z ≤ D ∧ D ≤ C.stage a ∧ ∃ r : Fin (N+1), a < r ∧ r < z ∧ C.HasProfile D r
def profileIntervalComplex (a z : Fin (N+1)) : InfiniteChains.Complex (Submodule K[X] (V K N)) where
faces := {s | (∀ D ∈ s, C.ProfileBetween a z D) ∧
(s : Set (Submodule K[X] (V K N))).Pairwise (fun D E => D ≤ E ∨ E ≤ D)}
empty_mem := by simp
downward := by intro s t hs hts; exact ⟨fun D hD => hs.1 D (hts hD),hs.2.mono hts⟩
lemma profileInterval_faces_selected (b : Fin N → V K N)
(hb : ∀ i, Leading (b i) i (pivotDegree C.top C.hasTop i))
(hstage : ∀ r, C.stage r = diagonalModule b (wordPrefix C.word r))
(a z : Fin (N+1)) (haz : a ≤ z)
(s : Finset (SelectedInterval (C.blockBasis b a) (wordSlice C.word a z))) :
s ∈ (prefixPatternComplex (C.blockBasis b a) (C.blockDegree a) (C.blockBasis_leading b hb a)
(wordSlice C.word a z)).faces ↔ s.image Subtype.val ∈ (C.profileIntervalComplex a z).faces := by
classical
constructor
· rintro ⟨hpat,hpair⟩
constructor
· intro D hD
obtain ⟨E,hE,rfl⟩ := Finset.mem_image.mp hD
refine ⟨?_,?_,(C.prefixPattern_iff_profile b hb a z haz E).mp (hpat E hE)⟩
· simpa only [C.block_lower b hstage a z haz] using E.property.1
· simpa only [C.block_upper b hstage a] using E.property.2
· intro D hD E hE hne
obtain ⟨D,hDs,rfl⟩ := Finset.mem_image.mp hD
obtain ⟨E,hEs,rfl⟩ := Finset.mem_image.mp hE
exact hpair hDs hEs (fun hh => hne (congrArg Subtype.val hh))
· rintro ⟨hprof,hpair⟩
constructor
· intro D hD
exact (C.prefixPattern_iff_profile b hb a z haz D).mpr
(hprof D.val (Finset.mem_image.mpr ⟨D,hD,rfl⟩)).2.2
· intro D hD E hE hne
exact hpair (Finset.mem_image.mpr ⟨D,hD,rfl⟩) (Finset.mem_image.mpr ⟨E,hE,rfl⟩)
(fun hh => hne (Subtype.ext hh))
noncomputable def profileIntervalCone (b : Fin N → V K N)
(hb : ∀ i, Leading (b i) i (pivotDegree C.top C.hasTop i))
(hstage : ∀ r, C.stage r = diagonalModule b (wordPrefix C.word r))
(a z : Fin (N+1)) (haz : a ≤ z) {n R : ℕ}
(H : BoundedCone (prefixPatternComplex (C.blockBasis b a) (C.blockDegree a)
(C.blockBasis_leading b hb a) (wordSlice C.word a z)) n R) :
BoundedCone (C.profileIntervalComplex a z) n R := by
classical
let A := SelectedInterval (C.blockBasis b a) (wordSlice C.word a z)
let d0 : A := ⟨C.stage a,by rw [C.block_lower b hstage a z haz]; exact C.strict.antitone haz,
by rw [C.block_upper b hstage a]⟩
let f : Submodule K[X] (V K N) → A := fun D =>
if h : C.stage z ≤ D ∧ D ≤ C.stage a then
⟨D,by rw [C.block_lower b hstage a z haz]; exact h.1,
by rw [C.block_upper b hstage a]; exact h.2⟩ else d0
have hfval (D : Submodule K[X] (V K N)) (hD : C.stage z ≤ D ∧ D ≤ C.stage a) : (f D).val = D := by
simp only [f,dite_eq_left hD]
have hret (s) (hs : s ∈ (C.profileIntervalComplex a z).faces) (D) (hD : D ∈ s) : (f D).val = D :=
hfval D ⟨(hs.1 D hD).1,(hs.1 D hD).2.1⟩
have him (s) (hs : s ∈ (C.profileIntervalComplex a z).faces) : (s.image f).image Subtype.val = s := by
rw [Finset.image_image]
exact (Finset.image_congr (fun D hD => hret s hs D hD)).trans (Finset.image_id)
refine H.retract f Subtype.val ?_ ?_ ?_ (fun _ _ => Subtype.val_injective.injOn) hret
· intro s hs
apply (C.profileInterval_faces_selected b hb hstage a z haz (s.image f)).mpr
rwa [him s hs]
· intro s hs
exact (C.profileInterval_faces_selected b hb hstage a z haz s).mp hs
· intro s hs D hD E hE hh
have he := congrArg Subtype.val hh
rwa [hret s hs D hD,hret s hs E hE] at he
end CoboundaryExpanders.PolynomialVectors.ResidueChamber
end
end OAI
end
section
-- module Solutions.OAIQ3_Cob.Coboundary_Mixing
attribute [-instance] _root_.OAI.CoboundaryExpanders.Blocks.gammaNormal _root_.OAI.CoboundaryExpanders.CongruenceFrames.invariant _root_.OAI.CoboundaryExpanders.TypedCosetFaces.complexInvariant _root_.OAI.CoboundaryExpanders.TypedCosetFaces.kernelInvariant _root_.OAI.CoboundaryExpanders.TypedCosetFaces.vertexMulAction
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
noncomputable section
/-!
Small-set expansion, local spectral descent, connectedness, and uniform coset mixing.
-/
open scoped BigOperators
open scoped BigOperators Matrix
open scoped Matrix
open scoped BigOperators InnerProductSpace
namespace CoboundaryExpanders.Construction
open Elementary
variable (p n m : ℕ) [Fact p.Prime]
def truncatedIwahori (hm : 1 ≤ m) :
Subgroup (Matrix.SpecialLinearGroup (Fin (n + 1)) (Trunc p m)) :=
(upperUnitriangular p (n + 1)).comap (Matrix.SpecialLinearGroup.map (residue p m hm))
def reducedGenerated (hn : 1 ≤ n) :=
(cycleGenerated p n hn).map (Matrix.SpecialLinearGroup.map (Ideal.Quotient.mk (powerIdeal p m)))
end CoboundaryExpanders.Construction
namespace CoboundaryExpanders.TypedCosetFaces
open InfiniteChains FiniteWeights Cone
open scoped Pointwise
variable {G I : Type} [Group G] [Fintype G] [DecidableEq I] [Fintype I] (H : I → Subgroup G)
noncomputable instance vertexFintype : Fintype (Vertex H) := Fintype.ofFinite _
end CoboundaryExpanders.TypedCosetFaces
end
end OAI
end
section
-- module Solutions.OAIQ3_Cob.Coboundary_Expansion
attribute [-instance] _root_.OAI.CoboundaryExpanders.InfiniteChains.Complex.faceMulAction _root_.OAI.CoboundaryExpanders.TypedCosetFaces.complexInvariant _root_.OAI.CoboundaryExpanders.TypedCosetFaces.kernelInvariant _root_.OAI.CoboundaryExpanders.TypedCosetFaces.vertexMulAction
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
/-!
Local repairs, fat-ladder inequalities, and uniform raw cosystolic expansion.
-/
noncomputable section
open scoped BigOperators
open scoped BigOperators Matrix
open scoped Matrix
open scoped BigOperators InnerProductSpace
namespace CoboundaryExpanders.InfiniteChains
namespace FiniteWeights
open Cone Averaging
open scoped Pointwise
variable {V : Type} [DecidableEq V] [Fintype V]
attribute [local instance] Classical.propDecidable
def rawNorm (X : CoboundaryExpanders.InfiniteChains.Complex V) (N r : ℕ) (f : Finset V → k) : ℝ :=
∑ s ∈ level X r, if f s ≠ 0 then (cofaces X N s:ℝ) else 0
end FiniteWeights
end CoboundaryExpanders.InfiniteChains
namespace CoboundaryExpanders.TypedCosetFaces
section
open InfiniteChains
open scoped Pointwise
variable {G I : Type} [Group G] [DecidableEq I] (H : I → Subgroup G)
def faceStabilizer (s : Finset (Vertex H)) : Subgroup G := MulAction.stabilizer G s
end
open InfiniteChains FiniteWeights Cone
open scoped Pointwise
end CoboundaryExpanders.TypedCosetFaces
end
end OAI
end
section
-- module Solutions.OAIQ3_Cob.Coboundary_Frames
attribute [-instance] _root_.OAI.CoboundaryExpanders.InfiniteChains.Complex.faceMulAction _root_.OAI.CoboundaryExpanders.InfiniteChains.FiniteWeights.faceFintype
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
/-!
Unimodular frames, bad-simplex transport, height reduction, and partial-basis exactness.
-/
noncomputable section
open scoped BigOperators
namespace CoboundaryExpanders.InfiniteChains.BadSimplex
open Attachment
variable {W V : Type} [DecidableEq W] [DecidableEq V]
def stage (X : CoboundaryExpanders.InfiniteChains.Complex (W ⊕ V)) (r : ℕ) : CoboundaryExpanders.InfiniteChains.Complex (W ⊕ V) where
faces := {s | s ∈ X.faces ∧ s.toLeft.card ≤ r}
empty_mem := ⟨X.empty_mem, by simp [Finset.toLeft]⟩
downward := by
intro s t hs ht
exact ⟨X.downward hs.1 ht,
(Finset.card_le_card (Finset.toLeft_subset_toLeft ht)).trans hs.2⟩
def goodLink (X : CoboundaryExpanders.InfiniteChains.Complex (W ⊕ V)) (F : Finset W)
(hF : F.disjSum (∅ : Finset V) ∈ X.faces) : CoboundaryExpanders.InfiniteChains.Complex V where
faces := {t | F.disjSum t ∈ X.faces}
empty_mem := hF
downward := by
intro s t hs ht
exact X.downward hs (Finset.disjSum_mono (by rfl) ht)
abbrev BadFaces (X : CoboundaryExpanders.InfiniteChains.Complex (W ⊕ V)) (r : ℕ) :=
{F : Finset W // F.disjSum (∅ : Finset V) ∈ X.faces ∧ F.card = r+1}
end CoboundaryExpanders.InfiniteChains.BadSimplex
end
noncomputable section
namespace CoboundaryExpanders.InfiniteChains.ChainTransport
open Attachment
variable {V W : Type} [DecidableEq V] [DecidableEq W]
def relabel (f : V → W) : Raw V →ₗ[k] Raw W :=
Finsupp.lmapDomain k k (Finset.image f)
omit [DecidableEq V] in
@[simp] lemma relabel_single (f : V → W) (s : Finset V) (a : k) :
relabel f (Finsupp.single s a) = Finsupp.single (s.image f) a := by
simp [relabel]
end CoboundaryExpanders.InfiniteChains.ChainTransport
end
noncomputable section
namespace CoboundaryExpanders.InfiniteChains.HeightReduction
open Attachment BadSimplex ChainTransport
attribute [local instance] Classical.propDecidable Classical.decEq
variable {V : Type} [DecidableEq V]
def bounded (X : CoboundaryExpanders.InfiniteChains.Complex V) (h : V → ℕ) (H : ℕ) : CoboundaryExpanders.InfiniteChains.Complex V where
faces := {s | s ∈ X.faces ∧ ∀ v ∈ s, h v ≤ H}
empty_mem := ⟨X.empty_mem, by simp⟩
downward := by
intro s t hs ht
exact ⟨X.downward hs.1 ht, fun v hv => hs.2 v (ht hv)⟩
def splitComplex (X : CoboundaryExpanders.InfiniteChains.Complex V) (h : V → ℕ) (H : ℕ) : CoboundaryExpanders.InfiniteChains.Complex (Bad h H ⊕ Good h H) where
faces := {s | s.image (split h H) ∈ (bounded X h H).faces}
empty_mem := by simpa using (bounded X h H).empty_mem
downward := by
intro s t hs ht
exact (bounded X h H).downward hs (Finset.image_mono _ ht)
end CoboundaryExpanders.InfiniteChains.HeightReduction
end
end OAI
end
section
-- module Solutions.OAIQ3_Cob.Congruence_Transfer
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
noncomputable section
/-!
Odd-index transfer, comparison of bar resolutions, and homology-coinvariant models.
-/
open CategoryTheory
open scoped BigOperators
open CategoryTheory Finsupp
open CategoryTheory Finsupp MonoidalCategory
namespace CoboundaryExpanders.Transfer
section
open CategoryTheory Representation Finsupp
universe u
variable {k G : Type u} [CommRing k] [Group G] [DecidableEq G]
(S : Subgroup G) [S.Normal] [Fintype (G ⧸ S)]
def barCoinvariantInclusion :
CoinvariantModel.complex (k := k) (G := S) ⟶ subgroupChains S (Rep.barComplex k G) :=
((Rep.coinvariantsFunctor k S).mapHomologicalComplex _).map
(BarComparison.inclusion (k := k) S)
end
open Representation
universe u
end CoboundaryExpanders.Transfer
namespace CoboundaryExpanders.Transfer
open Representation Finsupp
universe u
variable {k G : Type u} [CommRing k] [Group G] [DecidableEq G]
(S : Subgroup G) [S.Normal] [Fintype (G ⧸ S)]
def barCoinvariantAdjusted (g : G) : CoinvariantModel.complex (k := k) (G := S) ⟶
subgroupChains S (Rep.barComplex k G) :=
((Rep.coinvariantsFunctor k S).mapHomologicalComplex _).map
(BarComparison.adjusted S g)
end CoboundaryExpanders.Transfer
end
end OAI
end
section
-- module Solutions.OAIQ3_Cob.Congruence_Coinvariants
attribute [-instance] _root_.OAI.CoboundaryExpanders.InfiniteChains.FiniteWeights.faceFintype _root_.OAI.CoboundaryExpanders.MatrixOpposition.cutVertexFintype _root_.OAI.CoboundaryExpanders.TypedCosetFaces.kernelInvariant _root_.OAI.CoboundaryExpanders.TypedCosetFaces.vertexAction _root_.OAI.CoboundaryExpanders.TypedCosetFaces.vertexFintype
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
noncomputable section
/-!
Simplicial group actions, permutation modules, coset sums, and chain coinvariants.
-/
section
open CategoryTheory
open scoped BigOperators
open CategoryTheory Finsupp
open CategoryTheory Finsupp MonoidalCategory
open scoped BigOperators Matrix
open scoped Matrix
namespace CoboundaryExpanders.FinsuppPermutation
open CategoryTheory
variable (k G A : Type) [CommRing k] [Group G] [MulAction G A]
def coeffIso : Rep.ofMulAction k G A ≅ rep k G A :=
Rep.mkIso { MonoidAlgebra.coeffLinearEquiv k with
isIntertwining' := by
intro g
apply MonoidAlgebra.lhom_ext'
intro a
apply LinearMap.ext
intro r
simp [ρ_single] }
end CoboundaryExpanders.FinsuppPermutation
namespace CoboundaryExpanders.TypedCosetFaces
open InfiniteChains
variable {G I : Type} [Group G] [DecidableEq I] (H : I → Subgroup G)
instance basisMulAction (n : ℕ) : MulAction G (Basis H n) where
smul g x := ⟨x.1, g • x.2⟩
one_smul x := congrArg (Sigma.mk x.1) (one_smul G x.2)
mul_smul g h x := congrArg (Sigma.mk x.1) (mul_smul g h x.2)
def gradedEquiv (n : ℕ) : Basis H n ≃ (complex H).Face n :=
Equiv.ofBijective (gradedFace H n) (gradedFace_bijective H n)
lemma gradedFace_smul (n : ℕ) (g : G) (x : Basis H n) :
gradedFace H n (g • x) = g • gradedFace H n x := by
rcases x with ⟨A,x⟩
induction x using Quotient.inductionOn with | h h =>
apply Subtype.ext
change face H (g*h) A.val = (face H h A.val).map (MulAction.toPerm g).toEmbedding
exact (map_face H g h A.val).symm
end CoboundaryExpanders.TypedCosetFaces
end
open CategoryTheory
open scoped BigOperators
open CategoryTheory Finsupp
open CategoryTheory Finsupp MonoidalCategory
open scoped BigOperators Matrix
open scoped Matrix
open scoped MonoidAlgebra
namespace CoboundaryExpanders.CosetModules
section
universe u
variable {k G : Type u} [Field k] [Group G]
def extend (H : Subgroup G) (A : Rep k G) (x : A)
(hx : ∀ h : H, A.ρ h x = x) : permutation (k := k) H ⟶ A :=
Rep.ofHom ⟨(Finsupp.linearCombination k (orbitVector H A x hx)).comp (MonoidAlgebra.coeffLinearEquiv k).toLinearMap, by
intro g
apply MonoidAlgebra.lhom_ext'
intro q
apply LinearMap.ext
intro r
simp only [LinearMap.comp_apply, MonoidAlgebra.lsingle_apply,
Representation.ofMulAction_single]
change (Finsupp.linearCombination k (orbitVector H A x hx)) (Finsupp.single (g • q) r) =
A.ρ g ((Finsupp.linearCombination k (orbitVector H A x hx)) (Finsupp.single q r))
simp only [Finsupp.linearCombination_single, map_smul, orbitVector_smul]⟩
@[simp] theorem extend_single (H : Subgroup G) (A : Rep k G) (x : A)
(hx : ∀ h : H, A.ρ h x = x) (a : G) (r : k) :
extend H A x hx (MonoidAlgebra.single (QuotientGroup.mk a) r) = r • A.ρ a x := by
change (Finsupp.linearCombination k (orbitVector H A x hx))
(Finsupp.single (QuotientGroup.mk a) r) = _
rw [Finsupp.linearCombination_single, orbitVector_mk]
def base (H : Subgroup G) : Rep.trivial k H k ⟶ Rep.res H.subtype (permutation (k := k) H) :=
Rep.ofHom ⟨MonoidAlgebra.lsingle (QuotientGroup.mk (1 : G)), by
intro h
apply LinearMap.ext
intro r
change MonoidAlgebra.single (QuotientGroup.mk (1 : G)) r =
(Representation.ofMulAction k G (G ⧸ H)) h (MonoidAlgebra.single (QuotientGroup.mk (1 : G)) r)
rw [Representation.ofMulAction_single]
congr 1
change (QuotientGroup.mk (1 : G) : G ⧸ H) = QuotientGroup.mk (h.val * 1)
simp only [mul_one]
apply Quotient.sound
simpa only [QuotientGroup.leftRel_apply, inv_one, one_mul] using h.property⟩
theorem projective_permutation (H : Subgroup G) [Projective (Rep.trivial k H k)] :
Projective (permutation (k := k) H) where
factors {E X} f e he := by
let f₀ : Rep.trivial k H k ⟶ Rep.res H.subtype X :=
base H ≫ (Rep.resFunctor (k := k) H.subtype).map f
let e₀ : Rep.res H.subtype E ⟶ Rep.res H.subtype X :=
(Rep.resFunctor (k := k) H.subtype).map e
have : Epi e₀ := by
apply (Rep.epi_iff_surjective e₀).mpr
exact (Rep.epi_iff_surjective e).mp he
let l := Projective.factorThru f₀ e₀
let x : E := l 1
have hx : ∀ h : H, E.ρ h x = x := by
intro h
have hh := Rep.hom_comm_apply l h 1
simpa [x] using hh.symm
refine ⟨extend H E x hx, ?_⟩
apply Rep.hom_ext
apply Representation.IntertwiningMap.ext
apply MonoidAlgebra.lhom_ext'
intro q
apply LinearMap.ext
intro r
induction q using Quotient.inductionOn with | h a =>
have hbase : e x = f (MonoidAlgebra.single (QuotientGroup.mk (1 : G)) (1 : k)) := by
have hh := congrArg (fun z => z 1) (Projective.factorThru_comp f₀ e₀)
exact hh
change e (extend H E x hx (MonoidAlgebra.single (QuotientGroup.mk a) r)) =
f (MonoidAlgebra.single (QuotientGroup.mk a) r)
rw [extend_single, map_smul, Rep.hom_comm_apply, hbase]
have hf := Rep.hom_comm_apply f a (MonoidAlgebra.single (QuotientGroup.mk (1 : G)) (1 : k))
rw [← hf]
simp only [Representation.ofMulAction_single]
change r • f (MonoidAlgebra.single (QuotientGroup.mk (a * 1)) 1) = _
rw [mul_one, ← map_smul, MonoidAlgebra.smul_single, smul_eq_mul, mul_one]
theorem projective_permutation_of_invertible_order (H : Subgroup G)
[Finite H] [NeZero (Nat.card H : k)] : Projective (permutation (k := k) H) := by
let A := Rep.trivial k H k
let M := Rep.toModuleMonoidAlgebra.obj A
let : Module.Projective (MonoidAlgebra k H) M :=
Module.projective_of_isSemisimpleRing _ _
have : Projective M := inferInstance
have : Projective A :=
Rep.equivalenceModuleMonoidAlgebra.toAdjunction.projective_of_map_projective A
(inferInstance : Projective M)
exact projective_permutation H
end
theorem projective_permutation_of_odd_order {G : Type} [Group G]
(H : Subgroup G) [Finite H] (hH : Odd (Nat.card H)) :
Projective (permutation (k := ZMod 2) H) := by
have hc : (Nat.card H : ZMod 2) = 1 := by
rcases hH with ⟨r, hr⟩
rw [hr]
have htwo : (2 : ZMod 2) = 0 := by decide
simp [Nat.cast_add, Nat.cast_mul, htwo]
let : NeZero (Nat.card H : ZMod 2) := ⟨by rw [hc]; exact one_ne_zero⟩
exact projective_permutation_of_invertible_order H
end CoboundaryExpanders.CosetModules
namespace CoboundaryExpanders.CosetSums
variable {k G I : Type} [Field k] [Group G] (H : I → Subgroup G)
def inclusion (i : I) : CosetModules.permutation (k := k) (H i) ⟶ permutation (k := k) H :=
Rep.ofHom ⟨(Finsupp.linearCombination k (fun q : G ⧸ H i =>
MonoidAlgebra.single (⟨i,q⟩ : Basis H) (1 : k))).comp
(MonoidAlgebra.coeffLinearEquiv k).toLinearMap, by
intro g
apply MonoidAlgebra.lhom_ext'
intro q
apply LinearMap.ext
intro r
simp only [LinearMap.comp_apply, MonoidAlgebra.lsingle_apply,
Representation.ofMulAction_single]
change Finsupp.linearCombination _ _ (Finsupp.single (g • q) r) =
(Representation.ofMulAction k G (Basis H)) g
(Finsupp.linearCombination _ _ (Finsupp.single q r))
simp [Representation.ofMulAction_single]
rfl⟩
@[simp] theorem inclusion_single (i : I) (q : G ⧸ H i) (r : k) :
inclusion (k := k) H i (MonoidAlgebra.single q r) =
MonoidAlgebra.single (⟨i,q⟩ : Basis H) r := by
change Finsupp.linearCombination _ _ (Finsupp.single q r) = _
simp
def descend (A : Rep k G) (f : ∀ i, CosetModules.permutation (k := k) (H i) ⟶ A) :
permutation (k := k) H ⟶ A :=
Rep.ofHom ⟨(Finsupp.linearCombination k (fun x : Basis H =>
f x.1 (MonoidAlgebra.single x.2 (1 : k)))).comp
(MonoidAlgebra.coeffLinearEquiv k).toLinearMap, by
intro g
apply MonoidAlgebra.lhom_ext'
intro x
apply LinearMap.ext
intro r
simp only [LinearMap.comp_apply, MonoidAlgebra.lsingle_apply,
Representation.ofMulAction_single]
change Finsupp.linearCombination _ _ (Finsupp.single (g • x) r) =
A.ρ g (Finsupp.linearCombination _ _ (Finsupp.single x r))
simp only [Finsupp.linearCombination_single, map_smul]
congr 1
change (f x.1).hom (MonoidAlgebra.single (g • x.2) (1 : k)) =
A.ρ g ((f x.1).hom (MonoidAlgebra.single x.2 (1 : k)))
have hh := Rep.hom_comm_apply (f x.1) g (MonoidAlgebra.single x.2 (1 : k))
rw [Representation.ofMulAction_single] at hh
exact hh⟩
@[simp] theorem descend_single (A : Rep k G)
(f : ∀ i, CosetModules.permutation (k := k) (H i) ⟶ A)
(x : Basis H) (r : k) :
descend H A f (MonoidAlgebra.single x r) = f x.1 (MonoidAlgebra.single x.2 r) := by
change Finsupp.linearCombination _ _ (Finsupp.single x r) = _
simp [← map_smul]
theorem projective [∀ i, Projective (CosetModules.permutation (k := k) (H i))] :
Projective (permutation (k := k) H) where
factors {E X} f e he := by
let l := fun i => Projective.factorThru (inclusion H i ≫ f) e
refine ⟨descend H E l, ?_⟩
apply Rep.hom_ext
apply Representation.IntertwiningMap.ext
apply MonoidAlgebra.lhom_ext'
intro x
apply LinearMap.ext
intro r
change e (descend H E l (MonoidAlgebra.single x r)) = f (MonoidAlgebra.single x r)
rw [descend_single]
have hh := congrArg (fun z => z (MonoidAlgebra.single x.2 r))
(Projective.factorThru_comp (inclusion H x.1 ≫ f) e)
change e (l x.1 (MonoidAlgebra.single x.2 r)) =
f (inclusion H x.1 (MonoidAlgebra.single x.2 r)) at hh
exact hh.trans (congrArg (fun z => f z) (inclusion_single H x.1 x.2 r))
theorem projective_of_odd_order [∀ i, Finite (H i)] (hH : ∀ i, Odd (Nat.card (H i))) :
Projective (permutation (k := ZMod 2) H) := by
let _ : ∀ i, Projective (CosetModules.permutation (k := ZMod 2) (H i)) :=
fun i => CosetModules.projective_permutation_of_odd_order (H i) (hH i)
exact projective H
end CoboundaryExpanders.CosetSums
namespace CoboundaryExpanders.TypedCosetFaces
section
open CategoryTheory
variable {G I : Type} [Group G] [DecidableEq I] (H : I → Subgroup G)
def chainsIso (n : ℕ) :
CosetSums.permutation (k := ZMod 2) (fun A : Types (I := I) n => stabilizer H A.val) ≅
(complex H).chainsRep (G := G) n :=
FinsuppPermutation.coeffIso _ _ _ ≪≫ Rep.mkIso {
(Finsupp.domLCongr (gradedEquiv H n) : _ ≃ₗ[ZMod 2] _) with
isIntertwining' := by
intro g
apply Finsupp.lhom_ext'
intro x
apply LinearMap.ext
intro r
change (Finsupp.domLCongr (gradedEquiv H n) : _ ≃ₗ[ZMod 2] _)
(FinsuppPermutation.ρ (ZMod 2) G _ g (Finsupp.single x r)) =
FinsuppPermutation.ρ (ZMod 2) G _ g
((Finsupp.domLCongr (gradedEquiv H n) : _ ≃ₗ[ZMod 2] _) (Finsupp.single x r))
simp only [FinsuppPermutation.ρ_single, Finsupp.domLCongr_single]
exact congrArg (fun s => Finsupp.single s r) (gradedFace_smul H n g x) }
end
open InfiniteChains
open CategoryTheory
variable {G I : Type} [Group G] [DecidableEq I] (H : I → Subgroup G)
lemma face_orbit_base (n : ℕ) (s : (complex H).Face n) :
∃ g : G, g • baseFace H n (typeFace H n s) = s := by
obtain ⟨g,A,hA⟩ := s.property.1
refine ⟨g, Subtype.ext ?_⟩
change (face H 1 (types H s.val)).map (MulAction.toPerm g).toEmbedding = s.val
rw [map_face, mul_one, ← hA, types_face]
lemma fromTypes_toTypes (n : ℕ) : (fromTypes H n).comp (toTypes H n) = LinearMap.id := by
apply Representation.Coinvariants.hom_ext
apply Finsupp.lhom_ext'
intro s
apply LinearMap.ext
intro r
change fromTypes H n (typeMap H n (Finsupp.single s r)) =
Representation.Coinvariants.mk (FinsuppPermutation.ρ k G ((complex H).Face n))
(Finsupp.single s r)
rw [typeMap_single, fromTypes_single]
obtain ⟨g,hg⟩ := face_orbit_base H n s
have hh := (Representation.Coinvariants.mk_self_apply
(FinsuppPermutation.ρ k G ((complex H).Face n)) g
(Finsupp.single (baseFace H n (typeFace H n s)) r)).symm
simpa only [FinsuppPermutation.ρ_single, hg] using hh
lemma toTypes_fromTypes (n : ℕ) : (toTypes H n).comp (fromTypes H n) = LinearMap.id := by
apply Finsupp.lhom_ext'
intro A
apply LinearMap.ext
intro r
simp
def typesEquiv (n : ℕ) : CoinvariantChains H n ≃ₗ[k] (Simplex (I := I)).Chains n :=
LinearEquiv.ofLinearMap (toTypes H n) (fromTypes H n)
(toTypes_fromTypes H n) (fromTypes_toTypes H n)
lemma types_erase_vertex (g : G) (A : Finset I) (i : I) :
types H ((face H g A).erase (vertex H g i)) = A.erase i := by
rw [face, ← Finset.image_erase (vertex_injective H g)]
exact types_face H g (A.erase i)
lemma typeMap_boundary (n : ℕ) :
(typeMap H n).comp ((complex H).boundary n) =
(Simplex (I := I)).boundary n ∘ₗ typeMap H (n+1) := by
apply Finsupp.lhom_ext'
intro s
apply LinearMap.ext
intro r
apply (Simplex (I := I)).embed_injective n
simp only [LinearMap.comp_apply, Finsupp.lsingle_apply, CoboundaryExpanders.InfiniteChains.Complex.boundary_single,
map_sum, typeMap_single, CoboundaryExpanders.InfiniteChains.Complex.embed_single]
change (∑ v : ↥s.val, Finsupp.single (types H (s.val.erase v.val)) r) =
∑ i : ↥(types H s.val), Finsupp.single ((types H s.val).erase i.val) r
rw [Finset.sum_coe_sort s.val (fun v => Finsupp.single (types H (s.val.erase v)) r),
Finset.sum_coe_sort (types H s.val) (fun i => Finsupp.single ((types H s.val).erase i) r)]
obtain ⟨g,A,hA⟩ := s.property.1
rw [← hA, types_face]
change (∑ i ∈ A.image (vertex H g),
Finsupp.single (types H ((face H g A).erase i)) r) = _
rw [Finset.sum_image]
· apply Finset.sum_congr rfl
intro i hi
rw [types_erase_vertex]
· exact fun _ _ _ _ he => vertex_injective H g he
def coinvariantBoundary (n : ℕ) : CoinvariantChains H (n+1) →ₗ[k] CoinvariantChains H n :=
Representation.Coinvariants.map _ _ ((complex H).boundaryRep (G := G) n).hom
lemma toTypes_boundary (n : ℕ) :
(toTypes H n).comp (coinvariantBoundary H n) =
(Simplex (I := I)).boundary n ∘ₗ toTypes H (n+1) := by
apply Representation.Coinvariants.hom_ext
exact typeMap_boundary H n
abbrev coinvariantComplex : ChainComplex (ModuleCat k) ℕ :=
((Rep.coinvariantsFunctor k G).mapHomologicalComplex _).obj ((complex H).repComplex (G := G))
def coinvariantSimplexIso : coinvariantComplex H ≅ (Simplex (I := I)).chainComplex :=
HomologicalComplex.Hom.isoOfComponents
(fun j => (typesEquiv H (j+1)).toModuleIso) (by
intro i j hij
have he : i=j+1 := by simpa using hij.symm
subst i
apply ModuleCat.hom_ext
change ((Simplex (I := I)).chainComplex.d (j+1) j).hom.comp (toTypes H (j+2)) = _
rw [CoboundaryExpanders.InfiniteChains.Complex.chainComplex_d]
change (Simplex (I := I)).boundary (j+1) ∘ₗ toTypes H (j+2) =
(toTypes H (j+1)).comp
(Representation.Coinvariants.map _ _ (((complex H).repComplex (G := G)).d (j+1) j).hom)
rw [CoboundaryExpanders.InfiniteChains.Complex.repComplex_d]
exact (toTypes_boundary H (j+1)).symm)
end CoboundaryExpanders.TypedCosetFaces
end
end OAI
end
section
-- module Solutions.OAIQ3_Cob.Congruence_Resolution
attribute [-instance] _root_.OAI.CoboundaryExpanders.CongruenceFrames.invariant _root_.OAI.CoboundaryExpanders.InfiniteChains.FiniteWeights.faceFintype _root_.OAI.CoboundaryExpanders.MatrixOpposition.cutVertexFintype _root_.OAI.CoboundaryExpanders.TypedCosetFaces.vertexFintype
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
/-!
Partial resolutions, orbit projectivity, and homology of finite congruence coset complexes.
-/
noncomputable section
open CategoryTheory
open scoped BigOperators
open CategoryTheory Finsupp
open CategoryTheory Finsupp MonoidalCategory
open scoped BigOperators Matrix
open scoped Matrix
open scoped MonoidAlgebra
open CategoryTheory CategoryTheory.Limits
namespace CoboundaryExpanders.TypedCosetFaces
section
open InfiniteChains CategoryTheory
attribute [local instance 1100] InfiniteChains.Complex.faceMulAction
variable {G Q I : Type} [Group G] [Group Q] [DecidableEq I]
variable (H : I → Subgroup G) (f : G →* Q)
variable (hf : Function.Surjective f)
variable (hinter : ∀ A : Finset I, (stabilizer H A).map f = stabilizer (imageGroups H f) A)
lemma toQuotient_boundary (n : ℕ) :
(toQuotient H f n).comp (kernelCoinvariantBoundary H f n) =
(complex (imageGroups H f)).boundary n ∘ₗ toQuotient H f (n+1) := by
apply Representation.Coinvariants.hom_ext
exact quotientChainMap_boundary H f n
def kernelCoinvariantQuotientIso :
kernelCoinvariantComplex H f ≅ (complex (imageGroups H f)).chainComplex :=
HomologicalComplex.Hom.isoOfComponents
(fun j => (quotientChainsEquiv H f hf hinter (j+1)).toModuleIso) (by
intro i j hij
have he : i=j+1 := by simpa using hij.symm
subst i
apply ModuleCat.hom_ext
change ((complex (imageGroups H f)).chainComplex.d (j+1) j).hom.comp
(toQuotient H f (j+2)) = _
rw [CoboundaryExpanders.InfiniteChains.Complex.chainComplex_d]
change (complex (imageGroups H f)).boundary (j+1) ∘ₗ toQuotient H f (j+2) =
(toQuotient H f (j+1)).comp
(Representation.Coinvariants.map _ _ (((complex H).repComplex (G := f.ker)).d (j+1) j).hom)
rw [CoboundaryExpanders.InfiniteChains.Complex.repComplex_d]
exact (toQuotient_boundary H f (j+1)).symm)
end
open InfiniteChains CategoryTheory
attribute [local instance 1100] InfiniteChains.Complex.faceMulAction
variable {G Q I : Type} [Group G] [Group Q] [DecidableEq I]
variable (H : I → Subgroup G) (f : G →* Q)
theorem kernel_face_stabilizer (hlocal : ∀ i, Set.InjOn f (H i))
(n : ℕ) (s : (complex H).Face (n+1)) :
MulAction.stabilizer f.ker s = ⊥ := by
obtain ⟨⟨A,q⟩,rfl⟩ := (gradedFace_bijective H (n+1)).2 s
induction q using Quotient.inductionOn with | h g =>
obtain ⟨i,hi⟩ : A.val.Nonempty := Finset.card_pos.mp (by rw [A.property]; omega)
have hi' : Set.InjOn f (stabilizer H A.val) := by
intro a ha b hb hab
exact hlocal i ((mem_stabilizer H A.val a).mp ha i hi)
((mem_stabilizer H A.val b).mp hb i hi) hab
apply le_antisymm _ bot_le
intro x hx
have hfix : x • gradedFace H (n+1) ⟨A,QuotientGroup.mk g⟩ =
gradedFace H (n+1) ⟨A,QuotientGroup.mk g⟩ := hx
rw [kernel_smul_graded] at hfix
have he := (gradedFace_bijective H (n+1)).1 hfix
have hekk : x • (QuotientGroup.mk g : G ⧸ stabilizer H A.val) = QuotientGroup.mk g :=
eq_of_heq (Sigma.mk.inj_iff.mp he).2
have hx' : x ∈ MulAction.stabilizer f.ker (QuotientGroup.mk g : G ⧸ stabilizer H A.val) := hekk
rw [KernelCosetOrbits.stabilizer_eq_bot f (stabilizer H A.val) hi'] at hx'
exact hx'
end CoboundaryExpanders.TypedCosetFaces
namespace CoboundaryExpanders.PermutationProjectivity
open CategoryTheory
variable {k G X : Type} [Field k] [Group G] [MulAction G X]
def orbitBasis : CosetSums.Basis (orbitStabilizer (G := G) (X := X)) ≃ X :=
(MulAction.selfEquivSigmaOrbitsQuotientStabilizer G X).symm
lemma orbitBasis_apply (x : CosetSums.Basis (orbitStabilizer (G := G) (X := X))) :
orbitBasis x = MulAction.ofQuotientStabilizer G x.1.out x.2 := rfl
lemma orbitBasis_smul (g : G) (x : CosetSums.Basis (orbitStabilizer (G := G) (X := X))) :
orbitBasis (g • x) = g • orbitBasis x := by
rw [orbitBasis_apply, orbitBasis_apply]
exact MulAction.ofQuotientStabilizer_smul G x.1.out g x.2
def chainsIso :
CosetSums.permutation (k := k) (orbitStabilizer (G := G) (X := X)) ≅
FinsuppPermutation.rep k G X :=
FinsuppPermutation.coeffIso _ _ _ ≪≫ Rep.mkIso {
(Finsupp.domLCongr orbitBasis : _ ≃ₗ[k] _) with
isIntertwining' := by
intro g
apply Finsupp.lhom_ext'
intro x
apply LinearMap.ext
intro r
change (Finsupp.domLCongr orbitBasis : _ ≃ₗ[k] _)
(FinsuppPermutation.ρ k G _ g (Finsupp.single x r)) =
FinsuppPermutation.ρ k G _ g
((Finsupp.domLCongr orbitBasis : _ ≃ₗ[k] _) (Finsupp.single x r))
simp only [FinsuppPermutation.ρ_single, Finsupp.domLCongr_single]
exact congrArg (fun s => Finsupp.single s r) (orbitBasis_smul g x) }
theorem projective_of_odd [∀ x : X, Finite (MulAction.stabilizer G x)]
(hodd : ∀ x : X, Odd (Nat.card (MulAction.stabilizer G x))) :
Projective (FinsuppPermutation.rep (ZMod 2) G X) := by
let _ : ∀ q : Orbit (G := G) (X := X), Finite (orbitStabilizer q) :=
fun q => (inferInstance : Finite (MulAction.stabilizer G q.out))
have hP := CosetSums.projective_of_odd_order
(orbitStabilizer (G := G) (X := X)) (fun q => hodd q.out)
exact Projective.of_iso (chainsIso (k := ZMod 2) (G := G) (X := X)) hP
theorem projective_of_free (hfree : ∀ x : X, MulAction.stabilizer G x = ⊥) :
Projective (FinsuppPermutation.rep (ZMod 2) G X) := by
let _ : ∀ x : X, Finite (MulAction.stabilizer G x) := fun x => by
rw [hfree x]
infer_instance
apply projective_of_odd
intro x
rw [hfree x]
simp
end CoboundaryExpanders.PermutationProjectivity
namespace CoboundaryExpanders.TypedCosetFaces
open InfiniteChains CategoryTheory
attribute [local instance 1100] InfiniteChains.Complex.faceMulAction
variable {G Q I : Type} [Group G] [Group Q] [DecidableEq I] [Nonempty I]
variable (H : I → Subgroup G) (f : G →* Q)
omit [Nonempty I] in
lemma kernel_projective_chains (hlocal : ∀ i, Set.InjOn f (H i)) (n : ℕ) :
Projective (((complex H).repComplex (G := f.ker)).X n) :=
PermutationProjectivity.projective_of_free (kernel_face_stabilizer H f hlocal n)
def kernelHomologyQuotientIso (hf : Function.Surjective f)
(hinter : ∀ A : Finset I, (stabilizer H A).map f = stabilizer (imageGroups H f) A)
(hlocal : ∀ i, Set.InjOn f (H i)) (h : ℕ)
(hexact : ∀ n, n < h → (complex H).chainComplex.ExactAt (n+1))
(hzero : Function.Exact ((complex H).boundary 1) ((complex H).sumCoefficients 1))
(j : ℕ) (hj : j ≤ h) :
groupHomology (Rep.trivial k f.ker k) j ≅ (complex (imageGroups H f)).chainComplex.homology j := by
classical
let a : I := Classical.choice inferInstance
let _ : Nonempty ((complex H).Face 1) :=
⟨⟨face H 1 {a}, ⟨1,{a},rfl⟩, by simp⟩⟩
let ε : ((complex H).repComplex (G := f.ker)).X 0 ⟶ Rep.trivial k f.ker k :=
(complex H).augmentationRep
let _ : Epi ε := (complex H).augmentationRep_epi
have hε : ((complex H).repComplex (G := f.ker)).d 1 0 ≫ ε = 0 := by
change (complex H).boundaryRep 1 ≫ (complex H).augmentationRep = 0
exact (complex H).augmentationRep_boundary
have hz : (ShortComplex.mk (((complex H).repComplex (G := f.ker)).d 1 0)
ε hε).Exact := by
change (ShortComplex.mk ((complex H).boundaryRep 1)
(complex H).augmentationRep _).Exact
exact (complex H).augmentationRep_exact hzero
exact CoinvariantHomology.homologyIso k f.ker ((complex H).repComplex (G := f.ker)) h
ε hε
(fun n _ => kernel_projective_chains H f hlocal n)
(fun n hn => (complex H).repComplex_exactAt n (hexact n hn)) hz j hj ≪≫
(HomologicalComplex.homologyFunctor _ _ j).mapIso (kernelCoinvariantQuotientIso H f hf hinter)
end CoboundaryExpanders.TypedCosetFaces
namespace CoboundaryExpanders.Construction
open CategoryTheory TypedCosetFaces
variable (p n : ℕ) [Fact p.Prime]
def matrixKernelHomologyIso (hn : 2 ≤ n) (m : ℕ) (hm : 2 ≤ m)
(hL : OppositionAcyclic p n (by omega)) (j : ℕ) (hj : j < n-1) :
groupHomology (Rep.trivial (ZMod 2) (quotientProjection p n m).ker (ZMod 2)) j ≅
(quotientTypedComplex p n (by omega) m).chainComplex.homology j := by
classical
apply TypedCosetFaces.kernelHomologyQuotientIso (uLocalGroup p n (by omega))
(quotientProjection p n m) (QuotientGroup.mk'_surjective _)
(quotientProjection_intersections p n (by omega) hm)
(fun i a ha b hb he => quotientProjection_cross_injective p n (by omega) hm i i a b ha hb he)
(n-2)
· intro r hr
exact hL.2 (r+1) (by omega) (by omega)
· exact hL.1
· omega
end CoboundaryExpanders.Construction
end
end OAI
end
section
-- module Solutions.OAIQ3_Cob.Coboundary_Realization
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
/-!
Finite labeled coset complexes, purity, growth, incidence bounds, and weighted expansion reduction.
-/
noncomputable section
open CategoryTheory
open scoped BigOperators
open CategoryTheory Finsupp
open CategoryTheory Finsupp MonoidalCategory
open scoped BigOperators Matrix
open scoped Matrix
open scoped MonoidAlgebra
open CategoryTheory CategoryTheory.Limits
open Filter
namespace CoboundaryExpanders.CosetConstruction
section
open CoboundaryExpanders.Complex
variable {G : Type*} [Group G] [Fintype G] {n : ℕ}
abbrev Walk (H : Fin (n + 1) → Subgroup G)
(v w : Fin (Fintype.card (Vertex H))) : Prop :=
Relation.ReflTransGen (fun a b => a ≠ b ∧ {a, b} ∈ (complex H).faces) v w
end
end CoboundaryExpanders.CosetConstruction
namespace CoboundaryExpanders.InfiniteChains.Complex
variable {V : Type} [DecidableEq V] [Finite V] (X : InfiniteChains.Complex V)
instance finiteFaceFintype (n : ℕ) : Fintype (X.Face n) := Fintype.ofFinite _
lemma boundary_single_subfaces (n : ℕ) (s : X.Face (n+1)) (r : k) :
X.boundary n (Finsupp.single s r) =
∑ t : X.Face n, if t.val ⊆ s.val then Finsupp.single t r else 0 := by
classical
rw [boundary_single, ← Finset.sum_filter]
apply Finset.sum_bij (fun (v : ↥s.val) _ => X.erase n s v)
· intro v _
simp only [Finset.mem_filter, Finset.mem_univ, true_and]
exact Finset.erase_subset _ _
· intro a _ b _ he
apply Subtype.ext
exact (Finset.erase_inj s.val a.property).mp (congrArg Subtype.val he)
· intro t ht
have hsub : t.val ⊆ s.val := (Finset.mem_filter.mp ht).2
have hcard : (s.val \ t.val).card = 1 := by
rw [Finset.card_sdiff_of_subset hsub, s.property.2,t.property.2]
omega
obtain ⟨v,hv,he⟩ := (Finset.covBy_iff_card_sdiff_eq_one.mpr ⟨hsub,hcard⟩).exists_finset_erase
exact ⟨⟨v,hv⟩,Finset.mem_univ _,Subtype.ext he⟩
· intro _ _
rfl
end CoboundaryExpanders.InfiniteChains.Complex
namespace CoboundaryExpanders.CosetConstruction
open CategoryTheory
variable {G : Type} [Group G] [Fintype G] {n : ℕ}
variable (H : Fin (n+1) → Subgroup G)
lemma typedFaceEquiv_subset (i j : ℕ)
(s : (TypedCosetFaces.complex H).Face (i+1))
(t : (TypedCosetFaces.complex H).Face (j+1)) :
(typedFaceEquiv H i s).val ⊆ (typedFaceEquiv H j t).val ↔ s.val ⊆ t.val := by
change s.val.image (labelEquiv H) ⊆ t.val.image (labelEquiv H) ↔ _
exact Finset.image_subset_image_iff (labelEquiv H).injective
local instance instFintypeFace_rce28bb_1 (X : CoboundaryExpanders.Complex) (i : ℕ) : Fintype (X.Face i) := X.instFintypeFace i
lemma typedChainEquiv_boundary (i : ℕ) :
(typedChainEquiv H i).toLinearMap.comp ((TypedCosetFaces.complex H).boundary (i+1)) =
((complex H).boundaryLinear i).comp (typedChainEquiv H (i+1)).toLinearMap := by
classical
apply Finsupp.lhom_ext'
intro s
apply LinearMap.ext
intro r
simp only [LinearMap.comp_apply, Finsupp.lsingle_apply,
InfiniteChains.Complex.boundary_single_subfaces, map_sum,
LinearEquiv.coe_coe, typedChainEquiv_single, map_smul,
Complex.boundary_on_face, Finset.smul_sum]
apply @Fintype.sum_equiv _ _ _ _ ((complex H).instFintypeFace_2 i) _ (typedFaceEquiv H i)
intro t
by_cases ht : t.val ⊆ s.val
· have hlt := (typedFaceEquiv_subset H i (i+1) t s).mpr ht
simp only [ite_eq_left ht,ite_eq_left hlt,typedChainEquiv_single]
· have hlt := mt (typedFaceEquiv_subset H i (i+1) t s).mp ht
simp only [ite_eq_right ht,ite_eq_right hlt,map_zero,smul_zero]
def typedChainIso : (TypedCosetFaces.complex H).chainComplex ≅ (complex H).chainComplex :=
HomologicalComplex.Hom.isoOfComponents
(fun i => (typedChainEquiv H i).toModuleIso)
(by
intro i j hij
have hij' : j+1 = i := by simpa using hij
subst i
rw [InfiniteChains.Complex.chainComplex_d, CoboundaryExpanders.Complex.chainComplex_d]
apply ModuleCat.hom_ext
exact (typedChainEquiv_boundary H j).symm)
end CoboundaryExpanders.CosetConstruction
end
end OAI
end
section
-- module Solutions.OAIQ3_Cob.Congruence_ProStability
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
/-!
Positive exactness, coefficient change, Bockstein groups, integral pro-stability support, and F2 reductions.
-/
noncomputable section
open CategoryTheory
open scoped BigOperators
open CategoryTheory Finsupp
open CategoryTheory Finsupp MonoidalCategory
open scoped BigOperators Matrix
open scoped Matrix
open scoped MonoidAlgebra
open CategoryTheory CategoryTheory.Limits
open Filter
namespace CoboundaryExpanders.TypedCosetFaces
open InfiniteChains
variable {G I : Type} [Group G] [DecidableEq I] (H : I → Subgroup G)
def singletonFace (g : G) (i : I) : (complex H).Face 1 :=
⟨{vertex H g i}, ⟨g,{i},by simp [face]⟩, Finset.card_singleton _⟩
def pairFace (g : G) (i j : I) (hij : i ≠ j) : (complex H).Face 2 :=
⟨{vertex H g i,vertex H g j}, ⟨g,{i,j},by simp [face]⟩, by
have hv : vertex H g i ≠ vertex H g j := fun h => hij (vertex_injective H g h)
simp [hv]⟩
abbrev Components := (complex H).Chains 1 ⧸ LinearMap.range ((complex H).boundary 1)
def component (g : G) (i : I) : Components H :=
(LinearMap.range ((complex H).boundary 1)).mkQ (Finsupp.single (singletonFace H g i) 1)
end CoboundaryExpanders.TypedCosetFaces
namespace CoboundaryExpanders.ProCoefficientChange
attribute [instance] Tower.ab Tower.mod
end CoboundaryExpanders.ProCoefficientChange
namespace CoboundaryExpanders.GroupProStability
open ProCoefficientChange
attribute [local instance 2000] Rep.hV2
attribute [local instance 3000] ModuleCat.isModule
attribute [instance] Groups.grp
end CoboundaryExpanders.GroupProStability
end
end OAI
end
section
-- module Solutions.OAIQ3_Cob.Coboundary_LatticeCones
attribute [-instance] _root_.OAI.CoboundaryExpanders.CongruenceFrames.invariant
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
/-!
Bounded-chamber and codistance attachments, lattice acyclicity, and uniform positive coset exactness.
-/
noncomputable section
open scoped Polynomial BigOperators
namespace CoboundaryExpanders.RationalLattices.BoundedChamber
open scoped Polynomial BigOperators
open AffineLattices PolynomialVectors
variable {K : Type} [Field K] {M : ℕ}
variable (C : ResidueChamber (K := K) (N := M+2)) (hC : PolyBounded C.top)
def RootInterval (D : Submodule K[X] (PolynomialVectors.V K (M+2))) : Prop :=
powerShift C.top 1 ≤ D ∧ D ≤ C.top ∧ D ≠ powerShift C.top 1
noncomputable def normalizeModule (D : Submodule K[X] (PolynomialVectors.V K (M+2))) : Vertex K (M+2) := by
classical
exact if hD : PolyBounded D then normalizedPolynomial (by omega) D hD
else normalizedPolynomial (by omega) C.top hC
noncomputable def liftModule (v : Vertex K (M+2)) : Submodule K[X] (PolynomialVectors.V K (M+2)) := by
classical
exact if h : ∃ D, RootInterval C D ∧ normalizeModule C hC D = v then h.choose else C.top
end CoboundaryExpanders.RationalLattices.BoundedChamber
namespace CoboundaryExpanders.Construction
open CoboundaryExpanders.RationalLattices CoboundaryExpanders.AffineLattices
variable (p n : ℕ) [Fact p.Prime]
noncomputable def oppositionVertex (hn : 1 ≤ n) :
TypedCosetFaces.Vertex (uLocalGroup p n hn) → RationalLattices.Vertex (ZMod p) (n+1) :=
fun x => Quotient.lift (fun g : U p (n+1) =>
actVertex (ZMod p) (n+1) (by omega) g.val (cutVertex (ZMod p) (n+1) x.1))
(fun g h he => (act_cut_eq_iff p n hn g h x.1 x.1).mpr
⟨rfl,QuotientGroup.leftRel_apply.mp he⟩) x.2
@[simp] lemma oppositionVertex_mk (hn : 1 ≤ n) (g : U p (n+1)) (c : Fin (n+1)) :
oppositionVertex p n hn (TypedCosetFaces.vertex (uLocalGroup p n hn) g c) =
actVertex (ZMod p) (n+1) (by omega) g.val (cutVertex (ZMod p) (n+1) c) := rfl
def opposition : InfiniteChains.Complex (RationalLattices.Vertex (ZMod p) (n+1)) where
faces := {s | ∃ g : U p (n+1), ∃ A : Finset (Fin (n+1)),
A.image (fun c => actVertex (ZMod p) (n+1) (by omega) g.val (cutVertex (ZMod p) (n+1) c)) = s}
empty_mem := ⟨1,∅,Finset.image_empty _⟩
downward := by
rintro s t ⟨g,A,rfl⟩ ht
obtain ⟨B,hB,he⟩ := Finset.subset_image_iff.mp ht
exact ⟨g,B,he⟩
end CoboundaryExpanders.Construction
end
end OAI
end
section
-- module Solutions.OAIQ3_Cob.Congruence_OddHomology
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
noncomputable section
/-!
Permutation orbit parameters, locally finite odd groups, quotient coinvariants, and bar augmentations.
-/
namespace CoboundaryExpanders.FinsuppPermutation
open CategoryTheory
variable {k G X Y : Type} [CommRing k] [Group G] [MulAction G X]
namespace OrbitParam
variable (P : OrbitParam G X Y)
def H0Equiv : groupHomology (rep k G X) 0 ≃ₗ[k] (Y →₀ k) :=
(groupHomology.H0Iso (rep k G X)).toLinearEquiv.trans P.coinEquiv
end OrbitParam
end CoboundaryExpanders.FinsuppPermutation
section
open scoped BigOperators
open CategoryTheory CategoryTheory.Limits
open CategoryTheory CategoryTheory.Limits Representation
open CategoryTheory CategoryTheory.Limits Representation MonoidalCategory
open CategoryTheory CategoryTheory.Limits Representation Finsupp
open scoped BigOperators
open CategoryTheory CategoryTheory.Limits
open CategoryTheory CategoryTheory.Limits Representation
open CategoryTheory CategoryTheory.Limits Representation MonoidalCategory
open CategoryTheory CategoryTheory.Limits Representation Finsupp
open CategoryTheory CategoryTheory.Limits Representation Finsupp Rep TensorProduct
namespace CoboundaryExpanders.QuotientCoinvariants
open QuotientBarAugmentation
variable {G : Type} [Group G] [DecidableEq G] (N : Subgroup G) [N.Normal]
variable [DecidableEq (G ⧸ N)]
variable (H : ∀ s : Finset N, ∃ S : Subgroup N, Finite S ∧ Odd (Nat.card S) ∧ ∀ g ∈ s, g ∈ S)
theorem quotientBar_augmentation :
quotientBar N ≫ (Rep.barResolution (ZMod 2) (G ⧸ N)).π = (quotientResolution N H).π := by
apply HomologicalComplex.hom_ext
intro n
cases n with
| zero =>
apply (homEquiv N _ _).injective
apply Rep.free_ext
intro x
change ((Rep.barResolution (ZMod 2) (G ⧸ N)).π.f 0).hom
((quotientBarF N 0).hom (single x (.single 1 1))) =
((Rep.barResolution (ZMod 2) G).π.f 0).hom (single x (.single 1 1))
rw [quotientBarF_single,bar_augmentation_single,bar_augmentation_single]
| succ n =>
apply Limits.IsZero.eq_of_tgt
exact HomologicalComplex.isZero_single_obj_X (V := Rep (ZMod 2) (G ⧸ N))
(ComplexShape.down ℕ) 0 (Rep.trivial (ZMod 2) (G ⧸ N) (ZMod 2)) (n + 1) (by omega)
noncomputable def quotientBarHomotopy : Homotopy (quotientBar N)
((quotientResolution N H).homotopyEquiv (Rep.barResolution (ZMod 2) (G ⧸ N))).hom :=
ProjectiveResolution.liftHomotopy
(P := quotientResolution N H) (Q := Rep.barResolution (ZMod 2) (G ⧸ N))
(𝟙 _) (quotientBar N)
((quotientResolution N H).homotopyEquiv (Rep.barResolution (ZMod 2) (G ⧸ N))).hom
(by rw [CategoryTheory.Functor.map_id,Category.comp_id]; exact quotientBar_augmentation N H)
(by rw [CategoryTheory.Functor.map_id,Category.comp_id]; exact ProjectiveResolution.homotopyEquiv_hom_π _ _)
noncomputable def quotientBarEquiv : HomotopyEquiv
((L N).mapHomologicalComplex _ |>.obj (Rep.barComplex (ZMod 2) G))
(Rep.barComplex (ZMod 2) (G ⧸ N)) where
hom := quotientBar N
inv := ((quotientResolution N H).homotopyEquiv (Rep.barResolution (ZMod 2) (G ⧸ N))).inv
homotopyHomInvId := ((quotientBarHomotopy N H).compRight _).trans
((quotientResolution N H).homotopyEquiv (Rep.barResolution (ZMod 2) (G ⧸ N))).homotopyHomInvId
homotopyInvHomId := ((quotientBarHomotopy N H).compLeft _).trans
((quotientResolution N H).homotopyEquiv (Rep.barResolution (ZMod 2) (G ⧸ N))).homotopyInvHomId
end CoboundaryExpanders.QuotientCoinvariants
end
section
open scoped BigOperators
open CategoryTheory CategoryTheory.Limits
open CategoryTheory CategoryTheory.Limits Representation
open CategoryTheory CategoryTheory.Limits Representation MonoidalCategory
open CategoryTheory CategoryTheory.Limits Representation Finsupp
open CategoryTheory CategoryTheory.Limits Representation Finsupp Rep TensorProduct
open CategoryTheory Finsupp MonoidalCategory
namespace CoboundaryExpanders.QuotientCoinvariants
open Representation
variable {G : Type} [Group G] [DecidableEq G] (N : Subgroup G) [N.Normal] [DecidableEq (G ⧸ N)]
variable (H : ∀ s : Finset N, ∃ S : Subgroup N, Finite S ∧ Odd (Nat.card S) ∧ ∀ g ∈ s, g ∈ S)
noncomputable def coinvariantQuotientEquiv : HomotopyEquiv
(QuotientCoinvariantModel.complex (k := ZMod 2) (G := G))
(QuotientCoinvariantModel.complex (k := ZMod 2) (G := G ⧸ N)) :=
(HomotopyEquiv.ofIso
(((NatIso.mapHomologicalComplex (totalCoinvariantsIso N) _).app (Rep.barComplex (ZMod 2) G)).symm)).trans
((Rep.coinvariantsFunctor (ZMod 2) (G ⧸ N)).mapHomotopyEquiv (quotientBarEquiv N H))
end CoboundaryExpanders.QuotientCoinvariants
end
open scoped BigOperators
open CategoryTheory CategoryTheory.Limits
open CategoryTheory CategoryTheory.Limits Representation
open CategoryTheory CategoryTheory.Limits Representation MonoidalCategory
open CategoryTheory CategoryTheory.Limits Representation Finsupp
open CategoryTheory CategoryTheory.Limits Representation Finsupp Rep TensorProduct
open CategoryTheory Finsupp MonoidalCategory
open CategoryTheory
end
end OAI
end
section
-- module Solutions.OAIQ3_Cob.Congruence_Parabolic
attribute [-instance] _root_.OAI.CoboundaryExpanders.CongruenceFrames.invariant
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
noncomputable section
/-!
Actual parabolic stabilizers, F2 homological stability maps, and matrix duality.
-/
section
open CategoryTheory
open scoped Matrix
namespace CoboundaryExpanders.MatrixDual
variable {A B : Type*} [CommRing A] [CommRing B]
variable {ι κ : Type*} [Fintype ι] [DecidableEq ι] [Fintype κ] [DecidableEq κ]
open Construction
variable (p a m : ℕ)
lemma dual_mem_gamma (x : Gamma p a m) : dual x.val ∈ Gamma p a m := by
change Matrix.SpecialLinearGroup.map (Ideal.Quotient.mk (powerIdeal p m)) (dual x.val) = 1
rw [map_dual, x.property, map_one]
def gammaDual : MulAut (Gamma p a m) where
toFun x := ⟨dual x.val, dual_mem_gamma p a m x⟩
invFun x := ⟨dual x.val, dual_mem_gamma p a m x⟩
left_inv x := Subtype.ext (dual_dual x.val)
right_inv x := Subtype.ext (dual_dual x.val)
map_mul' _ _ := Subtype.ext (map_mul dual _ _)
end CoboundaryExpanders.MatrixDual
namespace CoboundaryExpanders.MatrixDual
open Construction F2Stability
variable (p a m : ℕ)
local instance gammaNormal : (Gamma p a m).Normal := by unfold Gamma; infer_instance
end CoboundaryExpanders.MatrixDual
end
open CategoryTheory
end
end OAI
end
section
-- module Solutions.OAIQ3_Cob.Congruence_CongruenceFrames
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
noncomputable section
/-!
Row-parabolic groups, row-frame actions, finite images, and congruence stabilizers.
-/
section
open scoped BigOperators Matrix
attribute [local instance] Classical.decEq
namespace CoboundaryExpanders.RowParabolic
variable (A : Type*) [CommRing A] (a b : ℕ)
def sectionHom : Matrix.SpecialLinearGroup (Fin a) A →* fixed A a b where
toFun g := ofBlocks A a b g 0
map_one' := by apply Subtype.ext; apply Subtype.ext; exact Matrix.fromBlocks_one
map_mul' g h := by
apply Subtype.ext; apply Subtype.ext
change Matrix.fromBlocks (g.val*h.val) 0 0 (1 : Matrix (Fin b) (Fin b) A) =
Matrix.fromBlocks g.val 0 0 1 * Matrix.fromBlocks h.val 0 0 1
simp [Matrix.fromBlocks_multiply]
end CoboundaryExpanders.RowParabolic
end
namespace CoboundaryExpanders.MultiParabolic
open scoped Matrix BigOperators
open Construction RowParabolic CategoryTheory
variable (p a b m : ℕ)
def toFixed : group p a b m →* fixed (R p) a b :=
Subgroup.inclusion inf_le_left
def project : group p a b m →* Gamma p a m :=
((RowParabolic.project (R p) a b).comp (toFixed p a b m)).codRestrict _ (by
intro A
have h := A.property.2
apply Matrix.SpecialLinearGroup.ext
intro i j
have he := congrArg (fun B : Matrix.SpecialLinearGroup (Idx a b) (R p ⧸ powerIdeal p m) =>
B (Sum.inl i) (Sum.inl j)) h
change Ideal.Quotient.mk (powerIdeal p m) (A.val.val (Sum.inl i) (Sum.inl j)) =
(1 : Matrix (Fin a) (Fin a) (R p ⧸ powerIdeal p m)) i j
simpa [Matrix.one_apply] using he)
def sectionValue (A : Gamma p a m) : group p a b m :=
⟨(RowParabolic.sectionHom (R p) a b A.val).val, by
constructor
· exact (RowParabolic.sectionHom (R p) a b A.val).property
· apply Matrix.SpecialLinearGroup.ext
intro i j
have h := A.property
change Matrix.SpecialLinearGroup.map (Ideal.Quotient.mk (powerIdeal p m)) A.val = 1 at h
have hh (i j : Fin a) := congrArg (fun B : Matrix.SpecialLinearGroup (Fin a)
(R p ⧸ powerIdeal p m) => B i j) h
change Ideal.Quotient.mk (powerIdeal p m)
(Matrix.fromBlocks A.val.val (0 : Matrix (Fin a) (Fin b) (R p)) 0 1 i j) =
(1 : Matrix (Idx a b) (Idx a b) (R p ⧸ powerIdeal p m)) i j
cases i with
| inl i => cases j with
| inl j => simpa [Matrix.one_apply, Matrix.SpecialLinearGroup.map_apply_coe] using hh i j
| inr j => simp
| inr i => cases j with
| inl j => simp
| inr j => simp [Matrix.one_apply]⟩
lemma kernel_form (A : (project p a b m).ker) : A.val.val.val =
Matrix.fromBlocks (1 : Matrix (Fin a) (Fin a) (R p))
(Matrix.toBlocks₁₂ A.val.val.val) 0 1 := by
have he := congrArg (fun x : Gamma p a m => x.val.val) A.property
change Matrix.toBlocks₁₁ A.val.val.val = 1 at he
have hh := RowParabolic.block_form (R p) a b (toFixed p a b m A.val)
change A.val.val.val = Matrix.fromBlocks (Matrix.toBlocks₁₁ A.val.val.val)
(Matrix.toBlocks₁₂ A.val.val.val) 0 1 at hh
rw [he] at hh
exact hh
def kernelBlock : (project p a b m).ker →* Multiplicative (Matrix (Fin a) (Fin b) (R p)) where
toFun A := Multiplicative.ofAdd (Matrix.toBlocks₁₂ A.val.val.val)
map_one' := by
change Matrix.toBlocks₁₂ (1 : Matrix (Idx a b) (Idx a b) (R p)) = 0
funext i j
change (1 : Matrix (Idx a b) (Idx a b) (R p)) (Sum.inl i) (Sum.inr j) = 0
simp
map_mul' A B := by
change Matrix.toBlocks₁₂ (A.val.val.val * B.val.val.val) =
Matrix.toBlocks₁₂ A.val.val.val + Matrix.toBlocks₁₂ B.val.val.val
rw [kernel_form p a b m A, kernel_form p a b m B, Matrix.fromBlocks_multiply]
simp [add_comm]
end CoboundaryExpanders.MultiParabolic
open scoped BigOperators Matrix CoboundaryExpanders.RowFrames
attribute [local instance] Classical.decEq
end
end OAI
end
section
-- module Solutions.OAIQ3_Cob.Congruence_FrameHomology
attribute [-instance] _root_.OAI.CoboundaryExpanders.InfiniteChains.Complex.finiteFaceFintype _root_.OAI.CoboundaryExpanders.InfiniteChains.FiniteWeights.faceFintype
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
noncomputable section
/-!
Shapiro comparison, frame resolution homology, augmentation ranges, and triviality of conjugation.
-/
section
open CategoryTheory CategoryTheory.Limits Rep Representation Finsupp
namespace CoboundaryExpanders.CosetModules
variable {k G : Type} [Field k] [Group G] [DecidableEq G] (S : Subgroup G)
omit [DecidableEq G] in
lemma hom_ext_base {A : Rep k G} {f g : permutation (k := k) S ⟶ A}
(h : base S ≫ (resFunctor S.subtype).map f = base S ≫ (resFunctor S.subtype).map g) : f = g := by
apply Rep.hom_ext
apply Representation.IntertwiningMap.ext
apply MonoidAlgebra.lhom_ext'
intro q
apply LinearMap.ext
intro r
induction q using Quotient.inductionOn with | h a =>
have hh := congrArg (fun f => f.hom r) h
have hf := Rep.hom_comm_apply f a (MonoidAlgebra.single (QuotientGroup.mk (1 : G)) r)
have hg := Rep.hom_comm_apply g a (MonoidAlgebra.single (QuotientGroup.mk (1 : G)) r)
rw [Representation.ofMulAction_single] at hf hg
change f.hom (MonoidAlgebra.single (QuotientGroup.mk (a*1)) r) = _ at hf
change g.hom (MonoidAlgebra.single (QuotientGroup.mk (a*1)) r) = _ at hg
simp only [mul_one] at hf hg
change f.hom (MonoidAlgebra.single (QuotientGroup.mk a) r) =
g.hom (MonoidAlgebra.single (QuotientGroup.mk a) r)
rw [hf, hg]
exact congrArg (A.ρ a) hh
def indToCoset : Rep.ind S.subtype (Rep.trivial k S k) ⟶ permutation (k := k) S :=
(Rep.indResHomEquiv S.subtype _ _).symm (base S)
omit [DecidableEq G] in
lemma indBase_comp_toCoset :
ActualShapiro.indBase S (Rep.trivial k S k) ≫ (resFunctor S.subtype).map (indToCoset S) = base S :=
(Rep.indResHomEquiv S.subtype _ _).apply_symm_apply (base S)
omit [DecidableEq G] in
lemma indBase_fixed (h : S) :
(Rep.ind S.subtype (Rep.trivial k S k)).ρ h
((ActualShapiro.indBase S (Rep.trivial k S k)).hom (1 : k)) =
(ActualShapiro.indBase S (Rep.trivial k S k)).hom (1 : k) := by
have hh := Rep.hom_comm_apply (ActualShapiro.indBase S (Rep.trivial k S k)) h (1 : k)
exact hh.symm
def cosetToInd : permutation (k := k) S ⟶ Rep.ind S.subtype (Rep.trivial k S k) :=
extend S _ ((ActualShapiro.indBase S (Rep.trivial k S k)).hom 1) (indBase_fixed S)
omit [DecidableEq G] in
lemma base_comp_toInd : base S ≫ (resFunctor S.subtype).map (cosetToInd (k := k) S) =
ActualShapiro.indBase S (Rep.trivial k S k) := by
apply Rep.hom_ext
apply Representation.IntertwiningMap.ext
apply LinearMap.ext
intro r
change extend S _ _ _ (MonoidAlgebra.single (QuotientGroup.mk (1 : G)) r) = _
rw [extend_single]
simp only [map_one, Module.End.one_apply]
change r • ((ActualShapiro.indBase S (Rep.trivial k S k)).hom 1) =
(ActualShapiro.indBase S (Rep.trivial k S k)).hom r
rw [← map_smul]
simp
def indCosetIso : Rep.ind S.subtype (Rep.trivial k S k) ≅ permutation (k := k) S where
hom := indToCoset S
inv := cosetToInd S
hom_inv_id := by
apply (Rep.indResHomEquiv S.subtype _ _).injective
change ActualShapiro.indBase S (Rep.trivial k S k) ≫
(resFunctor S.subtype).map (indToCoset S ≫ cosetToInd S) = _
rw [CategoryTheory.Functor.map_comp, ← Category.assoc, indBase_comp_toCoset, base_comp_toInd]
rfl
inv_hom_id := by
apply hom_ext_base S
rw [CategoryTheory.Functor.map_comp, ← Category.assoc, base_comp_toInd, indBase_comp_toCoset,
CategoryTheory.Functor.map_id, Category.comp_id]
end CoboundaryExpanders.CosetModules
open CategoryTheory CategoryTheory.Limits Rep Representation Finsupp
open scoped BigOperators
attribute [local instance] Classical.decEq
namespace CoboundaryExpanders.CosetSums
variable {k G I : Type} [Field k] [Group G] (H : I → Subgroup G)
def projection (i : I) : permutation (k := k) H ⟶ CosetModules.permutation (k := k) (H i) :=
Rep.ofHom ⟨(MonoidAlgebra.coeffLinearEquiv k).symm.toLinearMap.comp
((Finsupp.lcomapDomain (fun q : G ⧸ H i => (⟨i,q⟩ : Basis H)) (by intro a b h; exact eq_of_heq (Sigma.mk.inj h).2)).comp
(MonoidAlgebra.coeffLinearEquiv k).toLinearMap), by
intro g
apply LinearMap.ext
intro f
apply MonoidAlgebra.ext
apply Finsupp.ext
intro q
change ((Representation.ofMulAction k G (Basis H)) g f).coeff ⟨i,q⟩ =
((Representation.ofMulAction k G (G ⧸ H i)) g _).coeff q
rw [Representation.coeff_ofMulAction, Representation.coeff_ofMulAction]
rfl⟩
@[simp] lemma projection_coeff (i : I) (f : permutation (k := k) H) (q : G ⧸ H i) :
(projection H i f).coeff q = f.coeff ⟨i,q⟩ := rfl
open groupHomology
end CoboundaryExpanders.CosetSums
end
section
open CategoryTheory CategoryTheory.Limits
namespace CoboundaryExpanders.MultiParabolic
open Construction F2Stability RowFrames
variable (p a b m : ℕ)
def sectionHom : Gamma p a m →* group p a b m where
toFun := sectionValue p a b m
map_one' := by
apply Subtype.ext
change (RowParabolic.sectionHom (R p) a b 1).val = 1
exact congrArg Subtype.val (map_one (RowParabolic.sectionHom (R p) a b))
map_mul' A B := by
apply Subtype.ext
change (RowParabolic.sectionHom (R p) a b (A.val*B.val)).val =
(RowParabolic.sectionHom (R p) a b A.val).val * (RowParabolic.sectionHom (R p) a b B.val).val
exact congrArg Subtype.val (map_mul (RowParabolic.sectionHom (R p) a b) A.val B.val)
def inclusion : group p a b m →* Gamma p (a+b) m where
toFun A := ⟨Blocks.reindexSL finSumFinEquiv A.val, by
change Matrix.SpecialLinearGroup.map (Ideal.Quotient.mk (powerIdeal p m)) _ = 1
rw [Blocks.reindexSL_map,A.property.2,map_one]⟩
map_one' := by apply Subtype.ext; exact map_one _
map_mul' A B := by apply Subtype.ext; exact map_mul _ _ _
end CoboundaryExpanders.MultiParabolic
open CategoryTheory CategoryTheory.Limits
open scoped BigOperators Matrix CoboundaryExpanders.RowFrames
attribute [local instance] Classical.decEq
namespace CoboundaryExpanders.InfiniteChains.Complex
variable {V G : Type} [DecidableEq V] [Group G] [MulAction G V]
(X : CoboundaryExpanders.InfiniteChains.Complex V) [Fact (X.Invariant (G := G))]
def augmentedData : HomologyEdge.AugmentedData (k := k) (G := G) where
D | 0 => Rep.trivial k G k
| s+1 => X.chainsRep (G := G) (s+1)
d | 0 => X.augmentationRep
| s+1 => X.boundaryRep (s+1)
square s := by
cases s with
| zero => exact X.augmentationRep_boundary
| succ s => exact X.boundaryRep_squared (s+1)
end CoboundaryExpanders.InfiniteChains.Complex
end
open CategoryTheory CategoryTheory.Limits
open scoped BigOperators Matrix CoboundaryExpanders.RowFrames
attribute [local instance] Classical.decEq
end
end OAI
end