l3lab/ntp-mathlib huggingface dataset:
theorem matPolyEquiv_smul_one (p : R[X]) :
    matPolyEquiv (p • (1 : Matrix n n R[X])) = p.map (algebraMap R (Matrix n n R)) := by
  ext m i j
  

Proof state:
case a.a.h
R : Type u_1
A : Type u_2
inst✝⁴ : CommSemiring R
inst✝³ : Semiring A
inst✝² : Algebra R A
n : Type w
inst✝¹ : DecidableEq n
inst✝ : Fintype n
p : R[X]
m : ℕ
i j : n
⊢ coeff (matPolyEquiv (p • 1)) m i j = coeff (Polynomial.map (algebraMap R (Matrix n n R)) p) m i j

Next tactic:
simp only [coeff_map, one_apply, algebraMap_matrix_apply, mul_boole, Pi.smul_apply,
    matPolyEquiv_coeff_apply]
theorem matPolyEquiv_smul_one (p : R[X]) :
    matPolyEquiv (p • (1 : Matrix n n R[X])) = p.map (algebraMap R (Matrix n n R)) := by
  ext m i j
  simp only [coeff_map, one_apply, algebraMap_matrix_apply, mul_boole, Pi.smul_apply,
    matPolyEquiv_coeff_apply]
  

Proof state:
case a.a.h
R : Type u_1
A : Type u_2
inst✝⁴ : CommSemiring R
inst✝³ : Semiring A
inst✝² : Algebra R A
n : Type w
inst✝¹ : DecidableEq n
inst✝ : Fintype n
p : R[X]
m : ℕ
i j : n
⊢ coeff ((p • 1) i j) m = if i = j then (algebraMap R R) (coeff p m) else 0

Next tactic:
split_ifs
theorem matPolyEquiv_smul_one (p : R[X]) :
    matPolyEquiv (p • (1 : Matrix n n R[X])) = p.map (algebraMap R (Matrix n n R)) := by
  ext m i j
  simp only [coeff_map, one_apply, algebraMap_matrix_apply, mul_boole, Pi.smul_apply,
    matPolyEquiv_coeff_apply]
  split_ifs <;> 

Proof state:
case pos
R : Type u_1
A : Type u_2
inst✝⁴ : CommSemiring R
inst✝³ : Semiring A
inst✝² : Algebra R A
n : Type w
inst✝¹ : DecidableEq n
inst✝ : Fintype n
p : R[X]
m : ℕ
i j : n
h✝ : i = j
⊢ coeff ((p • 1) i j) m = (algebraMap R R) (coeff p m)

Next tactic:
simp
theorem matPolyEquiv_smul_one (p : R[X]) :
    matPolyEquiv (p • (1 : Matrix n n R[X])) = p.map (algebraMap R (Matrix n n R)) := by
  ext m i j
  simp only [coeff_map, one_apply, algebraMap_matrix_apply, mul_boole, Pi.smul_apply,
    matPolyEquiv_coeff_apply]
  split_ifs <;> 

Proof state:
case neg
R : Type u_1
A : Type u_2
inst✝⁴ : CommSemiring R
inst✝³ : Semiring A
inst✝² : Algebra R A
n : Type w
inst✝¹ : DecidableEq n
inst✝ : Fintype n
p : R[X]
m : ℕ
i j : n
h✝ : ¬i = j
⊢ coeff ((p • 1) i j) m = 0

Next tactic:
simp
theorem matPolyEquiv_smul_one (p : R[X]) :
    matPolyEquiv (p • (1 : Matrix n n R[X])) = p.map (algebraMap R (Matrix n n R)) := by
  ext m i j
  simp only [coeff_map, one_apply, algebraMap_matrix_apply, mul_boole, Pi.smul_apply,
    matPolyEquiv_coeff_apply]
  split_ifs <;> simp <;> 

Proof state:
case pos
R : Type u_1
A : Type u_2
inst✝⁴ : CommSemiring R
inst✝³ : Semiring A
inst✝² : Algebra R A
n : Type w
inst✝¹ : DecidableEq n
inst✝ : Fintype n
p : R[X]
m : ℕ
i j : n
h✝ : i = j
⊢ coeff (p * OfNat.ofNat 1 i j) m = coeff p m

Next tactic:
rename_i h
theorem matPolyEquiv_smul_one (p : R[X]) :
    matPolyEquiv (p • (1 : Matrix n n R[X])) = p.map (algebraMap R (Matrix n n R)) := by
  ext m i j
  simp only [coeff_map, one_apply, algebraMap_matrix_apply, mul_boole, Pi.smul_apply,
    matPolyEquiv_coeff_apply]
  split_ifs <;> simp <;> 

Proof state:
case neg
R : Type u_1
A : Type u_2
inst✝⁴ : CommSemiring R
inst✝³ : Semiring A
inst✝² : Algebra R A
n : Type w
inst✝¹ : DecidableEq n
inst✝ : Fintype n
p : R[X]
m : ℕ
i j : n
h✝ : ¬i = j
⊢ coeff (p * OfNat.ofNat 1 i j) m = 0

Next tactic:
rename_i h
theorem matPolyEquiv_smul_one (p : R[X]) :
    matPolyEquiv (p • (1 : Matrix n n R[X])) = p.map (algebraMap R (Matrix n n R)) := by
  ext m i j
  simp only [coeff_map, one_apply, algebraMap_matrix_apply, mul_boole, Pi.smul_apply,
    matPolyEquiv_coeff_apply]
  split_ifs <;> simp <;> rename_i h <;> 

Proof state:
case pos
R : Type u_1
A : Type u_2
inst✝⁴ : CommSemiring R
inst✝³ : Semiring A
inst✝² : Algebra R A
n : Type w
inst✝¹ : DecidableEq n
inst✝ : Fintype n
p : R[X]
m : ℕ
i j : n
h : i = j
⊢ coeff (p * OfNat.ofNat 1 i j) m = coeff p m

Next tactic:
simp [h]
theorem matPolyEquiv_smul_one (p : R[X]) :
    matPolyEquiv (p • (1 : Matrix n n R[X])) = p.map (algebraMap R (Matrix n n R)) := by
  ext m i j
  simp only [coeff_map, one_apply, algebraMap_matrix_apply, mul_boole, Pi.smul_apply,
    matPolyEquiv_coeff_apply]
  split_ifs <;> simp <;> rename_i h <;> 

Proof state:
case neg
R : Type u_1
A : Type u_2
inst✝⁴ : CommSemiring R
inst✝³ : Semiring A
inst✝² : Algebra R A
n : Type w
inst✝¹ : DecidableEq n
inst✝ : Fintype n
p : R[X]
m : ℕ
i j : n
h : ¬i = j
⊢ coeff (p * OfNat.ofNat 1 i j) m = 0

Next tactic:
simp [h]
@[simp]
lemma matPolyEquiv_map_smul (p : R[X]) (M : Matrix n n R[X]) :
    matPolyEquiv (p • M) = p.map (algebraMap _ _) * matPolyEquiv M := by
  

Proof state:
R : Type u_1
A : Type u_2
inst✝⁴ : CommSemiring R
inst✝³ : Semiring A
inst✝² : Algebra R A
n : Type w
inst✝¹ : DecidableEq n
inst✝ : Fintype n
p : R[X]
M : Matrix n n R[X]
⊢ matPolyEquiv (p • M) = Polynomial.map (algebraMap R (Matrix n n R)) p * matPolyEquiv M

Next tactic:
rw [← one_mul M, ← smul_mul_assoc, _root_.map_mul, matPolyEquiv_smul_one, one_mul]
theorem support_subset_support_matPolyEquiv (m : Matrix n n R[X]) (i j : n) :
    support (m i j) ⊆ support (matPolyEquiv m) := by
  

Proof state:
R : Type u_1
A : Type u_2
inst✝⁴ : CommSemiring R
inst✝³ : Semiring A
inst✝² : Algebra R A
n : Type w
inst✝¹ : DecidableEq n
inst✝ : Fintype n
m : Matrix n n R[X]
i j : n
⊢ support (m i j) ⊆ support (matPolyEquiv m)

Next tactic:
intro k
theorem support_subset_support_matPolyEquiv (m : Matrix n n R[X]) (i j : n) :
    support (m i j) ⊆ support (matPolyEquiv m) := by
  intro k
  

Proof state:
R : Type u_1
A : Type u_2
inst✝⁴ : CommSemiring R
inst✝³ : Semiring A
inst✝² : Algebra R A
n : Type w
inst✝¹ : DecidableEq n
inst✝ : Fintype n
m : Matrix n n R[X]
i j : n
k : ℕ
⊢ k ∈ support (m i j) → k ∈ support (matPolyEquiv m)

Next tactic:
contrapose
theorem support_subset_support_matPolyEquiv (m : Matrix n n R[X]) (i j : n) :
    support (m i j) ⊆ support (matPolyEquiv m) := by
  intro k
  contrapose
  

Proof state:
R : Type u_1
A : Type u_2
inst✝⁴ : CommSemiring R
inst✝³ : Semiring A
inst✝² : Algebra R A
n : Type w
inst✝¹ : DecidableEq n
inst✝ : Fintype n
m : Matrix n n R[X]
i j : n
k : ℕ
⊢ k ∉ support (matPolyEquiv m) → k ∉ support (m i j)

Next tactic:
simp only [not_mem_support_iff]
theorem support_subset_support_matPolyEquiv (m : Matrix n n R[X]) (i j : n) :
    support (m i j) ⊆ support (matPolyEquiv m) := by
  intro k
  contrapose
  simp only [not_mem_support_iff]
  

Proof state:
R : Type u_1
A : Type u_2
inst✝⁴ : CommSemiring R
inst✝³ : Semiring A
inst✝² : Algebra R A
n : Type w
inst✝¹ : DecidableEq n
inst✝ : Fintype n
m : Matrix n n R[X]
i j : n
k : ℕ
⊢ coeff (matPolyEquiv m) k = 0 → coeff (m i j) k = 0

Next tactic:
intro hk
theorem support_subset_support_matPolyEquiv (m : Matrix n n R[X]) (i j : n) :
    support (m i j) ⊆ support (matPolyEquiv m) := by
  intro k
  contrapose
  simp only [not_mem_support_iff]
  intro hk
  

Proof state:
R : Type u_1
A : Type u_2
inst✝⁴ : CommSemiring R
inst✝³ : Semiring A
inst✝² : Algebra R A
n : Type w
inst✝¹ : DecidableEq n
inst✝ : Fintype n
m : Matrix n n R[X]
i j : n
k : ℕ
hk : coeff (matPolyEquiv m) k = 0
⊢ coeff (m i j) k = 0

Next tactic:
rw [← matPolyEquiv_coeff_apply, hk]
theorem support_subset_support_matPolyEquiv (m : Matrix n n R[X]) (i j : n) :
    support (m i j) ⊆ support (matPolyEquiv m) := by
  intro k
  contrapose
  simp only [not_mem_support_iff]
  intro hk
  rw [← matPolyEquiv_coeff_apply, hk]
  

Proof state:
R : Type u_1
A : Type u_2
inst✝⁴ : CommSemiring R
inst✝³ : Semiring A
inst✝² : Algebra R A
n : Type w
inst✝¹ : DecidableEq n
inst✝ : Fintype n
m : Matrix n n R[X]
i j : n
k : ℕ
hk : coeff (matPolyEquiv m) k = 0
⊢ OfNat.ofNat 0 i j = 0

Next tactic:
rfl
theorem conjugate_i (g : G) (v : V) : (conjugate π g : W → V) (i v) = v := by
  

Proof state:
k : Type u
inst✝⁹ : CommRing k
G : Type u
inst✝⁸ : Group G
V : Type v
inst✝⁷ : AddCommGroup V
inst✝⁶ : Module k V
inst✝⁵ : Module (MonoidAlgebra k G) V
inst✝⁴ : IsScalarTower k (MonoidAlgebra k G) V
W : Type w
inst✝³ : AddCommGroup W
inst✝² : Module k W
inst✝¹ : Module (MonoidAlgebra k G) W
inst✝ : IsScalarTower k (MonoidAlgebra k G) W
π : W →ₗ[k] V
i : V →ₗ[MonoidAlgebra k G] W
h : ∀ (v : V), π (i v) = v
g : G
v : V
⊢ (conjugate π g) (i v) = v

Next tactic:
rw [conjugate_apply, ← i.map_smul, h, ← mul_smul, single_mul_single, mul_one, mul_left_inv,
    ← one_def, one_smul]
/-- In fact, the sum over `g : G` of the conjugate of `π` by `g` is a `k[G]`-linear map.
-/
def sumOfConjugatesEquivariant : W →ₗ[MonoidAlgebra k G] V :=
  MonoidAlgebra.equivariantOfLinearOfComm (π.sumOfConjugates G) fun g v => by
    

Proof state:
k : Type u
inst✝¹⁰ : CommRing k
G : Type u
inst✝⁹ : Group G
V : Type v
inst✝⁸ : AddCommGroup V
inst✝⁷ : Module k V
inst✝⁶ : Module (MonoidAlgebra k G) V
inst✝⁵ : IsScalarTower k (MonoidAlgebra k G) V
W : Type w
inst✝⁴ : AddCommGroup W
inst✝³ : Module k W
inst✝² : Module (MonoidAlgebra k G) W
inst✝¹ : IsScalarTower k (MonoidAlgebra k G) W
π : W →ₗ[k] V
i : V →ₗ[MonoidAlgebra k G] W
h : ∀ (v : V), π (i v) = v
inst✝ : Fintype G
g : G
v : W
⊢ (sumOfConjugates G π) (MonoidAlgebra.single g 1 • v) = MonoidAlgebra.single g 1 • (sumOfConjugates G π) v

Next tactic:
simp only [sumOfConjugates_apply, Finset.smul_sum, conjugate_apply]
/-- In fact, the sum over `g : G` of the conjugate of `π` by `g` is a `k[G]`-linear map.
-/
def sumOfConjugatesEquivariant : W →ₗ[MonoidAlgebra k G] V :=
  MonoidAlgebra.equivariantOfLinearOfComm (π.sumOfConjugates G) fun g v => by
    simp only [sumOfConjugates_apply, Finset.smul_sum, conjugate_apply]
    

Proof state:
k : Type u
inst✝¹⁰ : CommRing k
G : Type u
inst✝⁹ : Group G
V : Type v
inst✝⁸ : AddCommGroup V
inst✝⁷ : Module k V
inst✝⁶ : Module (MonoidAlgebra k G) V
inst✝⁵ : IsScalarTower k (MonoidAlgebra k G) V
W : Type w
inst✝⁴ : AddCommGroup W
inst✝³ : Module k W
inst✝² : Module (MonoidAlgebra k G) W
inst✝¹ : IsScalarTower k (MonoidAlgebra k G) W
π : W →ₗ[k] V
i : V →ₗ[MonoidAlgebra k G] W
h : ∀ (v : V), π (i v) = v
inst✝ : Fintype G
g : G
v : W
⊢ ∑ x : G, MonoidAlgebra.single x⁻¹ 1 • π (MonoidAlgebra.single x 1 • MonoidAlgebra.single g 1 • v) =
    ∑ x : G, MonoidAlgebra.single g 1 • MonoidAlgebra.single x⁻¹ 1 • π (MonoidAlgebra.single x 1 • v)

Next tactic:
refine Fintype.sum_bijective (· * g) (Group.mulRight_bijective g) _ _ fun i ↦ ?_
/-- In fact, the sum over `g : G` of the conjugate of `π` by `g` is a `k[G]`-linear map.
-/
def sumOfConjugatesEquivariant : W →ₗ[MonoidAlgebra k G] V :=
  MonoidAlgebra.equivariantOfLinearOfComm (π.sumOfConjugates G) fun g v => by
    simp only [sumOfConjugates_apply, Finset.smul_sum, conjugate_apply]
    refine Fintype.sum_bijective (· * g) (Group.mulRight_bijective g) _ _ fun i ↦ ?_
    

Proof state:
k : Type u
inst✝¹⁰ : CommRing k
G : Type u
inst✝⁹ : Group G
V : Type v
inst✝⁸ : AddCommGroup V
inst✝⁷ : Module k V
inst✝⁶ : Module (MonoidAlgebra k G) V
inst✝⁵ : IsScalarTower k (MonoidAlgebra k G) V
W : Type w
inst✝⁴ : AddCommGroup W
inst✝³ : Module k W
inst✝² : Module (MonoidAlgebra k G) W
inst✝¹ : IsScalarTower k (MonoidAlgebra k G) W
π : W →ₗ[k] V
i✝ : V →ₗ[MonoidAlgebra k G] W
h : ∀ (v : V), π (i✝ v) = v
inst✝ : Fintype G
g : G
v : W
i : G
⊢ MonoidAlgebra.single i⁻¹ 1 • π (MonoidAlgebra.single i 1 • MonoidAlgebra.single g 1 • v) =
    MonoidAlgebra.single g 1 •
      MonoidAlgebra.single ((fun x => x * g) i)⁻¹ 1 • π (MonoidAlgebra.single ((fun x => x * g) i) 1 • v)

Next tactic:
simp only [smul_smul, single_mul_single, mul_inv_rev, mul_inv_cancel_left, one_mul]
theorem equivariantProjection_apply (v : W) :
    π.equivariantProjection G v = ⅟(Fintype.card G : k) • ∑ g : G, π.conjugate g v := by
  

Proof state:
k : Type u
inst✝¹¹ : CommRing k
G : Type u
inst✝¹⁰ : Group G
V : Type v
inst✝⁹ : AddCommGroup V
inst✝⁸ : Module k V
inst✝⁷ : Module (MonoidAlgebra k G) V
inst✝⁶ : IsScalarTower k (MonoidAlgebra k G) V
W : Type w
inst✝⁵ : AddCommGroup W
inst✝⁴ : Module k W
inst✝³ : Module (MonoidAlgebra k G) W
inst✝² : IsScalarTower k (MonoidAlgebra k G) W
π : W →ₗ[k] V
i : V →ₗ[MonoidAlgebra k G] W
h : ∀ (v : V), π (i v) = v
inst✝¹ : Fintype G
inst✝ : Invertible ↑(Fintype.card G)
v : W
⊢ (equivariantProjection G π) v = ⅟↑(Fintype.card G) • ∑ g : G, (conjugate π g) v

Next tactic:
simp only [equivariantProjection, smul_apply, sumOfConjugatesEquivariant_apply]
theorem equivariantProjection_condition (v : V) : (π.equivariantProjection G) (i v) = v := by
  

Proof state:
k : Type u
inst✝¹¹ : CommRing k
G : Type u
inst✝¹⁰ : Group G
V : Type v
inst✝⁹ : AddCommGroup V
inst✝⁸ : Module k V
inst✝⁷ : Module (MonoidAlgebra k G) V
inst✝⁶ : IsScalarTower k (MonoidAlgebra k G) V
W : Type w
inst✝⁵ : AddCommGroup W
inst✝⁴ : Module k W
inst✝³ : Module (MonoidAlgebra k G) W
inst✝² : IsScalarTower k (MonoidAlgebra k G) W
π : W →ₗ[k] V
i : V →ₗ[MonoidAlgebra k G] W
h : ∀ (v : V), π (i v) = v
inst✝¹ : Fintype G
inst✝ : Invertible ↑(Fintype.card G)
v : V
⊢ (equivariantProjection G π) (i v) = v

Next tactic:
rw [equivariantProjection_apply]
theorem equivariantProjection_condition (v : V) : (π.equivariantProjection G) (i v) = v := by
  rw [equivariantProjection_apply]
  

Proof state:
k : Type u
inst✝¹¹ : CommRing k
G : Type u
inst✝¹⁰ : Group G
V : Type v
inst✝⁹ : AddCommGroup V
inst✝⁸ : Module k V
inst✝⁷ : Module (MonoidAlgebra k G) V
inst✝⁶ : IsScalarTower k (MonoidAlgebra k G) V
W : Type w
inst✝⁵ : AddCommGroup W
inst✝⁴ : Module k W
inst✝³ : Module (MonoidAlgebra k G) W
inst✝² : IsScalarTower k (MonoidAlgebra k G) W
π : W →ₗ[k] V
i : V →ₗ[MonoidAlgebra k G] W
h : ∀ (v : V), π (i v) = v
inst✝¹ : Fintype G
inst✝ : Invertible ↑(Fintype.card G)
v : V
⊢ ⅟↑(Fintype.card G) • ∑ g : G, (conjugate π g) (i v) = v

Next tactic:
simp only [conjugate_i π i h]
theorem equivariantProjection_condition (v : V) : (π.equivariantProjection G) (i v) = v := by
  rw [equivariantProjection_apply]
  simp only [conjugate_i π i h]
  

Proof state:
k : Type u
inst✝¹¹ : CommRing k
G : Type u
inst✝¹⁰ : Group G
V : Type v
inst✝⁹ : AddCommGroup V
inst✝⁸ : Module k V
inst✝⁷ : Module (MonoidAlgebra k G) V
inst✝⁶ : IsScalarTower k (MonoidAlgebra k G) V
W : Type w
inst✝⁵ : AddCommGroup W
inst✝⁴ : Module k W
inst✝³ : Module (MonoidAlgebra k G) W
inst✝² : IsScalarTower k (MonoidAlgebra k G) W
π : W →ₗ[k] V
i : V →ₗ[MonoidAlgebra k G] W
h : ∀ (v : V), π (i v) = v
inst✝¹ : Fintype G
inst✝ : Invertible ↑(Fintype.card G)
v : V
⊢ ⅟↑(Fintype.card G) • ∑ x : G, v = v

Next tactic:
rw [Finset.sum_const, Finset.card_univ, nsmul_eq_smul_cast k, smul_smul,
    Invertible.invOf_mul_self, one_smul]
theorem exists_leftInverse_of_injective (f : V →ₗ[MonoidAlgebra k G] W)
    (hf : LinearMap.ker f = ⊥) :
    ∃ g : W →ₗ[MonoidAlgebra k G] V, g.comp f = LinearMap.id := by
  

Proof state:
k : Type u
inst✝¹¹ : Field k
G : Type u
inst✝¹⁰ : Fintype G
inst✝⁹ : Invertible ↑(Fintype.card G)
inst✝⁸ : Group G
V : Type u
inst✝⁷ : AddCommGroup V
inst✝⁶ : Module k V
inst✝⁵ : Module (MonoidAlgebra k G) V
inst✝⁴ : IsScalarTower k (MonoidAlgebra k G) V
W : Type u
inst✝³ : AddCommGroup W
inst✝² : Module k W
inst✝¹ : Module (MonoidAlgebra k G) W
inst✝ : IsScalarTower k (MonoidAlgebra k G) W
f : V →ₗ[MonoidAlgebra k G] W
hf : LinearMap.ker f = ⊥
⊢ ∃ g, LinearMap.comp g f = LinearMap.id

Next tactic:
obtain ⟨φ, hφ⟩ := (f.restrictScalars k).exists_leftInverse_of_injective <| by
    simp only [hf, Submodule.restrictScalars_bot, LinearMap.ker_restrictScalars]
theorem exists_leftInverse_of_injective (f : V →ₗ[MonoidAlgebra k G] W)
    (hf : LinearMap.ker f = ⊥) :
    ∃ g : W →ₗ[MonoidAlgebra k G] V, g.comp f = LinearMap.id := by
  obtain ⟨φ, hφ⟩ := (f.restrictScalars k).exists_leftInverse_of_injective <| by
    

Proof state:
k : Type u
inst✝¹¹ : Field k
G : Type u
inst✝¹⁰ : Fintype G
inst✝⁹ : Invertible ↑(Fintype.card G)
inst✝⁸ : Group G
V : Type u
inst✝⁷ : AddCommGroup V
inst✝⁶ : Module k V
inst✝⁵ : Module (MonoidAlgebra k G) V
inst✝⁴ : IsScalarTower k (MonoidAlgebra k G) V
W : Type u
inst✝³ : AddCommGroup W
inst✝² : Module k W
inst✝¹ : Module (MonoidAlgebra k G) W
inst✝ : IsScalarTower k (MonoidAlgebra k G) W
f : V →ₗ[MonoidAlgebra k G] W
hf : LinearMap.ker f = ⊥
⊢ LinearMap.ker (↑k f) = ⊥

Next tactic:
simp only [hf, Submodule.restrictScalars_bot, LinearMap.ker_restrictScalars]
theorem exists_leftInverse_of_injective (f : V →ₗ[MonoidAlgebra k G] W)
    (hf : LinearMap.ker f = ⊥) :
    ∃ g : W →ₗ[MonoidAlgebra k G] V, g.comp f = LinearMap.id := by
  obtain ⟨φ, hφ⟩ := (f.restrictScalars k).exists_leftInverse_of_injective <| by
    simp only [hf, Submodule.restrictScalars_bot, LinearMap.ker_restrictScalars]
  

Proof state:
case intro
k : Type u
inst✝¹¹ : Field k
G : Type u
inst✝¹⁰ : Fintype G
inst✝⁹ : Invertible ↑(Fintype.card G)
inst✝⁸ : Group G
V : Type u
inst✝⁷ : AddCommGroup V
inst✝⁶ : Module k V
inst✝⁵ : Module (MonoidAlgebra k G) V
inst✝⁴ : IsScalarTower k (MonoidAlgebra k G) V
W : Type u
inst✝³ : AddCommGroup W
inst✝² : Module k W
inst✝¹ : Module (MonoidAlgebra k G) W
inst✝ : IsScalarTower k (MonoidAlgebra k G) W
f : V →ₗ[MonoidAlgebra k G] W
hf : LinearMap.ker f = ⊥
φ : W →ₗ[k] V
hφ : φ ∘ₗ ↑k f = LinearMap.id
⊢ ∃ g, LinearMap.comp g f = LinearMap.id

Next tactic:
refine ⟨φ.equivariantProjection G, FunLike.ext _ _ ?_⟩
theorem exists_leftInverse_of_injective (f : V →ₗ[MonoidAlgebra k G] W)
    (hf : LinearMap.ker f = ⊥) :
    ∃ g : W →ₗ[MonoidAlgebra k G] V, g.comp f = LinearMap.id := by
  obtain ⟨φ, hφ⟩ := (f.restrictScalars k).exists_leftInverse_of_injective <| by
    simp only [hf, Submodule.restrictScalars_bot, LinearMap.ker_restrictScalars]
  refine ⟨φ.equivariantProjection G, FunLike.ext _ _ ?_⟩
  

Proof state:
case intro
k : Type u
inst✝¹¹ : Field k
G : Type u
inst✝¹⁰ : Fintype G
inst✝⁹ : Invertible ↑(Fintype.card G)
inst✝⁸ : Group G
V : Type u
inst✝⁷ : AddCommGroup V
inst✝⁶ : Module k V
inst✝⁵ : Module (MonoidAlgebra k G) V
inst✝⁴ : IsScalarTower k (MonoidAlgebra k G) V
W : Type u
inst✝³ : AddCommGroup W
inst✝² : Module k W
inst✝¹ : Module (MonoidAlgebra k G) W
inst✝ : IsScalarTower k (MonoidAlgebra k G) W
f : V →ₗ[MonoidAlgebra k G] W
hf : LinearMap.ker f = ⊥
φ : W →ₗ[k] V
hφ : φ ∘ₗ ↑k f = LinearMap.id
⊢ ∀ (x : V), (LinearMap.comp (LinearMap.equivariantProjection G φ) f) x = LinearMap.id x

Next tactic:
exact φ.equivariantProjection_condition G _ <| FunLike.congr_fun hφ
theorem exists_isCompl (p : Submodule (MonoidAlgebra k G) V) :
    ∃ q : Submodule (MonoidAlgebra k G) V, IsCompl p q := by
  

Proof state:
k : Type u
inst✝¹¹ : Field k
G : Type u
inst✝¹⁰ : Fintype G
inst✝⁹ : Invertible ↑(Fintype.card G)
inst✝⁸ : Group G
V : Type u
inst✝⁷ : AddCommGroup V
inst✝⁶ : Module k V
inst✝⁵ : Module (MonoidAlgebra k G) V
inst✝⁴ : IsScalarTower k (MonoidAlgebra k G) V
W : Type u
inst✝³ : AddCommGroup W
inst✝² : Module k W
inst✝¹ : Module (MonoidAlgebra k G) W
inst✝ : IsScalarTower k (MonoidAlgebra k G) W
p : Submodule (MonoidAlgebra k G) V
⊢ ∃ q, IsCompl p q

Next tactic:
have : IsScalarTower k (MonoidAlgebra k G) p := p.isScalarTower'
theorem exists_isCompl (p : Submodule (MonoidAlgebra k G) V) :
    ∃ q : Submodule (MonoidAlgebra k G) V, IsCompl p q := by
  have : IsScalarTower k (MonoidAlgebra k G) p := p.isScalarTower'
  

Proof state:
k : Type u
inst✝¹¹ : Field k
G : Type u
inst✝¹⁰ : Fintype G
inst✝⁹ : Invertible ↑(Fintype.card G)
inst✝⁸ : Group G
V : Type u
inst✝⁷ : AddCommGroup V
inst✝⁶ : Module k V
inst✝⁵ : Module (MonoidAlgebra k G) V
inst✝⁴ : IsScalarTower k (MonoidAlgebra k G) V
W : Type u
inst✝³ : AddCommGroup W
inst✝² : Module k W
inst✝¹ : Module (MonoidAlgebra k G) W
inst✝ : IsScalarTower k (MonoidAlgebra k G) W
p : Submodule (MonoidAlgebra k G) V
this : IsScalarTower k (MonoidAlgebra k G) ↥p
⊢ ∃ q, IsCompl p q

Next tactic:
rcases MonoidAlgebra.exists_leftInverse_of_injective p.subtype p.ker_subtype with ⟨f, hf⟩
theorem exists_isCompl (p : Submodule (MonoidAlgebra k G) V) :
    ∃ q : Submodule (MonoidAlgebra k G) V, IsCompl p q := by
  have : IsScalarTower k (MonoidAlgebra k G) p := p.isScalarTower'
  rcases MonoidAlgebra.exists_leftInverse_of_injective p.subtype p.ker_subtype with ⟨f, hf⟩
  

Proof state:
case intro
k : Type u
inst✝¹¹ : Field k
G : Type u
inst✝¹⁰ : Fintype G
inst✝⁹ : Invertible ↑(Fintype.card G)
inst✝⁸ : Group G
V : Type u
inst✝⁷ : AddCommGroup V
inst✝⁶ : Module k V
inst✝⁵ : Module (MonoidAlgebra k G) V
inst✝⁴ : IsScalarTower k (MonoidAlgebra k G) V
W : Type u
inst✝³ : AddCommGroup W
inst✝² : Module k W
inst✝¹ : Module (MonoidAlgebra k G) W
inst✝ : IsScalarTower k (MonoidAlgebra k G) W
p : Submodule (MonoidAlgebra k G) V
this : IsScalarTower k (MonoidAlgebra k G) ↥p
f : V →ₗ[MonoidAlgebra k G] ↥p
hf : LinearMap.comp f (Submodule.subtype p) = LinearMap.id
⊢ ∃ q, IsCompl p q

Next tactic:
refine ⟨LinearMap.ker f, LinearMap.isCompl_of_proj ?_⟩
theorem exists_isCompl (p : Submodule (MonoidAlgebra k G) V) :
    ∃ q : Submodule (MonoidAlgebra k G) V, IsCompl p q := by
  have : IsScalarTower k (MonoidAlgebra k G) p := p.isScalarTower'
  rcases MonoidAlgebra.exists_leftInverse_of_injective p.subtype p.ker_subtype with ⟨f, hf⟩
  refine ⟨LinearMap.ker f, LinearMap.isCompl_of_proj ?_⟩
  

Proof state:
case intro
k : Type u
inst✝¹¹ : Field k
G : Type u
inst✝¹⁰ : Fintype G
inst✝⁹ : Invertible ↑(Fintype.card G)
inst✝⁸ : Group G
V : Type u
inst✝⁷ : AddCommGroup V
inst✝⁶ : Module k V
inst✝⁵ : Module (MonoidAlgebra k G) V
inst✝⁴ : IsScalarTower k (MonoidAlgebra k G) V
W : Type u
inst✝³ : AddCommGroup W
inst✝² : Module k W
inst✝¹ : Module (MonoidAlgebra k G) W
inst✝ : IsScalarTower k (MonoidAlgebra k G) W
p : Submodule (MonoidAlgebra k G) V
this : IsScalarTower k (MonoidAlgebra k G) ↥p
f : V →ₗ[MonoidAlgebra k G] ↥p
hf : LinearMap.comp f (Submodule.subtype p) = LinearMap.id
⊢ ∀ (x : ↥p), f ↑x = x

Next tactic:
exact FunLike.congr_fun hf
example : orderOf (-1 : ℤˣ) = 2 :=
  orderOf_eq_prime (Int.units_sq _) (by 

Proof state:
α : Type u
β : Type v
⊢ -1 ≠ 1

Next tactic:
decide
/-- `modSwap i j` contains permutations up to swapping `i` and `j`.

We use this to partition permutations in `Matrix.det_zero_of_row_eq`, such that each partition
sums up to `0`.
-/
def modSwap [DecidableEq α] (i j : α) : Setoid (Perm α) :=
  ⟨fun σ τ => σ = τ ∨ σ = swap i j * τ, fun σ => Or.inl (refl σ), fun {σ τ} h =>
    Or.casesOn h (fun h => Or.inl h.symm) fun h => Or.inr (by 

Proof state:
α : Type u
β : Type v
inst✝ : DecidableEq α
i j : α
σ τ : Perm α
h✝ : σ = τ ∨ σ = swap i j * τ
h : σ = swap i j * τ
⊢ τ = swap i j * σ

Next tactic:
rw [h, swap_mul_self_mul]
/-- `modSwap i j` contains permutations up to swapping `i` and `j`.

We use this to partition permutations in `Matrix.det_zero_of_row_eq`, such that each partition
sums up to `0`.
-/
def modSwap [DecidableEq α] (i j : α) : Setoid (Perm α) :=
  ⟨fun σ τ => σ = τ ∨ σ = swap i j * τ, fun σ => Or.inl (refl σ), fun {σ τ} h =>
    Or.casesOn h (fun h => Or.inl h.symm) fun h => Or.inr (by rw [h, swap_mul_self_mul]),
    fun {σ τ υ} hστ hτυ => by
    

Proof state:
α : Type u
β : Type v
inst✝ : DecidableEq α
i j : α
σ τ υ : Perm α
hστ : σ = τ ∨ σ = swap i j * τ
hτυ : τ = υ ∨ τ = swap i j * υ
⊢ σ = υ ∨ σ = swap i j * υ

Next tactic:
cases' hστ with hστ hστ
/-- `modSwap i j` contains permutations up to swapping `i` and `j`.

We use this to partition permutations in `Matrix.det_zero_of_row_eq`, such that each partition
sums up to `0`.
-/
def modSwap [DecidableEq α] (i j : α) : Setoid (Perm α) :=
  ⟨fun σ τ => σ = τ ∨ σ = swap i j * τ, fun σ => Or.inl (refl σ), fun {σ τ} h =>
    Or.casesOn h (fun h => Or.inl h.symm) fun h => Or.inr (by rw [h, swap_mul_self_mul]),
    fun {σ τ υ} hστ hτυ => by
    cases' hστ with hστ hστ <;> 

Proof state:
case inl
α : Type u
β : Type v
inst✝ : DecidableEq α
i j : α
σ τ υ : Perm α
hτυ : τ = υ ∨ τ = swap i j * υ
hστ : σ = τ
⊢ σ = υ ∨ σ = swap i j * υ

Next tactic:
cases' hτυ with hτυ hτυ
/-- `modSwap i j` contains permutations up to swapping `i` and `j`.

We use this to partition permutations in `Matrix.det_zero_of_row_eq`, such that each partition
sums up to `0`.
-/
def modSwap [DecidableEq α] (i j : α) : Setoid (Perm α) :=
  ⟨fun σ τ => σ = τ ∨ σ = swap i j * τ, fun σ => Or.inl (refl σ), fun {σ τ} h =>
    Or.casesOn h (fun h => Or.inl h.symm) fun h => Or.inr (by rw [h, swap_mul_self_mul]),
    fun {σ τ υ} hστ hτυ => by
    cases' hστ with hστ hστ <;> 

Proof state:
case inr
α : Type u
β : Type v
inst✝ : DecidableEq α
i j : α
σ τ υ : Perm α
hτυ : τ = υ ∨ τ = swap i j * υ
hστ : σ = swap i j * τ
⊢ σ = υ ∨ σ = swap i j * υ

Next tactic:
cases' hτυ with hτυ hτυ