File: Mathlib/LinearAlgebra/PerfectPairing.lean

full_name: PerfectPairing.bijectiveLeft
code: /-- A perfect pairing of two (left) modules over a commutative ring. -/
structure PerfectPairing :=
  toLin : M →ₗ[R] N →ₗ[R] R
  bijectiveLeft : Bijective toLin
  bijectiveRight : Bijective toLin.flip
goal: Function.Bijective ⇑self.toLin

full_name: PerfectPairing.toLin
code: /-- A perfect pairing of two (left) modules over a commutative ring. -/
structure PerfectPairing :=
  toLin : M →ₗ[R] N →ₗ[R] R
  bijectiveLeft : Bijective toLin
  bijectiveRight : Bijective toLin.flip
goal: M →ₗ[R] N →ₗ[R] R

full_name: PerfectPairing.bijectiveRight
code: /-- A perfect pairing of two (left) modules over a commutative ring. -/
structure PerfectPairing :=
  toLin : M →ₗ[R] N →ₗ[R] R
  bijectiveLeft : Bijective toLin
  bijectiveRight : Bijective toLin.flip
goal: Function.Bijective ⇑self.toLin.flip

full_name: PerfectPairing
code: /-- A perfect pairing of two (left) modules over a commutative ring. -/
structure PerfectPairing :=
  toLin : M →ₗ[R] N →ₗ[R] R
  bijectiveLeft : Bijective toLin
  bijectiveRight : Bijective toLin.flip
goal: Type (max (max u_1 u_2) u_3)

full_name: PerfectPairing.instFunLike
code: instance instFunLike : FunLike (PerfectPairing R M N) M (N →ₗ[R] R) 
goal: FunLike (PerfectPairing R M N) M (N →ₗ[R] R)

full_name: PerfectPairing.flip
code: /-- Given a perfect pairing between `M` and `N`, we may interchange the roles of `M` and `N`. -/
protected def flip : PerfectPairing R N M 
goal: PerfectPairing R N M

full_name: PerfectPairing.flip_flip
code: @[simp] lemma flip_flip : p.flip.flip = p 
goal: p.flip.flip = p

full_name: PerfectPairing.toDualLeft
code: /-- The linear equivalence from `M` to `Dual R N` induced by a perfect pairing. -/
noncomputable def toDualLeft : M ≃ₗ[R] Dual R N 
goal: M ≃ₗ[R] Module.Dual R N

full_name: PerfectPairing.toDualLeft_apply
code: @[simp]
theorem toDualLeft_apply (a : M) : p.toDualLeft a = p a 
goal: p.toDualLeft a = p a

full_name: PerfectPairing.apply_toDualLeft_symm_apply
code: @[simp]
theorem apply_toDualLeft_symm_apply (f : Dual R N) (x : N) : p (p.toDualLeft.symm f) x = f x 
goal: (p (p.toDualLeft.symm f)) x = f x

full_name: PerfectPairing.toDualRight
code: /-- The linear equivalence from `N` to `Dual R M` induced by a perfect pairing. -/
noncomputable def toDualRight : N ≃ₗ[R] Dual R M 
goal: N ≃ₗ[R] Module.Dual R M

full_name: PerfectPairing.toDualRight_apply
code: @[simp]
theorem toDualRight_apply (a : N) : p.toDualRight a = p.flip a 
goal: p.toDualRight a = p.flip a

full_name: PerfectPairing.apply_apply_toDualRight_symm
code: @[simp]
theorem apply_apply_toDualRight_symm (x : M) (f : Dual R M) :
    (p x) (p.toDualRight.symm f) = f x 
goal: (p x) (p.toDualRight.symm f) = f x

full_name: PerfectPairing.toDualLeft_of_toDualRight_symm
code: theorem toDualLeft_of_toDualRight_symm (x : M) (f : Dual R M) :
    (p.toDualLeft x) (p.toDualRight.symm f) = f x 
goal: (p.toDualLeft x) (p.toDualRight.symm f) = f x

full_name: PerfectPairing.toDualRight_symm_toDualLeft
code: theorem toDualRight_symm_toDualLeft (x : M) :
    p.toDualRight.symm.dualMap (p.toDualLeft x) = Dual.eval R M x 
goal: p.toDualRight.symm.dualMap (p.toDualLeft x) = (Module.Dual.eval R M) x

full_name: PerfectPairing.toDualRight_symm_comp_toDualLeft
code: theorem toDualRight_symm_comp_toDualLeft :
    p.toDualRight.symm.dualMap ∘ₗ (p.toDualLeft : M →ₗ[R] Dual R N) = Dual.eval R M 
goal: ↑p.toDualRight.symm.dualMap ∘ₗ ↑p.toDualLeft = Module.Dual.eval R M

full_name: PerfectPairing.bijective_toDualRight_symm_toDualLeft
code: theorem bijective_toDualRight_symm_toDualLeft :
    Bijective (fun x => p.toDualRight.symm.dualMap (p.toDualLeft x)) 
goal: Function.Bijective fun x => p.toDualRight.symm.dualMap (p.toDualLeft x)

full_name: PerfectPairing.reflexive_left
code: theorem reflexive_left : IsReflexive R M 
goal: Module.IsReflexive R M

full_name: PerfectPairing.reflexive_right
code: theorem reflexive_right : IsReflexive R N 
goal: Module.IsReflexive R N

full_name: IsReflexive.toPerfectPairingDual_toLin
code: /-- A reflexive module has a perfect pairing with its dual. -/
@[simps]
def IsReflexive.toPerfectPairingDual : PerfectPairing R (Dual R M) M 
goal: IsReflexive.toPerfectPairingDual.toLin = LinearMap.id

full_name: IsReflexive.toPerfectPairingDual
code: /-- A reflexive module has a perfect pairing with its dual. -/
@[simps]
def IsReflexive.toPerfectPairingDual : PerfectPairing R (Dual R M) M 
goal: PerfectPairing R (Module.Dual R M) M

full_name: LinearEquiv.flip
code: /-- For a reflexive module `M`, an equivalence `N ≃ₗ[R] Dual R M` naturally yields an equivalence
`M ≃ₗ[R] Dual R N`. Such equivalences are known as perfect pairings. -/
noncomputable def flip : M ≃ₗ[R] Dual R N 
goal: M ≃ₗ[R] Module.Dual R N

full_name: LinearEquiv.coe_toLinearMap_flip
code: @[simp] lemma coe_toLinearMap_flip : e.flip = (↑e : N →ₗ[R] Dual R M).flip 
goal: ↑e.flip = (↑e).flip

full_name: LinearEquiv.flip_apply
code: @[simp] lemma flip_apply (m : M) (n : N) : e.flip m n = e n m 
goal: (e.flip m) n = (e n) m

full_name: LinearEquiv.symm_flip
code: lemma symm_flip : e.flip.symm = e.symm.dualMap.trans (evalEquiv R M).symm 
goal: e.flip.symm = e.symm.dualMap ≪≫ₗ (Module.evalEquiv R M).symm

full_name: LinearEquiv.trans_dualMap_symm_flip
code: lemma trans_dualMap_symm_flip : e.trans e.flip.symm.dualMap = Dual.eval R N 
goal: ↑(e ≪≫ₗ e.flip.symm.dualMap) = Module.Dual.eval R N

full_name: LinearEquiv.isReflexive_of_equiv_dual_of_isReflexive
code: /-- If `N` is in perfect pairing with `M`, then it is reflexive. -/
lemma isReflexive_of_equiv_dual_of_isReflexive : IsReflexive R N 
goal: Module.IsReflexive R N

full_name: LinearEquiv.flip_flip
code: @[simp] lemma flip_flip (h : IsReflexive R N := isReflexive_of_equiv_dual_of_isReflexive e) :
    e.flip.flip = e 
goal: e.flip.flip = e

full_name: LinearEquiv.toPerfectPairing
code: /-- If `M` is reflexive then a linear equivalence `N ≃ Dual R M` is a perfect pairing. -/
@[simps]
noncomputable def toPerfectPairing : PerfectPairing R N M 
goal: PerfectPairing R N M

full_name: LinearEquiv.toPerfectPairing_toLin
code: /-- If `M` is reflexive then a linear equivalence `N ≃ Dual R M` is a perfect pairing. -/
@[simps]
noncomputable def toPerfectPairing : PerfectPairing R N M 
goal: e.toPerfectPairing.toLin = ↑e

full_name: Submodule.dualCoannihilator_map_linearEquiv_flip
code: @[simp]
lemma dualCoannihilator_map_linearEquiv_flip (p : Submodule R M) :
    (p.map e.flip).dualCoannihilator = p.dualAnnihilator.map e.symm 
goal: (Submodule.map e.flip p).dualCoannihilator = Submodule.map e.symm p.dualAnnihilator

full_name: Submodule.map_dualAnnihilator_linearEquiv_flip_symm
code: @[simp]
lemma map_dualAnnihilator_linearEquiv_flip_symm (p : Submodule R N) :
    p.dualAnnihilator.map e.flip.symm = (p.map e).dualCoannihilator 
goal: Submodule.map e.flip.symm p.dualAnnihilator = (Submodule.map e p).dualCoannihilator

full_name: Submodule.map_dualCoannihilator_linearEquiv_flip
code: @[simp]
lemma map_dualCoannihilator_linearEquiv_flip (p : Submodule R (Dual R M)) :
    p.dualCoannihilator.map e.flip = (p.map e.symm).dualAnnihilator 
goal: Submodule.map e.flip p.dualCoannihilator = (Submodule.map e.symm p).dualAnnihilator

full_name: Submodule.dualAnnihilator_map_linearEquiv_flip_symm
code: @[simp]
lemma dualAnnihilator_map_linearEquiv_flip_symm (p : Submodule R (Dual R N)) :
    (p.map e.flip.symm).dualAnnihilator = p.dualCoannihilator.map e 
goal: (Submodule.map e.flip.symm p).dualAnnihilator = Submodule.map e p.dualCoannihilator