l3lab/ntp-mathlib huggingface dataset:
/-- The norm on `Unitization 𝕜 E` satisfies the C⋆-property -/
instance Unitization.instCstarRing : CstarRing (Unitization 𝕜 E) where
  norm_star_mul_self {x} := by
    -- rewrite both sides as a `⊔`
    simp only [Unitization.norm_def, Prod.norm_def, ← sup_eq_max]
    -- Show that `(Unitization.splitMul 𝕜 E x).snd` satisifes the C⋆-property, in two stages:
    have h₁ : ∀ x : Unitization 𝕜 E,
        ‖(Unitization.splitMul 𝕜 E x).snd‖ ≤ ‖(Unitization.splitMul 𝕜 E (star x)).snd‖ := by
      simp only [add_zero, Unitization.splitMul_apply, Unitization.snd_star, Unitization.fst_star]
      intro x
      /- split based on whether the term inside the norm is zero or not. If so, it's trivial.
      If not, then apply `norm_splitMul_snd_sq` and cancel one copy of the norm -/
      by_cases h : algebraMap 𝕜 (E →L[𝕜] E) x.fst + mul 𝕜 E x.snd = 0
      · simp only [h, norm_zero, norm_le_zero_iff]
        exact norm_nonneg _
      · have : ‖(Unitization.splitMul 𝕜 E x).snd‖ ^ 2 ≤
          ‖(Unitization.splitMul 𝕜 E (star x)).snd‖ * ‖(Unitization.splitMul 𝕜 E x).snd‖ :=
          (norm_splitMul_snd_sq 𝕜 x).trans <| by
            rw [map_mul, Prod.snd_mul]
            exact norm_mul_le _ _
        rw [sq] at this
        rw [← Ne.def, ← norm_pos_iff] at h
        simp only [add_zero, Unitization.splitMul_apply, Unitization.snd_star,
          Unitization.fst_star, star_star] at this
        exact (mul_le_mul_right h).mp this
    -- in this step we make use of the key lemma `norm_splitMul_snd_sq`
    have h₂ : ‖(Unitization.splitMul 𝕜 E (star x * x)).snd‖
        = ‖(Unitization.splitMul 𝕜 E x).snd‖ ^ 2 := by
      refine le_antisymm ?_ (norm_splitMul_snd_sq 𝕜 x)
      rw [map_mul, Prod.snd_mul]
      exact (norm_mul_le _ _).trans <| by
        rw [sq]
        gcongr
        simpa only [star_star] using h₁ (star x)
    -- Show that `(Unitization.splitMul 𝕜 E x).fst` satisfies the C⋆-property
    have h₃ : ‖(Unitization.splitMul 𝕜 E (star x * x)).fst‖
        = ‖(Unitization.splitMul 𝕜 E x).fst‖ ^ 2 := by
      simp only [Unitization.splitMul_apply, Unitization.fst_mul, Unitization.fst_star, add_zero,
        norm_mul, norm_star, sq]
    

Proof state:
𝕜 : Type u_1
E : Type u_2
inst✝⁹ : DenselyNormedField 𝕜
inst✝⁸ : NonUnitalNormedRing E
inst✝⁷ : StarRing E
inst✝⁶ : CstarRing E
inst✝⁵ : NormedSpace 𝕜 E
inst✝⁴ : IsScalarTower 𝕜 E E
inst✝³ : SMulCommClass 𝕜 E E
inst✝² : StarRing 𝕜
inst✝¹ : CstarRing 𝕜
inst✝ : StarModule 𝕜 E
x : Unitization 𝕜 E
h₁ : ∀ (x : Unitization 𝕜 E), ‖((splitMul 𝕜 E) x).2‖ ≤ ‖((splitMul 𝕜 E) x⋆).2‖
h₂ : ‖((splitMul 𝕜 E) (x⋆ * x)).2‖ = ‖((splitMul 𝕜 E) x).2‖ ^ 2
h₃ : ‖((splitMul 𝕜 E) (x⋆ * x)).1‖ = ‖((splitMul 𝕜 E) x).1‖ ^ 2
⊢ ‖((splitMul 𝕜 E) (x⋆ * x)).1‖ ⊔ ‖((splitMul 𝕜 E) (x⋆ * x)).2‖ =
    (‖((splitMul 𝕜 E) x).1‖ ⊔ ‖((splitMul 𝕜 E) x).2‖) * (‖((splitMul 𝕜 E) x).1‖ ⊔ ‖((splitMul 𝕜 E) x).2‖)

Next tactic:
rw [h₂, h₃]
/-- The norm on `Unitization 𝕜 E` satisfies the C⋆-property -/
instance Unitization.instCstarRing : CstarRing (Unitization 𝕜 E) where
  norm_star_mul_self {x} := by
    -- rewrite both sides as a `⊔`
    simp only [Unitization.norm_def, Prod.norm_def, ← sup_eq_max]
    -- Show that `(Unitization.splitMul 𝕜 E x).snd` satisifes the C⋆-property, in two stages:
    have h₁ : ∀ x : Unitization 𝕜 E,
        ‖(Unitization.splitMul 𝕜 E x).snd‖ ≤ ‖(Unitization.splitMul 𝕜 E (star x)).snd‖ := by
      simp only [add_zero, Unitization.splitMul_apply, Unitization.snd_star, Unitization.fst_star]
      intro x
      /- split based on whether the term inside the norm is zero or not. If so, it's trivial.
      If not, then apply `norm_splitMul_snd_sq` and cancel one copy of the norm -/
      by_cases h : algebraMap 𝕜 (E →L[𝕜] E) x.fst + mul 𝕜 E x.snd = 0
      · simp only [h, norm_zero, norm_le_zero_iff]
        exact norm_nonneg _
      · have : ‖(Unitization.splitMul 𝕜 E x).snd‖ ^ 2 ≤
          ‖(Unitization.splitMul 𝕜 E (star x)).snd‖ * ‖(Unitization.splitMul 𝕜 E x).snd‖ :=
          (norm_splitMul_snd_sq 𝕜 x).trans <| by
            rw [map_mul, Prod.snd_mul]
            exact norm_mul_le _ _
        rw [sq] at this
        rw [← Ne.def, ← norm_pos_iff] at h
        simp only [add_zero, Unitization.splitMul_apply, Unitization.snd_star,
          Unitization.fst_star, star_star] at this
        exact (mul_le_mul_right h).mp this
    -- in this step we make use of the key lemma `norm_splitMul_snd_sq`
    have h₂ : ‖(Unitization.splitMul 𝕜 E (star x * x)).snd‖
        = ‖(Unitization.splitMul 𝕜 E x).snd‖ ^ 2 := by
      refine le_antisymm ?_ (norm_splitMul_snd_sq 𝕜 x)
      rw [map_mul, Prod.snd_mul]
      exact (norm_mul_le _ _).trans <| by
        rw [sq]
        gcongr
        simpa only [star_star] using h₁ (star x)
    -- Show that `(Unitization.splitMul 𝕜 E x).fst` satisfies the C⋆-property
    have h₃ : ‖(Unitization.splitMul 𝕜 E (star x * x)).fst‖
        = ‖(Unitization.splitMul 𝕜 E x).fst‖ ^ 2 := by
      simp only [Unitization.splitMul_apply, Unitization.fst_mul, Unitization.fst_star, add_zero,
        norm_mul, norm_star, sq]
    rw [h₂, h₃]
    /- use the definition of the norm, and split into cases based on whether the norm in the first
    coordinate is bigger or smaller than the norm in the second coordinate. -/
    

Proof state:
𝕜 : Type u_1
E : Type u_2
inst✝⁹ : DenselyNormedField 𝕜
inst✝⁸ : NonUnitalNormedRing E
inst✝⁷ : StarRing E
inst✝⁶ : CstarRing E
inst✝⁵ : NormedSpace 𝕜 E
inst✝⁴ : IsScalarTower 𝕜 E E
inst✝³ : SMulCommClass 𝕜 E E
inst✝² : StarRing 𝕜
inst✝¹ : CstarRing 𝕜
inst✝ : StarModule 𝕜 E
x : Unitization 𝕜 E
h₁ : ∀ (x : Unitization 𝕜 E), ‖((splitMul 𝕜 E) x).2‖ ≤ ‖((splitMul 𝕜 E) x⋆).2‖
h₂ : ‖((splitMul 𝕜 E) (x⋆ * x)).2‖ = ‖((splitMul 𝕜 E) x).2‖ ^ 2
h₃ : ‖((splitMul 𝕜 E) (x⋆ * x)).1‖ = ‖((splitMul 𝕜 E) x).1‖ ^ 2
⊢ ‖((splitMul 𝕜 E) x).1‖ ^ 2 ⊔ ‖((splitMul 𝕜 E) x).2‖ ^ 2 =
    (‖((splitMul 𝕜 E) x).1‖ ⊔ ‖((splitMul 𝕜 E) x).2‖) * (‖((splitMul 𝕜 E) x).1‖ ⊔ ‖((splitMul 𝕜 E) x).2‖)

Next tactic:
by_cases h : ‖(Unitization.splitMul 𝕜 E x).fst‖ ≤ ‖(Unitization.splitMul 𝕜 E x).snd‖
theorem cramer_is_linear : IsLinearMap α (cramerMap A) := by
  

Proof state:
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
b : n → α
⊢ IsLinearMap α (cramerMap A)

Next tactic:
constructor
theorem cramer_is_linear : IsLinearMap α (cramerMap A) := by
  constructor <;> 

Proof state:
case map_add
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
b : n → α
⊢ ∀ (x y : n → α), cramerMap A (x + y) = cramerMap A x + cramerMap A y

Next tactic:
intros
theorem cramer_is_linear : IsLinearMap α (cramerMap A) := by
  constructor <;> 

Proof state:
case map_smul
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
b : n → α
⊢ ∀ (c : α) (x : n → α), cramerMap A (c • x) = c • cramerMap A x

Next tactic:
intros
theorem cramer_is_linear : IsLinearMap α (cramerMap A) := by
  constructor <;> intros <;> 

Proof state:
case map_add
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
b x✝ y✝ : n → α
⊢ cramerMap A (x✝ + y✝) = cramerMap A x✝ + cramerMap A y✝

Next tactic:
ext i
theorem cramer_is_linear : IsLinearMap α (cramerMap A) := by
  constructor <;> intros <;> 

Proof state:
case map_smul
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
b : n → α
c✝ : α
x✝ : n → α
⊢ cramerMap A (c✝ • x✝) = c✝ • cramerMap A x✝

Next tactic:
ext i
theorem cramer_is_linear : IsLinearMap α (cramerMap A) := by
  constructor <;> intros <;> ext i
  · 

Proof state:
case map_add.h
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
b x✝ y✝ : n → α
i : n
⊢ cramerMap A (x✝ + y✝) i = (cramerMap A x✝ + cramerMap A y✝) i

Next tactic:
apply (cramerMap_is_linear A i).1
theorem cramer_is_linear : IsLinearMap α (cramerMap A) := by
  constructor <;> intros <;> ext i
  · apply (cramerMap_is_linear A i).1
  · 

Proof state:
case map_smul.h
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
b : n → α
c✝ : α
x✝ : n → α
i : n
⊢ cramerMap A (c✝ • x✝) i = (c✝ • cramerMap A x✝) i

Next tactic:
apply (cramerMap_is_linear A i).2
theorem cramer_transpose_apply (i : n) : cramer Aᵀ b i = (A.updateRow i b).det := by
  

Proof state:
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
b : n → α
i : n
⊢ (cramer Aᵀ) b i = det (updateRow A i b)

Next tactic:
rw [cramer_apply, updateColumn_transpose, det_transpose]
theorem cramer_transpose_row_self (i : n) : Aᵀ.cramer (A i) = Pi.single i A.det := by
  

Proof state:
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
b : n → α
i : n
⊢ (cramer Aᵀ) (A i) = Pi.single i (det A)

Next tactic:
ext j
theorem cramer_transpose_row_self (i : n) : Aᵀ.cramer (A i) = Pi.single i A.det := by
  ext j
  

Proof state:
case h
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
b : n → α
i j : n
⊢ (cramer Aᵀ) (A i) j = Pi.single i (det A) j

Next tactic:
rw [cramer_apply, Pi.single_apply]
theorem cramer_transpose_row_self (i : n) : Aᵀ.cramer (A i) = Pi.single i A.det := by
  ext j
  rw [cramer_apply, Pi.single_apply]
  

Proof state:
case h
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
b : n → α
i j : n
⊢ det (updateColumn Aᵀ j (A i)) = if j = i then det A else 0

Next tactic:
split_ifs with h
theorem cramer_transpose_row_self (i : n) : Aᵀ.cramer (A i) = Pi.single i A.det := by
  ext j
  rw [cramer_apply, Pi.single_apply]
  split_ifs with h
  · -- i = j: this entry should be `A.det`
    

Proof state:
case pos
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
b : n → α
i j : n
h : j = i
⊢ det (updateColumn Aᵀ j (A i)) = det A

Next tactic:
subst h
theorem cramer_transpose_row_self (i : n) : Aᵀ.cramer (A i) = Pi.single i A.det := by
  ext j
  rw [cramer_apply, Pi.single_apply]
  split_ifs with h
  · -- i = j: this entry should be `A.det`
    subst h
    

Proof state:
case pos
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
b : n → α
j : n
⊢ det (updateColumn Aᵀ j (A j)) = det A

Next tactic:
simp only [updateColumn_transpose, det_transpose, updateRow_eq_self]
theorem cramer_transpose_row_self (i : n) : Aᵀ.cramer (A i) = Pi.single i A.det := by
  ext j
  rw [cramer_apply, Pi.single_apply]
  split_ifs with h
  · -- i = j: this entry should be `A.det`
    subst h
    simp only [updateColumn_transpose, det_transpose, updateRow_eq_self]
  · -- i ≠ j: this entry should be 0
    

Proof state:
case neg
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
b : n → α
i j : n
h : ¬j = i
⊢ det (updateColumn Aᵀ j (A i)) = 0

Next tactic:
rw [updateColumn_transpose, det_transpose]
theorem cramer_transpose_row_self (i : n) : Aᵀ.cramer (A i) = Pi.single i A.det := by
  ext j
  rw [cramer_apply, Pi.single_apply]
  split_ifs with h
  · -- i = j: this entry should be `A.det`
    subst h
    simp only [updateColumn_transpose, det_transpose, updateRow_eq_self]
  · -- i ≠ j: this entry should be 0
    rw [updateColumn_transpose, det_transpose]
    

Proof state:
case neg
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
b : n → α
i j : n
h : ¬j = i
⊢ det (updateRow A j (A i)) = 0

Next tactic:
apply det_zero_of_row_eq h
theorem cramer_transpose_row_self (i : n) : Aᵀ.cramer (A i) = Pi.single i A.det := by
  ext j
  rw [cramer_apply, Pi.single_apply]
  split_ifs with h
  · -- i = j: this entry should be `A.det`
    subst h
    simp only [updateColumn_transpose, det_transpose, updateRow_eq_self]
  · -- i ≠ j: this entry should be 0
    rw [updateColumn_transpose, det_transpose]
    apply det_zero_of_row_eq h
    

Proof state:
case neg
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
b : n → α
i j : n
h : ¬j = i
⊢ updateRow A j (A i) j = updateRow A j (A i) i

Next tactic:
rw [updateRow_self, updateRow_ne (Ne.symm h)]
theorem cramer_row_self (i : n) (h : ∀ j, b j = A j i) : A.cramer b = Pi.single i A.det := by
  

Proof state:
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
b : n → α
i : n
h : ∀ (j : n), b j = A j i
⊢ (cramer A) b = Pi.single i (det A)

Next tactic:
rw [← transpose_transpose A, det_transpose]
theorem cramer_row_self (i : n) (h : ∀ j, b j = A j i) : A.cramer b = Pi.single i A.det := by
  rw [← transpose_transpose A, det_transpose]
  

Proof state:
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
b : n → α
i : n
h : ∀ (j : n), b j = A j i
⊢ (cramer Aᵀᵀ) b = Pi.single i (det Aᵀ)

Next tactic:
convert cramer_transpose_row_self Aᵀ i
theorem cramer_row_self (i : n) (h : ∀ j, b j = A j i) : A.cramer b = Pi.single i A.det := by
  rw [← transpose_transpose A, det_transpose]
  convert cramer_transpose_row_self Aᵀ i
  

Proof state:
case h.e'_2.h.e'_6
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
b : n → α
i : n
h : ∀ (j : n), b j = A j i
⊢ b = Aᵀ i

Next tactic:
exact funext h
@[simp]
theorem cramer_one : cramer (1 : Matrix n n α) = 1 := by
  -- Porting note: was `ext i j`
  

Proof state:
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
b : n → α
⊢ cramer 1 = 1

Next tactic:
refine LinearMap.pi_ext' (fun (i : n) => LinearMap.ext_ring (funext (fun (j : n) => ?_)))
@[simp]
theorem cramer_one : cramer (1 : Matrix n n α) = 1 := by
  -- Porting note: was `ext i j`
  refine LinearMap.pi_ext' (fun (i : n) => LinearMap.ext_ring (funext (fun (j : n) => ?_)))
  

Proof state:
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
b : n → α
i j : n
⊢ (cramer 1 ∘ₗ LinearMap.single i) 1 j = (1 ∘ₗ LinearMap.single i) 1 j

Next tactic:
convert congr_fun (cramer_row_self (1 : Matrix n n α) (Pi.single i 1) i _) j
@[simp]
theorem cramer_one : cramer (1 : Matrix n n α) = 1 := by
  -- Porting note: was `ext i j`
  refine LinearMap.pi_ext' (fun (i : n) => LinearMap.ext_ring (funext (fun (j : n) => ?_)))
  convert congr_fun (cramer_row_self (1 : Matrix n n α) (Pi.single i 1) i _) j
  · 

Proof state:
case h.e'_3.h.e'_1
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
b : n → α
i j : n
⊢ 1 = det 1

Next tactic:
simp
@[simp]
theorem cramer_one : cramer (1 : Matrix n n α) = 1 := by
  -- Porting note: was `ext i j`
  refine LinearMap.pi_ext' (fun (i : n) => LinearMap.ext_ring (funext (fun (j : n) => ?_)))
  convert congr_fun (cramer_row_self (1 : Matrix n n α) (Pi.single i 1) i _) j
  · simp
  · 

Proof state:
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
b : n → α
i j : n
⊢ ∀ (j : n), Pi.single i 1 j = OfNat.ofNat 1 j i

Next tactic:
intro j
@[simp]
theorem cramer_one : cramer (1 : Matrix n n α) = 1 := by
  -- Porting note: was `ext i j`
  refine LinearMap.pi_ext' (fun (i : n) => LinearMap.ext_ring (funext (fun (j : n) => ?_)))
  convert congr_fun (cramer_row_self (1 : Matrix n n α) (Pi.single i 1) i _) j
  · simp
  · intro j
    

Proof state:
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
b : n → α
i j✝ j : n
⊢ Pi.single i 1 j = OfNat.ofNat 1 j i

Next tactic:
rw [Matrix.one_eq_pi_single, Pi.single_comm]
@[simp]
theorem cramer_subsingleton_apply [Subsingleton n] (A : Matrix n n α) (b : n → α) (i : n) :
    cramer A b i = b i := by 

Proof state:
m : Type u
n : Type v
α : Type w
inst✝⁵ : DecidableEq n
inst✝⁴ : Fintype n
inst✝³ : DecidableEq m
inst✝² : Fintype m
inst✝¹ : CommRing α
A✝ : Matrix n n α
b✝ : n → α
inst✝ : Subsingleton n
A : Matrix n n α
b : n → α
i : n
⊢ (cramer A) b i = b i

Next tactic:
rw [cramer_apply, det_eq_elem_of_subsingleton _ i, updateColumn_self]
theorem cramer_zero [Nontrivial n] : cramer (0 : Matrix n n α) = 0 := by
  

Proof state:
m : Type u
n : Type v
α : Type w
inst✝⁵ : DecidableEq n
inst✝⁴ : Fintype n
inst✝³ : DecidableEq m
inst✝² : Fintype m
inst✝¹ : CommRing α
A : Matrix n n α
b : n → α
inst✝ : Nontrivial n
⊢ cramer 0 = 0

Next tactic:
ext i j
theorem cramer_zero [Nontrivial n] : cramer (0 : Matrix n n α) = 0 := by
  ext i j
  

Proof state:
case h.h.h
m : Type u
n : Type v
α : Type w
inst✝⁵ : DecidableEq n
inst✝⁴ : Fintype n
inst✝³ : DecidableEq m
inst✝² : Fintype m
inst✝¹ : CommRing α
A : Matrix n n α
b : n → α
inst✝ : Nontrivial n
i j : n
⊢ (cramer 0 ∘ₗ LinearMap.single i) 1 j = (0 ∘ₗ LinearMap.single i) 1 j

Next tactic:
obtain ⟨j', hj'⟩ : ∃ j', j' ≠ j := exists_ne j
theorem cramer_zero [Nontrivial n] : cramer (0 : Matrix n n α) = 0 := by
  ext i j
  obtain ⟨j', hj'⟩ : ∃ j', j' ≠ j := exists_ne j
  

Proof state:
case h.h.h.intro
m : Type u
n : Type v
α : Type w
inst✝⁵ : DecidableEq n
inst✝⁴ : Fintype n
inst✝³ : DecidableEq m
inst✝² : Fintype m
inst✝¹ : CommRing α
A : Matrix n n α
b : n → α
inst✝ : Nontrivial n
i j j' : n
hj' : j' ≠ j
⊢ (cramer 0 ∘ₗ LinearMap.single i) 1 j = (0 ∘ₗ LinearMap.single i) 1 j

Next tactic:
apply det_eq_zero_of_column_eq_zero j'
theorem cramer_zero [Nontrivial n] : cramer (0 : Matrix n n α) = 0 := by
  ext i j
  obtain ⟨j', hj'⟩ : ∃ j', j' ≠ j := exists_ne j
  apply det_eq_zero_of_column_eq_zero j'
  

Proof state:
case h.h.h.intro
m : Type u
n : Type v
α : Type w
inst✝⁵ : DecidableEq n
inst✝⁴ : Fintype n
inst✝³ : DecidableEq m
inst✝² : Fintype m
inst✝¹ : CommRing α
A : Matrix n n α
b : n → α
inst✝ : Nontrivial n
i j j' : n
hj' : j' ≠ j
⊢ ∀ (i_1 : n), updateColumn 0 j ((LinearMap.single i) 1) i_1 j' = 0

Next tactic:
intro j''
theorem cramer_zero [Nontrivial n] : cramer (0 : Matrix n n α) = 0 := by
  ext i j
  obtain ⟨j', hj'⟩ : ∃ j', j' ≠ j := exists_ne j
  apply det_eq_zero_of_column_eq_zero j'
  intro j''
  

Proof state:
case h.h.h.intro
m : Type u
n : Type v
α : Type w
inst✝⁵ : DecidableEq n
inst✝⁴ : Fintype n
inst✝³ : DecidableEq m
inst✝² : Fintype m
inst✝¹ : CommRing α
A : Matrix n n α
b : n → α
inst✝ : Nontrivial n
i j j' : n
hj' : j' ≠ j
j'' : n
⊢ updateColumn 0 j ((LinearMap.single i) 1) j'' j' = 0

Next tactic:
simp [updateColumn_ne hj']
/-- Use linearity of `cramer` and vector evaluation to take `cramer A _ i` out of a summation. -/
theorem sum_cramer_apply {β} (s : Finset β) (f : n → β → α) (i : n) :
    (∑ x in s, cramer A (fun j => f j x) i) = cramer A (fun j : n => ∑ x in s, f j x) i :=
  calc
    (∑ x in s, cramer A (fun j => f j x) i) = (∑ x in s, cramer A fun j => f j x) i :=
      (Finset.sum_apply i s _).symm
    _ = cramer A (fun j : n => ∑ x in s, f j x) i := by
      

Proof state:
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
b : n → α
β : Type u_1
s : Finset β
f : n → β → α
i : n
⊢ Finset.sum s (fun x => (cramer A) fun j => f j x) i = (cramer A) (fun j => ∑ x in s, f j x) i

Next tactic:
rw [sum_cramer, cramer_apply, cramer_apply]
/-- Use linearity of `cramer` and vector evaluation to take `cramer A _ i` out of a summation. -/
theorem sum_cramer_apply {β} (s : Finset β) (f : n → β → α) (i : n) :
    (∑ x in s, cramer A (fun j => f j x) i) = cramer A (fun j : n => ∑ x in s, f j x) i :=
  calc
    (∑ x in s, cramer A (fun j => f j x) i) = (∑ x in s, cramer A fun j => f j x) i :=
      (Finset.sum_apply i s _).symm
    _ = cramer A (fun j : n => ∑ x in s, f j x) i := by
      rw [sum_cramer, cramer_apply, cramer_apply]
      

Proof state:
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
b : n → α
β : Type u_1
s : Finset β
f : n → β → α
i : n
⊢ det (updateColumn A i (∑ x in s, fun j => f j x)) = det (updateColumn A i fun j => ∑ x in s, f j x)

Next tactic:
simp only [updateColumn]
/-- Use linearity of `cramer` and vector evaluation to take `cramer A _ i` out of a summation. -/
theorem sum_cramer_apply {β} (s : Finset β) (f : n → β → α) (i : n) :
    (∑ x in s, cramer A (fun j => f j x) i) = cramer A (fun j : n => ∑ x in s, f j x) i :=
  calc
    (∑ x in s, cramer A (fun j => f j x) i) = (∑ x in s, cramer A fun j => f j x) i :=
      (Finset.sum_apply i s _).symm
    _ = cramer A (fun j : n => ∑ x in s, f j x) i := by
      rw [sum_cramer, cramer_apply, cramer_apply]
      simp only [updateColumn]
      

Proof state:
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
b : n → α
β : Type u_1
s : Finset β
f : n → β → α
i : n
⊢ det (of fun i_1 => Function.update (A i_1) i (Finset.sum s (fun x j => f j x) i_1)) =
    det (of fun i_1 => Function.update (A i_1) i (∑ x in s, f i_1 x))

Next tactic:
congr with j
/-- Use linearity of `cramer` and vector evaluation to take `cramer A _ i` out of a summation. -/
theorem sum_cramer_apply {β} (s : Finset β) (f : n → β → α) (i : n) :
    (∑ x in s, cramer A (fun j => f j x) i) = cramer A (fun j : n => ∑ x in s, f j x) i :=
  calc
    (∑ x in s, cramer A (fun j => f j x) i) = (∑ x in s, cramer A fun j => f j x) i :=
      (Finset.sum_apply i s _).symm
    _ = cramer A (fun j : n => ∑ x in s, f j x) i := by
      rw [sum_cramer, cramer_apply, cramer_apply]
      simp only [updateColumn]
      congr with j
      

Proof state:
case e_M.h.e_6.h.h.h
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
b : n → α
β : Type u_1
s : Finset β
f : n → β → α
i j x✝ : n
⊢ Function.update (A j) i (Finset.sum s (fun x j => f j x) j) x✝ = Function.update (A j) i (∑ x in s, f j x) x✝

Next tactic:
congr
/-- Use linearity of `cramer` and vector evaluation to take `cramer A _ i` out of a summation. -/
theorem sum_cramer_apply {β} (s : Finset β) (f : n → β → α) (i : n) :
    (∑ x in s, cramer A (fun j => f j x) i) = cramer A (fun j : n => ∑ x in s, f j x) i :=
  calc
    (∑ x in s, cramer A (fun j => f j x) i) = (∑ x in s, cramer A fun j => f j x) i :=
      (Finset.sum_apply i s _).symm
    _ = cramer A (fun j : n => ∑ x in s, f j x) i := by
      rw [sum_cramer, cramer_apply, cramer_apply]
      simp only [updateColumn]
      congr with j
      congr
      

Proof state:
case e_M.h.e_6.h.h.h.e_v
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
b : n → α
β : Type u_1
s : Finset β
f : n → β → α
i j x✝ : n
⊢ Finset.sum s (fun x j => f j x) j = ∑ x in s, f j x

Next tactic:
apply Finset.sum_apply