l3lab/ntp-mathlib huggingface dataset:
lemma LinearMap.ker_restrictBilinear_eq_of_codisjoint
    {R M : Type*} [CommSemiring R] [AddCommMonoid M] [Module R M]
    {p q : Submodule R M} (hpq : Codisjoint p q)
    {B : M →ₗ[R] M →ₗ[R] R} (hB : ∀ x ∈ p, ∀ y ∈ q, B x y = 0) :
    LinearMap.ker (p.restrictBilinear B) = (LinearMap.ker B).comap p.subtype := by
  

Proof state:
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
p q : Submodule R M
hpq : Codisjoint p q
B : M →ₗ[R] M →ₗ[R] R
hB : ∀ x ∈ p, ∀ y ∈ q, (B x) y = 0
⊢ ker (Submodule.restrictBilinear p B) = Submodule.comap (Submodule.subtype p) (ker B)

Next tactic:
ext ⟨z, hz⟩
lemma LinearMap.ker_restrictBilinear_eq_of_codisjoint
    {R M : Type*} [CommSemiring R] [AddCommMonoid M] [Module R M]
    {p q : Submodule R M} (hpq : Codisjoint p q)
    {B : M →ₗ[R] M →ₗ[R] R} (hB : ∀ x ∈ p, ∀ y ∈ q, B x y = 0) :
    LinearMap.ker (p.restrictBilinear B) = (LinearMap.ker B).comap p.subtype := by
  ext ⟨z, hz⟩
  

Proof state:
case h.mk
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
p q : Submodule R M
hpq : Codisjoint p q
B : M →ₗ[R] M →ₗ[R] R
hB : ∀ x ∈ p, ∀ y ∈ q, (B x) y = 0
z : M
hz : z ∈ p
⊢ { val := z, property := hz } ∈ ker (Submodule.restrictBilinear p B) ↔
    { val := z, property := hz } ∈ Submodule.comap (Submodule.subtype p) (ker B)

Next tactic:
simp only [LinearMap.mem_ker, Submodule.mem_comap, Submodule.coeSubtype]
lemma LinearMap.ker_restrictBilinear_eq_of_codisjoint
    {R M : Type*} [CommSemiring R] [AddCommMonoid M] [Module R M]
    {p q : Submodule R M} (hpq : Codisjoint p q)
    {B : M →ₗ[R] M →ₗ[R] R} (hB : ∀ x ∈ p, ∀ y ∈ q, B x y = 0) :
    LinearMap.ker (p.restrictBilinear B) = (LinearMap.ker B).comap p.subtype := by
  ext ⟨z, hz⟩
  simp only [LinearMap.mem_ker, Submodule.mem_comap, Submodule.coeSubtype]
  

Proof state:
case h.mk
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
p q : Submodule R M
hpq : Codisjoint p q
B : M →ₗ[R] M →ₗ[R] R
hB : ∀ x ∈ p, ∀ y ∈ q, (B x) y = 0
z : M
hz : z ∈ p
⊢ (Submodule.restrictBilinear p B) { val := z, property := hz } = 0 ↔ B z = 0

Next tactic:
refine ⟨fun h ↦ ?_, fun h ↦ ?_⟩
lemma LinearMap.ker_restrictBilinear_eq_of_codisjoint
    {R M : Type*} [CommSemiring R] [AddCommMonoid M] [Module R M]
    {p q : Submodule R M} (hpq : Codisjoint p q)
    {B : M →ₗ[R] M →ₗ[R] R} (hB : ∀ x ∈ p, ∀ y ∈ q, B x y = 0) :
    LinearMap.ker (p.restrictBilinear B) = (LinearMap.ker B).comap p.subtype := by
  ext ⟨z, hz⟩
  simp only [LinearMap.mem_ker, Submodule.mem_comap, Submodule.coeSubtype]
  refine ⟨fun h ↦ ?_, fun h ↦ ?_⟩
  · 

Proof state:
case h.mk.refine_1
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
p q : Submodule R M
hpq : Codisjoint p q
B : M →ₗ[R] M →ₗ[R] R
hB : ∀ x ∈ p, ∀ y ∈ q, (B x) y = 0
z : M
hz : z ∈ p
h : (Submodule.restrictBilinear p B) { val := z, property := hz } = 0
⊢ B z = 0

Next tactic:
ext w
lemma LinearMap.ker_restrictBilinear_eq_of_codisjoint
    {R M : Type*} [CommSemiring R] [AddCommMonoid M] [Module R M]
    {p q : Submodule R M} (hpq : Codisjoint p q)
    {B : M →ₗ[R] M →ₗ[R] R} (hB : ∀ x ∈ p, ∀ y ∈ q, B x y = 0) :
    LinearMap.ker (p.restrictBilinear B) = (LinearMap.ker B).comap p.subtype := by
  ext ⟨z, hz⟩
  simp only [LinearMap.mem_ker, Submodule.mem_comap, Submodule.coeSubtype]
  refine ⟨fun h ↦ ?_, fun h ↦ ?_⟩
  · ext w
    

Proof state:
case h.mk.refine_1.h
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
p q : Submodule R M
hpq : Codisjoint p q
B : M →ₗ[R] M →ₗ[R] R
hB : ∀ x ∈ p, ∀ y ∈ q, (B x) y = 0
z : M
hz : z ∈ p
h : (Submodule.restrictBilinear p B) { val := z, property := hz } = 0
w : M
⊢ (B z) w = 0 w

Next tactic:
obtain ⟨x, hx, y, hy, rfl⟩ := Submodule.exists_add_eq_of_codisjoint hpq w
lemma LinearMap.ker_restrictBilinear_eq_of_codisjoint
    {R M : Type*} [CommSemiring R] [AddCommMonoid M] [Module R M]
    {p q : Submodule R M} (hpq : Codisjoint p q)
    {B : M →ₗ[R] M →ₗ[R] R} (hB : ∀ x ∈ p, ∀ y ∈ q, B x y = 0) :
    LinearMap.ker (p.restrictBilinear B) = (LinearMap.ker B).comap p.subtype := by
  ext ⟨z, hz⟩
  simp only [LinearMap.mem_ker, Submodule.mem_comap, Submodule.coeSubtype]
  refine ⟨fun h ↦ ?_, fun h ↦ ?_⟩
  · ext w
    obtain ⟨x, hx, y, hy, rfl⟩ := Submodule.exists_add_eq_of_codisjoint hpq w
    

Proof state:
case h.mk.refine_1.h.intro.intro.intro.intro
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
p q : Submodule R M
hpq : Codisjoint p q
B : M →ₗ[R] M →ₗ[R] R
hB : ∀ x ∈ p, ∀ y ∈ q, (B x) y = 0
z : M
hz : z ∈ p
h : (Submodule.restrictBilinear p B) { val := z, property := hz } = 0
x : M
hx : x ∈ p
y : M
hy : y ∈ q
⊢ (B z) (x + y) = 0 (x + y)

Next tactic:
simpa [hB z hz y hy] using LinearMap.congr_fun h ⟨x, hx⟩
lemma LinearMap.ker_restrictBilinear_eq_of_codisjoint
    {R M : Type*} [CommSemiring R] [AddCommMonoid M] [Module R M]
    {p q : Submodule R M} (hpq : Codisjoint p q)
    {B : M →ₗ[R] M →ₗ[R] R} (hB : ∀ x ∈ p, ∀ y ∈ q, B x y = 0) :
    LinearMap.ker (p.restrictBilinear B) = (LinearMap.ker B).comap p.subtype := by
  ext ⟨z, hz⟩
  simp only [LinearMap.mem_ker, Submodule.mem_comap, Submodule.coeSubtype]
  refine ⟨fun h ↦ ?_, fun h ↦ ?_⟩
  · ext w
    obtain ⟨x, hx, y, hy, rfl⟩ := Submodule.exists_add_eq_of_codisjoint hpq w
    simpa [hB z hz y hy] using LinearMap.congr_fun h ⟨x, hx⟩
  · 

Proof state:
case h.mk.refine_2
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
p q : Submodule R M
hpq : Codisjoint p q
B : M →ₗ[R] M →ₗ[R] R
hB : ∀ x ∈ p, ∀ y ∈ q, (B x) y = 0
z : M
hz : z ∈ p
h : B z = 0
⊢ (Submodule.restrictBilinear p B) { val := z, property := hz } = 0

Next tactic:
ext ⟨x, hx⟩
lemma LinearMap.ker_restrictBilinear_eq_of_codisjoint
    {R M : Type*} [CommSemiring R] [AddCommMonoid M] [Module R M]
    {p q : Submodule R M} (hpq : Codisjoint p q)
    {B : M →ₗ[R] M →ₗ[R] R} (hB : ∀ x ∈ p, ∀ y ∈ q, B x y = 0) :
    LinearMap.ker (p.restrictBilinear B) = (LinearMap.ker B).comap p.subtype := by
  ext ⟨z, hz⟩
  simp only [LinearMap.mem_ker, Submodule.mem_comap, Submodule.coeSubtype]
  refine ⟨fun h ↦ ?_, fun h ↦ ?_⟩
  · ext w
    obtain ⟨x, hx, y, hy, rfl⟩ := Submodule.exists_add_eq_of_codisjoint hpq w
    simpa [hB z hz y hy] using LinearMap.congr_fun h ⟨x, hx⟩
  · ext ⟨x, hx⟩
    

Proof state:
case h.mk.refine_2.h.mk
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
p q : Submodule R M
hpq : Codisjoint p q
B : M →ₗ[R] M →ₗ[R] R
hB : ∀ x ∈ p, ∀ y ∈ q, (B x) y = 0
z : M
hz : z ∈ p
h : B z = 0
x : M
hx : x ∈ p
⊢ ((Submodule.restrictBilinear p B) { val := z, property := hz }) { val := x, property := hx } =
    0 { val := x, property := hx }

Next tactic:
simpa using LinearMap.congr_fun h x
theorem char_mul_comm (V : FdRep k G) (g : G) (h : G) : V.character (h * g) = V.character (g * h) :=
  by 

Proof state:
k : Type u
inst✝¹ : Field k
G : Type u
inst✝ : Monoid G
V : FdRep k G
g h : G
⊢ character V (h * g) = character V (g * h)

Next tactic:
simp only [trace_mul_comm, character, map_mul]
@[simp]
theorem char_one (V : FdRep k G) : V.character 1 = FiniteDimensional.finrank k V := by
  

Proof state:
k : Type u
inst✝¹ : Field k
G : Type u
inst✝ : Monoid G
V : FdRep k G
⊢ character V 1 = ↑(finrank k (CoeSort.coe V))

Next tactic:
simp only [character, map_one, trace_one]
/-- The character is multiplicative under the tensor product. -/
theorem char_tensor (V W : FdRep k G) : (V ⊗ W).character = V.character * W.character := by
  

Proof state:
k : Type u
inst✝¹ : Field k
G : Type u
inst✝ : Monoid G
V W : FdRep k G
⊢ character (V ⊗ W) = character V * character W

Next tactic:
ext g
/-- The character is multiplicative under the tensor product. -/
theorem char_tensor (V W : FdRep k G) : (V ⊗ W).character = V.character * W.character := by
  ext g; 

Proof state:
case h
k : Type u
inst✝¹ : Field k
G : Type u
inst✝ : Monoid G
V W : FdRep k G
g : G
⊢ character (V ⊗ W) g = (character V * character W) g

Next tactic:
convert trace_tensorProduct' (V.ρ g) (W.ρ g)
@[simp]
theorem char_tensor' (V W : FdRep k G) :
    character (Action.FunctorCategoryEquivalence.inverse.obj
    (Action.FunctorCategoryEquivalence.functor.obj V ⊗
     Action.FunctorCategoryEquivalence.functor.obj W)) = V.character * W.character := by
  

Proof state:
k : Type u
inst✝¹ : Field k
G : Type u
inst✝ : Monoid G
V W : FdRep k G
⊢ character
      (Action.FunctorCategoryEquivalence.inverse.obj
        (Action.FunctorCategoryEquivalence.functor.obj V ⊗ Action.FunctorCategoryEquivalence.functor.obj W)) =
    character V * character W

Next tactic:
simp [← char_tensor]
/-- The character of isomorphic representations is the same. -/
theorem char_iso {V W : FdRep k G} (i : V ≅ W) : V.character = W.character := by
  

Proof state:
k : Type u
inst✝¹ : Field k
G : Type u
inst✝ : Monoid G
V W : FdRep k G
i : V ≅ W
⊢ character V = character W

Next tactic:
ext g
/-- The character of isomorphic representations is the same. -/
theorem char_iso {V W : FdRep k G} (i : V ≅ W) : V.character = W.character := by
  ext g; 

Proof state:
case h
k : Type u
inst✝¹ : Field k
G : Type u
inst✝ : Monoid G
V W : FdRep k G
i : V ≅ W
g : G
⊢ character V g = character W g

Next tactic:
simp only [character, FdRep.Iso.conj_ρ i]
/-- The character of isomorphic representations is the same. -/
theorem char_iso {V W : FdRep k G} (i : V ≅ W) : V.character = W.character := by
  ext g; simp only [character, FdRep.Iso.conj_ρ i]; 

Proof state:
case h
k : Type u
inst✝¹ : Field k
G : Type u
inst✝ : Monoid G
V W : FdRep k G
i : V ≅ W
g : G
⊢ (trace k (CoeSort.coe V)) ((ρ V) g) = (trace k (CoeSort.coe W)) ((LinearEquiv.conj (isoToLinearEquiv i)) ((ρ V) g))

Next tactic:
exact (trace_conj' (V.ρ g) _).symm
/-- The character of a representation is constant on conjugacy classes. -/
@[simp]
theorem char_conj (V : FdRep k G) (g : G) (h : G) : V.character (h * g * h⁻¹) = V.character g := by
  

Proof state:
k : Type u
inst✝¹ : Field k
G : Type u
inst✝ : Group G
V : FdRep k G
g h : G
⊢ character V (h * g * h⁻¹) = character V g

Next tactic:
rw [char_mul_comm, inv_mul_cancel_left]
@[simp]
theorem char_linHom (V W : FdRep k G) (g : G) :
    (of (linHom V.ρ W.ρ)).character g = V.character g⁻¹ * W.character g := by
  

Proof state:
k : Type u
inst✝¹ : Field k
G : Type u
inst✝ : Group G
V W : FdRep k G
g : G
⊢ character (of (linHom (ρ V) (ρ W))) g = character V g⁻¹ * character W g

Next tactic:
rw [← char_iso (dualTensorIsoLinHom _ _), char_tensor, Pi.mul_apply, char_dual]
theorem average_char_eq_finrank_invariants (V : FdRep k G) :
    ⅟ (Fintype.card G : k) • ∑ g : G, V.character g = finrank k (invariants V.ρ) := by
  

Proof state:
k : Type u
inst✝³ : Field k
G : Type u
inst✝² : Group G
inst✝¹ : Fintype G
inst✝ : Invertible ↑(Fintype.card G)
V : FdRep k G
⊢ ⅟↑(Fintype.card G) • ∑ g : G, character V g = ↑(finrank k ↥(invariants (ρ V)))

Next tactic:
erw [← (isProj_averageMap V.ρ).trace]
theorem average_char_eq_finrank_invariants (V : FdRep k G) :
    ⅟ (Fintype.card G : k) • ∑ g : G, V.character g = finrank k (invariants V.ρ) := by
  erw [← (isProj_averageMap V.ρ).trace] -- Porting note: Changed `rw` to `erw`
  

Proof state:
k : Type u
inst✝³ : Field k
G : Type u
inst✝² : Group G
inst✝¹ : Fintype G
inst✝ : Invertible ↑(Fintype.card G)
V : FdRep k G
⊢ ⅟↑(Fintype.card G) • ∑ g : G, character V g = (trace k (CoeSort.coe V)) (averageMap (ρ V))

Next tactic:
simp [character, GroupAlgebra.average, _root_.map_sum]
/-- Orthogonality of characters for irreducible representations of finite group over an
algebraically closed field whose characteristic doesn't divide the order of the group. -/
theorem char_orthonormal (V W : FdRep k G) [Simple V] [Simple W] :
    ⅟ (Fintype.card G : k) • ∑ g : G, V.character g * W.character g⁻¹ =
      if Nonempty (V ≅ W) then ↑1 else ↑0 := by
  -- First, we can rewrite the summand `V.character g * W.character g⁻¹` as the character
  -- of the representation `V ⊗ W* ≅ Hom(W, V)` applied to `g`.
  -- Porting note: Originally `conv in V.character _ * W.character _ =>`
  

Proof state:
k : Type u
inst✝⁵ : Field k
G : GroupCat
inst✝⁴ : IsAlgClosed k
inst✝³ : Fintype ↑G
inst✝² : Invertible ↑(Fintype.card ↑G)
V W : FdRep k ↑G
inst✝¹ : Simple V
inst✝ : Simple W
⊢ ⅟↑(Fintype.card ↑G) • ∑ g : ↑G, character V g * character W g⁻¹ = if Nonempty (V ≅ W) then 1 else 0

Next tactic:
conv_lhs =>
    enter [2, 2, g]
    rw [mul_comm, ← char_dual, ← Pi.mul_apply, ← char_tensor]
    rw [char_iso (FdRep.dualTensorIsoLinHom W.ρ V)]
/-- Orthogonality of characters for irreducible representations of finite group over an
algebraically closed field whose characteristic doesn't divide the order of the group. -/
theorem char_orthonormal (V W : FdRep k G) [Simple V] [Simple W] :
    ⅟ (Fintype.card G : k) • ∑ g : G, V.character g * W.character g⁻¹ =
      if Nonempty (V ≅ W) then ↑1 else ↑0 := by
  -- First, we can rewrite the summand `V.character g * W.character g⁻¹` as the character
  -- of the representation `V ⊗ W* ≅ Hom(W, V)` applied to `g`.
  -- Porting note: Originally `conv in V.character _ * W.character _ =>`
  conv_lhs =>
    

Proof state:
k : Type u
inst✝⁵ : Field k
G : GroupCat
inst✝⁴ : IsAlgClosed k
inst✝³ : Fintype ↑G
inst✝² : Invertible ↑(Fintype.card ↑G)
V W : FdRep k ↑G
inst✝¹ : Simple V
inst✝ : Simple W
| ⅟↑(Fintype.card ↑G) • ∑ g : ↑G, character V g * character W g⁻¹

Next tactic:
enter [2, 2, g]
    rw [mul_comm, ← char_dual, ← Pi.mul_apply, ← char_tensor]
    rw [char_iso (FdRep.dualTensorIsoLinHom W.ρ V)]
/-- Orthogonality of characters for irreducible representations of finite group over an
algebraically closed field whose characteristic doesn't divide the order of the group. -/
theorem char_orthonormal (V W : FdRep k G) [Simple V] [Simple W] :
    ⅟ (Fintype.card G : k) • ∑ g : G, V.character g * W.character g⁻¹ =
      if Nonempty (V ≅ W) then ↑1 else ↑0 := by
  -- First, we can rewrite the summand `V.character g * W.character g⁻¹` as the character
  -- of the representation `V ⊗ W* ≅ Hom(W, V)` applied to `g`.
  -- Porting note: Originally `conv in V.character _ * W.character _ =>`
  conv_lhs =>
    

Proof state:
k : Type u
inst✝⁵ : Field k
G : GroupCat
inst✝⁴ : IsAlgClosed k
inst✝³ : Fintype ↑G
inst✝² : Invertible ↑(Fintype.card ↑G)
V W : FdRep k ↑G
inst✝¹ : Simple V
inst✝ : Simple W
| ⅟↑(Fintype.card ↑G) • ∑ g : ↑G, character V g * character W g⁻¹

Next tactic:
enter [2, 2, g]
/-- Orthogonality of characters for irreducible representations of finite group over an
algebraically closed field whose characteristic doesn't divide the order of the group. -/
theorem char_orthonormal (V W : FdRep k G) [Simple V] [Simple W] :
    ⅟ (Fintype.card G : k) • ∑ g : G, V.character g * W.character g⁻¹ =
      if Nonempty (V ≅ W) then ↑1 else ↑0 := by
  -- First, we can rewrite the summand `V.character g * W.character g⁻¹` as the character
  -- of the representation `V ⊗ W* ≅ Hom(W, V)` applied to `g`.
  -- Porting note: Originally `conv in V.character _ * W.character _ =>`
  conv_lhs =>
    enter [2, 2, g]
    

Proof state:
case h
k : Type u
inst✝⁵ : Field k
G : GroupCat
inst✝⁴ : IsAlgClosed k
inst✝³ : Fintype ↑G
inst✝² : Invertible ↑(Fintype.card ↑G)
V W : FdRep k ↑G
inst✝¹ : Simple V
inst✝ : Simple W
g : ↑G
| character V g * character W g⁻¹

Next tactic:
rw [mul_comm, ← char_dual, ← Pi.mul_apply, ← char_tensor]
/-- Orthogonality of characters for irreducible representations of finite group over an
algebraically closed field whose characteristic doesn't divide the order of the group. -/
theorem char_orthonormal (V W : FdRep k G) [Simple V] [Simple W] :
    ⅟ (Fintype.card G : k) • ∑ g : G, V.character g * W.character g⁻¹ =
      if Nonempty (V ≅ W) then ↑1 else ↑0 := by
  -- First, we can rewrite the summand `V.character g * W.character g⁻¹` as the character
  -- of the representation `V ⊗ W* ≅ Hom(W, V)` applied to `g`.
  -- Porting note: Originally `conv in V.character _ * W.character _ =>`
  conv_lhs =>
    enter [2, 2, g]
    rw [mul_comm, ← char_dual, ← Pi.mul_apply, ← char_tensor]
    

Proof state:
case h
k : Type u
inst✝⁵ : Field k
G : GroupCat
inst✝⁴ : IsAlgClosed k
inst✝³ : Fintype ↑G
inst✝² : Invertible ↑(Fintype.card ↑G)
V W : FdRep k ↑G
inst✝¹ : Simple V
inst✝ : Simple W
g : ↑G
| character (of (dual (ρ W)) ⊗ V) g

Next tactic:
rw [char_iso (FdRep.dualTensorIsoLinHom W.ρ V)]
/-- Orthogonality of characters for irreducible representations of finite group over an
algebraically closed field whose characteristic doesn't divide the order of the group. -/
theorem char_orthonormal (V W : FdRep k G) [Simple V] [Simple W] :
    ⅟ (Fintype.card G : k) • ∑ g : G, V.character g * W.character g⁻¹ =
      if Nonempty (V ≅ W) then ↑1 else ↑0 := by
  -- First, we can rewrite the summand `V.character g * W.character g⁻¹` as the character
  -- of the representation `V ⊗ W* ≅ Hom(W, V)` applied to `g`.
  -- Porting note: Originally `conv in V.character _ * W.character _ =>`
  conv_lhs =>
    enter [2, 2, g]
    rw [mul_comm, ← char_dual, ← Pi.mul_apply, ← char_tensor]
    rw [char_iso (FdRep.dualTensorIsoLinHom W.ρ V)]
  -- The average over the group of the character of a representation equals the dimension of the
  -- space of invariants.
  

Proof state:
k : Type u
inst✝⁵ : Field k
G : GroupCat
inst✝⁴ : IsAlgClosed k
inst✝³ : Fintype ↑G
inst✝² : Invertible ↑(Fintype.card ↑G)
V W : FdRep k ↑G
inst✝¹ : Simple V
inst✝ : Simple W
⊢ ⅟↑(Fintype.card ↑G) • ∑ g : ↑G, character (of (linHom (ρ W) (ρ V))) g = if Nonempty (V ≅ W) then 1 else 0

Next tactic:
rw [average_char_eq_finrank_invariants]
/-- Orthogonality of characters for irreducible representations of finite group over an
algebraically closed field whose characteristic doesn't divide the order of the group. -/
theorem char_orthonormal (V W : FdRep k G) [Simple V] [Simple W] :
    ⅟ (Fintype.card G : k) • ∑ g : G, V.character g * W.character g⁻¹ =
      if Nonempty (V ≅ W) then ↑1 else ↑0 := by
  -- First, we can rewrite the summand `V.character g * W.character g⁻¹` as the character
  -- of the representation `V ⊗ W* ≅ Hom(W, V)` applied to `g`.
  -- Porting note: Originally `conv in V.character _ * W.character _ =>`
  conv_lhs =>
    enter [2, 2, g]
    rw [mul_comm, ← char_dual, ← Pi.mul_apply, ← char_tensor]
    rw [char_iso (FdRep.dualTensorIsoLinHom W.ρ V)]
  -- The average over the group of the character of a representation equals the dimension of the
  -- space of invariants.
  rw [average_char_eq_finrank_invariants]
  

Proof state:
k : Type u
inst✝⁵ : Field k
G : GroupCat
inst✝⁴ : IsAlgClosed k
inst✝³ : Fintype ↑G
inst✝² : Invertible ↑(Fintype.card ↑G)
V W : FdRep k ↑G
inst✝¹ : Simple V
inst✝ : Simple W
⊢ ↑(finrank k ↥(invariants (ρ (of (linHom (ρ W) (ρ V)))))) = if Nonempty (V ≅ W) then 1 else 0

Next tactic:
rw [show (of (linHom W.ρ V.ρ)).ρ = linHom W.ρ V.ρ from FdRep.of_ρ (linHom W.ρ V.ρ)]
/-- Orthogonality of characters for irreducible representations of finite group over an
algebraically closed field whose characteristic doesn't divide the order of the group. -/
theorem char_orthonormal (V W : FdRep k G) [Simple V] [Simple W] :
    ⅟ (Fintype.card G : k) • ∑ g : G, V.character g * W.character g⁻¹ =
      if Nonempty (V ≅ W) then ↑1 else ↑0 := by
  -- First, we can rewrite the summand `V.character g * W.character g⁻¹` as the character
  -- of the representation `V ⊗ W* ≅ Hom(W, V)` applied to `g`.
  -- Porting note: Originally `conv in V.character _ * W.character _ =>`
  conv_lhs =>
    enter [2, 2, g]
    rw [mul_comm, ← char_dual, ← Pi.mul_apply, ← char_tensor]
    rw [char_iso (FdRep.dualTensorIsoLinHom W.ρ V)]
  -- The average over the group of the character of a representation equals the dimension of the
  -- space of invariants.
  rw [average_char_eq_finrank_invariants]
  rw [show (of (linHom W.ρ V.ρ)).ρ = linHom W.ρ V.ρ from FdRep.of_ρ (linHom W.ρ V.ρ)]
  -- The space of invariants of `Hom(W, V)` is the subspace of `G`-equivariant linear maps,
  -- `Hom_G(W, V)`.
  

Proof state:
k : Type u
inst✝⁵ : Field k
G : GroupCat
inst✝⁴ : IsAlgClosed k
inst✝³ : Fintype ↑G
inst✝² : Invertible ↑(Fintype.card ↑G)
V W : FdRep k ↑G
inst✝¹ : Simple V
inst✝ : Simple W
⊢ ↑(finrank k ↥(invariants (linHom (ρ W) (ρ V)))) = if Nonempty (V ≅ W) then 1 else 0

Next tactic:
erw [(linHom.invariantsEquivFdRepHom W V).finrank_eq]
/-- Orthogonality of characters for irreducible representations of finite group over an
algebraically closed field whose characteristic doesn't divide the order of the group. -/
theorem char_orthonormal (V W : FdRep k G) [Simple V] [Simple W] :
    ⅟ (Fintype.card G : k) • ∑ g : G, V.character g * W.character g⁻¹ =
      if Nonempty (V ≅ W) then ↑1 else ↑0 := by
  -- First, we can rewrite the summand `V.character g * W.character g⁻¹` as the character
  -- of the representation `V ⊗ W* ≅ Hom(W, V)` applied to `g`.
  -- Porting note: Originally `conv in V.character _ * W.character _ =>`
  conv_lhs =>
    enter [2, 2, g]
    rw [mul_comm, ← char_dual, ← Pi.mul_apply, ← char_tensor]
    rw [char_iso (FdRep.dualTensorIsoLinHom W.ρ V)]
  -- The average over the group of the character of a representation equals the dimension of the
  -- space of invariants.
  rw [average_char_eq_finrank_invariants]
  rw [show (of (linHom W.ρ V.ρ)).ρ = linHom W.ρ V.ρ from FdRep.of_ρ (linHom W.ρ V.ρ)]
  -- The space of invariants of `Hom(W, V)` is the subspace of `G`-equivariant linear maps,
  -- `Hom_G(W, V)`.
  erw [(linHom.invariantsEquivFdRepHom W V).finrank_eq] -- Porting note: Changed `rw` to `erw`
  -- By Schur's Lemma, the dimension of `Hom_G(W, V)` is `1` is `V ≅ W` and `0` otherwise.
  

Proof state:
k : Type u
inst✝⁵ : Field k
G : GroupCat
inst✝⁴ : IsAlgClosed k
inst✝³ : Fintype ↑G
inst✝² : Invertible ↑(Fintype.card ↑G)
V W : FdRep k ↑G
inst✝¹ : Simple V
inst✝ : Simple W
⊢ ↑(finrank k (W ⟶ V)) = if Nonempty (V ≅ W) then 1 else 0

Next tactic:
rw_mod_cast [finrank_hom_simple_simple W V, Iso.nonempty_iso_symm]
/--
To construct a morphism from the explicit finite coproduct, it suffices to
specify a morphism from each of its factors.
This is essentially the universal property of the coproduct.
-/
def finiteCoproduct.desc {B : Stonean.{u}} (e : (a : α) → (X a ⟶ B)) :
    finiteCoproduct X ⟶ B where
  toFun := fun ⟨a,x⟩ => e a x
  continuous_toFun := by
    

Proof state:
α : Type
inst✝ : Fintype α
B✝ : Stonean
X : α → Stonean
B : Stonean
e : (a : α) → X a ⟶ B
⊢ Continuous fun x =>
    match x with
    | { fst := a, snd := x } => (e a) x

Next tactic:
apply continuous_sigma
/--
To construct a morphism from the explicit finite coproduct, it suffices to
specify a morphism from each of its factors.
This is essentially the universal property of the coproduct.
-/
def finiteCoproduct.desc {B : Stonean.{u}} (e : (a : α) → (X a ⟶ B)) :
    finiteCoproduct X ⟶ B where
  toFun := fun ⟨a,x⟩ => e a x
  continuous_toFun := by
    apply continuous_sigma
    

Proof state:
case hf
α : Type
inst✝ : Fintype α
B✝ : Stonean
X : α → Stonean
B : Stonean
e : (a : α) → X a ⟶ B
⊢ ∀ (i : α),
    Continuous fun a =>
      match { fst := i, snd := a } with
      | { fst := a, snd := x } => (e a) x

Next tactic:
intro a
/--
To construct a morphism from the explicit finite coproduct, it suffices to
specify a morphism from each of its factors.
This is essentially the universal property of the coproduct.
-/
def finiteCoproduct.desc {B : Stonean.{u}} (e : (a : α) → (X a ⟶ B)) :
    finiteCoproduct X ⟶ B where
  toFun := fun ⟨a,x⟩ => e a x
  continuous_toFun := by
    apply continuous_sigma
    intro a; 

Proof state:
case hf
α : Type
inst✝ : Fintype α
B✝ : Stonean
X : α → Stonean
B : Stonean
e : (a : α) → X a ⟶ B
a : α
⊢ Continuous fun a_1 =>
    match { fst := a, snd := a_1 } with
    | { fst := a, snd := x } => (e a) x

Next tactic:
exact (e a).continuous
lemma finiteCoproduct.hom_ext {B : Stonean.{u}} (f g : finiteCoproduct X ⟶ B)
    (h : ∀ a : α, finiteCoproduct.ι X a ≫ f = finiteCoproduct.ι X a ≫ g) : f = g := by
  

Proof state:
α : Type
inst✝ : Fintype α
B✝ : Stonean
X : α → Stonean
B : Stonean
f g : finiteCoproduct X ⟶ B
h : ∀ (a : α), ι X a ≫ f = ι X a ≫ g
⊢ f = g

Next tactic:
ext ⟨a, x⟩