File: Mathlib/LinearAlgebra/Dual.lean

full_name: Module.Dual
code: /-- The dual space of an R-module M is the R-module of linear maps `M → R`. -/
abbrev Dual 
goal: Type (max uM uR)

full_name: Module.dualPairing
code: /-- The canonical pairing of a vector space and its algebraic dual. -/
def dualPairing (R M) [CommSemiring R] [AddCommMonoid M] [Module R M] :
    Module.Dual R M →ₗ[R] M →ₗ[R] R 
goal: Module.Dual R M →ₗ[R] M →ₗ[R] R

full_name: Module.dualPairing_apply
code: @[simp]
theorem dualPairing_apply (v x) : dualPairing R M v x = v x 
goal: ((Module.dualPairing R M) v) x = v x

full_name: Module.Dual.instInhabited
code: instance : Inhabited (Dual R M) 
goal: Inhabited (Module.Dual R M)

full_name: Module.Dual.eval
code: /-- Maps a module M to the dual of the dual of M. See `Module.erange_coe` and
`Module.evalEquiv`. -/
def eval : M →ₗ[R] Dual R (Dual R M) 
goal: M →ₗ[R] Module.Dual R (Module.Dual R M)

full_name: Module.Dual.eval_apply
code: @[simp]
theorem eval_apply (v : M) (a : Dual R M) : eval R M v a = a v 
goal: ((Module.Dual.eval R M) v) a = a v

full_name: Module.Dual.transpose
code: /-- The transposition of linear maps, as a linear map from `M →ₗ[R] M'` to
`Dual R M' →ₗ[R] Dual R M`. -/
def transpose : (M →ₗ[R] M') →ₗ[R] Dual R M' →ₗ[R] Dual R M 
goal: (M →ₗ[R] M') →ₗ[R] Module.Dual R M' →ₗ[R] Module.Dual R M

full_name: Module.Dual.transpose_apply
code: theorem transpose_apply (u : M →ₗ[R] M') (l : Dual R M') : transpose (R := R) u l = l.comp u 
goal: (Module.Dual.transpose u) l = l ∘ₗ u

full_name: Module.Dual.transpose_comp
code: theorem transpose_comp (u : M' →ₗ[R] M'') (v : M →ₗ[R] M') :
    transpose (R := R) (u.comp v) = (transpose (R := R) v).comp (transpose (R := R) u) 
goal: Module.Dual.transpose (u ∘ₗ v) = Module.Dual.transpose v ∘ₗ Module.Dual.transpose u

full_name: Module.dualProdDualEquivDual_apply_apply
code: /-- Taking duals distributes over products. -/
@[simps!]
def dualProdDualEquivDual : (Module.Dual R M × Module.Dual R M') ≃ₗ[R] Module.Dual R (M × M') 
goal: ((Module.dualProdDualEquivDual R M M') f) a = f.1 a.1 + f.2 a.2

full_name: Module.dualProdDualEquivDual_symm_apply
code: /-- Taking duals distributes over products. -/
@[simps!]
def dualProdDualEquivDual : (Module.Dual R M × Module.Dual R M') ≃ₗ[R] Module.Dual R (M × M') 
goal: (Module.dualProdDualEquivDual R M M').symm f = (f ∘ₗ LinearMap.inl R M M', f ∘ₗ LinearMap.inr R M M')

full_name: Module.dualProdDualEquivDual
code: /-- Taking duals distributes over products. -/
@[simps!]
def dualProdDualEquivDual : (Module.Dual R M × Module.Dual R M') ≃ₗ[R] Module.Dual R (M × M') 
goal: (Module.Dual R M × Module.Dual R M') ≃ₗ[R] Module.Dual R (M × M')

full_name: Module.dualProdDualEquivDual_apply
code: @[simp]
theorem dualProdDualEquivDual_apply (φ : Module.Dual R M) (ψ : Module.Dual R M') :
    dualProdDualEquivDual R M M' (φ, ψ) = φ.coprod ψ 
goal: (Module.dualProdDualEquivDual R M M') (φ, ψ) = LinearMap.coprod φ ψ

full_name: LinearMap.dualMap
code: /-- Given a linear map `f : M₁ →ₗ[R] M₂`, `f.dualMap` is the linear map between the dual of
`M₂` and `M₁` such that it maps the functional `φ` to `φ ∘ f`. -/
def LinearMap.dualMap (f : M₁ →ₗ[R] M₂) : Dual R M₂ →ₗ[R] Dual R M₁ 
goal: Module.Dual R M₂ →ₗ[R] Module.Dual R M₁

full_name: LinearMap.dualMap_eq_lcomp
code: lemma LinearMap.dualMap_eq_lcomp (f : M₁ →ₗ[R] M₂) : f.dualMap = f.lcomp R 
goal: f.dualMap = LinearMap.lcomp R R f

full_name: LinearMap.dualMap_def
code: theorem LinearMap.dualMap_def (f : M₁ →ₗ[R] M₂) : f.dualMap = Module.Dual.transpose (R := R) f 
goal: f.dualMap = Module.Dual.transpose f

full_name: LinearMap.dualMap_apply'
code: theorem LinearMap.dualMap_apply' (f : M₁ →ₗ[R] M₂) (g : Dual R M₂) : f.dualMap g = g.comp f 
goal: f.dualMap g = g ∘ₗ f

full_name: LinearMap.dualMap_apply
code: @[simp]
theorem LinearMap.dualMap_apply (f : M₁ →ₗ[R] M₂) (g : Dual R M₂) (x : M₁) :
    f.dualMap g x = g (f x) 
goal: (f.dualMap g) x = g (f x)

full_name: LinearMap.dualMap_id
code: @[simp]
theorem LinearMap.dualMap_id : (LinearMap.id : M₁ →ₗ[R] M₁).dualMap = LinearMap.id 
goal: LinearMap.id.dualMap = LinearMap.id

full_name: LinearMap.dualMap_comp_dualMap
code: theorem LinearMap.dualMap_comp_dualMap {M₃ : Type*} [AddCommGroup M₃] [Module R M₃]
    (f : M₁ →ₗ[R] M₂) (g : M₂ →ₗ[R] M₃) : f.dualMap.comp g.dualMap = (g.comp f).dualMap 
goal: f.dualMap ∘ₗ g.dualMap = (g ∘ₗ f).dualMap

full_name: LinearMap.dualMap_injective_of_surjective
code: /-- If a linear map is surjective, then its dual is injective. -/
theorem LinearMap.dualMap_injective_of_surjective {f : M₁ →ₗ[R] M₂} (hf : Function.Surjective f) :
    Function.Injective f.dualMap 
goal: Function.Injective ⇑f.dualMap

full_name: LinearEquiv.dualMap
code: /-- The `Linear_equiv` version of `LinearMap.dualMap`. -/
def LinearEquiv.dualMap (f : M₁ ≃ₗ[R] M₂) : Dual R M₂ ≃ₗ[R] Dual R M₁ 
goal: Module.Dual R M₂ ≃ₗ[R] Module.Dual R M₁

full_name: LinearEquiv.dualMap_apply
code: @[simp]
theorem LinearEquiv.dualMap_apply (f : M₁ ≃ₗ[R] M₂) (g : Dual R M₂) (x : M₁) :
    f.dualMap g x = g (f x) 
goal: (f.dualMap g) x = g (f x)

full_name: LinearEquiv.dualMap_refl
code: @[simp]
theorem LinearEquiv.dualMap_refl :
    (LinearEquiv.refl R M₁).dualMap = LinearEquiv.refl R (Dual R M₁) 
goal: (LinearEquiv.refl R M₁).dualMap = LinearEquiv.refl R (Module.Dual R M₁)

full_name: LinearEquiv.dualMap_symm
code: @[simp]
theorem LinearEquiv.dualMap_symm {f : M₁ ≃ₗ[R] M₂} :
    (LinearEquiv.dualMap f).symm = LinearEquiv.dualMap f.symm 
goal: f.dualMap.symm = f.symm.dualMap

full_name: LinearEquiv.dualMap_trans
code: theorem LinearEquiv.dualMap_trans {M₃ : Type*} [AddCommGroup M₃] [Module R M₃] (f : M₁ ≃ₗ[R] M₂)
    (g : M₂ ≃ₗ[R] M₃) : g.dualMap.trans f.dualMap = (f.trans g).dualMap 
goal: g.dualMap ≪≫ₗ f.dualMap = (f ≪≫ₗ g).dualMap

full_name: Dual.apply_one_mul_eq
code: @[simp]
lemma Dual.apply_one_mul_eq (f : Dual R R) (r : R) :
    f 1 * r = f r 
goal: f 1 * r = f r

full_name: LinearMap.range_dualMap_dual_eq_span_singleton
code: @[simp]
lemma LinearMap.range_dualMap_dual_eq_span_singleton (f : Dual R M₁) :
    range f.dualMap = R ∙ f 
goal: LinearMap.range (LinearMap.dualMap f) = Submodule.span R {f}

full_name: Basis.toDual
code: /-- The linear map from a vector space equipped with basis to its dual vector space,
taking basis elements to corresponding dual basis elements. -/
def toDual : M →ₗ[R] Module.Dual R M 
goal: M →ₗ[R] Module.Dual R M

full_name: Basis.toDual_apply
code: theorem toDual_apply (i j : ι) : b.toDual (b i) (b j) = if i = j then 1 else 0 
goal: (b.toDual (b i)) (b j) = if i = j then 1 else 0

full_name: Basis.toDual_total_left
code: @[simp]
theorem toDual_total_left (f : ι →₀ R) (i : ι) :
    b.toDual (Finsupp.total ι M R b f) (b i) = f i 
goal: (b.toDual ((Finsupp.total ι M R ⇑b) f)) (b i) = f i

full_name: Basis.toDual_total_right
code: @[simp]
theorem toDual_total_right (f : ι →₀ R) (i : ι) :
    b.toDual (b i) (Finsupp.total ι M R b f) = f i 
goal: (b.toDual (b i)) ((Finsupp.total ι M R ⇑b) f) = f i

full_name: Basis.toDual_apply_left
code: theorem toDual_apply_left (m : M) (i : ι) : b.toDual m (b i) = b.repr m i 
goal: (b.toDual m) (b i) = (b.repr m) i

full_name: Basis.toDual_apply_right
code: theorem toDual_apply_right (i : ι) (m : M) : b.toDual (b i) m = b.repr m i 
goal: (b.toDual (b i)) m = (b.repr m) i

full_name: Basis.coe_toDual_self
code: theorem coe_toDual_self (i : ι) : b.toDual (b i) = b.coord i 
goal: b.toDual (b i) = b.coord i

full_name: Basis.toDualFlip
code: /-- `h.toDual_flip v` is the linear map sending `w` to `h.toDual w v`. -/
def toDualFlip (m : M) : M →ₗ[R] R 
goal: M →ₗ[R] R

full_name: Basis.toDualFlip_apply
code: theorem toDualFlip_apply (m₁ m₂ : M) : b.toDualFlip m₁ m₂ = b.toDual m₂ m₁ 
goal: (b.toDualFlip m₁) m₂ = (b.toDual m₂) m₁

full_name: Basis.toDual_eq_repr
code: theorem toDual_eq_repr (m : M) (i : ι) : b.toDual m (b i) = b.repr m i 
goal: (b.toDual m) (b i) = (b.repr m) i

full_name: Basis.toDual_eq_equivFun
code: theorem toDual_eq_equivFun [Finite ι] (m : M) (i : ι) : b.toDual m (b i) = b.equivFun m i 
goal: (b.toDual m) (b i) = b.equivFun m i

full_name: Basis.toDual_injective
code: theorem toDual_injective : Injective b.toDual 
goal: Function.Injective ⇑b.toDual

full_name: Basis.toDual_inj
code: theorem toDual_inj (m : M) (a : b.toDual m = 0) : m = 0 
goal: m = 0

full_name: Basis.toDual_ker
code: theorem toDual_ker : LinearMap.ker b.toDual = ⊥ 
goal: LinearMap.ker b.toDual = ⊥

full_name: Basis.toDual_range
code: theorem toDual_range [Finite ι] : LinearMap.range b.toDual = ⊤ 
goal: LinearMap.range b.toDual = ⊤

full_name: Basis.sum_dual_apply_smul_coord
code: @[simp]
theorem sum_dual_apply_smul_coord (f : Module.Dual R M) :
    (∑ x, f (b x) • b.coord x) = f 
goal: ∑ x : ι, f (b x) • b.coord x = f

full_name: Basis.toDualEquiv
code: /-- A vector space is linearly equivalent to its dual space. -/
def toDualEquiv : M ≃ₗ[R] Dual R M 
goal: M ≃ₗ[R] Module.Dual R M

full_name: Basis.toDualEquiv_apply
code: @[simp]
theorem toDualEquiv_apply (m : M) : b.toDualEquiv m = b.toDual m 
goal: b.toDualEquiv m = b.toDual m

full_name: Basis.linearEquiv_dual_iff_finiteDimensional
code: /-- A vector space over a field is isomorphic to its dual if and only if it is finite-dimensional:
  a consequence of the Erdős-Kaplansky theorem. -/
theorem linearEquiv_dual_iff_finiteDimensional [Field K] [AddCommGroup V] [Module K V] :
    Nonempty (V ≃ₗ[K] Dual K V) ↔ FiniteDimensional K V 
goal: Nonempty (V ≃ₗ[K] Module.Dual K V) ↔ FiniteDimensional K V

full_name: Basis.dualBasis
code: /-- Maps a basis for `V` to a basis for the dual space. -/
def dualBasis : Basis ι R (Dual R M) 
goal: Basis ι R (Module.Dual R M)

full_name: Basis.dualBasis_apply_self
code: theorem dualBasis_apply_self (i j : ι) : b.dualBasis i (b j) =
    if j = i then 1 else 0 
goal: (b.dualBasis i) (b j) = if j = i then 1 else 0

full_name: Basis.total_dualBasis
code: theorem total_dualBasis (f : ι →₀ R) (i : ι) :
    Finsupp.total ι (Dual R M) R b.dualBasis f (b i) = f i 
goal: ((Finsupp.total ι (Module.Dual R M) R ⇑b.dualBasis) f) (b i) = f i

full_name: Basis.dualBasis_repr
code: theorem dualBasis_repr (l : Dual R M) (i : ι) : b.dualBasis.repr l i = l (b i) 
goal: (b.dualBasis.repr l) i = l (b i)

full_name: Basis.dualBasis_apply
code: theorem dualBasis_apply (i : ι) (m : M) : b.dualBasis i m = b.repr m i 
goal: (b.dualBasis i) m = (b.repr m) i

full_name: Basis.coe_dualBasis
code: @[simp]
theorem coe_dualBasis : ⇑b.dualBasis = b.coord 
goal: ⇑b.dualBasis = b.coord

full_name: Basis.toDual_toDual
code: @[simp]
theorem toDual_toDual : b.dualBasis.toDual.comp b.toDual = Dual.eval R M 
goal: b.dualBasis.toDual ∘ₗ b.toDual = Module.Dual.eval R M

full_name: Basis.dualBasis_equivFun
code: theorem dualBasis_equivFun [Finite ι] (l : Dual R M) (i : ι) :
    b.dualBasis.equivFun l i = l (b i) 
goal: b.dualBasis.equivFun l i = l (b i)

full_name: Basis.eval_ker
code: theorem eval_ker {ι : Type*} (b : Basis ι R M) :
    LinearMap.ker (Dual.eval R M) = ⊥ 
goal: LinearMap.ker (Module.Dual.eval R M) = ⊥

full_name: Basis.eval_range
code: theorem eval_range {ι : Type*} [Finite ι] (b : Basis ι R M) :
    LinearMap.range (Dual.eval R M) = ⊤ 
goal: LinearMap.range (Module.Dual.eval R M) = ⊤

full_name: Basis.dual_free
code: instance dual_free : Free R (Dual R M) 
goal: Module.Free R (Module.Dual R M)

full_name: Basis.dual_finite
code: instance dual_finite : Finite R (Dual R M) 
goal: Module.Finite R (Module.Dual R M)

full_name: Basis.total_coord
code: /-- `simp` normal form version of `total_dualBasis` -/
@[simp]
theorem total_coord [CommRing R] [AddCommGroup M] [Module R M] [Finite ι] (b : Basis ι R M)
    (f : ι →₀ R) (i : ι) : Finsupp.total ι (Dual R M) R b.coord f (b i) = f i 
goal: ((Finsupp.total ι (Module.Dual R M) R b.coord) f) (b i) = f i

full_name: Basis.dual_rank_eq
code: theorem dual_rank_eq [CommRing K] [AddCommGroup V] [Module K V] [Finite ι] (b : Basis ι K V) :
    Cardinal.lift.{uK,uV} (Module.rank K V) = Module.rank K (Dual K V) 
goal: Cardinal.lift.{uK, uV} (Module.rank K V) = Module.rank K (Module.Dual K V)

full_name: Module.eval_ker
code: theorem eval_ker : LinearMap.ker (eval K V) = ⊥ 
goal: LinearMap.ker (Module.Dual.eval K V) = ⊥

full_name: Module.map_eval_injective
code: theorem map_eval_injective : (Submodule.map (eval K V)).Injective 
goal: Function.Injective (Submodule.map (Module.Dual.eval K V))

full_name: Module.comap_eval_surjective
code: theorem comap_eval_surjective : (Submodule.comap (eval K V)).Surjective 
goal: Function.Surjective (Submodule.comap (Module.Dual.eval K V))

full_name: Module.eval_apply_eq_zero_iff
code: theorem eval_apply_eq_zero_iff (v : V) : (eval K V) v = 0 ↔ v = 0 
goal: (Module.Dual.eval K V) v = 0 ↔ v = 0

full_name: Module.eval_apply_injective
code: theorem eval_apply_injective : Function.Injective (eval K V) 
goal: Function.Injective ⇑(Module.Dual.eval K V)

full_name: Module.forall_dual_apply_eq_zero_iff
code: theorem forall_dual_apply_eq_zero_iff (v : V) : (∀ φ : Module.Dual K V, φ v = 0) ↔ v = 0 
goal: (∀ (φ : Module.Dual K V), φ v = 0) ↔ v = 0

full_name: Module.subsingleton_dual_iff
code: @[simp]
theorem subsingleton_dual_iff :
    Subsingleton (Dual K V) ↔ Subsingleton V 
goal: Subsingleton (Module.Dual K V) ↔ Subsingleton V

full_name: Module.instSubsingletonDual
code: instance instSubsingletonDual [Subsingleton V] : Subsingleton (Dual K V) 
goal: Subsingleton (Module.Dual K V)

full_name: Module.nontrivial_dual_iff
code: @[simp]
theorem nontrivial_dual_iff :
    Nontrivial (Dual K V) ↔ Nontrivial V 
goal: Nontrivial (Module.Dual K V) ↔ Nontrivial V

full_name: Module.instNontrivialDual
code: instance instNontrivialDual [Nontrivial V] : Nontrivial (Dual K V) 
goal: Nontrivial (Module.Dual K V)

full_name: Module.finite_dual_iff
code: theorem finite_dual_iff : Finite K (Dual K V) ↔ Finite K V 
goal: Module.Finite K (Module.Dual K V) ↔ Module.Finite K V

full_name: Module.dual_rank_eq
code: theorem dual_rank_eq [Module.Finite K V] :
    Cardinal.lift.{uK,uV} (Module.rank K V) = Module.rank K (Dual K V) 
goal: Cardinal.lift.{uK, uV} (Module.rank K V) = Module.rank K (Module.Dual K V)

full_name: Module.erange_coe
code: theorem erange_coe [Module.Finite K V] : LinearMap.range (eval K V) = ⊤ 
goal: LinearMap.range (Module.Dual.eval K V) = ⊤

full_name: Module.IsReflexive
code: /-- A reflexive module is one for which the natural map to its double dual is a bijection.

Any finitely-generated free module (and thus any finite-dimensional vector space) is reflexive.
See `Module.IsReflexive.of_finite_of_free`. -/
class IsReflexive : Prop where
  /-- A reflexive module is one for which the natural map to its double dual is a bijection. -/
  bijective_dual_eval' : Bijective (Dual.eval R M)
goal: Prop

full_name: Module.IsReflexive.bijective_dual_eval'
code: /-- A reflexive module is one for which the natural map to its double dual is a bijection.

Any finitely-generated free module (and thus any finite-dimensional vector space) is reflexive.
See `Module.IsReflexive.of_finite_of_free`. -/
class IsReflexive : Prop where
  /-- A reflexive module is one for which the natural map to its double dual is a bijection. -/
  bijective_dual_eval' : Bijective (Dual.eval R M)
goal: Function.Bijective ⇑(Module.Dual.eval R M)

full_name: Module.bijective_dual_eval
code: lemma bijective_dual_eval [IsReflexive R M] : Bijective (Dual.eval R M) 
goal: Function.Bijective ⇑(Module.Dual.eval R M)

full_name: Module.IsReflexive.of_finite_of_free
code: instance IsReflexive.of_finite_of_free [Finite R M] [Free R M] : IsReflexive R M 
goal: Module.IsReflexive R M

full_name: Module.evalEquiv
code: /-- The bijection between a reflexive module and its double dual, bundled as a `LinearEquiv`. -/
def evalEquiv : M ≃ₗ[R] Dual R (Dual R M) 
goal: M ≃ₗ[R] Module.Dual R (Module.Dual R M)

full_name: Module.evalEquiv_toLinearMap
code: @[simp] lemma evalEquiv_toLinearMap : evalEquiv R M = Dual.eval R M 
goal: ↑(Module.evalEquiv R M) = Module.Dual.eval R M

full_name: Module.evalEquiv_apply
code: @[simp] lemma evalEquiv_apply (m : M) : evalEquiv R M m = Dual.eval R M m 
goal: (Module.evalEquiv R M) m = (Module.Dual.eval R M) m

full_name: Module.apply_evalEquiv_symm_apply
code: @[simp] lemma apply_evalEquiv_symm_apply (f : Dual R M) (g : Dual R (Dual R M)) :
    f ((evalEquiv R M).symm g) = g f 
goal: f ((Module.evalEquiv R M).symm g) = g f

full_name: Module.symm_dualMap_evalEquiv
code: @[simp] lemma symm_dualMap_evalEquiv :
    (evalEquiv R M).symm.dualMap = Dual.eval R (Dual R M) 
goal: ↑(Module.evalEquiv R M).symm.dualMap = Module.Dual.eval R (Module.Dual R M)

full_name: Module.Dual.instIsReflecive
code: /-- The dual of a reflexive module is reflexive. -/
instance Dual.instIsReflecive : IsReflexive R (Dual R M) 
goal: Module.IsReflexive R (Module.Dual R M)

full_name: Module.mapEvalEquiv
code: /-- The isomorphism `Module.evalEquiv` induces an order isomorphism on subspaces. -/
def mapEvalEquiv : Submodule R M ≃o Submodule R (Dual R (Dual R M)) 
goal: Submodule R M ≃o Submodule R (Module.Dual R (Module.Dual R M))

full_name: Module.mapEvalEquiv_apply
code: @[simp]
theorem mapEvalEquiv_apply (W : Submodule R M) :
    mapEvalEquiv R M W = W.map (Dual.eval R M) 
goal: (Module.mapEvalEquiv R M) W = Submodule.map (Module.Dual.eval R M) W

full_name: Module.mapEvalEquiv_symm_apply
code: @[simp]
theorem mapEvalEquiv_symm_apply (W'' : Submodule R (Dual R (Dual R M))) :
    (mapEvalEquiv R M).symm W'' = W''.comap (Dual.eval R M) 
goal: (Module.mapEvalEquiv R M).symm W'' = Submodule.comap (Module.Dual.eval R M) W''

full_name: Prod.instModuleIsReflexive
code: instance _root_.Prod.instModuleIsReflexive [IsReflexive R N] :
    IsReflexive R (M × N) 
goal: Module.IsReflexive R (M × N)

full_name: Module.equiv
code: lemma equiv (e : M ≃ₗ[R] N) : IsReflexive R N 
goal: Module.IsReflexive R N

full_name: MulOpposite.instModuleIsReflexive
code: instance _root_.MulOpposite.instModuleIsReflexive : IsReflexive R (MulOpposite M) 
goal: Module.IsReflexive R Mᵐᵒᵖ

full_name: ULift.instModuleIsReflexive
code: instance _root_.ULift.instModuleIsReflexive.{w} : IsReflexive R (ULift.{w} M) 
goal: Module.IsReflexive R (ULift.{w, u_2} M)

full_name: Submodule.exists_dual_map_eq_bot_of_nmem
code: theorem exists_dual_map_eq_bot_of_nmem {x : M} (hx : x ∉ p) (hp' : Free R (M ⧸ p)) :
    ∃ f : Dual R M, f x ≠ 0 ∧ p.map f = ⊥ 
goal: ∃ f, f x ≠ 0 ∧ Submodule.map f p = ⊥

full_name: Submodule.exists_dual_map_eq_bot_of_lt_top
code: theorem exists_dual_map_eq_bot_of_lt_top (hp : p < ⊤) (hp' : Free R (M ⧸ p)) :
    ∃ f : Dual R M, f ≠ 0 ∧ p.map f = ⊥ 
goal: ∃ f, f ≠ 0 ∧ Submodule.map f p = ⊥

full_name: evalUseFiniteInstance
code: /-- Try using `Set.toFinite` to dispatch a `Set.Finite` goal. -/
def evalUseFiniteInstance : TacticM Unit 
goal: Lean.Elab.Tactic.TacticM Unit

full_name: tacticUse_finite_instance
code: elab "use_finite_instance" : tactic => evalUseFiniteInstance
goal: Lean.ParserDescr

full_name: _aux_Mathlib_LinearAlgebra_Dual___elabRules_tacticUse_finite_instance_1
code: elab "use_finite_instance" : tactic => evalUseFiniteInstance
goal: Lean.Elab.Tactic.Tactic

full_name: Module.DualBases
code: /-- `e` and `ε` have characteristic properties of a basis and its dual -/
-- @[nolint has_nonempty_instance] Porting note (#5171): removed
structure Module.DualBases (e : ι → M) (ε : ι → Dual R M) : Prop where
  eval : ∀ i j : ι, ε i (e j) = if i = j then 1 else 0
  protected total : ∀ {m : M}, (∀ i, ε i m = 0) → m = 0
  protected finite : ∀ m : M, { i | ε i m ≠ 0 }.Finite := by
      use_finite_instance
goal: Prop

full_name: Module.DualBases.total
code: /-- `e` and `ε` have characteristic properties of a basis and its dual -/
-- @[nolint has_nonempty_instance] Porting note (#5171): removed
structure Module.DualBases (e : ι → M) (ε : ι → Dual R M) : Prop where
  eval : ∀ i j : ι, ε i (e j) = if i = j then 1 else 0
  protected total : ∀ {m : M}, (∀ i, ε i m = 0) → m = 0
  protected finite : ∀ m : M, { i | ε i m ≠ 0 }.Finite := by
      use_finite_instance
goal: (∀ (i : ι), (ε i) m = 0) → m = 0

full_name: Module.DualBases.eval
code: /-- `e` and `ε` have characteristic properties of a basis and its dual -/
-- @[nolint has_nonempty_instance] Porting note (#5171): removed
structure Module.DualBases (e : ι → M) (ε : ι → Dual R M) : Prop where
  eval : ∀ i j : ι, ε i (e j) = if i = j then 1 else 0
  protected total : ∀ {m : M}, (∀ i, ε i m = 0) → m = 0
  protected finite : ∀ m : M, { i | ε i m ≠ 0 }.Finite := by
      use_finite_instance
goal: (ε i) (e j) = if i = j then 1 else 0

full_name: Module.DualBases.finite
code: /-- `e` and `ε` have characteristic properties of a basis and its dual -/
-- @[nolint has_nonempty_instance] Porting note (#5171): removed
structure Module.DualBases (e : ι → M) (ε : ι → Dual R M) : Prop where
  eval : ∀ i j : ι, ε i (e j) = if i = j then 1 else 0
  protected total : ∀ {m : M}, (∀ i, ε i m = 0) → m = 0
  protected finite : ∀ m : M, { i | ε i m ≠ 0 }.Finite := by
      use_finite_instance
goal: {i | (ε i) m ≠ 0}.Finite

full_name: Module.DualBases.coeffs
code: /-- The coefficients of `v` on the basis `e` -/
def coeffs [DecidableEq ι] (h : DualBases e ε) (m : M) : ι →₀ R 
goal: ι →₀ R

full_name: Module.DualBases.coeffs_apply
code: @[simp]
theorem coeffs_apply [DecidableEq ι] (h : DualBases e ε) (m : M) (i : ι) : h.coeffs m i = ε i m 
goal: (h.coeffs m) i = (ε i) m

full_name: Module.DualBases.lc
code: /-- linear combinations of elements of `e`.
This is a convenient abbreviation for `Finsupp.total _ M R e l` -/
def lc {ι} (e : ι → M) (l : ι →₀ R) : M 
goal: M

full_name: Module.DualBases.lc_def
code: theorem lc_def (e : ι → M) (l : ι →₀ R) : lc e l = Finsupp.total _ _ R e l 
goal: Module.DualBases.lc e l = (Finsupp.total ι M R e) l

full_name: Module.DualBases.dual_lc
code: theorem dual_lc (l : ι →₀ R) (i : ι) : ε i (DualBases.lc e l) = l i 
goal: (ε i) (Module.DualBases.lc e l) = l i

full_name: Module.DualBases.coeffs_lc
code: @[simp]
theorem coeffs_lc (l : ι →₀ R) : h.coeffs (DualBases.lc e l) = l 
goal: h.coeffs (Module.DualBases.lc e l) = l

full_name: Module.DualBases.lc_coeffs
code: /-- For any m : M n, \sum_{p ∈ Q n} (ε p m) • e p = m -/
@[simp]
theorem lc_coeffs (m : M) : DualBases.lc e (h.coeffs m) = m 
goal: Module.DualBases.lc e (h.coeffs m) = m

full_name: Module.DualBases.basis
code: /-- `(h : DualBases e ε).basis` shows the family of vectors `e` forms a basis. -/
@[simps]
def basis : Basis ι R M 
goal: Basis ι R M

full_name: Module.DualBases.basis_repr_apply
code: /-- `(h : DualBases e ε).basis` shows the family of vectors `e` forms a basis. -/
@[simps]
def basis : Basis ι R M 
goal: h.basis.repr m = h.coeffs m

full_name: Module.DualBases.basis_repr_symm_apply
code: /-- `(h : DualBases e ε).basis` shows the family of vectors `e` forms a basis. -/
@[simps]
def basis : Basis ι R M 
goal: h.basis.repr.symm l = Module.DualBases.lc e l

full_name: Module.DualBases.coe_basis
code: @[simp]
theorem coe_basis : ⇑h.basis = e 
goal: ⇑h.basis = e

full_name: Module.DualBases.mem_of_mem_span
code: theorem mem_of_mem_span {H : Set ι} {x : M} (hmem : x ∈ Submodule.span R (e '' H)) :
    ∀ i : ι, ε i x ≠ 0 → i ∈ H 
goal: (ε i) x ≠ 0 → i ∈ H

full_name: Module.DualBases.coe_dualBasis
code: theorem coe_dualBasis [_root_.Finite ι] : ⇑h.basis.dualBasis = ε 
goal: ⇑h.basis.dualBasis = ε

full_name: Submodule.dualRestrict
code: /-- The `dualRestrict` of a submodule `W` of `M` is the linear map from the
  dual of `M` to the dual of `W` such that the domain of each linear map is
  restricted to `W`. -/
def dualRestrict (W : Submodule R M) : Module.Dual R M →ₗ[R] Module.Dual R W 
goal: Module.Dual R M →ₗ[R] Module.Dual R ↥W

full_name: Submodule.dualRestrict_def
code: theorem dualRestrict_def (W : Submodule R M) : W.dualRestrict = W.subtype.dualMap 
goal: W.dualRestrict = W.subtype.dualMap

full_name: Submodule.dualRestrict_apply
code: @[simp]
theorem dualRestrict_apply (W : Submodule R M) (φ : Module.Dual R M) (x : W) :
    W.dualRestrict φ x = φ (x : M) 
goal: (W.dualRestrict φ) x = φ ↑x

full_name: Submodule.dualAnnihilator
code: /-- The `dualAnnihilator` of a submodule `W` is the set of linear maps `φ` such
  that `φ w = 0` for all `w ∈ W`. -/
def dualAnnihilator {R : Type u} {M : Type v} [CommSemiring R] [AddCommMonoid M] [Module R M]
    (W : Submodule R M) : Submodule R <| Module.Dual R M 
goal: Submodule R (Module.Dual R M)

full_name: Submodule.mem_dualAnnihilator
code: @[simp]
theorem mem_dualAnnihilator (φ : Module.Dual R M) : φ ∈ W.dualAnnihilator ↔ ∀ w ∈ W, φ w = 0 
goal: φ ∈ W.dualAnnihilator ↔ ∀ w ∈ W, φ w = 0

full_name: Submodule.dualRestrict_ker_eq_dualAnnihilator
code: /-- That $\operatorname{ker}(\iota^* : V^* \to W^*) = \operatorname{ann}(W)$.
This is the definition of the dual annihilator of the submodule $W$. -/
theorem dualRestrict_ker_eq_dualAnnihilator (W : Submodule R M) :
    -- Porting note (#11036): broken dot notation lean4#1910 LinearMap.ker
    LinearMap.ker W.dualRestrict = W.dualAnnihilator 
goal: LinearMap.ker W.dualRestrict = W.dualAnnihilator

full_name: Submodule.dualCoannihilator
code: /-- The `dualAnnihilator` of a submodule of the dual space pulled back along the evaluation map
`Module.Dual.eval`. -/
def dualCoannihilator (Φ : Submodule R (Module.Dual R M)) : Submodule R M 
goal: Submodule R M

full_name: Submodule.mem_dualCoannihilator
code: @[simp]
theorem mem_dualCoannihilator {Φ : Submodule R (Module.Dual R M)} (x : M) :
    x ∈ Φ.dualCoannihilator ↔ ∀ φ ∈ Φ, (φ x : R) = 0 
goal: x ∈ Φ.dualCoannihilator ↔ ∀ φ ∈ Φ, φ x = 0

full_name: Submodule.comap_dualAnnihilator
code: theorem comap_dualAnnihilator (Φ : Submodule R (Module.Dual R M)) :
    Φ.dualAnnihilator.comap (Module.Dual.eval R M) = Φ.dualCoannihilator 
goal: Submodule.comap (Module.Dual.eval R M) Φ.dualAnnihilator = Φ.dualCoannihilator

full_name: Submodule.map_dualCoannihilator_le
code: theorem map_dualCoannihilator_le (Φ : Submodule R (Module.Dual R M)) :
    Φ.dualCoannihilator.map (Module.Dual.eval R M) ≤ Φ.dualAnnihilator 
goal: Submodule.map (Module.Dual.eval R M) Φ.dualCoannihilator ≤ Φ.dualAnnihilator

full_name: Submodule.dualAnnihilator_gc
code: theorem dualAnnihilator_gc :
    GaloisConnection
      (OrderDual.toDual ∘ (dualAnnihilator : Submodule R M → Submodule R (Module.Dual R M)))
      (dualCoannihilator ∘ OrderDual.ofDual) 
goal: GaloisConnection (⇑OrderDual.toDual ∘ Submodule.dualAnnihilator) (Submodule.dualCoannihilator ∘ ⇑OrderDual.ofDual)

full_name: Submodule.le_dualAnnihilator_iff_le_dualCoannihilator
code: theorem le_dualAnnihilator_iff_le_dualCoannihilator {U : Submodule R (Module.Dual R M)}
    {V : Submodule R M} : U ≤ V.dualAnnihilator ↔ V ≤ U.dualCoannihilator 
goal: U ≤ V.dualAnnihilator ↔ V ≤ U.dualCoannihilator

full_name: Submodule.dualAnnihilator_bot
code: @[simp]
theorem dualAnnihilator_bot : (⊥ : Submodule R M).dualAnnihilator = ⊤ 
goal: ⊥.dualAnnihilator = ⊤

full_name: Submodule.dualAnnihilator_top
code: @[simp]
theorem dualAnnihilator_top : (⊤ : Submodule R M).dualAnnihilator = ⊥ 
goal: ⊤.dualAnnihilator = ⊥

full_name: Submodule.dualCoannihilator_bot
code: @[simp]
theorem dualCoannihilator_bot : (⊥ : Submodule R (Module.Dual R M)).dualCoannihilator = ⊤ 
goal: ⊥.dualCoannihilator = ⊤

full_name: Submodule.dualAnnihilator_anti
code: @[mono]
theorem dualAnnihilator_anti {U V : Submodule R M} (hUV : U ≤ V) :
    V.dualAnnihilator ≤ U.dualAnnihilator 
goal: V.dualAnnihilator ≤ U.dualAnnihilator

full_name: Submodule.dualCoannihilator_anti
code: @[mono]
theorem dualCoannihilator_anti {U V : Submodule R (Module.Dual R M)} (hUV : U ≤ V) :
    V.dualCoannihilator ≤ U.dualCoannihilator 
goal: V.dualCoannihilator ≤ U.dualCoannihilator

full_name: Submodule.le_dualAnnihilator_dualCoannihilator
code: theorem le_dualAnnihilator_dualCoannihilator (U : Submodule R M) :
    U ≤ U.dualAnnihilator.dualCoannihilator 
goal: U ≤ U.dualAnnihilator.dualCoannihilator

full_name: Submodule.le_dualCoannihilator_dualAnnihilator
code: theorem le_dualCoannihilator_dualAnnihilator (U : Submodule R (Module.Dual R M)) :
    U ≤ U.dualCoannihilator.dualAnnihilator 
goal: U ≤ U.dualCoannihilator.dualAnnihilator

full_name: Submodule.dualAnnihilator_dualCoannihilator_dualAnnihilator
code: theorem dualAnnihilator_dualCoannihilator_dualAnnihilator (U : Submodule R M) :
    U.dualAnnihilator.dualCoannihilator.dualAnnihilator = U.dualAnnihilator 
goal: U.dualAnnihilator.dualCoannihilator.dualAnnihilator = U.dualAnnihilator

full_name: Submodule.dualCoannihilator_dualAnnihilator_dualCoannihilator
code: theorem dualCoannihilator_dualAnnihilator_dualCoannihilator (U : Submodule R (Module.Dual R M)) :
    U.dualCoannihilator.dualAnnihilator.dualCoannihilator = U.dualCoannihilator 
goal: U.dualCoannihilator.dualAnnihilator.dualCoannihilator = U.dualCoannihilator

full_name: Submodule.dualAnnihilator_sup_eq
code: theorem dualAnnihilator_sup_eq (U V : Submodule R M) :
    (U ⊔ V).dualAnnihilator = U.dualAnnihilator ⊓ V.dualAnnihilator 
goal: (U ⊔ V).dualAnnihilator = U.dualAnnihilator ⊓ V.dualAnnihilator

full_name: Submodule.dualCoannihilator_sup_eq
code: theorem dualCoannihilator_sup_eq (U V : Submodule R (Module.Dual R M)) :
    (U ⊔ V).dualCoannihilator = U.dualCoannihilator ⊓ V.dualCoannihilator 
goal: (U ⊔ V).dualCoannihilator = U.dualCoannihilator ⊓ V.dualCoannihilator

full_name: Submodule.dualAnnihilator_iSup_eq
code: theorem dualAnnihilator_iSup_eq {ι : Sort*} (U : ι → Submodule R M) :
    (⨆ i : ι, U i).dualAnnihilator = ⨅ i : ι, (U i).dualAnnihilator 
goal: (⨆ i, U i).dualAnnihilator = ⨅ i, (U i).dualAnnihilator

full_name: Submodule.dualCoannihilator_iSup_eq
code: theorem dualCoannihilator_iSup_eq {ι : Sort*} (U : ι → Submodule R (Module.Dual R M)) :
    (⨆ i : ι, U i).dualCoannihilator = ⨅ i : ι, (U i).dualCoannihilator 
goal: (⨆ i, U i).dualCoannihilator = ⨅ i, (U i).dualCoannihilator

full_name: Submodule.sup_dualAnnihilator_le_inf
code: /-- See also `Subspace.dualAnnihilator_inf_eq` for vector subspaces. -/
theorem sup_dualAnnihilator_le_inf (U V : Submodule R M) :
    U.dualAnnihilator ⊔ V.dualAnnihilator ≤ (U ⊓ V).dualAnnihilator 
goal: U.dualAnnihilator ⊔ V.dualAnnihilator ≤ (U ⊓ V).dualAnnihilator

full_name: Submodule.iSup_dualAnnihilator_le_iInf
code: /-- See also `Subspace.dualAnnihilator_iInf_eq` for vector subspaces when `ι` is finite. -/
theorem iSup_dualAnnihilator_le_iInf {ι : Sort*} (U : ι → Submodule R M) :
    ⨆ i : ι, (U i).dualAnnihilator ≤ (⨅ i : ι, U i).dualAnnihilator 
goal: ⨆ i, (U i).dualAnnihilator ≤ (⨅ i, U i).dualAnnihilator

full_name: Subspace.dualCoannihilator_top
code: @[simp]
theorem dualCoannihilator_top (W : Subspace K V) :
    (⊤ : Subspace K (Module.Dual K W)).dualCoannihilator = ⊥ 
goal: Submodule.dualCoannihilator ⊤ = ⊥

full_name: Subspace.dualAnnihilator_dualCoannihilator_eq
code: @[simp]
theorem dualAnnihilator_dualCoannihilator_eq {W : Subspace K V} :
    W.dualAnnihilator.dualCoannihilator = W 
goal: (Submodule.dualAnnihilator W).dualCoannihilator = W

full_name: Subspace.forall_mem_dualAnnihilator_apply_eq_zero_iff
code: theorem forall_mem_dualAnnihilator_apply_eq_zero_iff (W : Subspace K V) (v : V) :
    (∀ φ : Module.Dual K V, φ ∈ W.dualAnnihilator → φ v = 0) ↔ v ∈ W 
goal: (∀ φ ∈ Submodule.dualAnnihilator W, φ v = 0) ↔ v ∈ W

full_name: Subspace.comap_dualAnnihilator_dualAnnihilator
code: theorem comap_dualAnnihilator_dualAnnihilator (W : Subspace K V) :
    W.dualAnnihilator.dualAnnihilator.comap (Module.Dual.eval K V) = W 
goal: Submodule.comap (Module.Dual.eval K V) (Submodule.dualAnnihilator W).dualAnnihilator = W

full_name: Subspace.map_le_dualAnnihilator_dualAnnihilator
code: theorem map_le_dualAnnihilator_dualAnnihilator (W : Subspace K V) :
    W.map (Module.Dual.eval K V) ≤ W.dualAnnihilator.dualAnnihilator 
goal: Submodule.map (Module.Dual.eval K V) W ≤ (Submodule.dualAnnihilator W).dualAnnihilator

full_name: Subspace.dualAnnihilatorGci
code: /-- `Submodule.dualAnnihilator` and `Submodule.dualCoannihilator` form a Galois coinsertion. -/
def dualAnnihilatorGci (K V : Type*) [Field K] [AddCommGroup V] [Module K V] :
    GaloisCoinsertion
      (OrderDual.toDual ∘ (dualAnnihilator : Subspace K V → Subspace K (Module.Dual K V)))
      (dualCoannihilator ∘ OrderDual.ofDual) 
goal: GaloisCoinsertion (⇑OrderDual.toDual ∘ Submodule.dualAnnihilator) (Submodule.dualCoannihilator ∘ ⇑OrderDual.ofDual)

full_name: Subspace.dualAnnihilator_le_dualAnnihilator_iff
code: theorem dualAnnihilator_le_dualAnnihilator_iff {W W' : Subspace K V} :
    W.dualAnnihilator ≤ W'.dualAnnihilator ↔ W' ≤ W 
goal: Submodule.dualAnnihilator W ≤ Submodule.dualAnnihilator W' ↔ W' ≤ W

full_name: Subspace.dualAnnihilator_inj
code: theorem dualAnnihilator_inj {W W' : Subspace K V} :
    W.dualAnnihilator = W'.dualAnnihilator ↔ W = W' 
goal: Submodule.dualAnnihilator W = Submodule.dualAnnihilator W' ↔ W = W'

full_name: Subspace.dualLift
code: /-- Given a subspace `W` of `V` and an element of its dual `φ`, `dualLift W φ` is
an arbitrary extension of `φ` to an element of the dual of `V`.
That is, `dualLift W φ` sends `w ∈ W` to `φ x` and `x` in a chosen complement of `W` to `0`. -/
noncomputable def dualLift (W : Subspace K V) : Module.Dual K W →ₗ[K] Module.Dual K V 
goal: Module.Dual K ↥W →ₗ[K] Module.Dual K V

full_name: Subspace.dualLift_of_subtype
code: @[simp]
theorem dualLift_of_subtype {φ : Module.Dual K W} (w : W) : W.dualLift φ (w : V) = φ w 
goal: (W.dualLift φ) ↑w = φ w

full_name: Subspace.dualLift_of_mem
code: theorem dualLift_of_mem {φ : Module.Dual K W} {w : V} (hw : w ∈ W) : W.dualLift φ w = φ ⟨w, hw⟩ 
goal: (W.dualLift φ) w = φ ⟨w, hw⟩

full_name: Subspace.dualRestrict_comp_dualLift
code: @[simp]
theorem dualRestrict_comp_dualLift (W : Subspace K V) : W.dualRestrict.comp W.dualLift = 1 
goal: Submodule.dualRestrict W ∘ₗ W.dualLift = 1

full_name: Subspace.dualRestrict_leftInverse
code: theorem dualRestrict_leftInverse (W : Subspace K V) :
    Function.LeftInverse W.dualRestrict W.dualLift 
goal: Function.LeftInverse ⇑(Submodule.dualRestrict W) ⇑W.dualLift

full_name: Subspace.dualLift_rightInverse
code: theorem dualLift_rightInverse (W : Subspace K V) :
    Function.RightInverse W.dualLift W.dualRestrict 
goal: Function.RightInverse ⇑W.dualLift ⇑(Submodule.dualRestrict W)

full_name: Subspace.dualRestrict_surjective
code: theorem dualRestrict_surjective : Function.Surjective W.dualRestrict 
goal: Function.Surjective ⇑(Submodule.dualRestrict W)

full_name: Subspace.dualLift_injective
code: theorem dualLift_injective : Function.Injective W.dualLift 
goal: Function.Injective ⇑W.dualLift

full_name: Subspace.quotAnnihilatorEquiv
code: /-- The quotient by the `dualAnnihilator` of a subspace is isomorphic to the
  dual of that subspace. -/
noncomputable def quotAnnihilatorEquiv (W : Subspace K V) :
    (Module.Dual K V ⧸ W.dualAnnihilator) ≃ₗ[K] Module.Dual K W 
goal: (Module.Dual K V ⧸ Submodule.dualAnnihilator W) ≃ₗ[K] Module.Dual K ↥W

full_name: Subspace.quotAnnihilatorEquiv_apply
code: @[simp]
theorem quotAnnihilatorEquiv_apply (W : Subspace K V) (φ : Module.Dual K V) :
    W.quotAnnihilatorEquiv (Submodule.Quotient.mk φ) = W.dualRestrict φ 
goal: W.quotAnnihilatorEquiv (Submodule.Quotient.mk φ) = (Submodule.dualRestrict W) φ

full_name: Subspace.dualEquivDual
code: /-- The natural isomorphism from the dual of a subspace `W` to `W.dualLift.range`. -/
-- Porting note (#11036): broken dot notation lean4#1910 LinearMap.range
noncomputable def dualEquivDual (W : Subspace K V) :
    Module.Dual K W ≃ₗ[K] LinearMap.range W.dualLift 
goal: Module.Dual K ↥W ≃ₗ[K] ↥(LinearMap.range W.dualLift)

full_name: Subspace.dualEquivDual_def
code: theorem dualEquivDual_def (W : Subspace K V) :
    W.dualEquivDual.toLinearMap = W.dualLift.rangeRestrict 
goal: ↑W.dualEquivDual = W.dualLift.rangeRestrict

full_name: Subspace.dualEquivDual_apply
code: @[simp]
theorem dualEquivDual_apply (φ : Module.Dual K W) :
    W.dualEquivDual φ = ⟨W.dualLift φ, mem_range.2 ⟨φ, rfl⟩⟩ 
goal: W.dualEquivDual φ = ⟨W.dualLift φ, ⋯⟩

full_name: Subspace.instModuleDualFiniteDimensional
code: instance instModuleDualFiniteDimensional [FiniteDimensional K V] :
    FiniteDimensional K (Module.Dual K V) 
goal: FiniteDimensional K (Module.Dual K V)

full_name: Subspace.dual_finrank_eq
code: @[simp]
theorem dual_finrank_eq : finrank K (Module.Dual K V) = finrank K V 
goal: FiniteDimensional.finrank K (Module.Dual K V) = FiniteDimensional.finrank K V

full_name: Subspace.dualAnnihilator_dualAnnihilator_eq
code: theorem dualAnnihilator_dualAnnihilator_eq (W : Subspace K V) :
    W.dualAnnihilator.dualAnnihilator = Module.mapEvalEquiv K V W 
goal: (Submodule.dualAnnihilator W).dualAnnihilator = (Module.mapEvalEquiv K V) W

full_name: Subspace.quotDualEquivAnnihilator
code: /-- The quotient by the dual is isomorphic to its dual annihilator.  -/
-- Porting note (#11036): broken dot notation lean4#1910 LinearMap.range
noncomputable def quotDualEquivAnnihilator (W : Subspace K V) :
    (Module.Dual K V ⧸ LinearMap.range W.dualLift) ≃ₗ[K] W.dualAnnihilator 
goal: (Module.Dual K V ⧸ LinearMap.range W.dualLift) ≃ₗ[K] ↥(Submodule.dualAnnihilator W)

full_name: Subspace.quotEquivAnnihilator
code: /-- The quotient by a subspace is isomorphic to its dual annihilator. -/
noncomputable def quotEquivAnnihilator (W : Subspace K V) : (V ⧸ W) ≃ₗ[K] W.dualAnnihilator 
goal: (V ⧸ W) ≃ₗ[K] ↥(Submodule.dualAnnihilator W)

full_name: Subspace.finrank_dualCoannihilator_eq
code: @[simp]
theorem finrank_dualCoannihilator_eq {Φ : Subspace K (Module.Dual K V)} :
    finrank K Φ.dualCoannihilator = finrank K Φ.dualAnnihilator 
goal: FiniteDimensional.finrank K ↥(Submodule.dualCoannihilator Φ) =
  FiniteDimensional.finrank K ↥(Submodule.dualAnnihilator Φ)

full_name: Subspace.finrank_add_finrank_dualCoannihilator_eq
code: theorem finrank_add_finrank_dualCoannihilator_eq (W : Subspace K (Module.Dual K V)) :
    finrank K W + finrank K W.dualCoannihilator = finrank K V 
goal: FiniteDimensional.finrank K ↥W + FiniteDimensional.finrank K ↥(Submodule.dualCoannihilator W) =
  FiniteDimensional.finrank K V

full_name: LinearMap.ker_dualMap_eq_dualAnnihilator_range
code: theorem ker_dualMap_eq_dualAnnihilator_range :
    LinearMap.ker f.dualMap = f.range.dualAnnihilator 
goal: LinearMap.ker f.dualMap = (LinearMap.range f).dualAnnihilator

full_name: LinearMap.range_dualMap_le_dualAnnihilator_ker
code: theorem range_dualMap_le_dualAnnihilator_ker :
    LinearMap.range f.dualMap ≤ f.ker.dualAnnihilator 
goal: LinearMap.range f.dualMap ≤ (LinearMap.ker f).dualAnnihilator

full_name: Submodule.dualCopairing
code: /-- Given a submodule, corestrict to the pairing on `M ⧸ W` by
simultaneously restricting to `W.dualAnnihilator`.

See `Subspace.dualCopairing_nondegenerate`. -/
def dualCopairing (W : Submodule R M) : W.dualAnnihilator →ₗ[R] M ⧸ W →ₗ[R] R 
goal: ↥W.dualAnnihilator →ₗ[R] M ⧸ W →ₗ[R] R

full_name: Submodule.instFunLikeSubtypeDualMemDualAnnihilator
code: instance (W : Submodule R M) : FunLike (W.dualAnnihilator) M R 
goal: FunLike (↥W.dualAnnihilator) M R

full_name: Submodule.dualCopairing_apply
code: @[simp]
theorem dualCopairing_apply {W : Submodule R M} (φ : W.dualAnnihilator) (x : M) :
    W.dualCopairing φ (Quotient.mk x) = φ x 
goal: (W.dualCopairing φ) (Submodule.Quotient.mk x) = φ x

full_name: Submodule.dualPairing
code: /-- Given a submodule, restrict to the pairing on `W` by
simultaneously corestricting to `Module.Dual R M ⧸ W.dualAnnihilator`.
This is `Submodule.dualRestrict` factored through the quotient by its kernel (which
is `W.dualAnnihilator` by definition).

See `Subspace.dualPairing_nondegenerate`. -/
def dualPairing (W : Submodule R M) : Module.Dual R M ⧸ W.dualAnnihilator →ₗ[R] W →ₗ[R] R 
goal: Module.Dual R M ⧸ W.dualAnnihilator →ₗ[R] ↥W →ₗ[R] R

full_name: Submodule.dualPairing_apply
code: @[simp]
theorem dualPairing_apply {W : Submodule R M} (φ : Module.Dual R M) (x : W) :
    W.dualPairing (Quotient.mk φ) x = φ x 
goal: (W.dualPairing (Submodule.Quotient.mk φ)) x = φ ↑x

full_name: Submodule.range_dualMap_mkQ_eq
code: /-- That $\operatorname{im}(q^* : (V/W)^* \to V^*) = \operatorname{ann}(W)$. -/
theorem range_dualMap_mkQ_eq (W : Submodule R M) :
    LinearMap.range W.mkQ.dualMap = W.dualAnnihilator 
goal: LinearMap.range W.mkQ.dualMap = W.dualAnnihilator

full_name: Submodule.dualQuotEquivDualAnnihilator
code: /-- Equivalence $(M/W)^* \cong \operatorname{ann}(W)$. That is, there is a one-to-one
correspondence between the dual of `M ⧸ W` and those elements of the dual of `M` that
vanish on `W`.

The inverse of this is `Submodule.dualCopairing`. -/
def dualQuotEquivDualAnnihilator (W : Submodule R M) :
    Module.Dual R (M ⧸ W) ≃ₗ[R] W.dualAnnihilator 
goal: Module.Dual R (M ⧸ W) ≃ₗ[R] ↥W.dualAnnihilator

full_name: Submodule.dualQuotEquivDualAnnihilator_apply
code: @[simp]
theorem dualQuotEquivDualAnnihilator_apply (W : Submodule R M) (φ : Module.Dual R (M ⧸ W)) (x : M) :
    dualQuotEquivDualAnnihilator W φ x = φ (Quotient.mk x) 
goal: (W.dualQuotEquivDualAnnihilator φ) x = φ (Submodule.Quotient.mk x)

full_name: Submodule.dualCopairing_eq
code: theorem dualCopairing_eq (W : Submodule R M) :
    W.dualCopairing = (dualQuotEquivDualAnnihilator W).symm.toLinearMap 
goal: W.dualCopairing = ↑W.dualQuotEquivDualAnnihilator.symm

full_name: Submodule.dualQuotEquivDualAnnihilator_symm_apply_mk
code: @[simp]
theorem dualQuotEquivDualAnnihilator_symm_apply_mk (W : Submodule R M) (φ : W.dualAnnihilator)
    (x : M) : (dualQuotEquivDualAnnihilator W).symm φ (Quotient.mk x) = φ x 
goal: (W.dualQuotEquivDualAnnihilator.symm φ) (Submodule.Quotient.mk x) = φ x

full_name: Submodule.finite_dualAnnihilator_iff
code: theorem finite_dualAnnihilator_iff {W : Submodule R M} [Free R (M ⧸ W)] :
    Finite R W.dualAnnihilator ↔ Finite R (M ⧸ W) 
goal: Module.Finite R ↥W.dualAnnihilator ↔ Module.Finite R (M ⧸ W)

full_name: Submodule.quotDualCoannihilatorToDual
code: /-- The pairing between a submodule `W` of a dual module `Dual R M` and the quotient of
`M` by the coannihilator of `W`, which is always nondegenerate. -/
def quotDualCoannihilatorToDual (W : Submodule R (Dual R M)) :
    M ⧸ W.dualCoannihilator →ₗ[R] Dual R W 
goal: M ⧸ W.dualCoannihilator →ₗ[R] Module.Dual R ↥W

full_name: Submodule.quotDualCoannihilatorToDual_apply
code: @[simp]
theorem quotDualCoannihilatorToDual_apply (W : Submodule R (Dual R M)) (m : M) (w : W) :
    W.quotDualCoannihilatorToDual (Quotient.mk m) w = w.1 m 
goal: (W.quotDualCoannihilatorToDual (Submodule.Quotient.mk m)) w = ↑w m

full_name: Submodule.quotDualCoannihilatorToDual_injective
code: theorem quotDualCoannihilatorToDual_injective (W : Submodule R (Dual R M)) :
    Function.Injective W.quotDualCoannihilatorToDual 
goal: Function.Injective ⇑W.quotDualCoannihilatorToDual

full_name: Submodule.flip_quotDualCoannihilatorToDual_injective
code: theorem flip_quotDualCoannihilatorToDual_injective (W : Submodule R (Dual R M)) :
    Function.Injective W.quotDualCoannihilatorToDual.flip 
goal: Function.Injective ⇑W.quotDualCoannihilatorToDual.flip

full_name: Submodule.quotDualCoannihilatorToDual_nondegenerate
code: theorem quotDualCoannihilatorToDual_nondegenerate (W : Submodule R (Dual R M)) :
    W.quotDualCoannihilatorToDual.Nondegenerate 
goal: W.quotDualCoannihilatorToDual.Nondegenerate

full_name: LinearMap.range_dualMap_eq_dualAnnihilator_ker_of_surjective
code: theorem range_dualMap_eq_dualAnnihilator_ker_of_surjective (f : M →ₗ[R] M')
    (hf : Function.Surjective f) : LinearMap.range f.dualMap = f.ker.dualAnnihilator 
goal: LinearMap.range f.dualMap = (LinearMap.ker f).dualAnnihilator

full_name: LinearMap.range_dualMap_eq_dualAnnihilator_ker_of_subtype_range_surjective
code: theorem range_dualMap_eq_dualAnnihilator_ker_of_subtype_range_surjective (f : M →ₗ[R] M')
    (hf : Function.Surjective f.range.subtype.dualMap) :
    LinearMap.range f.dualMap = f.ker.dualAnnihilator 
goal: LinearMap.range f.dualMap = (LinearMap.ker f).dualAnnihilator

full_name: LinearMap.ker_dualMap_eq_dualCoannihilator_range
code: theorem ker_dualMap_eq_dualCoannihilator_range (f : M →ₗ[R] M') :
    LinearMap.ker f.dualMap = (Dual.eval R M' ∘ₗ f).range.dualCoannihilator 
goal: LinearMap.ker f.dualMap = (LinearMap.range (Module.Dual.eval R M' ∘ₗ f)).dualCoannihilator

full_name: LinearMap.dualCoannihilator_range_eq_ker_flip
code: @[simp]
lemma dualCoannihilator_range_eq_ker_flip (B : M →ₗ[R] M' →ₗ[R] R) :
    (range B).dualCoannihilator = LinearMap.ker B.flip 
goal: (LinearMap.range B).dualCoannihilator = LinearMap.ker B.flip

full_name: Module.Dual.range_eq_top_of_ne_zero
code: lemma range_eq_top_of_ne_zero :
    LinearMap.range f = ⊤ 
goal: LinearMap.range f = ⊤

full_name: Module.Dual.finrank_ker_add_one_of_ne_zero
code: lemma finrank_ker_add_one_of_ne_zero :
    finrank K (LinearMap.ker f) + 1 = finrank K V₁ 
goal: FiniteDimensional.finrank K ↥(LinearMap.ker f) + 1 = FiniteDimensional.finrank K V₁

full_name: Module.Dual.isCompl_ker_of_disjoint_of_ne_bot
code: lemma isCompl_ker_of_disjoint_of_ne_bot {p : Submodule K V₁}
    (hpf : Disjoint (LinearMap.ker f) p) (hp : p ≠ ⊥) :
    IsCompl (LinearMap.ker f) p 
goal: IsCompl (LinearMap.ker f) p

full_name: Module.Dual.eq_of_ker_eq_of_apply_eq
code: lemma eq_of_ker_eq_of_apply_eq {f g : Module.Dual K V₁} (x : V₁)
    (h : LinearMap.ker f = LinearMap.ker g) (h' : f x = g x) (hx : f x ≠ 0) :
    f = g 
goal: f = g

full_name: LinearMap.dualPairing_nondegenerate
code: theorem dualPairing_nondegenerate : (dualPairing K V₁).Nondegenerate 
goal: (Module.dualPairing K V₁).Nondegenerate

full_name: LinearMap.dualMap_surjective_of_injective
code: theorem dualMap_surjective_of_injective {f : V₁ →ₗ[K] V₂} (hf : Function.Injective f) :
    Function.Surjective f.dualMap 
goal: Function.Surjective ⇑f.dualMap

full_name: LinearMap.range_dualMap_eq_dualAnnihilator_ker
code: theorem range_dualMap_eq_dualAnnihilator_ker (f : V₁ →ₗ[K] V₂) :
    LinearMap.range f.dualMap = f.ker.dualAnnihilator 
goal: LinearMap.range f.dualMap = (LinearMap.ker f).dualAnnihilator

full_name: LinearMap.dualMap_surjective_iff
code: /-- For vector spaces, `f.dualMap` is surjective if and only if `f` is injective -/
@[simp]
theorem dualMap_surjective_iff {f : V₁ →ₗ[K] V₂} :
    Function.Surjective f.dualMap ↔ Function.Injective f 
goal: Function.Surjective ⇑f.dualMap ↔ Function.Injective ⇑f

full_name: Subspace.dualPairing_eq
code: theorem dualPairing_eq (W : Subspace K V₁) :
    W.dualPairing = W.quotAnnihilatorEquiv.toLinearMap 
goal: Submodule.dualPairing W = ↑W.quotAnnihilatorEquiv

full_name: Subspace.dualPairing_nondegenerate
code: theorem dualPairing_nondegenerate (W : Subspace K V₁) : W.dualPairing.Nondegenerate 
goal: (Submodule.dualPairing W).Nondegenerate

full_name: Subspace.dualCopairing_nondegenerate
code: theorem dualCopairing_nondegenerate (W : Subspace K V₁) : W.dualCopairing.Nondegenerate 
goal: (Submodule.dualCopairing W).Nondegenerate

full_name: Subspace.dualAnnihilator_inf_eq
code: theorem dualAnnihilator_inf_eq (W W' : Subspace K V₁) :
    (W ⊓ W').dualAnnihilator = W.dualAnnihilator ⊔ W'.dualAnnihilator 
goal: Submodule.dualAnnihilator (W ⊓ W') = Submodule.dualAnnihilator W ⊔ Submodule.dualAnnihilator W'

full_name: Subspace.dualAnnihilator_iInf_eq
code: theorem dualAnnihilator_iInf_eq {ι : Type*} [Finite ι] (W : ι → Subspace K V₁) :
    (⨅ i : ι, W i).dualAnnihilator = ⨆ i : ι, (W i).dualAnnihilator 
goal: Submodule.dualAnnihilator (⨅ i, W i) = ⨆ i, Submodule.dualAnnihilator (W i)

full_name: Subspace.isCompl_dualAnnihilator
code: /-- For vector spaces, dual annihilators carry direct sum decompositions
to direct sum decompositions. -/
theorem isCompl_dualAnnihilator {W W' : Subspace K V₁} (h : IsCompl W W') :
    IsCompl W.dualAnnihilator W'.dualAnnihilator 
goal: IsCompl (Submodule.dualAnnihilator W) (Submodule.dualAnnihilator W')

full_name: Subspace.dualQuotDistrib
code: /-- For finite-dimensional vector spaces, one can distribute duals over quotients by identifying
`W.dualLift.range` with `W`. Note that this depends on a choice of splitting of `V₁`. -/
def dualQuotDistrib [FiniteDimensional K V₁] (W : Subspace K V₁) :
    Module.Dual K (V₁ ⧸ W) ≃ₗ[K] Module.Dual K V₁ ⧸ LinearMap.range W.dualLift 
goal: Module.Dual K (V₁ ⧸ W) ≃ₗ[K] Module.Dual K V₁ ⧸ LinearMap.range W.dualLift

full_name: LinearMap.finrank_range_dualMap_eq_finrank_range
code: @[simp]
theorem finrank_range_dualMap_eq_finrank_range (f : V₁ →ₗ[K] V₂) :
    -- Porting note (#11036): broken dot notation lean4#1910
    finrank K (LinearMap.range f.dualMap) = finrank K (LinearMap.range f) 
goal: FiniteDimensional.finrank K ↥(LinearMap.range f.dualMap) = FiniteDimensional.finrank K ↥(LinearMap.range f)

full_name: LinearMap.dualMap_injective_iff
code: /-- `f.dualMap` is injective if and only if `f` is surjective -/
@[simp]
theorem dualMap_injective_iff {f : V₁ →ₗ[K] V₂} :
    Function.Injective f.dualMap ↔ Function.Surjective f 
goal: Function.Injective ⇑f.dualMap ↔ Function.Surjective ⇑f

full_name: LinearMap.dualMap_bijective_iff
code: /-- `f.dualMap` is bijective if and only if `f` is -/
@[simp]
theorem dualMap_bijective_iff {f : V₁ →ₗ[K] V₂} :
    Function.Bijective f.dualMap ↔ Function.Bijective f 
goal: Function.Bijective ⇑f.dualMap ↔ Function.Bijective ⇑f

full_name: LinearMap.dualAnnihilator_ker_eq_range_flip
code: @[simp]
lemma dualAnnihilator_ker_eq_range_flip [IsReflexive K V₂] :
    (ker B).dualAnnihilator = range B.flip 
goal: (LinearMap.ker B).dualAnnihilator = LinearMap.range B.flip

full_name: LinearMap.flip_injective_iff₁
code: theorem flip_injective_iff₁ [FiniteDimensional K V₁] : Injective B.flip ↔ Surjective B 
goal: Function.Injective ⇑B.flip ↔ Function.Surjective ⇑B

full_name: LinearMap.flip_injective_iff₂
code: theorem flip_injective_iff₂ [FiniteDimensional K V₂] : Injective B.flip ↔ Surjective B 
goal: Function.Injective ⇑B.flip ↔ Function.Surjective ⇑B

full_name: LinearMap.flip_surjective_iff₁
code: theorem flip_surjective_iff₁ [FiniteDimensional K V₁] : Surjective B.flip ↔ Injective B 
goal: Function.Surjective ⇑B.flip ↔ Function.Injective ⇑B

full_name: LinearMap.flip_surjective_iff₂
code: theorem flip_surjective_iff₂ [FiniteDimensional K V₂] : Surjective B.flip ↔ Injective B 
goal: Function.Surjective ⇑B.flip ↔ Function.Injective ⇑B

full_name: LinearMap.flip_bijective_iff₁
code: theorem flip_bijective_iff₁ [FiniteDimensional K V₁] : Bijective B.flip ↔ Bijective B 
goal: Function.Bijective ⇑B.flip ↔ Function.Bijective ⇑B

full_name: LinearMap.flip_bijective_iff₂
code: theorem flip_bijective_iff₂ [FiniteDimensional K V₂] : Bijective B.flip ↔ Bijective B 
goal: Function.Bijective ⇑B.flip ↔ Function.Bijective ⇑B

full_name: Subspace.quotDualCoannihilatorToDual_bijective
code: theorem quotDualCoannihilatorToDual_bijective (W : Subspace K (Dual K V)) [FiniteDimensional K W] :
    Function.Bijective W.quotDualCoannihilatorToDual 
goal: Function.Bijective ⇑(Submodule.quotDualCoannihilatorToDual W)

full_name: Subspace.flip_quotDualCoannihilatorToDual_bijective
code: theorem flip_quotDualCoannihilatorToDual_bijective (W : Subspace K (Dual K V))
    [FiniteDimensional K W] : Function.Bijective W.quotDualCoannihilatorToDual.flip 
goal: Function.Bijective ⇑(Submodule.quotDualCoannihilatorToDual W).flip

full_name: Subspace.dualCoannihilator_dualAnnihilator_eq
code: theorem dualCoannihilator_dualAnnihilator_eq {W : Subspace K (Dual K V)} [FiniteDimensional K W] :
    W.dualCoannihilator.dualAnnihilator = W 
goal: (Submodule.dualCoannihilator W).dualAnnihilator = W

full_name: Subspace.finiteDimensional_quot_dualCoannihilator_iff
code: theorem finiteDimensional_quot_dualCoannihilator_iff {W : Submodule K (Dual K V)} :
    FiniteDimensional K (V ⧸ W.dualCoannihilator) ↔ FiniteDimensional K W 
goal: FiniteDimensional K (V ⧸ W.dualCoannihilator) ↔ FiniteDimensional K ↥W

full_name: Subspace.orderIsoFiniteCodimDim
code: /-- For any vector space, `dualAnnihilator` and `dualCoannihilator` gives an antitone order
  isomorphism between the finite-codimensional subspaces in the vector space and the
  finite-dimensional subspaces in its dual. -/
def orderIsoFiniteCodimDim :
    {W : Subspace K V // FiniteDimensional K (V ⧸ W)} ≃o
    {W : Subspace K (Dual K V) // FiniteDimensional K W}ᵒᵈ 
goal: { W // FiniteDimensional K (V ⧸ W) } ≃o { W // FiniteDimensional K ↥W }ᵒᵈ

full_name: Subspace.orderIsoFiniteDimensional
code: /-- For any finite-dimensional vector space, `dualAnnihilator` and `dualCoannihilator` give
  an antitone order isomorphism between the subspaces in the vector space and the subspaces
  in its dual. -/
def orderIsoFiniteDimensional [FiniteDimensional K V] :
    Subspace K V ≃o (Subspace K (Dual K V))ᵒᵈ 
goal: Subspace K V ≃o (Subspace K (Module.Dual K V))ᵒᵈ

full_name: Subspace.dualAnnihilator_dualAnnihilator_eq_map
code: theorem dualAnnihilator_dualAnnihilator_eq_map (W : Subspace K V) [FiniteDimensional K W] :
    W.dualAnnihilator.dualAnnihilator = W.map (Dual.eval K V) 
goal: (Submodule.dualAnnihilator W).dualAnnihilator = Submodule.map (Module.Dual.eval K V) W

full_name: Subspace.map_dualCoannihilator
code: theorem map_dualCoannihilator (W : Subspace K (Dual K V)) [FiniteDimensional K V] :
    W.dualCoannihilator.map (Dual.eval K V) = W.dualAnnihilator 
goal: Submodule.map (Module.Dual.eval K V) (Submodule.dualCoannihilator W) = Submodule.dualAnnihilator W

full_name: TensorProduct.dualDistrib
code: /-- The canonical linear map from `Dual M ⊗ Dual N` to `Dual (M ⊗ N)`,
sending `f ⊗ g` to the composition of `TensorProduct.map f g` with
the natural isomorphism `R ⊗ R ≃ R`.
-/
def dualDistrib : Dual R M ⊗[R] Dual R N →ₗ[R] Dual R (M ⊗[R] N) 
goal: TensorProduct R (Module.Dual R M) (Module.Dual R N) →ₗ[R] Module.Dual R (TensorProduct R M N)

full_name: TensorProduct.dualDistrib_apply
code: @[simp]
theorem dualDistrib_apply (f : Dual R M) (g : Dual R N) (m : M) (n : N) :
    dualDistrib R M N (f ⊗ₜ g) (m ⊗ₜ n) = f m * g n 
goal: ((TensorProduct.dualDistrib R M N) (f ⊗ₜ[R] g)) (m ⊗ₜ[R] n) = f m * g n

full_name: TensorProduct.AlgebraTensorModule.dualDistrib
code: /-- Heterobasic version of `TensorProduct.dualDistrib` -/
def dualDistrib : Dual A M ⊗[R] Dual R N →ₗ[A] Dual A (M ⊗[R] N) 
goal: TensorProduct R (Module.Dual A M) (Module.Dual R N) →ₗ[A] Module.Dual A (TensorProduct R M N)

full_name: TensorProduct.AlgebraTensorModule.dualDistrib_apply
code: @[simp]
theorem dualDistrib_apply (f : Dual A M) (g : Dual R N) (m : M) (n : N) :
    dualDistrib R A M N (f ⊗ₜ g) (m ⊗ₜ n) = g n • f m 
goal: ((TensorProduct.AlgebraTensorModule.dualDistrib R A M N) (f ⊗ₜ[R] g)) (m ⊗ₜ[R] n) = g n • f m

full_name: TensorProduct.dualDistribInvOfBasis
code: /-- An inverse to `TensorProduct.dualDistrib` given bases.
-/
noncomputable def dualDistribInvOfBasis (b : Basis ι R M) (c : Basis κ R N) :
    Dual R (M ⊗[R] N) →ₗ[R] Dual R M ⊗[R] Dual R N 
goal: Module.Dual R (TensorProduct R M N) →ₗ[R] TensorProduct R (Module.Dual R M) (Module.Dual R N)

full_name: TensorProduct.dualDistribInvOfBasis_apply
code: @[simp]
theorem dualDistribInvOfBasis_apply (b : Basis ι R M) (c : Basis κ R N) (f : Dual R (M ⊗[R] N)) :
    dualDistribInvOfBasis b c f = ∑ i, ∑ j, f (b i ⊗ₜ c j) • b.dualBasis i ⊗ₜ c.dualBasis j 
goal: (TensorProduct.dualDistribInvOfBasis b c) f = ∑ i : ι, ∑ j : κ, f (b i ⊗ₜ[R] c j) • b.dualBasis i ⊗ₜ[R] c.dualBasis j

full_name: TensorProduct.dualDistrib_dualDistribInvOfBasis_left_inverse
code: theorem dualDistrib_dualDistribInvOfBasis_left_inverse (b : Basis ι R M) (c : Basis κ R N) :
    comp (dualDistrib R M N) (dualDistribInvOfBasis b c) = LinearMap.id 
goal: TensorProduct.dualDistrib R M N ∘ₗ TensorProduct.dualDistribInvOfBasis b c = LinearMap.id

full_name: TensorProduct.dualDistrib_dualDistribInvOfBasis_right_inverse
code: theorem dualDistrib_dualDistribInvOfBasis_right_inverse (b : Basis ι R M) (c : Basis κ R N) :
    comp (dualDistribInvOfBasis b c) (dualDistrib R M N) = LinearMap.id 
goal: TensorProduct.dualDistribInvOfBasis b c ∘ₗ TensorProduct.dualDistrib R M N = LinearMap.id

full_name: TensorProduct.dualDistribEquivOfBasis_symm_apply
code: /-- A linear equivalence between `Dual M ⊗ Dual N` and `Dual (M ⊗ N)` given bases for `M` and `N`.
It sends `f ⊗ g` to the composition of `TensorProduct.map f g` with the natural
isomorphism `R ⊗ R ≃ R`.
-/
@[simps!]
noncomputable def dualDistribEquivOfBasis (b : Basis ι R M) (c : Basis κ R N) :
    Dual R M ⊗[R] Dual R N ≃ₗ[R] Dual R (M ⊗[R] N) 
goal: (TensorProduct.dualDistribEquivOfBasis b c).symm a =
  ∑ x : ι, ∑ x_1 : κ, a (b x ⊗ₜ[R] c x_1) • b.coord x ⊗ₜ[R] c.coord x_1

full_name: TensorProduct.dualDistribEquivOfBasis_apply_apply
code: /-- A linear equivalence between `Dual M ⊗ Dual N` and `Dual (M ⊗ N)` given bases for `M` and `N`.
It sends `f ⊗ g` to the composition of `TensorProduct.map f g` with the natural
isomorphism `R ⊗ R ≃ R`.
-/
@[simps!]
noncomputable def dualDistribEquivOfBasis (b : Basis ι R M) (c : Basis κ R N) :
    Dual R M ⊗[R] Dual R N ≃ₗ[R] Dual R (M ⊗[R] N) 
goal: ∀ (a : TensorProduct R (Module.Dual R M) (Module.Dual R N)) (a_1 : TensorProduct R M N),
  ((TensorProduct.dualDistribEquivOfBasis b c) a) a_1 =
    (TensorProduct.lid R R) (((TensorProduct.homTensorHomMap R M N R R) a) a_1)

full_name: TensorProduct.dualDistribEquivOfBasis
code: /-- A linear equivalence between `Dual M ⊗ Dual N` and `Dual (M ⊗ N)` given bases for `M` and `N`.
It sends `f ⊗ g` to the composition of `TensorProduct.map f g` with the natural
isomorphism `R ⊗ R ≃ R`.
-/
@[simps!]
noncomputable def dualDistribEquivOfBasis (b : Basis ι R M) (c : Basis κ R N) :
    Dual R M ⊗[R] Dual R N ≃ₗ[R] Dual R (M ⊗[R] N) 
goal: TensorProduct R (Module.Dual R M) (Module.Dual R N) ≃ₗ[R] Module.Dual R (TensorProduct R M N)

full_name: TensorProduct.dualDistribEquiv
code: /--
A linear equivalence between `Dual M ⊗ Dual N` and `Dual (M ⊗ N)` when `M` and `N` are finite free
modules. It sends `f ⊗ g` to the composition of `TensorProduct.map f g` with the natural
isomorphism `R ⊗ R ≃ R`.
-/
@[simp]
noncomputable def dualDistribEquiv : Dual R M ⊗[R] Dual R N ≃ₗ[R] Dual R (M ⊗[R] N) 
goal: TensorProduct R (Module.Dual R M) (Module.Dual R N) ≃ₗ[R] Module.Dual R (TensorProduct R M N)