l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem trace_conj' (f : M →ₗ[R] M) (e : M ≃ₗ[R] N) : trace R N (e.conj f) = trace R M f := by
  classical
  by_cases hM : ∃ s : Finset M, Nonempty (Basis s R M)
  · obtain ⟨s, ⟨b⟩⟩ := hM
    haveI := Module.Finite.of_basis b
    haveI := (Module.free_def R M).mpr ⟨_, ⟨b⟩⟩
    haveI := Module.Finite.of_basis (b.map e)
    haveI := (Module.free_def R N).mpr ⟨_, ⟨(b.map e).reindex (e.toEquiv.image _)⟩⟩
    rw [e.conj_apply, trace_comp_comm', ← comp_assoc, LinearEquiv.comp_coe,
      LinearEquiv.self_trans_symm, LinearEquiv.refl_toLinearMap, id_comp]
  · rw [trace, trace, dif_neg hM, dif_neg]; rfl
    rintro ⟨s, ⟨b⟩⟩
    

Proof state:
case neg.hnc.intro.intro
R : Type u_1
inst✝¹² : CommRing R
M : Type u_2
inst✝¹¹ : AddCommGroup M
inst✝¹⁰ : Module R M
N : Type u_3
P : Type u_4
inst✝⁹ : AddCommGroup N
inst✝⁸ : Module R N
inst✝⁷ : AddCommGroup P
inst✝⁶ : Module R P
ι : Type u_5
inst✝⁵ : Module.Free R M
inst✝⁴ : Module.Finite R M
inst✝³ : Module.Free R N
inst✝² : Module.Finite R N
inst✝¹ : Module.Free R P
inst✝ : Module.Finite R P
f : M →ₗ[R] M
e : M ≃ₗ[R] N
hM : ¬∃ s, Nonempty (Basis { x // x ∈ s } R M)
s : Finset N
b : Basis { x // x ∈ s } R N
⊢ False

Next tactic:
exact hM ⟨s.image e.symm, ⟨(b.map e.symm).reindex
      ((e.symm.toEquiv.image s).trans (Equiv.Set.ofEq Finset.coe_image.symm))⟩⟩
theorem IsProj.trace {p : Submodule R M} {f : M →ₗ[R] M} (h : IsProj p f) [Module.Free R p]
    [Module.Finite R p] [Module.Free R (ker f)] [Module.Finite R (ker f)] :
    trace R M f = (finrank R p : R) := by
  

Proof state:
R : Type u_1
inst✝¹⁶ : CommRing R
M : Type u_2
inst✝¹⁵ : AddCommGroup M
inst✝¹⁴ : Module R M
N : Type u_3
P : Type u_4
inst✝¹³ : AddCommGroup N
inst✝¹² : Module R N
inst✝¹¹ : AddCommGroup P
inst✝¹⁰ : Module R P
ι : Type u_5
inst✝⁹ : Module.Free R M
inst✝⁸ : Module.Finite R M
inst✝⁷ : Module.Free R N
inst✝⁶ : Module.Finite R N
inst✝⁵ : Module.Free R P
inst✝⁴ : Module.Finite R P
p : Submodule R M
f : M →ₗ[R] M
h : IsProj p f
inst✝³ : Module.Free R ↥p
inst✝² : Module.Finite R ↥p
inst✝¹ : Module.Free R ↥(ker f)
inst✝ : Module.Finite R ↥(ker f)
⊢ (LinearMap.trace R M) f = ↑(finrank R ↥p)

Next tactic:
rw [h.eq_conj_prodMap, trace_conj', trace_prodMap', trace_id, map_zero, add_zero]
lemma isNilpotent_trace_of_isNilpotent {f : M →ₗ[R] M} (hf : IsNilpotent f) :
    IsNilpotent (trace R M f) := by
  

Proof state:
R : Type u_1
inst✝¹² : CommRing R
M : Type u_2
inst✝¹¹ : AddCommGroup M
inst✝¹⁰ : Module R M
N : Type u_3
P : Type u_4
inst✝⁹ : AddCommGroup N
inst✝⁸ : Module R N
inst✝⁷ : AddCommGroup P
inst✝⁶ : Module R P
ι : Type u_5
inst✝⁵ : Module.Free R M
inst✝⁴ : Module.Finite R M
inst✝³ : Module.Free R N
inst✝² : Module.Finite R N
inst✝¹ : Module.Free R P
inst✝ : Module.Finite R P
f : M →ₗ[R] M
hf : IsNilpotent f
⊢ IsNilpotent ((trace R M) f)

Next tactic:
let b : Basis _ R M := Module.Free.chooseBasis R M
lemma isNilpotent_trace_of_isNilpotent {f : M →ₗ[R] M} (hf : IsNilpotent f) :
    IsNilpotent (trace R M f) := by
  let b : Basis _ R M := Module.Free.chooseBasis R M
  

Proof state:
R : Type u_1
inst✝¹² : CommRing R
M : Type u_2
inst✝¹¹ : AddCommGroup M
inst✝¹⁰ : Module R M
N : Type u_3
P : Type u_4
inst✝⁹ : AddCommGroup N
inst✝⁸ : Module R N
inst✝⁷ : AddCommGroup P
inst✝⁶ : Module R P
ι : Type u_5
inst✝⁵ : Module.Free R M
inst✝⁴ : Module.Finite R M
inst✝³ : Module.Free R N
inst✝² : Module.Finite R N
inst✝¹ : Module.Free R P
inst✝ : Module.Finite R P
f : M →ₗ[R] M
hf : IsNilpotent f
b : Basis (Module.Free.ChooseBasisIndex R M) R M := Module.Free.chooseBasis R M
⊢ IsNilpotent ((trace R M) f)

Next tactic:
rw [trace_eq_matrix_trace R b]
lemma isNilpotent_trace_of_isNilpotent {f : M →ₗ[R] M} (hf : IsNilpotent f) :
    IsNilpotent (trace R M f) := by
  let b : Basis _ R M := Module.Free.chooseBasis R M
  rw [trace_eq_matrix_trace R b]
  

Proof state:
R : Type u_1
inst✝¹² : CommRing R
M : Type u_2
inst✝¹¹ : AddCommGroup M
inst✝¹⁰ : Module R M
N : Type u_3
P : Type u_4
inst✝⁹ : AddCommGroup N
inst✝⁸ : Module R N
inst✝⁷ : AddCommGroup P
inst✝⁶ : Module R P
ι : Type u_5
inst✝⁵ : Module.Free R M
inst✝⁴ : Module.Finite R M
inst✝³ : Module.Free R N
inst✝² : Module.Finite R N
inst✝¹ : Module.Free R P
inst✝ : Module.Finite R P
f : M →ₗ[R] M
hf : IsNilpotent f
b : Basis (Module.Free.ChooseBasisIndex R M) R M := Module.Free.chooseBasis R M
⊢ IsNilpotent (Matrix.trace ((toMatrix b b) f))

Next tactic:
apply Matrix.isNilpotent_trace_of_isNilpotent
lemma isNilpotent_trace_of_isNilpotent {f : M →ₗ[R] M} (hf : IsNilpotent f) :
    IsNilpotent (trace R M f) := by
  let b : Basis _ R M := Module.Free.chooseBasis R M
  rw [trace_eq_matrix_trace R b]
  apply Matrix.isNilpotent_trace_of_isNilpotent
  

Proof state:
case hM
R : Type u_1
inst✝¹² : CommRing R
M : Type u_2
inst✝¹¹ : AddCommGroup M
inst✝¹⁰ : Module R M
N : Type u_3
P : Type u_4
inst✝⁹ : AddCommGroup N
inst✝⁸ : Module R N
inst✝⁷ : AddCommGroup P
inst✝⁶ : Module R P
ι : Type u_5
inst✝⁵ : Module.Free R M
inst✝⁴ : Module.Finite R M
inst✝³ : Module.Free R N
inst✝² : Module.Finite R N
inst✝¹ : Module.Free R P
inst✝ : Module.Finite R P
f : M →ₗ[R] M
hf : IsNilpotent f
b : Basis (Module.Free.ChooseBasisIndex R M) R M := Module.Free.chooseBasis R M
⊢ IsNilpotent ((toMatrix b b) f)

Next tactic:
simpa
lemma trace_comp_eq_mul_of_commute_of_isNilpotent [IsReduced R] {f g : Module.End R M}
    (μ : R) (h_comm : Commute f g) (hg : IsNilpotent (g - algebraMap R _ μ)) :
    trace R M (f ∘ₗ g) = μ * trace R M f := by
  

Proof state:
R : Type u_1
inst✝¹³ : CommRing R
M : Type u_2
inst✝¹² : AddCommGroup M
inst✝¹¹ : Module R M
N : Type u_3
P : Type u_4
inst✝¹⁰ : AddCommGroup N
inst✝⁹ : Module R N
inst✝⁸ : AddCommGroup P
inst✝⁷ : Module R P
ι : Type u_5
inst✝⁶ : Module.Free R M
inst✝⁵ : Module.Finite R M
inst✝⁴ : Module.Free R N
inst✝³ : Module.Finite R N
inst✝² : Module.Free R P
inst✝¹ : Module.Finite R P
inst✝ : IsReduced R
f g : Module.End R M
μ : R
h_comm : Commute f g
hg : IsNilpotent (g - (algebraMap R (Module.End R M)) μ)
⊢ (trace R M) (f ∘ₗ g) = μ * (trace R M) f

Next tactic:
set n := g - algebraMap R _ μ
lemma trace_comp_eq_mul_of_commute_of_isNilpotent [IsReduced R] {f g : Module.End R M}
    (μ : R) (h_comm : Commute f g) (hg : IsNilpotent (g - algebraMap R _ μ)) :
    trace R M (f ∘ₗ g) = μ * trace R M f := by
  set n := g - algebraMap R _ μ
  

Proof state:
R : Type u_1
inst✝¹³ : CommRing R
M : Type u_2
inst✝¹² : AddCommGroup M
inst✝¹¹ : Module R M
N : Type u_3
P : Type u_4
inst✝¹⁰ : AddCommGroup N
inst✝⁹ : Module R N
inst✝⁸ : AddCommGroup P
inst✝⁷ : Module R P
ι : Type u_5
inst✝⁶ : Module.Free R M
inst✝⁵ : Module.Finite R M
inst✝⁴ : Module.Free R N
inst✝³ : Module.Finite R N
inst✝² : Module.Free R P
inst✝¹ : Module.Finite R P
inst✝ : IsReduced R
f g : Module.End R M
μ : R
h_comm : Commute f g
n : Module.End R M := g - (algebraMap R (Module.End R M)) μ
hg : IsNilpotent n
⊢ (trace R M) (f ∘ₗ g) = μ * (trace R M) f

Next tactic:
replace hg : trace R M (f ∘ₗ n) = 0 := by
    rw [← isNilpotent_iff_eq_zero, ← mul_eq_comp]
    refine isNilpotent_trace_of_isNilpotent (Commute.isNilpotent_mul_right ?_ hg)
    exact h_comm.sub_right (Algebra.commute_algebraMap_right μ f)
lemma trace_comp_eq_mul_of_commute_of_isNilpotent [IsReduced R] {f g : Module.End R M}
    (μ : R) (h_comm : Commute f g) (hg : IsNilpotent (g - algebraMap R _ μ)) :
    trace R M (f ∘ₗ g) = μ * trace R M f := by
  set n := g - algebraMap R _ μ
  replace hg : trace R M (f ∘ₗ n) = 0 := by
    

Proof state:
R : Type u_1
inst✝¹³ : CommRing R
M : Type u_2
inst✝¹² : AddCommGroup M
inst✝¹¹ : Module R M
N : Type u_3
P : Type u_4
inst✝¹⁰ : AddCommGroup N
inst✝⁹ : Module R N
inst✝⁸ : AddCommGroup P
inst✝⁷ : Module R P
ι : Type u_5
inst✝⁶ : Module.Free R M
inst✝⁵ : Module.Finite R M
inst✝⁴ : Module.Free R N
inst✝³ : Module.Finite R N
inst✝² : Module.Free R P
inst✝¹ : Module.Finite R P
inst✝ : IsReduced R
f g : Module.End R M
μ : R
h_comm : Commute f g
n : Module.End R M := g - (algebraMap R (Module.End R M)) μ
hg : IsNilpotent n
⊢ (trace R M) (f ∘ₗ n) = 0

Next tactic:
rw [← isNilpotent_iff_eq_zero, ← mul_eq_comp]
lemma trace_comp_eq_mul_of_commute_of_isNilpotent [IsReduced R] {f g : Module.End R M}
    (μ : R) (h_comm : Commute f g) (hg : IsNilpotent (g - algebraMap R _ μ)) :
    trace R M (f ∘ₗ g) = μ * trace R M f := by
  set n := g - algebraMap R _ μ
  replace hg : trace R M (f ∘ₗ n) = 0 := by
    rw [← isNilpotent_iff_eq_zero, ← mul_eq_comp]
    

Proof state:
R : Type u_1
inst✝¹³ : CommRing R
M : Type u_2
inst✝¹² : AddCommGroup M
inst✝¹¹ : Module R M
N : Type u_3
P : Type u_4
inst✝¹⁰ : AddCommGroup N
inst✝⁹ : Module R N
inst✝⁸ : AddCommGroup P
inst✝⁷ : Module R P
ι : Type u_5
inst✝⁶ : Module.Free R M
inst✝⁵ : Module.Finite R M
inst✝⁴ : Module.Free R N
inst✝³ : Module.Finite R N
inst✝² : Module.Free R P
inst✝¹ : Module.Finite R P
inst✝ : IsReduced R
f g : Module.End R M
μ : R
h_comm : Commute f g
n : Module.End R M := g - (algebraMap R (Module.End R M)) μ
hg : IsNilpotent n
⊢ IsNilpotent ((trace R M) (f * n))

Next tactic:
refine isNilpotent_trace_of_isNilpotent (Commute.isNilpotent_mul_right ?_ hg)
lemma trace_comp_eq_mul_of_commute_of_isNilpotent [IsReduced R] {f g : Module.End R M}
    (μ : R) (h_comm : Commute f g) (hg : IsNilpotent (g - algebraMap R _ μ)) :
    trace R M (f ∘ₗ g) = μ * trace R M f := by
  set n := g - algebraMap R _ μ
  replace hg : trace R M (f ∘ₗ n) = 0 := by
    rw [← isNilpotent_iff_eq_zero, ← mul_eq_comp]
    refine isNilpotent_trace_of_isNilpotent (Commute.isNilpotent_mul_right ?_ hg)
    

Proof state:
R : Type u_1
inst✝¹³ : CommRing R
M : Type u_2
inst✝¹² : AddCommGroup M
inst✝¹¹ : Module R M
N : Type u_3
P : Type u_4
inst✝¹⁰ : AddCommGroup N
inst✝⁹ : Module R N
inst✝⁸ : AddCommGroup P
inst✝⁷ : Module R P
ι : Type u_5
inst✝⁶ : Module.Free R M
inst✝⁵ : Module.Finite R M
inst✝⁴ : Module.Free R N
inst✝³ : Module.Finite R N
inst✝² : Module.Free R P
inst✝¹ : Module.Finite R P
inst✝ : IsReduced R
f g : Module.End R M
μ : R
h_comm : Commute f g
n : Module.End R M := g - (algebraMap R (Module.End R M)) μ
hg : IsNilpotent n
⊢ Commute f n

Next tactic:
exact h_comm.sub_right (Algebra.commute_algebraMap_right μ f)
lemma trace_comp_eq_mul_of_commute_of_isNilpotent [IsReduced R] {f g : Module.End R M}
    (μ : R) (h_comm : Commute f g) (hg : IsNilpotent (g - algebraMap R _ μ)) :
    trace R M (f ∘ₗ g) = μ * trace R M f := by
  set n := g - algebraMap R _ μ
  replace hg : trace R M (f ∘ₗ n) = 0 := by
    rw [← isNilpotent_iff_eq_zero, ← mul_eq_comp]
    refine isNilpotent_trace_of_isNilpotent (Commute.isNilpotent_mul_right ?_ hg)
    exact h_comm.sub_right (Algebra.commute_algebraMap_right μ f)
  

Proof state:
R : Type u_1
inst✝¹³ : CommRing R
M : Type u_2
inst✝¹² : AddCommGroup M
inst✝¹¹ : Module R M
N : Type u_3
P : Type u_4
inst✝¹⁰ : AddCommGroup N
inst✝⁹ : Module R N
inst✝⁸ : AddCommGroup P
inst✝⁷ : Module R P
ι : Type u_5
inst✝⁶ : Module.Free R M
inst✝⁵ : Module.Finite R M
inst✝⁴ : Module.Free R N
inst✝³ : Module.Finite R N
inst✝² : Module.Free R P
inst✝¹ : Module.Finite R P
inst✝ : IsReduced R
f g : Module.End R M
μ : R
h_comm : Commute f g
n : Module.End R M := g - (algebraMap R (Module.End R M)) μ
hg : (trace R M) (f ∘ₗ n) = 0
⊢ (trace R M) (f ∘ₗ g) = μ * (trace R M) f

Next tactic:
have hμ : g = algebraMap R _ μ + n := eq_add_of_sub_eq' rfl
lemma trace_comp_eq_mul_of_commute_of_isNilpotent [IsReduced R] {f g : Module.End R M}
    (μ : R) (h_comm : Commute f g) (hg : IsNilpotent (g - algebraMap R _ μ)) :
    trace R M (f ∘ₗ g) = μ * trace R M f := by
  set n := g - algebraMap R _ μ
  replace hg : trace R M (f ∘ₗ n) = 0 := by
    rw [← isNilpotent_iff_eq_zero, ← mul_eq_comp]
    refine isNilpotent_trace_of_isNilpotent (Commute.isNilpotent_mul_right ?_ hg)
    exact h_comm.sub_right (Algebra.commute_algebraMap_right μ f)
  have hμ : g = algebraMap R _ μ + n := eq_add_of_sub_eq' rfl
  

Proof state:
R : Type u_1
inst✝¹³ : CommRing R
M : Type u_2
inst✝¹² : AddCommGroup M
inst✝¹¹ : Module R M
N : Type u_3
P : Type u_4
inst✝¹⁰ : AddCommGroup N
inst✝⁹ : Module R N
inst✝⁸ : AddCommGroup P
inst✝⁷ : Module R P
ι : Type u_5
inst✝⁶ : Module.Free R M
inst✝⁵ : Module.Finite R M
inst✝⁴ : Module.Free R N
inst✝³ : Module.Finite R N
inst✝² : Module.Free R P
inst✝¹ : Module.Finite R P
inst✝ : IsReduced R
f g : Module.End R M
μ : R
h_comm : Commute f g
n : Module.End R M := g - (algebraMap R (Module.End R M)) μ
hg : (trace R M) (f ∘ₗ n) = 0
hμ : g = (algebraMap R (Module.End R M)) μ + n
⊢ (trace R M) (f ∘ₗ g) = μ * (trace R M) f

Next tactic:
have : f ∘ₗ algebraMap R _ μ = μ • f := by ext; simp
lemma trace_comp_eq_mul_of_commute_of_isNilpotent [IsReduced R] {f g : Module.End R M}
    (μ : R) (h_comm : Commute f g) (hg : IsNilpotent (g - algebraMap R _ μ)) :
    trace R M (f ∘ₗ g) = μ * trace R M f := by
  set n := g - algebraMap R _ μ
  replace hg : trace R M (f ∘ₗ n) = 0 := by
    rw [← isNilpotent_iff_eq_zero, ← mul_eq_comp]
    refine isNilpotent_trace_of_isNilpotent (Commute.isNilpotent_mul_right ?_ hg)
    exact h_comm.sub_right (Algebra.commute_algebraMap_right μ f)
  have hμ : g = algebraMap R _ μ + n := eq_add_of_sub_eq' rfl
  have : f ∘ₗ algebraMap R _ μ = μ • f := by 

Proof state:
R : Type u_1
inst✝¹³ : CommRing R
M : Type u_2
inst✝¹² : AddCommGroup M
inst✝¹¹ : Module R M
N : Type u_3
P : Type u_4
inst✝¹⁰ : AddCommGroup N
inst✝⁹ : Module R N
inst✝⁸ : AddCommGroup P
inst✝⁷ : Module R P
ι : Type u_5
inst✝⁶ : Module.Free R M
inst✝⁵ : Module.Finite R M
inst✝⁴ : Module.Free R N
inst✝³ : Module.Finite R N
inst✝² : Module.Free R P
inst✝¹ : Module.Finite R P
inst✝ : IsReduced R
f g : Module.End R M
μ : R
h_comm : Commute f g
n : Module.End R M := g - (algebraMap R (Module.End R M)) μ
hg : (trace R M) (f ∘ₗ n) = 0
hμ : g = (algebraMap R (Module.End R M)) μ + n
⊢ f ∘ₗ (algebraMap R (M →ₗ[R] M)) μ = μ • f

Next tactic:
ext
lemma trace_comp_eq_mul_of_commute_of_isNilpotent [IsReduced R] {f g : Module.End R M}
    (μ : R) (h_comm : Commute f g) (hg : IsNilpotent (g - algebraMap R _ μ)) :
    trace R M (f ∘ₗ g) = μ * trace R M f := by
  set n := g - algebraMap R _ μ
  replace hg : trace R M (f ∘ₗ n) = 0 := by
    rw [← isNilpotent_iff_eq_zero, ← mul_eq_comp]
    refine isNilpotent_trace_of_isNilpotent (Commute.isNilpotent_mul_right ?_ hg)
    exact h_comm.sub_right (Algebra.commute_algebraMap_right μ f)
  have hμ : g = algebraMap R _ μ + n := eq_add_of_sub_eq' rfl
  have : f ∘ₗ algebraMap R _ μ = μ • f := by ext; 

Proof state:
case h
R : Type u_1
inst✝¹³ : CommRing R
M : Type u_2
inst✝¹² : AddCommGroup M
inst✝¹¹ : Module R M
N : Type u_3
P : Type u_4
inst✝¹⁰ : AddCommGroup N
inst✝⁹ : Module R N
inst✝⁸ : AddCommGroup P
inst✝⁷ : Module R P
ι : Type u_5
inst✝⁶ : Module.Free R M
inst✝⁵ : Module.Finite R M
inst✝⁴ : Module.Free R N
inst✝³ : Module.Finite R N
inst✝² : Module.Free R P
inst✝¹ : Module.Finite R P
inst✝ : IsReduced R
f g : Module.End R M
μ : R
h_comm : Commute f g
n : Module.End R M := g - (algebraMap R (Module.End R M)) μ
hg : (trace R M) (f ∘ₗ n) = 0
hμ : g = (algebraMap R (Module.End R M)) μ + n
x✝ : M
⊢ (f ∘ₗ (algebraMap R (M →ₗ[R] M)) μ) x✝ = (μ • f) x✝

Next tactic:
simp
lemma trace_comp_eq_mul_of_commute_of_isNilpotent [IsReduced R] {f g : Module.End R M}
    (μ : R) (h_comm : Commute f g) (hg : IsNilpotent (g - algebraMap R _ μ)) :
    trace R M (f ∘ₗ g) = μ * trace R M f := by
  set n := g - algebraMap R _ μ
  replace hg : trace R M (f ∘ₗ n) = 0 := by
    rw [← isNilpotent_iff_eq_zero, ← mul_eq_comp]
    refine isNilpotent_trace_of_isNilpotent (Commute.isNilpotent_mul_right ?_ hg)
    exact h_comm.sub_right (Algebra.commute_algebraMap_right μ f)
  have hμ : g = algebraMap R _ μ + n := eq_add_of_sub_eq' rfl
  have : f ∘ₗ algebraMap R _ μ = μ • f := by ext; simp -- TODO Surely exists?
  

Proof state:
R : Type u_1
inst✝¹³ : CommRing R
M : Type u_2
inst✝¹² : AddCommGroup M
inst✝¹¹ : Module R M
N : Type u_3
P : Type u_4
inst✝¹⁰ : AddCommGroup N
inst✝⁹ : Module R N
inst✝⁸ : AddCommGroup P
inst✝⁷ : Module R P
ι : Type u_5
inst✝⁶ : Module.Free R M
inst✝⁵ : Module.Finite R M
inst✝⁴ : Module.Free R N
inst✝³ : Module.Finite R N
inst✝² : Module.Free R P
inst✝¹ : Module.Finite R P
inst✝ : IsReduced R
f g : Module.End R M
μ : R
h_comm : Commute f g
n : Module.End R M := g - (algebraMap R (Module.End R M)) μ
hg : (trace R M) (f ∘ₗ n) = 0
hμ : g = (algebraMap R (Module.End R M)) μ + n
this : f ∘ₗ (algebraMap R (M →ₗ[R] M)) μ = μ • f
⊢ (trace R M) (f ∘ₗ g) = μ * (trace R M) f

Next tactic:
rw [hμ, comp_add, map_add, hg, add_zero, this, LinearMap.map_smul, smul_eq_mul]
@[simp]
lemma trace_baseChange [Module.Free R M] [Module.Finite R M]
    (f : M →ₗ[R] M) (A : Type*) [CommRing A] [Algebra R A] :
    trace A _ (f.baseChange A) = algebraMap R A (trace R _ f) := by
  

Proof state:
R : Type u_1
inst✝¹⁶ : CommRing R
M : Type u_2
inst✝¹⁵ : AddCommGroup M
inst✝¹⁴ : Module R M
N : Type u_3
P : Type u_4
inst✝¹³ : AddCommGroup N
inst✝¹² : Module R N
inst✝¹¹ : AddCommGroup P
inst✝¹⁰ : Module R P
ι : Type u_5
inst✝⁹ : Module.Free R M
inst✝⁸ : Module.Finite R M
inst✝⁷ : Module.Free R N
inst✝⁶ : Module.Finite R N
inst✝⁵ : Module.Free R P
inst✝⁴ : Module.Finite R P
inst✝³ : Module.Free R M
inst✝² : Module.Finite R M
f : M →ₗ[R] M
A : Type u_6
inst✝¹ : CommRing A
inst✝ : Algebra R A
⊢ (trace A (A ⊗[R] M)) (baseChange A f) = (algebraMap R A) ((trace R M) f)

Next tactic:
let b := Module.Free.chooseBasis R M
@[simp]
lemma trace_baseChange [Module.Free R M] [Module.Finite R M]
    (f : M →ₗ[R] M) (A : Type*) [CommRing A] [Algebra R A] :
    trace A _ (f.baseChange A) = algebraMap R A (trace R _ f) := by
  let b := Module.Free.chooseBasis R M
  

Proof state:
R : Type u_1
inst✝¹⁶ : CommRing R
M : Type u_2
inst✝¹⁵ : AddCommGroup M
inst✝¹⁴ : Module R M
N : Type u_3
P : Type u_4
inst✝¹³ : AddCommGroup N
inst✝¹² : Module R N
inst✝¹¹ : AddCommGroup P
inst✝¹⁰ : Module R P
ι : Type u_5
inst✝⁹ : Module.Free R M
inst✝⁸ : Module.Finite R M
inst✝⁷ : Module.Free R N
inst✝⁶ : Module.Finite R N
inst✝⁵ : Module.Free R P
inst✝⁴ : Module.Finite R P
inst✝³ : Module.Free R M
inst✝² : Module.Finite R M
f : M →ₗ[R] M
A : Type u_6
inst✝¹ : CommRing A
inst✝ : Algebra R A
b : Basis (Module.Free.ChooseBasisIndex R M) R M := Module.Free.chooseBasis R M
⊢ (trace A (A ⊗[R] M)) (baseChange A f) = (algebraMap R A) ((trace R M) f)

Next tactic:
let b' := Algebra.TensorProduct.basis A b
@[simp]
lemma trace_baseChange [Module.Free R M] [Module.Finite R M]
    (f : M →ₗ[R] M) (A : Type*) [CommRing A] [Algebra R A] :
    trace A _ (f.baseChange A) = algebraMap R A (trace R _ f) := by
  let b := Module.Free.chooseBasis R M
  let b' := Algebra.TensorProduct.basis A b
  

Proof state:
R : Type u_1
inst✝¹⁶ : CommRing R
M : Type u_2
inst✝¹⁵ : AddCommGroup M
inst✝¹⁴ : Module R M
N : Type u_3
P : Type u_4
inst✝¹³ : AddCommGroup N
inst✝¹² : Module R N
inst✝¹¹ : AddCommGroup P
inst✝¹⁰ : Module R P
ι : Type u_5
inst✝⁹ : Module.Free R M
inst✝⁸ : Module.Finite R M
inst✝⁷ : Module.Free R N
inst✝⁶ : Module.Finite R N
inst✝⁵ : Module.Free R P
inst✝⁴ : Module.Finite R P
inst✝³ : Module.Free R M
inst✝² : Module.Finite R M
f : M →ₗ[R] M
A : Type u_6
inst✝¹ : CommRing A
inst✝ : Algebra R A
b : Basis (Module.Free.ChooseBasisIndex R M) R M := Module.Free.chooseBasis R M
b' : Basis (Module.Free.ChooseBasisIndex R M) A (A ⊗[R] M) := Algebra.TensorProduct.basis A b
⊢ (trace A (A ⊗[R] M)) (baseChange A f) = (algebraMap R A) ((trace R M) f)

Next tactic:
change _ = (algebraMap R A : R →+ A) _
@[simp]
lemma trace_baseChange [Module.Free R M] [Module.Finite R M]
    (f : M →ₗ[R] M) (A : Type*) [CommRing A] [Algebra R A] :
    trace A _ (f.baseChange A) = algebraMap R A (trace R _ f) := by
  let b := Module.Free.chooseBasis R M
  let b' := Algebra.TensorProduct.basis A b
  change _ = (algebraMap R A : R →+ A) _
  

Proof state:
R : Type u_1
inst✝¹⁶ : CommRing R
M : Type u_2
inst✝¹⁵ : AddCommGroup M
inst✝¹⁴ : Module R M
N : Type u_3
P : Type u_4
inst✝¹³ : AddCommGroup N
inst✝¹² : Module R N
inst✝¹¹ : AddCommGroup P
inst✝¹⁰ : Module R P
ι : Type u_5
inst✝⁹ : Module.Free R M
inst✝⁸ : Module.Finite R M
inst✝⁷ : Module.Free R N
inst✝⁶ : Module.Finite R N
inst✝⁵ : Module.Free R P
inst✝⁴ : Module.Finite R P
inst✝³ : Module.Free R M
inst✝² : Module.Finite R M
f : M →ₗ[R] M
A : Type u_6
inst✝¹ : CommRing A
inst✝ : Algebra R A
b : Basis (Module.Free.ChooseBasisIndex R M) R M := Module.Free.chooseBasis R M
b' : Basis (Module.Free.ChooseBasisIndex R M) A (A ⊗[R] M) := Algebra.TensorProduct.basis A b
⊢ (trace A (A ⊗[R] M)) (baseChange A f) = ↑(algebraMap R A) ((trace R M) f)

Next tactic:
simp [trace_eq_matrix_trace R b, trace_eq_matrix_trace A b', AddMonoidHom.map_trace]
theorem mod_four_eq_three_of_nat_prime_of_prime (p : ℕ) [hp : Fact p.Prime]
    (hpi : Prime (p : ℤ[i])) : p % 4 = 3 :=
  hp.1.eq_two_or_odd.elim
    (fun hp2 =>
      absurd hpi
        (mt irreducible_iff_prime.2 fun ⟨_, h⟩ => by
          

Proof state:
p : ℕ
hp : Fact (Nat.Prime p)
hpi : Prime ↑p
hp2 : p = 2
x✝ : Irreducible ↑p
not_unit✝ : ¬IsUnit ↑p
h : ∀ (a b : ℤ[i]), ↑p = a * b → IsUnit a ∨ IsUnit b
⊢ False

Next tactic:
have := h ⟨1, 1⟩ ⟨1, -1⟩ (hp2.symm ▸ rfl)
theorem mod_four_eq_three_of_nat_prime_of_prime (p : ℕ) [hp : Fact p.Prime]
    (hpi : Prime (p : ℤ[i])) : p % 4 = 3 :=
  hp.1.eq_two_or_odd.elim
    (fun hp2 =>
      absurd hpi
        (mt irreducible_iff_prime.2 fun ⟨_, h⟩ => by
          have := h ⟨1, 1⟩ ⟨1, -1⟩ (hp2.symm ▸ rfl)
          

Proof state:
p : ℕ
hp : Fact (Nat.Prime p)
hpi : Prime ↑p
hp2 : p = 2
x✝ : Irreducible ↑p
not_unit✝ : ¬IsUnit ↑p
h : ∀ (a b : ℤ[i]), ↑p = a * b → IsUnit a ∨ IsUnit b
this : IsUnit { re := 1, im := 1 } ∨ IsUnit { re := 1, im := -1 }
⊢ False

Next tactic:
rw [← norm_eq_one_iff, ← norm_eq_one_iff] at this
theorem mod_four_eq_three_of_nat_prime_of_prime (p : ℕ) [hp : Fact p.Prime]
    (hpi : Prime (p : ℤ[i])) : p % 4 = 3 :=
  hp.1.eq_two_or_odd.elim
    (fun hp2 =>
      absurd hpi
        (mt irreducible_iff_prime.2 fun ⟨_, h⟩ => by
          have := h ⟨1, 1⟩ ⟨1, -1⟩ (hp2.symm ▸ rfl)
          rw [← norm_eq_one_iff, ← norm_eq_one_iff] at this
          

Proof state:
p : ℕ
hp : Fact (Nat.Prime p)
hpi : Prime ↑p
hp2 : p = 2
x✝ : Irreducible ↑p
not_unit✝ : ¬IsUnit ↑p
h : ∀ (a b : ℤ[i]), ↑p = a * b → IsUnit a ∨ IsUnit b
this : Int.natAbs (Zsqrtd.norm { re := 1, im := 1 }) = 1 ∨ Int.natAbs (Zsqrtd.norm { re := 1, im := -1 }) = 1
⊢ False

Next tactic:
exact absurd this (by decide)
theorem mod_four_eq_three_of_nat_prime_of_prime (p : ℕ) [hp : Fact p.Prime]
    (hpi : Prime (p : ℤ[i])) : p % 4 = 3 :=
  hp.1.eq_two_or_odd.elim
    (fun hp2 =>
      absurd hpi
        (mt irreducible_iff_prime.2 fun ⟨_, h⟩ => by
          have := h ⟨1, 1⟩ ⟨1, -1⟩ (hp2.symm ▸ rfl)
          rw [← norm_eq_one_iff, ← norm_eq_one_iff] at this
          exact absurd this (by 

Proof state:
p : ℕ
hp : Fact (Nat.Prime p)
hpi : Prime ↑p
hp2 : p = 2
x✝ : Irreducible ↑p
not_unit✝ : ¬IsUnit ↑p
h : ∀ (a b : ℤ[i]), ↑p = a * b → IsUnit a ∨ IsUnit b
this : Int.natAbs (Zsqrtd.norm { re := 1, im := 1 }) = 1 ∨ Int.natAbs (Zsqrtd.norm { re := 1, im := -1 }) = 1
⊢ ¬(Int.natAbs (Zsqrtd.norm { re := 1, im := 1 }) = 1 ∨ Int.natAbs (Zsqrtd.norm { re := 1, im := -1 }) = 1)

Next tactic:
decide
theorem mod_four_eq_three_of_nat_prime_of_prime (p : ℕ) [hp : Fact p.Prime]
    (hpi : Prime (p : ℤ[i])) : p % 4 = 3 :=
  hp.1.eq_two_or_odd.elim
    (fun hp2 =>
      absurd hpi
        (mt irreducible_iff_prime.2 fun ⟨_, h⟩ => by
          have := h ⟨1, 1⟩ ⟨1, -1⟩ (hp2.symm ▸ rfl)
          rw [← norm_eq_one_iff, ← norm_eq_one_iff] at this
          exact absurd this (by decide)))
    fun hp1 =>
    by_contradiction fun hp3 : p % 4 ≠ 3 => by
      

Proof state:
p : ℕ
hp : Fact (Nat.Prime p)
hpi : Prime ↑p
hp1 : p % 2 = 1
hp3 : p % 4 ≠ 3
⊢ False

Next tactic:
have hp41 : p % 4 = 1 := by
        rw [← Nat.mod_mul_left_mod p 2 2, show 2 * 2 = 4 from rfl] at hp1
        have := Nat.mod_lt p (show 0 < 4 by decide)
        revert this hp3 hp1
        generalize p % 4 = m
        intros; interval_cases m <;> simp_all