l3lab/ntp-mathlib huggingface dataset:
@[norm_cast] -- @[simp] -- Porting note: simp can prove this
theorem int_cast_inj {m n : ℤ} {R : Type*} [Ring R] [CharZero R] : (↑m : R[X]) = ↑n ↔ m = n := by
  constructor
  · intro h
    apply_fun fun p => p.coeff 0 at h
    simpa using h
  · rintro rfl
    

Proof state:
case mpr
R✝ : Type u
S : Type v
a b : R✝
n m✝ : ℕ
inst✝² : Semiring R✝
p q r : R✝[X]
m : ℤ
R : Type u_1
inst✝¹ : Ring R
inst✝ : CharZero R
⊢ ↑m = ↑m

Next tactic:
rfl
instance : ContinuousOpenMapClass (α →CO β) α β where
  coe f := f.toFun
  coe_injective' f g h := by
    

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
δ : Type u_5
inst✝³ : TopologicalSpace α
inst✝² : TopologicalSpace β
inst✝¹ : TopologicalSpace γ
inst✝ : TopologicalSpace δ
f g : α →CO β
h : (fun f => f.toFun) f = (fun f => f.toFun) g
⊢ f = g

Next tactic:
obtain ⟨⟨_, _⟩, _⟩ := f
instance : ContinuousOpenMapClass (α →CO β) α β where
  coe f := f.toFun
  coe_injective' f g h := by
    obtain ⟨⟨_, _⟩, _⟩ := f
    

Proof state:
case mk.mk
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
δ : Type u_5
inst✝³ : TopologicalSpace α
inst✝² : TopologicalSpace β
inst✝¹ : TopologicalSpace γ
inst✝ : TopologicalSpace δ
g : α →CO β
toFun✝ : α → β
continuous_toFun✝ : Continuous toFun✝
map_open'✝ : IsOpenMap (ContinuousMap.mk toFun✝).toFun
h : (fun f => f.toFun) { toContinuousMap := ContinuousMap.mk toFun✝, map_open' := map_open'✝ } = (fun f => f.toFun) g
⊢ { toContinuousMap := ContinuousMap.mk toFun✝, map_open' := map_open'✝ } = g

Next tactic:
obtain ⟨⟨_, _⟩, _⟩ := g
instance : ContinuousOpenMapClass (α →CO β) α β where
  coe f := f.toFun
  coe_injective' f g h := by
    obtain ⟨⟨_, _⟩, _⟩ := f
    obtain ⟨⟨_, _⟩, _⟩ := g
    

Proof state:
case mk.mk.mk.mk
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
δ : Type u_5
inst✝³ : TopologicalSpace α
inst✝² : TopologicalSpace β
inst✝¹ : TopologicalSpace γ
inst✝ : TopologicalSpace δ
toFun✝¹ : α → β
continuous_toFun✝¹ : Continuous toFun✝¹
map_open'✝¹ : IsOpenMap (ContinuousMap.mk toFun✝¹).toFun
toFun✝ : α → β
continuous_toFun✝ : Continuous toFun✝
map_open'✝ : IsOpenMap (ContinuousMap.mk toFun✝).toFun
h :
  (fun f => f.toFun) { toContinuousMap := ContinuousMap.mk toFun✝¹, map_open' := map_open'✝¹ } =
    (fun f => f.toFun) { toContinuousMap := ContinuousMap.mk toFun✝, map_open' := map_open'✝ }
⊢ { toContinuousMap := ContinuousMap.mk toFun✝¹, map_open' := map_open'✝¹ } =
    { toContinuousMap := ContinuousMap.mk toFun✝, map_open' := map_open'✝ }

Next tactic:
congr
@[simp]
theorem cancel_left {g : β →CO γ} {f₁ f₂ : α →CO β} (hg : Injective g) :
    g.comp f₁ = g.comp f₂ ↔ f₁ = f₂ :=
  ⟨fun h => ext fun a => hg <| by 

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
δ : Type u_5
inst✝³ : TopologicalSpace α
inst✝² : TopologicalSpace β
inst✝¹ : TopologicalSpace γ
inst✝ : TopologicalSpace δ
g : β →CO γ
f₁ f₂ : α →CO β
hg : Injective ⇑g
h : comp g f₁ = comp g f₂
a : α
⊢ g (f₁ a) = g (f₂ a)

Next tactic:
rw [← comp_apply, h, comp_apply]
theorem equitableOn_iff_exists_le_le_add_one {s : Set α} {f : α → ℕ} :
    s.EquitableOn f ↔ ∃ b, ∀ a ∈ s, b ≤ f a ∧ f a ≤ b + 1 := by
  

Proof state:
α : Type u_1
β : Type u_2
s : Set α
f : α → ℕ
⊢ EquitableOn s f ↔ ∃ b, ∀ a ∈ s, b ≤ f a ∧ f a ≤ b + 1

Next tactic:
refine' ⟨_, fun ⟨b, hb⟩ x y hx hy => (hb x hx).2.trans (add_le_add_right (hb y hy).1 _)⟩
theorem equitableOn_iff_exists_le_le_add_one {s : Set α} {f : α → ℕ} :
    s.EquitableOn f ↔ ∃ b, ∀ a ∈ s, b ≤ f a ∧ f a ≤ b + 1 := by
  refine' ⟨_, fun ⟨b, hb⟩ x y hx hy => (hb x hx).2.trans (add_le_add_right (hb y hy).1 _)⟩
  

Proof state:
α : Type u_1
β : Type u_2
s : Set α
f : α → ℕ
⊢ EquitableOn s f → ∃ b, ∀ a ∈ s, b ≤ f a ∧ f a ≤ b + 1

Next tactic:
obtain rfl | ⟨x, hx⟩ := s.eq_empty_or_nonempty
theorem equitableOn_iff_exists_le_le_add_one {s : Set α} {f : α → ℕ} :
    s.EquitableOn f ↔ ∃ b, ∀ a ∈ s, b ≤ f a ∧ f a ≤ b + 1 := by
  refine' ⟨_, fun ⟨b, hb⟩ x y hx hy => (hb x hx).2.trans (add_le_add_right (hb y hy).1 _)⟩
  obtain rfl | ⟨x, hx⟩ := s.eq_empty_or_nonempty
  · 

Proof state:
case inl
α : Type u_1
β : Type u_2
f : α → ℕ
⊢ EquitableOn ∅ f → ∃ b, ∀ a ∈ ∅, b ≤ f a ∧ f a ≤ b + 1

Next tactic:
simp
theorem equitableOn_iff_exists_le_le_add_one {s : Set α} {f : α → ℕ} :
    s.EquitableOn f ↔ ∃ b, ∀ a ∈ s, b ≤ f a ∧ f a ≤ b + 1 := by
  refine' ⟨_, fun ⟨b, hb⟩ x y hx hy => (hb x hx).2.trans (add_le_add_right (hb y hy).1 _)⟩
  obtain rfl | ⟨x, hx⟩ := s.eq_empty_or_nonempty
  · simp
  

Proof state:
case inr.intro
α : Type u_1
β : Type u_2
s : Set α
f : α → ℕ
x : α
hx : x ∈ s
⊢ EquitableOn s f → ∃ b, ∀ a ∈ s, b ≤ f a ∧ f a ≤ b + 1

Next tactic:
intro hs
theorem equitableOn_iff_exists_le_le_add_one {s : Set α} {f : α → ℕ} :
    s.EquitableOn f ↔ ∃ b, ∀ a ∈ s, b ≤ f a ∧ f a ≤ b + 1 := by
  refine' ⟨_, fun ⟨b, hb⟩ x y hx hy => (hb x hx).2.trans (add_le_add_right (hb y hy).1 _)⟩
  obtain rfl | ⟨x, hx⟩ := s.eq_empty_or_nonempty
  · simp
  intro hs
  

Proof state:
case inr.intro
α : Type u_1
β : Type u_2
s : Set α
f : α → ℕ
x : α
hx : x ∈ s
hs : EquitableOn s f
⊢ ∃ b, ∀ a ∈ s, b ≤ f a ∧ f a ≤ b + 1

Next tactic:
by_cases h : ∀ y ∈ s, f x ≤ f y
theorem equitableOn_iff_exists_le_le_add_one {s : Set α} {f : α → ℕ} :
    s.EquitableOn f ↔ ∃ b, ∀ a ∈ s, b ≤ f a ∧ f a ≤ b + 1 := by
  refine' ⟨_, fun ⟨b, hb⟩ x y hx hy => (hb x hx).2.trans (add_le_add_right (hb y hy).1 _)⟩
  obtain rfl | ⟨x, hx⟩ := s.eq_empty_or_nonempty
  · simp
  intro hs
  by_cases h : ∀ y ∈ s, f x ≤ f y
  · 

Proof state:
case pos
α : Type u_1
β : Type u_2
s : Set α
f : α → ℕ
x : α
hx : x ∈ s
hs : EquitableOn s f
h : ∀ y ∈ s, f x ≤ f y
⊢ ∃ b, ∀ a ∈ s, b ≤ f a ∧ f a ≤ b + 1

Next tactic:
exact ⟨f x, fun y hy => ⟨h _ hy, hs hy hx⟩⟩
theorem equitableOn_iff_exists_le_le_add_one {s : Set α} {f : α → ℕ} :
    s.EquitableOn f ↔ ∃ b, ∀ a ∈ s, b ≤ f a ∧ f a ≤ b + 1 := by
  refine' ⟨_, fun ⟨b, hb⟩ x y hx hy => (hb x hx).2.trans (add_le_add_right (hb y hy).1 _)⟩
  obtain rfl | ⟨x, hx⟩ := s.eq_empty_or_nonempty
  · simp
  intro hs
  by_cases h : ∀ y ∈ s, f x ≤ f y
  · exact ⟨f x, fun y hy => ⟨h _ hy, hs hy hx⟩⟩
  

Proof state:
case neg
α : Type u_1
β : Type u_2
s : Set α
f : α → ℕ
x : α
hx : x ∈ s
hs : EquitableOn s f
h : ¬∀ y ∈ s, f x ≤ f y
⊢ ∃ b, ∀ a ∈ s, b ≤ f a ∧ f a ≤ b + 1

Next tactic:
push_neg at h
theorem equitableOn_iff_exists_le_le_add_one {s : Set α} {f : α → ℕ} :
    s.EquitableOn f ↔ ∃ b, ∀ a ∈ s, b ≤ f a ∧ f a ≤ b + 1 := by
  refine' ⟨_, fun ⟨b, hb⟩ x y hx hy => (hb x hx).2.trans (add_le_add_right (hb y hy).1 _)⟩
  obtain rfl | ⟨x, hx⟩ := s.eq_empty_or_nonempty
  · simp
  intro hs
  by_cases h : ∀ y ∈ s, f x ≤ f y
  · exact ⟨f x, fun y hy => ⟨h _ hy, hs hy hx⟩⟩
  push_neg at h
  

Proof state:
case neg
α : Type u_1
β : Type u_2
s : Set α
f : α → ℕ
x : α
hx : x ∈ s
hs : EquitableOn s f
h : ∃ y ∈ s, f y < f x
⊢ ∃ b, ∀ a ∈ s, b ≤ f a ∧ f a ≤ b + 1

Next tactic:
obtain ⟨w, hw, hwx⟩ := h
theorem equitableOn_iff_exists_le_le_add_one {s : Set α} {f : α → ℕ} :
    s.EquitableOn f ↔ ∃ b, ∀ a ∈ s, b ≤ f a ∧ f a ≤ b + 1 := by
  refine' ⟨_, fun ⟨b, hb⟩ x y hx hy => (hb x hx).2.trans (add_le_add_right (hb y hy).1 _)⟩
  obtain rfl | ⟨x, hx⟩ := s.eq_empty_or_nonempty
  · simp
  intro hs
  by_cases h : ∀ y ∈ s, f x ≤ f y
  · exact ⟨f x, fun y hy => ⟨h _ hy, hs hy hx⟩⟩
  push_neg at h
  obtain ⟨w, hw, hwx⟩ := h
  

Proof state:
case neg.intro.intro
α : Type u_1
β : Type u_2
s : Set α
f : α → ℕ
x : α
hx : x ∈ s
hs : EquitableOn s f
w : α
hw : w ∈ s
hwx : f w < f x
⊢ ∃ b, ∀ a ∈ s, b ≤ f a ∧ f a ≤ b + 1

Next tactic:
refine' ⟨f w, fun y hy => ⟨Nat.le_of_succ_le_succ _, hs hy hw⟩⟩
theorem equitableOn_iff_exists_le_le_add_one {s : Set α} {f : α → ℕ} :
    s.EquitableOn f ↔ ∃ b, ∀ a ∈ s, b ≤ f a ∧ f a ≤ b + 1 := by
  refine' ⟨_, fun ⟨b, hb⟩ x y hx hy => (hb x hx).2.trans (add_le_add_right (hb y hy).1 _)⟩
  obtain rfl | ⟨x, hx⟩ := s.eq_empty_or_nonempty
  · simp
  intro hs
  by_cases h : ∀ y ∈ s, f x ≤ f y
  · exact ⟨f x, fun y hy => ⟨h _ hy, hs hy hx⟩⟩
  push_neg at h
  obtain ⟨w, hw, hwx⟩ := h
  refine' ⟨f w, fun y hy => ⟨Nat.le_of_succ_le_succ _, hs hy hw⟩⟩
  

Proof state:
case neg.intro.intro
α : Type u_1
β : Type u_2
s : Set α
f : α → ℕ
x : α
hx : x ∈ s
hs : EquitableOn s f
w : α
hw : w ∈ s
hwx : f w < f x
y : α
hy : y ∈ s
⊢ Nat.succ (f w) ≤ Nat.succ (f y)

Next tactic:
rw [(Nat.succ_le_of_lt hwx).antisymm (hs hx hw)]
theorem equitableOn_iff_exists_le_le_add_one {s : Set α} {f : α → ℕ} :
    s.EquitableOn f ↔ ∃ b, ∀ a ∈ s, b ≤ f a ∧ f a ≤ b + 1 := by
  refine' ⟨_, fun ⟨b, hb⟩ x y hx hy => (hb x hx).2.trans (add_le_add_right (hb y hy).1 _)⟩
  obtain rfl | ⟨x, hx⟩ := s.eq_empty_or_nonempty
  · simp
  intro hs
  by_cases h : ∀ y ∈ s, f x ≤ f y
  · exact ⟨f x, fun y hy => ⟨h _ hy, hs hy hx⟩⟩
  push_neg at h
  obtain ⟨w, hw, hwx⟩ := h
  refine' ⟨f w, fun y hy => ⟨Nat.le_of_succ_le_succ _, hs hy hw⟩⟩
  rw [(Nat.succ_le_of_lt hwx).antisymm (hs hx hw)]
  

Proof state:
case neg.intro.intro
α : Type u_1
β : Type u_2
s : Set α
f : α → ℕ
x : α
hx : x ∈ s
hs : EquitableOn s f
w : α
hw : w ∈ s
hwx : f w < f x
y : α
hy : y ∈ s
⊢ f x ≤ Nat.succ (f y)

Next tactic:
exact hs hx hy
theorem equitableOn_iff_exists_image_subset_icc {s : Set α} {f : α → ℕ} :
    s.EquitableOn f ↔ ∃ b, f '' s ⊆ Icc b (b + 1) := by
  

Proof state:
α : Type u_1
β : Type u_2
s : Set α
f : α → ℕ
⊢ EquitableOn s f ↔ ∃ b, f '' s ⊆ Icc b (b + 1)

Next tactic:
simpa only [image_subset_iff] using equitableOn_iff_exists_le_le_add_one
theorem equitableOn_iff_exists_eq_eq_add_one {s : Set α} {f : α → ℕ} :
    s.EquitableOn f ↔ ∃ b, ∀ a ∈ s, f a = b ∨ f a = b + 1 := by
  

Proof state:
α : Type u_1
β : Type u_2
s : Set α
f : α → ℕ
⊢ EquitableOn s f ↔ ∃ b, ∀ a ∈ s, f a = b ∨ f a = b + 1

Next tactic:
simp_rw [equitableOn_iff_exists_le_le_add_one, Nat.le_and_le_add_one_iff]
@[simp]
lemma not_equitableOn : ¬s.EquitableOn f ↔ ∃ a ∈ s, ∃ b ∈ s, f b + 1 < f a := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝² : LinearOrder β
inst✝¹ : Add β
inst✝ : One β
s : Set α
f : α → β
⊢ ¬EquitableOn s f ↔ ∃ a ∈ s, ∃ b ∈ s, f b + 1 < f a

Next tactic:
simp [EquitableOn]
@[simp]
lemma not_equitableOn : ¬s.EquitableOn f ↔ ∃ a ∈ s, ∃ b ∈ s, f b + 1 < f a := by
  simp [EquitableOn]; 

Proof state:
α : Type u_1
β : Type u_2
inst✝² : LinearOrder β
inst✝¹ : Add β
inst✝ : One β
s : Set α
f : α → β
⊢ (∃ x, ∃ x_1 ∈ s, x ∈ s ∧ f x_1 + 1 < f x) ↔ ∃ a ∈ s, ∃ b ∈ s, f b + 1 < f a

Next tactic:
aesop
theorem Subsingleton.equitableOn {s : Set α} (hs : s.Subsingleton) (f : α → β) : s.EquitableOn f :=
  fun i j hi hj => by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝ : OrderedSemiring β
s : Set α
hs : Set.Subsingleton s
f : α → β
i j : α
hi : i ∈ s
hj : j ∈ s
⊢ f i ≤ f j + 1

Next tactic:
rw [hs hi hj]
theorem Subsingleton.equitableOn {s : Set α} (hs : s.Subsingleton) (f : α → β) : s.EquitableOn f :=
  fun i j hi hj => by
  rw [hs hi hj]
  

Proof state:
α : Type u_1
β : Type u_2
inst✝ : OrderedSemiring β
s : Set α
hs : Set.Subsingleton s
f : α → β
i j : α
hi : i ∈ s
hj : j ∈ s
⊢ f j ≤ f j + 1

Next tactic:
exact le_add_of_nonneg_right zero_le_one
theorem equitableOn_iff_le_le_add_one :
    EquitableOn (s : Set α) f ↔
      ∀ a ∈ s, (∑ i in s, f i) / s.card ≤ f a ∧ f a ≤ (∑ i in s, f i) / s.card + 1 := by
  

Proof state:
α : Type u_1
β : Type u_2
s : Finset α
f : α → ℕ
a : α
⊢ EquitableOn (↑s) f ↔ ∀ a ∈ s, (∑ i in s, f i) / card s ≤ f a ∧ f a ≤ (∑ i in s, f i) / card s + 1

Next tactic:
rw [Set.equitableOn_iff_exists_le_le_add_one]
theorem equitableOn_iff_le_le_add_one :
    EquitableOn (s : Set α) f ↔
      ∀ a ∈ s, (∑ i in s, f i) / s.card ≤ f a ∧ f a ≤ (∑ i in s, f i) / s.card + 1 := by
  rw [Set.equitableOn_iff_exists_le_le_add_one]
  

Proof state:
α : Type u_1
β : Type u_2
s : Finset α
f : α → ℕ
a : α
⊢ (∃ b, ∀ a ∈ ↑s, b ≤ f a ∧ f a ≤ b + 1) ↔ ∀ a ∈ s, (∑ i in s, f i) / card s ≤ f a ∧ f a ≤ (∑ i in s, f i) / card s + 1

Next tactic:
refine' ⟨_, fun h => ⟨_, h⟩⟩
theorem equitableOn_iff_le_le_add_one :
    EquitableOn (s : Set α) f ↔
      ∀ a ∈ s, (∑ i in s, f i) / s.card ≤ f a ∧ f a ≤ (∑ i in s, f i) / s.card + 1 := by
  rw [Set.equitableOn_iff_exists_le_le_add_one]
  refine' ⟨_, fun h => ⟨_, h⟩⟩
  

Proof state:
α : Type u_1
β : Type u_2
s : Finset α
f : α → ℕ
a : α
⊢ (∃ b, ∀ a ∈ ↑s, b ≤ f a ∧ f a ≤ b + 1) → ∀ a ∈ s, (∑ i in s, f i) / card s ≤ f a ∧ f a ≤ (∑ i in s, f i) / card s + 1

Next tactic:
rintro ⟨b, hb⟩
theorem equitableOn_iff_le_le_add_one :
    EquitableOn (s : Set α) f ↔
      ∀ a ∈ s, (∑ i in s, f i) / s.card ≤ f a ∧ f a ≤ (∑ i in s, f i) / s.card + 1 := by
  rw [Set.equitableOn_iff_exists_le_le_add_one]
  refine' ⟨_, fun h => ⟨_, h⟩⟩
  rintro ⟨b, hb⟩
  

Proof state:
case intro
α : Type u_1
β : Type u_2
s : Finset α
f : α → ℕ
a : α
b : ℕ
hb : ∀ a ∈ ↑s, b ≤ f a ∧ f a ≤ b + 1
⊢ ∀ a ∈ s, (∑ i in s, f i) / card s ≤ f a ∧ f a ≤ (∑ i in s, f i) / card s + 1

Next tactic:
by_cases h : ∀ a ∈ s, f a = b + 1
theorem equitableOn_iff_le_le_add_one :
    EquitableOn (s : Set α) f ↔
      ∀ a ∈ s, (∑ i in s, f i) / s.card ≤ f a ∧ f a ≤ (∑ i in s, f i) / s.card + 1 := by
  rw [Set.equitableOn_iff_exists_le_le_add_one]
  refine' ⟨_, fun h => ⟨_, h⟩⟩
  rintro ⟨b, hb⟩
  by_cases h : ∀ a ∈ s, f a = b + 1
  · 

Proof state:
case pos
α : Type u_1
β : Type u_2
s : Finset α
f : α → ℕ
a : α
b : ℕ
hb : ∀ a ∈ ↑s, b ≤ f a ∧ f a ≤ b + 1
h : ∀ a ∈ s, f a = b + 1
⊢ ∀ a ∈ s, (∑ i in s, f i) / card s ≤ f a ∧ f a ≤ (∑ i in s, f i) / card s + 1

Next tactic:
intro a ha
theorem equitableOn_iff_le_le_add_one :
    EquitableOn (s : Set α) f ↔
      ∀ a ∈ s, (∑ i in s, f i) / s.card ≤ f a ∧ f a ≤ (∑ i in s, f i) / s.card + 1 := by
  rw [Set.equitableOn_iff_exists_le_le_add_one]
  refine' ⟨_, fun h => ⟨_, h⟩⟩
  rintro ⟨b, hb⟩
  by_cases h : ∀ a ∈ s, f a = b + 1
  · intro a ha
    

Proof state:
case pos
α : Type u_1
β : Type u_2
s : Finset α
f : α → ℕ
a✝ : α
b : ℕ
hb : ∀ a ∈ ↑s, b ≤ f a ∧ f a ≤ b + 1
h : ∀ a ∈ s, f a = b + 1
a : α
ha : a ∈ s
⊢ (∑ i in s, f i) / card s ≤ f a ∧ f a ≤ (∑ i in s, f i) / card s + 1

Next tactic:
rw [h _ ha, sum_const_nat h, Nat.mul_div_cancel_left _ (card_pos.2 ⟨a, ha⟩)]
theorem equitableOn_iff_le_le_add_one :
    EquitableOn (s : Set α) f ↔
      ∀ a ∈ s, (∑ i in s, f i) / s.card ≤ f a ∧ f a ≤ (∑ i in s, f i) / s.card + 1 := by
  rw [Set.equitableOn_iff_exists_le_le_add_one]
  refine' ⟨_, fun h => ⟨_, h⟩⟩
  rintro ⟨b, hb⟩
  by_cases h : ∀ a ∈ s, f a = b + 1
  · intro a ha
    rw [h _ ha, sum_const_nat h, Nat.mul_div_cancel_left _ (card_pos.2 ⟨a, ha⟩)]
    

Proof state:
case pos
α : Type u_1
β : Type u_2
s : Finset α
f : α → ℕ
a✝ : α
b : ℕ
hb : ∀ a ∈ ↑s, b ≤ f a ∧ f a ≤ b + 1
h : ∀ a ∈ s, f a = b + 1
a : α
ha : a ∈ s
⊢ b + 1 ≤ b + 1 ∧ b + 1 ≤ b + 1 + 1

Next tactic:
exact ⟨le_rfl, Nat.le_succ _⟩
theorem equitableOn_iff_le_le_add_one :
    EquitableOn (s : Set α) f ↔
      ∀ a ∈ s, (∑ i in s, f i) / s.card ≤ f a ∧ f a ≤ (∑ i in s, f i) / s.card + 1 := by
  rw [Set.equitableOn_iff_exists_le_le_add_one]
  refine' ⟨_, fun h => ⟨_, h⟩⟩
  rintro ⟨b, hb⟩
  by_cases h : ∀ a ∈ s, f a = b + 1
  · intro a ha
    rw [h _ ha, sum_const_nat h, Nat.mul_div_cancel_left _ (card_pos.2 ⟨a, ha⟩)]
    exact ⟨le_rfl, Nat.le_succ _⟩
  

Proof state:
case neg
α : Type u_1
β : Type u_2
s : Finset α
f : α → ℕ
a : α
b : ℕ
hb : ∀ a ∈ ↑s, b ≤ f a ∧ f a ≤ b + 1
h : ¬∀ a ∈ s, f a = b + 1
⊢ ∀ a ∈ s, (∑ i in s, f i) / card s ≤ f a ∧ f a ≤ (∑ i in s, f i) / card s + 1

Next tactic:
push_neg at h
theorem equitableOn_iff_le_le_add_one :
    EquitableOn (s : Set α) f ↔
      ∀ a ∈ s, (∑ i in s, f i) / s.card ≤ f a ∧ f a ≤ (∑ i in s, f i) / s.card + 1 := by
  rw [Set.equitableOn_iff_exists_le_le_add_one]
  refine' ⟨_, fun h => ⟨_, h⟩⟩
  rintro ⟨b, hb⟩
  by_cases h : ∀ a ∈ s, f a = b + 1
  · intro a ha
    rw [h _ ha, sum_const_nat h, Nat.mul_div_cancel_left _ (card_pos.2 ⟨a, ha⟩)]
    exact ⟨le_rfl, Nat.le_succ _⟩
  push_neg at h
  

Proof state:
case neg
α : Type u_1
β : Type u_2
s : Finset α
f : α → ℕ
a : α
b : ℕ
hb : ∀ a ∈ ↑s, b ≤ f a ∧ f a ≤ b + 1
h : ∃ a ∈ s, f a ≠ b + 1
⊢ ∀ a ∈ s, (∑ i in s, f i) / card s ≤ f a ∧ f a ≤ (∑ i in s, f i) / card s + 1

Next tactic:
obtain ⟨x, hx₁, hx₂⟩ := h
theorem equitableOn_iff_le_le_add_one :
    EquitableOn (s : Set α) f ↔
      ∀ a ∈ s, (∑ i in s, f i) / s.card ≤ f a ∧ f a ≤ (∑ i in s, f i) / s.card + 1 := by
  rw [Set.equitableOn_iff_exists_le_le_add_one]
  refine' ⟨_, fun h => ⟨_, h⟩⟩
  rintro ⟨b, hb⟩
  by_cases h : ∀ a ∈ s, f a = b + 1
  · intro a ha
    rw [h _ ha, sum_const_nat h, Nat.mul_div_cancel_left _ (card_pos.2 ⟨a, ha⟩)]
    exact ⟨le_rfl, Nat.le_succ _⟩
  push_neg at h
  obtain ⟨x, hx₁, hx₂⟩ := h
  

Proof state:
case neg.intro.intro
α : Type u_1
β : Type u_2
s : Finset α
f : α → ℕ
a : α
b : ℕ
hb : ∀ a ∈ ↑s, b ≤ f a ∧ f a ≤ b + 1
x : α
hx₁ : x ∈ s
hx₂ : f x ≠ b + 1
⊢ ∀ a ∈ s, (∑ i in s, f i) / card s ≤ f a ∧ f a ≤ (∑ i in s, f i) / card s + 1

Next tactic:
suffices h : b = (∑ i in s, f i) / s.card by
    simp_rw [← h]
    apply hb
theorem equitableOn_iff_le_le_add_one :
    EquitableOn (s : Set α) f ↔
      ∀ a ∈ s, (∑ i in s, f i) / s.card ≤ f a ∧ f a ≤ (∑ i in s, f i) / s.card + 1 := by
  rw [Set.equitableOn_iff_exists_le_le_add_one]
  refine' ⟨_, fun h => ⟨_, h⟩⟩
  rintro ⟨b, hb⟩
  by_cases h : ∀ a ∈ s, f a = b + 1
  · intro a ha
    rw [h _ ha, sum_const_nat h, Nat.mul_div_cancel_left _ (card_pos.2 ⟨a, ha⟩)]
    exact ⟨le_rfl, Nat.le_succ _⟩
  push_neg at h
  obtain ⟨x, hx₁, hx₂⟩ := h
  suffices h : b = (∑ i in s, f i) / s.card by
    

Proof state:
α : Type u_1
β : Type u_2
s : Finset α
f : α → ℕ
a : α
b : ℕ
hb : ∀ a ∈ ↑s, b ≤ f a ∧ f a ≤ b + 1
x : α
hx₁ : x ∈ s
hx₂ : f x ≠ b + 1
h : b = (∑ i in s, f i) / card s
⊢ ∀ a ∈ s, (∑ i in s, f i) / card s ≤ f a ∧ f a ≤ (∑ i in s, f i) / card s + 1

Next tactic:
simp_rw [← h]
theorem equitableOn_iff_le_le_add_one :
    EquitableOn (s : Set α) f ↔
      ∀ a ∈ s, (∑ i in s, f i) / s.card ≤ f a ∧ f a ≤ (∑ i in s, f i) / s.card + 1 := by
  rw [Set.equitableOn_iff_exists_le_le_add_one]
  refine' ⟨_, fun h => ⟨_, h⟩⟩
  rintro ⟨b, hb⟩
  by_cases h : ∀ a ∈ s, f a = b + 1
  · intro a ha
    rw [h _ ha, sum_const_nat h, Nat.mul_div_cancel_left _ (card_pos.2 ⟨a, ha⟩)]
    exact ⟨le_rfl, Nat.le_succ _⟩
  push_neg at h
  obtain ⟨x, hx₁, hx₂⟩ := h
  suffices h : b = (∑ i in s, f i) / s.card by
    simp_rw [← h]
    

Proof state:
α : Type u_1
β : Type u_2
s : Finset α
f : α → ℕ
a : α
b : ℕ
hb : ∀ a ∈ ↑s, b ≤ f a ∧ f a ≤ b + 1
x : α
hx₁ : x ∈ s
hx₂ : f x ≠ b + 1
h : b = (∑ i in s, f i) / card s
⊢ ∀ a ∈ s, b ≤ f a ∧ f a ≤ b + 1

Next tactic:
apply hb
theorem equitableOn_iff_le_le_add_one :
    EquitableOn (s : Set α) f ↔
      ∀ a ∈ s, (∑ i in s, f i) / s.card ≤ f a ∧ f a ≤ (∑ i in s, f i) / s.card + 1 := by
  rw [Set.equitableOn_iff_exists_le_le_add_one]
  refine' ⟨_, fun h => ⟨_, h⟩⟩
  rintro ⟨b, hb⟩
  by_cases h : ∀ a ∈ s, f a = b + 1
  · intro a ha
    rw [h _ ha, sum_const_nat h, Nat.mul_div_cancel_left _ (card_pos.2 ⟨a, ha⟩)]
    exact ⟨le_rfl, Nat.le_succ _⟩
  push_neg at h
  obtain ⟨x, hx₁, hx₂⟩ := h
  suffices h : b = (∑ i in s, f i) / s.card by
    simp_rw [← h]
    apply hb
  

Proof state:
case neg.intro.intro
α : Type u_1
β : Type u_2
s : Finset α
f : α → ℕ
a : α
b : ℕ
hb : ∀ a ∈ ↑s, b ≤ f a ∧ f a ≤ b + 1
x : α
hx₁ : x ∈ s
hx₂ : f x ≠ b + 1
⊢ b = (∑ i in s, f i) / card s

Next tactic:
symm
theorem equitableOn_iff_le_le_add_one :
    EquitableOn (s : Set α) f ↔
      ∀ a ∈ s, (∑ i in s, f i) / s.card ≤ f a ∧ f a ≤ (∑ i in s, f i) / s.card + 1 := by
  rw [Set.equitableOn_iff_exists_le_le_add_one]
  refine' ⟨_, fun h => ⟨_, h⟩⟩
  rintro ⟨b, hb⟩
  by_cases h : ∀ a ∈ s, f a = b + 1
  · intro a ha
    rw [h _ ha, sum_const_nat h, Nat.mul_div_cancel_left _ (card_pos.2 ⟨a, ha⟩)]
    exact ⟨le_rfl, Nat.le_succ _⟩
  push_neg at h
  obtain ⟨x, hx₁, hx₂⟩ := h
  suffices h : b = (∑ i in s, f i) / s.card by
    simp_rw [← h]
    apply hb
  symm
  

Proof state:
case neg.intro.intro
α : Type u_1
β : Type u_2
s : Finset α
f : α → ℕ
a : α
b : ℕ
hb : ∀ a ∈ ↑s, b ≤ f a ∧ f a ≤ b + 1
x : α
hx₁ : x ∈ s
hx₂ : f x ≠ b + 1
⊢ (∑ i in s, f i) / card s = b

Next tactic:
refine'
    Nat.div_eq_of_lt_le (le_trans (by simp [mul_comm]) (sum_le_sum fun a ha => (hb a ha).1))
      ((sum_lt_sum (fun a ha => (hb a ha).2) ⟨_, hx₁, (hb _ hx₁).2.lt_of_ne hx₂⟩).trans_le _)
theorem equitableOn_iff_le_le_add_one :
    EquitableOn (s : Set α) f ↔
      ∀ a ∈ s, (∑ i in s, f i) / s.card ≤ f a ∧ f a ≤ (∑ i in s, f i) / s.card + 1 := by
  rw [Set.equitableOn_iff_exists_le_le_add_one]
  refine' ⟨_, fun h => ⟨_, h⟩⟩
  rintro ⟨b, hb⟩
  by_cases h : ∀ a ∈ s, f a = b + 1
  · intro a ha
    rw [h _ ha, sum_const_nat h, Nat.mul_div_cancel_left _ (card_pos.2 ⟨a, ha⟩)]
    exact ⟨le_rfl, Nat.le_succ _⟩
  push_neg at h
  obtain ⟨x, hx₁, hx₂⟩ := h
  suffices h : b = (∑ i in s, f i) / s.card by
    simp_rw [← h]
    apply hb
  symm
  refine'
    Nat.div_eq_of_lt_le (le_trans (by 

Proof state:
α : Type u_1
β : Type u_2
s : Finset α
f : α → ℕ
a : α
b : ℕ
hb : ∀ a ∈ ↑s, b ≤ f a ∧ f a ≤ b + 1
x : α
hx₁ : x ∈ s
hx₂ : f x ≠ b + 1
⊢ b * card s ≤ ∑ i in s, b

Next tactic:
simp [mul_comm]
theorem equitableOn_iff_le_le_add_one :
    EquitableOn (s : Set α) f ↔
      ∀ a ∈ s, (∑ i in s, f i) / s.card ≤ f a ∧ f a ≤ (∑ i in s, f i) / s.card + 1 := by
  rw [Set.equitableOn_iff_exists_le_le_add_one]
  refine' ⟨_, fun h => ⟨_, h⟩⟩
  rintro ⟨b, hb⟩
  by_cases h : ∀ a ∈ s, f a = b + 1
  · intro a ha
    rw [h _ ha, sum_const_nat h, Nat.mul_div_cancel_left _ (card_pos.2 ⟨a, ha⟩)]
    exact ⟨le_rfl, Nat.le_succ _⟩
  push_neg at h
  obtain ⟨x, hx₁, hx₂⟩ := h
  suffices h : b = (∑ i in s, f i) / s.card by
    simp_rw [← h]
    apply hb
  symm
  refine'
    Nat.div_eq_of_lt_le (le_trans (by simp [mul_comm]) (sum_le_sum fun a ha => (hb a ha).1))
      ((sum_lt_sum (fun a ha => (hb a ha).2) ⟨_, hx₁, (hb _ hx₁).2.lt_of_ne hx₂⟩).trans_le _)
  

Proof state:
case neg.intro.intro
α : Type u_1
β : Type u_2
s : Finset α
f : α → ℕ
a : α
b : ℕ
hb : ∀ a ∈ ↑s, b ≤ f a ∧ f a ≤ b + 1
x : α
hx₁ : x ∈ s
hx₂ : f x ≠ b + 1
⊢ ∑ i in s, (b + 1) ≤ Nat.succ b * card s

Next tactic:
rw [mul_comm, sum_const_nat]
theorem equitableOn_iff_le_le_add_one :
    EquitableOn (s : Set α) f ↔
      ∀ a ∈ s, (∑ i in s, f i) / s.card ≤ f a ∧ f a ≤ (∑ i in s, f i) / s.card + 1 := by
  rw [Set.equitableOn_iff_exists_le_le_add_one]
  refine' ⟨_, fun h => ⟨_, h⟩⟩
  rintro ⟨b, hb⟩
  by_cases h : ∀ a ∈ s, f a = b + 1
  · intro a ha
    rw [h _ ha, sum_const_nat h, Nat.mul_div_cancel_left _ (card_pos.2 ⟨a, ha⟩)]
    exact ⟨le_rfl, Nat.le_succ _⟩
  push_neg at h
  obtain ⟨x, hx₁, hx₂⟩ := h
  suffices h : b = (∑ i in s, f i) / s.card by
    simp_rw [← h]
    apply hb
  symm
  refine'
    Nat.div_eq_of_lt_le (le_trans (by simp [mul_comm]) (sum_le_sum fun a ha => (hb a ha).1))
      ((sum_lt_sum (fun a ha => (hb a ha).2) ⟨_, hx₁, (hb _ hx₁).2.lt_of_ne hx₂⟩).trans_le _)
  rw [mul_comm, sum_const_nat]
  

Proof state:
case neg.intro.intro
α : Type u_1
β : Type u_2
s : Finset α
f : α → ℕ
a : α
b : ℕ
hb : ∀ a ∈ ↑s, b ≤ f a ∧ f a ≤ b + 1
x : α
hx₁ : x ∈ s
hx₂ : f x ≠ b + 1
⊢ ∀ x ∈ s, b + 1 = Nat.succ b

Next tactic:
exact fun _ _ => rfl
theorem equitableOn_iff :
    EquitableOn (s : Set α) f ↔
      ∀ a ∈ s, f a = (∑ i in s, f i) / s.card ∨ f a = (∑ i in s, f i) / s.card + 1 :=
  by 

Proof state:
α : Type u_1
β : Type u_2
s : Finset α
f : α → ℕ
a : α
⊢ EquitableOn (↑s) f ↔ ∀ a ∈ s, f a = (∑ i in s, f i) / card s ∨ f a = (∑ i in s, f i) / card s + 1

Next tactic:
simp_rw [equitableOn_iff_le_le_add_one, Nat.le_and_le_add_one_iff]
attribute [local simp] EndMonoidal in
instance (X : C) : MonoidalCategory (EndMonoidal X) where
  tensorObj f g := f ≫ g
  whiskerLeft {f g h} η := f ◁ η
  whiskerRight {f g} η h := η ▷ h
  tensorUnit := 𝟙 _
  associator f g h := α_ f g h
  leftUnitor f := λ_ f
  rightUnitor f := ρ_ f
  tensor_comp := by
    

Proof state:
C : Type u_1
inst✝ : Bicategory C
X : C
⊢ ∀ {X₁ Y₁ Z₁ X₂ Y₂ Z₂ : EndMonoidal X} (f₁ : X₁ ⟶ Y₁) (f₂ : X₂ ⟶ Y₂) (g₁ : Y₁ ⟶ Z₁) (g₂ : Y₂ ⟶ Z₂),
    f₁ ≫ g₁ ⊗ f₂ ≫ g₂ = (f₁ ⊗ f₂) ≫ (g₁ ⊗ g₂)

Next tactic:
intros
attribute [local simp] EndMonoidal in
instance (X : C) : MonoidalCategory (EndMonoidal X) where
  tensorObj f g := f ≫ g
  whiskerLeft {f g h} η := f ◁ η
  whiskerRight {f g} η h := η ▷ h
  tensorUnit := 𝟙 _
  associator f g h := α_ f g h
  leftUnitor f := λ_ f
  rightUnitor f := ρ_ f
  tensor_comp := by
    intros
    

Proof state:
C : Type u_1
inst✝ : Bicategory C
X : C
X₁✝ Y₁✝ Z₁✝ X₂✝ Y₂✝ Z₂✝ : EndMonoidal X
f₁✝ : X₁✝ ⟶ Y₁✝
f₂✝ : X₂✝ ⟶ Y₂✝
g₁✝ : Y₁✝ ⟶ Z₁✝
g₂✝ : Y₂✝ ⟶ Z₂✝
⊢ f₁✝ ≫ g₁✝ ⊗ f₂✝ ≫ g₂✝ = (f₁✝ ⊗ f₂✝) ≫ (g₁✝ ⊗ g₂✝)

Next tactic:
dsimp