l3lab/ntp-mathlib huggingface dataset:
/-- The norm of the sum of two vectors equals the norm of their difference if and only if
the angle between them is π/2. -/
theorem norm_add_eq_norm_sub_iff_angle_eq_pi_div_two (x y : V) :
    ‖x + y‖ = ‖x - y‖ ↔ angle x y = π / 2 := by
  

Proof state:
V : Type u_1
inst✝¹ : NormedAddCommGroup V
inst✝ : InnerProductSpace ℝ V
x✝ y✝ x y : V
⊢ ‖x + y‖ = ‖x - y‖ ↔ angle x y = π / 2

Next tactic:
rw [← sq_eq_sq (norm_nonneg (x + y)) (norm_nonneg (x - y)),
    ← inner_eq_zero_iff_angle_eq_pi_div_two x y, norm_add_pow_two_real, norm_sub_pow_two_real]
/-- The norm of the sum of two vectors equals the norm of their difference if and only if
the angle between them is π/2. -/
theorem norm_add_eq_norm_sub_iff_angle_eq_pi_div_two (x y : V) :
    ‖x + y‖ = ‖x - y‖ ↔ angle x y = π / 2 := by
  rw [← sq_eq_sq (norm_nonneg (x + y)) (norm_nonneg (x - y)),
    ← inner_eq_zero_iff_angle_eq_pi_div_two x y, norm_add_pow_two_real, norm_sub_pow_two_real]
  

Proof state:
V : Type u_1
inst✝¹ : NormedAddCommGroup V
inst✝ : InnerProductSpace ℝ V
x✝ y✝ x y : V
⊢ ‖x‖ ^ 2 + 2 * inner x y + ‖y‖ ^ 2 = ‖x‖ ^ 2 - 2 * inner x y + ‖y‖ ^ 2 ↔ inner x y = 0

Next tactic:
constructor
/-- The norm of the sum of two vectors equals the norm of their difference if and only if
the angle between them is π/2. -/
theorem norm_add_eq_norm_sub_iff_angle_eq_pi_div_two (x y : V) :
    ‖x + y‖ = ‖x - y‖ ↔ angle x y = π / 2 := by
  rw [← sq_eq_sq (norm_nonneg (x + y)) (norm_nonneg (x - y)),
    ← inner_eq_zero_iff_angle_eq_pi_div_two x y, norm_add_pow_two_real, norm_sub_pow_two_real]
  constructor <;> 

Proof state:
case mp
V : Type u_1
inst✝¹ : NormedAddCommGroup V
inst✝ : InnerProductSpace ℝ V
x✝ y✝ x y : V
⊢ ‖x‖ ^ 2 + 2 * inner x y + ‖y‖ ^ 2 = ‖x‖ ^ 2 - 2 * inner x y + ‖y‖ ^ 2 → inner x y = 0

Next tactic:
intro h
/-- The norm of the sum of two vectors equals the norm of their difference if and only if
the angle between them is π/2. -/
theorem norm_add_eq_norm_sub_iff_angle_eq_pi_div_two (x y : V) :
    ‖x + y‖ = ‖x - y‖ ↔ angle x y = π / 2 := by
  rw [← sq_eq_sq (norm_nonneg (x + y)) (norm_nonneg (x - y)),
    ← inner_eq_zero_iff_angle_eq_pi_div_two x y, norm_add_pow_two_real, norm_sub_pow_two_real]
  constructor <;> 

Proof state:
case mpr
V : Type u_1
inst✝¹ : NormedAddCommGroup V
inst✝ : InnerProductSpace ℝ V
x✝ y✝ x y : V
⊢ inner x y = 0 → ‖x‖ ^ 2 + 2 * inner x y + ‖y‖ ^ 2 = ‖x‖ ^ 2 - 2 * inner x y + ‖y‖ ^ 2

Next tactic:
intro h
/-- The norm of the sum of two vectors equals the norm of their difference if and only if
the angle between them is π/2. -/
theorem norm_add_eq_norm_sub_iff_angle_eq_pi_div_two (x y : V) :
    ‖x + y‖ = ‖x - y‖ ↔ angle x y = π / 2 := by
  rw [← sq_eq_sq (norm_nonneg (x + y)) (norm_nonneg (x - y)),
    ← inner_eq_zero_iff_angle_eq_pi_div_two x y, norm_add_pow_two_real, norm_sub_pow_two_real]
  constructor <;> intro h <;> 

Proof state:
case mp
V : Type u_1
inst✝¹ : NormedAddCommGroup V
inst✝ : InnerProductSpace ℝ V
x✝ y✝ x y : V
h : ‖x‖ ^ 2 + 2 * inner x y + ‖y‖ ^ 2 = ‖x‖ ^ 2 - 2 * inner x y + ‖y‖ ^ 2
⊢ inner x y = 0

Next tactic:
linarith
/-- The norm of the sum of two vectors equals the norm of their difference if and only if
the angle between them is π/2. -/
theorem norm_add_eq_norm_sub_iff_angle_eq_pi_div_two (x y : V) :
    ‖x + y‖ = ‖x - y‖ ↔ angle x y = π / 2 := by
  rw [← sq_eq_sq (norm_nonneg (x + y)) (norm_nonneg (x - y)),
    ← inner_eq_zero_iff_angle_eq_pi_div_two x y, norm_add_pow_two_real, norm_sub_pow_two_real]
  constructor <;> intro h <;> 

Proof state:
case mpr
V : Type u_1
inst✝¹ : NormedAddCommGroup V
inst✝ : InnerProductSpace ℝ V
x✝ y✝ x y : V
h : inner x y = 0
⊢ ‖x‖ ^ 2 + 2 * inner x y + ‖y‖ ^ 2 = ‖x‖ ^ 2 - 2 * inner x y + ‖y‖ ^ 2

Next tactic:
linarith
/-- The cosine of the angle between two vectors is 1 if and only if the angle is 0. -/
theorem cos_eq_one_iff_angle_eq_zero : cos (angle x y) = 1 ↔ angle x y = 0 := by
  

Proof state:
V : Type u_1
inst✝¹ : NormedAddCommGroup V
inst✝ : InnerProductSpace ℝ V
x y : V
⊢ cos (angle x y) = 1 ↔ angle x y = 0

Next tactic:
rw [← cos_zero]
/-- The cosine of the angle between two vectors is 1 if and only if the angle is 0. -/
theorem cos_eq_one_iff_angle_eq_zero : cos (angle x y) = 1 ↔ angle x y = 0 := by
  rw [← cos_zero]
  

Proof state:
V : Type u_1
inst✝¹ : NormedAddCommGroup V
inst✝ : InnerProductSpace ℝ V
x y : V
⊢ cos (angle x y) = cos 0 ↔ angle x y = 0

Next tactic:
exact injOn_cos.eq_iff ⟨angle_nonneg x y, angle_le_pi x y⟩ (left_mem_Icc.2 pi_pos.le)
/-- The cosine of the angle between two vectors is 0 if and only if the angle is π / 2. -/
theorem cos_eq_zero_iff_angle_eq_pi_div_two : cos (angle x y) = 0 ↔ angle x y = π / 2 := by
  

Proof state:
V : Type u_1
inst✝¹ : NormedAddCommGroup V
inst✝ : InnerProductSpace ℝ V
x y : V
⊢ cos (angle x y) = 0 ↔ angle x y = π / 2

Next tactic:
rw [← cos_pi_div_two]
/-- The cosine of the angle between two vectors is 0 if and only if the angle is π / 2. -/
theorem cos_eq_zero_iff_angle_eq_pi_div_two : cos (angle x y) = 0 ↔ angle x y = π / 2 := by
  rw [← cos_pi_div_two]
  

Proof state:
V : Type u_1
inst✝¹ : NormedAddCommGroup V
inst✝ : InnerProductSpace ℝ V
x y : V
⊢ cos (angle x y) = cos (π / 2) ↔ angle x y = π / 2

Next tactic:
apply injOn_cos.eq_iff ⟨angle_nonneg x y, angle_le_pi x y⟩
/-- The cosine of the angle between two vectors is 0 if and only if the angle is π / 2. -/
theorem cos_eq_zero_iff_angle_eq_pi_div_two : cos (angle x y) = 0 ↔ angle x y = π / 2 := by
  rw [← cos_pi_div_two]
  apply injOn_cos.eq_iff ⟨angle_nonneg x y, angle_le_pi x y⟩
  

Proof state:
V : Type u_1
inst✝¹ : NormedAddCommGroup V
inst✝ : InnerProductSpace ℝ V
x y : V
⊢ π / 2 ∈ Icc 0 π

Next tactic:
constructor
/-- The cosine of the angle between two vectors is 0 if and only if the angle is π / 2. -/
theorem cos_eq_zero_iff_angle_eq_pi_div_two : cos (angle x y) = 0 ↔ angle x y = π / 2 := by
  rw [← cos_pi_div_two]
  apply injOn_cos.eq_iff ⟨angle_nonneg x y, angle_le_pi x y⟩
  constructor <;> 

Proof state:
case left
V : Type u_1
inst✝¹ : NormedAddCommGroup V
inst✝ : InnerProductSpace ℝ V
x y : V
⊢ 0 ≤ π / 2

Next tactic:
linarith [pi_pos]
/-- The cosine of the angle between two vectors is 0 if and only if the angle is π / 2. -/
theorem cos_eq_zero_iff_angle_eq_pi_div_two : cos (angle x y) = 0 ↔ angle x y = π / 2 := by
  rw [← cos_pi_div_two]
  apply injOn_cos.eq_iff ⟨angle_nonneg x y, angle_le_pi x y⟩
  constructor <;> 

Proof state:
case right
V : Type u_1
inst✝¹ : NormedAddCommGroup V
inst✝ : InnerProductSpace ℝ V
x y : V
⊢ π / 2 ≤ π

Next tactic:
linarith [pi_pos]
/-- The cosine of the angle between two vectors is -1 if and only if the angle is π. -/
theorem cos_eq_neg_one_iff_angle_eq_pi : cos (angle x y) = -1 ↔ angle x y = π := by
  

Proof state:
V : Type u_1
inst✝¹ : NormedAddCommGroup V
inst✝ : InnerProductSpace ℝ V
x y : V
⊢ cos (angle x y) = -1 ↔ angle x y = π

Next tactic:
rw [← cos_pi]
/-- The cosine of the angle between two vectors is -1 if and only if the angle is π. -/
theorem cos_eq_neg_one_iff_angle_eq_pi : cos (angle x y) = -1 ↔ angle x y = π := by
  rw [← cos_pi]
  

Proof state:
V : Type u_1
inst✝¹ : NormedAddCommGroup V
inst✝ : InnerProductSpace ℝ V
x y : V
⊢ cos (angle x y) = cos π ↔ angle x y = π

Next tactic:
exact injOn_cos.eq_iff ⟨angle_nonneg x y, angle_le_pi x y⟩ (right_mem_Icc.2 pi_pos.le)
/-- The sine of the angle between two vectors is 0 if and only if the angle is 0 or π. -/
theorem sin_eq_zero_iff_angle_eq_zero_or_angle_eq_pi :
    sin (angle x y) = 0 ↔ angle x y = 0 ∨ angle x y = π := by
  

Proof state:
V : Type u_1
inst✝¹ : NormedAddCommGroup V
inst✝ : InnerProductSpace ℝ V
x y : V
⊢ sin (angle x y) = 0 ↔ angle x y = 0 ∨ angle x y = π

Next tactic:
rw [sin_eq_zero_iff_cos_eq, cos_eq_one_iff_angle_eq_zero, cos_eq_neg_one_iff_angle_eq_pi]
/-- The sine of the angle between two vectors is 1 if and only if the angle is π / 2. -/
theorem sin_eq_one_iff_angle_eq_pi_div_two : sin (angle x y) = 1 ↔ angle x y = π / 2 := by
  

Proof state:
V : Type u_1
inst✝¹ : NormedAddCommGroup V
inst✝ : InnerProductSpace ℝ V
x y : V
⊢ sin (angle x y) = 1 ↔ angle x y = π / 2

Next tactic:
refine' ⟨fun h => _, fun h => by rw [h, sin_pi_div_two]⟩
/-- The sine of the angle between two vectors is 1 if and only if the angle is π / 2. -/
theorem sin_eq_one_iff_angle_eq_pi_div_two : sin (angle x y) = 1 ↔ angle x y = π / 2 := by
  refine' ⟨fun h => _, fun h => by 

Proof state:
V : Type u_1
inst✝¹ : NormedAddCommGroup V
inst✝ : InnerProductSpace ℝ V
x y : V
h : angle x y = π / 2
⊢ sin (angle x y) = 1

Next tactic:
rw [h, sin_pi_div_two]
/-- The sine of the angle between two vectors is 1 if and only if the angle is π / 2. -/
theorem sin_eq_one_iff_angle_eq_pi_div_two : sin (angle x y) = 1 ↔ angle x y = π / 2 := by
  refine' ⟨fun h => _, fun h => by rw [h, sin_pi_div_two]⟩
  

Proof state:
V : Type u_1
inst✝¹ : NormedAddCommGroup V
inst✝ : InnerProductSpace ℝ V
x y : V
h : sin (angle x y) = 1
⊢ angle x y = π / 2

Next tactic:
rw [← cos_eq_zero_iff_angle_eq_pi_div_two, ← abs_eq_zero, abs_cos_eq_sqrt_one_sub_sin_sq, h]
/-- The sine of the angle between two vectors is 1 if and only if the angle is π / 2. -/
theorem sin_eq_one_iff_angle_eq_pi_div_two : sin (angle x y) = 1 ↔ angle x y = π / 2 := by
  refine' ⟨fun h => _, fun h => by rw [h, sin_pi_div_two]⟩
  rw [← cos_eq_zero_iff_angle_eq_pi_div_two, ← abs_eq_zero, abs_cos_eq_sqrt_one_sub_sin_sq, h]
  

Proof state:
V : Type u_1
inst✝¹ : NormedAddCommGroup V
inst✝ : InnerProductSpace ℝ V
x y : V
h : sin (angle x y) = 1
⊢ sqrt (1 - 1 ^ 2) = 0

Next tactic:
simp
instance [Preorder α] [SuccOrder α] :
    PredOrder αᵒᵈ where
  pred := toDual ∘ SuccOrder.succ ∘ ofDual
  pred_le := by
    

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : SuccOrder α
⊢ ∀ (a : αᵒᵈ), (⇑toDual ∘ SuccOrder.succ ∘ ⇑ofDual) a ≤ a

Next tactic:
simp only [comp, OrderDual.forall, ofDual_toDual, toDual_le_toDual,
     SuccOrder.le_succ, implies_true]
instance [Preorder α] [SuccOrder α] :
    PredOrder αᵒᵈ where
  pred := toDual ∘ SuccOrder.succ ∘ ofDual
  pred_le := by
    simp only [comp, OrderDual.forall, ofDual_toDual, toDual_le_toDual,
     SuccOrder.le_succ, implies_true]
  min_of_le_pred h := by 

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : SuccOrder α
a✝ : αᵒᵈ
h : a✝ ≤ (⇑toDual ∘ SuccOrder.succ ∘ ⇑ofDual) a✝
⊢ IsMin a✝

Next tactic:
apply SuccOrder.max_of_succ_le h
instance [Preorder α] [SuccOrder α] :
    PredOrder αᵒᵈ where
  pred := toDual ∘ SuccOrder.succ ∘ ofDual
  pred_le := by
    simp only [comp, OrderDual.forall, ofDual_toDual, toDual_le_toDual,
     SuccOrder.le_succ, implies_true]
  min_of_le_pred h := by apply SuccOrder.max_of_succ_le h
  le_pred_of_lt := by 

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : SuccOrder α
⊢ ∀ {a b : αᵒᵈ}, a < b → a ≤ (⇑toDual ∘ SuccOrder.succ ∘ ⇑ofDual) b

Next tactic:
intro a b h
instance [Preorder α] [SuccOrder α] :
    PredOrder αᵒᵈ where
  pred := toDual ∘ SuccOrder.succ ∘ ofDual
  pred_le := by
    simp only [comp, OrderDual.forall, ofDual_toDual, toDual_le_toDual,
     SuccOrder.le_succ, implies_true]
  min_of_le_pred h := by apply SuccOrder.max_of_succ_le h
  le_pred_of_lt := by intro a b h; 

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : SuccOrder α
a b : αᵒᵈ
h : a < b
⊢ a ≤ (⇑toDual ∘ SuccOrder.succ ∘ ⇑ofDual) b

Next tactic:
exact SuccOrder.succ_le_of_lt h
instance [Preorder α] [PredOrder α] :
    SuccOrder αᵒᵈ where
  succ := toDual ∘ PredOrder.pred ∘ ofDual
  le_succ := by
    

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : PredOrder α
⊢ ∀ (a : αᵒᵈ), a ≤ (⇑toDual ∘ PredOrder.pred ∘ ⇑ofDual) a

Next tactic:
simp only [comp, OrderDual.forall, ofDual_toDual, toDual_le_toDual,
     PredOrder.pred_le, implies_true]
instance [Preorder α] [PredOrder α] :
    SuccOrder αᵒᵈ where
  succ := toDual ∘ PredOrder.pred ∘ ofDual
  le_succ := by
    simp only [comp, OrderDual.forall, ofDual_toDual, toDual_le_toDual,
     PredOrder.pred_le, implies_true]
  max_of_succ_le h := by 

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : PredOrder α
a✝ : αᵒᵈ
h : (⇑toDual ∘ PredOrder.pred ∘ ⇑ofDual) a✝ ≤ a✝
⊢ IsMax a✝

Next tactic:
apply PredOrder.min_of_le_pred h
instance [Preorder α] [PredOrder α] :
    SuccOrder αᵒᵈ where
  succ := toDual ∘ PredOrder.pred ∘ ofDual
  le_succ := by
    simp only [comp, OrderDual.forall, ofDual_toDual, toDual_le_toDual,
     PredOrder.pred_le, implies_true]
  max_of_succ_le h := by apply PredOrder.min_of_le_pred h
  succ_le_of_lt := by 

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : PredOrder α
⊢ ∀ {a b : αᵒᵈ}, a < b → (⇑toDual ∘ PredOrder.pred ∘ ⇑ofDual) a ≤ b

Next tactic:
intro a b h
instance [Preorder α] [PredOrder α] :
    SuccOrder αᵒᵈ where
  succ := toDual ∘ PredOrder.pred ∘ ofDual
  le_succ := by
    simp only [comp, OrderDual.forall, ofDual_toDual, toDual_le_toDual,
     PredOrder.pred_le, implies_true]
  max_of_succ_le h := by apply PredOrder.min_of_le_pred h
  succ_le_of_lt := by intro a b h; 

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : PredOrder α
a b : αᵒᵈ
h : a < b
⊢ (⇑toDual ∘ PredOrder.pred ∘ ⇑ofDual) a ≤ b

Next tactic:
exact PredOrder.le_pred_of_lt h
/-- A constructor for `SuccOrder α` for `α` a linear order. -/
@[simps]
def SuccOrder.ofCore (succ : α → α) (hn : ∀ {a}, ¬IsMax a → ∀ b, a < b ↔ succ a ≤ b)
    (hm : ∀ a, IsMax a → succ a = a) : SuccOrder α :=
  { succ
    succ_le_of_lt := fun {a b} =>
      by_cases (fun h hab => (hm a h).symm ▸ hab.le) fun h => (hn h b).mp
    le_succ := fun a =>
      by_cases (fun h => (hm a h).symm.le) fun h => le_of_lt <| by 

Proof state:
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
succ : α → α
hn : ∀ {a : α}, ¬IsMax a → ∀ (b : α), a < b ↔ succ a ≤ b
hm : ∀ (a : α), IsMax a → succ a = a
a : α
h : ¬IsMax a
⊢ a < succ a

Next tactic:
simpa using (hn h a).not
/-- A constructor for `SuccOrder α` for `α` a linear order. -/
@[simps]
def SuccOrder.ofCore (succ : α → α) (hn : ∀ {a}, ¬IsMax a → ∀ b, a < b ↔ succ a ≤ b)
    (hm : ∀ a, IsMax a → succ a = a) : SuccOrder α :=
  { succ
    succ_le_of_lt := fun {a b} =>
      by_cases (fun h hab => (hm a h).symm ▸ hab.le) fun h => (hn h b).mp
    le_succ := fun a =>
      by_cases (fun h => (hm a h).symm.le) fun h => le_of_lt <| by simpa using (hn h a).not
    le_of_lt_succ := fun {a b} hab =>
      by_cases (fun h => hm b h ▸ hab.le) fun h => by simpa [hab] using (hn h a).not
    max_of_succ_le := fun {a} => not_imp_not.mp fun h => by 

Proof state:
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
succ : α → α
hn : ∀ {a : α}, ¬IsMax a → ∀ (b : α), a < b ↔ succ a ≤ b
hm : ∀ (a : α), IsMax a → succ a = a
a : α
h : ¬IsMax a
⊢ ¬succ a ≤ a

Next tactic:
simpa using (hn h a).not
/-- A constructor for `SuccOrder α` for `α` a linear order. -/
@[simps]
def SuccOrder.ofCore (succ : α → α) (hn : ∀ {a}, ¬IsMax a → ∀ b, a < b ↔ succ a ≤ b)
    (hm : ∀ a, IsMax a → succ a = a) : SuccOrder α :=
  { succ
    succ_le_of_lt := fun {a b} =>
      by_cases (fun h hab => (hm a h).symm ▸ hab.le) fun h => (hn h b).mp
    le_succ := fun a =>
      by_cases (fun h => (hm a h).symm.le) fun h => le_of_lt <| by simpa using (hn h a).not
    le_of_lt_succ := fun {a b} hab =>
      by_cases (fun h => hm b h ▸ hab.le) fun h => by 

Proof state:
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
succ : α → α
hn : ∀ {a : α}, ¬IsMax a → ∀ (b : α), a < b ↔ succ a ≤ b
hm : ∀ (a : α), IsMax a → succ a = a
a b : α
hab : a < succ b
h : ¬IsMax b
⊢ a ≤ b

Next tactic:
simpa [hab] using (hn h a).not
/-- A constructor for `PredOrder α` for `α` a linear order. -/
@[simps]
def PredOrder.ofCore {α} [LinearOrder α] (pred : α → α)
    (hn : ∀ {a}, ¬IsMin a → ∀ b, b ≤ pred a ↔ b < a) (hm : ∀ a, IsMin a → pred a = a) :
    PredOrder α :=
  { pred
    le_pred_of_lt := fun {a b} =>
      by_cases (fun h hab => (hm b h).symm ▸ hab.le) fun h => (hn h a).mpr
    pred_le := fun a =>
      by_cases (fun h => (hm a h).le) fun h => le_of_lt <| by 

Proof state:
α✝ : Type u_1
β : Type u_2
inst✝¹ : LinearOrder α✝
α : Type ?u.4763
inst✝ : LinearOrder α
pred : α → α
hn : ∀ {a : α}, ¬IsMin a → ∀ (b : α), b ≤ pred a ↔ b < a
hm : ∀ (a : α), IsMin a → pred a = a
a : α
h : ¬IsMin a
⊢ pred a < a

Next tactic:
simpa using (hn h a).not
/-- A constructor for `PredOrder α` for `α` a linear order. -/
@[simps]
def PredOrder.ofCore {α} [LinearOrder α] (pred : α → α)
    (hn : ∀ {a}, ¬IsMin a → ∀ b, b ≤ pred a ↔ b < a) (hm : ∀ a, IsMin a → pred a = a) :
    PredOrder α :=
  { pred
    le_pred_of_lt := fun {a b} =>
      by_cases (fun h hab => (hm b h).symm ▸ hab.le) fun h => (hn h a).mpr
    pred_le := fun a =>
      by_cases (fun h => (hm a h).le) fun h => le_of_lt <| by simpa using (hn h a).not
    le_of_pred_lt := fun {a b} hab =>
      by_cases (fun h => hm a h ▸ hab.le) fun h => by simpa [hab] using (hn h b).not
    min_of_le_pred := fun {a} => not_imp_not.mp fun h => by 

Proof state:
α✝ : Type u_1
β : Type u_2
inst✝¹ : LinearOrder α✝
α : Type ?u.4763
inst✝ : LinearOrder α
pred : α → α
hn : ∀ {a : α}, ¬IsMin a → ∀ (b : α), b ≤ pred a ↔ b < a
hm : ∀ (a : α), IsMin a → pred a = a
a : α
h : ¬IsMin a
⊢ ¬a ≤ pred a

Next tactic:
simpa using (hn h a).not
/-- A constructor for `PredOrder α` for `α` a linear order. -/
@[simps]
def PredOrder.ofCore {α} [LinearOrder α] (pred : α → α)
    (hn : ∀ {a}, ¬IsMin a → ∀ b, b ≤ pred a ↔ b < a) (hm : ∀ a, IsMin a → pred a = a) :
    PredOrder α :=
  { pred
    le_pred_of_lt := fun {a b} =>
      by_cases (fun h hab => (hm b h).symm ▸ hab.le) fun h => (hn h a).mpr
    pred_le := fun a =>
      by_cases (fun h => (hm a h).le) fun h => le_of_lt <| by simpa using (hn h a).not
    le_of_pred_lt := fun {a b} hab =>
      by_cases (fun h => hm a h ▸ hab.le) fun h => by 

Proof state:
α✝ : Type u_1
β : Type u_2
inst✝¹ : LinearOrder α✝
α : Type ?u.4763
inst✝ : LinearOrder α
pred : α → α
hn : ∀ {a : α}, ¬IsMin a → ∀ (b : α), b ≤ pred a ↔ b < a
hm : ∀ (a : α), IsMin a → pred a = a
a b : α
hab : pred a < b
h : ¬IsMin a
⊢ a ≤ b

Next tactic:
simpa [hab] using (hn h b).not
theorem succ_lt_succ_iff_of_not_isMax (ha : ¬IsMax a) (hb : ¬IsMax b) :
    succ a < succ b ↔ a < b := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : SuccOrder α
a b : α
ha : ¬IsMax a
hb : ¬IsMax b
⊢ succ a < succ b ↔ a < b

Next tactic:
rw [lt_succ_iff_of_not_isMax hb, succ_le_iff_of_not_isMax ha]
theorem succ_le_succ_iff_of_not_isMax (ha : ¬IsMax a) (hb : ¬IsMax b) :
    succ a ≤ succ b ↔ a ≤ b := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : SuccOrder α
a b : α
ha : ¬IsMax a
hb : ¬IsMax b
⊢ succ a ≤ succ b ↔ a ≤ b

Next tactic:
rw [succ_le_iff_of_not_isMax ha, lt_succ_iff_of_not_isMax hb]
@[simp, mono]
theorem succ_le_succ (h : a ≤ b) : succ a ≤ succ b := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : SuccOrder α
a b : α
h : a ≤ b
⊢ succ a ≤ succ b

Next tactic:
by_cases hb : IsMax b
@[simp, mono]
theorem succ_le_succ (h : a ≤ b) : succ a ≤ succ b := by
  by_cases hb : IsMax b
  · 

Proof state:
case pos
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : SuccOrder α
a b : α
h : a ≤ b
hb : IsMax b
⊢ succ a ≤ succ b

Next tactic:
by_cases hba : b ≤ a
@[simp, mono]
theorem succ_le_succ (h : a ≤ b) : succ a ≤ succ b := by
  by_cases hb : IsMax b
  · by_cases hba : b ≤ a
    · 

Proof state:
case pos
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : SuccOrder α
a b : α
h : a ≤ b
hb : IsMax b
hba : b ≤ a
⊢ succ a ≤ succ b

Next tactic:
exact (hb <| hba.trans <| le_succ _).trans (le_succ _)
@[simp, mono]
theorem succ_le_succ (h : a ≤ b) : succ a ≤ succ b := by
  by_cases hb : IsMax b
  · by_cases hba : b ≤ a
    · exact (hb <| hba.trans <| le_succ _).trans (le_succ _)
    · 

Proof state:
case neg
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : SuccOrder α
a b : α
h : a ≤ b
hb : IsMax b
hba : ¬b ≤ a
⊢ succ a ≤ succ b

Next tactic:
exact succ_le_of_lt ((h.lt_of_not_le hba).trans_le <| le_succ b)
@[simp, mono]
theorem succ_le_succ (h : a ≤ b) : succ a ≤ succ b := by
  by_cases hb : IsMax b
  · by_cases hba : b ≤ a
    · exact (hb <| hba.trans <| le_succ _).trans (le_succ _)
    · exact succ_le_of_lt ((h.lt_of_not_le hba).trans_le <| le_succ b)
  · 

Proof state:
case neg
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : SuccOrder α
a b : α
h : a ≤ b
hb : ¬IsMax b
⊢ succ a ≤ succ b

Next tactic:
rwa [succ_le_iff_of_not_isMax fun ha => hb <| ha.mono h, lt_succ_iff_of_not_isMax hb]
theorem le_succ_iterate (k : ℕ) (x : α) : x ≤ succ^[k] x := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : SuccOrder α
a b : α
k : ℕ
x : α
⊢ x ≤ succ^[k] x

Next tactic:
conv_lhs => rw [(by simp only [Function.iterate_id, id.def] : x = id^[k] x)]
theorem le_succ_iterate (k : ℕ) (x : α) : x ≤ succ^[k] x := by
  conv_lhs => 

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : SuccOrder α
a b : α
k : ℕ
x : α
| x

Next tactic:
rw [(by simp only [Function.iterate_id, id.def] : x = id^[k] x)]
theorem le_succ_iterate (k : ℕ) (x : α) : x ≤ succ^[k] x := by
  conv_lhs => rw [(by 

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : SuccOrder α
a b : α
k : ℕ
x : α
⊢ x = id^[k] x

Next tactic:
simp only [Function.iterate_id, id.def]
theorem le_succ_iterate (k : ℕ) (x : α) : x ≤ succ^[k] x := by
  conv_lhs => rw [(by simp only [Function.iterate_id, id.def] : x = id^[k] x)]
  

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : SuccOrder α
a b : α
k : ℕ
x : α
⊢ id^[k] x ≤ succ^[k] x

Next tactic:
exact Monotone.le_iterate_of_le succ_mono le_succ k x
theorem isMax_iterate_succ_of_eq_of_lt {n m : ℕ} (h_eq : succ^[n] a = succ^[m] a)
    (h_lt : n < m) : IsMax (succ^[n] a) := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : SuccOrder α
a b : α
n m : ℕ
h_eq : succ^[n] a = succ^[m] a
h_lt : n < m
⊢ IsMax (succ^[n] a)

Next tactic:
refine' max_of_succ_le (le_trans _ h_eq.symm.le)
theorem isMax_iterate_succ_of_eq_of_lt {n m : ℕ} (h_eq : succ^[n] a = succ^[m] a)
    (h_lt : n < m) : IsMax (succ^[n] a) := by
  refine' max_of_succ_le (le_trans _ h_eq.symm.le)
  

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : SuccOrder α
a b : α
n m : ℕ
h_eq : succ^[n] a = succ^[m] a
h_lt : n < m
⊢ succ (succ^[n] a) ≤ succ^[m] a

Next tactic:
have : succ (succ^[n] a) = succ^[n + 1] a := by rw [Function.iterate_succ', comp]
theorem isMax_iterate_succ_of_eq_of_lt {n m : ℕ} (h_eq : succ^[n] a = succ^[m] a)
    (h_lt : n < m) : IsMax (succ^[n] a) := by
  refine' max_of_succ_le (le_trans _ h_eq.symm.le)
  have : succ (succ^[n] a) = succ^[n + 1] a := by 

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : SuccOrder α
a b : α
n m : ℕ
h_eq : succ^[n] a = succ^[m] a
h_lt : n < m
⊢ succ (succ^[n] a) = succ^[n + 1] a

Next tactic:
rw [Function.iterate_succ', comp]
theorem isMax_iterate_succ_of_eq_of_lt {n m : ℕ} (h_eq : succ^[n] a = succ^[m] a)
    (h_lt : n < m) : IsMax (succ^[n] a) := by
  refine' max_of_succ_le (le_trans _ h_eq.symm.le)
  have : succ (succ^[n] a) = succ^[n + 1] a := by rw [Function.iterate_succ', comp]
  

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : SuccOrder α
a b : α
n m : ℕ
h_eq : succ^[n] a = succ^[m] a
h_lt : n < m
this : succ (succ^[n] a) = succ^[n + 1] a
⊢ succ (succ^[n] a) ≤ succ^[m] a

Next tactic:
rw [this]
theorem isMax_iterate_succ_of_eq_of_lt {n m : ℕ} (h_eq : succ^[n] a = succ^[m] a)
    (h_lt : n < m) : IsMax (succ^[n] a) := by
  refine' max_of_succ_le (le_trans _ h_eq.symm.le)
  have : succ (succ^[n] a) = succ^[n + 1] a := by rw [Function.iterate_succ', comp]
  rw [this]
  

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : SuccOrder α
a b : α
n m : ℕ
h_eq : succ^[n] a = succ^[m] a
h_lt : n < m
this : succ (succ^[n] a) = succ^[n + 1] a
⊢ succ^[n + 1] a ≤ succ^[m] a

Next tactic:
have h_le : n + 1 ≤ m := Nat.succ_le_of_lt h_lt