l3lab/ntp-mathlib huggingface dataset:
/-- Equivalence between continuous maps into the units of a monoid with continuous multiplication
and the units of the monoid of continuous maps. -/
-- porting note: `simps` made bad `simp` lemmas (LHS simplifies) so we add them manually below
@[to_additive (attr := simps apply_val_apply symm_apply_apply_val)
"Equivalence between continuous maps into the additive units of an additive monoid with continuous
addition and the additive units of the additive monoid of continuous maps."]
def unitsLift : C(X, Mˣ) ≃ C(X, M)ˣ where
  toFun f :=
    { val := ⟨fun x => f x, Units.continuous_val.comp f.continuous⟩
      inv := ⟨fun x => ↑(f x)⁻¹, Units.continuous_val.comp (continuous_inv.comp f.continuous)⟩
      val_inv := ext fun x => Units.mul_inv _
      inv_val := ext fun x => Units.inv_mul _ }
  invFun f :=
    { toFun := fun x =>
        ⟨(f : C(X, M)) x, (↑f⁻¹ : C(X, M)) x,
          ContinuousMap.congr_fun f.mul_inv x, ContinuousMap.congr_fun f.inv_mul x⟩
      continuous_toFun := continuous_induced_rng.2 <|
        (f : C(X, M)).continuous.prod_mk <|
        MulOpposite.continuous_op.comp (↑f⁻¹ : C(X, M)).continuous }
  left_inv f := by ext; 

Proof state:
case h.a
X : Type u_1
M : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝³ : TopologicalSpace X
inst✝² : Monoid M
inst✝¹ : TopologicalSpace M
inst✝ : ContinuousMul M
f : C(X, Mˣ)
a✝ : X
⊢ ↑(((fun f =>
            mk fun x =>
              { val := ↑f x, inv := ↑f⁻¹ x, val_inv := (_ : (↑f * ↑f⁻¹) x = 1 x),
                inv_val := (_ : (↑f⁻¹ * ↑f) x = 1 x) })
          ((fun f =>
              { val := mk fun x => ↑(f x), inv := mk fun x => ↑(f x)⁻¹,
                val_inv := (_ : ((mk fun x => ↑(f x)) * mk fun x => ↑(f x)⁻¹) = 1),
                inv_val := (_ : ((mk fun x => ↑(f x)⁻¹) * mk fun x => ↑(f x)) = 1) })
            f))
        a✝) =
    ↑(f a✝)

Next tactic:
rfl
/-- Equivalence between continuous maps into the units of a monoid with continuous multiplication
and the units of the monoid of continuous maps. -/
-- porting note: `simps` made bad `simp` lemmas (LHS simplifies) so we add them manually below
@[to_additive (attr := simps apply_val_apply symm_apply_apply_val)
"Equivalence between continuous maps into the additive units of an additive monoid with continuous
addition and the additive units of the additive monoid of continuous maps."]
def unitsLift : C(X, Mˣ) ≃ C(X, M)ˣ where
  toFun f :=
    { val := ⟨fun x => f x, Units.continuous_val.comp f.continuous⟩
      inv := ⟨fun x => ↑(f x)⁻¹, Units.continuous_val.comp (continuous_inv.comp f.continuous)⟩
      val_inv := ext fun x => Units.mul_inv _
      inv_val := ext fun x => Units.inv_mul _ }
  invFun f :=
    { toFun := fun x =>
        ⟨(f : C(X, M)) x, (↑f⁻¹ : C(X, M)) x,
          ContinuousMap.congr_fun f.mul_inv x, ContinuousMap.congr_fun f.inv_mul x⟩
      continuous_toFun := continuous_induced_rng.2 <|
        (f : C(X, M)).continuous.prod_mk <|
        MulOpposite.continuous_op.comp (↑f⁻¹ : C(X, M)).continuous }
  left_inv f := by ext; rfl
  right_inv f := by 

Proof state:
X : Type u_1
M : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝³ : TopologicalSpace X
inst✝² : Monoid M
inst✝¹ : TopologicalSpace M
inst✝ : ContinuousMul M
f : C(X, M)ˣ
⊢ (fun f =>
        { val := mk fun x => ↑(f x), inv := mk fun x => ↑(f x)⁻¹,
          val_inv := (_ : ((mk fun x => ↑(f x)) * mk fun x => ↑(f x)⁻¹) = 1),
          inv_val := (_ : ((mk fun x => ↑(f x)⁻¹) * mk fun x => ↑(f x)) = 1) })
      ((fun f =>
          mk fun x =>
            { val := ↑f x, inv := ↑f⁻¹ x, val_inv := (_ : (↑f * ↑f⁻¹) x = 1 x), inv_val := (_ : (↑f⁻¹ * ↑f) x = 1 x) })
        f) =
    f

Next tactic:
ext
/-- Equivalence between continuous maps into the units of a monoid with continuous multiplication
and the units of the monoid of continuous maps. -/
-- porting note: `simps` made bad `simp` lemmas (LHS simplifies) so we add them manually below
@[to_additive (attr := simps apply_val_apply symm_apply_apply_val)
"Equivalence between continuous maps into the additive units of an additive monoid with continuous
addition and the additive units of the additive monoid of continuous maps."]
def unitsLift : C(X, Mˣ) ≃ C(X, M)ˣ where
  toFun f :=
    { val := ⟨fun x => f x, Units.continuous_val.comp f.continuous⟩
      inv := ⟨fun x => ↑(f x)⁻¹, Units.continuous_val.comp (continuous_inv.comp f.continuous)⟩
      val_inv := ext fun x => Units.mul_inv _
      inv_val := ext fun x => Units.inv_mul _ }
  invFun f :=
    { toFun := fun x =>
        ⟨(f : C(X, M)) x, (↑f⁻¹ : C(X, M)) x,
          ContinuousMap.congr_fun f.mul_inv x, ContinuousMap.congr_fun f.inv_mul x⟩
      continuous_toFun := continuous_induced_rng.2 <|
        (f : C(X, M)).continuous.prod_mk <|
        MulOpposite.continuous_op.comp (↑f⁻¹ : C(X, M)).continuous }
  left_inv f := by ext; rfl
  right_inv f := by ext; 

Proof state:
case a.h
X : Type u_1
M : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝³ : TopologicalSpace X
inst✝² : Monoid M
inst✝¹ : TopologicalSpace M
inst✝ : ContinuousMul M
f : C(X, M)ˣ
a✝ : X
⊢ ↑((fun f =>
            { val := mk fun x => ↑(f x), inv := mk fun x => ↑(f x)⁻¹,
              val_inv := (_ : ((mk fun x => ↑(f x)) * mk fun x => ↑(f x)⁻¹) = 1),
              inv_val := (_ : ((mk fun x => ↑(f x)⁻¹) * mk fun x => ↑(f x)) = 1) })
          ((fun f =>
              mk fun x =>
                { val := ↑f x, inv := ↑f⁻¹ x, val_inv := (_ : (↑f * ↑f⁻¹) x = 1 x),
                  inv_val := (_ : (↑f⁻¹ * ↑f) x = 1 x) })
            f))
      a✝ =
    ↑f a✝

Next tactic:
rfl
@[to_additive (attr := simp)]
lemma unitsLift_symm_apply_apply_inv' (f : C(X, M)ˣ) (x : X) :
    (ContinuousMap.unitsLift.symm f x)⁻¹ = (↑f⁻¹ : C(X, M)) x := by
  

Proof state:
X : Type u_1
M : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝³ : TopologicalSpace X
inst✝² : Monoid M
inst✝¹ : TopologicalSpace M
inst✝ : ContinuousMul M
f : C(X, M)ˣ
x : X
⊢ ↑((unitsLift.symm f) x)⁻¹ = ↑f⁻¹ x

Next tactic:
rfl
theorem continuous_isUnit_unit {f : C(X, R)} (h : ∀ x, IsUnit (f x)) :
    Continuous fun x => (h x).unit := by
  

Proof state:
X : Type u_1
M : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝² : TopologicalSpace X
inst✝¹ : NormedRing R
inst✝ : CompleteSpace R
f : C(X, R)
h : ∀ (x : X), IsUnit (f x)
⊢ Continuous fun x => IsUnit.unit (_ : IsUnit (f x))

Next tactic:
refine'
    continuous_induced_rng.2
      (Continuous.prod_mk f.continuous
        (MulOpposite.continuous_op.comp (continuous_iff_continuousAt.mpr fun x => _)))
theorem continuous_isUnit_unit {f : C(X, R)} (h : ∀ x, IsUnit (f x)) :
    Continuous fun x => (h x).unit := by
  refine'
    continuous_induced_rng.2
      (Continuous.prod_mk f.continuous
        (MulOpposite.continuous_op.comp (continuous_iff_continuousAt.mpr fun x => _)))
  

Proof state:
X : Type u_1
M : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝² : TopologicalSpace X
inst✝¹ : NormedRing R
inst✝ : CompleteSpace R
f : C(X, R)
h : ∀ (x : X), IsUnit (f x)
x : X
⊢ ContinuousAt (fun x => ↑((fun x => IsUnit.unit (_ : IsUnit (f x))) x)⁻¹) x

Next tactic:
have := NormedRing.inverse_continuousAt (h x).unit
theorem continuous_isUnit_unit {f : C(X, R)} (h : ∀ x, IsUnit (f x)) :
    Continuous fun x => (h x).unit := by
  refine'
    continuous_induced_rng.2
      (Continuous.prod_mk f.continuous
        (MulOpposite.continuous_op.comp (continuous_iff_continuousAt.mpr fun x => _)))
  have := NormedRing.inverse_continuousAt (h x).unit
  

Proof state:
X : Type u_1
M : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝² : TopologicalSpace X
inst✝¹ : NormedRing R
inst✝ : CompleteSpace R
f : C(X, R)
h : ∀ (x : X), IsUnit (f x)
x : X
this : ContinuousAt Ring.inverse ↑(IsUnit.unit (_ : IsUnit (f x)))
⊢ ContinuousAt (fun x => ↑((fun x => IsUnit.unit (_ : IsUnit (f x))) x)⁻¹) x

Next tactic:
simp only
theorem continuous_isUnit_unit {f : C(X, R)} (h : ∀ x, IsUnit (f x)) :
    Continuous fun x => (h x).unit := by
  refine'
    continuous_induced_rng.2
      (Continuous.prod_mk f.continuous
        (MulOpposite.continuous_op.comp (continuous_iff_continuousAt.mpr fun x => _)))
  have := NormedRing.inverse_continuousAt (h x).unit
  simp only
  

Proof state:
X : Type u_1
M : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝² : TopologicalSpace X
inst✝¹ : NormedRing R
inst✝ : CompleteSpace R
f : C(X, R)
h : ∀ (x : X), IsUnit (f x)
x : X
this : ContinuousAt Ring.inverse ↑(IsUnit.unit (_ : IsUnit (f x)))
⊢ ContinuousAt (fun x => ↑(IsUnit.unit (_ : IsUnit (f x)))⁻¹) x

Next tactic:
simp only [← Ring.inverse_unit, IsUnit.unit_spec] at this ⊢
theorem continuous_isUnit_unit {f : C(X, R)} (h : ∀ x, IsUnit (f x)) :
    Continuous fun x => (h x).unit := by
  refine'
    continuous_induced_rng.2
      (Continuous.prod_mk f.continuous
        (MulOpposite.continuous_op.comp (continuous_iff_continuousAt.mpr fun x => _)))
  have := NormedRing.inverse_continuousAt (h x).unit
  simp only
  simp only [← Ring.inverse_unit, IsUnit.unit_spec] at this ⊢
  

Proof state:
X : Type u_1
M : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝² : TopologicalSpace X
inst✝¹ : NormedRing R
inst✝ : CompleteSpace R
f : C(X, R)
h : ∀ (x : X), IsUnit (f x)
x : X
this : ContinuousAt Ring.inverse (f x)
⊢ ContinuousAt (fun x => Ring.inverse (f x)) x

Next tactic:
exact this.comp (f.continuousAt x)
instance canLift :
    CanLift C(X, R) C(X, Rˣ) (fun f => ⟨fun x => f x, Units.continuous_val.comp f.continuous⟩)
      fun f => ∀ x, IsUnit (f x) where
  prf f h := ⟨unitsOfForallIsUnit h, by 

Proof state:
X : Type u_1
M : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝² : TopologicalSpace X
inst✝¹ : NormedRing R
inst✝ : CompleteSpace R
f : C(X, R)
h : ∀ (x : X), IsUnit (f x)
⊢ (mk fun x => ↑((unitsOfForallIsUnit h) x)) = f

Next tactic:
ext
instance canLift :
    CanLift C(X, R) C(X, Rˣ) (fun f => ⟨fun x => f x, Units.continuous_val.comp f.continuous⟩)
      fun f => ∀ x, IsUnit (f x) where
  prf f h := ⟨unitsOfForallIsUnit h, by ext; 

Proof state:
case h
X : Type u_1
M : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝² : TopologicalSpace X
inst✝¹ : NormedRing R
inst✝ : CompleteSpace R
f : C(X, R)
h : ∀ (x : X), IsUnit (f x)
a✝ : X
⊢ (mk fun x => ↑((unitsOfForallIsUnit h) x)) a✝ = f a✝

Next tactic:
rfl
theorem isUnit_iff_forall_isUnit (f : C(X, R)) : IsUnit f ↔ ∀ x, IsUnit (f x) :=
  Iff.intro (fun h => fun x => ⟨unitsLift.symm h.unit x, rfl⟩) fun h =>
    ⟨ContinuousMap.unitsLift (unitsOfForallIsUnit h), by 

Proof state:
X : Type u_1
M : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝² : TopologicalSpace X
inst✝¹ : NormedRing R
inst✝ : CompleteSpace R
f : C(X, R)
h : ∀ (x : X), IsUnit (f x)
⊢ ↑(unitsLift (unitsOfForallIsUnit h)) = f

Next tactic:
ext
theorem isUnit_iff_forall_isUnit (f : C(X, R)) : IsUnit f ↔ ∀ x, IsUnit (f x) :=
  Iff.intro (fun h => fun x => ⟨unitsLift.symm h.unit x, rfl⟩) fun h =>
    ⟨ContinuousMap.unitsLift (unitsOfForallIsUnit h), by ext; 

Proof state:
case h
X : Type u_1
M : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝² : TopologicalSpace X
inst✝¹ : NormedRing R
inst✝ : CompleteSpace R
f : C(X, R)
h : ∀ (x : X), IsUnit (f x)
a✝ : X
⊢ ↑(unitsLift (unitsOfForallIsUnit h)) a✝ = f a✝

Next tactic:
rfl
theorem isUnit_iff_forall_ne_zero (f : C(X, 𝕜)) : IsUnit f ↔ ∀ x, f x ≠ 0 := by
  

Proof state:
X : Type u_1
M : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝² : TopologicalSpace X
inst✝¹ : NormedField 𝕜
inst✝ : CompleteSpace 𝕜
f : C(X, 𝕜)
⊢ IsUnit f ↔ ∀ (x : X), f x ≠ 0

Next tactic:
simp_rw [f.isUnit_iff_forall_isUnit, isUnit_iff_ne_zero]
theorem spectrum_eq_range (f : C(X, 𝕜)) : spectrum 𝕜 f = Set.range f := by
  

Proof state:
X : Type u_1
M : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝² : TopologicalSpace X
inst✝¹ : NormedField 𝕜
inst✝ : CompleteSpace 𝕜
f : C(X, 𝕜)
⊢ spectrum 𝕜 f = Set.range ⇑f

Next tactic:
ext x
theorem spectrum_eq_range (f : C(X, 𝕜)) : spectrum 𝕜 f = Set.range f := by
  ext x
  

Proof state:
case h
X : Type u_1
M : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝² : TopologicalSpace X
inst✝¹ : NormedField 𝕜
inst✝ : CompleteSpace 𝕜
f : C(X, 𝕜)
x : 𝕜
⊢ x ∈ spectrum 𝕜 f ↔ x ∈ Set.range ⇑f

Next tactic:
simp only [spectrum.mem_iff, isUnit_iff_forall_ne_zero, not_forall, coe_sub, Pi.sub_apply,
    algebraMap_apply, Algebra.id.smul_eq_mul, mul_one, Classical.not_not, Set.mem_range,
    sub_eq_zero, @eq_comm _ x _]
/-- The natural equivalence between linear endomorphisms of finite free modules and square matrices
is compatible with the Lie algebra structures. -/
def lieEquivMatrix' : Module.End R (n → R) ≃ₗ⁅R⁆ Matrix n n R :=
  { LinearMap.toMatrix' with
    map_lie' := fun {T S} => by
      

Proof state:
R : Type u
inst✝² : CommRing R
n : Type w
inst✝¹ : DecidableEq n
inst✝ : Fintype n
src✝ : ((n → R) →ₗ[R] n → R) ≃ₗ[R] Matrix n n R := LinearMap.toMatrix'
T S : Module.End R (n → R)
⊢ AddHom.toFun src✝.toAddHom ⁅T, S⁆ = ⁅AddHom.toFun src✝.toAddHom T, AddHom.toFun src✝.toAddHom S⁆

Next tactic:
let f := @LinearMap.toMatrix' R _ n n _ _
/-- The natural equivalence between linear endomorphisms of finite free modules and square matrices
is compatible with the Lie algebra structures. -/
def lieEquivMatrix' : Module.End R (n → R) ≃ₗ⁅R⁆ Matrix n n R :=
  { LinearMap.toMatrix' with
    map_lie' := fun {T S} => by
      let f := @LinearMap.toMatrix' R _ n n _ _
      

Proof state:
R : Type u
inst✝² : CommRing R
n : Type w
inst✝¹ : DecidableEq n
inst✝ : Fintype n
src✝ : ((n → R) →ₗ[R] n → R) ≃ₗ[R] Matrix n n R := LinearMap.toMatrix'
T S : Module.End R (n → R)
f : ((n → R) →ₗ[R] n → R) ≃ₗ[R] Matrix n n R := LinearMap.toMatrix'
⊢ AddHom.toFun src✝.toAddHom ⁅T, S⁆ = ⁅AddHom.toFun src✝.toAddHom T, AddHom.toFun src✝.toAddHom S⁆

Next tactic:
change f (T.comp S - S.comp T) = f T * f S - f S * f T
/-- The natural equivalence between linear endomorphisms of finite free modules and square matrices
is compatible with the Lie algebra structures. -/
def lieEquivMatrix' : Module.End R (n → R) ≃ₗ⁅R⁆ Matrix n n R :=
  { LinearMap.toMatrix' with
    map_lie' := fun {T S} => by
      let f := @LinearMap.toMatrix' R _ n n _ _
      change f (T.comp S - S.comp T) = f T * f S - f S * f T
      

Proof state:
R : Type u
inst✝² : CommRing R
n : Type w
inst✝¹ : DecidableEq n
inst✝ : Fintype n
src✝ : ((n → R) →ₗ[R] n → R) ≃ₗ[R] Matrix n n R := LinearMap.toMatrix'
T S : Module.End R (n → R)
f : ((n → R) →ₗ[R] n → R) ≃ₗ[R] Matrix n n R := LinearMap.toMatrix'
⊢ f (T ∘ₗ S - S ∘ₗ T) = f T * f S - f S * f T

Next tactic:
have h : ∀ T S : Module.End R _, f (T.comp S) = f T * f S := LinearMap.toMatrix'_comp
/-- The natural equivalence between linear endomorphisms of finite free modules and square matrices
is compatible with the Lie algebra structures. -/
def lieEquivMatrix' : Module.End R (n → R) ≃ₗ⁅R⁆ Matrix n n R :=
  { LinearMap.toMatrix' with
    map_lie' := fun {T S} => by
      let f := @LinearMap.toMatrix' R _ n n _ _
      change f (T.comp S - S.comp T) = f T * f S - f S * f T
      have h : ∀ T S : Module.End R _, f (T.comp S) = f T * f S := LinearMap.toMatrix'_comp
      

Proof state:
R : Type u
inst✝² : CommRing R
n : Type w
inst✝¹ : DecidableEq n
inst✝ : Fintype n
src✝ : ((n → R) →ₗ[R] n → R) ≃ₗ[R] Matrix n n R := LinearMap.toMatrix'
T S : Module.End R (n → R)
f : ((n → R) →ₗ[R] n → R) ≃ₗ[R] Matrix n n R := LinearMap.toMatrix'
h : ∀ (T S : Module.End R (n → R)), f (T ∘ₗ S) = f T * f S
⊢ f (T ∘ₗ S - S ∘ₗ T) = f T * f S - f S * f T

Next tactic:
rw [LinearEquiv.map_sub, h, h]
@[simp]
theorem Matrix.lieConj_apply (P A : Matrix n n R) (h : Invertible P) :
    P.lieConj h A = P * A * P⁻¹ := by
  

Proof state:
R : Type u
inst✝² : CommRing R
n : Type w
inst✝¹ : DecidableEq n
inst✝ : Fintype n
P A : Matrix n n R
h : Invertible P
⊢ (lieConj P h) A = P * A * P⁻¹

Next tactic:
simp [LinearEquiv.conj_apply, Matrix.lieConj, LinearMap.toMatrix'_comp,
    LinearMap.toMatrix'_toLin']
@[simp]
theorem Matrix.lieConj_symm_apply (P A : Matrix n n R) (h : Invertible P) :
    (P.lieConj h).symm A = P⁻¹ * A * P := by
  

Proof state:
R : Type u
inst✝² : CommRing R
n : Type w
inst✝¹ : DecidableEq n
inst✝ : Fintype n
P A : Matrix n n R
h : Invertible P
⊢ (LieEquiv.symm (lieConj P h)) A = P⁻¹ * A * P

Next tactic:
simp [LinearEquiv.symm_conj_apply, Matrix.lieConj, LinearMap.toMatrix'_comp,
    LinearMap.toMatrix'_toLin']
/-- For square matrices, the natural map that reindexes a matrix's rows and columns with equivalent
types, `Matrix.reindex`, is an equivalence of Lie algebras. -/
def Matrix.reindexLieEquiv : Matrix n n R ≃ₗ⁅R⁆ Matrix m m R :=
  { Matrix.reindexLinearEquiv R R e e with
    toFun := Matrix.reindex e e
    map_lie' := fun {_ _} => by
      

Proof state:
R : Type u
inst✝⁴ : CommRing R
n : Type w
inst✝³ : DecidableEq n
inst✝² : Fintype n
m : Type w₁
inst✝¹ : DecidableEq m
inst✝ : Fintype m
e : n ≃ m
src✝ : Matrix n n R ≃ₗ[R] Matrix m m R := reindexLinearEquiv R R e e
x✝¹ x✝ : Matrix n n R
⊢ AddHom.toFun
      {
          toAddHom :=
            { toFun := ⇑(reindex e e),
              map_add' :=
                (_ :
                  ∀ (x y : Matrix n n R),
                    AddHom.toFun src✝.toAddHom (x + y) = AddHom.toFun src✝.toAddHom x + AddHom.toFun src✝.toAddHom y) },
          map_smul' :=
            (_ :
              ∀ (r : R) (x : Matrix n n R),
                AddHom.toFun src✝.toAddHom (r • x) = (RingHom.id R) r • AddHom.toFun src✝.toAddHom x) }.toAddHom
      ⁅x✝¹, x✝⁆ =
    ⁅AddHom.toFun
        {
            toAddHom :=
              { toFun := ⇑(reindex e e),
                map_add' :=
                  (_ :
                    ∀ (x y : Matrix n n R),
                      AddHom.toFun src✝.toAddHom (x + y) =
                        AddHom.toFun src✝.toAddHom x + AddHom.toFun src✝.toAddHom y) },
            map_smul' :=
              (_ :
                ∀ (r : R) (x : Matrix n n R),
                  AddHom.toFun src✝.toAddHom (r • x) = (RingHom.id R) r • AddHom.toFun src✝.toAddHom x) }.toAddHom
        x✝¹,
      AddHom.toFun
        {
            toAddHom :=
              { toFun := ⇑(reindex e e),
                map_add' :=
                  (_ :
                    ∀ (x y : Matrix n n R),
                      AddHom.toFun src✝.toAddHom (x + y) =
                        AddHom.toFun src✝.toAddHom x + AddHom.toFun src✝.toAddHom y) },
            map_smul' :=
              (_ :
                ∀ (r : R) (x : Matrix n n R),
                  AddHom.toFun src✝.toAddHom (r • x) = (RingHom.id R) r • AddHom.toFun src✝.toAddHom x) }.toAddHom
        x✝⁆

Next tactic:
simp only [LieRing.of_associative_ring_bracket, Matrix.reindex_apply,
        Matrix.submatrix_mul_equiv, Matrix.submatrix_sub, Pi.sub_apply]
theorem blockTriangular_reindex_iff {b : n → α} {e : m ≃ n} :
    (reindex e e M).BlockTriangular b ↔ M.BlockTriangular (b ∘ e) := by
  

Proof state:
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝¹ : CommRing R
M N : Matrix m m R
b✝ : m → α
inst✝ : LT α
b : n → α
e : m ≃ n
⊢ BlockTriangular ((reindex e e) M) b ↔ BlockTriangular M (b ∘ ⇑e)

Next tactic:
refine' ⟨fun h => _, fun h => _⟩
theorem blockTriangular_reindex_iff {b : n → α} {e : m ≃ n} :
    (reindex e e M).BlockTriangular b ↔ M.BlockTriangular (b ∘ e) := by
  refine' ⟨fun h => _, fun h => _⟩
  · 

Proof state:
case refine'_1
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝¹ : CommRing R
M N : Matrix m m R
b✝ : m → α
inst✝ : LT α
b : n → α
e : m ≃ n
h : BlockTriangular ((reindex e e) M) b
⊢ BlockTriangular M (b ∘ ⇑e)

Next tactic:
convert h.submatrix
theorem blockTriangular_reindex_iff {b : n → α} {e : m ≃ n} :
    (reindex e e M).BlockTriangular b ↔ M.BlockTriangular (b ∘ e) := by
  refine' ⟨fun h => _, fun h => _⟩
  · convert h.submatrix
    

Proof state:
case h.e'_6
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝¹ : CommRing R
M N : Matrix m m R
b✝ : m → α
inst✝ : LT α
b : n → α
e : m ≃ n
h : BlockTriangular ((reindex e e) M) b
⊢ M = submatrix ((reindex e e) M) ⇑e ⇑e

Next tactic:
simp only [reindex_apply, submatrix_submatrix, submatrix_id_id, Equiv.symm_comp_self]
theorem blockTriangular_reindex_iff {b : n → α} {e : m ≃ n} :
    (reindex e e M).BlockTriangular b ↔ M.BlockTriangular (b ∘ e) := by
  refine' ⟨fun h => _, fun h => _⟩
  · convert h.submatrix
    simp only [reindex_apply, submatrix_submatrix, submatrix_id_id, Equiv.symm_comp_self]
  · 

Proof state:
case refine'_2
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝¹ : CommRing R
M N : Matrix m m R
b✝ : m → α
inst✝ : LT α
b : n → α
e : m ≃ n
h : BlockTriangular M (b ∘ ⇑e)
⊢ BlockTriangular ((reindex e e) M) b

Next tactic:
convert h.submatrix
theorem blockTriangular_reindex_iff {b : n → α} {e : m ≃ n} :
    (reindex e e M).BlockTriangular b ↔ M.BlockTriangular (b ∘ e) := by
  refine' ⟨fun h => _, fun h => _⟩
  · convert h.submatrix
    simp only [reindex_apply, submatrix_submatrix, submatrix_id_id, Equiv.symm_comp_self]
  · convert h.submatrix
    

Proof state:
case h.e'_7
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝¹ : CommRing R
M N : Matrix m m R
b✝ : m → α
inst✝ : LT α
b : n → α
e : m ≃ n
h : BlockTriangular M (b ∘ ⇑e)
⊢ b = (b ∘ ⇑e) ∘ fun i => e.symm i

Next tactic:
simp only [comp.assoc b e e.symm, Equiv.self_comp_symm, comp.right_id]
theorem BlockTriangular.add (hM : BlockTriangular M b) (hN : BlockTriangular N b) :
    BlockTriangular (M + N) b := fun i j h => by 

Proof state:
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝¹ : CommRing R
M N : Matrix m m R
b : m → α
inst✝ : LT α
hM : BlockTriangular M b
hN : BlockTriangular N b
i j : m
h : b j < b i
⊢ (M + N) i j = 0

Next tactic:
simp_rw [Matrix.add_apply, hM h, hN h, zero_add]
theorem BlockTriangular.sub (hM : BlockTriangular M b) (hN : BlockTriangular N b) :
    BlockTriangular (M - N) b := fun i j h => by 

Proof state:
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝¹ : CommRing R
M N : Matrix m m R
b : m → α
inst✝ : LT α
hM : BlockTriangular M b
hN : BlockTriangular N b
i j : m
h : b j < b i
⊢ (M - N) i j = 0

Next tactic:
simp_rw [Matrix.sub_apply, hM h, hN h, sub_zero]
theorem blockTriangular_blockDiagonal' [DecidableEq α] (d : ∀ i : α, Matrix (m' i) (m' i) R) :
    BlockTriangular (blockDiagonal' d) Sigma.fst := by
  

Proof state:
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝² : CommRing R
M N : Matrix m m R
b : m → α
inst✝¹ : Preorder α
inst✝ : DecidableEq α
d : (i : α) → Matrix (m' i) (m' i) R
⊢ BlockTriangular (blockDiagonal' d) Sigma.fst

Next tactic:
rintro ⟨i, i'⟩ ⟨j, j'⟩ h
theorem blockTriangular_blockDiagonal' [DecidableEq α] (d : ∀ i : α, Matrix (m' i) (m' i) R) :
    BlockTriangular (blockDiagonal' d) Sigma.fst := by
  rintro ⟨i, i'⟩ ⟨j, j'⟩ h
  

Proof state:
case mk.mk
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝² : CommRing R
M N : Matrix m m R
b : m → α
inst✝¹ : Preorder α
inst✝ : DecidableEq α
d : (i : α) → Matrix (m' i) (m' i) R
i : α
i' : m' i
j : α
j' : m' j
h : { fst := j, snd := j' }.fst < { fst := i, snd := i' }.fst
⊢ blockDiagonal' d { fst := i, snd := i' } { fst := j, snd := j' } = 0

Next tactic:
apply blockDiagonal'_apply_ne d i' j' fun h' => ne_of_lt h h'.symm
theorem blockTriangular_blockDiagonal [DecidableEq α] (d : α → Matrix m m R) :
    BlockTriangular (blockDiagonal d) Prod.snd := by
  

Proof state:
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝² : CommRing R
M N : Matrix m m R
b : m → α
inst✝¹ : Preorder α
inst✝ : DecidableEq α
d : α → Matrix m m R
⊢ BlockTriangular (blockDiagonal d) Prod.snd

Next tactic:
rintro ⟨i, i'⟩ ⟨j, j'⟩ h