l3lab/ntp-mathlib huggingface dataset:
/-- If `find p` returns `some i`, then `p j` does not hold for `j < i`, i.e., `i` is minimal among
the indices where `p` holds. -/
theorem find_min :
    ∀ {n : ℕ} {p : Fin n → Prop} [DecidablePred p] {i : Fin n} (_ : i ∈ Fin.find p) {j : Fin n}
      (_ : j < i), ¬p j
  | 0, p, _, i, hi, _, _, _ => Option.noConfusion hi
  | n + 1, p, _, i, hi, ⟨j, hjn⟩, hj, hpj => by
    rw [find] at hi
    cases' h : find fun i : Fin n ↦ p (i.castLT (Nat.lt_succ_of_lt i.2)) with k
    · simp only [h] at hi
      split_ifs at hi with hl
      · 

Proof state:
case pos
m n✝ n : ℕ
p : Fin (n + 1) → Prop
x✝ : DecidablePred p
i : Fin (n + 1)
j : ℕ
hjn : j < n + 1
hj : { val := j, isLt := hjn } < i
hpj : p { val := j, isLt := hjn }
h : (find fun i => p (castLT i (_ : ↑i < Nat.succ n))) = none
hl : p (last n)
hi : i ∈ some (last n)
⊢ False

Next tactic:
cases hi
/-- If `find p` returns `some i`, then `p j` does not hold for `j < i`, i.e., `i` is minimal among
the indices where `p` holds. -/
theorem find_min :
    ∀ {n : ℕ} {p : Fin n → Prop} [DecidablePred p] {i : Fin n} (_ : i ∈ Fin.find p) {j : Fin n}
      (_ : j < i), ¬p j
  | 0, p, _, i, hi, _, _, _ => Option.noConfusion hi
  | n + 1, p, _, i, hi, ⟨j, hjn⟩, hj, hpj => by
    rw [find] at hi
    cases' h : find fun i : Fin n ↦ p (i.castLT (Nat.lt_succ_of_lt i.2)) with k
    · simp only [h] at hi
      split_ifs at hi with hl
      · cases hi
        

Proof state:
case pos.refl
m n✝ n : ℕ
p : Fin (n + 1) → Prop
x✝ : DecidablePred p
j : ℕ
hjn : j < n + 1
hpj : p { val := j, isLt := hjn }
h : (find fun i => p (castLT i (_ : ↑i < Nat.succ n))) = none
hl : p (last n)
hj : { val := j, isLt := hjn } < last n
⊢ False

Next tactic:
rw [find_eq_none_iff] at h
/-- If `find p` returns `some i`, then `p j` does not hold for `j < i`, i.e., `i` is minimal among
the indices where `p` holds. -/
theorem find_min :
    ∀ {n : ℕ} {p : Fin n → Prop} [DecidablePred p] {i : Fin n} (_ : i ∈ Fin.find p) {j : Fin n}
      (_ : j < i), ¬p j
  | 0, p, _, i, hi, _, _, _ => Option.noConfusion hi
  | n + 1, p, _, i, hi, ⟨j, hjn⟩, hj, hpj => by
    rw [find] at hi
    cases' h : find fun i : Fin n ↦ p (i.castLT (Nat.lt_succ_of_lt i.2)) with k
    · simp only [h] at hi
      split_ifs at hi with hl
      · cases hi
        rw [find_eq_none_iff] at h
        

Proof state:
case pos.refl
m n✝ n : ℕ
p : Fin (n + 1) → Prop
x✝ : DecidablePred p
j : ℕ
hjn : j < n + 1
hpj : p { val := j, isLt := hjn }
h : ∀ (i : Fin n), ¬p (castLT i (_ : ↑i < Nat.succ n))
hl : p (last n)
hj : { val := j, isLt := hjn } < last n
⊢ False

Next tactic:
refine h ⟨j, hj⟩ hpj
/-- If `find p` returns `some i`, then `p j` does not hold for `j < i`, i.e., `i` is minimal among
the indices where `p` holds. -/
theorem find_min :
    ∀ {n : ℕ} {p : Fin n → Prop} [DecidablePred p] {i : Fin n} (_ : i ∈ Fin.find p) {j : Fin n}
      (_ : j < i), ¬p j
  | 0, p, _, i, hi, _, _, _ => Option.noConfusion hi
  | n + 1, p, _, i, hi, ⟨j, hjn⟩, hj, hpj => by
    rw [find] at hi
    cases' h : find fun i : Fin n ↦ p (i.castLT (Nat.lt_succ_of_lt i.2)) with k
    · simp only [h] at hi
      split_ifs at hi with hl
      · cases hi
        rw [find_eq_none_iff] at h
        refine h ⟨j, hj⟩ hpj
      · 

Proof state:
case neg
m n✝ n : ℕ
p : Fin (n + 1) → Prop
x✝ : DecidablePred p
i : Fin (n + 1)
j : ℕ
hjn : j < n + 1
hj : { val := j, isLt := hjn } < i
hpj : p { val := j, isLt := hjn }
h : (find fun i => p (castLT i (_ : ↑i < Nat.succ n))) = none
hl : ¬p (last n)
hi : i ∈ none
⊢ False

Next tactic:
exact Option.not_mem_none _ hi
/-- If `find p` returns `some i`, then `p j` does not hold for `j < i`, i.e., `i` is minimal among
the indices where `p` holds. -/
theorem find_min :
    ∀ {n : ℕ} {p : Fin n → Prop} [DecidablePred p] {i : Fin n} (_ : i ∈ Fin.find p) {j : Fin n}
      (_ : j < i), ¬p j
  | 0, p, _, i, hi, _, _, _ => Option.noConfusion hi
  | n + 1, p, _, i, hi, ⟨j, hjn⟩, hj, hpj => by
    rw [find] at hi
    cases' h : find fun i : Fin n ↦ p (i.castLT (Nat.lt_succ_of_lt i.2)) with k
    · simp only [h] at hi
      split_ifs at hi with hl
      · cases hi
        rw [find_eq_none_iff] at h
        refine h ⟨j, hj⟩ hpj
      · exact Option.not_mem_none _ hi
    · 

Proof state:
case some
m n✝ n : ℕ
p : Fin (n + 1) → Prop
x✝ : DecidablePred p
i : Fin (n + 1)
hi :
  i ∈
    Option.casesOn (find fun i => p (castLT i (_ : ↑i < Nat.succ n))) (if x : p (last n) then some (last n) else none)
      fun i => some (castLT i (_ : ↑i < Nat.succ n))
j : ℕ
hjn : j < n + 1
hj : { val := j, isLt := hjn } < i
hpj : p { val := j, isLt := hjn }
k : Fin n
h : (find fun i => p (castLT i (_ : ↑i < Nat.succ n))) = some k
⊢ False

Next tactic:
rw [h] at hi
/-- If `find p` returns `some i`, then `p j` does not hold for `j < i`, i.e., `i` is minimal among
the indices where `p` holds. -/
theorem find_min :
    ∀ {n : ℕ} {p : Fin n → Prop} [DecidablePred p] {i : Fin n} (_ : i ∈ Fin.find p) {j : Fin n}
      (_ : j < i), ¬p j
  | 0, p, _, i, hi, _, _, _ => Option.noConfusion hi
  | n + 1, p, _, i, hi, ⟨j, hjn⟩, hj, hpj => by
    rw [find] at hi
    cases' h : find fun i : Fin n ↦ p (i.castLT (Nat.lt_succ_of_lt i.2)) with k
    · simp only [h] at hi
      split_ifs at hi with hl
      · cases hi
        rw [find_eq_none_iff] at h
        refine h ⟨j, hj⟩ hpj
      · exact Option.not_mem_none _ hi
    · rw [h] at hi
      

Proof state:
case some
m n✝ n : ℕ
p : Fin (n + 1) → Prop
x✝ : DecidablePred p
i : Fin (n + 1)
j : ℕ
hjn : j < n + 1
hj : { val := j, isLt := hjn } < i
hpj : p { val := j, isLt := hjn }
k : Fin n
hi :
  i ∈
    Option.casesOn (some k) (if x : p (last n) then some (last n) else none) fun i =>
      some (castLT i (_ : ↑i < Nat.succ n))
h : (find fun i => p (castLT i (_ : ↑i < Nat.succ n))) = some k
⊢ False

Next tactic:
dsimp at hi
/-- If `find p` returns `some i`, then `p j` does not hold for `j < i`, i.e., `i` is minimal among
the indices where `p` holds. -/
theorem find_min :
    ∀ {n : ℕ} {p : Fin n → Prop} [DecidablePred p] {i : Fin n} (_ : i ∈ Fin.find p) {j : Fin n}
      (_ : j < i), ¬p j
  | 0, p, _, i, hi, _, _, _ => Option.noConfusion hi
  | n + 1, p, _, i, hi, ⟨j, hjn⟩, hj, hpj => by
    rw [find] at hi
    cases' h : find fun i : Fin n ↦ p (i.castLT (Nat.lt_succ_of_lt i.2)) with k
    · simp only [h] at hi
      split_ifs at hi with hl
      · cases hi
        rw [find_eq_none_iff] at h
        refine h ⟨j, hj⟩ hpj
      · exact Option.not_mem_none _ hi
    · rw [h] at hi
      dsimp at hi
      

Proof state:
case some
m n✝ n : ℕ
p : Fin (n + 1) → Prop
x✝ : DecidablePred p
i : Fin (n + 1)
j : ℕ
hjn : j < n + 1
hj : { val := j, isLt := hjn } < i
hpj : p { val := j, isLt := hjn }
k : Fin n
hi : i ∈ some (castLT k (_ : ↑k < Nat.succ n))
h : (find fun i => p (castLT i (_ : ↑i < Nat.succ n))) = some k
⊢ False

Next tactic:
obtain rfl := Option.some_inj.1 hi
/-- If `find p` returns `some i`, then `p j` does not hold for `j < i`, i.e., `i` is minimal among
the indices where `p` holds. -/
theorem find_min :
    ∀ {n : ℕ} {p : Fin n → Prop} [DecidablePred p] {i : Fin n} (_ : i ∈ Fin.find p) {j : Fin n}
      (_ : j < i), ¬p j
  | 0, p, _, i, hi, _, _, _ => Option.noConfusion hi
  | n + 1, p, _, i, hi, ⟨j, hjn⟩, hj, hpj => by
    rw [find] at hi
    cases' h : find fun i : Fin n ↦ p (i.castLT (Nat.lt_succ_of_lt i.2)) with k
    · simp only [h] at hi
      split_ifs at hi with hl
      · cases hi
        rw [find_eq_none_iff] at h
        refine h ⟨j, hj⟩ hpj
      · exact Option.not_mem_none _ hi
    · rw [h] at hi
      dsimp at hi
      obtain rfl := Option.some_inj.1 hi
      

Proof state:
case some
m n✝ n : ℕ
p : Fin (n + 1) → Prop
x✝ : DecidablePred p
j : ℕ
hjn : j < n + 1
hpj : p { val := j, isLt := hjn }
k : Fin n
h : (find fun i => p (castLT i (_ : ↑i < Nat.succ n))) = some k
hj : { val := j, isLt := hjn } < castLT k (_ : ↑k < Nat.succ n)
hi : castLT k (_ : ↑k < Nat.succ n) ∈ some (castLT k (_ : ↑k < Nat.succ n))
⊢ False

Next tactic:
exact find_min h (show (⟨j, lt_trans hj k.2⟩ : Fin n) < k from hj) hpj
theorem nat_find_mem_find {p : Fin n → Prop} [DecidablePred p]
    (h : ∃ i, ∃ hin : i < n, p ⟨i, hin⟩) :
    (⟨Nat.find h, (Nat.find_spec h).fst⟩ : Fin n) ∈ find p := by
  

Proof state:
m n : ℕ
p : Fin n → Prop
inst✝ : DecidablePred p
h : ∃ i, ∃ (hin : i < n), p { val := i, isLt := hin }
⊢ { val := Nat.find h, isLt := (_ : Nat.find h < n) } ∈ find p

Next tactic:
let ⟨i, hin, hi⟩ := h
theorem nat_find_mem_find {p : Fin n → Prop} [DecidablePred p]
    (h : ∃ i, ∃ hin : i < n, p ⟨i, hin⟩) :
    (⟨Nat.find h, (Nat.find_spec h).fst⟩ : Fin n) ∈ find p := by
  let ⟨i, hin, hi⟩ := h
  

Proof state:
m n : ℕ
p : Fin n → Prop
inst✝ : DecidablePred p
h : ∃ i, ∃ (hin : i < n), p { val := i, isLt := hin }
i : ℕ
hin : i < n
hi : p { val := i, isLt := hin }
⊢ { val := Nat.find (_ : ∃ i, ∃ (hin : i < n), p { val := i, isLt := hin }),
      isLt := (_ : Nat.find (_ : ∃ i, ∃ (hin : i < n), p { val := i, isLt := hin }) < n) } ∈
    find p

Next tactic:
cases' hf : find p with f
theorem nat_find_mem_find {p : Fin n → Prop} [DecidablePred p]
    (h : ∃ i, ∃ hin : i < n, p ⟨i, hin⟩) :
    (⟨Nat.find h, (Nat.find_spec h).fst⟩ : Fin n) ∈ find p := by
  let ⟨i, hin, hi⟩ := h
  cases' hf : find p with f
  · 

Proof state:
case none
m n : ℕ
p : Fin n → Prop
inst✝ : DecidablePred p
h : ∃ i, ∃ (hin : i < n), p { val := i, isLt := hin }
i : ℕ
hin : i < n
hi : p { val := i, isLt := hin }
hf : find p = none
⊢ { val := Nat.find (_ : ∃ i, ∃ (hin : i < n), p { val := i, isLt := hin }),
      isLt := (_ : Nat.find (_ : ∃ i, ∃ (hin : i < n), p { val := i, isLt := hin }) < n) } ∈
    none

Next tactic:
rw [find_eq_none_iff] at hf
theorem nat_find_mem_find {p : Fin n → Prop} [DecidablePred p]
    (h : ∃ i, ∃ hin : i < n, p ⟨i, hin⟩) :
    (⟨Nat.find h, (Nat.find_spec h).fst⟩ : Fin n) ∈ find p := by
  let ⟨i, hin, hi⟩ := h
  cases' hf : find p with f
  · rw [find_eq_none_iff] at hf
    

Proof state:
case none
m n : ℕ
p : Fin n → Prop
inst✝ : DecidablePred p
h : ∃ i, ∃ (hin : i < n), p { val := i, isLt := hin }
i : ℕ
hin : i < n
hi : p { val := i, isLt := hin }
hf : ∀ (i : Fin n), ¬p i
⊢ { val := Nat.find (_ : ∃ i, ∃ (hin : i < n), p { val := i, isLt := hin }),
      isLt := (_ : Nat.find (_ : ∃ i, ∃ (hin : i < n), p { val := i, isLt := hin }) < n) } ∈
    none

Next tactic:
exact (hf ⟨i, hin⟩ hi).elim
theorem nat_find_mem_find {p : Fin n → Prop} [DecidablePred p]
    (h : ∃ i, ∃ hin : i < n, p ⟨i, hin⟩) :
    (⟨Nat.find h, (Nat.find_spec h).fst⟩ : Fin n) ∈ find p := by
  let ⟨i, hin, hi⟩ := h
  cases' hf : find p with f
  · rw [find_eq_none_iff] at hf
    exact (hf ⟨i, hin⟩ hi).elim
  · 

Proof state:
case some
m n : ℕ
p : Fin n → Prop
inst✝ : DecidablePred p
h : ∃ i, ∃ (hin : i < n), p { val := i, isLt := hin }
i : ℕ
hin : i < n
hi : p { val := i, isLt := hin }
f : Fin n
hf : find p = some f
⊢ { val := Nat.find (_ : ∃ i, ∃ (hin : i < n), p { val := i, isLt := hin }),
      isLt := (_ : Nat.find (_ : ∃ i, ∃ (hin : i < n), p { val := i, isLt := hin }) < n) } ∈
    some f

Next tactic:
refine' Option.some_inj.2 (le_antisymm _ _)
theorem nat_find_mem_find {p : Fin n → Prop} [DecidablePred p]
    (h : ∃ i, ∃ hin : i < n, p ⟨i, hin⟩) :
    (⟨Nat.find h, (Nat.find_spec h).fst⟩ : Fin n) ∈ find p := by
  let ⟨i, hin, hi⟩ := h
  cases' hf : find p with f
  · rw [find_eq_none_iff] at hf
    exact (hf ⟨i, hin⟩ hi).elim
  · refine' Option.some_inj.2 (le_antisymm _ _)
    · 

Proof state:
case some.refine'_1
m n : ℕ
p : Fin n → Prop
inst✝ : DecidablePred p
h : ∃ i, ∃ (hin : i < n), p { val := i, isLt := hin }
i : ℕ
hin : i < n
hi : p { val := i, isLt := hin }
f : Fin n
hf : find p = some f
⊢ f ≤
    { val := Nat.find (_ : ∃ i, ∃ (hin : i < n), p { val := i, isLt := hin }),
      isLt := (_ : Nat.find (_ : ∃ i, ∃ (hin : i < n), p { val := i, isLt := hin }) < n) }

Next tactic:
exact find_min' hf (Nat.find_spec h).snd
theorem nat_find_mem_find {p : Fin n → Prop} [DecidablePred p]
    (h : ∃ i, ∃ hin : i < n, p ⟨i, hin⟩) :
    (⟨Nat.find h, (Nat.find_spec h).fst⟩ : Fin n) ∈ find p := by
  let ⟨i, hin, hi⟩ := h
  cases' hf : find p with f
  · rw [find_eq_none_iff] at hf
    exact (hf ⟨i, hin⟩ hi).elim
  · refine' Option.some_inj.2 (le_antisymm _ _)
    · exact find_min' hf (Nat.find_spec h).snd
    · 

Proof state:
case some.refine'_2
m n : ℕ
p : Fin n → Prop
inst✝ : DecidablePred p
h : ∃ i, ∃ (hin : i < n), p { val := i, isLt := hin }
i : ℕ
hin : i < n
hi : p { val := i, isLt := hin }
f : Fin n
hf : find p = some f
⊢ { val := Nat.find (_ : ∃ i, ∃ (hin : i < n), p { val := i, isLt := hin }),
      isLt := (_ : Nat.find (_ : ∃ i, ∃ (hin : i < n), p { val := i, isLt := hin }) < n) } ≤
    f

Next tactic:
exact Nat.find_min' _ ⟨f.2, by convert find_spec p hf⟩
theorem nat_find_mem_find {p : Fin n → Prop} [DecidablePred p]
    (h : ∃ i, ∃ hin : i < n, p ⟨i, hin⟩) :
    (⟨Nat.find h, (Nat.find_spec h).fst⟩ : Fin n) ∈ find p := by
  let ⟨i, hin, hi⟩ := h
  cases' hf : find p with f
  · rw [find_eq_none_iff] at hf
    exact (hf ⟨i, hin⟩ hi).elim
  · refine' Option.some_inj.2 (le_antisymm _ _)
    · exact find_min' hf (Nat.find_spec h).snd
    · exact Nat.find_min' _ ⟨f.2, by 

Proof state:
m n : ℕ
p : Fin n → Prop
inst✝ : DecidablePred p
h : ∃ i, ∃ (hin : i < n), p { val := i, isLt := hin }
i : ℕ
hin : i < n
hi : p { val := i, isLt := hin }
f : Fin n
hf : find p = some f
⊢ p { val := ↑f, isLt := (_ : ↑f < n) }

Next tactic:
convert find_spec p hf
theorem mem_find_iff {p : Fin n → Prop} [DecidablePred p] {i : Fin n} :
    i ∈ Fin.find p ↔ p i ∧ ∀ j, p j → i ≤ j :=
  ⟨fun hi ↦ ⟨find_spec _ hi, fun _ ↦ find_min' hi⟩, by
    

Proof state:
m n : ℕ
p : Fin n → Prop
inst✝ : DecidablePred p
i : Fin n
⊢ (p i ∧ ∀ (j : Fin n), p j → i ≤ j) → i ∈ find p

Next tactic:
rintro ⟨hpi, hj⟩
theorem mem_find_iff {p : Fin n → Prop} [DecidablePred p] {i : Fin n} :
    i ∈ Fin.find p ↔ p i ∧ ∀ j, p j → i ≤ j :=
  ⟨fun hi ↦ ⟨find_spec _ hi, fun _ ↦ find_min' hi⟩, by
    rintro ⟨hpi, hj⟩
    

Proof state:
case intro
m n : ℕ
p : Fin n → Prop
inst✝ : DecidablePred p
i : Fin n
hpi : p i
hj : ∀ (j : Fin n), p j → i ≤ j
⊢ i ∈ find p

Next tactic:
cases hfp : Fin.find p
theorem mem_find_iff {p : Fin n → Prop} [DecidablePred p] {i : Fin n} :
    i ∈ Fin.find p ↔ p i ∧ ∀ j, p j → i ≤ j :=
  ⟨fun hi ↦ ⟨find_spec _ hi, fun _ ↦ find_min' hi⟩, by
    rintro ⟨hpi, hj⟩
    cases hfp : Fin.find p
    · 

Proof state:
case intro.none
m n : ℕ
p : Fin n → Prop
inst✝ : DecidablePred p
i : Fin n
hpi : p i
hj : ∀ (j : Fin n), p j → i ≤ j
hfp : find p = none
⊢ i ∈ none

Next tactic:
rw [find_eq_none_iff] at hfp
theorem mem_find_iff {p : Fin n → Prop} [DecidablePred p] {i : Fin n} :
    i ∈ Fin.find p ↔ p i ∧ ∀ j, p j → i ≤ j :=
  ⟨fun hi ↦ ⟨find_spec _ hi, fun _ ↦ find_min' hi⟩, by
    rintro ⟨hpi, hj⟩
    cases hfp : Fin.find p
    · rw [find_eq_none_iff] at hfp
      

Proof state:
case intro.none
m n : ℕ
p : Fin n → Prop
inst✝ : DecidablePred p
i : Fin n
hpi : p i
hj : ∀ (j : Fin n), p j → i ≤ j
hfp : ∀ (i : Fin n), ¬p i
⊢ i ∈ none

Next tactic:
exact (hfp _ hpi).elim
theorem mem_find_iff {p : Fin n → Prop} [DecidablePred p] {i : Fin n} :
    i ∈ Fin.find p ↔ p i ∧ ∀ j, p j → i ≤ j :=
  ⟨fun hi ↦ ⟨find_spec _ hi, fun _ ↦ find_min' hi⟩, by
    rintro ⟨hpi, hj⟩
    cases hfp : Fin.find p
    · rw [find_eq_none_iff] at hfp
      exact (hfp _ hpi).elim
    · 

Proof state:
case intro.some
m n : ℕ
p : Fin n → Prop
inst✝ : DecidablePred p
i : Fin n
hpi : p i
hj : ∀ (j : Fin n), p j → i ≤ j
val✝ : Fin n
hfp : find p = some val✝
⊢ i ∈ some val✝

Next tactic:
exact Option.some_inj.2 (le_antisymm (find_min' hfp hpi) (hj _ (find_spec _ hfp)))
theorem contractNth_apply_of_eq (j : Fin (n + 1)) (op : α → α → α) (g : Fin (n + 1) → α) (k : Fin n)
    (h : (k : ℕ) = j) : contractNth j op g k = op (g (Fin.castSucc k)) (g k.succ) := by
  

Proof state:
m n : ℕ
α : Type u_1
j : Fin (n + 1)
op : α → α → α
g : Fin (n + 1) → α
k : Fin n
h : ↑k = ↑j
⊢ contractNth j op g k = op (g (castSucc k)) (g (succ k))

Next tactic:
have : ¬(k : ℕ) < j := not_lt.2 (le_of_eq h.symm)
theorem contractNth_apply_of_eq (j : Fin (n + 1)) (op : α → α → α) (g : Fin (n + 1) → α) (k : Fin n)
    (h : (k : ℕ) = j) : contractNth j op g k = op (g (Fin.castSucc k)) (g k.succ) := by
  have : ¬(k : ℕ) < j := not_lt.2 (le_of_eq h.symm)
  

Proof state:
m n : ℕ
α : Type u_1
j : Fin (n + 1)
op : α → α → α
g : Fin (n + 1) → α
k : Fin n
h : ↑k = ↑j
this : ¬↑k < ↑j
⊢ contractNth j op g k = op (g (castSucc k)) (g (succ k))

Next tactic:
rw [contractNth, if_neg this, if_pos h]
theorem contractNth_apply_of_gt (j : Fin (n + 1)) (op : α → α → α) (g : Fin (n + 1) → α) (k : Fin n)
    (h : (j : ℕ) < k) : contractNth j op g k = g k.succ := by
  

Proof state:
m n : ℕ
α : Type u_1
j : Fin (n + 1)
op : α → α → α
g : Fin (n + 1) → α
k : Fin n
h : ↑j < ↑k
⊢ contractNth j op g k = g (succ k)

Next tactic:
rw [contractNth, if_neg (not_lt_of_gt h), if_neg (Ne.symm <| ne_of_lt h)]
theorem contractNth_apply_of_ne (j : Fin (n + 1)) (op : α → α → α) (g : Fin (n + 1) → α) (k : Fin n)
    (hjk : (j : ℕ) ≠ k) : contractNth j op g k = g (j.succAbove k) := by
  

Proof state:
m n : ℕ
α : Type u_1
j : Fin (n + 1)
op : α → α → α
g : Fin (n + 1) → α
k : Fin n
hjk : ↑j ≠ ↑k
⊢ contractNth j op g k = g (succAbove j k)

Next tactic:
rcases lt_trichotomy (k : ℕ) j with (h | h | h)
theorem contractNth_apply_of_ne (j : Fin (n + 1)) (op : α → α → α) (g : Fin (n + 1) → α) (k : Fin n)
    (hjk : (j : ℕ) ≠ k) : contractNth j op g k = g (j.succAbove k) := by
  rcases lt_trichotomy (k : ℕ) j with (h | h | h)
  · 

Proof state:
case inl
m n : ℕ
α : Type u_1
j : Fin (n + 1)
op : α → α → α
g : Fin (n + 1) → α
k : Fin n
hjk : ↑j ≠ ↑k
h : ↑k < ↑j
⊢ contractNth j op g k = g (succAbove j k)

Next tactic:
rwa [j.succAbove_below, contractNth_apply_of_lt]
theorem contractNth_apply_of_ne (j : Fin (n + 1)) (op : α → α → α) (g : Fin (n + 1) → α) (k : Fin n)
    (hjk : (j : ℕ) ≠ k) : contractNth j op g k = g (j.succAbove k) := by
  rcases lt_trichotomy (k : ℕ) j with (h | h | h)
  · rwa [j.succAbove_below, contractNth_apply_of_lt]
    · 

Proof state:
case inl.h
m n : ℕ
α : Type u_1
j : Fin (n + 1)
op : α → α → α
g : Fin (n + 1) → α
k : Fin n
hjk : ↑j ≠ ↑k
h : ↑k < ↑j
⊢ castSucc k < j

Next tactic:
rwa [Fin.lt_iff_val_lt_val]
theorem contractNth_apply_of_ne (j : Fin (n + 1)) (op : α → α → α) (g : Fin (n + 1) → α) (k : Fin n)
    (hjk : (j : ℕ) ≠ k) : contractNth j op g k = g (j.succAbove k) := by
  rcases lt_trichotomy (k : ℕ) j with (h | h | h)
  · rwa [j.succAbove_below, contractNth_apply_of_lt]
    · rwa [Fin.lt_iff_val_lt_val]
  · 

Proof state:
case inr.inl
m n : ℕ
α : Type u_1
j : Fin (n + 1)
op : α → α → α
g : Fin (n + 1) → α
k : Fin n
hjk : ↑j ≠ ↑k
h : ↑k = ↑j
⊢ contractNth j op g k = g (succAbove j k)

Next tactic:
exact False.elim (hjk h.symm)
theorem contractNth_apply_of_ne (j : Fin (n + 1)) (op : α → α → α) (g : Fin (n + 1) → α) (k : Fin n)
    (hjk : (j : ℕ) ≠ k) : contractNth j op g k = g (j.succAbove k) := by
  rcases lt_trichotomy (k : ℕ) j with (h | h | h)
  · rwa [j.succAbove_below, contractNth_apply_of_lt]
    · rwa [Fin.lt_iff_val_lt_val]
  · exact False.elim (hjk h.symm)
  · 

Proof state:
case inr.inr
m n : ℕ
α : Type u_1
j : Fin (n + 1)
op : α → α → α
g : Fin (n + 1) → α
k : Fin n
hjk : ↑j ≠ ↑k
h : ↑j < ↑k
⊢ contractNth j op g k = g (succAbove j k)

Next tactic:
rwa [j.succAbove_above, contractNth_apply_of_gt]
theorem contractNth_apply_of_ne (j : Fin (n + 1)) (op : α → α → α) (g : Fin (n + 1) → α) (k : Fin n)
    (hjk : (j : ℕ) ≠ k) : contractNth j op g k = g (j.succAbove k) := by
  rcases lt_trichotomy (k : ℕ) j with (h | h | h)
  · rwa [j.succAbove_below, contractNth_apply_of_lt]
    · rwa [Fin.lt_iff_val_lt_val]
  · exact False.elim (hjk h.symm)
  · rwa [j.succAbove_above, contractNth_apply_of_gt]
    · 

Proof state:
case inr.inr.h
m n : ℕ
α : Type u_1
j : Fin (n + 1)
op : α → α → α
g : Fin (n + 1) → α
k : Fin n
hjk : ↑j ≠ ↑k
h : ↑j < ↑k
⊢ j ≤ castSucc k

Next tactic:
exact Fin.le_iff_val_le_val.2 (le_of_lt h)
/-- To show two sigma pairs of tuples agree, it to show the second elements are related via
`Fin.cast`. -/
theorem sigma_eq_of_eq_comp_cast {α : Type*} :
    ∀ {a b : Σii, Fin ii → α} (h : a.fst = b.fst), a.snd = b.snd ∘ Fin.cast h → a = b
  | ⟨ai, a⟩, ⟨bi, b⟩, hi, h => by
    

Proof state:
m n : ℕ
α : Type u_1
ai : ℕ
a : Fin ai → α
bi : ℕ
b : Fin bi → α
hi : { fst := ai, snd := a }.fst = { fst := bi, snd := b }.fst
h : { fst := ai, snd := a }.snd = { fst := bi, snd := b }.snd ∘ cast hi
⊢ { fst := ai, snd := a } = { fst := bi, snd := b }

Next tactic:
dsimp only at hi
/-- To show two sigma pairs of tuples agree, it to show the second elements are related via
`Fin.cast`. -/
theorem sigma_eq_of_eq_comp_cast {α : Type*} :
    ∀ {a b : Σii, Fin ii → α} (h : a.fst = b.fst), a.snd = b.snd ∘ Fin.cast h → a = b
  | ⟨ai, a⟩, ⟨bi, b⟩, hi, h => by
    dsimp only at hi
    

Proof state:
m n : ℕ
α : Type u_1
ai : ℕ
a : Fin ai → α
bi : ℕ
b : Fin bi → α
hi : ai = bi
h : { fst := ai, snd := a }.snd = { fst := bi, snd := b }.snd ∘ cast hi
⊢ { fst := ai, snd := a } = { fst := bi, snd := b }

Next tactic:
subst hi
/-- To show two sigma pairs of tuples agree, it to show the second elements are related via
`Fin.cast`. -/
theorem sigma_eq_of_eq_comp_cast {α : Type*} :
    ∀ {a b : Σii, Fin ii → α} (h : a.fst = b.fst), a.snd = b.snd ∘ Fin.cast h → a = b
  | ⟨ai, a⟩, ⟨bi, b⟩, hi, h => by
    dsimp only at hi
    subst hi
    

Proof state:
m n : ℕ
α : Type u_1
ai : ℕ
a b : Fin ai → α
h : { fst := ai, snd := a }.snd = { fst := ai, snd := b }.snd ∘ cast (_ : ai = ai)
⊢ { fst := ai, snd := a } = { fst := ai, snd := b }

Next tactic:
simpa using h
theorem convexHull_eq_iInter : convexHull 𝕜 s = ⋂ (t : Set E) (_ : s ⊆ t) (_ : Convex 𝕜 t), t := by
  

Proof state:
𝕜 : Type u_1
E : Type u_2
F : Type u_3
inst✝⁴ : OrderedSemiring 𝕜
inst✝³ : AddCommMonoid E
inst✝² : AddCommMonoid F
inst✝¹ : Module 𝕜 E
inst✝ : Module 𝕜 F
s : Set E
⊢ (convexHull 𝕜) s = ⋂ t, ⋂ (_ : s ⊆ t), ⋂ (_ : Convex 𝕜 t), t

Next tactic:
simp [convexHull, iInter_subtype, iInter_and]
theorem mem_convexHull_iff : x ∈ convexHull 𝕜 s ↔ ∀ t, s ⊆ t → Convex 𝕜 t → x ∈ t := by
  

Proof state:
𝕜 : Type u_1
E : Type u_2
F : Type u_3
inst✝⁴ : OrderedSemiring 𝕜
inst✝³ : AddCommMonoid E
inst✝² : AddCommMonoid F
inst✝¹ : Module 𝕜 E
inst✝ : Module 𝕜 F
s t : Set E
x y : E
⊢ x ∈ (convexHull 𝕜) s ↔ ∀ (t : Set E), s ⊆ t → Convex 𝕜 t → x ∈ t

Next tactic:
simp_rw [convexHull_eq_iInter, mem_iInter]
@[simp]
theorem convexHull_empty_iff : convexHull 𝕜 s = ∅ ↔ s = ∅ := by
  

Proof state:
𝕜 : Type u_1
E : Type u_2
F : Type u_3
inst✝⁴ : OrderedSemiring 𝕜
inst✝³ : AddCommMonoid E
inst✝² : AddCommMonoid F
inst✝¹ : Module 𝕜 E
inst✝ : Module 𝕜 F
s t : Set E
x y : E
⊢ (convexHull 𝕜) s = ∅ ↔ s = ∅

Next tactic:
constructor
@[simp]
theorem convexHull_empty_iff : convexHull 𝕜 s = ∅ ↔ s = ∅ := by
  constructor
  · 

Proof state:
case mp
𝕜 : Type u_1
E : Type u_2
F : Type u_3
inst✝⁴ : OrderedSemiring 𝕜
inst✝³ : AddCommMonoid E
inst✝² : AddCommMonoid F
inst✝¹ : Module 𝕜 E
inst✝ : Module 𝕜 F
s t : Set E
x y : E
⊢ (convexHull 𝕜) s = ∅ → s = ∅

Next tactic:
intro h
@[simp]
theorem convexHull_empty_iff : convexHull 𝕜 s = ∅ ↔ s = ∅ := by
  constructor
  · intro h
    

Proof state:
case mp
𝕜 : Type u_1
E : Type u_2
F : Type u_3
inst✝⁴ : OrderedSemiring 𝕜
inst✝³ : AddCommMonoid E
inst✝² : AddCommMonoid F
inst✝¹ : Module 𝕜 E
inst✝ : Module 𝕜 F
s t : Set E
x y : E
h : (convexHull 𝕜) s = ∅
⊢ s = ∅

Next tactic:
rw [← Set.subset_empty_iff, ← h]
@[simp]
theorem convexHull_empty_iff : convexHull 𝕜 s = ∅ ↔ s = ∅ := by
  constructor
  · intro h
    rw [← Set.subset_empty_iff, ← h]
    

Proof state:
case mp
𝕜 : Type u_1
E : Type u_2
F : Type u_3
inst✝⁴ : OrderedSemiring 𝕜
inst✝³ : AddCommMonoid E
inst✝² : AddCommMonoid F
inst✝¹ : Module 𝕜 E
inst✝ : Module 𝕜 F
s t : Set E
x y : E
h : (convexHull 𝕜) s = ∅
⊢ s ⊆ (convexHull 𝕜) s

Next tactic:
exact subset_convexHull 𝕜 _
@[simp]
theorem convexHull_empty_iff : convexHull 𝕜 s = ∅ ↔ s = ∅ := by
  constructor
  · intro h
    rw [← Set.subset_empty_iff, ← h]
    exact subset_convexHull 𝕜 _
  · 

Proof state:
case mpr
𝕜 : Type u_1
E : Type u_2
F : Type u_3
inst✝⁴ : OrderedSemiring 𝕜
inst✝³ : AddCommMonoid E
inst✝² : AddCommMonoid F
inst✝¹ : Module 𝕜 E
inst✝ : Module 𝕜 F
s t : Set E
x y : E
⊢ s = ∅ → (convexHull 𝕜) s = ∅

Next tactic:
rintro rfl