Skip to content

Commit b90d47b

Browse files
committed
feat: port LinearAlgebra.ExteriorAlgebra.Basic (#5375)
1 parent 8c343e5 commit b90d47b

File tree

2 files changed

+353
-0
lines changed

2 files changed

+353
-0
lines changed

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2004,6 +2004,7 @@ import Mathlib.LinearAlgebra.Dual
20042004
import Mathlib.LinearAlgebra.Eigenspace.Basic
20052005
import Mathlib.LinearAlgebra.Eigenspace.IsAlgClosed
20062006
import Mathlib.LinearAlgebra.Eigenspace.Minpoly
2007+
import Mathlib.LinearAlgebra.ExteriorAlgebra.Basic
20072008
import Mathlib.LinearAlgebra.FiniteDimensional
20082009
import Mathlib.LinearAlgebra.Finrank
20092010
import Mathlib.LinearAlgebra.Finsupp
Lines changed: 352 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,352 @@
1+
/-
2+
Copyright (c) 2020 Adam Topaz. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Zhangir Azerbayev, Adam Topaz, Eric Wieser
5+
6+
! This file was ported from Lean 3 source module linear_algebra.exterior_algebra.basic
7+
! leanprover-community/mathlib commit b8d2eaa69d69ce8f03179a5cda774fc0cde984e4
8+
! Please do not edit these lines, except to modify the commit id
9+
! if you have ported upstream changes.
10+
-/
11+
import Mathlib.LinearAlgebra.CliffordAlgebra.Basic
12+
import Mathlib.LinearAlgebra.Alternating
13+
14+
/-!
15+
# Exterior Algebras
16+
17+
We construct the exterior algebra of a module `M` over a commutative semiring `R`.
18+
19+
## Notation
20+
21+
The exterior algebra of the `R`-module `M` is denoted as `ExteriorAlgebra R M`.
22+
It is endowed with the structure of an `R`-algebra.
23+
24+
Given a linear morphism `f : M → A` from a module `M` to another `R`-algebra `A`, such that
25+
`cond : ∀ m : M, f m * f m = 0`, there is a (unique) lift of `f` to an `R`-algebra morphism,
26+
which is denoted `ExteriorAlgebra.lift R f cond`.
27+
28+
The canonical linear map `M → ExteriorAlgebra R M` is denoted `ExteriorAlgebra.ι R`.
29+
30+
## Theorems
31+
32+
The main theorems proved ensure that `ExteriorAlgebra R M` satisfies the universal property
33+
of the exterior algebra.
34+
1. `ι_comp_lift` is the fact that the composition of `ι R` with `lift R f cond` agrees with `f`.
35+
2. `lift_unique` ensures the uniqueness of `lift R f cond` with respect to 1.
36+
37+
## Definitions
38+
39+
* `ιMulti` is the `AlternatingMap` corresponding to the wedge product of `ι R m` terms.
40+
41+
## Implementation details
42+
43+
The exterior algebra of `M` is constructed as simply `CliffordAlgebra (0 : QuadraticForm R M)`,
44+
as this avoids us having to duplicate API.
45+
-/
46+
47+
48+
universe u1 u2 u3
49+
50+
variable (R : Type u1) [CommRing R]
51+
52+
variable (M : Type u2) [AddCommGroup M] [Module R M]
53+
54+
/-- The exterior algebra of an `R`-module `M`.
55+
-/
56+
@[reducible]
57+
def ExteriorAlgebra :=
58+
CliffordAlgebra (0 : QuadraticForm R M)
59+
#align exterior_algebra ExteriorAlgebra
60+
61+
namespace ExteriorAlgebra
62+
63+
variable {M}
64+
65+
/-- The canonical linear map `M →ₗ[R] ExteriorAlgebra R M`.
66+
-/
67+
@[reducible]
68+
def ι : M →ₗ[R] ExteriorAlgebra R M :=
69+
CliffordAlgebra.ι _
70+
#align exterior_algebra.ι ExteriorAlgebra.ι
71+
72+
variable {R}
73+
74+
/-- As well as being linear, `ι m` squares to zero. -/
75+
-- @[simp] -- Porting note: simp can prove this
76+
theorem ι_sq_zero (m : M) : ι R m * ι R m = 0 :=
77+
(CliffordAlgebra.ι_sq_scalar _ m).trans <| map_zero _
78+
#align exterior_algebra.ι_sq_zero ExteriorAlgebra.ι_sq_zero
79+
80+
variable {A : Type _} [Semiring A] [Algebra R A]
81+
82+
-- @[simp] -- Porting note: simp can prove this
83+
theorem comp_ι_sq_zero (g : ExteriorAlgebra R M →ₐ[R] A) (m : M) : g (ι R m) * g (ι R m) = 0 := by
84+
rw [← AlgHom.map_mul, ι_sq_zero, AlgHom.map_zero]
85+
#align exterior_algebra.comp_ι_sq_zero ExteriorAlgebra.comp_ι_sq_zero
86+
87+
variable (R)
88+
89+
/-- Given a linear map `f : M →ₗ[R] A` into an `R`-algebra `A`, which satisfies the condition:
90+
`cond : ∀ m : M, f m * f m = 0`, this is the canonical lift of `f` to a morphism of `R`-algebras
91+
from `ExteriorAlgebra R M` to `A`.
92+
-/
93+
@[simps! symm_apply]
94+
def lift : { f : M →ₗ[R] A // ∀ m, f m * f m = 0 } ≃ (ExteriorAlgebra R M →ₐ[R] A) :=
95+
Equiv.trans (Equiv.subtypeEquiv (Equiv.refl _) <| by simp) <| CliffordAlgebra.lift _
96+
#align exterior_algebra.lift ExteriorAlgebra.lift
97+
98+
@[simp]
99+
theorem ι_comp_lift (f : M →ₗ[R] A) (cond : ∀ m, f m * f m = 0) :
100+
(lift R ⟨f, cond⟩).toLinearMap.comp (ι R) = f :=
101+
CliffordAlgebra.ι_comp_lift f _
102+
#align exterior_algebra.ι_comp_lift ExteriorAlgebra.ι_comp_lift
103+
104+
@[simp]
105+
theorem lift_ι_apply (f : M →ₗ[R] A) (cond : ∀ m, f m * f m = 0) (x) :
106+
lift R ⟨f, cond⟩ (ι R x) = f x :=
107+
CliffordAlgebra.lift_ι_apply f _ x
108+
#align exterior_algebra.lift_ι_apply ExteriorAlgebra.lift_ι_apply
109+
110+
@[simp]
111+
theorem lift_unique (f : M →ₗ[R] A) (cond : ∀ m, f m * f m = 0) (g : ExteriorAlgebra R M →ₐ[R] A) :
112+
g.toLinearMap.comp (ι R) = f ↔ g = lift R ⟨f, cond⟩ :=
113+
CliffordAlgebra.lift_unique f _ _
114+
#align exterior_algebra.lift_unique ExteriorAlgebra.lift_unique
115+
116+
variable {R}
117+
118+
@[simp]
119+
theorem lift_comp_ι (g : ExteriorAlgebra R M →ₐ[R] A) :
120+
lift R ⟨g.toLinearMap.comp (ι R), comp_ι_sq_zero _⟩ = g :=
121+
CliffordAlgebra.lift_comp_ι g
122+
#align exterior_algebra.lift_comp_ι ExteriorAlgebra.lift_comp_ι
123+
124+
/-- See note [partially-applied ext lemmas]. -/
125+
@[ext]
126+
theorem hom_ext {f g : ExteriorAlgebra R M →ₐ[R] A}
127+
(h : f.toLinearMap.comp (ι R) = g.toLinearMap.comp (ι R)) : f = g :=
128+
CliffordAlgebra.hom_ext h
129+
#align exterior_algebra.hom_ext ExteriorAlgebra.hom_ext
130+
131+
/-- If `C` holds for the `algebraMap` of `r : R` into `ExteriorAlgebra R M`, the `ι` of `x : M`,
132+
and is preserved under addition and muliplication, then it holds for all of `ExteriorAlgebra R M`.
133+
-/
134+
@[elab_as_elim]
135+
theorem induction {C : ExteriorAlgebra R M → Prop}
136+
(h_grade0 : ∀ r, C (algebraMap R (ExteriorAlgebra R M) r)) (h_grade1 : ∀ x, C (ι R x))
137+
(h_mul : ∀ a b, C a → C b → C (a * b)) (h_add : ∀ a b, C a → C b → C (a + b))
138+
(a : ExteriorAlgebra R M) : C a :=
139+
CliffordAlgebra.induction h_grade0 h_grade1 h_mul h_add a
140+
#align exterior_algebra.induction ExteriorAlgebra.induction
141+
142+
/-- The left-inverse of `algebraMap`. -/
143+
def algebraMapInv : ExteriorAlgebra R M →ₐ[R] R :=
144+
ExteriorAlgebra.lift R ⟨(0 : M →ₗ[R] R), fun m => by simp⟩
145+
#align exterior_algebra.algebra_map_inv ExteriorAlgebra.algebraMapInv
146+
147+
variable (M)
148+
149+
theorem algebraMap_leftInverse :
150+
Function.LeftInverse algebraMapInv (algebraMap R <| ExteriorAlgebra R M) := fun x => by
151+
simp [algebraMapInv]
152+
#align exterior_algebra.algebra_map_left_inverse ExteriorAlgebra.algebraMap_leftInverse
153+
154+
@[simp]
155+
theorem algebraMap_inj (x y : R) :
156+
algebraMap R (ExteriorAlgebra R M) x = algebraMap R (ExteriorAlgebra R M) y ↔ x = y :=
157+
(algebraMap_leftInverse M).injective.eq_iff
158+
#align exterior_algebra.algebra_map_inj ExteriorAlgebra.algebraMap_inj
159+
160+
@[simp]
161+
theorem algebraMap_eq_zero_iff (x : R) : algebraMap R (ExteriorAlgebra R M) x = 0 ↔ x = 0 :=
162+
map_eq_zero_iff (algebraMap _ _) (algebraMap_leftInverse _).injective
163+
#align exterior_algebra.algebra_map_eq_zero_iff ExteriorAlgebra.algebraMap_eq_zero_iff
164+
165+
@[simp]
166+
theorem algebraMap_eq_one_iff (x : R) : algebraMap R (ExteriorAlgebra R M) x = 1 ↔ x = 1 :=
167+
map_eq_one_iff (algebraMap _ _) (algebraMap_leftInverse _).injective
168+
#align exterior_algebra.algebra_map_eq_one_iff ExteriorAlgebra.algebraMap_eq_one_iff
169+
170+
theorem isUnit_algebraMap (r : R) : IsUnit (algebraMap R (ExteriorAlgebra R M) r) ↔ IsUnit r :=
171+
isUnit_map_of_leftInverse _ (algebraMap_leftInverse M)
172+
#align exterior_algebra.is_unit_algebra_map ExteriorAlgebra.isUnit_algebraMap
173+
174+
/-- Invertibility in the exterior algebra is the same as invertibility of the base ring. -/
175+
@[simps!]
176+
def invertibleAlgebraMapEquiv (r : R) :
177+
Invertible (algebraMap R (ExteriorAlgebra R M) r) ≃ Invertible r :=
178+
invertibleEquivOfLeftInverse _ _ _ (algebraMap_leftInverse M)
179+
#align exterior_algebra.invertible_algebra_map_equiv ExteriorAlgebra.invertibleAlgebraMapEquiv
180+
181+
variable {M}
182+
183+
/-- The canonical map from `ExteriorAlgebra R M` into `TrivSqZeroExt R M` that sends
184+
`ExteriorAlgebra.ι` to `TrivSqZeroExt.inr`. -/
185+
def toTrivSqZeroExt [Module Rᵐᵒᵖ M] [IsCentralScalar R M] :
186+
ExteriorAlgebra R M →ₐ[R] TrivSqZeroExt R M :=
187+
lift R ⟨TrivSqZeroExt.inrHom R M, fun m => TrivSqZeroExt.inr_mul_inr R m m⟩
188+
#align exterior_algebra.to_triv_sq_zero_ext ExteriorAlgebra.toTrivSqZeroExt
189+
190+
@[simp]
191+
theorem toTrivSqZeroExt_ι [Module Rᵐᵒᵖ M] [IsCentralScalar R M] (x : M) :
192+
toTrivSqZeroExt (ι R x) = TrivSqZeroExt.inr x :=
193+
lift_ι_apply _ _ _ _
194+
#align exterior_algebra.to_triv_sq_zero_ext_ι ExteriorAlgebra.toTrivSqZeroExt_ι
195+
196+
/-- The left-inverse of `ι`.
197+
198+
As an implementation detail, we implement this using `TrivSqZeroExt` which has a suitable
199+
algebra structure. -/
200+
def ιInv : ExteriorAlgebra R M →ₗ[R] M := by
201+
letI : Module Rᵐᵒᵖ M := Module.compHom _ ((RingHom.id R).fromOpposite mul_comm)
202+
haveI : IsCentralScalar R M := ⟨fun r m => rfl⟩
203+
exact (TrivSqZeroExt.sndHom R M).comp toTrivSqZeroExt.toLinearMap
204+
#align exterior_algebra.ι_inv ExteriorAlgebra.ιInv
205+
206+
-- Porting note: In the type, changed `ιInv` to `ιInv.1`
207+
theorem ι_leftInverse : Function.LeftInverse ιInv.1 (ι R : M → ExteriorAlgebra R M) := fun x => by
208+
-- Porting note: Original proof didn't have `letI` and `haveI`
209+
letI : Module Rᵐᵒᵖ M := Module.compHom _ ((RingHom.id R).fromOpposite mul_comm)
210+
haveI : IsCentralScalar R M := ⟨fun r m => rfl⟩
211+
simp [ιInv]
212+
#align exterior_algebra.ι_left_inverse ExteriorAlgebra.ι_leftInverse
213+
214+
variable (R)
215+
216+
@[simp]
217+
theorem ι_inj (x y : M) : ι R x = ι R y ↔ x = y :=
218+
ι_leftInverse.injective.eq_iff
219+
#align exterior_algebra.ι_inj ExteriorAlgebra.ι_inj
220+
221+
variable {R}
222+
223+
@[simp]
224+
theorem ι_eq_zero_iff (x : M) : ι R x = 0 ↔ x = 0 := by rw [← ι_inj R x 0, LinearMap.map_zero]
225+
#align exterior_algebra.ι_eq_zero_iff ExteriorAlgebra.ι_eq_zero_iff
226+
227+
@[simp]
228+
theorem ι_eq_algebraMap_iff (x : M) (r : R) : ι R x = algebraMap R _ r ↔ x = 0 ∧ r = 0 := by
229+
refine' ⟨fun h => _, _⟩
230+
· letI : Module Rᵐᵒᵖ M := Module.compHom _ ((RingHom.id R).fromOpposite mul_comm)
231+
haveI : IsCentralScalar R M := ⟨fun r m => rfl⟩
232+
have hf0 : toTrivSqZeroExt (ι R x) = (0, x) := toTrivSqZeroExt_ι _
233+
rw [h, AlgHom.commutes] at hf0
234+
have : r = 00 = x := Prod.ext_iff.1 hf0
235+
exact this.symm.imp_left Eq.symm
236+
· rintro ⟨rfl, rfl⟩
237+
rw [LinearMap.map_zero, RingHom.map_zero]
238+
#align exterior_algebra.ι_eq_algebra_map_iff ExteriorAlgebra.ι_eq_algebraMap_iff
239+
240+
@[simp]
241+
theorem ι_ne_one [Nontrivial R] (x : M) : ι R x ≠ 1 := by
242+
rw [← (algebraMap R (ExteriorAlgebra R M)).map_one, Ne.def, ι_eq_algebraMap_iff]
243+
exact one_ne_zero ∘ And.right
244+
#align exterior_algebra.ι_ne_one ExteriorAlgebra.ι_ne_one
245+
246+
/-- The generators of the exterior algebra are disjoint from its scalars. -/
247+
theorem ι_range_disjoint_one :
248+
Disjoint (LinearMap.range (ι R : M →ₗ[R] ExteriorAlgebra R M))
249+
(1 : Submodule R (ExteriorAlgebra R M)) := by
250+
rw [Submodule.disjoint_def]
251+
rintro _ ⟨x, hx⟩ ⟨r, rfl : algebraMap R (ExteriorAlgebra R M) r = _⟩
252+
rw [ι_eq_algebraMap_iff x] at hx
253+
rw [hx.2, RingHom.map_zero]
254+
#align exterior_algebra.ι_range_disjoint_one ExteriorAlgebra.ι_range_disjoint_one
255+
256+
@[simp]
257+
theorem ι_add_mul_swap (x y : M) : ι R x * ι R y + ι R y * ι R x = 0 :=
258+
calc
259+
_ = ι R (y + x) * ι R (y + x) := by simp [mul_add, add_mul]
260+
_ = _ := ι_sq_zero _
261+
#align exterior_algebra.ι_add_mul_swap ExteriorAlgebra.ι_add_mul_swap
262+
263+
theorem ι_mul_prod_list {n : ℕ} (f : Fin n → M) (i : Fin n) :
264+
(ι R <| f i) * (List.ofFn fun i => ι R <| f i).prod = 0 := by
265+
induction' n with n hn
266+
· exact i.elim0
267+
· rw [List.ofFn_succ, List.prod_cons, ← mul_assoc]
268+
by_cases h : i = 0
269+
· rw [h, ι_sq_zero, MulZeroClass.zero_mul]
270+
· replace hn := congr_arg ((· * ·) <| ι R <| f 0) (hn (fun i => f <| Fin.succ i) (i.pred h))
271+
simp only at hn
272+
rw [Fin.succ_pred, ← mul_assoc, MulZeroClass.mul_zero] at hn
273+
refine' (eq_zero_iff_eq_zero_of_add_eq_zero _).mp hn
274+
rw [← add_mul, ι_add_mul_swap, MulZeroClass.zero_mul]
275+
#align exterior_algebra.ι_mul_prod_list ExteriorAlgebra.ι_mul_prod_list
276+
277+
variable (R)
278+
279+
/-- The product of `n` terms of the form `ι R m` is an alternating map.
280+
281+
This is a special case of `MultilinearMap.mkPiAlgebraFin`, and the exterior algebra version of
282+
`TensorAlgebra.tprod`. -/
283+
def ιMulti (n : ℕ) : AlternatingMap R M (ExteriorAlgebra R M) (Fin n) :=
284+
let F := (MultilinearMap.mkPiAlgebraFin R n (ExteriorAlgebra R M)).compLinearMap fun _ => ι R
285+
{ F with
286+
map_eq_zero_of_eq' := fun f x y hfxy hxy => by
287+
dsimp
288+
clear F
289+
wlog h : x < y
290+
· exact this R (A := A) n f y x hfxy.symm hxy.symm (hxy.lt_or_lt.resolve_left h)
291+
clear hxy
292+
induction' n with n hn
293+
· exact x.elim0
294+
· rw [List.ofFn_succ, List.prod_cons]
295+
by_cases hx : x = 0
296+
-- one of the repeated terms is on the left
297+
· rw [hx] at hfxy h
298+
rw [hfxy, ← Fin.succ_pred y (ne_of_lt h).symm]
299+
exact ι_mul_prod_list (f ∘ Fin.succ) _
300+
-- ignore the left-most term and induct on the remaining ones, decrementing indices
301+
· convert MulZeroClass.mul_zero (ι R (f 0))
302+
refine' hn (fun i => f <| Fin.succ i) (x.pred hx)
303+
(y.pred (ne_of_lt <| lt_of_le_of_lt x.zero_le h).symm) _ (Fin.pred_lt_pred_iff.mpr h)
304+
simp only [Fin.succ_pred]
305+
exact hfxy
306+
toFun := F }
307+
#align exterior_algebra.ι_multi ExteriorAlgebra.ιMulti
308+
309+
variable {R}
310+
311+
theorem ιMulti_apply {n : ℕ} (v : Fin n → M) : ιMulti R n v = (List.ofFn fun i => ι R (v i)).prod :=
312+
rfl
313+
#align exterior_algebra.ι_multi_apply ExteriorAlgebra.ιMulti_apply
314+
315+
@[simp]
316+
theorem ιMulti_zero_apply (v : Fin 0 → M) : ιMulti R 0 v = 1 :=
317+
rfl
318+
#align exterior_algebra.ι_multi_zero_apply ExteriorAlgebra.ιMulti_zero_apply
319+
320+
@[simp]
321+
theorem ιMulti_succ_apply {n : ℕ} (v : Fin n.succ → M) :
322+
ιMulti R _ v = ι R (v 0) * ιMulti R _ (Matrix.vecTail v) :=
323+
(congr_arg List.prod (List.ofFn_succ _)).trans List.prod_cons
324+
#align exterior_algebra.ι_multi_succ_apply ExteriorAlgebra.ιMulti_succ_apply
325+
326+
theorem ιMulti_succ_curryLeft {n : ℕ} (m : M) :
327+
(ιMulti R n.succ).curryLeft m = (LinearMap.mulLeft R (ι R m)).compAlternatingMap (ιMulti R n) :=
328+
AlternatingMap.ext fun v =>
329+
(ιMulti_succ_apply _).trans <| by
330+
simp_rw [Matrix.tail_cons]
331+
rfl
332+
#align exterior_algebra.ι_multi_succ_curry_left ExteriorAlgebra.ιMulti_succ_curryLeft
333+
334+
end ExteriorAlgebra
335+
336+
namespace TensorAlgebra
337+
338+
variable {R M}
339+
340+
/-- The canonical image of the `TensorAlgebra` in the `ExteriorAlgebra`, which maps
341+
`TensorAlgebra.ι R x` to `ExteriorAlgebra.ι R x`. -/
342+
def toExterior : TensorAlgebra R M →ₐ[R] ExteriorAlgebra R M :=
343+
TensorAlgebra.lift R (ExteriorAlgebra.ι R : M →ₗ[R] ExteriorAlgebra R M)
344+
#align tensor_algebra.to_exterior TensorAlgebra.toExterior
345+
346+
@[simp]
347+
theorem toExterior_ι (m : M) :
348+
TensorAlgebra.toExterior (TensorAlgebra.ι R m) = ExteriorAlgebra.ι R m := by
349+
simp [toExterior]
350+
#align tensor_algebra.to_exterior_ι TensorAlgebra.toExterior_ι
351+
352+
end TensorAlgebra

0 commit comments

Comments
 (0)