l3lab/ntp-mathlib huggingface dataset:
/-- In the case of a triangle, altitudes are the same thing as Monge
planes. -/
theorem altitude_eq_mongePlane (t : Triangle ℝ P) {i₁ i₂ i₃ : Fin 3} (h₁₂ : i₁ ≠ i₂) (h₁₃ : i₁ ≠ i₃)
    (h₂₃ : i₂ ≠ i₃) : t.altitude i₁ = t.mongePlane i₂ i₃ := by
  have hs : ({i₂, i₃}ᶜ : Finset (Fin 3)) = {i₁} := by
    -- porting note: was `decide!`
    fin_cases i₁ <;> fin_cases i₂ <;> fin_cases i₃
      <;> simp (config := {decide := true}) at h₁₂ h₁₃ h₂₃ ⊢
  have he : univ.erase i₁ = {i₂, i₃} := by
    -- porting note: was `decide!`
    fin_cases i₁ <;> fin_cases i₂ <;> fin_cases i₃
      <;> 

Proof state:
case tail.head.tail.tail.head.tail.tail.head
V : Type u_1
P : Type u_2
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
t : Triangle ℝ P
h₁₂ h₁₃ : { val := 1, isLt := (_ : (fun a => a < 3) 1) } ≠ { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) }
h₂₃ :
  { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) } ≠
    { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) }
hs :
  {{ val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) },
        { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) }}ᶜ =
    {{ val := 1, isLt := (_ : (fun a => a < 3) 1) }}
⊢ erase univ { val := 1, isLt := (_ : (fun a => a < 3) 1) } =
    {{ val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) },
      { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) }}

Next tactic:
simp (config := {decide := true}) at h₁₂ h₁₃ h₂₃ ⊢
/-- In the case of a triangle, altitudes are the same thing as Monge
planes. -/
theorem altitude_eq_mongePlane (t : Triangle ℝ P) {i₁ i₂ i₃ : Fin 3} (h₁₂ : i₁ ≠ i₂) (h₁₃ : i₁ ≠ i₃)
    (h₂₃ : i₂ ≠ i₃) : t.altitude i₁ = t.mongePlane i₂ i₃ := by
  have hs : ({i₂, i₃}ᶜ : Finset (Fin 3)) = {i₁} := by
    -- porting note: was `decide!`
    fin_cases i₁ <;> fin_cases i₂ <;> fin_cases i₃
      <;> simp (config := {decide := true}) at h₁₂ h₁₃ h₂₃ ⊢
  have he : univ.erase i₁ = {i₂, i₃} := by
    -- porting note: was `decide!`
    fin_cases i₁ <;> fin_cases i₂ <;> fin_cases i₃
      <;> 

Proof state:
case tail.tail.head.head.head
V : Type u_1
P : Type u_2
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
t : Triangle ℝ P
h₁₂ h₁₃ : { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) } ≠ { val := 0, isLt := (_ : 0 < 3) }
h₂₃ : { val := 0, isLt := (_ : 0 < 3) } ≠ { val := 0, isLt := (_ : 0 < 3) }
hs :
  {{ val := 0, isLt := (_ : 0 < 3) }, { val := 0, isLt := (_ : 0 < 3) }}ᶜ =
    {{ val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) }}
⊢ erase univ { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) } =
    {{ val := 0, isLt := (_ : 0 < 3) }, { val := 0, isLt := (_ : 0 < 3) }}

Next tactic:
simp (config := {decide := true}) at h₁₂ h₁₃ h₂₃ ⊢
/-- In the case of a triangle, altitudes are the same thing as Monge
planes. -/
theorem altitude_eq_mongePlane (t : Triangle ℝ P) {i₁ i₂ i₃ : Fin 3} (h₁₂ : i₁ ≠ i₂) (h₁₃ : i₁ ≠ i₃)
    (h₂₃ : i₂ ≠ i₃) : t.altitude i₁ = t.mongePlane i₂ i₃ := by
  have hs : ({i₂, i₃}ᶜ : Finset (Fin 3)) = {i₁} := by
    -- porting note: was `decide!`
    fin_cases i₁ <;> fin_cases i₂ <;> fin_cases i₃
      <;> simp (config := {decide := true}) at h₁₂ h₁₃ h₂₃ ⊢
  have he : univ.erase i₁ = {i₂, i₃} := by
    -- porting note: was `decide!`
    fin_cases i₁ <;> fin_cases i₂ <;> fin_cases i₃
      <;> 

Proof state:
case tail.tail.head.head.tail.head
V : Type u_1
P : Type u_2
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
t : Triangle ℝ P
h₁₂ : { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) } ≠ { val := 0, isLt := (_ : 0 < 3) }
h₁₃ : { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) } ≠ { val := 1, isLt := (_ : (fun a => a < 3) 1) }
h₂₃ : { val := 0, isLt := (_ : 0 < 3) } ≠ { val := 1, isLt := (_ : (fun a => a < 3) 1) }
hs :
  {{ val := 0, isLt := (_ : 0 < 3) }, { val := 1, isLt := (_ : (fun a => a < 3) 1) }}ᶜ =
    {{ val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) }}
⊢ erase univ { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) } =
    {{ val := 0, isLt := (_ : 0 < 3) }, { val := 1, isLt := (_ : (fun a => a < 3) 1) }}

Next tactic:
simp (config := {decide := true}) at h₁₂ h₁₃ h₂₃ ⊢
/-- In the case of a triangle, altitudes are the same thing as Monge
planes. -/
theorem altitude_eq_mongePlane (t : Triangle ℝ P) {i₁ i₂ i₃ : Fin 3} (h₁₂ : i₁ ≠ i₂) (h₁₃ : i₁ ≠ i₃)
    (h₂₃ : i₂ ≠ i₃) : t.altitude i₁ = t.mongePlane i₂ i₃ := by
  have hs : ({i₂, i₃}ᶜ : Finset (Fin 3)) = {i₁} := by
    -- porting note: was `decide!`
    fin_cases i₁ <;> fin_cases i₂ <;> fin_cases i₃
      <;> simp (config := {decide := true}) at h₁₂ h₁₃ h₂₃ ⊢
  have he : univ.erase i₁ = {i₂, i₃} := by
    -- porting note: was `decide!`
    fin_cases i₁ <;> fin_cases i₂ <;> fin_cases i₃
      <;> 

Proof state:
case tail.tail.head.head.tail.tail.head
V : Type u_1
P : Type u_2
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
t : Triangle ℝ P
h₁₂ : { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) } ≠ { val := 0, isLt := (_ : 0 < 3) }
h₁₃ :
  { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) } ≠
    { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) }
h₂₃ : { val := 0, isLt := (_ : 0 < 3) } ≠ { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) }
hs :
  {{ val := 0, isLt := (_ : 0 < 3) }, { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) }}ᶜ =
    {{ val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) }}
⊢ erase univ { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) } =
    {{ val := 0, isLt := (_ : 0 < 3) }, { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) }}

Next tactic:
simp (config := {decide := true}) at h₁₂ h₁₃ h₂₃ ⊢
/-- In the case of a triangle, altitudes are the same thing as Monge
planes. -/
theorem altitude_eq_mongePlane (t : Triangle ℝ P) {i₁ i₂ i₃ : Fin 3} (h₁₂ : i₁ ≠ i₂) (h₁₃ : i₁ ≠ i₃)
    (h₂₃ : i₂ ≠ i₃) : t.altitude i₁ = t.mongePlane i₂ i₃ := by
  have hs : ({i₂, i₃}ᶜ : Finset (Fin 3)) = {i₁} := by
    -- porting note: was `decide!`
    fin_cases i₁ <;> fin_cases i₂ <;> fin_cases i₃
      <;> simp (config := {decide := true}) at h₁₂ h₁₃ h₂₃ ⊢
  have he : univ.erase i₁ = {i₂, i₃} := by
    -- porting note: was `decide!`
    fin_cases i₁ <;> fin_cases i₂ <;> fin_cases i₃
      <;> 

Proof state:
case tail.tail.head.tail.head.head
V : Type u_1
P : Type u_2
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
t : Triangle ℝ P
h₁₂ : { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) } ≠ { val := 1, isLt := (_ : (fun a => a < 3) 1) }
h₁₃ : { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) } ≠ { val := 0, isLt := (_ : 0 < 3) }
h₂₃ : { val := 1, isLt := (_ : (fun a => a < 3) 1) } ≠ { val := 0, isLt := (_ : 0 < 3) }
hs :
  {{ val := 1, isLt := (_ : (fun a => a < 3) 1) }, { val := 0, isLt := (_ : 0 < 3) }}ᶜ =
    {{ val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) }}
⊢ erase univ { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) } =
    {{ val := 1, isLt := (_ : (fun a => a < 3) 1) }, { val := 0, isLt := (_ : 0 < 3) }}

Next tactic:
simp (config := {decide := true}) at h₁₂ h₁₃ h₂₃ ⊢
/-- In the case of a triangle, altitudes are the same thing as Monge
planes. -/
theorem altitude_eq_mongePlane (t : Triangle ℝ P) {i₁ i₂ i₃ : Fin 3} (h₁₂ : i₁ ≠ i₂) (h₁₃ : i₁ ≠ i₃)
    (h₂₃ : i₂ ≠ i₃) : t.altitude i₁ = t.mongePlane i₂ i₃ := by
  have hs : ({i₂, i₃}ᶜ : Finset (Fin 3)) = {i₁} := by
    -- porting note: was `decide!`
    fin_cases i₁ <;> fin_cases i₂ <;> fin_cases i₃
      <;> simp (config := {decide := true}) at h₁₂ h₁₃ h₂₃ ⊢
  have he : univ.erase i₁ = {i₂, i₃} := by
    -- porting note: was `decide!`
    fin_cases i₁ <;> fin_cases i₂ <;> fin_cases i₃
      <;> 

Proof state:
case tail.tail.head.tail.head.tail.head
V : Type u_1
P : Type u_2
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
t : Triangle ℝ P
h₁₂ h₁₃ : { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) } ≠ { val := 1, isLt := (_ : (fun a => a < 3) 1) }
h₂₃ : { val := 1, isLt := (_ : (fun a => a < 3) 1) } ≠ { val := 1, isLt := (_ : (fun a => a < 3) 1) }
hs :
  {{ val := 1, isLt := (_ : (fun a => a < 3) 1) }, { val := 1, isLt := (_ : (fun a => a < 3) 1) }}ᶜ =
    {{ val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) }}
⊢ erase univ { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) } =
    {{ val := 1, isLt := (_ : (fun a => a < 3) 1) }, { val := 1, isLt := (_ : (fun a => a < 3) 1) }}

Next tactic:
simp (config := {decide := true}) at h₁₂ h₁₃ h₂₃ ⊢
/-- In the case of a triangle, altitudes are the same thing as Monge
planes. -/
theorem altitude_eq_mongePlane (t : Triangle ℝ P) {i₁ i₂ i₃ : Fin 3} (h₁₂ : i₁ ≠ i₂) (h₁₃ : i₁ ≠ i₃)
    (h₂₃ : i₂ ≠ i₃) : t.altitude i₁ = t.mongePlane i₂ i₃ := by
  have hs : ({i₂, i₃}ᶜ : Finset (Fin 3)) = {i₁} := by
    -- porting note: was `decide!`
    fin_cases i₁ <;> fin_cases i₂ <;> fin_cases i₃
      <;> simp (config := {decide := true}) at h₁₂ h₁₃ h₂₃ ⊢
  have he : univ.erase i₁ = {i₂, i₃} := by
    -- porting note: was `decide!`
    fin_cases i₁ <;> fin_cases i₂ <;> fin_cases i₃
      <;> 

Proof state:
case tail.tail.head.tail.head.tail.tail.head
V : Type u_1
P : Type u_2
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
t : Triangle ℝ P
h₁₂ : { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) } ≠ { val := 1, isLt := (_ : (fun a => a < 3) 1) }
h₁₃ :
  { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) } ≠
    { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) }
h₂₃ : { val := 1, isLt := (_ : (fun a => a < 3) 1) } ≠ { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) }
hs :
  {{ val := 1, isLt := (_ : (fun a => a < 3) 1) }, { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) }}ᶜ =
    {{ val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) }}
⊢ erase univ { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) } =
    {{ val := 1, isLt := (_ : (fun a => a < 3) 1) }, { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) }}

Next tactic:
simp (config := {decide := true}) at h₁₂ h₁₃ h₂₃ ⊢
/-- In the case of a triangle, altitudes are the same thing as Monge
planes. -/
theorem altitude_eq_mongePlane (t : Triangle ℝ P) {i₁ i₂ i₃ : Fin 3} (h₁₂ : i₁ ≠ i₂) (h₁₃ : i₁ ≠ i₃)
    (h₂₃ : i₂ ≠ i₃) : t.altitude i₁ = t.mongePlane i₂ i₃ := by
  have hs : ({i₂, i₃}ᶜ : Finset (Fin 3)) = {i₁} := by
    -- porting note: was `decide!`
    fin_cases i₁ <;> fin_cases i₂ <;> fin_cases i₃
      <;> simp (config := {decide := true}) at h₁₂ h₁₃ h₂₃ ⊢
  have he : univ.erase i₁ = {i₂, i₃} := by
    -- porting note: was `decide!`
    fin_cases i₁ <;> fin_cases i₂ <;> fin_cases i₃
      <;> 

Proof state:
case tail.tail.head.tail.tail.head.head
V : Type u_1
P : Type u_2
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
t : Triangle ℝ P
h₁₂ :
  { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) } ≠
    { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) }
h₁₃ h₂₃ : { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) } ≠ { val := 0, isLt := (_ : 0 < 3) }
hs :
  {{ val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) }, { val := 0, isLt := (_ : 0 < 3) }}ᶜ =
    {{ val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) }}
⊢ erase univ { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) } =
    {{ val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) }, { val := 0, isLt := (_ : 0 < 3) }}

Next tactic:
simp (config := {decide := true}) at h₁₂ h₁₃ h₂₃ ⊢
/-- In the case of a triangle, altitudes are the same thing as Monge
planes. -/
theorem altitude_eq_mongePlane (t : Triangle ℝ P) {i₁ i₂ i₃ : Fin 3} (h₁₂ : i₁ ≠ i₂) (h₁₃ : i₁ ≠ i₃)
    (h₂₃ : i₂ ≠ i₃) : t.altitude i₁ = t.mongePlane i₂ i₃ := by
  have hs : ({i₂, i₃}ᶜ : Finset (Fin 3)) = {i₁} := by
    -- porting note: was `decide!`
    fin_cases i₁ <;> fin_cases i₂ <;> fin_cases i₃
      <;> simp (config := {decide := true}) at h₁₂ h₁₃ h₂₃ ⊢
  have he : univ.erase i₁ = {i₂, i₃} := by
    -- porting note: was `decide!`
    fin_cases i₁ <;> fin_cases i₂ <;> fin_cases i₃
      <;> 

Proof state:
case tail.tail.head.tail.tail.head.tail.head
V : Type u_1
P : Type u_2
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
t : Triangle ℝ P
h₁₂ :
  { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) } ≠
    { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) }
h₁₃ h₂₃ : { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) } ≠ { val := 1, isLt := (_ : (fun a => a < 3) 1) }
hs :
  {{ val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) }, { val := 1, isLt := (_ : (fun a => a < 3) 1) }}ᶜ =
    {{ val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) }}
⊢ erase univ { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) } =
    {{ val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) }, { val := 1, isLt := (_ : (fun a => a < 3) 1) }}

Next tactic:
simp (config := {decide := true}) at h₁₂ h₁₃ h₂₃ ⊢
/-- In the case of a triangle, altitudes are the same thing as Monge
planes. -/
theorem altitude_eq_mongePlane (t : Triangle ℝ P) {i₁ i₂ i₃ : Fin 3} (h₁₂ : i₁ ≠ i₂) (h₁₃ : i₁ ≠ i₃)
    (h₂₃ : i₂ ≠ i₃) : t.altitude i₁ = t.mongePlane i₂ i₃ := by
  have hs : ({i₂, i₃}ᶜ : Finset (Fin 3)) = {i₁} := by
    -- porting note: was `decide!`
    fin_cases i₁ <;> fin_cases i₂ <;> fin_cases i₃
      <;> simp (config := {decide := true}) at h₁₂ h₁₃ h₂₃ ⊢
  have he : univ.erase i₁ = {i₂, i₃} := by
    -- porting note: was `decide!`
    fin_cases i₁ <;> fin_cases i₂ <;> fin_cases i₃
      <;> 

Proof state:
case tail.tail.head.tail.tail.head.tail.tail.head
V : Type u_1
P : Type u_2
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
t : Triangle ℝ P
h₁₂ h₁₃ h₂₃ :
  { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) } ≠
    { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) }
hs :
  {{ val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) },
        { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) }}ᶜ =
    {{ val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) }}
⊢ erase univ { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) } =
    {{ val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) },
      { val := 2, isLt := (_ : (fun a => (fun a => a < 3) a) 2) }}

Next tactic:
simp (config := {decide := true}) at h₁₂ h₁₃ h₂₃ ⊢
/-- In the case of a triangle, altitudes are the same thing as Monge
planes. -/
theorem altitude_eq_mongePlane (t : Triangle ℝ P) {i₁ i₂ i₃ : Fin 3} (h₁₂ : i₁ ≠ i₂) (h₁₃ : i₁ ≠ i₃)
    (h₂₃ : i₂ ≠ i₃) : t.altitude i₁ = t.mongePlane i₂ i₃ := by
  have hs : ({i₂, i₃}ᶜ : Finset (Fin 3)) = {i₁} := by
    -- porting note: was `decide!`
    fin_cases i₁ <;> fin_cases i₂ <;> fin_cases i₃
      <;> simp (config := {decide := true}) at h₁₂ h₁₃ h₂₃ ⊢
  have he : univ.erase i₁ = {i₂, i₃} := by
    -- porting note: was `decide!`
    fin_cases i₁ <;> fin_cases i₂ <;> fin_cases i₃
      <;> simp (config := {decide := true}) at h₁₂ h₁₃ h₂₃ ⊢
  

Proof state:
V : Type u_1
P : Type u_2
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
t : Triangle ℝ P
i₁ i₂ i₃ : Fin 3
h₁₂ : i₁ ≠ i₂
h₁₃ : i₁ ≠ i₃
h₂₃ : i₂ ≠ i₃
hs : {i₂, i₃}ᶜ = {i₁}
he : erase univ i₁ = {i₂, i₃}
⊢ altitude t i₁ = mongePlane t i₂ i₃

Next tactic:
rw [mongePlane_def, altitude_def, direction_affineSpan, hs, he, centroid_singleton, coe_insert,
    coe_singleton, vectorSpan_image_eq_span_vsub_set_left_ne ℝ _ (Set.mem_insert i₂ _)]
/-- In the case of a triangle, altitudes are the same thing as Monge
planes. -/
theorem altitude_eq_mongePlane (t : Triangle ℝ P) {i₁ i₂ i₃ : Fin 3} (h₁₂ : i₁ ≠ i₂) (h₁₃ : i₁ ≠ i₃)
    (h₂₃ : i₂ ≠ i₃) : t.altitude i₁ = t.mongePlane i₂ i₃ := by
  have hs : ({i₂, i₃}ᶜ : Finset (Fin 3)) = {i₁} := by
    -- porting note: was `decide!`
    fin_cases i₁ <;> fin_cases i₂ <;> fin_cases i₃
      <;> simp (config := {decide := true}) at h₁₂ h₁₃ h₂₃ ⊢
  have he : univ.erase i₁ = {i₂, i₃} := by
    -- porting note: was `decide!`
    fin_cases i₁ <;> fin_cases i₂ <;> fin_cases i₃
      <;> simp (config := {decide := true}) at h₁₂ h₁₃ h₂₃ ⊢
  rw [mongePlane_def, altitude_def, direction_affineSpan, hs, he, centroid_singleton, coe_insert,
    coe_singleton, vectorSpan_image_eq_span_vsub_set_left_ne ℝ _ (Set.mem_insert i₂ _)]
  

Proof state:
V : Type u_1
P : Type u_2
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
t : Triangle ℝ P
i₁ i₂ i₃ : Fin 3
h₁₂ : i₁ ≠ i₂
h₁₃ : i₁ ≠ i₃
h₂₃ : i₂ ≠ i₃
hs : {i₂, i₃}ᶜ = {i₁}
he : erase univ i₁ = {i₂, i₃}
⊢ mk' (points t i₁) (Submodule.span ℝ ((fun x => points t i₂ -ᵥ x) '' (t.points '' ({i₂, i₃} \ {i₂}))))ᗮ ⊓
      affineSpan ℝ (Set.range t.points) =
    mk' (points t i₁) (Submodule.span ℝ {points t i₂ -ᵥ points t i₃})ᗮ ⊓ affineSpan ℝ (Set.range t.points)

Next tactic:
simp [h₂₃, Submodule.span_insert_eq_span]
/-- In the case of a triangle, altitudes are the same thing as Monge
planes. -/
theorem altitude_eq_mongePlane (t : Triangle ℝ P) {i₁ i₂ i₃ : Fin 3} (h₁₂ : i₁ ≠ i₂) (h₁₃ : i₁ ≠ i₃)
    (h₂₃ : i₂ ≠ i₃) : t.altitude i₁ = t.mongePlane i₂ i₃ := by
  have hs : ({i₂, i₃}ᶜ : Finset (Fin 3)) = {i₁} := by
    -- porting note: was `decide!`
    fin_cases i₁ <;> fin_cases i₂ <;> fin_cases i₃
      <;> simp (config := {decide := true}) at h₁₂ h₁₃ h₂₃ ⊢
  have he : univ.erase i₁ = {i₂, i₃} := by
    -- porting note: was `decide!`
    fin_cases i₁ <;> fin_cases i₂ <;> fin_cases i₃
      <;> simp (config := {decide := true}) at h₁₂ h₁₃ h₂₃ ⊢
  rw [mongePlane_def, altitude_def, direction_affineSpan, hs, he, centroid_singleton, coe_insert,
    coe_singleton, vectorSpan_image_eq_span_vsub_set_left_ne ℝ _ (Set.mem_insert i₂ _)]
  simp [h₂₃, Submodule.span_insert_eq_span]
  -- porting note: this didn't need the `congr` and the `fin_cases`
  

Proof state:
V : Type u_1
P : Type u_2
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
t : Triangle ℝ P
i₁ i₂ i₃ : Fin 3
h₁₂ : i₁ ≠ i₂
h₁₃ : i₁ ≠ i₃
h₂₃ : i₂ ≠ i₃
hs : {i₂, i₃}ᶜ = {i₁}
he : erase univ i₁ = {i₂, i₃}
⊢ mk' (points t i₁) (Submodule.span ℝ ((fun x => points t i₂ -ᵥ x) '' (t.points '' ({i₃} \ {i₂}))))ᗮ ⊓
      affineSpan ℝ (Set.range t.points) =
    mk' (points t i₁) (Submodule.span ℝ {points t i₂ -ᵥ points t i₃})ᗮ ⊓ affineSpan ℝ (Set.range t.points)

Next tactic:
congr
/-- In the case of a triangle, altitudes are the same thing as Monge
planes. -/
theorem altitude_eq_mongePlane (t : Triangle ℝ P) {i₁ i₂ i₃ : Fin 3} (h₁₂ : i₁ ≠ i₂) (h₁₃ : i₁ ≠ i₃)
    (h₂₃ : i₂ ≠ i₃) : t.altitude i₁ = t.mongePlane i₂ i₃ := by
  have hs : ({i₂, i₃}ᶜ : Finset (Fin 3)) = {i₁} := by
    -- porting note: was `decide!`
    fin_cases i₁ <;> fin_cases i₂ <;> fin_cases i₃
      <;> simp (config := {decide := true}) at h₁₂ h₁₃ h₂₃ ⊢
  have he : univ.erase i₁ = {i₂, i₃} := by
    -- porting note: was `decide!`
    fin_cases i₁ <;> fin_cases i₂ <;> fin_cases i₃
      <;> simp (config := {decide := true}) at h₁₂ h₁₃ h₂₃ ⊢
  rw [mongePlane_def, altitude_def, direction_affineSpan, hs, he, centroid_singleton, coe_insert,
    coe_singleton, vectorSpan_image_eq_span_vsub_set_left_ne ℝ _ (Set.mem_insert i₂ _)]
  simp [h₂₃, Submodule.span_insert_eq_span]
  -- porting note: this didn't need the `congr` and the `fin_cases`
  congr
  

Proof state:
case e_a.e_direction.e_K.e_s
V : Type u_1
P : Type u_2
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
t : Triangle ℝ P
i₁ i₂ i₃ : Fin 3
h₁₂ : i₁ ≠ i₂
h₁₃ : i₁ ≠ i₃
h₂₃ : i₂ ≠ i₃
hs : {i₂, i₃}ᶜ = {i₁}
he : erase univ i₁ = {i₂, i₃}
⊢ (fun x => points t i₂ -ᵥ x) '' (t.points '' ({i₃} \ {i₂})) = {points t i₂ -ᵥ points t i₃}

Next tactic:
fin_cases i₂
/-- In the case of a triangle, altitudes are the same thing as Monge
planes. -/
theorem altitude_eq_mongePlane (t : Triangle ℝ P) {i₁ i₂ i₃ : Fin 3} (h₁₂ : i₁ ≠ i₂) (h₁₃ : i₁ ≠ i₃)
    (h₂₃ : i₂ ≠ i₃) : t.altitude i₁ = t.mongePlane i₂ i₃ := by
  have hs : ({i₂, i₃}ᶜ : Finset (Fin 3)) = {i₁} := by
    -- porting note: was `decide!`
    fin_cases i₁ <;> fin_cases i₂ <;> fin_cases i₃
      <;> simp (config := {decide := true}) at h₁₂ h₁₃ h₂₃ ⊢
  have he : univ.erase i₁ = {i₂, i₃} := by
    -- porting note: was `decide!`
    fin_cases i₁ <;> fin_cases i₂ <;> fin_cases i₃
      <;> simp (config := {decide := true}) at h₁₂ h₁₃ h₂₃ ⊢
  rw [mongePlane_def, altitude_def, direction_affineSpan, hs, he, centroid_singleton, coe_insert,
    coe_singleton, vectorSpan_image_eq_span_vsub_set_left_ne ℝ _ (Set.mem_insert i₂ _)]
  simp [h₂₃, Submodule.span_insert_eq_span]
  -- porting note: this didn't need the `congr` and the `fin_cases`
  congr
  fin_cases i₂ <;> 

Proof state:
case e_a.e_direction.e_K.e_s.head
V : Type u_1
P : Type u_2
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
t : Triangle ℝ P
i₁ i₃ : Fin 3
h₁₃ : i₁ ≠ i₃
h₁₂ : i₁ ≠ { val := 0, isLt := (_ : 0 < 3) }
h₂₃ : { val := 0, isLt := (_ : 0 < 3) } ≠ i₃
hs : {{ val := 0, isLt := (_ : 0 < 3) }, i₃}ᶜ = {i₁}
he : erase univ i₁ = {{ val := 0, isLt := (_ : 0 < 3) }, i₃}
⊢ (fun x => points t { val := 0, isLt := (_ : 0 < 3) } -ᵥ x) ''
      (t.points '' ({i₃} \ {{ val := 0, isLt := (_ : 0 < 3) }})) =
    {points t { val := 0, isLt := (_ : 0 < 3) } -ᵥ points t i₃}

Next tactic:
fin_cases i₃
/-- In the case of a triangle, altitudes are the same thing as Monge
planes. -/
theorem altitude_eq_mongePlane (t : Triangle ℝ P) {i₁ i₂ i₃ : Fin 3} (h₁₂ : i₁ ≠ i₂) (h₁₃ : i₁ ≠ i₃)
    (h₂₃ : i₂ ≠ i₃) : t.altitude i₁ = t.mongePlane i₂ i₃ := by
  have hs : ({i₂, i₃}ᶜ : Finset (Fin 3)) = {i₁} := by
    -- porting note: was `decide!`
    fin_cases i₁ <;> fin_cases i₂ <;> fin_cases i₃
      <;> simp (config := {decide := true}) at h₁₂ h₁₃ h₂₃ ⊢
  have he : univ.erase i₁ = {i₂, i₃} := by
    -- porting note: was `decide!`
    fin_cases i₁ <;> fin_cases i₂ <;> fin_cases i₃
      <;> simp (config := {decide := true}) at h₁₂ h₁₃ h₂₃ ⊢
  rw [mongePlane_def, altitude_def, direction_affineSpan, hs, he, centroid_singleton, coe_insert,
    coe_singleton, vectorSpan_image_eq_span_vsub_set_left_ne ℝ _ (Set.mem_insert i₂ _)]
  simp [h₂₃, Submodule.span_insert_eq_span]
  -- porting note: this didn't need the `congr` and the `fin_cases`
  congr
  fin_cases i₂ <;> 

Proof state:
case e_a.e_direction.e_K.e_s.tail.head
V : Type u_1
P : Type u_2
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
t : Triangle ℝ P
i₁ i₃ : Fin 3
h₁₃ : i₁ ≠ i₃
h₁₂ : i₁ ≠ { val := 1, isLt := (_ : (fun a => a < 3) 1) }
h₂₃ : { val := 1, isLt := (_ : (fun a => a < 3) 1) } ≠ i₃
hs : {{ val := 1, isLt := (_ : (fun a => a < 3) 1) }, i₃}ᶜ = {i₁}
he : erase univ i₁ = {{ val := 1, isLt := (_ : (fun a => a < 3) 1) }, i₃}
⊢ (fun x => points t { val := 1, isLt := (_ : (fun a => a < 3) 1) } -ᵥ x) ''
      (t.points '' ({i₃} \ {{ val := 1, isLt := (_ : (fun a => a < 3) 1) }})) =
    {points t { val := 1, isLt := (_ : (fun a => a < 3) 1) } -ᵥ points t i₃}

Next tactic:
fin_cases i₃