l3lab/ntp-mathlib huggingface dataset:
theorem fold_op_rel_iff_or {r : β → β → Prop} (hr : ∀ {x y z}, r x (op y z) ↔ r x y ∨ r x z)
    {c : β} : r c (s.fold op b f) ↔ r c b ∨ ∃ x ∈ s, r c (f x) := by
  classical
    induction' s using Finset.induction_on with a s ha IH
    · simp
    

Proof state:
case insert
α : Type u_1
β : Type u_2
γ : Type u_3
op : β → β → β
hc : IsCommutative β op
ha✝ : IsAssociative β op
f : α → β
b : β
s✝ : Finset α
a✝ : α
r : β → β → Prop
hr : ∀ {x y z : β}, r x (op y z) ↔ r x y ∨ r x z
c : β
a : α
s : Finset α
ha : a ∉ s
IH : r c (fold op b f s) ↔ r c b ∨ ∃ x ∈ s, r c (f x)
⊢ r c (fold op b f (insert a s)) ↔ r c b ∨ ∃ x ∈ insert a s, r c (f x)

Next tactic:
rw [Finset.fold_insert ha, hr, IH, ← or_assoc, @or_comm (r c (f a)), or_assoc]
theorem fold_op_rel_iff_or {r : β → β → Prop} (hr : ∀ {x y z}, r x (op y z) ↔ r x y ∨ r x z)
    {c : β} : r c (s.fold op b f) ↔ r c b ∨ ∃ x ∈ s, r c (f x) := by
  classical
    induction' s using Finset.induction_on with a s ha IH
    · simp
    rw [Finset.fold_insert ha, hr, IH, ← or_assoc, @or_comm (r c (f a)), or_assoc]
    

Proof state:
case insert
α : Type u_1
β : Type u_2
γ : Type u_3
op : β → β → β
hc : IsCommutative β op
ha✝ : IsAssociative β op
f : α → β
b : β
s✝ : Finset α
a✝ : α
r : β → β → Prop
hr : ∀ {x y z : β}, r x (op y z) ↔ r x y ∨ r x z
c : β
a : α
s : Finset α
ha : a ∉ s
IH : r c (fold op b f s) ↔ r c b ∨ ∃ x ∈ s, r c (f x)
⊢ (r c b ∨ r c (f a) ∨ ∃ x ∈ s, r c (f x)) ↔ r c b ∨ ∃ x ∈ insert a s, r c (f x)

Next tactic:
apply or_congr Iff.rfl
theorem fold_op_rel_iff_or {r : β → β → Prop} (hr : ∀ {x y z}, r x (op y z) ↔ r x y ∨ r x z)
    {c : β} : r c (s.fold op b f) ↔ r c b ∨ ∃ x ∈ s, r c (f x) := by
  classical
    induction' s using Finset.induction_on with a s ha IH
    · simp
    rw [Finset.fold_insert ha, hr, IH, ← or_assoc, @or_comm (r c (f a)), or_assoc]
    apply or_congr Iff.rfl
    

Proof state:
case insert
α : Type u_1
β : Type u_2
γ : Type u_3
op : β → β → β
hc : IsCommutative β op
ha✝ : IsAssociative β op
f : α → β
b : β
s✝ : Finset α
a✝ : α
r : β → β → Prop
hr : ∀ {x y z : β}, r x (op y z) ↔ r x y ∨ r x z
c : β
a : α
s : Finset α
ha : a ∉ s
IH : r c (fold op b f s) ↔ r c b ∨ ∃ x ∈ s, r c (f x)
⊢ (r c (f a) ∨ ∃ x ∈ s, r c (f x)) ↔ ∃ x ∈ insert a s, r c (f x)

Next tactic:
constructor
theorem fold_op_rel_iff_or {r : β → β → Prop} (hr : ∀ {x y z}, r x (op y z) ↔ r x y ∨ r x z)
    {c : β} : r c (s.fold op b f) ↔ r c b ∨ ∃ x ∈ s, r c (f x) := by
  classical
    induction' s using Finset.induction_on with a s ha IH
    · simp
    rw [Finset.fold_insert ha, hr, IH, ← or_assoc, @or_comm (r c (f a)), or_assoc]
    apply or_congr Iff.rfl
    constructor
    · 

Proof state:
case insert.mp
α : Type u_1
β : Type u_2
γ : Type u_3
op : β → β → β
hc : IsCommutative β op
ha✝ : IsAssociative β op
f : α → β
b : β
s✝ : Finset α
a✝ : α
r : β → β → Prop
hr : ∀ {x y z : β}, r x (op y z) ↔ r x y ∨ r x z
c : β
a : α
s : Finset α
ha : a ∉ s
IH : r c (fold op b f s) ↔ r c b ∨ ∃ x ∈ s, r c (f x)
⊢ (r c (f a) ∨ ∃ x ∈ s, r c (f x)) → ∃ x ∈ insert a s, r c (f x)

Next tactic:
rintro (h₁ | ⟨x, hx, h₂⟩)
theorem fold_op_rel_iff_or {r : β → β → Prop} (hr : ∀ {x y z}, r x (op y z) ↔ r x y ∨ r x z)
    {c : β} : r c (s.fold op b f) ↔ r c b ∨ ∃ x ∈ s, r c (f x) := by
  classical
    induction' s using Finset.induction_on with a s ha IH
    · simp
    rw [Finset.fold_insert ha, hr, IH, ← or_assoc, @or_comm (r c (f a)), or_assoc]
    apply or_congr Iff.rfl
    constructor
    · rintro (h₁ | ⟨x, hx, h₂⟩)
      · 

Proof state:
case insert.mp.inl
α : Type u_1
β : Type u_2
γ : Type u_3
op : β → β → β
hc : IsCommutative β op
ha✝ : IsAssociative β op
f : α → β
b : β
s✝ : Finset α
a✝ : α
r : β → β → Prop
hr : ∀ {x y z : β}, r x (op y z) ↔ r x y ∨ r x z
c : β
a : α
s : Finset α
ha : a ∉ s
IH : r c (fold op b f s) ↔ r c b ∨ ∃ x ∈ s, r c (f x)
h₁ : r c (f a)
⊢ ∃ x ∈ insert a s, r c (f x)

Next tactic:
use a
theorem fold_op_rel_iff_or {r : β → β → Prop} (hr : ∀ {x y z}, r x (op y z) ↔ r x y ∨ r x z)
    {c : β} : r c (s.fold op b f) ↔ r c b ∨ ∃ x ∈ s, r c (f x) := by
  classical
    induction' s using Finset.induction_on with a s ha IH
    · simp
    rw [Finset.fold_insert ha, hr, IH, ← or_assoc, @or_comm (r c (f a)), or_assoc]
    apply or_congr Iff.rfl
    constructor
    · rintro (h₁ | ⟨x, hx, h₂⟩)
      · use a
        

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
op : β → β → β
hc : IsCommutative β op
ha✝ : IsAssociative β op
f : α → β
b : β
s✝ : Finset α
a✝ : α
r : β → β → Prop
hr : ∀ {x y z : β}, r x (op y z) ↔ r x y ∨ r x z
c : β
a : α
s : Finset α
ha : a ∉ s
IH : r c (fold op b f s) ↔ r c b ∨ ∃ x ∈ s, r c (f x)
h₁ : r c (f a)
⊢ a ∈ insert a s ∧ r c (f a)

Next tactic:
simp [h₁]
theorem fold_op_rel_iff_or {r : β → β → Prop} (hr : ∀ {x y z}, r x (op y z) ↔ r x y ∨ r x z)
    {c : β} : r c (s.fold op b f) ↔ r c b ∨ ∃ x ∈ s, r c (f x) := by
  classical
    induction' s using Finset.induction_on with a s ha IH
    · simp
    rw [Finset.fold_insert ha, hr, IH, ← or_assoc, @or_comm (r c (f a)), or_assoc]
    apply or_congr Iff.rfl
    constructor
    · rintro (h₁ | ⟨x, hx, h₂⟩)
      · use a
        simp [h₁]
      · 

Proof state:
case insert.mp.inr.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
op : β → β → β
hc : IsCommutative β op
ha✝ : IsAssociative β op
f : α → β
b : β
s✝ : Finset α
a✝ : α
r : β → β → Prop
hr : ∀ {x y z : β}, r x (op y z) ↔ r x y ∨ r x z
c : β
a : α
s : Finset α
ha : a ∉ s
IH : r c (fold op b f s) ↔ r c b ∨ ∃ x ∈ s, r c (f x)
x : α
hx : x ∈ s
h₂ : r c (f x)
⊢ ∃ x ∈ insert a s, r c (f x)

Next tactic:
refine' ⟨x, by simp [hx], h₂⟩
theorem fold_op_rel_iff_or {r : β → β → Prop} (hr : ∀ {x y z}, r x (op y z) ↔ r x y ∨ r x z)
    {c : β} : r c (s.fold op b f) ↔ r c b ∨ ∃ x ∈ s, r c (f x) := by
  classical
    induction' s using Finset.induction_on with a s ha IH
    · simp
    rw [Finset.fold_insert ha, hr, IH, ← or_assoc, @or_comm (r c (f a)), or_assoc]
    apply or_congr Iff.rfl
    constructor
    · rintro (h₁ | ⟨x, hx, h₂⟩)
      · use a
        simp [h₁]
      · refine' ⟨x, by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
op : β → β → β
hc : IsCommutative β op
ha✝ : IsAssociative β op
f : α → β
b : β
s✝ : Finset α
a✝ : α
r : β → β → Prop
hr : ∀ {x y z : β}, r x (op y z) ↔ r x y ∨ r x z
c : β
a : α
s : Finset α
ha : a ∉ s
IH : r c (fold op b f s) ↔ r c b ∨ ∃ x ∈ s, r c (f x)
x : α
hx : x ∈ s
h₂ : r c (f x)
⊢ x ∈ insert a s

Next tactic:
simp [hx]
theorem fold_op_rel_iff_or {r : β → β → Prop} (hr : ∀ {x y z}, r x (op y z) ↔ r x y ∨ r x z)
    {c : β} : r c (s.fold op b f) ↔ r c b ∨ ∃ x ∈ s, r c (f x) := by
  classical
    induction' s using Finset.induction_on with a s ha IH
    · simp
    rw [Finset.fold_insert ha, hr, IH, ← or_assoc, @or_comm (r c (f a)), or_assoc]
    apply or_congr Iff.rfl
    constructor
    · rintro (h₁ | ⟨x, hx, h₂⟩)
      · use a
        simp [h₁]
      · refine' ⟨x, by simp [hx], h₂⟩
    · 

Proof state:
case insert.mpr
α : Type u_1
β : Type u_2
γ : Type u_3
op : β → β → β
hc : IsCommutative β op
ha✝ : IsAssociative β op
f : α → β
b : β
s✝ : Finset α
a✝ : α
r : β → β → Prop
hr : ∀ {x y z : β}, r x (op y z) ↔ r x y ∨ r x z
c : β
a : α
s : Finset α
ha : a ∉ s
IH : r c (fold op b f s) ↔ r c b ∨ ∃ x ∈ s, r c (f x)
⊢ (∃ x ∈ insert a s, r c (f x)) → r c (f a) ∨ ∃ x ∈ s, r c (f x)

Next tactic:
rintro ⟨x, hx, h⟩
theorem fold_op_rel_iff_or {r : β → β → Prop} (hr : ∀ {x y z}, r x (op y z) ↔ r x y ∨ r x z)
    {c : β} : r c (s.fold op b f) ↔ r c b ∨ ∃ x ∈ s, r c (f x) := by
  classical
    induction' s using Finset.induction_on with a s ha IH
    · simp
    rw [Finset.fold_insert ha, hr, IH, ← or_assoc, @or_comm (r c (f a)), or_assoc]
    apply or_congr Iff.rfl
    constructor
    · rintro (h₁ | ⟨x, hx, h₂⟩)
      · use a
        simp [h₁]
      · refine' ⟨x, by simp [hx], h₂⟩
    · rintro ⟨x, hx, h⟩
      

Proof state:
case insert.mpr.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
op : β → β → β
hc : IsCommutative β op
ha✝ : IsAssociative β op
f : α → β
b : β
s✝ : Finset α
a✝ : α
r : β → β → Prop
hr : ∀ {x y z : β}, r x (op y z) ↔ r x y ∨ r x z
c : β
a : α
s : Finset α
ha : a ∉ s
IH : r c (fold op b f s) ↔ r c b ∨ ∃ x ∈ s, r c (f x)
x : α
hx : x ∈ insert a s
h : r c (f x)
⊢ r c (f a) ∨ ∃ x ∈ s, r c (f x)

Next tactic:
exact (mem_insert.mp hx).imp (fun hx => by rwa [hx] at h) (fun hx => ⟨x, hx, h⟩)
theorem fold_op_rel_iff_or {r : β → β → Prop} (hr : ∀ {x y z}, r x (op y z) ↔ r x y ∨ r x z)
    {c : β} : r c (s.fold op b f) ↔ r c b ∨ ∃ x ∈ s, r c (f x) := by
  classical
    induction' s using Finset.induction_on with a s ha IH
    · simp
    rw [Finset.fold_insert ha, hr, IH, ← or_assoc, @or_comm (r c (f a)), or_assoc]
    apply or_congr Iff.rfl
    constructor
    · rintro (h₁ | ⟨x, hx, h₂⟩)
      · use a
        simp [h₁]
      · refine' ⟨x, by simp [hx], h₂⟩
    · rintro ⟨x, hx, h⟩
      exact (mem_insert.mp hx).imp (fun hx => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
op : β → β → β
hc : IsCommutative β op
ha✝ : IsAssociative β op
f : α → β
b : β
s✝ : Finset α
a✝ : α
r : β → β → Prop
hr : ∀ {x y z : β}, r x (op y z) ↔ r x y ∨ r x z
c : β
a : α
s : Finset α
ha : a ∉ s
IH : r c (fold op b f s) ↔ r c b ∨ ∃ x ∈ s, r c (f x)
x : α
hx✝ : x ∈ insert a s
h : r c (f x)
hx : x = a
⊢ r c (f a)

Next tactic:
rwa [hx] at h
@[simp]
theorem fold_union_empty_singleton [DecidableEq α] (s : Finset α) :
    Finset.fold (· ∪ ·) ∅ singleton s = s := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
op : β → β → β
hc : IsCommutative β op
ha : IsAssociative β op
f : α → β
b : β
s✝ : Finset α
a : α
inst✝ : DecidableEq α
s : Finset α
⊢ fold (fun x x_1 => x ∪ x_1) ∅ singleton s = s

Next tactic:
induction' s using Finset.induction_on with a s has ih
@[simp]
theorem fold_union_empty_singleton [DecidableEq α] (s : Finset α) :
    Finset.fold (· ∪ ·) ∅ singleton s = s := by
  induction' s using Finset.induction_on with a s has ih
  · 

Proof state:
case empty
α : Type u_1
β : Type u_2
γ : Type u_3
op : β → β → β
hc : IsCommutative β op
ha : IsAssociative β op
f : α → β
b : β
s : Finset α
a : α
inst✝ : DecidableEq α
⊢ fold (fun x x_1 => x ∪ x_1) ∅ singleton ∅ = ∅

Next tactic:
simp only [fold_empty]
@[simp]
theorem fold_union_empty_singleton [DecidableEq α] (s : Finset α) :
    Finset.fold (· ∪ ·) ∅ singleton s = s := by
  induction' s using Finset.induction_on with a s has ih
  · simp only [fold_empty]
  · 

Proof state:
case insert
α : Type u_1
β : Type u_2
γ : Type u_3
op : β → β → β
hc : IsCommutative β op
ha : IsAssociative β op
f : α → β
b : β
s✝ : Finset α
a✝ : α
inst✝ : DecidableEq α
a : α
s : Finset α
has : a ∉ s
ih : fold (fun x x_1 => x ∪ x_1) ∅ singleton s = s
⊢ fold (fun x x_1 => x ∪ x_1) ∅ singleton (insert a s) = insert a s

Next tactic:
rw [fold_insert has, ih, insert_eq]
theorem fold_min_le : s.fold min b f ≤ c ↔ b ≤ c ∨ ∃ x ∈ s, f x ≤ c := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
op : β → β → β
hc : IsCommutative β op
ha : IsAssociative β op
f : α → β
b : β
s : Finset α
a : α
inst✝ : LinearOrder β
c : β
⊢ fold min b f s ≤ c ↔ b ≤ c ∨ ∃ x ∈ s, f x ≤ c

Next tactic:
show _ ≥ _ ↔ _
theorem fold_min_le : s.fold min b f ≤ c ↔ b ≤ c ∨ ∃ x ∈ s, f x ≤ c := by
  show _ ≥ _ ↔ _
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
op : β → β → β
hc : IsCommutative β op
ha : IsAssociative β op
f : α → β
b : β
s : Finset α
a : α
inst✝ : LinearOrder β
c : β
⊢ c ≥ fold min b f s ↔ b ≤ c ∨ ∃ x ∈ s, f x ≤ c

Next tactic:
apply fold_op_rel_iff_or
theorem fold_min_le : s.fold min b f ≤ c ↔ b ≤ c ∨ ∃ x ∈ s, f x ≤ c := by
  show _ ≥ _ ↔ _
  apply fold_op_rel_iff_or
  

Proof state:
case hr
α : Type u_1
β : Type u_2
γ : Type u_3
op : β → β → β
hc : IsCommutative β op
ha : IsAssociative β op
f : α → β
b : β
s : Finset α
a : α
inst✝ : LinearOrder β
c : β
⊢ ∀ {x y z : β}, x ≥ min y z ↔ x ≥ y ∨ x ≥ z

Next tactic:
intro x y z
theorem fold_min_le : s.fold min b f ≤ c ↔ b ≤ c ∨ ∃ x ∈ s, f x ≤ c := by
  show _ ≥ _ ↔ _
  apply fold_op_rel_iff_or
  intro x y z
  

Proof state:
case hr
α : Type u_1
β : Type u_2
γ : Type u_3
op : β → β → β
hc : IsCommutative β op
ha : IsAssociative β op
f : α → β
b : β
s : Finset α
a : α
inst✝ : LinearOrder β
c x y z : β
⊢ x ≥ min y z ↔ x ≥ y ∨ x ≥ z

Next tactic:
show _ ≤ _ ↔ _
theorem fold_min_le : s.fold min b f ≤ c ↔ b ≤ c ∨ ∃ x ∈ s, f x ≤ c := by
  show _ ≥ _ ↔ _
  apply fold_op_rel_iff_or
  intro x y z
  show _ ≤ _ ↔ _
  

Proof state:
case hr
α : Type u_1
β : Type u_2
γ : Type u_3
op : β → β → β
hc : IsCommutative β op
ha : IsAssociative β op
f : α → β
b : β
s : Finset α
a : α
inst✝ : LinearOrder β
c x y z : β
⊢ min y z ≤ x ↔ x ≥ y ∨ x ≥ z

Next tactic:
exact min_le_iff
theorem fold_min_lt : s.fold min b f < c ↔ b < c ∨ ∃ x ∈ s, f x < c := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
op : β → β → β
hc : IsCommutative β op
ha : IsAssociative β op
f : α → β
b : β
s : Finset α
a : α
inst✝ : LinearOrder β
c : β
⊢ fold min b f s < c ↔ b < c ∨ ∃ x ∈ s, f x < c

Next tactic:
show _ > _ ↔ _
theorem fold_min_lt : s.fold min b f < c ↔ b < c ∨ ∃ x ∈ s, f x < c := by
  show _ > _ ↔ _
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
op : β → β → β
hc : IsCommutative β op
ha : IsAssociative β op
f : α → β
b : β
s : Finset α
a : α
inst✝ : LinearOrder β
c : β
⊢ c > fold min b f s ↔ b < c ∨ ∃ x ∈ s, f x < c

Next tactic:
apply fold_op_rel_iff_or
theorem fold_min_lt : s.fold min b f < c ↔ b < c ∨ ∃ x ∈ s, f x < c := by
  show _ > _ ↔ _
  apply fold_op_rel_iff_or
  

Proof state:
case hr
α : Type u_1
β : Type u_2
γ : Type u_3
op : β → β → β
hc : IsCommutative β op
ha : IsAssociative β op
f : α → β
b : β
s : Finset α
a : α
inst✝ : LinearOrder β
c : β
⊢ ∀ {x y z : β}, x > min y z ↔ x > y ∨ x > z

Next tactic:
intro x y z
theorem fold_min_lt : s.fold min b f < c ↔ b < c ∨ ∃ x ∈ s, f x < c := by
  show _ > _ ↔ _
  apply fold_op_rel_iff_or
  intro x y z
  

Proof state:
case hr
α : Type u_1
β : Type u_2
γ : Type u_3
op : β → β → β
hc : IsCommutative β op
ha : IsAssociative β op
f : α → β
b : β
s : Finset α
a : α
inst✝ : LinearOrder β
c x y z : β
⊢ x > min y z ↔ x > y ∨ x > z

Next tactic:
show _ < _ ↔ _
theorem fold_min_lt : s.fold min b f < c ↔ b < c ∨ ∃ x ∈ s, f x < c := by
  show _ > _ ↔ _
  apply fold_op_rel_iff_or
  intro x y z
  show _ < _ ↔ _
  

Proof state:
case hr
α : Type u_1
β : Type u_2
γ : Type u_3
op : β → β → β
hc : IsCommutative β op
ha : IsAssociative β op
f : α → β
b : β
s : Finset α
a : α
inst✝ : LinearOrder β
c x y z : β
⊢ min y z < x ↔ x > y ∨ x > z

Next tactic:
exact min_lt_iff
theorem fold_max_le : s.fold max b f ≤ c ↔ b ≤ c ∧ ∀ x ∈ s, f x ≤ c := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
op : β → β → β
hc : IsCommutative β op
ha : IsAssociative β op
f : α → β
b : β
s : Finset α
a : α
inst✝ : LinearOrder β
c : β
⊢ fold max b f s ≤ c ↔ b ≤ c ∧ ∀ x ∈ s, f x ≤ c

Next tactic:
show _ ≥ _ ↔ _
theorem fold_max_le : s.fold max b f ≤ c ↔ b ≤ c ∧ ∀ x ∈ s, f x ≤ c := by
  show _ ≥ _ ↔ _
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
op : β → β → β
hc : IsCommutative β op
ha : IsAssociative β op
f : α → β
b : β
s : Finset α
a : α
inst✝ : LinearOrder β
c : β
⊢ c ≥ fold max b f s ↔ b ≤ c ∧ ∀ x ∈ s, f x ≤ c

Next tactic:
apply fold_op_rel_iff_and
theorem fold_max_le : s.fold max b f ≤ c ↔ b ≤ c ∧ ∀ x ∈ s, f x ≤ c := by
  show _ ≥ _ ↔ _
  apply fold_op_rel_iff_and
  

Proof state:
case hr
α : Type u_1
β : Type u_2
γ : Type u_3
op : β → β → β
hc : IsCommutative β op
ha : IsAssociative β op
f : α → β
b : β
s : Finset α
a : α
inst✝ : LinearOrder β
c : β
⊢ ∀ {x y z : β}, x ≥ max y z ↔ x ≥ y ∧ x ≥ z

Next tactic:
intro x y z
theorem fold_max_le : s.fold max b f ≤ c ↔ b ≤ c ∧ ∀ x ∈ s, f x ≤ c := by
  show _ ≥ _ ↔ _
  apply fold_op_rel_iff_and
  intro x y z
  

Proof state:
case hr
α : Type u_1
β : Type u_2
γ : Type u_3
op : β → β → β
hc : IsCommutative β op
ha : IsAssociative β op
f : α → β
b : β
s : Finset α
a : α
inst✝ : LinearOrder β
c x y z : β
⊢ x ≥ max y z ↔ x ≥ y ∧ x ≥ z

Next tactic:
show _ ≤ _ ↔ _
theorem fold_max_le : s.fold max b f ≤ c ↔ b ≤ c ∧ ∀ x ∈ s, f x ≤ c := by
  show _ ≥ _ ↔ _
  apply fold_op_rel_iff_and
  intro x y z
  show _ ≤ _ ↔ _
  

Proof state:
case hr
α : Type u_1
β : Type u_2
γ : Type u_3
op : β → β → β
hc : IsCommutative β op
ha : IsAssociative β op
f : α → β
b : β
s : Finset α
a : α
inst✝ : LinearOrder β
c x y z : β
⊢ max y z ≤ x ↔ x ≥ y ∧ x ≥ z

Next tactic:
exact max_le_iff
theorem fold_max_lt : s.fold max b f < c ↔ b < c ∧ ∀ x ∈ s, f x < c := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
op : β → β → β
hc : IsCommutative β op
ha : IsAssociative β op
f : α → β
b : β
s : Finset α
a : α
inst✝ : LinearOrder β
c : β
⊢ fold max b f s < c ↔ b < c ∧ ∀ x ∈ s, f x < c

Next tactic:
show _ > _ ↔ _
theorem fold_max_lt : s.fold max b f < c ↔ b < c ∧ ∀ x ∈ s, f x < c := by
  show _ > _ ↔ _
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
op : β → β → β
hc : IsCommutative β op
ha : IsAssociative β op
f : α → β
b : β
s : Finset α
a : α
inst✝ : LinearOrder β
c : β
⊢ c > fold max b f s ↔ b < c ∧ ∀ x ∈ s, f x < c

Next tactic:
apply fold_op_rel_iff_and
theorem fold_max_lt : s.fold max b f < c ↔ b < c ∧ ∀ x ∈ s, f x < c := by
  show _ > _ ↔ _
  apply fold_op_rel_iff_and
  

Proof state:
case hr
α : Type u_1
β : Type u_2
γ : Type u_3
op : β → β → β
hc : IsCommutative β op
ha : IsAssociative β op
f : α → β
b : β
s : Finset α
a : α
inst✝ : LinearOrder β
c : β
⊢ ∀ {x y z : β}, x > max y z ↔ x > y ∧ x > z

Next tactic:
intro x y z
theorem fold_max_lt : s.fold max b f < c ↔ b < c ∧ ∀ x ∈ s, f x < c := by
  show _ > _ ↔ _
  apply fold_op_rel_iff_and
  intro x y z
  

Proof state:
case hr
α : Type u_1
β : Type u_2
γ : Type u_3
op : β → β → β
hc : IsCommutative β op
ha : IsAssociative β op
f : α → β
b : β
s : Finset α
a : α
inst✝ : LinearOrder β
c x y z : β
⊢ x > max y z ↔ x > y ∧ x > z

Next tactic:
show _ < _ ↔ _
theorem fold_max_lt : s.fold max b f < c ↔ b < c ∧ ∀ x ∈ s, f x < c := by
  show _ > _ ↔ _
  apply fold_op_rel_iff_and
  intro x y z
  show _ < _ ↔ _
  

Proof state:
case hr
α : Type u_1
β : Type u_2
γ : Type u_3
op : β → β → β
hc : IsCommutative β op
ha : IsAssociative β op
f : α → β
b : β
s : Finset α
a : α
inst✝ : LinearOrder β
c x y z : β
⊢ max y z < x ↔ x > y ∧ x > z

Next tactic:
exact max_lt_iff
theorem fold_max_add [Add β] [CovariantClass β β (Function.swap (· + ·)) (· ≤ ·)] (n : WithBot β)
    (s : Finset α) : (s.fold max ⊥ fun x : α => ↑(f x) + n) = s.fold max ⊥ ((↑) ∘ f) + n := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
op : β → β → β
hc : IsCommutative β op
ha : IsAssociative β op
f : α → β
b : β
s✝ : Finset α
a : α
inst✝² : LinearOrder β
c : β
inst✝¹ : Add β
inst✝ : CovariantClass β β (Function.swap fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
n : WithBot β
s : Finset α
⊢ fold max ⊥ (fun x => ↑(f x) + n) s = fold max ⊥ (WithBot.some ∘ f) s + n

Next tactic:
classical
    induction' s using Finset.induction_on with a s _ ih <;> simp [*, max_add_add_right]
theorem fold_max_add [Add β] [CovariantClass β β (Function.swap (· + ·)) (· ≤ ·)] (n : WithBot β)
    (s : Finset α) : (s.fold max ⊥ fun x : α => ↑(f x) + n) = s.fold max ⊥ ((↑) ∘ f) + n := by
  classical
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
op : β → β → β
hc : IsCommutative β op
ha : IsAssociative β op
f : α → β
b : β
s✝ : Finset α
a : α
inst✝² : LinearOrder β
c : β
inst✝¹ : Add β
inst✝ : CovariantClass β β (Function.swap fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
n : WithBot β
s : Finset α
⊢ fold max ⊥ (fun x => ↑(f x) + n) s = fold max ⊥ (WithBot.some ∘ f) s + n

Next tactic:
induction' s using Finset.induction_on with a s _ ih
theorem fold_max_add [Add β] [CovariantClass β β (Function.swap (· + ·)) (· ≤ ·)] (n : WithBot β)
    (s : Finset α) : (s.fold max ⊥ fun x : α => ↑(f x) + n) = s.fold max ⊥ ((↑) ∘ f) + n := by
  classical
    induction' s using Finset.induction_on with a s _ ih <;> 

Proof state:
case empty
α : Type u_1
β : Type u_2
γ : Type u_3
op : β → β → β
hc : IsCommutative β op
ha : IsAssociative β op
f : α → β
b : β
s : Finset α
a : α
inst✝² : LinearOrder β
c : β
inst✝¹ : Add β
inst✝ : CovariantClass β β (Function.swap fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
n : WithBot β
⊢ fold max ⊥ (fun x => ↑(f x) + n) ∅ = fold max ⊥ (WithBot.some ∘ f) ∅ + n

Next tactic:
simp [*, max_add_add_right]
theorem fold_max_add [Add β] [CovariantClass β β (Function.swap (· + ·)) (· ≤ ·)] (n : WithBot β)
    (s : Finset α) : (s.fold max ⊥ fun x : α => ↑(f x) + n) = s.fold max ⊥ ((↑) ∘ f) + n := by
  classical
    induction' s using Finset.induction_on with a s _ ih <;> 

Proof state:
case insert
α : Type u_1
β : Type u_2
γ : Type u_3
op : β → β → β
hc : IsCommutative β op
ha : IsAssociative β op
f : α → β
b : β
s✝ : Finset α
a✝¹ : α
inst✝² : LinearOrder β
c : β
inst✝¹ : Add β
inst✝ : CovariantClass β β (Function.swap fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
n : WithBot β
a : α
s : Finset α
a✝ : a ∉ s
ih : fold max ⊥ (fun x => ↑(f x) + n) s = fold max ⊥ (WithBot.some ∘ f) s + n
⊢ fold max ⊥ (fun x => ↑(f x) + n) (insert a s) = fold max ⊥ (WithBot.some ∘ f) (insert a s) + n

Next tactic:
simp [*, max_add_add_right]
@[simp]
lemma zero_hom_app_obj (X : C) :
    (zero F s i hF).hom.app (F.obj X) =
      (i 0).hom.app X ≫ F.map ((shiftFunctorZero C A).hom.app X) := by
  

Proof state:
C : Type u_5
D : Type u_2
inst✝³ : Category.{u_4, u_5} C
inst✝² : Category.{u_1, u_2} D
F : C ⥤ D
A : Type u_3
inst✝¹ : AddMonoid A
inst✝ : HasShift C A
s : A → D ⥤ D
i : (a : A) → F ⋙ s a ≅ shiftFunctor C a ⋙ F
hF : Nonempty (Full ((whiskeringLeft C D D).obj F)) ∧ Faithful ((whiskeringLeft C D D).obj F)
X : C
⊢ (zero F s i hF).hom.app (F.obj X) = (i 0).hom.app X ≫ F.map ((shiftFunctorZero C A).hom.app X)

Next tactic:
letI := hF.1.some
@[simp]
lemma zero_hom_app_obj (X : C) :
    (zero F s i hF).hom.app (F.obj X) =
      (i 0).hom.app X ≫ F.map ((shiftFunctorZero C A).hom.app X) := by
  letI := hF.1.some
  

Proof state:
C : Type u_5
D : Type u_2
inst✝³ : Category.{u_4, u_5} C
inst✝² : Category.{u_1, u_2} D
F : C ⥤ D
A : Type u_3
inst✝¹ : AddMonoid A
inst✝ : HasShift C A
s : A → D ⥤ D
i : (a : A) → F ⋙ s a ≅ shiftFunctor C a ⋙ F
hF : Nonempty (Full ((whiskeringLeft C D D).obj F)) ∧ Faithful ((whiskeringLeft C D D).obj F)
X : C
this : Full ((whiskeringLeft C D D).obj F) := Nonempty.some (_ : Nonempty (Full ((whiskeringLeft C D D).obj F)))
⊢ (zero F s i hF).hom.app (F.obj X) = (i 0).hom.app X ≫ F.map ((shiftFunctorZero C A).hom.app X)

Next tactic:
have h : whiskerLeft F (zero F s i hF).hom = _ :=
    ((whiskeringLeft C D D).obj F).image_preimage _
@[simp]
lemma zero_hom_app_obj (X : C) :
    (zero F s i hF).hom.app (F.obj X) =
      (i 0).hom.app X ≫ F.map ((shiftFunctorZero C A).hom.app X) := by
  letI := hF.1.some
  have h : whiskerLeft F (zero F s i hF).hom = _ :=
    ((whiskeringLeft C D D).obj F).image_preimage _
  

Proof state:
C : Type u_5
D : Type u_2
inst✝³ : Category.{u_4, u_5} C
inst✝² : Category.{u_1, u_2} D
F : C ⥤ D
A : Type u_3
inst✝¹ : AddMonoid A
inst✝ : HasShift C A
s : A → D ⥤ D
i : (a : A) → F ⋙ s a ≅ shiftFunctor C a ⋙ F
hF : Nonempty (Full ((whiskeringLeft C D D).obj F)) ∧ Faithful ((whiskeringLeft C D D).obj F)
X : C
this : Full ((whiskeringLeft C D D).obj F) := Nonempty.some (_ : Nonempty (Full ((whiskeringLeft C D D).obj F)))
h :
  whiskerLeft F (zero F s i hF).hom =
    (i 0 ≪≫ isoWhiskerRight (shiftFunctorZero C A) F ≪≫ Functor.leftUnitor F ≪≫ (Functor.rightUnitor F).symm).hom
⊢ (zero F s i hF).hom.app (F.obj X) = (i 0).hom.app X ≫ F.map ((shiftFunctorZero C A).hom.app X)

Next tactic:
exact (NatTrans.congr_app h X).trans (by simp)