l3lab/ntp-mathlib huggingface dataset:
theorem abs_eq_abs {a b : α} : |a| = |b| ↔ a = b ∨ a = -b := by
  refine' ⟨fun h => _, fun h => _⟩
  · obtain rfl | rfl := eq_or_eq_neg_of_abs_eq h <;>
      simpa only [neg_eq_iff_eq_neg (a := |b|), neg_inj, or_comm] using abs_choice b
  · cases' h with h h <;>
    

Proof state:
case refine'_2.inr
α : Type u_1
inst✝¹ : AddGroup α
inst✝ : LinearOrder α
a b : α
h : a = -b
⊢ |a| = |b|

Next tactic:
simp [h, abs_neg]
theorem abs_le_abs_of_nonneg (ha : 0 ≤ a) (hab : a ≤ b) : |a| ≤ |b| := by
  

Proof state:
α : Type u_1
inst✝² : AddGroup α
inst✝¹ : LinearOrder α
inst✝ : CovariantClass α α (fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
a b c : α
ha : 0 ≤ a
hab : a ≤ b
⊢ |a| ≤ |b|

Next tactic:
rwa [abs_of_nonneg ha, abs_of_nonneg (ha.trans hab)]
@[simp]
theorem abs_pos : 0 < |a| ↔ a ≠ 0 := by
  

Proof state:
α : Type u_1
inst✝² : AddGroup α
inst✝¹ : LinearOrder α
inst✝ : CovariantClass α α (fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
a b c : α
⊢ 0 < |a| ↔ a ≠ 0

Next tactic:
rcases lt_trichotomy a 0 with (ha | rfl | ha)
@[simp]
theorem abs_pos : 0 < |a| ↔ a ≠ 0 := by
  rcases lt_trichotomy a 0 with (ha | rfl | ha)
  · 

Proof state:
case inl
α : Type u_1
inst✝² : AddGroup α
inst✝¹ : LinearOrder α
inst✝ : CovariantClass α α (fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
a b c : α
ha : a < 0
⊢ 0 < |a| ↔ a ≠ 0

Next tactic:
simp [abs_of_neg ha, neg_pos, ha.ne, ha]
@[simp]
theorem abs_pos : 0 < |a| ↔ a ≠ 0 := by
  rcases lt_trichotomy a 0 with (ha | rfl | ha)
  · simp [abs_of_neg ha, neg_pos, ha.ne, ha]
  · 

Proof state:
case inr.inl
α : Type u_1
inst✝² : AddGroup α
inst✝¹ : LinearOrder α
inst✝ : CovariantClass α α (fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
b c : α
⊢ 0 < |0| ↔ 0 ≠ 0

Next tactic:
simp
@[simp]
theorem abs_pos : 0 < |a| ↔ a ≠ 0 := by
  rcases lt_trichotomy a 0 with (ha | rfl | ha)
  · simp [abs_of_neg ha, neg_pos, ha.ne, ha]
  · simp
  · 

Proof state:
case inr.inr
α : Type u_1
inst✝² : AddGroup α
inst✝¹ : LinearOrder α
inst✝ : CovariantClass α α (fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
a b c : α
ha : 0 < a
⊢ 0 < |a| ↔ a ≠ 0

Next tactic:
simp [abs_of_pos ha, ha, ha.ne.symm]
theorem neg_abs_le_self (a : α) : -|a| ≤ a := by
  

Proof state:
α : Type u_1
inst✝² : AddGroup α
inst✝¹ : LinearOrder α
inst✝ : CovariantClass α α (fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
a✝ b c a : α
⊢ -|a| ≤ a

Next tactic:
rcases le_total 0 a with h | h
theorem neg_abs_le_self (a : α) : -|a| ≤ a := by
  rcases le_total 0 a with h | h
  · 

Proof state:
case inl
α : Type u_1
inst✝² : AddGroup α
inst✝¹ : LinearOrder α
inst✝ : CovariantClass α α (fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
a✝ b c a : α
h : 0 ≤ a
⊢ -|a| ≤ a

Next tactic:
calc
      -|a| = -a := congr_arg Neg.neg (abs_of_nonneg h)
      _ ≤ 0 := neg_nonpos.mpr h
      _ ≤ a := h
theorem neg_abs_le_self (a : α) : -|a| ≤ a := by
  rcases le_total 0 a with h | h
  · calc
      -|a| = -a := congr_arg Neg.neg (abs_of_nonneg h)
      _ ≤ 0 := neg_nonpos.mpr h
      _ ≤ a := h
  · 

Proof state:
case inr
α : Type u_1
inst✝² : AddGroup α
inst✝¹ : LinearOrder α
inst✝ : CovariantClass α α (fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
a✝ b c a : α
h : a ≤ 0
⊢ -|a| ≤ a

Next tactic:
calc
      -|a| = - -a := congr_arg Neg.neg (abs_of_nonpos h)
      _ ≤ a := (neg_neg a).le
theorem add_abs_nonneg (a : α) : 0 ≤ a + |a| := by
  

Proof state:
α : Type u_1
inst✝² : AddGroup α
inst✝¹ : LinearOrder α
inst✝ : CovariantClass α α (fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
a✝ b c a : α
⊢ 0 ≤ a + |a|

Next tactic:
rw [← add_right_neg a]
theorem add_abs_nonneg (a : α) : 0 ≤ a + |a| := by
  rw [← add_right_neg a]
  

Proof state:
α : Type u_1
inst✝² : AddGroup α
inst✝¹ : LinearOrder α
inst✝ : CovariantClass α α (fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
a✝ b c a : α
⊢ a + -a ≤ a + |a|

Next tactic:
apply add_le_add_left
theorem add_abs_nonneg (a : α) : 0 ≤ a + |a| := by
  rw [← add_right_neg a]
  apply add_le_add_left
  

Proof state:
case bc
α : Type u_1
inst✝² : AddGroup α
inst✝¹ : LinearOrder α
inst✝ : CovariantClass α α (fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
a✝ b c a : α
⊢ -a ≤ |a|

Next tactic:
exact neg_le_abs_self a
theorem neg_abs_le_neg (a : α) : -|a| ≤ -a := by 

Proof state:
α : Type u_1
inst✝² : AddGroup α
inst✝¹ : LinearOrder α
inst✝ : CovariantClass α α (fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
a✝ b c a : α
⊢ -|a| ≤ -a

Next tactic:
simpa using neg_abs_le_self (-a)
theorem abs_le_abs_of_nonpos (ha : a ≤ 0) (hab : b ≤ a) : |a| ≤ |b| := by
  

Proof state:
α : Type u_1
inst✝³ : AddGroup α
inst✝² : LinearOrder α
inst✝¹ : CovariantClass α α (fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
a b c : α
inst✝ : CovariantClass α α (swap fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
ha : a ≤ 0
hab : b ≤ a
⊢ |a| ≤ |b|

Next tactic:
rw [abs_of_nonpos ha, abs_of_nonpos (hab.trans ha)]
theorem abs_le_abs_of_nonpos (ha : a ≤ 0) (hab : b ≤ a) : |a| ≤ |b| := by
  rw [abs_of_nonpos ha, abs_of_nonpos (hab.trans ha)]
  

Proof state:
α : Type u_1
inst✝³ : AddGroup α
inst✝² : LinearOrder α
inst✝¹ : CovariantClass α α (fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
a b c : α
inst✝ : CovariantClass α α (swap fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
ha : a ≤ 0
hab : b ≤ a
⊢ -a ≤ -b

Next tactic:
exact neg_le_neg_iff.mpr hab
theorem abs_lt : |a| < b ↔ -b < a ∧ a < b :=
  max_lt_iff.trans <| and_comm.trans <| by 

Proof state:
α : Type u_1
inst✝³ : AddGroup α
inst✝² : LinearOrder α
inst✝¹ : CovariantClass α α (fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
a b c : α
inst✝ : CovariantClass α α (swap fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
⊢ -a < b ∧ a < b ↔ -b < a ∧ a < b

Next tactic:
rw [neg_lt]
theorem max_sub_min_eq_abs' (a b : α) : max a b - min a b = |a - b| := by
  

Proof state:
α : Type u_1
inst✝³ : AddGroup α
inst✝² : LinearOrder α
inst✝¹ : CovariantClass α α (fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
a✝ b✝ c : α
inst✝ : CovariantClass α α (swap fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
a b : α
⊢ max a b - min a b = |a - b|

Next tactic:
rcases le_total a b with ab | ba
theorem max_sub_min_eq_abs' (a b : α) : max a b - min a b = |a - b| := by
  rcases le_total a b with ab | ba
  · 

Proof state:
case inl
α : Type u_1
inst✝³ : AddGroup α
inst✝² : LinearOrder α
inst✝¹ : CovariantClass α α (fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
a✝ b✝ c : α
inst✝ : CovariantClass α α (swap fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
a b : α
ab : a ≤ b
⊢ max a b - min a b = |a - b|

Next tactic:
rw [max_eq_right ab, min_eq_left ab, abs_of_nonpos, neg_sub]
theorem max_sub_min_eq_abs' (a b : α) : max a b - min a b = |a - b| := by
  rcases le_total a b with ab | ba
  · rw [max_eq_right ab, min_eq_left ab, abs_of_nonpos, neg_sub]
    

Proof state:
case inl
α : Type u_1
inst✝³ : AddGroup α
inst✝² : LinearOrder α
inst✝¹ : CovariantClass α α (fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
a✝ b✝ c : α
inst✝ : CovariantClass α α (swap fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
a b : α
ab : a ≤ b
⊢ a - b ≤ 0

Next tactic:
rwa [sub_nonpos]
theorem max_sub_min_eq_abs' (a b : α) : max a b - min a b = |a - b| := by
  rcases le_total a b with ab | ba
  · rw [max_eq_right ab, min_eq_left ab, abs_of_nonpos, neg_sub]
    rwa [sub_nonpos]
  · 

Proof state:
case inr
α : Type u_1
inst✝³ : AddGroup α
inst✝² : LinearOrder α
inst✝¹ : CovariantClass α α (fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
a✝ b✝ c : α
inst✝ : CovariantClass α α (swap fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
a b : α
ba : b ≤ a
⊢ max a b - min a b = |a - b|

Next tactic:
rw [max_eq_left ba, min_eq_right ba, abs_of_nonneg]
theorem max_sub_min_eq_abs' (a b : α) : max a b - min a b = |a - b| := by
  rcases le_total a b with ab | ba
  · rw [max_eq_right ab, min_eq_left ab, abs_of_nonpos, neg_sub]
    rwa [sub_nonpos]
  · rw [max_eq_left ba, min_eq_right ba, abs_of_nonneg]
    

Proof state:
case inr
α : Type u_1
inst✝³ : AddGroup α
inst✝² : LinearOrder α
inst✝¹ : CovariantClass α α (fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
a✝ b✝ c : α
inst✝ : CovariantClass α α (swap fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
a b : α
ba : b ≤ a
⊢ 0 ≤ a - b

Next tactic:
rwa [sub_nonneg]
theorem max_sub_min_eq_abs (a b : α) : max a b - min a b = |b - a| := by
  

Proof state:
α : Type u_1
inst✝³ : AddGroup α
inst✝² : LinearOrder α
inst✝¹ : CovariantClass α α (fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
a✝ b✝ c : α
inst✝ : CovariantClass α α (swap fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
a b : α
⊢ max a b - min a b = |b - a|

Next tactic:
rw [abs_sub_comm]
theorem max_sub_min_eq_abs (a b : α) : max a b - min a b = |b - a| := by
  rw [abs_sub_comm]
  

Proof state:
α : Type u_1
inst✝³ : AddGroup α
inst✝² : LinearOrder α
inst✝¹ : CovariantClass α α (fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
a✝ b✝ c : α
inst✝ : CovariantClass α α (swap fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
a b : α
⊢ max a b - min a b = |a - b|

Next tactic:
exact max_sub_min_eq_abs' _ _
theorem abs_le : |a| ≤ b ↔ -b ≤ a ∧ a ≤ b := by 

Proof state:
α : Type u_1
inst✝ : LinearOrderedAddCommGroup α
a b c d : α
⊢ |a| ≤ b ↔ -b ≤ a ∧ a ≤ b

Next tactic:
rw [abs_le', and_comm, @neg_le α]
theorem le_abs' : a ≤ |b| ↔ b ≤ -a ∨ a ≤ b := by 

Proof state:
α : Type u_1
inst✝ : LinearOrderedAddCommGroup α
a b c d : α
⊢ a ≤ |b| ↔ b ≤ -a ∨ a ≤ b

Next tactic:
rw [le_abs, or_comm, @le_neg α]
theorem abs_add' (a b : α) : |a| ≤ |b| + |b + a| := by 

Proof state:
α : Type u_1
inst✝ : LinearOrderedAddCommGroup α
a✝ b✝ c d a b : α
⊢ |a| ≤ |b| + |b + a|

Next tactic:
simpa using abs_add (-b) (b + a)
theorem abs_sub (a b : α) : |a - b| ≤ |a| + |b| := by
  

Proof state:
α : Type u_1
inst✝ : LinearOrderedAddCommGroup α
a✝ b✝ c d a b : α
⊢ |a - b| ≤ |a| + |b|

Next tactic:
rw [sub_eq_add_neg, ← abs_neg b]
theorem abs_sub (a b : α) : |a - b| ≤ |a| + |b| := by
  rw [sub_eq_add_neg, ← abs_neg b]
  

Proof state:
α : Type u_1
inst✝ : LinearOrderedAddCommGroup α
a✝ b✝ c d a b : α
⊢ |a + -b| ≤ |a| + |(-b)|

Next tactic:
exact abs_add a _
theorem abs_sub_le_iff : |a - b| ≤ c ↔ a - b ≤ c ∧ b - a ≤ c := by
  

Proof state:
α : Type u_1
inst✝ : LinearOrderedAddCommGroup α
a b c d : α
⊢ |a - b| ≤ c ↔ a - b ≤ c ∧ b - a ≤ c

Next tactic:
rw [abs_le, neg_le_sub_iff_le_add, sub_le_iff_le_add', and_comm, sub_le_iff_le_add']
theorem abs_sub_lt_iff : |a - b| < c ↔ a - b < c ∧ b - a < c := by
  

Proof state:
α : Type u_1
inst✝ : LinearOrderedAddCommGroup α
a b c d : α
⊢ |a - b| < c ↔ a - b < c ∧ b - a < c

Next tactic:
rw [@abs_lt α, neg_lt_sub_iff_lt_add', sub_lt_iff_lt_add', and_comm, sub_lt_iff_lt_add']
theorem abs_sub_abs_le_abs_sub (a b : α) : |a| - |b| ≤ |a - b| :=
  (@sub_le_iff_le_add α ..).2 <|
    calc
      |a| = |a - b + b| := by 

Proof state:
α : Type u_1
inst✝ : LinearOrderedAddCommGroup α
a✝ b✝ c d a b : α
⊢ |a| = |a - b + b|

Next tactic:
rw [sub_add_cancel]
theorem abs_abs_sub_abs_le_abs_sub (a b : α) : |(|a| - |b|)| ≤ |a - b| :=
  abs_sub_le_iff.2
    ⟨abs_sub_abs_le_abs_sub _ _, by 

Proof state:
α : Type u_1
inst✝ : LinearOrderedAddCommGroup α
a✝ b✝ c d a b : α
⊢ |b| - |a| ≤ |a - b|

Next tactic:
rw [abs_sub_comm]
theorem abs_abs_sub_abs_le_abs_sub (a b : α) : |(|a| - |b|)| ≤ |a - b| :=
  abs_sub_le_iff.2
    ⟨abs_sub_abs_le_abs_sub _ _, by rw [abs_sub_comm]; 

Proof state:
α : Type u_1
inst✝ : LinearOrderedAddCommGroup α
a✝ b✝ c d a b : α
⊢ |b| - |a| ≤ |b - a|

Next tactic:
apply abs_sub_abs_le_abs_sub
theorem abs_eq (hb : 0 ≤ b) : |a| = b ↔ a = b ∨ a = -b := by
  

Proof state:
α : Type u_1
inst✝ : LinearOrderedAddCommGroup α
a b c d : α
hb : 0 ≤ b
⊢ |a| = b ↔ a = b ∨ a = -b

Next tactic:
refine' ⟨eq_or_eq_neg_of_abs_eq, _⟩
theorem abs_eq (hb : 0 ≤ b) : |a| = b ↔ a = b ∨ a = -b := by
  refine' ⟨eq_or_eq_neg_of_abs_eq, _⟩
  

Proof state:
α : Type u_1
inst✝ : LinearOrderedAddCommGroup α
a b c d : α
hb : 0 ≤ b
⊢ a = b ∨ a = -b → |a| = b

Next tactic:
rintro (rfl | rfl)
theorem abs_eq (hb : 0 ≤ b) : |a| = b ↔ a = b ∨ a = -b := by
  refine' ⟨eq_or_eq_neg_of_abs_eq, _⟩
  rintro (rfl | rfl) <;> 

Proof state:
case inl
α : Type u_1
inst✝ : LinearOrderedAddCommGroup α
a c d : α
hb : 0 ≤ a
⊢ |a| = a

Next tactic:
simp only [abs_neg, abs_of_nonneg hb]
theorem abs_eq (hb : 0 ≤ b) : |a| = b ↔ a = b ∨ a = -b := by
  refine' ⟨eq_or_eq_neg_of_abs_eq, _⟩
  rintro (rfl | rfl) <;> 

Proof state:
case inr
α : Type u_1
inst✝ : LinearOrderedAddCommGroup α
b c d : α
hb : 0 ≤ b
⊢ |(-b)| = b

Next tactic:
simp only [abs_neg, abs_of_nonneg hb]
theorem abs_le_max_abs_abs (hab : a ≤ b) (hbc : b ≤ c) : |b| ≤ max |a| |c| :=
  abs_le'.2
    ⟨by 

Proof state:
α : Type u_1
inst✝ : LinearOrderedAddCommGroup α
a b c d : α
hab : a ≤ b
hbc : b ≤ c
⊢ b ≤ max |a| |c|

Next tactic:
simp [hbc.trans (le_abs_self c)]
theorem abs_le_max_abs_abs (hab : a ≤ b) (hbc : b ≤ c) : |b| ≤ max |a| |c| :=
  abs_le'.2
    ⟨by simp [hbc.trans (le_abs_self c)], by
      

Proof state:
α : Type u_1
inst✝ : LinearOrderedAddCommGroup α
a b c d : α
hab : a ≤ b
hbc : b ≤ c
⊢ -b ≤ max |a| |c|

Next tactic:
simp [((@neg_le_neg_iff α ..).mpr hab).trans (neg_le_abs_self a)]
theorem abs_sub_le (a b c : α) : |a - c| ≤ |a - b| + |b - c| :=
  calc
    |a - c| = |a - b + (b - c)| := by 

Proof state:
α : Type u_1
inst✝ : LinearOrderedAddCommGroup α
a✝ b✝ c✝ d a b c : α
⊢ |a - c| = |a - b + (b - c)|

Next tactic:
rw [sub_add_sub_cancel]
@[simp]
theorem abs_eq_self : |a| = a ↔ 0 ≤ a := by
  

Proof state:
α : Type u_1
inst✝ : LinearOrderedAddCommGroup α
a b c d : α
⊢ |a| = a ↔ 0 ≤ a

Next tactic:
rw [abs_eq_max_neg, max_eq_left_iff, neg_le_self_iff]
@[simp]
theorem abs_eq_neg_self : |a| = -a ↔ a ≤ 0 := by
  

Proof state:
α : Type u_1
inst✝ : LinearOrderedAddCommGroup α
a b c d : α
⊢ |a| = -a ↔ a ≤ 0

Next tactic:
rw [abs_eq_max_neg, max_eq_right_iff, le_neg_self_iff]
/-- For an element `a` of a linear ordered ring, either `abs a = a` and `0 ≤ a`,
    or `abs a = -a` and `a < 0`.
    Use cases on this lemma to automate linarith in inequalities -/
theorem abs_cases (a : α) : |a| = a ∧ 0 ≤ a ∨ |a| = -a ∧ a < 0 := by
  

Proof state:
α : Type u_1
inst✝ : LinearOrderedAddCommGroup α
a✝ b c d a : α
⊢ |a| = a ∧ 0 ≤ a ∨ |a| = -a ∧ a < 0

Next tactic:
by_cases h : 0 ≤ a
/-- For an element `a` of a linear ordered ring, either `abs a = a` and `0 ≤ a`,
    or `abs a = -a` and `a < 0`.
    Use cases on this lemma to automate linarith in inequalities -/
theorem abs_cases (a : α) : |a| = a ∧ 0 ≤ a ∨ |a| = -a ∧ a < 0 := by
  by_cases h : 0 ≤ a
  · 

Proof state:
case pos
α : Type u_1
inst✝ : LinearOrderedAddCommGroup α
a✝ b c d a : α
h : 0 ≤ a
⊢ |a| = a ∧ 0 ≤ a ∨ |a| = -a ∧ a < 0

Next tactic:
left
/-- For an element `a` of a linear ordered ring, either `abs a = a` and `0 ≤ a`,
    or `abs a = -a` and `a < 0`.
    Use cases on this lemma to automate linarith in inequalities -/
theorem abs_cases (a : α) : |a| = a ∧ 0 ≤ a ∨ |a| = -a ∧ a < 0 := by
  by_cases h : 0 ≤ a
  · left
    

Proof state:
case pos.h
α : Type u_1
inst✝ : LinearOrderedAddCommGroup α
a✝ b c d a : α
h : 0 ≤ a
⊢ |a| = a ∧ 0 ≤ a

Next tactic:
exact ⟨abs_eq_self.mpr h, h⟩
/-- For an element `a` of a linear ordered ring, either `abs a = a` and `0 ≤ a`,
    or `abs a = -a` and `a < 0`.
    Use cases on this lemma to automate linarith in inequalities -/
theorem abs_cases (a : α) : |a| = a ∧ 0 ≤ a ∨ |a| = -a ∧ a < 0 := by
  by_cases h : 0 ≤ a
  · left
    exact ⟨abs_eq_self.mpr h, h⟩
  · 

Proof state:
case neg
α : Type u_1
inst✝ : LinearOrderedAddCommGroup α
a✝ b c d a : α
h : ¬0 ≤ a
⊢ |a| = a ∧ 0 ≤ a ∨ |a| = -a ∧ a < 0

Next tactic:
right
/-- For an element `a` of a linear ordered ring, either `abs a = a` and `0 ≤ a`,
    or `abs a = -a` and `a < 0`.
    Use cases on this lemma to automate linarith in inequalities -/
theorem abs_cases (a : α) : |a| = a ∧ 0 ≤ a ∨ |a| = -a ∧ a < 0 := by
  by_cases h : 0 ≤ a
  · left
    exact ⟨abs_eq_self.mpr h, h⟩
  · right
    

Proof state:
case neg.h
α : Type u_1
inst✝ : LinearOrderedAddCommGroup α
a✝ b c d a : α
h : ¬0 ≤ a
⊢ |a| = -a ∧ a < 0

Next tactic:
push_neg at h
/-- For an element `a` of a linear ordered ring, either `abs a = a` and `0 ≤ a`,
    or `abs a = -a` and `a < 0`.
    Use cases on this lemma to automate linarith in inequalities -/
theorem abs_cases (a : α) : |a| = a ∧ 0 ≤ a ∨ |a| = -a ∧ a < 0 := by
  by_cases h : 0 ≤ a
  · left
    exact ⟨abs_eq_self.mpr h, h⟩
  · right
    push_neg at h
    

Proof state:
case neg.h
α : Type u_1
inst✝ : LinearOrderedAddCommGroup α
a✝ b c d a : α
h : a < 0
⊢ |a| = -a ∧ a < 0

Next tactic:
exact ⟨abs_eq_neg_self.mpr (le_of_lt h), h⟩
@[simp]
theorem max_zero_add_max_neg_zero_eq_abs_self (a : α) : max a 0 + max (-a) 0 = |a| := by
  

Proof state:
α : Type u_1
inst✝ : LinearOrderedAddCommGroup α
a✝ b c d a : α
⊢ max a 0 + max (-a) 0 = |a|

Next tactic:
symm
@[simp]
theorem max_zero_add_max_neg_zero_eq_abs_self (a : α) : max a 0 + max (-a) 0 = |a| := by
  symm
  

Proof state:
α : Type u_1
inst✝ : LinearOrderedAddCommGroup α
a✝ b c d a : α
⊢ |a| = max a 0 + max (-a) 0

Next tactic:
rcases le_total 0 a with (ha | ha)
@[simp]
theorem max_zero_add_max_neg_zero_eq_abs_self (a : α) : max a 0 + max (-a) 0 = |a| := by
  symm
  rcases le_total 0 a with (ha | ha) <;> 

Proof state:
case inl
α : Type u_1
inst✝ : LinearOrderedAddCommGroup α
a✝ b c d a : α
ha : 0 ≤ a
⊢ |a| = max a 0 + max (-a) 0

Next tactic:
simp [ha]
@[simp]
theorem max_zero_add_max_neg_zero_eq_abs_self (a : α) : max a 0 + max (-a) 0 = |a| := by
  symm
  rcases le_total 0 a with (ha | ha) <;> 

Proof state:
case inr
α : Type u_1
inst✝ : LinearOrderedAddCommGroup α
a✝ b c d a : α
ha : a ≤ 0
⊢ |a| = max a 0 + max (-a) 0

Next tactic:
simp [ha]
theorem cast_type (is : List ℕ) (eq : ds₁ = ds₂) (h : Forall₂ (· < ·) is ds₁) :
    (cast (congr_arg HolorIndex eq) ⟨is, h⟩).val = is := by 

Proof state:
ds₁ ds₂ ds₃ is : List ℕ
eq : ds₁ = ds₂
h : Forall₂ (fun x x_1 => x < x_1) is ds₁
⊢ ↑(cast (_ : HolorIndex ds₁ = HolorIndex ds₂) { val := is, property := h }) = is

Next tactic:
subst eq
theorem cast_type (is : List ℕ) (eq : ds₁ = ds₂) (h : Forall₂ (· < ·) is ds₁) :
    (cast (congr_arg HolorIndex eq) ⟨is, h⟩).val = is := by subst eq; 

Proof state:
ds₁ ds₃ is : List ℕ
h : Forall₂ (fun x x_1 => x < x_1) is ds₁
⊢ ↑(cast (_ : HolorIndex ds₁ = HolorIndex ds₁) { val := is, property := h }) = is

Next tactic:
rfl
theorem take_take : ∀ t : HolorIndex (ds₁ ++ ds₂ ++ ds₃), t.assocRight.take = t.take.take
  | ⟨is, h⟩ =>
    Subtype.eq <| by
      

Proof state:
ds₁ ds₂ ds₃ is : List ℕ
h : Forall₂ (fun x x_1 => x < x_1) is (ds₁ ++ ds₂ ++ ds₃)
⊢ ↑(take (assocRight { val := is, property := h })) = ↑(take (take { val := is, property := h }))

Next tactic:
simp [assocRight, take, cast_type, List.take_take, Nat.le_add_right, min_eq_left]
theorem drop_take : ∀ t : HolorIndex (ds₁ ++ ds₂ ++ ds₃), t.assocRight.drop.take = t.take.drop
  | ⟨is, h⟩ => Subtype.eq (by 

Proof state:
ds₁ ds₂ ds₃ is : List ℕ
h : Forall₂ (fun x x_1 => x < x_1) is (ds₁ ++ ds₂ ++ ds₃)
⊢ ↑(take (drop (assocRight { val := is, property := h }))) = ↑(drop (take { val := is, property := h }))

Next tactic:
simp [assocRight, take, drop, cast_type, List.drop_take]
theorem drop_drop : ∀ t : HolorIndex (ds₁ ++ ds₂ ++ ds₃), t.assocRight.drop.drop = t.drop
  | ⟨is, h⟩ => Subtype.eq (by 

Proof state:
ds₁ ds₂ ds₃ is : List ℕ
h : Forall₂ (fun x x_1 => x < x_1) is (ds₁ ++ ds₂ ++ ds₃)
⊢ ↑(drop (drop (assocRight { val := is, property := h }))) = ↑(drop { val := is, property := h })

Next tactic:
simp [add_comm, assocRight, drop, cast_type, List.drop_drop]
theorem cast_type (eq : ds₁ = ds₂) (a : Holor α ds₁) :
    cast (congr_arg (Holor α) eq) a = fun t => a (cast (congr_arg HolorIndex eq.symm) t) := by
  

Proof state:
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
eq : ds₁ = ds₂
a : Holor α ds₁
⊢ cast (_ : Holor α ds₁ = Holor α ds₂) a = fun t => a (cast (_ : HolorIndex ds₂ = HolorIndex ds₁) t)

Next tactic:
subst eq
theorem cast_type (eq : ds₁ = ds₂) (a : Holor α ds₁) :
    cast (congr_arg (Holor α) eq) a = fun t => a (cast (congr_arg HolorIndex eq.symm) t) := by
  subst eq; 

Proof state:
α : Type
d : ℕ
ds ds₁ ds₃ : List ℕ
a : Holor α ds₁
⊢ cast (_ : Holor α ds₁ = Holor α ds₁) a = fun t => a (cast (_ : HolorIndex ds₁ = HolorIndex ds₁) t)

Next tactic:
rfl
theorem mul_assoc0 [Semigroup α] (x : Holor α ds₁) (y : Holor α ds₂) (z : Holor α ds₃) :
    x ⊗ y ⊗ z = (x ⊗ (y ⊗ z)).assocLeft :=
  funext fun t : HolorIndex (ds₁ ++ ds₂ ++ ds₃) => by
    

Proof state:
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
inst✝ : Semigroup α
x : Holor α ds₁
y : Holor α ds₂
z : Holor α ds₃
t : HolorIndex (ds₁ ++ ds₂ ++ ds₃)
⊢ (x ⊗ y ⊗ z) t = assocLeft (x ⊗ (y ⊗ z)) t

Next tactic:
rw [assocLeft]
theorem mul_assoc0 [Semigroup α] (x : Holor α ds₁) (y : Holor α ds₂) (z : Holor α ds₃) :
    x ⊗ y ⊗ z = (x ⊗ (y ⊗ z)).assocLeft :=
  funext fun t : HolorIndex (ds₁ ++ ds₂ ++ ds₃) => by
    rw [assocLeft]
    

Proof state:
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
inst✝ : Semigroup α
x : Holor α ds₁
y : Holor α ds₂
z : Holor α ds₃
t : HolorIndex (ds₁ ++ ds₂ ++ ds₃)
⊢ (x ⊗ y ⊗ z) t = cast (_ : Holor α (ds₁ ++ (ds₂ ++ ds₃)) = Holor α (ds₁ ++ ds₂ ++ ds₃)) (x ⊗ (y ⊗ z)) t

Next tactic:
unfold mul
theorem mul_assoc0 [Semigroup α] (x : Holor α ds₁) (y : Holor α ds₂) (z : Holor α ds₃) :
    x ⊗ y ⊗ z = (x ⊗ (y ⊗ z)).assocLeft :=
  funext fun t : HolorIndex (ds₁ ++ ds₂ ++ ds₃) => by
    rw [assocLeft]
    unfold mul
    

Proof state:
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
inst✝ : Semigroup α
x : Holor α ds₁
y : Holor α ds₂
z : Holor α ds₃
t : HolorIndex (ds₁ ++ ds₂ ++ ds₃)
⊢ x (HolorIndex.take (HolorIndex.take t)) * y (HolorIndex.drop (HolorIndex.take t)) * z (HolorIndex.drop t) =
    cast (_ : Holor α (ds₁ ++ (ds₂ ++ ds₃)) = Holor α (ds₁ ++ ds₂ ++ ds₃))
      (fun t =>
        x (HolorIndex.take t) * (y (HolorIndex.take (HolorIndex.drop t)) * z (HolorIndex.drop (HolorIndex.drop t))))
      t

Next tactic:
rw [mul_assoc, ← HolorIndex.take_take, ← HolorIndex.drop_take, ← HolorIndex.drop_drop,
      cast_type]
theorem mul_assoc0 [Semigroup α] (x : Holor α ds₁) (y : Holor α ds₂) (z : Holor α ds₃) :
    x ⊗ y ⊗ z = (x ⊗ (y ⊗ z)).assocLeft :=
  funext fun t : HolorIndex (ds₁ ++ ds₂ ++ ds₃) => by
    rw [assocLeft]
    unfold mul
    rw [mul_assoc, ← HolorIndex.take_take, ← HolorIndex.drop_take, ← HolorIndex.drop_drop,
      cast_type]
    

Proof state:
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
inst✝ : Semigroup α
x : Holor α ds₁
y : Holor α ds₂
z : Holor α ds₃
t : HolorIndex (ds₁ ++ ds₂ ++ ds₃)
⊢ x (HolorIndex.take (HolorIndex.assocRight t)) *
      (y (HolorIndex.take (HolorIndex.drop (HolorIndex.assocRight t))) *
        z (HolorIndex.drop (HolorIndex.drop (HolorIndex.assocRight t)))) =
    (fun t =>
        x (HolorIndex.take (cast (_ : HolorIndex (ds₁ ++ ds₂ ++ ds₃) = HolorIndex (ds₁ ++ (ds₂ ++ ds₃))) t)) *
          (y
              (HolorIndex.take
                (HolorIndex.drop (cast (_ : HolorIndex (ds₁ ++ ds₂ ++ ds₃) = HolorIndex (ds₁ ++ (ds₂ ++ ds₃))) t))) *
            z
              (HolorIndex.drop
                (HolorIndex.drop (cast (_ : HolorIndex (ds₁ ++ ds₂ ++ ds₃) = HolorIndex (ds₁ ++ (ds₂ ++ ds₃))) t)))))
      t
case eq
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
inst✝ : Semigroup α
x : Holor α ds₁
y : Holor α ds₂
z : Holor α ds₃
t : HolorIndex (ds₁ ++ ds₂ ++ ds₃)
⊢ ds₁ ++ (ds₂ ++ ds₃) = ds₁ ++ ds₂ ++ ds₃

Next tactic:
rfl
theorem mul_assoc0 [Semigroup α] (x : Holor α ds₁) (y : Holor α ds₂) (z : Holor α ds₃) :
    x ⊗ y ⊗ z = (x ⊗ (y ⊗ z)).assocLeft :=
  funext fun t : HolorIndex (ds₁ ++ ds₂ ++ ds₃) => by
    rw [assocLeft]
    unfold mul
    rw [mul_assoc, ← HolorIndex.take_take, ← HolorIndex.drop_take, ← HolorIndex.drop_drop,
      cast_type]
    rfl
    

Proof state:
case eq
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
inst✝ : Semigroup α
x : Holor α ds₁
y : Holor α ds₂
z : Holor α ds₃
t : HolorIndex (ds₁ ++ ds₂ ++ ds₃)
⊢ ds₁ ++ (ds₂ ++ ds₃) = ds₁ ++ ds₂ ++ ds₃

Next tactic:
rw [append_assoc]
theorem mul_assoc [Semigroup α] (x : Holor α ds₁) (y : Holor α ds₂) (z : Holor α ds₃) :
    HEq (mul (mul x y) z) (mul x (mul y z)) := by 

Proof state:
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
inst✝ : Semigroup α
x : Holor α ds₁
y : Holor α ds₂
z : Holor α ds₃
⊢ HEq (x ⊗ y ⊗ z) (x ⊗ (y ⊗ z))

Next tactic:
simp [cast_heq, mul_assoc0, assocLeft]