Skip to content

Commit 1da931e

Browse files
committed
feat(RingTheory/StandardSmooth): pre-requisites for calculating the naive cotangent complex of a submersive presentation (#19749)
Preparations for #19748 Co-authored-by: Christian Merten <136261474+chrisflav@users.noreply.github.com>
1 parent 5177008 commit 1da931e

File tree

10 files changed

+204
-3
lines changed

10 files changed

+204
-3
lines changed

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3366,6 +3366,7 @@ import Mathlib.LinearAlgebra.Basis.Basic
33663366
import Mathlib.LinearAlgebra.Basis.Bilinear
33673367
import Mathlib.LinearAlgebra.Basis.Cardinality
33683368
import Mathlib.LinearAlgebra.Basis.Defs
3369+
import Mathlib.LinearAlgebra.Basis.Exact
33693370
import Mathlib.LinearAlgebra.Basis.Flag
33703371
import Mathlib.LinearAlgebra.Basis.VectorSpace
33713372
import Mathlib.LinearAlgebra.BilinearForm.Basic

Mathlib/Algebra/BigOperators/Group/Finset.lean

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,12 @@ theorem prod_disj_sum (s : Finset α) (t : Finset γ) (f : α ⊕ γ → β) :
543543
rw [← map_inl_disjUnion_map_inr, prod_disjUnion, prod_map, prod_map]
544544
rfl
545545

546+
@[to_additive]
547+
lemma prod_sum_eq_prod_toLeft_mul_prod_toRight (s : Finset (α ⊕ γ)) (f : α ⊕ γ → β) :
548+
∏ x ∈ s, f x = (∏ x ∈ s.toLeft, f (Sum.inl x)) * ∏ x ∈ s.toRight, f (Sum.inr x) := by
549+
rw [← Finset.toLeft_disjSum_toRight (u := s), Finset.prod_disj_sum, Finset.toLeft_disjSum,
550+
Finset.toRight_disjSum]
551+
546552
@[to_additive]
547553
theorem prod_sum_elim (s : Finset α) (t : Finset γ) (f : α → β) (g : γ → β) :
548554
∏ x ∈ s.disjSum t, Sum.elim f g x = (∏ x ∈ s, f x) * ∏ x ∈ t, g x := by simp

Mathlib/Data/Matrix/Mul.lean

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -890,6 +890,24 @@ theorem vecMul_mulVec [Fintype m] [Fintype n] (A : Matrix m n α) (B : Matrix m
890890

891891
end NonUnitalCommSemiring
892892

893+
section Semiring
894+
895+
variable [Semiring R]
896+
897+
lemma mulVec_injective_of_isUnit [Fintype m] [DecidableEq m] {A : Matrix m m R}
898+
(ha : IsUnit A) : Function.Injective A.mulVec := by
899+
obtain ⟨B, hBl, hBr⟩ := isUnit_iff_exists.mp ha
900+
intro x y hxy
901+
simpa [hBr] using congrArg B.mulVec hxy
902+
903+
lemma vecMul_injective_of_isUnit [Fintype m] [DecidableEq m] {A : Matrix m m R}
904+
(ha : IsUnit A) : Function.Injective A.vecMul := by
905+
obtain ⟨B, hBl, hBr⟩ := isUnit_iff_exists.mp ha
906+
intro x y hxy
907+
simpa [hBl] using congrArg B.vecMul hxy
908+
909+
end Semiring
910+
893911
section CommSemiring
894912

895913
variable [CommSemiring α]
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/-
2+
Copyright (c) 2024 Christian Merten. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Christian Merten
5+
-/
6+
import Mathlib.Algebra.Exact
7+
import Mathlib.Algebra.Module.Submodule.Pointwise
8+
import Mathlib.LinearAlgebra.Basis.Basic
9+
10+
/-!
11+
# Basis from a split exact sequence
12+
13+
Let `0 → K → M → P → 0` be a split exact sequence of `R`-modules, let `s : M → K` be a
14+
retraction of `f` and `v` be a basis of `M` indexed by `κ ⊕ σ`. Then
15+
if `s vᵢ = 0` for `i : κ` and `(s vⱼ)ⱼ` is linear independent for `j : σ`, then
16+
the images of `vᵢ` for `i : κ` form a basis of `P`.
17+
18+
We treat linear independence and the span condition separately. For convenience this
19+
is stated not for `κ ⊕ σ`, but for an arbitrary type `ι` with two maps `κ → ι` and `σ → ι`.
20+
-/
21+
22+
variable {R M K P : Type*} [Ring R] [AddCommGroup M] [AddCommGroup K] [AddCommGroup P]
23+
variable [Module R M] [Module R K] [Module R P]
24+
variable {f : K →ₗ[R] M} {g : M →ₗ[R] P} {s : M →ₗ[R] K}
25+
variable (hs : s ∘ₗ f = LinearMap.id) (hfg : Function.Exact f g)
26+
variable {ι κ σ : Type*} {v : ι → M} {a : κ → ι} {b : σ → ι}
27+
include hs hfg
28+
29+
lemma LinearIndependent.linearIndependent_of_exact_of_retraction
30+
(hainj : Function.Injective a) (hsa : ∀ i, s (v (a i)) = 0)
31+
(hli : LinearIndependent R v) :
32+
LinearIndependent R (g ∘ v ∘ a) := by
33+
apply (LinearIndependent.comp hli a hainj).map
34+
rw [Submodule.disjoint_def, hfg.linearMap_ker_eq]
35+
rintro - hy ⟨y, rfl⟩
36+
have hz : s (f y) = 0 := by
37+
revert hy
38+
generalize f y = x
39+
intro hy
40+
induction' hy using Submodule.span_induction with m hm
41+
· obtain ⟨i, rfl⟩ := hm
42+
apply hsa
43+
all_goals simp_all
44+
replace hs := DFunLike.congr_fun hs y
45+
simp only [LinearMap.coe_comp, Function.comp_apply, LinearMap.id_coe, id_eq] at hs
46+
rw [← hs, hz, map_zero]
47+
48+
private lemma top_le_span_of_aux (v : κ ⊕ σ → M)
49+
(hg : Function.Surjective g) (hslzero : ∀ i, s (v (.inl i)) = 0)
50+
(hli : LinearIndependent R (s ∘ v ∘ .inr)) (hsp : ⊤ ≤ Submodule.span R (Set.range v)) :
51+
⊤ ≤ Submodule.span R (Set.range <| g ∘ v ∘ .inl) := by
52+
rintro p -
53+
obtain ⟨m, rfl⟩ := hg p
54+
wlog h : m ∈ LinearMap.ker s
55+
· let x : M := f (s m)
56+
rw [show g m = g (m - f (s m)) by simp [hfg.apply_apply_eq_zero]]
57+
apply this hs hfg v hg hslzero hli hsp
58+
replace hs := DFunLike.congr_fun hs (s m)
59+
simp only [LinearMap.coe_comp, Function.comp_apply, LinearMap.id_coe, id_eq] at hs
60+
simp [hs]
61+
have : m ∈ Submodule.span R (Set.range v) := hsp trivial
62+
obtain ⟨c, rfl⟩ := Finsupp.mem_span_range_iff_exists_finsupp.mp this
63+
simp only [LinearMap.mem_ker, Finsupp.sum, map_sum, map_smul,
64+
Finset.sum_sum_eq_sum_toLeft_add_sum_toRight, map_add, hslzero, smul_zero,
65+
Finset.sum_const_zero, zero_add] at h
66+
replace hli := (linearIndependent_iff'.mp hli) c.support.toRight (c ∘ .inr) h
67+
simp only [Finset.mem_toRight, Finsupp.mem_support_iff, Function.comp_apply, not_imp_self] at hli
68+
simp only [Finsupp.sum, Finset.sum_sum_eq_sum_toLeft_add_sum_toRight, hli, zero_smul,
69+
Finset.sum_const_zero, add_zero, map_sum, map_smul]
70+
exact Submodule.sum_mem _ (fun i hi ↦ Submodule.smul_mem _ _ <| Submodule.subset_span ⟨i, rfl⟩)
71+
72+
lemma Submodule.top_le_span_of_exact_of_retraction (hg : Function.Surjective g)
73+
(hsa : ∀ i, s (v (a i)) = 0) (hlib : LinearIndependent R (s ∘ v ∘ b))
74+
(hab : Codisjoint (Set.range a) (Set.range b))
75+
(hsp : ⊤ ≤ Submodule.span R (Set.range v)) :
76+
⊤ ≤ Submodule.span R (Set.range <| g ∘ v ∘ a) := by
77+
apply top_le_span_of_aux hs hfg (Sum.elim (v ∘ a) (v ∘ b)) hg hsa hlib
78+
simp only [codisjoint_iff, Set.sup_eq_union, Set.top_eq_univ] at hab
79+
rwa [Set.Sum.elim_range, Set.range_comp, Set.range_comp, ← Set.image_union, hab, Set.image_univ]
80+
81+
/-- Let `0 → K → M → P → 0` be a split exact sequence of `R`-modules, let `s : M → K` be a
82+
retraction of `f` and `v` be a basis of `M` indexed by `κ ⊕ σ`. Then
83+
if `s vᵢ = 0` for `i : κ` and `(s vⱼ)ⱼ` is linear independent for `j : σ`, then
84+
the images of `vᵢ` for `i : κ` form a basis of `P`.
85+
86+
For convenience this is stated for an arbitrary type `ι` with two maps `κ → ι` and `σ → ι`. -/
87+
noncomputable def Basis.ofSplitExact (hg : Function.Surjective g) (v : Basis ι R M)
88+
(hainj : Function.Injective a) (hsa : ∀ i, s (v (a i)) = 0)
89+
(hlib : LinearIndependent R (s ∘ v ∘ b))
90+
(hab : Codisjoint (Set.range a) (Set.range b)) :
91+
Basis κ R P :=
92+
Basis.mk (v.linearIndependent.linearIndependent_of_exact_of_retraction hs hfg hainj hsa)
93+
(Submodule.top_le_span_of_exact_of_retraction hs hfg hg hsa hlib hab (by rw [v.span_eq]))

Mathlib/LinearAlgebra/Dimension/Free.lean

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,11 @@ variable {M M'}
165165

166166
namespace Module
167167

168+
/-- A free module of rank zero is trivial. -/
169+
lemma subsingleton_of_rank_zero (h : Module.rank R M = 0) : Subsingleton M := by
170+
rw [← Basis.mk_eq_rank'' (Module.Free.chooseBasis R M), Cardinal.mk_eq_zero_iff] at h
171+
exact (Module.Free.repr R M).subsingleton
172+
168173
/-- See `rank_lt_aleph0` for the inverse direction without `Module.Free R M`. -/
169174
lemma rank_lt_aleph0_iff : Module.rank R M < ℵ₀ ↔ Module.Finite R M := by
170175
rw [Free.rank_eq_card_chooseBasisIndex, mk_lt_aleph0_iff]

Mathlib/LinearAlgebra/Finsupp/Defs.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ sending `l : β →₀ M` to the finitely supported function from `α` to `M` gi
158158
`l` with `f`.
159159
160160
This is the linear version of `Finsupp.comapDomain`. -/
161+
@[simps]
161162
def lcomapDomain (f : α → β) (hf : Function.Injective f) : (β →₀ M) →ₗ[R] α →₀ M where
162163
toFun l := Finsupp.comapDomain f l hf.injOn
163164
map_add' x y := by ext; simp

Mathlib/LinearAlgebra/Matrix/ToLin.lean

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,11 @@ theorem Matrix.vecMul_injective_iff {R : Type*} [CommRing R] {M : Matrix m n R}
115115
ext j
116116
simp [vecMul, dotProduct]
117117

118+
lemma Matrix.linearIndependent_rows_of_isUnit {R : Type*} [CommRing R] {A : Matrix m m R}
119+
[DecidableEq m] (ha : IsUnit A) : LinearIndependent R (fun i ↦ A i) := by
120+
rw [← Matrix.vecMul_injective_iff]
121+
exact Matrix.vecMul_injective_of_isUnit ha
122+
118123
section
119124
variable [DecidableEq m]
120125

@@ -276,6 +281,12 @@ theorem Matrix.mulVec_injective_iff {R : Type*} [CommRing R] {M : Matrix m n R}
276281
change Function.Injective (fun x ↦ _) ↔ _
277282
simp_rw [← M.vecMul_transpose, vecMul_injective_iff]
278283

284+
lemma Matrix.linearIndependent_cols_of_isUnit {R : Type*} [CommRing R] [Fintype m]
285+
{A : Matrix m m R} [DecidableEq m] (ha : IsUnit A) :
286+
LinearIndependent R (fun i ↦ A.transpose i) := by
287+
rw [← Matrix.mulVec_injective_iff]
288+
exact Matrix.mulVec_injective_of_isUnit ha
289+
279290
end mulVec
280291

281292
section ToMatrix'

Mathlib/RingTheory/Extension.lean

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,10 @@ lemma Cotangent.val_mk (x : P.ker) : (mk x).val = Ideal.toCotangent _ x := rfl
360360
lemma Cotangent.mk_surjective : Function.Surjective (mk (P := P)) :=
361361
fun x ↦ Ideal.toCotangent_surjective P.ker x.val
362362

363+
lemma Cotangent.mk_eq_zero_iff {P : Extension R S} (x : P.ker) :
364+
Cotangent.mk x = 0 ↔ x.val ∈ P.ker ^ 2 := by
365+
simp [Cotangent.ext_iff, Ideal.toCotangent_eq_zero]
366+
363367
variable {P'}
364368
variable [Algebra R R'] [Algebra R' R''] [Algebra R' S'']
365369
variable [Algebra S S'] [Algebra S' S''] [Algebra S S'']

Mathlib/RingTheory/Presentation.lean

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ lemma aeval_val_relation (i) : aeval P.val (P.relation i) = 0 := by
7373
rw [← RingHom.mem_ker, ← P.ker_eq_ker_aeval_val, ← P.span_range_relation_eq_ker]
7474
exact Ideal.subset_span ⟨i, rfl⟩
7575

76+
lemma relation_mem_ker (i : P.rels) : P.relation i ∈ P.ker := by
77+
rw [← P.span_range_relation_eq_ker]
78+
apply Ideal.subset_span
79+
use i
80+
7681
/-- The polynomial algebra wrt a family of generators modulo a family of relations. -/
7782
protected abbrev Quotient : Type (max w u) := P.Ring ⧸ P.ker
7883

Mathlib/RingTheory/Smooth/StandardSmooth.lean

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,17 @@ noncomputable def differential : (P.rels → P.Ring) →ₗ[P.Ring] (P.rels →
135135
Basis.constr P.basis P.Ring
136136
(fun j i : P.rels ↦ MvPolynomial.pderiv (P.map i) (P.relation j))
137137

138+
/-- `PreSubmersivePresentation.differential` pushed forward to `S` via `aeval P.val`. -/
139+
noncomputable def aevalDifferential : (P.rels → S) →ₗ[S] (P.rels → S) :=
140+
(Pi.basisFun S P.rels).constr S
141+
(fun j i : P.rels ↦ aeval P.val <| pderiv (P.map i) (P.relation j))
142+
143+
@[simp]
144+
lemma aevalDifferential_single [DecidableEq P.rels] (i j : P.rels) :
145+
P.aevalDifferential (Pi.single i 1) j = aeval P.val (pderiv (P.map j) (P.relation i)) := by
146+
dsimp only [aevalDifferential]
147+
rw [← Pi.basisFun_apply, Basis.constr_basis]
148+
138149
/-- The jacobian of a `P : PreSubmersivePresentation` is the determinant
139150
of `P.differential` viewed as element of `S`. -/
140151
noncomputable def jacobian : S :=
@@ -158,6 +169,13 @@ lemma jacobiMatrix_apply (i j : P.rels) :
158169
P.jacobiMatrix i j = MvPolynomial.pderiv (P.map i) (P.relation j) := by
159170
simp [jacobiMatrix, LinearMap.toMatrix, differential, basis]
160171

172+
lemma aevalDifferential_toMatrix'_eq_mapMatrix_jacobiMatrix :
173+
P.aevalDifferential.toMatrix' = (aeval P.val).mapMatrix P.jacobiMatrix := by
174+
ext i j : 1
175+
rw [← LinearMap.toMatrix_eq_toMatrix']
176+
rw [LinearMap.toMatrix_apply]
177+
simp [jacobiMatrix_apply]
178+
161179
end Matrix
162180

163181
section Constructions
@@ -262,11 +280,12 @@ the lower-right block has determinant jacobian of `P`.
262280
263281
-/
264282

265-
variable [Fintype (Q.comp P).rels]
283+
variable [DecidableEq (Q.comp P).rels] [Fintype (Q.comp P).rels]
266284

267285
open scoped Classical in
268286
private lemma jacobiMatrix_comp_inl_inr (i : Q.rels) (j : P.rels) :
269287
(Q.comp P).jacobiMatrix (Sum.inl i) (Sum.inr j) = 0 := by
288+
classical
270289
rw [jacobiMatrix_apply]
271290
refine MvPolynomial.pderiv_eq_zero_of_not_mem_vars (fun hmem ↦ ?_)
272291
apply MvPolynomial.vars_rename at hmem
@@ -279,7 +298,7 @@ private lemma jacobiMatrix_comp_₁₂ : (Q.comp P).jacobiMatrix.toBlocks₁₂
279298

280299
section Q
281300

282-
variable [Fintype Q.rels]
301+
variable [DecidableEq Q.rels] [Fintype Q.rels]
283302

284303
open scoped Classical in
285304
private lemma jacobiMatrix_comp_inl_inl (i j : Q.rels) :
@@ -303,7 +322,7 @@ end Q
303322

304323
section P
305324

306-
variable [Fintype P.rels]
325+
variable [Fintype P.rels] [DecidableEq P.rels]
307326

308327
open scoped Classical in
309328
private lemma jacobiMatrix_comp_inr_inr (i j : P.rels) :
@@ -471,6 +490,44 @@ end BaseChange
471490

472491
end Constructions
473492

493+
variable {R S}
494+
495+
open Classical in
496+
/-- If `P` is submersive, `PreSubmersivePresentation.aevalDifferential` is an isomorphism. -/
497+
noncomputable def aevalDifferentialEquiv (P : SubmersivePresentation R S) :
498+
(P.rels → S) ≃ₗ[S] (P.rels → S) :=
499+
haveI : Fintype P.rels := Fintype.ofFinite P.rels
500+
have : IsUnit (LinearMap.toMatrix (Pi.basisFun S P.rels) (Pi.basisFun S P.rels)
501+
P.aevalDifferential).det := by
502+
convert P.jacobian_isUnit
503+
rw [LinearMap.toMatrix_eq_toMatrix', jacobian_eq_jacobiMatrix_det,
504+
aevalDifferential_toMatrix'_eq_mapMatrix_jacobiMatrix, P.algebraMap_eq]
505+
simp [RingHom.map_det]
506+
LinearEquiv.ofIsUnitDet this
507+
508+
variable (P : SubmersivePresentation R S)
509+
510+
@[simp]
511+
lemma aevalDifferentialEquiv_apply (x : P.rels → S) :
512+
P.aevalDifferentialEquiv x = P.aevalDifferential x :=
513+
rfl
514+
515+
/-- If `P` is a submersive presentation, the partial derivatives of `P.relation i` by
516+
`P.map j` form a basis of `P.rels → S`. -/
517+
noncomputable def basisDeriv (P : SubmersivePresentation R S) : Basis P.rels S (P.rels → S) :=
518+
Basis.map (Pi.basisFun S P.rels) P.aevalDifferentialEquiv
519+
520+
@[simp]
521+
lemma basisDeriv_apply (i j : P.rels) :
522+
P.basisDeriv i j = (aeval P.val) (pderiv (P.map j) (P.relation i)) := by
523+
classical
524+
simp [basisDeriv]
525+
526+
lemma linearIndependent_aeval_val_pderiv_relation :
527+
LinearIndependent S (fun i j ↦ (aeval P.val) (pderiv (P.map j) (P.relation i))) := by
528+
simp_rw [← SubmersivePresentation.basisDeriv_apply]
529+
exact P.basisDeriv.linearIndependent
530+
474531
end SubmersivePresentation
475532

476533
/--

0 commit comments

Comments
 (0)