-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Expand file tree
/
Copy pathBasic.lean
More file actions
305 lines (228 loc) · 10.8 KB
/
Copy pathBasic.lean
File metadata and controls
305 lines (228 loc) · 10.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
/-
Copyright (c) 2018 Andreas Swerdlow. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Andreas Swerdlow, Kexing Ying
-/
import Mathlib.Algebra.Algebra.Tower
import Mathlib.LinearAlgebra.BilinearMap
#align_import linear_algebra.bilinear_form from "leanprover-community/mathlib"@"f0c8bf9245297a541f468be517f1bde6195105e9"
/-!
# Bilinear form
This file defines a bilinear form over a module. Basic ideas
such as orthogonality are also introduced, as well as reflexive,
symmetric, non-degenerate and alternating bilinear forms. Adjoints of
linear maps with respect to a bilinear form are also introduced.
A bilinear form on an `R`-(semi)module `M`, is a function from `M × M` to `R`,
that is linear in both arguments. Comments will typically abbreviate
"(semi)module" as just "module", but the definitions should be as general as
possible.
The result that there exists an orthogonal basis with respect to a symmetric,
nondegenerate bilinear form can be found in `QuadraticForm.lean` with
`exists_orthogonal_basis`.
## Notations
Given any term `B` of type `BilinForm`, due to a coercion, can use
the notation `B x y` to refer to the function field, ie. `B x y = B.bilin x y`.
In this file we use the following type variables:
- `M`, `M'`, ... are modules over the commutative semiring `R`,
- `M₁`, `M₁'`, ... are modules over the commutative ring `R₁`,
- `V`, ... is a vector space over the field `K`.
## References
* <https://en.wikipedia.org/wiki/Bilinear_form>
## Tags
Bilinear form,
-/
open BigOperators
open LinearMap (BilinForm)
universe u v w
variable {R : Type*} {M : Type*} [CommSemiring R] [AddCommMonoid M] [Module R M]
variable {S : Type*} [CommSemiring S] [Algebra S R] [Module S M] [IsScalarTower S R M]
variable {R₁ : Type*} {M₁ : Type*} [CommRing R₁] [AddCommGroup M₁] [Module R₁ M₁]
variable {V : Type*} {K : Type*} [Field K] [AddCommGroup V] [Module K V]
variable {B : BilinForm R M} {B₁ : BilinForm R₁ M₁}
namespace LinearMap
namespace BilinForm
instance : CoeFun (BilinForm R M) fun _ => M → M → R := ⟨fun B₃ x y => B₃ x y⟩
/-
initialize_simps_projections BilinForm (bilin → apply)
-- Porting note: removed for simpVarHead @[simp]
theorem coeFn_mk (f : M → M → R) (h₁ h₂ h₃ h₄) : (BilinForm.mk f h₁ h₂ h₃ h₄ : M → M → R) = f :=
rfl
#align bilin_form.coe_fn_mk BilinForm.coeFn_mk
-/
theorem coeFn_congr : ∀ {x x' y y' : M}, x = x' → y = y' → B x y = B x' y'
| _, _, _, _, rfl, rfl => rfl
#align bilin_form.coe_fn_congr LinearMap.BilinForm.coeFn_congr
theorem add_left (x y z : M) : B (x + y) z = B x z + B y z := by
simp only [map_add, LinearMap.add_apply]
#align bilin_form.add_left LinearMap.BilinForm.add_left
theorem smul_left (a : R) (x y : M) : B (a • x) y = a * B x y := by
simp only [map_smul, LinearMap.smul_apply, smul_eq_mul]
#align bilin_form.smul_left LinearMap.BilinForm.smul_left
theorem add_right (x y z : M) : B x (y + z) = B x y + B x z := map_add _ _ _
#align bilin_form.add_right LinearMap.BilinForm.add_right
theorem smul_right (a : R) (x y : M) : B x (a • y) = a * B x y := map_smul _ _ _
#align bilin_form.smul_right LinearMap.BilinForm.smul_right
theorem zero_left (x : M) : B 0 x = 0 := by
rw [← @zero_smul R _ _ _ _ (0 : M), smul_left, zero_mul]
#align bilin_form.zero_left LinearMap.BilinForm.zero_left
theorem zero_right (x : M) : B x 0 = 0 := by
rw [← @zero_smul R _ _ _ _ (0 : M), smul_right, zero_mul]
#align bilin_form.zero_right LinearMap.BilinForm.zero_right
theorem neg_left (x y : M₁) : B₁ (-x) y = -B₁ x y := by
rw [← @neg_one_smul R₁ _ _, smul_left, neg_one_mul]
#align bilin_form.neg_left LinearMap.BilinForm.neg_left
theorem neg_right (x y : M₁) : B₁ x (-y) = -B₁ x y := by
rw [← @neg_one_smul R₁ _ _, smul_right, neg_one_mul]
#align bilin_form.neg_right LinearMap.BilinForm.neg_right
theorem sub_left (x y z : M₁) : B₁ (x - y) z = B₁ x z - B₁ y z := by
rw [sub_eq_add_neg, sub_eq_add_neg, add_left, neg_left]
#align bilin_form.sub_left LinearMap.BilinForm.sub_left
theorem sub_right (x y z : M₁) : B₁ x (y - z) = B₁ x y - B₁ x z := by
rw [sub_eq_add_neg, sub_eq_add_neg, add_right, neg_right]
#align bilin_form.sub_right LinearMap.BilinForm.sub_right
lemma smul_left_of_tower (r : S) (x y : M) : B (r • x) y = r • B x y := by
rw [← IsScalarTower.algebraMap_smul R r, smul_left, Algebra.smul_def]
lemma smul_right_of_tower (r : S) (x y : M) : B x (r • y) = r • B x y := by
rw [← IsScalarTower.algebraMap_smul R r, smul_right, Algebra.smul_def]
variable {D : BilinForm R M} {D₁ : BilinForm R₁ M₁}
-- TODO: instantiate `FunLike`
theorem coe_injective : Function.Injective ((↑) : BilinForm R M → M → M → R) := fun B D h => by
ext x y
apply congrFun₂ h
#align bilin_form.coe_injective LinearMap.BilinForm.coe_injective
@[ext]
theorem ext (H : ∀ x y : M, B x y = D x y) : B = D :=
coe_injective <| by
funext
exact H _ _
#align bilin_form.ext LinearMap.BilinForm.ext
theorem congr_fun (h : B = D) (x y : M) : B x y = D x y :=
h ▸ rfl
#align bilin_form.congr_fun LinearMap.BilinForm.congr_fun
theorem ext_iff : B = D ↔ ∀ x y, B x y = D x y :=
⟨congr_fun, ext⟩
#align bilin_form.ext_iff LinearMap.BilinForm.ext_iff
instance : Zero (BilinForm R M) := LinearMap.instZeroLinearMap
theorem coe_zero : ⇑(0 : BilinForm R M) = 0 :=
rfl
#align bilin_form.coe_zero LinearMap.BilinForm.coe_zero
@[simp]
theorem zero_apply (x y : M) : (0 : BilinForm R M) x y = 0 :=
rfl
#align bilin_form.zero_apply LinearMap.BilinForm.zero_apply
variable (B D B₁ D₁)
instance : Add (BilinForm R M) := LinearMap.instAddLinearMap
theorem coe_add : ⇑(B + D) = B + D :=
rfl
#align bilin_form.coe_add LinearMap.BilinForm.coe_add
@[simp]
theorem add_apply (x y : M) : (B + D) x y = B x y + D x y :=
rfl
#align bilin_form.add_apply LinearMap.BilinForm.add_apply
/-- `BilinForm R M` inherits the scalar action by `α` on `R` if this is compatible with
multiplication.
When `R` itself is commutative, this provides an `R`-action via `Algebra.id`. -/
instance {α} [Monoid α] [DistribMulAction α R] [SMulCommClass R α R] : SMul α (BilinForm R M) :=
LinearMap.instSMulLinearMap
theorem coe_smul {α} [Monoid α] [DistribMulAction α R] [SMulCommClass R α R] (a : α)
(B : BilinForm R M) : ⇑(a • B) = a • ⇑B :=
rfl
#align bilin_form.coe_smul LinearMap.BilinForm.coe_smul
@[simp]
theorem smul_apply {α} [Monoid α] [DistribMulAction α R] [SMulCommClass R α R] (a : α)
(B : BilinForm R M) (x y : M) : (a • B) x y = a • B x y :=
rfl
#align bilin_form.smul_apply LinearMap.BilinForm.smul_apply
instance {α β} [Monoid α] [Monoid β] [DistribMulAction α R] [DistribMulAction β R]
[SMulCommClass R α R] [SMulCommClass R β R] [SMulCommClass α β R] :
SMulCommClass α β (BilinForm R M) :=
⟨fun a b B => ext fun x y => smul_comm a b (B x y)⟩
instance {α β} [Monoid α] [Monoid β] [SMul α β] [DistribMulAction α R] [DistribMulAction β R]
[SMulCommClass R α R] [SMulCommClass R β R] [IsScalarTower α β R] :
IsScalarTower α β (BilinForm R M) :=
⟨fun a b B => ext fun x y => smul_assoc a b (B x y)⟩
instance {α} [Monoid α] [DistribMulAction α R] [DistribMulAction αᵐᵒᵖ R]
[SMulCommClass R α R] [IsCentralScalar α R] :
IsCentralScalar α (BilinForm R M) :=
⟨fun a B => ext fun x y => op_smul_eq_smul a (B x y)⟩
instance : AddCommMonoid (BilinForm R M) :=
Function.Injective.addCommMonoid _ coe_injective coe_zero coe_add fun _ _ => coe_smul _ _
instance : Neg (BilinForm R₁ M₁) := LinearMap.instNegLinearMapToAddCommMonoid
theorem coe_neg : ⇑(-B₁) = -B₁ :=
rfl
#align bilin_form.coe_neg LinearMap.BilinForm.coe_neg
@[simp]
theorem neg_apply (x y : M₁) : (-B₁) x y = -B₁ x y :=
rfl
#align bilin_form.neg_apply LinearMap.BilinForm.neg_apply
instance : Sub (BilinForm R₁ M₁) := LinearMap.instSubLinearMapToAddCommMonoid
theorem coe_sub : ⇑(B₁ - D₁) = B₁ - D₁ :=
rfl
#align bilin_form.coe_sub LinearMap.BilinForm.coe_sub
@[simp]
theorem sub_apply (x y : M₁) : (B₁ - D₁) x y = B₁ x y - D₁ x y :=
rfl
#align bilin_form.sub_apply LinearMap.BilinForm.sub_apply
instance : AddCommGroup (BilinForm R₁ M₁) :=
Function.Injective.addCommGroup _ coe_injective coe_zero coe_add coe_neg coe_sub
(fun _ _ => coe_smul _ _) fun _ _ => coe_smul _ _
instance : Inhabited (BilinForm R M) :=
⟨0⟩
/-- `coeFn` as an `AddMonoidHom` -/
def coeFnAddMonoidHom : BilinForm R M →+ M → M → R where
toFun := (↑)
map_zero' := coe_zero
map_add' := coe_add
#align bilin_form.coe_fn_add_monoid_hom LinearMap.BilinForm.coeFnAddMonoidHom
instance {α} [Monoid α] [DistribMulAction α R] [SMulCommClass R α R] :
DistribMulAction α (BilinForm R M) :=
Function.Injective.distribMulAction coeFnAddMonoidHom coe_injective coe_smul
instance {α} [CommSemiring α] [Module α R] [SMulCommClass R α R] : Module α (BilinForm R M) :=
Function.Injective.module _ coeFnAddMonoidHom coe_injective coe_smul
section flip
/-- Auxiliary construction for the flip of a bilinear form, obtained by exchanging the left and
right arguments. This version is a `LinearMap`; it is later upgraded to a `LinearEquiv`
in `flipHom`. -/
def flipHomAux : (BilinForm R M) →ₗ[R] (BilinForm R M) where
toFun A := A.flip
map_add' A₁ A₂ := by
ext
simp only [LinearMap.flip_apply, LinearMap.add_apply]
map_smul' c A := by
ext
simp only [LinearMap.flip_apply, LinearMap.smul_apply, RingHom.id_apply]
#align bilin_form.flip_hom_aux LinearMap.BilinForm.flipHomAux
theorem flip_flip_aux (A : BilinForm R M) :
flipHomAux.toFun (flipHomAux.toFun A) = A := by
ext A
simp [flipHomAux]
#align bilin_form.flip_flip_aux LinearMap.BilinForm.flip_flip_aux
/-- The flip of a bilinear form, obtained by exchanging the left and right arguments. -/
def flipHom : BilinForm R M ≃ₗ[R] BilinForm R M :=
{ flipHomAux with
invFun := flipHomAux.toFun
left_inv := flip_flip_aux
right_inv := flip_flip_aux }
#align bilin_form.flip_hom LinearMap.BilinForm.flipHom
@[simp]
theorem flip_apply (A : BilinForm R M) (x y : M) : flipHom A x y = A y x :=
rfl
#align bilin_form.flip_apply LinearMap.BilinForm.flip_apply
theorem flip_flip :
flipHom.trans flipHom = LinearEquiv.refl R (BilinForm R M) := by
ext A
simp
#align bilin_form.flip_flip LinearMap.BilinForm.flip_flip
/-- The `flip` of a bilinear form over a commutative ring, obtained by exchanging the left and
right arguments. -/
abbrev flip : BilinForm R M ≃ₗ[R] BilinForm R M :=
flipHom
#align bilin_form.flip LinearMap.BilinForm.flip
end flip
/-- The restriction of a bilinear form on a submodule. -/
@[simps! apply]
def restrict (B : BilinForm R M) (W : Submodule R M) : BilinForm R W :=
LinearMap.domRestrict₁₂ B W W
#align bilin_form.restrict LinearMap.BilinForm.restrict
end BilinForm
end LinearMap