l3lab/ntp-mathlib huggingface dataset:
theorem infinite_image2 (hfs : ∀ b ∈ t, InjOn (fun a => f a b) s) (hft : ∀ a ∈ s, InjOn (f a) t) :
    (image2 f s t).Infinite ↔ s.Infinite ∧ t.Nonempty ∨ t.Infinite ∧ s.Nonempty := by
  refine' ⟨fun h => Set.infinite_prod.1 _, _⟩
  · rw [← image_uncurry_prod] at h
    exact h.of_image _
  · rintro (⟨hs, b, hb⟩ | ⟨ht, a, ha⟩)
    · 

Proof state:
case refine'_2.inl.intro.intro
α : Type u
β : Type v
ι : Sort w
γ : Type x
s✝ t✝ : Set α
f : α → β → γ
s : Set α
t : Set β
a : α
b✝ : β
hfs : ∀ b ∈ t, InjOn (fun a => f a b) s
hft : ∀ a ∈ s, InjOn (f a) t
hs : Set.Infinite s
b : β
hb : b ∈ t
⊢ Set.Infinite (image2 f s t)

Next tactic:
exact hs.image2_left hb (hfs _ hb)
theorem infinite_image2 (hfs : ∀ b ∈ t, InjOn (fun a => f a b) s) (hft : ∀ a ∈ s, InjOn (f a) t) :
    (image2 f s t).Infinite ↔ s.Infinite ∧ t.Nonempty ∨ t.Infinite ∧ s.Nonempty := by
  refine' ⟨fun h => Set.infinite_prod.1 _, _⟩
  · rw [← image_uncurry_prod] at h
    exact h.of_image _
  · rintro (⟨hs, b, hb⟩ | ⟨ht, a, ha⟩)
    · exact hs.image2_left hb (hfs _ hb)
    · 

Proof state:
case refine'_2.inr.intro.intro
α : Type u
β : Type v
ι : Sort w
γ : Type x
s✝ t✝ : Set α
f : α → β → γ
s : Set α
t : Set β
a✝ : α
b : β
hfs : ∀ b ∈ t, InjOn (fun a => f a b) s
hft : ∀ a ∈ s, InjOn (f a) t
ht : Set.Infinite t
a : α
ha : a ∈ s
⊢ Set.Infinite (image2 f s t)

Next tactic:
exact ht.image2_right ha (hft _ ha)
lemma finite_image2 (hfs : ∀ b ∈ t, InjOn (f · b) s) (hft : ∀ a ∈ s, InjOn (f a) t) :
    (image2 f s t).Finite ↔ s.Finite ∧ t.Finite ∨ s = ∅ ∨ t = ∅ := by
  

Proof state:
α : Type u
β : Type v
ι : Sort w
γ : Type x
s✝ t✝ : Set α
f : α → β → γ
s : Set α
t : Set β
a : α
b : β
hfs : ∀ b ∈ t, InjOn (fun x => f x b) s
hft : ∀ a ∈ s, InjOn (f a) t
⊢ Set.Finite (image2 f s t) ↔ Set.Finite s ∧ Set.Finite t ∨ s = ∅ ∨ t = ∅

Next tactic:
rw [← not_infinite, infinite_image2 hfs hft]
lemma finite_image2 (hfs : ∀ b ∈ t, InjOn (f · b) s) (hft : ∀ a ∈ s, InjOn (f a) t) :
    (image2 f s t).Finite ↔ s.Finite ∧ t.Finite ∨ s = ∅ ∨ t = ∅ := by
  rw [← not_infinite, infinite_image2 hfs hft]
  

Proof state:
α : Type u
β : Type v
ι : Sort w
γ : Type x
s✝ t✝ : Set α
f : α → β → γ
s : Set α
t : Set β
a : α
b : β
hfs : ∀ b ∈ t, InjOn (fun x => f x b) s
hft : ∀ a ∈ s, InjOn (f a) t
⊢ ¬(Set.Infinite s ∧ Set.Nonempty t ∨ Set.Infinite t ∧ Set.Nonempty s) ↔ Set.Finite s ∧ Set.Finite t ∨ s = ∅ ∨ t = ∅

Next tactic:
simp [not_or, -not_and, not_and_or, not_nonempty_iff_eq_empty]
lemma finite_image2 (hfs : ∀ b ∈ t, InjOn (f · b) s) (hft : ∀ a ∈ s, InjOn (f a) t) :
    (image2 f s t).Finite ↔ s.Finite ∧ t.Finite ∨ s = ∅ ∨ t = ∅ := by
  rw [← not_infinite, infinite_image2 hfs hft]
  simp [not_or, -not_and, not_and_or, not_nonempty_iff_eq_empty]
  

Proof state:
α : Type u
β : Type v
ι : Sort w
γ : Type x
s✝ t✝ : Set α
f : α → β → γ
s : Set α
t : Set β
a : α
b : β
hfs : ∀ b ∈ t, InjOn (fun x => f x b) s
hft : ∀ a ∈ s, InjOn (f a) t
⊢ (Set.Finite s ∨ t = ∅) ∧ (Set.Finite t ∨ s = ∅) ↔ Set.Finite s ∧ Set.Finite t ∨ s = ∅ ∨ t = ∅

Next tactic:
aesop
theorem Infinite.exists_ne_map_eq_of_mapsTo {s : Set α} {t : Set β} {f : α → β} (hs : s.Infinite)
    (hf : MapsTo f s t) (ht : t.Finite) : ∃ x ∈ s, ∃ y ∈ s, x ≠ y ∧ f x = f y := by
  

Proof state:
α : Type u
β : Type v
ι : Sort w
γ : Type x
s✝ t✝ s : Set α
t : Set β
f : α → β
hs : Set.Infinite s
hf : MapsTo f s t
ht : Set.Finite t
⊢ ∃ x ∈ s, ∃ y ∈ s, x ≠ y ∧ f x = f y

Next tactic:
contrapose! ht
theorem Infinite.exists_ne_map_eq_of_mapsTo {s : Set α} {t : Set β} {f : α → β} (hs : s.Infinite)
    (hf : MapsTo f s t) (ht : t.Finite) : ∃ x ∈ s, ∃ y ∈ s, x ≠ y ∧ f x = f y := by
  contrapose! ht
  

Proof state:
α : Type u
β : Type v
ι : Sort w
γ : Type x
s✝ t✝ s : Set α
t : Set β
f : α → β
hs : Set.Infinite s
hf : MapsTo f s t
ht : ∀ x ∈ s, ∀ y ∈ s, x ≠ y → f x ≠ f y
⊢ ¬Set.Finite t

Next tactic:
exact infinite_of_injOn_mapsTo (fun x hx y hy => not_imp_not.1 (ht x hx y hy)) hf hs
theorem infinite_range_of_injective [Infinite α] {f : α → β} (hi : Injective f) :
    (range f).Infinite := by
  

Proof state:
α : Type u
β : Type v
ι : Sort w
γ : Type x
s t : Set α
inst✝ : Infinite α
f : α → β
hi : Injective f
⊢ Set.Infinite (range f)

Next tactic:
rw [← image_univ, infinite_image_iff (injOn_of_injective hi _)]
theorem infinite_range_of_injective [Infinite α] {f : α → β} (hi : Injective f) :
    (range f).Infinite := by
  rw [← image_univ, infinite_image_iff (injOn_of_injective hi _)]
  

Proof state:
α : Type u
β : Type v
ι : Sort w
γ : Type x
s t : Set α
inst✝ : Infinite α
f : α → β
hi : Injective f
⊢ Set.Infinite univ

Next tactic:
exact infinite_univ
theorem infinite_of_injective_forall_mem [Infinite α] {s : Set β} {f : α → β} (hi : Injective f)
    (hf : ∀ x : α, f x ∈ s) : s.Infinite := by
  

Proof state:
α : Type u
β : Type v
ι : Sort w
γ : Type x
s✝ t : Set α
inst✝ : Infinite α
s : Set β
f : α → β
hi : Injective f
hf : ∀ (x : α), f x ∈ s
⊢ Set.Infinite s

Next tactic:
rw [← range_subset_iff] at hf
theorem infinite_of_injective_forall_mem [Infinite α] {s : Set β} {f : α → β} (hi : Injective f)
    (hf : ∀ x : α, f x ∈ s) : s.Infinite := by
  rw [← range_subset_iff] at hf
  

Proof state:
α : Type u
β : Type v
ι : Sort w
γ : Type x
s✝ t : Set α
inst✝ : Infinite α
s : Set β
f : α → β
hi : Injective f
hf : (range fun x => f x) ⊆ s
⊢ Set.Infinite s

Next tactic:
exact (infinite_range_of_injective hi).mono hf
theorem not_injOn_infinite_finite_image {f : α → β} {s : Set α} (h_inf : s.Infinite)
    (h_fin : (f '' s).Finite) : ¬InjOn f s := by
  

Proof state:
α : Type u
β : Type v
ι : Sort w
γ : Type x
s✝ t : Set α
f : α → β
s : Set α
h_inf : Set.Infinite s
h_fin : Set.Finite (f '' s)
⊢ ¬InjOn f s

Next tactic:
have : Finite (f '' s) := finite_coe_iff.mpr h_fin
theorem not_injOn_infinite_finite_image {f : α → β} {s : Set α} (h_inf : s.Infinite)
    (h_fin : (f '' s).Finite) : ¬InjOn f s := by
  have : Finite (f '' s) := finite_coe_iff.mpr h_fin
  

Proof state:
α : Type u
β : Type v
ι : Sort w
γ : Type x
s✝ t : Set α
f : α → β
s : Set α
h_inf : Set.Infinite s
h_fin : Set.Finite (f '' s)
this : Finite ↑(f '' s)
⊢ ¬InjOn f s

Next tactic:
have : Infinite s := infinite_coe_iff.mpr h_inf
theorem not_injOn_infinite_finite_image {f : α → β} {s : Set α} (h_inf : s.Infinite)
    (h_fin : (f '' s).Finite) : ¬InjOn f s := by
  have : Finite (f '' s) := finite_coe_iff.mpr h_fin
  have : Infinite s := infinite_coe_iff.mpr h_inf
  

Proof state:
α : Type u
β : Type v
ι : Sort w
γ : Type x
s✝ t : Set α
f : α → β
s : Set α
h_inf : Set.Infinite s
h_fin : Set.Finite (f '' s)
this✝ : Finite ↑(f '' s)
this : Infinite ↑s
⊢ ¬InjOn f s

Next tactic:
have h := not_injective_infinite_finite
            ((f '' s).codRestrict (s.restrict f) fun x => ⟨x, x.property, rfl⟩)
theorem not_injOn_infinite_finite_image {f : α → β} {s : Set α} (h_inf : s.Infinite)
    (h_fin : (f '' s).Finite) : ¬InjOn f s := by
  have : Finite (f '' s) := finite_coe_iff.mpr h_fin
  have : Infinite s := infinite_coe_iff.mpr h_inf
  have h := not_injective_infinite_finite
            ((f '' s).codRestrict (s.restrict f) fun x => ⟨x, x.property, rfl⟩)
  

Proof state:
α : Type u
β : Type v
ι : Sort w
γ : Type x
s✝ t : Set α
f : α → β
s : Set α
h_inf : Set.Infinite s
h_fin : Set.Finite (f '' s)
this✝ : Finite ↑(f '' s)
this : Infinite ↑s
h : ¬Injective (codRestrict (restrict s f) (f '' s) (_ : ∀ (x : ↑s), ∃ a ∈ s, f a = restrict s f x))
⊢ ¬InjOn f s

Next tactic:
contrapose! h
theorem not_injOn_infinite_finite_image {f : α → β} {s : Set α} (h_inf : s.Infinite)
    (h_fin : (f '' s).Finite) : ¬InjOn f s := by
  have : Finite (f '' s) := finite_coe_iff.mpr h_fin
  have : Infinite s := infinite_coe_iff.mpr h_inf
  have h := not_injective_infinite_finite
            ((f '' s).codRestrict (s.restrict f) fun x => ⟨x, x.property, rfl⟩)
  contrapose! h
  

Proof state:
α : Type u
β : Type v
ι : Sort w
γ : Type x
s✝ t : Set α
f : α → β
s : Set α
h_inf : Set.Infinite s
h_fin : Set.Finite (f '' s)
this✝ : Finite ↑(f '' s)
this : Infinite ↑s
h : InjOn f s
⊢ Injective (codRestrict (restrict s f) (f '' s) (_ : ∀ (x : ↑s), ∃ a ∈ s, f a = restrict s f x))

Next tactic:
rwa [injective_codRestrict, ← injOn_iff_injective]
theorem infinite_of_forall_exists_gt (h : ∀ a, ∃ b ∈ s, a < b) : s.Infinite := by
  

Proof state:
α : Type u
β : Type v
ι : Sort w
γ : Type x
s✝ t : Set α
inst✝¹ : Preorder α
inst✝ : Nonempty α
s : Set α
h : ∀ (a : α), ∃ b ∈ s, a < b
⊢ Set.Infinite s

Next tactic:
inhabit α
theorem infinite_of_forall_exists_gt (h : ∀ a, ∃ b ∈ s, a < b) : s.Infinite := by
  inhabit α
  

Proof state:
α : Type u
β : Type v
ι : Sort w
γ : Type x
s✝ t : Set α
inst✝¹ : Preorder α
inst✝ : Nonempty α
s : Set α
h : ∀ (a : α), ∃ b ∈ s, a < b
inhabited_h : Inhabited α
⊢ Set.Infinite s

Next tactic:
set f : ℕ → α := fun n => Nat.recOn n (h default).choose fun _ a => (h a).choose
theorem infinite_of_forall_exists_gt (h : ∀ a, ∃ b ∈ s, a < b) : s.Infinite := by
  inhabit α
  set f : ℕ → α := fun n => Nat.recOn n (h default).choose fun _ a => (h a).choose
  

Proof state:
α : Type u
β : Type v
ι : Sort w
γ : Type x
s✝ t : Set α
inst✝¹ : Preorder α
inst✝ : Nonempty α
s : Set α
h : ∀ (a : α), ∃ b ∈ s, a < b
inhabited_h : Inhabited α
f : ℕ → α :=
  fun n => Nat.recOn n (Exists.choose (_ : ∃ b ∈ s, default < b)) fun x a => Exists.choose (_ : ∃ b ∈ s, a < b)
⊢ Set.Infinite s

Next tactic:
have hf : ∀ n, f n ∈ s := by rintro (_ | _) <;> exact (h _).choose_spec.1
theorem infinite_of_forall_exists_gt (h : ∀ a, ∃ b ∈ s, a < b) : s.Infinite := by
  inhabit α
  set f : ℕ → α := fun n => Nat.recOn n (h default).choose fun _ a => (h a).choose
  have hf : ∀ n, f n ∈ s := by 

Proof state:
α : Type u
β : Type v
ι : Sort w
γ : Type x
s✝ t : Set α
inst✝¹ : Preorder α
inst✝ : Nonempty α
s : Set α
h : ∀ (a : α), ∃ b ∈ s, a < b
inhabited_h : Inhabited α
f : ℕ → α :=
  fun n => Nat.recOn n (Exists.choose (_ : ∃ b ∈ s, default < b)) fun x a => Exists.choose (_ : ∃ b ∈ s, a < b)
⊢ ∀ (n : ℕ), f n ∈ s

Next tactic:
rintro (_ | _)
theorem infinite_of_forall_exists_gt (h : ∀ a, ∃ b ∈ s, a < b) : s.Infinite := by
  inhabit α
  set f : ℕ → α := fun n => Nat.recOn n (h default).choose fun _ a => (h a).choose
  have hf : ∀ n, f n ∈ s := by rintro (_ | _) <;> 

Proof state:
case zero
α : Type u
β : Type v
ι : Sort w
γ : Type x
s✝ t : Set α
inst✝¹ : Preorder α
inst✝ : Nonempty α
s : Set α
h : ∀ (a : α), ∃ b ∈ s, a < b
inhabited_h : Inhabited α
f : ℕ → α :=
  fun n => Nat.recOn n (Exists.choose (_ : ∃ b ∈ s, default < b)) fun x a => Exists.choose (_ : ∃ b ∈ s, a < b)
⊢ f Nat.zero ∈ s

Next tactic:
exact (h _).choose_spec.1
theorem infinite_of_forall_exists_gt (h : ∀ a, ∃ b ∈ s, a < b) : s.Infinite := by
  inhabit α
  set f : ℕ → α := fun n => Nat.recOn n (h default).choose fun _ a => (h a).choose
  have hf : ∀ n, f n ∈ s := by rintro (_ | _) <;> 

Proof state:
case succ
α : Type u
β : Type v
ι : Sort w
γ : Type x
s✝ t : Set α
inst✝¹ : Preorder α
inst✝ : Nonempty α
s : Set α
h : ∀ (a : α), ∃ b ∈ s, a < b
inhabited_h : Inhabited α
f : ℕ → α :=
  fun n => Nat.recOn n (Exists.choose (_ : ∃ b ∈ s, default < b)) fun x a => Exists.choose (_ : ∃ b ∈ s, a < b)
n✝ : ℕ
⊢ f (Nat.succ n✝) ∈ s

Next tactic:
exact (h _).choose_spec.1
theorem infinite_of_forall_exists_gt (h : ∀ a, ∃ b ∈ s, a < b) : s.Infinite := by
  inhabit α
  set f : ℕ → α := fun n => Nat.recOn n (h default).choose fun _ a => (h a).choose
  have hf : ∀ n, f n ∈ s := by rintro (_ | _) <;> exact (h _).choose_spec.1
  

Proof state:
α : Type u
β : Type v
ι : Sort w
γ : Type x
s✝ t : Set α
inst✝¹ : Preorder α
inst✝ : Nonempty α
s : Set α
h : ∀ (a : α), ∃ b ∈ s, a < b
inhabited_h : Inhabited α
f : ℕ → α :=
  fun n => Nat.recOn n (Exists.choose (_ : ∃ b ∈ s, default < b)) fun x a => Exists.choose (_ : ∃ b ∈ s, a < b)
hf : ∀ (n : ℕ), f n ∈ s
⊢ Set.Infinite s

Next tactic:
exact infinite_of_injective_forall_mem
    (strictMono_nat_of_lt_succ fun n => (h _).choose_spec.2).injective hf
theorem Finite.exists_lt_map_eq_of_forall_mem [LinearOrder α] [Infinite α] {t : Set β} {f : α → β}
    (hf : ∀ a, f a ∈ t) (ht : t.Finite) : ∃ a b, a < b ∧ f a = f b := by
  

Proof state:
α : Type u
β : Type v
ι : Sort w
γ : Type x
s t✝ : Set α
inst✝¹ : LinearOrder α
inst✝ : Infinite α
t : Set β
f : α → β
hf : ∀ (a : α), f a ∈ t
ht : Set.Finite t
⊢ ∃ a b, a < b ∧ f a = f b

Next tactic:
rw [← maps_univ_to] at hf
theorem Finite.exists_lt_map_eq_of_forall_mem [LinearOrder α] [Infinite α] {t : Set β} {f : α → β}
    (hf : ∀ a, f a ∈ t) (ht : t.Finite) : ∃ a b, a < b ∧ f a = f b := by
  rw [← maps_univ_to] at hf
  

Proof state:
α : Type u
β : Type v
ι : Sort w
γ : Type x
s t✝ : Set α
inst✝¹ : LinearOrder α
inst✝ : Infinite α
t : Set β
f : α → β
hf : MapsTo (fun a => f a) univ t
ht : Set.Finite t
⊢ ∃ a b, a < b ∧ f a = f b

Next tactic:
obtain ⟨a, -, b, -, h⟩ := infinite_univ.exists_lt_map_eq_of_mapsTo hf ht
theorem Finite.exists_lt_map_eq_of_forall_mem [LinearOrder α] [Infinite α] {t : Set β} {f : α → β}
    (hf : ∀ a, f a ∈ t) (ht : t.Finite) : ∃ a b, a < b ∧ f a = f b := by
  rw [← maps_univ_to] at hf
  obtain ⟨a, -, b, -, h⟩ := infinite_univ.exists_lt_map_eq_of_mapsTo hf ht
  

Proof state:
case intro.intro.intro.intro
α : Type u
β : Type v
ι : Sort w
γ : Type x
s t✝ : Set α
inst✝¹ : LinearOrder α
inst✝ : Infinite α
t : Set β
f : α → β
hf : MapsTo (fun a => f a) univ t
ht : Set.Finite t
a b : α
h : a < b ∧ f a = f b
⊢ ∃ a b, a < b ∧ f a = f b

Next tactic:
exact ⟨a, b, h⟩
theorem exists_min_image [LinearOrder β] (s : Set α) (f : α → β) (h1 : s.Finite) :
    s.Nonempty → ∃ a ∈ s, ∀ b ∈ s, f a ≤ f b
  | ⟨x, hx⟩ => by
    

Proof state:
α : Type u
β : Type v
ι : Sort w
γ : Type x
s✝ t : Set α
inst✝ : LinearOrder β
s : Set α
f : α → β
h1 : Set.Finite s
x : α
hx : x ∈ s
⊢ ∃ a ∈ s, ∀ b ∈ s, f a ≤ f b

Next tactic:
simpa only [exists_prop, Finite.mem_toFinset] using
      h1.toFinset.exists_min_image f ⟨x, h1.mem_toFinset.2 hx⟩
theorem exists_max_image [LinearOrder β] (s : Set α) (f : α → β) (h1 : s.Finite) :
    s.Nonempty → ∃ a ∈ s, ∀ b ∈ s, f b ≤ f a
  | ⟨x, hx⟩ => by
    

Proof state:
α : Type u
β : Type v
ι : Sort w
γ : Type x
s✝ t : Set α
inst✝ : LinearOrder β
s : Set α
f : α → β
h1 : Set.Finite s
x : α
hx : x ∈ s
⊢ ∃ a ∈ s, ∀ b ∈ s, f b ≤ f a

Next tactic:
simpa only [exists_prop, Finite.mem_toFinset] using
      h1.toFinset.exists_max_image f ⟨x, h1.mem_toFinset.2 hx⟩
theorem exists_lower_bound_image [Nonempty α] [LinearOrder β] (s : Set α) (f : α → β)
    (h : s.Finite) : ∃ a : α, ∀ b ∈ s, f a ≤ f b := by
  

Proof state:
α : Type u
β : Type v
ι : Sort w
γ : Type x
s✝ t : Set α
inst✝¹ : Nonempty α
inst✝ : LinearOrder β
s : Set α
f : α → β
h : Set.Finite s
⊢ ∃ a, ∀ b ∈ s, f a ≤ f b

Next tactic:
rcases s.eq_empty_or_nonempty with rfl | hs
theorem exists_lower_bound_image [Nonempty α] [LinearOrder β] (s : Set α) (f : α → β)
    (h : s.Finite) : ∃ a : α, ∀ b ∈ s, f a ≤ f b := by
  rcases s.eq_empty_or_nonempty with rfl | hs
  · 

Proof state:
case inl
α : Type u
β : Type v
ι : Sort w
γ : Type x
s t : Set α
inst✝¹ : Nonempty α
inst✝ : LinearOrder β
f : α → β
h : Set.Finite ∅
⊢ ∃ a, ∀ b ∈ ∅, f a ≤ f b

Next tactic:
exact ‹Nonempty α›.elim fun a => ⟨a, fun _ => False.elim⟩
theorem exists_lower_bound_image [Nonempty α] [LinearOrder β] (s : Set α) (f : α → β)
    (h : s.Finite) : ∃ a : α, ∀ b ∈ s, f a ≤ f b := by
  rcases s.eq_empty_or_nonempty with rfl | hs
  · exact ‹Nonempty α›.elim fun a => ⟨a, fun _ => False.elim⟩
  · 

Proof state:
case inr
α : Type u
β : Type v
ι : Sort w
γ : Type x
s✝ t : Set α
inst✝¹ : Nonempty α
inst✝ : LinearOrder β
s : Set α
f : α → β
h : Set.Finite s
hs : Set.Nonempty s
⊢ ∃ a, ∀ b ∈ s, f a ≤ f b

Next tactic:
rcases Set.exists_min_image s f h hs with ⟨x₀, _, hx₀⟩
theorem exists_lower_bound_image [Nonempty α] [LinearOrder β] (s : Set α) (f : α → β)
    (h : s.Finite) : ∃ a : α, ∀ b ∈ s, f a ≤ f b := by
  rcases s.eq_empty_or_nonempty with rfl | hs
  · exact ‹Nonempty α›.elim fun a => ⟨a, fun _ => False.elim⟩
  · rcases Set.exists_min_image s f h hs with ⟨x₀, _, hx₀⟩
    

Proof state:
case inr.intro.intro
α : Type u
β : Type v
ι : Sort w
γ : Type x
s✝ t : Set α
inst✝¹ : Nonempty α
inst✝ : LinearOrder β
s : Set α
f : α → β
h : Set.Finite s
hs : Set.Nonempty s
x₀ : α
left✝ : x₀ ∈ s
hx₀ : ∀ b ∈ s, f x₀ ≤ f b
⊢ ∃ a, ∀ b ∈ s, f a ≤ f b

Next tactic:
exact ⟨x₀, fun x hx => hx₀ x hx⟩
theorem Finite.iSup_biInf_of_monotone {ι ι' α : Type*} [Preorder ι'] [Nonempty ι']
    [IsDirected ι' (· ≤ ·)] [Order.Frame α] {s : Set ι} (hs : s.Finite) {f : ι → ι' → α}
    (hf : ∀ i ∈ s, Monotone (f i)) : ⨆ j, ⨅ i ∈ s, f i j = ⨅ i ∈ s, ⨆ j, f i j := by
  

Proof state:
α✝ : Type u
β : Type v
ι✝ : Sort w
γ : Type x
s✝ t : Set α✝
ι : Type u_1
ι' : Type u_2
α : Type u_3
inst✝³ : Preorder ι'
inst✝² : Nonempty ι'
inst✝¹ : IsDirected ι' fun x x_1 => x ≤ x_1
inst✝ : Order.Frame α
s : Set ι
hs : Set.Finite s
f : ι → ι' → α
hf : ∀ i ∈ s, Monotone (f i)
⊢ ⨆ j, ⨅ i ∈ s, f i j = ⨅ i ∈ s, ⨆ j, f i j

Next tactic:
induction' s, hs using Set.Finite.dinduction_on with a s _ _ ihs hf
theorem Finite.iSup_biInf_of_monotone {ι ι' α : Type*} [Preorder ι'] [Nonempty ι']
    [IsDirected ι' (· ≤ ·)] [Order.Frame α] {s : Set ι} (hs : s.Finite) {f : ι → ι' → α}
    (hf : ∀ i ∈ s, Monotone (f i)) : ⨆ j, ⨅ i ∈ s, f i j = ⨅ i ∈ s, ⨆ j, f i j := by
  induction' s, hs using Set.Finite.dinduction_on with a s _ _ ihs hf
  · 

Proof state:
case H0
α✝ : Type u
β : Type v
ι✝ : Sort w
γ : Type x
s✝ t : Set α✝
ι : Type u_1
ι' : Type u_2
α : Type u_3
inst✝³ : Preorder ι'
inst✝² : Nonempty ι'
inst✝¹ : IsDirected ι' fun x x_1 => x ≤ x_1
inst✝ : Order.Frame α
s : Set ι
f : ι → ι' → α
hf : ∀ i ∈ ∅, Monotone (f i)
⊢ ⨆ j, ⨅ i ∈ ∅, f i j = ⨅ i ∈ ∅, ⨆ j, f i j

Next tactic:
simp [iSup_const]
theorem Finite.iSup_biInf_of_monotone {ι ι' α : Type*} [Preorder ι'] [Nonempty ι']
    [IsDirected ι' (· ≤ ·)] [Order.Frame α] {s : Set ι} (hs : s.Finite) {f : ι → ι' → α}
    (hf : ∀ i ∈ s, Monotone (f i)) : ⨆ j, ⨅ i ∈ s, f i j = ⨅ i ∈ s, ⨆ j, f i j := by
  induction' s, hs using Set.Finite.dinduction_on with a s _ _ ihs hf
  · simp [iSup_const]
  · 

Proof state:
case H1
α✝ : Type u
β : Type v
ι✝ : Sort w
γ : Type x
s✝¹ t : Set α✝
ι : Type u_1
ι' : Type u_2
α : Type u_3
inst✝³ : Preorder ι'
inst✝² : Nonempty ι'
inst✝¹ : IsDirected ι' fun x x_1 => x ≤ x_1
inst✝ : Order.Frame α
s✝ : Set ι
f : ι → ι' → α
a : ι
s : Set ι
a✝ : a ∉ s
h✝ : Set.Finite s
ihs : (∀ i ∈ s, Monotone (f i)) → ⨆ j, ⨅ i ∈ s, f i j = ⨅ i ∈ s, ⨆ j, f i j
hf : ∀ i ∈ insert a s, Monotone (f i)
⊢ ⨆ j, ⨅ i ∈ insert a s, f i j = ⨅ i ∈ insert a s, ⨆ j, f i j

Next tactic:
rw [ball_insert_iff] at hf
theorem Finite.iSup_biInf_of_monotone {ι ι' α : Type*} [Preorder ι'] [Nonempty ι']
    [IsDirected ι' (· ≤ ·)] [Order.Frame α] {s : Set ι} (hs : s.Finite) {f : ι → ι' → α}
    (hf : ∀ i ∈ s, Monotone (f i)) : ⨆ j, ⨅ i ∈ s, f i j = ⨅ i ∈ s, ⨆ j, f i j := by
  induction' s, hs using Set.Finite.dinduction_on with a s _ _ ihs hf
  · simp [iSup_const]
  · rw [ball_insert_iff] at hf
    

Proof state:
case H1
α✝ : Type u
β : Type v
ι✝ : Sort w
γ : Type x
s✝¹ t : Set α✝
ι : Type u_1
ι' : Type u_2
α : Type u_3
inst✝³ : Preorder ι'
inst✝² : Nonempty ι'
inst✝¹ : IsDirected ι' fun x x_1 => x ≤ x_1
inst✝ : Order.Frame α
s✝ : Set ι
f : ι → ι' → α
a : ι
s : Set ι
a✝ : a ∉ s
h✝ : Set.Finite s
ihs : (∀ i ∈ s, Monotone (f i)) → ⨆ j, ⨅ i ∈ s, f i j = ⨅ i ∈ s, ⨆ j, f i j
hf : Monotone (f a) ∧ ∀ x ∈ s, Monotone (f x)
⊢ ⨆ j, ⨅ i ∈ insert a s, f i j = ⨅ i ∈ insert a s, ⨆ j, f i j

Next tactic:
simp only [iInf_insert, ← ihs hf.2]
theorem Finite.iSup_biInf_of_monotone {ι ι' α : Type*} [Preorder ι'] [Nonempty ι']
    [IsDirected ι' (· ≤ ·)] [Order.Frame α] {s : Set ι} (hs : s.Finite) {f : ι → ι' → α}
    (hf : ∀ i ∈ s, Monotone (f i)) : ⨆ j, ⨅ i ∈ s, f i j = ⨅ i ∈ s, ⨆ j, f i j := by
  induction' s, hs using Set.Finite.dinduction_on with a s _ _ ihs hf
  · simp [iSup_const]
  · rw [ball_insert_iff] at hf
    simp only [iInf_insert, ← ihs hf.2]
    

Proof state:
case H1
α✝ : Type u
β : Type v
ι✝ : Sort w
γ : Type x
s✝¹ t : Set α✝
ι : Type u_1
ι' : Type u_2
α : Type u_3
inst✝³ : Preorder ι'
inst✝² : Nonempty ι'
inst✝¹ : IsDirected ι' fun x x_1 => x ≤ x_1
inst✝ : Order.Frame α
s✝ : Set ι
f : ι → ι' → α
a : ι
s : Set ι
a✝ : a ∉ s
h✝ : Set.Finite s
ihs : (∀ i ∈ s, Monotone (f i)) → ⨆ j, ⨅ i ∈ s, f i j = ⨅ i ∈ s, ⨆ j, f i j
hf : Monotone (f a) ∧ ∀ x ∈ s, Monotone (f x)
⊢ ⨆ j, f a j ⊓ ⨅ x ∈ s, f x j = (⨆ j, f a j) ⊓ ⨆ j, ⨅ i ∈ s, f i j

Next tactic:
exact iSup_inf_of_monotone hf.1 fun j₁ j₂ hj => iInf₂_mono fun i hi => hf.2 i hi hj
theorem iSup_iInf_of_monotone {ι ι' α : Type*} [Finite ι] [Preorder ι'] [Nonempty ι']
    [IsDirected ι' (· ≤ ·)] [Order.Frame α] {f : ι → ι' → α} (hf : ∀ i, Monotone (f i)) :
    ⨆ j, ⨅ i, f i j = ⨅ i, ⨆ j, f i j := by
  

Proof state:
α✝ : Type u
β : Type v
ι✝ : Sort w
γ : Type x
s t : Set α✝
ι : Type u_1
ι' : Type u_2
α : Type u_3
inst✝⁴ : Finite ι
inst✝³ : Preorder ι'
inst✝² : Nonempty ι'
inst✝¹ : IsDirected ι' fun x x_1 => x ≤ x_1
inst✝ : Order.Frame α
f : ι → ι' → α
hf : ∀ (i : ι), Monotone (f i)
⊢ ⨆ j, ⨅ i, f i j = ⨅ i, ⨆ j, f i j

Next tactic:
simpa only [iInf_univ] using finite_univ.iSup_biInf_of_monotone fun i _ => hf i
theorem iUnion_pi_of_monotone {ι ι' : Type*} [LinearOrder ι'] [Nonempty ι'] {α : ι → Type*}
    {I : Set ι} {s : ∀ i, ι' → Set (α i)} (hI : I.Finite) (hs : ∀ i ∈ I, Monotone (s i)) :
    ⋃ j : ι', I.pi (fun i => s i j) = I.pi fun i => ⋃ j, s i j := by
  

Proof state:
α✝ : Type u
β : Type v
ι✝ : Sort w
γ : Type x
s✝ t : Set α✝
ι : Type u_1
ι' : Type u_2
inst✝¹ : LinearOrder ι'
inst✝ : Nonempty ι'
α : ι → Type u_3
I : Set ι
s : (i : ι) → ι' → Set (α i)
hI : Set.Finite I
hs : ∀ i ∈ I, Monotone (s i)
⊢ (⋃ j, pi I fun i => s i j) = pi I fun i => ⋃ j, s i j

Next tactic:
simp only [pi_def, biInter_eq_iInter, preimage_iUnion]
theorem iUnion_pi_of_monotone {ι ι' : Type*} [LinearOrder ι'] [Nonempty ι'] {α : ι → Type*}
    {I : Set ι} {s : ∀ i, ι' → Set (α i)} (hI : I.Finite) (hs : ∀ i ∈ I, Monotone (s i)) :
    ⋃ j : ι', I.pi (fun i => s i j) = I.pi fun i => ⋃ j, s i j := by
  simp only [pi_def, biInter_eq_iInter, preimage_iUnion]
  

Proof state:
α✝ : Type u
β : Type v
ι✝ : Sort w
γ : Type x
s✝ t : Set α✝
ι : Type u_1
ι' : Type u_2
inst✝¹ : LinearOrder ι'
inst✝ : Nonempty ι'
α : ι → Type u_3
I : Set ι
s : (i : ι) → ι' → Set (α i)
hI : Set.Finite I
hs : ∀ i ∈ I, Monotone (s i)
⊢ ⋃ j, ⋂ x, eval ↑x ⁻¹' s (↑x) j = ⋂ x, ⋃ i, eval ↑x ⁻¹' s (↑x) i

Next tactic:
haveI := hI.fintype.finite
theorem iUnion_pi_of_monotone {ι ι' : Type*} [LinearOrder ι'] [Nonempty ι'] {α : ι → Type*}
    {I : Set ι} {s : ∀ i, ι' → Set (α i)} (hI : I.Finite) (hs : ∀ i ∈ I, Monotone (s i)) :
    ⋃ j : ι', I.pi (fun i => s i j) = I.pi fun i => ⋃ j, s i j := by
  simp only [pi_def, biInter_eq_iInter, preimage_iUnion]
  haveI := hI.fintype.finite
  

Proof state:
α✝ : Type u
β : Type v
ι✝ : Sort w
γ : Type x
s✝ t : Set α✝
ι : Type u_1
ι' : Type u_2
inst✝¹ : LinearOrder ι'
inst✝ : Nonempty ι'
α : ι → Type u_3
I : Set ι
s : (i : ι) → ι' → Set (α i)
hI : Set.Finite I
hs : ∀ i ∈ I, Monotone (s i)
this : Finite ↑I
⊢ ⋃ j, ⋂ x, eval ↑x ⁻¹' s (↑x) j = ⋂ x, ⋃ i, eval ↑x ⁻¹' s (↑x) i

Next tactic:
refine' iUnion_iInter_of_monotone (ι' := ι') (fun (i : I) j₁ j₂ h => _)
theorem iUnion_pi_of_monotone {ι ι' : Type*} [LinearOrder ι'] [Nonempty ι'] {α : ι → Type*}
    {I : Set ι} {s : ∀ i, ι' → Set (α i)} (hI : I.Finite) (hs : ∀ i ∈ I, Monotone (s i)) :
    ⋃ j : ι', I.pi (fun i => s i j) = I.pi fun i => ⋃ j, s i j := by
  simp only [pi_def, biInter_eq_iInter, preimage_iUnion]
  haveI := hI.fintype.finite
  refine' iUnion_iInter_of_monotone (ι' := ι') (fun (i : I) j₁ j₂ h => _)
  

Proof state:
α✝ : Type u
β : Type v
ι✝ : Sort w
γ : Type x
s✝ t : Set α✝
ι : Type u_1
ι' : Type u_2
inst✝¹ : LinearOrder ι'
inst✝ : Nonempty ι'
α : ι → Type u_3
I : Set ι
s : (i : ι) → ι' → Set (α i)
hI : Set.Finite I
hs : ∀ i ∈ I, Monotone (s i)
this : Finite ↑I
i : ↑I
j₁ j₂ : ι'
h : j₁ ≤ j₂
⊢ eval ↑i ⁻¹' s (↑i) j₁ ≤ eval ↑i ⁻¹' s (↑i) j₂

Next tactic:
exact preimage_mono <| hs i i.2 h