l3lab/ntp-mathlib huggingface dataset:
theorem index_of_argmax :
    ∀ {l : List α} {m : α}, m ∈ argmax f l → ∀ {a}, a ∈ l → f m ≤ f a → l.indexOf m ≤ l.indexOf a
  | [], m, _, _, _, _ => by simp
  | hd :: tl, m, hm, a, ha, ham => by
    simp only [indexOf_cons, argmax_cons, Option.mem_def] at hm ⊢
    cases h : argmax f tl
    · rw [h] at hm
      simp_all
    rw [h] at hm
    dsimp only at hm
    simp only [cond_eq_if, beq_iff_eq]
    obtain ha | ha := ha <;> split_ifs at hm <;> injection hm with hm <;> 

Proof state:
case pos
α : Type u_1
β : Type u_2
inst✝¹ : LinearOrder β
f : α → β
l : List α
o : Option α
a m✝ : α
inst✝ : DecidableEq α
hd : α
tl : List α
m val✝ : α
h : argmax f tl = some val✝
ham : f m ≤ f hd
h✝ : f hd < f val✝
hm : val✝ = m
⊢ (if hd = m then 0 else indexOf m tl + 1) ≤ if hd = hd then 0 else indexOf hd tl + 1

Next tactic:
subst hm
theorem index_of_argmax :
    ∀ {l : List α} {m : α}, m ∈ argmax f l → ∀ {a}, a ∈ l → f m ≤ f a → l.indexOf m ≤ l.indexOf a
  | [], m, _, _, _, _ => by simp
  | hd :: tl, m, hm, a, ha, ham => by
    simp only [indexOf_cons, argmax_cons, Option.mem_def] at hm ⊢
    cases h : argmax f tl
    · rw [h] at hm
      simp_all
    rw [h] at hm
    dsimp only at hm
    simp only [cond_eq_if, beq_iff_eq]
    obtain ha | ha := ha <;> split_ifs at hm <;> injection hm with hm <;> 

Proof state:
case neg
α : Type u_1
β : Type u_2
inst✝¹ : LinearOrder β
f : α → β
l : List α
o : Option α
a m✝ : α
inst✝ : DecidableEq α
hd : α
tl : List α
m val✝ : α
h : argmax f tl = some val✝
ham : f m ≤ f hd
h✝ : ¬f hd < f val✝
hm : hd = m
⊢ (if hd = m then 0 else indexOf m tl + 1) ≤ if hd = hd then 0 else indexOf hd tl + 1

Next tactic:
subst hm
theorem index_of_argmax :
    ∀ {l : List α} {m : α}, m ∈ argmax f l → ∀ {a}, a ∈ l → f m ≤ f a → l.indexOf m ≤ l.indexOf a
  | [], m, _, _, _, _ => by simp
  | hd :: tl, m, hm, a, ha, ham => by
    simp only [indexOf_cons, argmax_cons, Option.mem_def] at hm ⊢
    cases h : argmax f tl
    · rw [h] at hm
      simp_all
    rw [h] at hm
    dsimp only at hm
    simp only [cond_eq_if, beq_iff_eq]
    obtain ha | ha := ha <;> split_ifs at hm <;> injection hm with hm <;> 

Proof state:
case pos
α : Type u_1
β : Type u_2
inst✝¹ : LinearOrder β
f : α → β
l : List α
o : Option α
a✝¹ m✝ : α
inst✝ : DecidableEq α
hd : α
tl : List α
m a : α
ham : f m ≤ f a
val✝ : α
h : argmax f tl = some val✝
a✝ : Mem a tl
h✝ : f hd < f val✝
hm : val✝ = m
⊢ (if hd = m then 0 else indexOf m tl + 1) ≤ if hd = a then 0 else indexOf a tl + 1

Next tactic:
subst hm
theorem index_of_argmax :
    ∀ {l : List α} {m : α}, m ∈ argmax f l → ∀ {a}, a ∈ l → f m ≤ f a → l.indexOf m ≤ l.indexOf a
  | [], m, _, _, _, _ => by simp
  | hd :: tl, m, hm, a, ha, ham => by
    simp only [indexOf_cons, argmax_cons, Option.mem_def] at hm ⊢
    cases h : argmax f tl
    · rw [h] at hm
      simp_all
    rw [h] at hm
    dsimp only at hm
    simp only [cond_eq_if, beq_iff_eq]
    obtain ha | ha := ha <;> split_ifs at hm <;> injection hm with hm <;> 

Proof state:
case neg
α : Type u_1
β : Type u_2
inst✝¹ : LinearOrder β
f : α → β
l : List α
o : Option α
a✝¹ m✝ : α
inst✝ : DecidableEq α
hd : α
tl : List α
m a : α
ham : f m ≤ f a
val✝ : α
h : argmax f tl = some val✝
a✝ : Mem a tl
h✝ : ¬f hd < f val✝
hm : hd = m
⊢ (if hd = m then 0 else indexOf m tl + 1) ≤ if hd = a then 0 else indexOf a tl + 1

Next tactic:
subst hm
theorem index_of_argmax :
    ∀ {l : List α} {m : α}, m ∈ argmax f l → ∀ {a}, a ∈ l → f m ≤ f a → l.indexOf m ≤ l.indexOf a
  | [], m, _, _, _, _ => by simp
  | hd :: tl, m, hm, a, ha, ham => by
    simp only [indexOf_cons, argmax_cons, Option.mem_def] at hm ⊢
    cases h : argmax f tl
    · rw [h] at hm
      simp_all
    rw [h] at hm
    dsimp only at hm
    simp only [cond_eq_if, beq_iff_eq]
    obtain ha | ha := ha <;> split_ifs at hm <;> injection hm with hm <;> subst hm
    · 

Proof state:
case pos
α : Type u_1
β : Type u_2
inst✝¹ : LinearOrder β
f : α → β
l : List α
o : Option α
a m : α
inst✝ : DecidableEq α
hd : α
tl : List α
val✝ : α
h : argmax f tl = some val✝
h✝ : f hd < f val✝
ham : f val✝ ≤ f hd
⊢ (if hd = val✝ then 0 else indexOf val✝ tl + 1) ≤ if hd = hd then 0 else indexOf hd tl + 1

Next tactic:
cases not_le_of_lt ‹_› ‹_›
theorem index_of_argmax :
    ∀ {l : List α} {m : α}, m ∈ argmax f l → ∀ {a}, a ∈ l → f m ≤ f a → l.indexOf m ≤ l.indexOf a
  | [], m, _, _, _, _ => by simp
  | hd :: tl, m, hm, a, ha, ham => by
    simp only [indexOf_cons, argmax_cons, Option.mem_def] at hm ⊢
    cases h : argmax f tl
    · rw [h] at hm
      simp_all
    rw [h] at hm
    dsimp only at hm
    simp only [cond_eq_if, beq_iff_eq]
    obtain ha | ha := ha <;> split_ifs at hm <;> injection hm with hm <;> subst hm
    · cases not_le_of_lt ‹_› ‹_›
    · 

Proof state:
case neg
α : Type u_1
β : Type u_2
inst✝¹ : LinearOrder β
f : α → β
l : List α
o : Option α
a m : α
inst✝ : DecidableEq α
hd : α
tl : List α
val✝ : α
h : argmax f tl = some val✝
h✝ : ¬f hd < f val✝
ham : f hd ≤ f hd
⊢ (if hd = hd then 0 else indexOf hd tl + 1) ≤ if hd = hd then 0 else indexOf hd tl + 1

Next tactic:
rw [if_pos rfl]
theorem index_of_argmax :
    ∀ {l : List α} {m : α}, m ∈ argmax f l → ∀ {a}, a ∈ l → f m ≤ f a → l.indexOf m ≤ l.indexOf a
  | [], m, _, _, _, _ => by simp
  | hd :: tl, m, hm, a, ha, ham => by
    simp only [indexOf_cons, argmax_cons, Option.mem_def] at hm ⊢
    cases h : argmax f tl
    · rw [h] at hm
      simp_all
    rw [h] at hm
    dsimp only at hm
    simp only [cond_eq_if, beq_iff_eq]
    obtain ha | ha := ha <;> split_ifs at hm <;> injection hm with hm <;> subst hm
    · cases not_le_of_lt ‹_› ‹_›
    · rw [if_pos rfl]
    · 

Proof state:
case pos
α : Type u_1
β : Type u_2
inst✝¹ : LinearOrder β
f : α → β
l : List α
o : Option α
a✝¹ m : α
inst✝ : DecidableEq α
hd : α
tl : List α
a val✝ : α
h : argmax f tl = some val✝
a✝ : Mem a tl
h✝ : f hd < f val✝
ham : f val✝ ≤ f a
⊢ (if hd = val✝ then 0 else indexOf val✝ tl + 1) ≤ if hd = a then 0 else indexOf a tl + 1

Next tactic:
rw [if_neg, if_neg]
theorem index_of_argmax :
    ∀ {l : List α} {m : α}, m ∈ argmax f l → ∀ {a}, a ∈ l → f m ≤ f a → l.indexOf m ≤ l.indexOf a
  | [], m, _, _, _, _ => by simp
  | hd :: tl, m, hm, a, ha, ham => by
    simp only [indexOf_cons, argmax_cons, Option.mem_def] at hm ⊢
    cases h : argmax f tl
    · rw [h] at hm
      simp_all
    rw [h] at hm
    dsimp only at hm
    simp only [cond_eq_if, beq_iff_eq]
    obtain ha | ha := ha <;> split_ifs at hm <;> injection hm with hm <;> subst hm
    · cases not_le_of_lt ‹_› ‹_›
    · rw [if_pos rfl]
    · rw [if_neg, if_neg]
      

Proof state:
case pos
α : Type u_1
β : Type u_2
inst✝¹ : LinearOrder β
f : α → β
l : List α
o : Option α
a✝¹ m : α
inst✝ : DecidableEq α
hd : α
tl : List α
a val✝ : α
h : argmax f tl = some val✝
a✝ : Mem a tl
h✝ : f hd < f val✝
ham : f val✝ ≤ f a
⊢ indexOf val✝ tl + 1 ≤ indexOf a tl + 1
case pos.hnc
α : Type u_1
β : Type u_2
inst✝¹ : LinearOrder β
f : α → β
l : List α
o : Option α
a✝¹ m : α
inst✝ : DecidableEq α
hd : α
tl : List α
a val✝ : α
h : argmax f tl = some val✝
a✝ : Mem a tl
h✝ : f hd < f val✝
ham : f val✝ ≤ f a
⊢ ¬hd = a
case pos.hnc
α : Type u_1
β : Type u_2
inst✝¹ : LinearOrder β
f : α → β
l : List α
o : Option α
a✝¹ m : α
inst✝ : DecidableEq α
hd : α
tl : List α
a val✝ : α
h : argmax f tl = some val✝
a✝ : Mem a tl
h✝ : f hd < f val✝
ham : f val✝ ≤ f a
⊢ ¬hd = val✝

Next tactic:
exact Nat.succ_le_succ (index_of_argmax h (by assumption) ham)
theorem index_of_argmax :
    ∀ {l : List α} {m : α}, m ∈ argmax f l → ∀ {a}, a ∈ l → f m ≤ f a → l.indexOf m ≤ l.indexOf a
  | [], m, _, _, _, _ => by simp
  | hd :: tl, m, hm, a, ha, ham => by
    simp only [indexOf_cons, argmax_cons, Option.mem_def] at hm ⊢
    cases h : argmax f tl
    · rw [h] at hm
      simp_all
    rw [h] at hm
    dsimp only at hm
    simp only [cond_eq_if, beq_iff_eq]
    obtain ha | ha := ha <;> split_ifs at hm <;> injection hm with hm <;> subst hm
    · cases not_le_of_lt ‹_› ‹_›
    · rw [if_pos rfl]
    · rw [if_neg, if_neg]
      exact Nat.succ_le_succ (index_of_argmax h (by 

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : LinearOrder β
f : α → β
l : List α
o : Option α
a✝¹ m : α
inst✝ : DecidableEq α
hd : α
tl : List α
a val✝ : α
h : argmax f tl = some val✝
a✝ : Mem a tl
h✝ : f hd < f val✝
ham : f val✝ ≤ f a
⊢ a ∈ tl

Next tactic:
assumption
theorem index_of_argmax :
    ∀ {l : List α} {m : α}, m ∈ argmax f l → ∀ {a}, a ∈ l → f m ≤ f a → l.indexOf m ≤ l.indexOf a
  | [], m, _, _, _, _ => by simp
  | hd :: tl, m, hm, a, ha, ham => by
    simp only [indexOf_cons, argmax_cons, Option.mem_def] at hm ⊢
    cases h : argmax f tl
    · rw [h] at hm
      simp_all
    rw [h] at hm
    dsimp only at hm
    simp only [cond_eq_if, beq_iff_eq]
    obtain ha | ha := ha <;> split_ifs at hm <;> injection hm with hm <;> subst hm
    · cases not_le_of_lt ‹_› ‹_›
    · rw [if_pos rfl]
    · rw [if_neg, if_neg]
      exact Nat.succ_le_succ (index_of_argmax h (by assumption) ham)
      · 

Proof state:
case pos.hnc
α : Type u_1
β : Type u_2
inst✝¹ : LinearOrder β
f : α → β
l : List α
o : Option α
a✝¹ m : α
inst✝ : DecidableEq α
hd : α
tl : List α
a val✝ : α
h : argmax f tl = some val✝
a✝ : Mem a tl
h✝ : f hd < f val✝
ham : f val✝ ≤ f a
⊢ ¬hd = a

Next tactic:
exact ne_of_apply_ne f (lt_of_lt_of_le ‹_› ‹_›).ne
theorem index_of_argmax :
    ∀ {l : List α} {m : α}, m ∈ argmax f l → ∀ {a}, a ∈ l → f m ≤ f a → l.indexOf m ≤ l.indexOf a
  | [], m, _, _, _, _ => by simp
  | hd :: tl, m, hm, a, ha, ham => by
    simp only [indexOf_cons, argmax_cons, Option.mem_def] at hm ⊢
    cases h : argmax f tl
    · rw [h] at hm
      simp_all
    rw [h] at hm
    dsimp only at hm
    simp only [cond_eq_if, beq_iff_eq]
    obtain ha | ha := ha <;> split_ifs at hm <;> injection hm with hm <;> subst hm
    · cases not_le_of_lt ‹_› ‹_›
    · rw [if_pos rfl]
    · rw [if_neg, if_neg]
      exact Nat.succ_le_succ (index_of_argmax h (by assumption) ham)
      · exact ne_of_apply_ne f (lt_of_lt_of_le ‹_› ‹_›).ne
      · 

Proof state:
case pos.hnc
α : Type u_1
β : Type u_2
inst✝¹ : LinearOrder β
f : α → β
l : List α
o : Option α
a✝¹ m : α
inst✝ : DecidableEq α
hd : α
tl : List α
a val✝ : α
h : argmax f tl = some val✝
a✝ : Mem a tl
h✝ : f hd < f val✝
ham : f val✝ ≤ f a
⊢ ¬hd = val✝

Next tactic:
exact ne_of_apply_ne _ ‹f hd < f _›.ne
theorem index_of_argmax :
    ∀ {l : List α} {m : α}, m ∈ argmax f l → ∀ {a}, a ∈ l → f m ≤ f a → l.indexOf m ≤ l.indexOf a
  | [], m, _, _, _, _ => by simp
  | hd :: tl, m, hm, a, ha, ham => by
    simp only [indexOf_cons, argmax_cons, Option.mem_def] at hm ⊢
    cases h : argmax f tl
    · rw [h] at hm
      simp_all
    rw [h] at hm
    dsimp only at hm
    simp only [cond_eq_if, beq_iff_eq]
    obtain ha | ha := ha <;> split_ifs at hm <;> injection hm with hm <;> subst hm
    · cases not_le_of_lt ‹_› ‹_›
    · rw [if_pos rfl]
    · rw [if_neg, if_neg]
      exact Nat.succ_le_succ (index_of_argmax h (by assumption) ham)
      · exact ne_of_apply_ne f (lt_of_lt_of_le ‹_› ‹_›).ne
      · exact ne_of_apply_ne _ ‹f hd < f _›.ne
    · 

Proof state:
case neg
α : Type u_1
β : Type u_2
inst✝¹ : LinearOrder β
f : α → β
l : List α
o : Option α
a✝¹ m : α
inst✝ : DecidableEq α
hd : α
tl : List α
a val✝ : α
h : argmax f tl = some val✝
a✝ : Mem a tl
h✝ : ¬f hd < f val✝
ham : f hd ≤ f a
⊢ (if hd = hd then 0 else indexOf hd tl + 1) ≤ if hd = a then 0 else indexOf a tl + 1

Next tactic:
rw [if_pos rfl]
theorem index_of_argmax :
    ∀ {l : List α} {m : α}, m ∈ argmax f l → ∀ {a}, a ∈ l → f m ≤ f a → l.indexOf m ≤ l.indexOf a
  | [], m, _, _, _, _ => by simp
  | hd :: tl, m, hm, a, ha, ham => by
    simp only [indexOf_cons, argmax_cons, Option.mem_def] at hm ⊢
    cases h : argmax f tl
    · rw [h] at hm
      simp_all
    rw [h] at hm
    dsimp only at hm
    simp only [cond_eq_if, beq_iff_eq]
    obtain ha | ha := ha <;> split_ifs at hm <;> injection hm with hm <;> subst hm
    · cases not_le_of_lt ‹_› ‹_›
    · rw [if_pos rfl]
    · rw [if_neg, if_neg]
      exact Nat.succ_le_succ (index_of_argmax h (by assumption) ham)
      · exact ne_of_apply_ne f (lt_of_lt_of_le ‹_› ‹_›).ne
      · exact ne_of_apply_ne _ ‹f hd < f _›.ne
    · rw [if_pos rfl]
      

Proof state:
case neg
α : Type u_1
β : Type u_2
inst✝¹ : LinearOrder β
f : α → β
l : List α
o : Option α
a✝¹ m : α
inst✝ : DecidableEq α
hd : α
tl : List α
a val✝ : α
h : argmax f tl = some val✝
a✝ : Mem a tl
h✝ : ¬f hd < f val✝
ham : f hd ≤ f a
⊢ 0 ≤ if hd = a then 0 else indexOf a tl + 1

Next tactic:
exact Nat.zero_le _
theorem mem_argmax_iff :
    m ∈ argmax f l ↔
      m ∈ l ∧ (∀ a ∈ l, f a ≤ f m) ∧ ∀ a ∈ l, f m ≤ f a → l.indexOf m ≤ l.indexOf a :=
  ⟨fun hm => ⟨argmax_mem hm, fun a ha => le_of_mem_argmax ha hm, fun _ => index_of_argmax hm⟩,
    by
      

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : LinearOrder β
f : α → β
l : List α
o : Option α
a m : α
inst✝ : DecidableEq α
⊢ (m ∈ l ∧ (∀ (a : α), a ∈ l → f a ≤ f m) ∧ ∀ (a : α), a ∈ l → f m ≤ f a → indexOf m l ≤ indexOf a l) → m ∈ argmax f l

Next tactic:
rintro ⟨hml, ham, hma⟩
theorem mem_argmax_iff :
    m ∈ argmax f l ↔
      m ∈ l ∧ (∀ a ∈ l, f a ≤ f m) ∧ ∀ a ∈ l, f m ≤ f a → l.indexOf m ≤ l.indexOf a :=
  ⟨fun hm => ⟨argmax_mem hm, fun a ha => le_of_mem_argmax ha hm, fun _ => index_of_argmax hm⟩,
    by
      rintro ⟨hml, ham, hma⟩
      

Proof state:
case intro.intro
α : Type u_1
β : Type u_2
inst✝¹ : LinearOrder β
f : α → β
l : List α
o : Option α
a m : α
inst✝ : DecidableEq α
hml : m ∈ l
ham : ∀ (a : α), a ∈ l → f a ≤ f m
hma : ∀ (a : α), a ∈ l → f m ≤ f a → indexOf m l ≤ indexOf a l
⊢ m ∈ argmax f l

Next tactic:
cases' harg : argmax f l with n
theorem mem_argmax_iff :
    m ∈ argmax f l ↔
      m ∈ l ∧ (∀ a ∈ l, f a ≤ f m) ∧ ∀ a ∈ l, f m ≤ f a → l.indexOf m ≤ l.indexOf a :=
  ⟨fun hm => ⟨argmax_mem hm, fun a ha => le_of_mem_argmax ha hm, fun _ => index_of_argmax hm⟩,
    by
      rintro ⟨hml, ham, hma⟩
      cases' harg : argmax f l with n
      · 

Proof state:
case intro.intro.none
α : Type u_1
β : Type u_2
inst✝¹ : LinearOrder β
f : α → β
l : List α
o : Option α
a m : α
inst✝ : DecidableEq α
hml : m ∈ l
ham : ∀ (a : α), a ∈ l → f a ≤ f m
hma : ∀ (a : α), a ∈ l → f m ≤ f a → indexOf m l ≤ indexOf a l
harg : argmax f l = none
⊢ m ∈ none

Next tactic:
simp_all
theorem mem_argmax_iff :
    m ∈ argmax f l ↔
      m ∈ l ∧ (∀ a ∈ l, f a ≤ f m) ∧ ∀ a ∈ l, f m ≤ f a → l.indexOf m ≤ l.indexOf a :=
  ⟨fun hm => ⟨argmax_mem hm, fun a ha => le_of_mem_argmax ha hm, fun _ => index_of_argmax hm⟩,
    by
      rintro ⟨hml, ham, hma⟩
      cases' harg : argmax f l with n
      · simp_all
      · 

Proof state:
case intro.intro.some
α : Type u_1
β : Type u_2
inst✝¹ : LinearOrder β
f : α → β
l : List α
o : Option α
a m : α
inst✝ : DecidableEq α
hml : m ∈ l
ham : ∀ (a : α), a ∈ l → f a ≤ f m
hma : ∀ (a : α), a ∈ l → f m ≤ f a → indexOf m l ≤ indexOf a l
n : α
harg : argmax f l = some n
⊢ m ∈ some n

Next tactic:
have :=
          _root_.le_antisymm (hma n (argmax_mem harg) (le_of_mem_argmax hml harg))
            (index_of_argmax harg hml (ham _ (argmax_mem harg)))
theorem mem_argmax_iff :
    m ∈ argmax f l ↔
      m ∈ l ∧ (∀ a ∈ l, f a ≤ f m) ∧ ∀ a ∈ l, f m ≤ f a → l.indexOf m ≤ l.indexOf a :=
  ⟨fun hm => ⟨argmax_mem hm, fun a ha => le_of_mem_argmax ha hm, fun _ => index_of_argmax hm⟩,
    by
      rintro ⟨hml, ham, hma⟩
      cases' harg : argmax f l with n
      · simp_all
      · have :=
          _root_.le_antisymm (hma n (argmax_mem harg) (le_of_mem_argmax hml harg))
            (index_of_argmax harg hml (ham _ (argmax_mem harg)))
        

Proof state:
case intro.intro.some
α : Type u_1
β : Type u_2
inst✝¹ : LinearOrder β
f : α → β
l : List α
o : Option α
a m : α
inst✝ : DecidableEq α
hml : m ∈ l
ham : ∀ (a : α), a ∈ l → f a ≤ f m
hma : ∀ (a : α), a ∈ l → f m ≤ f a → indexOf m l ≤ indexOf a l
n : α
harg : argmax f l = some n
this : indexOf m l = indexOf n l
⊢ m ∈ some n

Next tactic:
rw [(indexOf_inj hml (argmax_mem harg)).1 this, Option.mem_def]
theorem not_lt_maximum_of_mem' (ha : a ∈ l) : ¬maximum l < (a : WithBot α) := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : DecidableRel fun x x_1 => x < x_1
l : List α
a m : α
ha : a ∈ l
⊢ ¬maximum l < ↑a

Next tactic:
cases h : l.maximum
theorem not_lt_maximum_of_mem' (ha : a ∈ l) : ¬maximum l < (a : WithBot α) := by
  cases h : l.maximum
  · 

Proof state:
case none
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : DecidableRel fun x x_1 => x < x_1
l : List α
a m : α
ha : a ∈ l
h : maximum l = none
⊢ ¬none < ↑a

Next tactic:
simp_all
theorem not_lt_maximum_of_mem' (ha : a ∈ l) : ¬maximum l < (a : WithBot α) := by
  cases h : l.maximum
  · simp_all
  · 

Proof state:
case some
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : DecidableRel fun x x_1 => x < x_1
l : List α
a m : α
ha : a ∈ l
val✝ : α
h : maximum l = some val✝
⊢ ¬some val✝ < ↑a

Next tactic:
simp [WithBot.some_eq_coe, WithBot.coe_lt_coe, not_lt_maximum_of_mem ha h, not_false_iff]
theorem maximum_concat (a : α) (l : List α) : maximum (l ++ [a]) = max (maximum l) a := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
l✝ : List α
a✝ m a : α
l : List α
⊢ maximum (l ++ [a]) = max (maximum l) ↑a

Next tactic:
simp only [maximum, argmax_concat, id]
theorem maximum_concat (a : α) (l : List α) : maximum (l ++ [a]) = max (maximum l) a := by
  simp only [maximum, argmax_concat, id]
  

Proof state:
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
l✝ : List α
a✝ m a : α
l : List α
⊢ Option.rec (some a) (fun val => if val < a then some a else some val) (argmax id l) = max (argmax id l) ↑a

Next tactic:
cases h : argmax id l
theorem maximum_concat (a : α) (l : List α) : maximum (l ++ [a]) = max (maximum l) a := by
  simp only [maximum, argmax_concat, id]
  cases h : argmax id l
  · 

Proof state:
case none
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
l✝ : List α
a✝ m a : α
l : List α
h : argmax id l = none
⊢ Option.rec (some a) (fun val => if val < a then some a else some val) none = max none ↑a

Next tactic:
exact (max_eq_right bot_le).symm
theorem maximum_concat (a : α) (l : List α) : maximum (l ++ [a]) = max (maximum l) a := by
  simp only [maximum, argmax_concat, id]
  cases h : argmax id l
  · exact (max_eq_right bot_le).symm
  · 

Proof state:
case some
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
l✝ : List α
a✝ m a : α
l : List α
val✝ : α
h : argmax id l = some val✝
⊢ Option.rec (some a) (fun val => if val < a then some a else some val) (some val✝) = max (some val✝) ↑a

Next tactic:
simp [WithBot.some_eq_coe, max_def_lt, WithBot.coe_lt_coe]
theorem maximum_cons (a : α) (l : List α) : maximum (a :: l) = max ↑a (maximum l) :=
  List.reverseRecOn l (by 

Proof state:
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
l✝ : List α
a✝ m a : α
l : List α
⊢ maximum [a] = max (↑a) (maximum [])

Next tactic:
simp [@max_eq_left (WithBot α) _ _ _ bot_le]
theorem maximum_cons (a : α) (l : List α) : maximum (a :: l) = max ↑a (maximum l) :=
  List.reverseRecOn l (by simp [@max_eq_left (WithBot α) _ _ _ bot_le]) fun tl hd ih => by
    

Proof state:
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
l✝ : List α
a✝ m a : α
l tl : List α
hd : α
ih : maximum (a :: tl) = max (↑a) (maximum tl)
⊢ maximum (a :: (tl ++ [hd])) = max (↑a) (maximum (tl ++ [hd]))

Next tactic:
rw [← cons_append, maximum_concat, ih, maximum_concat, max_assoc]
theorem maximum_le_of_forall_le {b : WithBot α} (h : ∀ a ∈ l, a ≤ b) : l.maximum ≤ b := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
l : List α
a m : α
b : WithBot α
h : ∀ (a : α), a ∈ l → ↑a ≤ b
⊢ maximum l ≤ b

Next tactic:
induction l with
  | nil => simp
  | cons a l ih =>
    simp only [maximum_cons, ge_iff_le, max_le_iff, WithBot.coe_le_coe]
    exact ⟨h a (by simp), ih fun a w => h a (mem_cons.mpr (Or.inr w))⟩
theorem maximum_le_of_forall_le {b : WithBot α} (h : ∀ a ∈ l, a ≤ b) : l.maximum ≤ b := by
  induction l with
  

Proof state:
case nil
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
l : List α
a m : α
b : WithBot α
h : ∀ (a : α), a ∈ [] → ↑a ≤ b
⊢ maximum [] ≤ b

Next tactic:
| nil => simp
theorem maximum_le_of_forall_le {b : WithBot α} (h : ∀ a ∈ l, a ≤ b) : l.maximum ≤ b := by
  induction l with
  | nil => 

Proof state:
case nil
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
l : List α
a m : α
b : WithBot α
h : ∀ (a : α), a ∈ [] → ↑a ≤ b
⊢ maximum [] ≤ b

Next tactic:
simp
theorem maximum_le_of_forall_le {b : WithBot α} (h : ∀ a ∈ l, a ≤ b) : l.maximum ≤ b := by
  induction l with
  | nil => simp
  

Proof state:
case cons
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
l✝ : List α
a✝ m : α
b : WithBot α
a : α
l : List α
ih : (∀ (a : α), a ∈ l → ↑a ≤ b) → maximum l ≤ b
h : ∀ (a_1 : α), a_1 ∈ a :: l → ↑a_1 ≤ b
⊢ maximum (a :: l) ≤ b

Next tactic:
| cons a l ih =>
    simp only [maximum_cons, ge_iff_le, max_le_iff, WithBot.coe_le_coe]
    exact ⟨h a (by simp), ih fun a w => h a (mem_cons.mpr (Or.inr w))⟩
theorem maximum_le_of_forall_le {b : WithBot α} (h : ∀ a ∈ l, a ≤ b) : l.maximum ≤ b := by
  induction l with
  | nil => simp
  | cons a l ih =>
    

Proof state:
case cons
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
l✝ : List α
a✝ m : α
b : WithBot α
a : α
l : List α
ih : (∀ (a : α), a ∈ l → ↑a ≤ b) → maximum l ≤ b
h : ∀ (a_1 : α), a_1 ∈ a :: l → ↑a_1 ≤ b
⊢ maximum (a :: l) ≤ b

Next tactic:
simp only [maximum_cons, ge_iff_le, max_le_iff, WithBot.coe_le_coe]
theorem maximum_le_of_forall_le {b : WithBot α} (h : ∀ a ∈ l, a ≤ b) : l.maximum ≤ b := by
  induction l with
  | nil => simp
  | cons a l ih =>
    simp only [maximum_cons, ge_iff_le, max_le_iff, WithBot.coe_le_coe]
    

Proof state:
case cons
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
l✝ : List α
a✝ m : α
b : WithBot α
a : α
l : List α
ih : (∀ (a : α), a ∈ l → ↑a ≤ b) → maximum l ≤ b
h : ∀ (a_1 : α), a_1 ∈ a :: l → ↑a_1 ≤ b
⊢ ↑a ≤ b ∧ maximum l ≤ b

Next tactic:
exact ⟨h a (by simp), ih fun a w => h a (mem_cons.mpr (Or.inr w))⟩
theorem maximum_le_of_forall_le {b : WithBot α} (h : ∀ a ∈ l, a ≤ b) : l.maximum ≤ b := by
  induction l with
  | nil => simp
  | cons a l ih =>
    simp only [maximum_cons, ge_iff_le, max_le_iff, WithBot.coe_le_coe]
    exact ⟨h a (by 

Proof state:
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
l✝ : List α
a✝ m : α
b : WithBot α
a : α
l : List α
ih : (∀ (a : α), a ∈ l → ↑a ≤ b) → maximum l ≤ b
h : ∀ (a_1 : α), a_1 ∈ a :: l → ↑a_1 ≤ b
⊢ a ∈ a :: l

Next tactic:
simp
theorem maximum_eq_coe_iff : maximum l = m ↔ m ∈ l ∧ ∀ a ∈ l, a ≤ m := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
l : List α
a m : α
⊢ maximum l = ↑m ↔ m ∈ l ∧ ∀ (a : α), a ∈ l → a ≤ m

Next tactic:
rw [maximum, ← WithBot.some_eq_coe, argmax_eq_some_iff]
theorem maximum_eq_coe_iff : maximum l = m ↔ m ∈ l ∧ ∀ a ∈ l, a ≤ m := by
  rw [maximum, ← WithBot.some_eq_coe, argmax_eq_some_iff]
  

Proof state:
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
l : List α
a m : α
⊢ (m ∈ l ∧ (∀ (a : α), a ∈ l → id a ≤ id m) ∧ ∀ (a : α), a ∈ l → id m ≤ id a → indexOf m l ≤ indexOf a l) ↔
    m ∈ l ∧ ∀ (a : α), a ∈ l → a ≤ m

Next tactic:
simp only [id_eq, and_congr_right_iff, and_iff_left_iff_imp]
theorem maximum_eq_coe_iff : maximum l = m ↔ m ∈ l ∧ ∀ a ∈ l, a ≤ m := by
  rw [maximum, ← WithBot.some_eq_coe, argmax_eq_some_iff]
  simp only [id_eq, and_congr_right_iff, and_iff_left_iff_imp]
  

Proof state:
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
l : List α
a m : α
⊢ m ∈ l → (∀ (a : α), a ∈ l → a ≤ m) → ∀ (a : α), a ∈ l → m ≤ a → indexOf m l ≤ indexOf a l

Next tactic:
intro _ h a hal hma
theorem maximum_eq_coe_iff : maximum l = m ↔ m ∈ l ∧ ∀ a ∈ l, a ≤ m := by
  rw [maximum, ← WithBot.some_eq_coe, argmax_eq_some_iff]
  simp only [id_eq, and_congr_right_iff, and_iff_left_iff_imp]
  intro _ h a hal hma
  

Proof state:
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
l : List α
a✝¹ m : α
a✝ : m ∈ l
h : ∀ (a : α), a ∈ l → a ≤ m
a : α
hal : a ∈ l
hma : m ≤ a
⊢ indexOf m l ≤ indexOf a l

Next tactic:
rw [_root_.le_antisymm hma (h a hal)]
theorem coe_le_maximum_iff : a ≤ l.maximum ↔ ∃ b, b ∈ l ∧ a ≤ b := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
l : List α
a m : α
⊢ ↑a ≤ maximum l ↔ ∃ b, b ∈ l ∧ a ≤ b

Next tactic:
induction l with
  | nil => simp
  | cons h t ih =>
    simp [maximum_cons, ih]
theorem coe_le_maximum_iff : a ≤ l.maximum ↔ ∃ b, b ∈ l ∧ a ≤ b := by
  induction l with
  

Proof state:
case nil
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
l : List α
a m : α
⊢ ↑a ≤ maximum [] ↔ ∃ b, b ∈ [] ∧ a ≤ b

Next tactic:
| nil => simp