11/-
22Copyright (c) 2026 Patrick Massot. All rights reserved.
33Released under Apache 2.0 license as described in the file LICENSE.
4- Authors: Patrick Massot, Anatole Dedecker
4+ Authors: Patrick Massot, Anatole Dedecker, Yongxi Lin
55-/
66module
77
@@ -32,6 +32,9 @@ In this file, we define:
3232 noetherian ring, in which case the two notions agree.
3333 This is an instance in the scope `LinearMap.FiniteRangeSetoid`,
3434 so opening this scope allows this relation to be denoted by `≈`.
35+ * `LinearMap.IsQuasiInverse`: two linear maps `u` and `v` are **quasi-inverses** if we have
36+ `u ∘ₗ v ≈ id` and `v ∘ₗ u ≈ id` modulo linear maps with noetherian ranges.
37+
3538 -/
3639
3740@[expose] public section
@@ -50,10 +53,12 @@ variable [Semiring K]
5053 [AddCommMonoid V₃] [Module K V₃]
5154
5255/-- A linear map **has Noetherian range** if its range is a Noetherian module. -/
53- def HasNoetherianRange (f : V →ₗ[K] V₂) := IsNoetherian K f.range
56+ def HasNoetherianRange (f : V →ₗ[K] V₂) : Prop :=
57+ IsNoetherian K f.range
5458
5559/-- A linear map **has finite range** if its range is finitely generated. -/
56- def HasFiniteRange (f : V →ₗ[K] V₂) := f.range.FG
60+ def HasFiniteRange (f : V →ₗ[K] V₂) : Prop :=
61+ f.range.FG
5762
5863lemma hasNoetherianRange_iff_range {f : V →ₗ[K] V₂} :
5964 f.HasNoetherianRange ↔ IsNoetherian K f.range :=
@@ -268,4 +273,165 @@ end FiniteRangeSetoid
268273
269274end Setoid
270275
276+ section QuasiInverse
277+
278+ variable [CommRing K]
279+ [AddCommGroup V] [Module K V]
280+ [AddCommGroup V₂] [Module K V₂]
281+ [AddCommGroup V₃] [Module K V₃]
282+
283+ open scoped LinearMap.FiniteRangeSetoid
284+
285+ /-- `u` is a **left quasi-inverse** to `v` if `u ∘ₗ v ≈ id` modulo
286+ linear maps with noetherian ranges. Recall that if the scalar ring is noetherian
287+ (e.g a field), then "noetherian range" can be replaced by "finitely generated range". -/
288+ def IsLeftQuasiInverse (u : V →ₗ[K] V₂) (v : V₂ →ₗ[K] V) : Prop :=
289+ u ∘ₗ v ≈ .id
290+
291+ /-- `u` is a **right quasi-inverse** to `v` if `v ∘ₗ u ≈ id` modulo
292+ linear maps with noetherian ranges. Recall that if the scalar ring is noetherian
293+ (e.g a field), then "noetherian range" can be replaced by "finitely generated range". -/
294+ def IsRightQuasiInverse (u : V₃ →ₗ[K] V₂) (v : V₂ →ₗ[K] V₃) : Prop :=
295+ v ∘ₗ u ≈ .id
296+
297+ /-- `u` is a **quasi-inverse** to `v` if `u ∘ₗ v ≈ id` and `v ∘ₗ u ≈ id` modulo
298+ linear maps with noetherian ranges. Recall that if the scalar ring is noetherian
299+ (e.g a field), then "noetherian range" can be replaced by "finitely generated range". -/
300+ def IsQuasiInverse (u : V₃ →ₗ[K] V₂) (v : V₂ →ₗ[K] V₃) : Prop :=
301+ u.IsLeftQuasiInverse v ∧ u.IsRightQuasiInverse v
302+
303+ lemma isLeftQuasiInverse_iff_isRightQuasiInverse_swap {u : V₃ →ₗ[K] V₂} {v : V₂ →ₗ[K] V₃} :
304+ u.IsLeftQuasiInverse v ↔ v.IsRightQuasiInverse u := Iff.rfl
305+
306+ alias ⟨IsLeftQuasiInverse.isRightQuasiInverse, IsRightQuasiInverse.isLeftQuasiInverse⟩ :=
307+ isLeftQuasiInverse_iff_isRightQuasiInverse_swap
308+
309+ lemma IsLeftQuasiInverse.equiv {u : V₃ →ₗ[K] V₂} {v : V₂ →ₗ[K] V₃}
310+ (h : u.IsLeftQuasiInverse v) : u ∘ₗ v ≈ .id := h
311+
312+ lemma IsRightQuasiInverse.equiv {u : V₃ →ₗ[K] V₂} {v : V₂ →ₗ[K] V₃}
313+ (h : u.IsRightQuasiInverse v) : v ∘ₗ u ≈ .id := h
314+
315+ @[symm]
316+ lemma IsQuasiInverse.symm {u : V₃ →ₗ[K] V₂} {v : V₂ →ₗ[K] V₃}
317+ (h : u.IsQuasiInverse v) : v.IsQuasiInverse u :=
318+ And.symm h
319+
320+ @[gcongr]
321+ lemma IsLeftQuasiInverse.congr {u u' : V₃ →ₗ[K] V₂} {v v' : V₂ →ₗ[K] V₃}
322+ (h : u.IsLeftQuasiInverse v) (hu : u' ≈ u) (hv : v' ≈ v) :
323+ u'.IsLeftQuasiInverse v' := by
324+ unfold IsLeftQuasiInverse at *
325+ grw [hu, hv]
326+ assumption
327+
328+ @[gcongr]
329+ lemma isLeftQuasiInverse_congr {u u' : V₃ →ₗ[K] V₂} {v v' : V₂ →ₗ[K] V₃}
330+ (hu : u' ≈ u) (hv : v' ≈ v) :
331+ u.IsLeftQuasiInverse v ↔ u'.IsLeftQuasiInverse v' :=
332+ ⟨fun H ↦ H.congr hu hv, fun H ↦ H.congr (Setoid.symm hu) (Setoid.symm hv)⟩
333+
334+ @[gcongr]
335+ lemma IsRightQuasiInverse.congr {u u' : V₃ →ₗ[K] V₂} {v v' : V₂ →ₗ[K] V₃}
336+ (h : u.IsRightQuasiInverse v) (hu : u' ≈ u) (hv : v' ≈ v) :
337+ u'.IsRightQuasiInverse v' :=
338+ h.isLeftQuasiInverse.congr hv hu |>.isRightQuasiInverse
339+
340+ lemma isRightQuasiInverse_congr {u u' : V₃ →ₗ[K] V₂} {v v' : V₂ →ₗ[K] V₃}
341+ (hu : u' ≈ u) (hv : v' ≈ v) :
342+ u.IsRightQuasiInverse v ↔ u'.IsRightQuasiInverse v' :=
343+ ⟨fun H ↦ H.congr hu hv, fun H ↦ H.congr (Setoid.symm hu) (Setoid.symm hv)⟩
344+
345+ @[gcongr]
346+ lemma IsQuasiInverse.congr {u u' : V₃ →ₗ[K] V₂} {v v' : V₂ →ₗ[K] V₃}
347+ (h : u.IsQuasiInverse v) (hu : u' ≈ u) (hv : v' ≈ v) :
348+ u'.IsQuasiInverse v' :=
349+ ⟨h.1 .congr hu hv, h.2 .congr hu hv⟩
350+
351+ lemma isQuasiInverse_congr {u u' : V₃ →ₗ[K] V₂} {v v' : V₂ →ₗ[K] V₃}
352+ (hu : u' ≈ u) (hv : v' ≈ v) :
353+ u.IsQuasiInverse v ↔ u'.IsQuasiInverse v' := by
354+ simp [IsQuasiInverse, isLeftQuasiInverse_congr hu hv, isRightQuasiInverse_congr hu hv]
355+
356+ lemma IsQuasiInverse.equiv_of_left {u u' : V₃ →ₗ[K] V₂} {v v' : V₂ →ₗ[K] V₃}
357+ (h : u.IsQuasiInverse v) (h' : u'.IsQuasiInverse v') (hu : u ≈ u') :
358+ v ≈ v' := by
359+ calc
360+ v = v ∘ₗ .id := by simp
361+ _ ≈ v ∘ₗ (u' ∘ₗ v') := by grw [h'.1 .equiv]
362+ _ ≈ v ∘ₗ (u ∘ₗ v') := by grw [hu]
363+ _ = (v ∘ₗ u) ∘ₗ v' := by rw [comp_assoc]
364+ _ ≈ .id ∘ₗ v' := by grw [h.2 .equiv]
365+ _ = v' := by simp
366+
367+ lemma IsQuasiInverse.equiv_of_right {u u' : V₃ →ₗ[K] V₂} {v v' : V₂ →ₗ[K] V₃}
368+ (h : u.IsQuasiInverse v) (h' : u'.IsQuasiInverse v') (hv : v ≈ v') :
369+ u ≈ u' :=
370+ h.symm.equiv_of_left h'.symm hv
371+
372+ /-- Left quasi-inverses compose in the opposite order. -/
373+ lemma IsLeftQuasiInverse.comp {u : V →ₗ[K] V₂} {v : V₂ →ₗ[K] V₃} {u' : V₂ →ₗ[K] V}
374+ {v' : V₃ →ₗ[K] V₂} (hu : u'.IsLeftQuasiInverse u) (hv : v'.IsLeftQuasiInverse v) :
375+ (u' ∘ₗ v').IsLeftQuasiInverse (v ∘ₗ u) :=
376+ calc
377+ _ = u' ∘ₗ (v' ∘ₗ v) ∘ₗ u := rfl
378+ _ ≈ u' ∘ₗ .id ∘ₗ u := by grw [hv.equiv]
379+ _ ≈ .id := hu.equiv
380+
381+ /-- Right quasi-inverses compose in the opposite order. -/
382+ lemma IsRightQuasiInverse.comp {u : V →ₗ[K] V₂} {v : V₂ →ₗ[K] V₃} {u' : V₂ →ₗ[K] V}
383+ {v' : V₃ →ₗ[K] V₂} (hu : u'.IsRightQuasiInverse u) (hv : v'.IsRightQuasiInverse v) :
384+ (u' ∘ₗ v').IsRightQuasiInverse (v ∘ₗ u) :=
385+ hv.isLeftQuasiInverse.comp hu.isLeftQuasiInverse |>.isRightQuasiInverse
386+
387+ /-- Quasi-inverses compose in the opposite order. -/
388+ lemma IsQuasiInverse.comp {u : V →ₗ[K] V₂} {v : V₂ →ₗ[K] V₃} {u' : V₂ →ₗ[K] V}
389+ {v' : V₃ →ₗ[K] V₂} (hu : u'.IsQuasiInverse u) (hv : v'.IsQuasiInverse v) :
390+ (u' ∘ₗ v').IsQuasiInverse (v ∘ₗ u) :=
391+ ⟨hu.1 .comp hv.1 , hu.2 .comp hv.2 ⟩
392+
393+ /-- If `u'` is a right quasi-inverse of `u` and `w` is a left quasi-inverse of `v ∘ₗ u`,
394+ then `u ∘ₗ w` is a left quasi-inverse of `v`. -/
395+ lemma IsLeftQuasiInverse.of_comp_left {u : V →ₗ[K] V₂} {v : V₂ →ₗ[K] V₃}
396+ {u' : V₂ →ₗ[K] V} {w : V₃ →ₗ[K] V} (hu : u'.IsRightQuasiInverse u)
397+ (hw : w.IsLeftQuasiInverse (v ∘ₗ u)) :
398+ (u ∘ₗ w).IsLeftQuasiInverse v := by
399+ calc
400+ _ = ((u ∘ₗ w) ∘ₗ v) ∘ₗ .id := rfl
401+ _ ≈ ((u ∘ₗ w) ∘ₗ v) ∘ₗ (u ∘ₗ u') := by grw [hu.equiv]
402+ _ = u ∘ₗ (w ∘ₗ (v ∘ₗ u)) ∘ₗ u' := rfl
403+ _ ≈ u ∘ₗ .id ∘ₗ u' := by grw [hw.equiv]
404+ _ ≈ .id := hu.equiv
405+
406+ /-- If `u'` is a quasi-inverse of `u` and `w` is a quasi-inverse of `v ∘ₗ u`, then
407+ `u ∘ₗ w` is a quasi-inverse of `v`. -/
408+ lemma IsQuasiInverse.of_comp_left {u : V →ₗ[K] V₂} {v : V₂ →ₗ[K] V₃}
409+ {u' : V₂ →ₗ[K] V} {w : V₃ →ₗ[K] V} (hu : u'.IsQuasiInverse u)
410+ (hw : w.IsQuasiInverse (v ∘ₗ u)) :
411+ (u ∘ₗ w).IsQuasiInverse v :=
412+ ⟨.of_comp_left hu.2 hw.1 , hw.2 ⟩
413+
414+ /-- If `v'` is a left quasi-inverse of `v` and `w` is a right quasi-inverse of `v ∘ₗ u`,
415+ then `w ∘ₗ v` is a right quasi-inverse of `u`. -/
416+ lemma IsRightQuasiInverse.of_comp_right {u : V →ₗ[K] V₂} {v : V₂ →ₗ[K] V₃}
417+ {v' : V₃ →ₗ[K] V₂} {w : V₃ →ₗ[K] V} (hv : v'.IsLeftQuasiInverse v)
418+ (hw : w.IsRightQuasiInverse (v ∘ₗ u)) :
419+ (w ∘ₗ v).IsRightQuasiInverse u := by
420+ calc
421+ _ = .id ∘ₗ (u ∘ₗ (w ∘ₗ v)) := rfl
422+ _ ≈ (v' ∘ₗ v) ∘ₗ (u ∘ₗ (w ∘ₗ v)) := by grw [hv.equiv]
423+ _ = v' ∘ₗ ((v ∘ₗ u) ∘ₗ w) ∘ₗ v := rfl
424+ _ ≈ v' ∘ₗ .id ∘ₗ v := by grw [hw.equiv]
425+ _ ≈ .id := hv.equiv
426+
427+ /-- If `v'` is a quasi-inverse of `v` and `w` is a quasi-inverse of `v ∘ₗ u`, then
428+ `w ∘ₗ v` is a quasi-inverse of `u`. -/
429+ lemma IsQuasiInverse.of_comp_right {u : V →ₗ[K] V₂} {v : V₂ →ₗ[K] V₃}
430+ {v' : V₃ →ₗ[K] V₂} {w : V₃ →ₗ[K] V} (hv : v'.IsQuasiInverse v)
431+ (hw : w.IsQuasiInverse (v ∘ₗ u)) :
432+ (w ∘ₗ v).IsQuasiInverse u :=
433+ ⟨hw.1 , IsRightQuasiInverse.of_comp_right hv.1 hw.2 ⟩
434+
435+ end QuasiInverse
436+
271437end LinearMap
0 commit comments