l3lab/ntp-mathlib huggingface dataset:
/-- Given a chain from `a` to `b`, and a predicate true at `b`, if `r x y → p y → p x` then
the predicate is true everywhere in the chain and at `a`.
That is, we can propagate the predicate up the chain.
-/
theorem Chain.induction (p : α → Prop) (l : List α) (h : Chain r a l)
    (hb : getLast (a :: l) (cons_ne_nil _ _) = b) (carries : ∀ ⦃x y : α⦄, r x y → p y → p x)
    (final : p b) : ∀ i ∈ a :: l, p i := by
  induction' l with _ _ l_ih generalizing a
  · cases hb
    simpa using final
  · rw [chain_cons] at h
    simp only [mem_cons]
    rintro _ (rfl | H)
    

Proof state:
case cons.inl
α : Type u
β : Type v
R r : α → α → Prop
l l₁ l₂ : List α
b : α
p : α → Prop
carries : ∀ ⦃x y : α⦄, r x y → p y → p x
final : p b
head✝ : α
tail✝ : List α
l_ih : ∀ {a : α}, Chain r a tail✝ → getLast (a :: tail✝) (_ : a :: tail✝ ≠ []) = b → ∀ (i : α), i ∈ a :: tail✝ → p i
i✝ : α
h : r i✝ head✝ ∧ Chain r head✝ tail✝
hb : getLast (i✝ :: head✝ :: tail✝) (_ : i✝ :: head✝ :: tail✝ ≠ []) = b
⊢ p i✝
case cons.inr
α : Type u
β : Type v
R r : α → α → Prop
l l₁ l₂ : List α
b : α
p : α → Prop
carries : ∀ ⦃x y : α⦄, r x y → p y → p x
final : p b
head✝ : α
tail✝ : List α
l_ih : ∀ {a : α}, Chain r a tail✝ → getLast (a :: tail✝) (_ : a :: tail✝ ≠ []) = b → ∀ (i : α), i ∈ a :: tail✝ → p i
a : α
h : r a head✝ ∧ Chain r head✝ tail✝
hb : getLast (a :: head✝ :: tail✝) (_ : a :: head✝ :: tail✝ ≠ []) = b
i✝ : α
H : i✝ = head✝ ∨ i✝ ∈ tail✝
⊢ p i✝

Next tactic:
apply carries h.1 (l_ih h.2 hb _ (mem_cons.2 (Or.inl rfl)))
/-- Given a chain from `a` to `b`, and a predicate true at `b`, if `r x y → p y → p x` then
the predicate is true everywhere in the chain and at `a`.
That is, we can propagate the predicate up the chain.
-/
theorem Chain.induction (p : α → Prop) (l : List α) (h : Chain r a l)
    (hb : getLast (a :: l) (cons_ne_nil _ _) = b) (carries : ∀ ⦃x y : α⦄, r x y → p y → p x)
    (final : p b) : ∀ i ∈ a :: l, p i := by
  induction' l with _ _ l_ih generalizing a
  · cases hb
    simpa using final
  · rw [chain_cons] at h
    simp only [mem_cons]
    rintro _ (rfl | H)
    apply carries h.1 (l_ih h.2 hb _ (mem_cons.2 (Or.inl rfl)))
    

Proof state:
case cons.inr
α : Type u
β : Type v
R r : α → α → Prop
l l₁ l₂ : List α
b : α
p : α → Prop
carries : ∀ ⦃x y : α⦄, r x y → p y → p x
final : p b
head✝ : α
tail✝ : List α
l_ih : ∀ {a : α}, Chain r a tail✝ → getLast (a :: tail✝) (_ : a :: tail✝ ≠ []) = b → ∀ (i : α), i ∈ a :: tail✝ → p i
a : α
h : r a head✝ ∧ Chain r head✝ tail✝
hb : getLast (a :: head✝ :: tail✝) (_ : a :: head✝ :: tail✝ ≠ []) = b
i✝ : α
H : i✝ = head✝ ∨ i✝ ∈ tail✝
⊢ p i✝

Next tactic:
apply l_ih h.2 hb _ (mem_cons.2 H)
theorem Chain'.cons_of_le [LinearOrder α] {a : α} {as m : List α}
    (ha : List.Chain' (· > ·) (a :: as)) (hm : List.Chain' (· > ·) m) (hmas : m ≤ as) :
    List.Chain' (· > ·) (a :: m) := by
  

Proof state:
α : Type u
β : Type v
R r : α → α → Prop
l l₁ l₂ : List α
a✝ b : α
inst✝ : LinearOrder α
a : α
as m : List α
ha : Chain' (fun x x_1 => x > x_1) (a :: as)
hm : Chain' (fun x x_1 => x > x_1) m
hmas : m ≤ as
⊢ Chain' (fun x x_1 => x > x_1) (a :: m)

Next tactic:
cases m with
  | nil => simp only [List.chain'_singleton]
  | cons b bs =>
    apply hm.cons
    cases as with
    | nil =>
      simp only [le_iff_lt_or_eq, or_false] at hmas
      exact (List.Lex.not_nil_right (·<·) _ hmas).elim
    | cons a' as =>
      rw [List.chain'_cons] at ha
      refine gt_of_gt_of_ge ha.1 ?_
      rw [le_iff_lt_or_eq] at hmas
      cases' hmas with hmas hmas
      · by_contra! hh
        rw [← not_le] at hmas
        apply hmas
        apply le_of_lt
        exact (List.lt_iff_lex_lt _ _).mp (List.lt.head _ _ hh)
      · simp only [List.cons.injEq] at hmas
        rw [ge_iff_le, le_iff_lt_or_eq]
        exact Or.inr hmas.1
theorem Chain'.cons_of_le [LinearOrder α] {a : α} {as m : List α}
    (ha : List.Chain' (· > ·) (a :: as)) (hm : List.Chain' (· > ·) m) (hmas : m ≤ as) :
    List.Chain' (· > ·) (a :: m) := by
  cases m with
  

Proof state:
case nil
α : Type u
β : Type v
R r : α → α → Prop
l l₁ l₂ : List α
a✝ b : α
inst✝ : LinearOrder α
a : α
as : List α
ha : Chain' (fun x x_1 => x > x_1) (a :: as)
hm : Chain' (fun x x_1 => x > x_1) []
hmas : [] ≤ as
⊢ Chain' (fun x x_1 => x > x_1) [a]

Next tactic:
| nil => simp only [List.chain'_singleton]
theorem Chain'.cons_of_le [LinearOrder α] {a : α} {as m : List α}
    (ha : List.Chain' (· > ·) (a :: as)) (hm : List.Chain' (· > ·) m) (hmas : m ≤ as) :
    List.Chain' (· > ·) (a :: m) := by
  cases m with
  | nil => 

Proof state:
case nil
α : Type u
β : Type v
R r : α → α → Prop
l l₁ l₂ : List α
a✝ b : α
inst✝ : LinearOrder α
a : α
as : List α
ha : Chain' (fun x x_1 => x > x_1) (a :: as)
hm : Chain' (fun x x_1 => x > x_1) []
hmas : [] ≤ as
⊢ Chain' (fun x x_1 => x > x_1) [a]

Next tactic:
simp only [List.chain'_singleton]
theorem Chain'.cons_of_le [LinearOrder α] {a : α} {as m : List α}
    (ha : List.Chain' (· > ·) (a :: as)) (hm : List.Chain' (· > ·) m) (hmas : m ≤ as) :
    List.Chain' (· > ·) (a :: m) := by
  cases m with
  | nil => simp only [List.chain'_singleton]
  

Proof state:
case cons
α : Type u
β : Type v
R r : α → α → Prop
l l₁ l₂ : List α
a✝ b✝ : α
inst✝ : LinearOrder α
a : α
as : List α
ha : Chain' (fun x x_1 => x > x_1) (a :: as)
b : α
bs : List α
hm : Chain' (fun x x_1 => x > x_1) (b :: bs)
hmas : b :: bs ≤ as
⊢ Chain' (fun x x_1 => x > x_1) (a :: b :: bs)

Next tactic:
| cons b bs =>
    apply hm.cons
    cases as with
    | nil =>
      simp only [le_iff_lt_or_eq, or_false] at hmas
      exact (List.Lex.not_nil_right (·<·) _ hmas).elim
    | cons a' as =>
      rw [List.chain'_cons] at ha
      refine gt_of_gt_of_ge ha.1 ?_
      rw [le_iff_lt_or_eq] at hmas
      cases' hmas with hmas hmas
      · by_contra! hh
        rw [← not_le] at hmas
        apply hmas
        apply le_of_lt
        exact (List.lt_iff_lex_lt _ _).mp (List.lt.head _ _ hh)
      · simp only [List.cons.injEq] at hmas
        rw [ge_iff_le, le_iff_lt_or_eq]
        exact Or.inr hmas.1
theorem Chain'.cons_of_le [LinearOrder α] {a : α} {as m : List α}
    (ha : List.Chain' (· > ·) (a :: as)) (hm : List.Chain' (· > ·) m) (hmas : m ≤ as) :
    List.Chain' (· > ·) (a :: m) := by
  cases m with
  | nil => simp only [List.chain'_singleton]
  | cons b bs =>
    

Proof state:
case cons
α : Type u
β : Type v
R r : α → α → Prop
l l₁ l₂ : List α
a✝ b✝ : α
inst✝ : LinearOrder α
a : α
as : List α
ha : Chain' (fun x x_1 => x > x_1) (a :: as)
b : α
bs : List α
hm : Chain' (fun x x_1 => x > x_1) (b :: bs)
hmas : b :: bs ≤ as
⊢ Chain' (fun x x_1 => x > x_1) (a :: b :: bs)

Next tactic:
apply hm.cons
theorem Chain'.cons_of_le [LinearOrder α] {a : α} {as m : List α}
    (ha : List.Chain' (· > ·) (a :: as)) (hm : List.Chain' (· > ·) m) (hmas : m ≤ as) :
    List.Chain' (· > ·) (a :: m) := by
  cases m with
  | nil => simp only [List.chain'_singleton]
  | cons b bs =>
    apply hm.cons
    

Proof state:
case cons
α : Type u
β : Type v
R r : α → α → Prop
l l₁ l₂ : List α
a✝ b✝ : α
inst✝ : LinearOrder α
a : α
as : List α
ha : Chain' (fun x x_1 => x > x_1) (a :: as)
b : α
bs : List α
hm : Chain' (fun x x_1 => x > x_1) (b :: bs)
hmas : b :: bs ≤ as
⊢ a > b

Next tactic:
cases as with
    | nil =>
      simp only [le_iff_lt_or_eq, or_false] at hmas
      exact (List.Lex.not_nil_right (·<·) _ hmas).elim
    | cons a' as =>
      rw [List.chain'_cons] at ha
      refine gt_of_gt_of_ge ha.1 ?_
      rw [le_iff_lt_or_eq] at hmas
      cases' hmas with hmas hmas
      · by_contra! hh
        rw [← not_le] at hmas
        apply hmas
        apply le_of_lt
        exact (List.lt_iff_lex_lt _ _).mp (List.lt.head _ _ hh)
      · simp only [List.cons.injEq] at hmas
        rw [ge_iff_le, le_iff_lt_or_eq]
        exact Or.inr hmas.1
theorem Chain'.cons_of_le [LinearOrder α] {a : α} {as m : List α}
    (ha : List.Chain' (· > ·) (a :: as)) (hm : List.Chain' (· > ·) m) (hmas : m ≤ as) :
    List.Chain' (· > ·) (a :: m) := by
  cases m with
  | nil => simp only [List.chain'_singleton]
  | cons b bs =>
    apply hm.cons
    cases as with
    

Proof state:
case cons.nil
α : Type u
β : Type v
R r : α → α → Prop
l l₁ l₂ : List α
a✝ b✝ : α
inst✝ : LinearOrder α
a b : α
bs : List α
hm : Chain' (fun x x_1 => x > x_1) (b :: bs)
ha : Chain' (fun x x_1 => x > x_1) [a]
hmas : b :: bs ≤ []
⊢ a > b

Next tactic:
| nil =>
      simp only [le_iff_lt_or_eq, or_false] at hmas
      exact (List.Lex.not_nil_right (·<·) _ hmas).elim
theorem Chain'.cons_of_le [LinearOrder α] {a : α} {as m : List α}
    (ha : List.Chain' (· > ·) (a :: as)) (hm : List.Chain' (· > ·) m) (hmas : m ≤ as) :
    List.Chain' (· > ·) (a :: m) := by
  cases m with
  | nil => simp only [List.chain'_singleton]
  | cons b bs =>
    apply hm.cons
    cases as with
    | nil =>
      

Proof state:
case cons.nil
α : Type u
β : Type v
R r : α → α → Prop
l l₁ l₂ : List α
a✝ b✝ : α
inst✝ : LinearOrder α
a b : α
bs : List α
hm : Chain' (fun x x_1 => x > x_1) (b :: bs)
ha : Chain' (fun x x_1 => x > x_1) [a]
hmas : b :: bs ≤ []
⊢ a > b

Next tactic:
simp only [le_iff_lt_or_eq, or_false] at hmas
theorem Chain'.cons_of_le [LinearOrder α] {a : α} {as m : List α}
    (ha : List.Chain' (· > ·) (a :: as)) (hm : List.Chain' (· > ·) m) (hmas : m ≤ as) :
    List.Chain' (· > ·) (a :: m) := by
  cases m with
  | nil => simp only [List.chain'_singleton]
  | cons b bs =>
    apply hm.cons
    cases as with
    | nil =>
      simp only [le_iff_lt_or_eq, or_false] at hmas
      

Proof state:
case cons.nil
α : Type u
β : Type v
R r : α → α → Prop
l l₁ l₂ : List α
a✝ b✝ : α
inst✝ : LinearOrder α
a b : α
bs : List α
hm : Chain' (fun x x_1 => x > x_1) (b :: bs)
ha : Chain' (fun x x_1 => x > x_1) [a]
hmas : b :: bs < []
⊢ a > b

Next tactic:
exact (List.Lex.not_nil_right (·<·) _ hmas).elim
theorem Chain'.cons_of_le [LinearOrder α] {a : α} {as m : List α}
    (ha : List.Chain' (· > ·) (a :: as)) (hm : List.Chain' (· > ·) m) (hmas : m ≤ as) :
    List.Chain' (· > ·) (a :: m) := by
  cases m with
  | nil => simp only [List.chain'_singleton]
  | cons b bs =>
    apply hm.cons
    cases as with
    | nil =>
      simp only [le_iff_lt_or_eq, or_false] at hmas
      exact (List.Lex.not_nil_right (·<·) _ hmas).elim
    

Proof state:
case cons.cons
α : Type u
β : Type v
R r : α → α → Prop
l l₁ l₂ : List α
a✝ b✝ : α
inst✝ : LinearOrder α
a b : α
bs : List α
hm : Chain' (fun x x_1 => x > x_1) (b :: bs)
a' : α
as : List α
ha : Chain' (fun x x_1 => x > x_1) (a :: a' :: as)
hmas : b :: bs ≤ a' :: as
⊢ a > b

Next tactic:
| cons a' as =>
      rw [List.chain'_cons] at ha
      refine gt_of_gt_of_ge ha.1 ?_
      rw [le_iff_lt_or_eq] at hmas
      cases' hmas with hmas hmas
      · by_contra! hh
        rw [← not_le] at hmas
        apply hmas
        apply le_of_lt
        exact (List.lt_iff_lex_lt _ _).mp (List.lt.head _ _ hh)
      · simp only [List.cons.injEq] at hmas
        rw [ge_iff_le, le_iff_lt_or_eq]
        exact Or.inr hmas.1
theorem Chain'.cons_of_le [LinearOrder α] {a : α} {as m : List α}
    (ha : List.Chain' (· > ·) (a :: as)) (hm : List.Chain' (· > ·) m) (hmas : m ≤ as) :
    List.Chain' (· > ·) (a :: m) := by
  cases m with
  | nil => simp only [List.chain'_singleton]
  | cons b bs =>
    apply hm.cons
    cases as with
    | nil =>
      simp only [le_iff_lt_or_eq, or_false] at hmas
      exact (List.Lex.not_nil_right (·<·) _ hmas).elim
    | cons a' as =>
      

Proof state:
case cons.cons
α : Type u
β : Type v
R r : α → α → Prop
l l₁ l₂ : List α
a✝ b✝ : α
inst✝ : LinearOrder α
a b : α
bs : List α
hm : Chain' (fun x x_1 => x > x_1) (b :: bs)
a' : α
as : List α
ha : Chain' (fun x x_1 => x > x_1) (a :: a' :: as)
hmas : b :: bs ≤ a' :: as
⊢ a > b

Next tactic:
rw [List.chain'_cons] at ha
theorem Chain'.cons_of_le [LinearOrder α] {a : α} {as m : List α}
    (ha : List.Chain' (· > ·) (a :: as)) (hm : List.Chain' (· > ·) m) (hmas : m ≤ as) :
    List.Chain' (· > ·) (a :: m) := by
  cases m with
  | nil => simp only [List.chain'_singleton]
  | cons b bs =>
    apply hm.cons
    cases as with
    | nil =>
      simp only [le_iff_lt_or_eq, or_false] at hmas
      exact (List.Lex.not_nil_right (·<·) _ hmas).elim
    | cons a' as =>
      rw [List.chain'_cons] at ha
      

Proof state:
case cons.cons
α : Type u
β : Type v
R r : α → α → Prop
l l₁ l₂ : List α
a✝ b✝ : α
inst✝ : LinearOrder α
a b : α
bs : List α
hm : Chain' (fun x x_1 => x > x_1) (b :: bs)
a' : α
as : List α
ha : a > a' ∧ Chain' (fun x x_1 => x > x_1) (a' :: as)
hmas : b :: bs ≤ a' :: as
⊢ a > b

Next tactic:
refine gt_of_gt_of_ge ha.1 ?_
theorem Chain'.cons_of_le [LinearOrder α] {a : α} {as m : List α}
    (ha : List.Chain' (· > ·) (a :: as)) (hm : List.Chain' (· > ·) m) (hmas : m ≤ as) :
    List.Chain' (· > ·) (a :: m) := by
  cases m with
  | nil => simp only [List.chain'_singleton]
  | cons b bs =>
    apply hm.cons
    cases as with
    | nil =>
      simp only [le_iff_lt_or_eq, or_false] at hmas
      exact (List.Lex.not_nil_right (·<·) _ hmas).elim
    | cons a' as =>
      rw [List.chain'_cons] at ha
      refine gt_of_gt_of_ge ha.1 ?_
      

Proof state:
case cons.cons
α : Type u
β : Type v
R r : α → α → Prop
l l₁ l₂ : List α
a✝ b✝ : α
inst✝ : LinearOrder α
a b : α
bs : List α
hm : Chain' (fun x x_1 => x > x_1) (b :: bs)
a' : α
as : List α
ha : a > a' ∧ Chain' (fun x x_1 => x > x_1) (a' :: as)
hmas : b :: bs ≤ a' :: as
⊢ a' ≥ b

Next tactic:
rw [le_iff_lt_or_eq] at hmas
theorem Chain'.cons_of_le [LinearOrder α] {a : α} {as m : List α}
    (ha : List.Chain' (· > ·) (a :: as)) (hm : List.Chain' (· > ·) m) (hmas : m ≤ as) :
    List.Chain' (· > ·) (a :: m) := by
  cases m with
  | nil => simp only [List.chain'_singleton]
  | cons b bs =>
    apply hm.cons
    cases as with
    | nil =>
      simp only [le_iff_lt_or_eq, or_false] at hmas
      exact (List.Lex.not_nil_right (·<·) _ hmas).elim
    | cons a' as =>
      rw [List.chain'_cons] at ha
      refine gt_of_gt_of_ge ha.1 ?_
      rw [le_iff_lt_or_eq] at hmas
      

Proof state:
case cons.cons
α : Type u
β : Type v
R r : α → α → Prop
l l₁ l₂ : List α
a✝ b✝ : α
inst✝ : LinearOrder α
a b : α
bs : List α
hm : Chain' (fun x x_1 => x > x_1) (b :: bs)
a' : α
as : List α
ha : a > a' ∧ Chain' (fun x x_1 => x > x_1) (a' :: as)
hmas : b :: bs < a' :: as ∨ b :: bs = a' :: as
⊢ a' ≥ b

Next tactic:
cases' hmas with hmas hmas
theorem Chain'.cons_of_le [LinearOrder α] {a : α} {as m : List α}
    (ha : List.Chain' (· > ·) (a :: as)) (hm : List.Chain' (· > ·) m) (hmas : m ≤ as) :
    List.Chain' (· > ·) (a :: m) := by
  cases m with
  | nil => simp only [List.chain'_singleton]
  | cons b bs =>
    apply hm.cons
    cases as with
    | nil =>
      simp only [le_iff_lt_or_eq, or_false] at hmas
      exact (List.Lex.not_nil_right (·<·) _ hmas).elim
    | cons a' as =>
      rw [List.chain'_cons] at ha
      refine gt_of_gt_of_ge ha.1 ?_
      rw [le_iff_lt_or_eq] at hmas
      cases' hmas with hmas hmas
      · 

Proof state:
case cons.cons.inl
α : Type u
β : Type v
R r : α → α → Prop
l l₁ l₂ : List α
a✝ b✝ : α
inst✝ : LinearOrder α
a b : α
bs : List α
hm : Chain' (fun x x_1 => x > x_1) (b :: bs)
a' : α
as : List α
ha : a > a' ∧ Chain' (fun x x_1 => x > x_1) (a' :: as)
hmas : b :: bs < a' :: as
⊢ a' ≥ b

Next tactic:
by_contra! hh
theorem Chain'.cons_of_le [LinearOrder α] {a : α} {as m : List α}
    (ha : List.Chain' (· > ·) (a :: as)) (hm : List.Chain' (· > ·) m) (hmas : m ≤ as) :
    List.Chain' (· > ·) (a :: m) := by
  cases m with
  | nil => simp only [List.chain'_singleton]
  | cons b bs =>
    apply hm.cons
    cases as with
    | nil =>
      simp only [le_iff_lt_or_eq, or_false] at hmas
      exact (List.Lex.not_nil_right (·<·) _ hmas).elim
    | cons a' as =>
      rw [List.chain'_cons] at ha
      refine gt_of_gt_of_ge ha.1 ?_
      rw [le_iff_lt_or_eq] at hmas
      cases' hmas with hmas hmas
      · by_contra! hh
        

Proof state:
case cons.cons.inl
α : Type u
β : Type v
R r : α → α → Prop
l l₁ l₂ : List α
a✝ b✝ : α
inst✝ : LinearOrder α
a b : α
bs : List α
hm : Chain' (fun x x_1 => x > x_1) (b :: bs)
a' : α
as : List α
ha : a > a' ∧ Chain' (fun x x_1 => x > x_1) (a' :: as)
hmas : b :: bs < a' :: as
hh : a' < b
⊢ False

Next tactic:
rw [← not_le] at hmas
theorem Chain'.cons_of_le [LinearOrder α] {a : α} {as m : List α}
    (ha : List.Chain' (· > ·) (a :: as)) (hm : List.Chain' (· > ·) m) (hmas : m ≤ as) :
    List.Chain' (· > ·) (a :: m) := by
  cases m with
  | nil => simp only [List.chain'_singleton]
  | cons b bs =>
    apply hm.cons
    cases as with
    | nil =>
      simp only [le_iff_lt_or_eq, or_false] at hmas
      exact (List.Lex.not_nil_right (·<·) _ hmas).elim
    | cons a' as =>
      rw [List.chain'_cons] at ha
      refine gt_of_gt_of_ge ha.1 ?_
      rw [le_iff_lt_or_eq] at hmas
      cases' hmas with hmas hmas
      · by_contra! hh
        rw [← not_le] at hmas
        

Proof state:
case cons.cons.inl
α : Type u
β : Type v
R r : α → α → Prop
l l₁ l₂ : List α
a✝ b✝ : α
inst✝ : LinearOrder α
a b : α
bs : List α
hm : Chain' (fun x x_1 => x > x_1) (b :: bs)
a' : α
as : List α
ha : a > a' ∧ Chain' (fun x x_1 => x > x_1) (a' :: as)
hmas : ¬a' :: as ≤ b :: bs
hh : a' < b
⊢ False

Next tactic:
apply hmas
theorem Chain'.cons_of_le [LinearOrder α] {a : α} {as m : List α}
    (ha : List.Chain' (· > ·) (a :: as)) (hm : List.Chain' (· > ·) m) (hmas : m ≤ as) :
    List.Chain' (· > ·) (a :: m) := by
  cases m with
  | nil => simp only [List.chain'_singleton]
  | cons b bs =>
    apply hm.cons
    cases as with
    | nil =>
      simp only [le_iff_lt_or_eq, or_false] at hmas
      exact (List.Lex.not_nil_right (·<·) _ hmas).elim
    | cons a' as =>
      rw [List.chain'_cons] at ha
      refine gt_of_gt_of_ge ha.1 ?_
      rw [le_iff_lt_or_eq] at hmas
      cases' hmas with hmas hmas
      · by_contra! hh
        rw [← not_le] at hmas
        apply hmas
        

Proof state:
case cons.cons.inl
α : Type u
β : Type v
R r : α → α → Prop
l l₁ l₂ : List α
a✝ b✝ : α
inst✝ : LinearOrder α
a b : α
bs : List α
hm : Chain' (fun x x_1 => x > x_1) (b :: bs)
a' : α
as : List α
ha : a > a' ∧ Chain' (fun x x_1 => x > x_1) (a' :: as)
hmas : ¬a' :: as ≤ b :: bs
hh : a' < b
⊢ a' :: as ≤ b :: bs

Next tactic:
apply le_of_lt
theorem Chain'.cons_of_le [LinearOrder α] {a : α} {as m : List α}
    (ha : List.Chain' (· > ·) (a :: as)) (hm : List.Chain' (· > ·) m) (hmas : m ≤ as) :
    List.Chain' (· > ·) (a :: m) := by
  cases m with
  | nil => simp only [List.chain'_singleton]
  | cons b bs =>
    apply hm.cons
    cases as with
    | nil =>
      simp only [le_iff_lt_or_eq, or_false] at hmas
      exact (List.Lex.not_nil_right (·<·) _ hmas).elim
    | cons a' as =>
      rw [List.chain'_cons] at ha
      refine gt_of_gt_of_ge ha.1 ?_
      rw [le_iff_lt_or_eq] at hmas
      cases' hmas with hmas hmas
      · by_contra! hh
        rw [← not_le] at hmas
        apply hmas
        apply le_of_lt
        

Proof state:
case cons.cons.inl.a
α : Type u
β : Type v
R r : α → α → Prop
l l₁ l₂ : List α
a✝ b✝ : α
inst✝ : LinearOrder α
a b : α
bs : List α
hm : Chain' (fun x x_1 => x > x_1) (b :: bs)
a' : α
as : List α
ha : a > a' ∧ Chain' (fun x x_1 => x > x_1) (a' :: as)
hmas : ¬a' :: as ≤ b :: bs
hh : a' < b
⊢ a' :: as < b :: bs

Next tactic:
exact (List.lt_iff_lex_lt _ _).mp (List.lt.head _ _ hh)
theorem Chain'.cons_of_le [LinearOrder α] {a : α} {as m : List α}
    (ha : List.Chain' (· > ·) (a :: as)) (hm : List.Chain' (· > ·) m) (hmas : m ≤ as) :
    List.Chain' (· > ·) (a :: m) := by
  cases m with
  | nil => simp only [List.chain'_singleton]
  | cons b bs =>
    apply hm.cons
    cases as with
    | nil =>
      simp only [le_iff_lt_or_eq, or_false] at hmas
      exact (List.Lex.not_nil_right (·<·) _ hmas).elim
    | cons a' as =>
      rw [List.chain'_cons] at ha
      refine gt_of_gt_of_ge ha.1 ?_
      rw [le_iff_lt_or_eq] at hmas
      cases' hmas with hmas hmas
      · by_contra! hh
        rw [← not_le] at hmas
        apply hmas
        apply le_of_lt
        exact (List.lt_iff_lex_lt _ _).mp (List.lt.head _ _ hh)
      · 

Proof state:
case cons.cons.inr
α : Type u
β : Type v
R r : α → α → Prop
l l₁ l₂ : List α
a✝ b✝ : α
inst✝ : LinearOrder α
a b : α
bs : List α
hm : Chain' (fun x x_1 => x > x_1) (b :: bs)
a' : α
as : List α
ha : a > a' ∧ Chain' (fun x x_1 => x > x_1) (a' :: as)
hmas : b :: bs = a' :: as
⊢ a' ≥ b

Next tactic:
simp only [List.cons.injEq] at hmas
theorem Chain'.cons_of_le [LinearOrder α] {a : α} {as m : List α}
    (ha : List.Chain' (· > ·) (a :: as)) (hm : List.Chain' (· > ·) m) (hmas : m ≤ as) :
    List.Chain' (· > ·) (a :: m) := by
  cases m with
  | nil => simp only [List.chain'_singleton]
  | cons b bs =>
    apply hm.cons
    cases as with
    | nil =>
      simp only [le_iff_lt_or_eq, or_false] at hmas
      exact (List.Lex.not_nil_right (·<·) _ hmas).elim
    | cons a' as =>
      rw [List.chain'_cons] at ha
      refine gt_of_gt_of_ge ha.1 ?_
      rw [le_iff_lt_or_eq] at hmas
      cases' hmas with hmas hmas
      · by_contra! hh
        rw [← not_le] at hmas
        apply hmas
        apply le_of_lt
        exact (List.lt_iff_lex_lt _ _).mp (List.lt.head _ _ hh)
      · simp only [List.cons.injEq] at hmas
        

Proof state:
case cons.cons.inr
α : Type u
β : Type v
R r : α → α → Prop
l l₁ l₂ : List α
a✝ b✝ : α
inst✝ : LinearOrder α
a b : α
bs : List α
hm : Chain' (fun x x_1 => x > x_1) (b :: bs)
a' : α
as : List α
ha : a > a' ∧ Chain' (fun x x_1 => x > x_1) (a' :: as)
hmas : b = a' ∧ bs = as
⊢ a' ≥ b

Next tactic:
rw [ge_iff_le, le_iff_lt_or_eq]
theorem Chain'.cons_of_le [LinearOrder α] {a : α} {as m : List α}
    (ha : List.Chain' (· > ·) (a :: as)) (hm : List.Chain' (· > ·) m) (hmas : m ≤ as) :
    List.Chain' (· > ·) (a :: m) := by
  cases m with
  | nil => simp only [List.chain'_singleton]
  | cons b bs =>
    apply hm.cons
    cases as with
    | nil =>
      simp only [le_iff_lt_or_eq, or_false] at hmas
      exact (List.Lex.not_nil_right (·<·) _ hmas).elim
    | cons a' as =>
      rw [List.chain'_cons] at ha
      refine gt_of_gt_of_ge ha.1 ?_
      rw [le_iff_lt_or_eq] at hmas
      cases' hmas with hmas hmas
      · by_contra! hh
        rw [← not_le] at hmas
        apply hmas
        apply le_of_lt
        exact (List.lt_iff_lex_lt _ _).mp (List.lt.head _ _ hh)
      · simp only [List.cons.injEq] at hmas
        rw [ge_iff_le, le_iff_lt_or_eq]
        

Proof state:
case cons.cons.inr
α : Type u
β : Type v
R r : α → α → Prop
l l₁ l₂ : List α
a✝ b✝ : α
inst✝ : LinearOrder α
a b : α
bs : List α
hm : Chain' (fun x x_1 => x > x_1) (b :: bs)
a' : α
as : List α
ha : a > a' ∧ Chain' (fun x x_1 => x > x_1) (a' :: as)
hmas : b = a' ∧ bs = as
⊢ b < a' ∨ b = a'

Next tactic:
exact Or.inr hmas.1
/-- If an `r`-decreasing chain `l` is empty or its head is accessible by `r`, then
  `l` is accessible by the lexicographic order `List.Lex r`. -/
theorem Acc.list_chain' {l : List.chains r} (acc : ∀ a ∈ l.val.head?, Acc r a) :
    Acc (List.lex_chains r) l := by
  

Proof state:
α : Type u_1
r : α → α → Prop
l : List.chains r
acc : ∀ (a : α), a ∈ List.head? ↑l → Acc r a
⊢ Acc (List.lex_chains r) l

Next tactic:
obtain ⟨_ | ⟨a, l⟩, hl⟩ := l
/-- If an `r`-decreasing chain `l` is empty or its head is accessible by `r`, then
  `l` is accessible by the lexicographic order `List.Lex r`. -/
theorem Acc.list_chain' {l : List.chains r} (acc : ∀ a ∈ l.val.head?, Acc r a) :
    Acc (List.lex_chains r) l := by
  obtain ⟨_ | ⟨a, l⟩, hl⟩ := l
  · 

Proof state:
case mk.nil
α : Type u_1
r : α → α → Prop
hl : List.Chain' (flip r) []
acc : ∀ (a : α), a ∈ List.head? ↑{ val := [], property := hl } → Acc r a
⊢ Acc (List.lex_chains r) { val := [], property := hl }

Next tactic:
apply Acc.intro
/-- If an `r`-decreasing chain `l` is empty or its head is accessible by `r`, then
  `l` is accessible by the lexicographic order `List.Lex r`. -/
theorem Acc.list_chain' {l : List.chains r} (acc : ∀ a ∈ l.val.head?, Acc r a) :
    Acc (List.lex_chains r) l := by
  obtain ⟨_ | ⟨a, l⟩, hl⟩ := l
  · apply Acc.intro; 

Proof state:
case mk.nil.h
α : Type u_1
r : α → α → Prop
hl : List.Chain' (flip r) []
acc : ∀ (a : α), a ∈ List.head? ↑{ val := [], property := hl } → Acc r a
⊢ ∀ (y : List.chains r), List.lex_chains r y { val := [], property := hl } → Acc (List.lex_chains r) y

Next tactic:
rintro ⟨_⟩ ⟨_⟩