l3lab/ntp-mathlib huggingface dataset:
theorem frequently_imp_distrib_left {f : Filter α} [NeBot f] {p : Prop} {q : α → Prop} :
    (∃ᶠ x in f, p → q x) ↔ p → ∃ᶠ x in f, q x := by 

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f : Filter α
inst✝ : NeBot f
p : Prop
q : α → Prop
⊢ (∃ᶠ (x : α) in f, p → q x) ↔ p → ∃ᶠ (x : α) in f, q x

Next tactic:
simp [frequently_imp_distrib]
theorem frequently_imp_distrib_right {f : Filter α} [NeBot f] {p : α → Prop} {q : Prop} :
    (∃ᶠ x in f, p x → q) ↔ (∀ᶠ x in f, p x) → q := by 

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f : Filter α
inst✝ : NeBot f
p : α → Prop
q : Prop
⊢ (∃ᶠ (x : α) in f, p x → q) ↔ (∀ᶠ (x : α) in f, p x) → q

Next tactic:
simp [frequently_imp_distrib]
theorem eventually_imp_distrib_right {f : Filter α} {p : α → Prop} {q : Prop} :
    (∀ᶠ x in f, p x → q) ↔ (∃ᶠ x in f, p x) → q := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f : Filter α
p : α → Prop
q : Prop
⊢ (∀ᶠ (x : α) in f, p x → q) ↔ (∃ᶠ (x : α) in f, p x) → q

Next tactic:
simp only [imp_iff_not_or, eventually_or_distrib_right, not_frequently]
@[simp]
theorem frequently_and_distrib_left {f : Filter α} {p : Prop} {q : α → Prop} :
    (∃ᶠ x in f, p ∧ q x) ↔ p ∧ ∃ᶠ x in f, q x := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f : Filter α
p : Prop
q : α → Prop
⊢ (∃ᶠ (x : α) in f, p ∧ q x) ↔ p ∧ ∃ᶠ (x : α) in f, q x

Next tactic:
simp only [Filter.Frequently, not_and, eventually_imp_distrib_left, not_imp]
@[simp]
theorem frequently_and_distrib_right {f : Filter α} {p : α → Prop} {q : Prop} :
    (∃ᶠ x in f, p x ∧ q) ↔ (∃ᶠ x in f, p x) ∧ q := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f : Filter α
p : α → Prop
q : Prop
⊢ (∃ᶠ (x : α) in f, p x ∧ q) ↔ (∃ᶠ (x : α) in f, p x) ∧ q

Next tactic:
simp only [@and_comm _ q, frequently_and_distrib_left]
@[simp]
theorem frequently_bot {p : α → Prop} : ¬∃ᶠ x in ⊥, p x := by 

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
p : α → Prop
⊢ ¬∃ᶠ (x : α) in ⊥, p x

Next tactic:
simp
@[simp]
theorem frequently_top {p : α → Prop} : (∃ᶠ x in ⊤, p x) ↔ ∃ x, p x := by 

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
p : α → Prop
⊢ (∃ᶠ (x : α) in ⊤, p x) ↔ ∃ x, p x

Next tactic:
simp [Filter.Frequently]
@[simp]
theorem frequently_principal {a : Set α} {p : α → Prop} : (∃ᶠ x in 𝓟 a, p x) ↔ ∃ x ∈ a, p x := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
a : Set α
p : α → Prop
⊢ (∃ᶠ (x : α) in 𝓟 a, p x) ↔ ∃ x ∈ a, p x

Next tactic:
simp [Filter.Frequently, not_forall]
theorem frequently_sup {p : α → Prop} {f g : Filter α} :
    (∃ᶠ x in f ⊔ g, p x) ↔ (∃ᶠ x in f, p x) ∨ ∃ᶠ x in g, p x := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
p : α → Prop
f g : Filter α
⊢ (∃ᶠ (x : α) in f ⊔ g, p x) ↔ (∃ᶠ (x : α) in f, p x) ∨ ∃ᶠ (x : α) in g, p x

Next tactic:
simp only [Filter.Frequently, eventually_sup, not_and_or]
@[simp]
theorem frequently_sSup {p : α → Prop} {fs : Set (Filter α)} :
    (∃ᶠ x in sSup fs, p x) ↔ ∃ f ∈ fs, ∃ᶠ x in f, p x := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
p : α → Prop
fs : Set (Filter α)
⊢ (∃ᶠ (x : α) in sSup fs, p x) ↔ ∃ f ∈ fs, ∃ᶠ (x : α) in f, p x

Next tactic:
simp only [Filter.Frequently, not_forall, eventually_sSup, exists_prop]
@[simp]
theorem frequently_iSup {p : α → Prop} {fs : β → Filter α} :
    (∃ᶠ x in ⨆ b, fs b, p x) ↔ ∃ b, ∃ᶠ x in fs b, p x := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
p : α → Prop
fs : β → Filter α
⊢ (∃ᶠ (x : α) in ⨆ b, fs b, p x) ↔ ∃ b, ∃ᶠ (x : α) in fs b, p x

Next tactic:
simp only [Filter.Frequently, eventually_iSup, not_forall]
theorem Eventually.choice {r : α → β → Prop} {l : Filter α} [l.NeBot] (h : ∀ᶠ x in l, ∃ y, r x y) :
    ∃ f : α → β, ∀ᶠ x in l, r x (f x) := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
r : α → β → Prop
l : Filter α
inst✝ : NeBot l
h : ∀ᶠ (x : α) in l, ∃ y, r x y
⊢ ∃ f, ∀ᶠ (x : α) in l, r x (f x)

Next tactic:
haveI : Nonempty β := let ⟨_, hx⟩ := h.exists; hx.nonempty
theorem Eventually.choice {r : α → β → Prop} {l : Filter α} [l.NeBot] (h : ∀ᶠ x in l, ∃ y, r x y) :
    ∃ f : α → β, ∀ᶠ x in l, r x (f x) := by
  haveI : Nonempty β := let ⟨_, hx⟩ := h.exists; hx.nonempty
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
r : α → β → Prop
l : Filter α
inst✝ : NeBot l
h : ∀ᶠ (x : α) in l, ∃ y, r x y
this : Nonempty β
⊢ ∃ f, ∀ᶠ (x : α) in l, r x (f x)

Next tactic:
choose! f hf using fun x (hx : ∃ y, r x y) => hx
theorem Eventually.choice {r : α → β → Prop} {l : Filter α} [l.NeBot] (h : ∀ᶠ x in l, ∃ y, r x y) :
    ∃ f : α → β, ∀ᶠ x in l, r x (f x) := by
  haveI : Nonempty β := let ⟨_, hx⟩ := h.exists; hx.nonempty
  choose! f hf using fun x (hx : ∃ y, r x y) => hx
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
r : α → β → Prop
l : Filter α
inst✝ : NeBot l
h : ∀ᶠ (x : α) in l, ∃ y, r x y
this : Nonempty β
f : α → β
hf : ∀ (x : α), (∃ y, r x y) → r x (f x)
⊢ ∃ f, ∀ᶠ (x : α) in l, r x (f x)

Next tactic:
exact ⟨f, h.mono hf⟩
@[simp]
theorem eventuallyEq_univ {s : Set α} {l : Filter α} : s =ᶠ[l] univ ↔ s ∈ l := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
s : Set α
l : Filter α
⊢ s =ᶠ[l] univ ↔ s ∈ l

Next tactic:
simp [eventuallyEq_set]
theorem EventuallyEq.prod_mk {l} {f f' : α → β} (hf : f =ᶠ[l] f') {g g' : α → γ} (hg : g =ᶠ[l] g') :
    (fun x => (f x, g x)) =ᶠ[l] fun x => (f' x, g' x) :=
  hf.mp <|
    hg.mono <| by
      

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
l : Filter α
f f' : α → β
hf : f =ᶠ[l] f'
g g' : α → γ
hg : g =ᶠ[l] g'
⊢ ∀ (x : α), g x = g' x → f x = f' x → (fun x => (f x, g x)) x = (fun x => (f' x, g' x)) x

Next tactic:
intros
theorem EventuallyEq.prod_mk {l} {f f' : α → β} (hf : f =ᶠ[l] f') {g g' : α → γ} (hg : g =ᶠ[l] g') :
    (fun x => (f x, g x)) =ᶠ[l] fun x => (f' x, g' x) :=
  hf.mp <|
    hg.mono <| by
      intros
      

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
l : Filter α
f f' : α → β
hf : f =ᶠ[l] f'
g g' : α → γ
hg : g =ᶠ[l] g'
x✝ : α
a✝¹ : g x✝ = g' x✝
a✝ : f x✝ = f' x✝
⊢ (fun x => (f x, g x)) x✝ = (fun x => (f' x, g' x)) x✝

Next tactic:
simp only [*]
theorem eventuallyEq_empty {s : Set α} {l : Filter α} : s =ᶠ[l] (∅ : Set α) ↔ ∀ᶠ x in l, x ∉ s :=
  eventuallyEq_set.trans <| by 

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
s : Set α
l : Filter α
⊢ (∀ᶠ (x : α) in l, x ∈ s ↔ x ∈ ∅) ↔ ∀ᶠ (x : α) in l, x ∉ s

Next tactic:
simp
theorem inter_eventuallyEq_left {s t : Set α} {l : Filter α} :
    (s ∩ t : Set α) =ᶠ[l] s ↔ ∀ᶠ x in l, x ∈ s → x ∈ t := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
s t : Set α
l : Filter α
⊢ s ∩ t =ᶠ[l] s ↔ ∀ᶠ (x : α) in l, x ∈ s → x ∈ t

Next tactic:
simp only [eventuallyEq_set, mem_inter_iff, and_iff_left_iff_imp]
theorem inter_eventuallyEq_right {s t : Set α} {l : Filter α} :
    (s ∩ t : Set α) =ᶠ[l] t ↔ ∀ᶠ x in l, x ∈ t → x ∈ s := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
s t : Set α
l : Filter α
⊢ s ∩ t =ᶠ[l] t ↔ ∀ᶠ (x : α) in l, x ∈ t → x ∈ s

Next tactic:
rw [inter_comm, inter_eventuallyEq_left]
theorem EventuallyEq.sub_eq [AddGroup β] {f g : α → β} {l : Filter α} (h : f =ᶠ[l] g) :
    f - g =ᶠ[l] 0 := by 

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
inst✝ : AddGroup β
f g : α → β
l : Filter α
h : f =ᶠ[l] g
⊢ f - g =ᶠ[l] 0

Next tactic:
simpa using ((EventuallyEq.refl l f).sub h).symm
theorem eventuallyEq_iff_sub [AddGroup β] {f g : α → β} {l : Filter α} :
    f =ᶠ[l] g ↔ f - g =ᶠ[l] 0 :=
  ⟨fun h => h.sub_eq, fun h => by 

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
inst✝ : AddGroup β
f g : α → β
l : Filter α
h : f - g =ᶠ[l] 0
⊢ f =ᶠ[l] g

Next tactic:
simpa using h.add (EventuallyEq.refl l g)
theorem EventuallyLE.congr {f f' g g' : α → β} (H : f ≤ᶠ[l] g) (hf : f =ᶠ[l] f') (hg : g =ᶠ[l] g') :
    f' ≤ᶠ[l] g' :=
  H.mp <| hg.mp <| hf.mono fun x hf hg H => by 

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
inst✝ : LE β
l : Filter α
f f' g g' : α → β
H✝ : f ≤ᶠ[l] g
hf✝ : f =ᶠ[l] f'
hg✝ : g =ᶠ[l] g'
x : α
hf : f x = f' x
hg : g x = g' x
H : f x ≤ g x
⊢ f' x ≤ g' x

Next tactic:
rwa [hf, hg] at H
theorem eventuallyLE_antisymm_iff [PartialOrder β] {l : Filter α} {f g : α → β} :
    f =ᶠ[l] g ↔ f ≤ᶠ[l] g ∧ g ≤ᶠ[l] f := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
inst✝ : PartialOrder β
l : Filter α
f g : α → β
⊢ f =ᶠ[l] g ↔ f ≤ᶠ[l] g ∧ g ≤ᶠ[l] f

Next tactic:
simp only [EventuallyEq, EventuallyLE, le_antisymm_iff, eventually_and]
lemma _root_.Set.Finite.eventuallyLE_iUnion {ι : Type*} {s : Set ι} (hs : s.Finite)
    {f g : ι → Set α} (hle : ∀ i ∈ s, f i ≤ᶠ[l] g i) : (⋃ i ∈ s, f i) ≤ᶠ[l] (⋃ i ∈ s, g i) := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι✝ : Sort x
l : Filter α
ι : Type u_2
s : Set ι
hs : Set.Finite s
f g : ι → Set α
hle : ∀ i ∈ s, f i ≤ᶠ[l] g i
⊢ ⋃ i ∈ s, f i ≤ᶠ[l] ⋃ i ∈ s, g i

Next tactic:
have := hs.to_subtype
lemma _root_.Set.Finite.eventuallyLE_iUnion {ι : Type*} {s : Set ι} (hs : s.Finite)
    {f g : ι → Set α} (hle : ∀ i ∈ s, f i ≤ᶠ[l] g i) : (⋃ i ∈ s, f i) ≤ᶠ[l] (⋃ i ∈ s, g i) := by
  have := hs.to_subtype
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι✝ : Sort x
l : Filter α
ι : Type u_2
s : Set ι
hs : Set.Finite s
f g : ι → Set α
hle : ∀ i ∈ s, f i ≤ᶠ[l] g i
this : Finite ↑s
⊢ ⋃ i ∈ s, f i ≤ᶠ[l] ⋃ i ∈ s, g i

Next tactic:
rw [biUnion_eq_iUnion, biUnion_eq_iUnion]
lemma _root_.Set.Finite.eventuallyLE_iUnion {ι : Type*} {s : Set ι} (hs : s.Finite)
    {f g : ι → Set α} (hle : ∀ i ∈ s, f i ≤ᶠ[l] g i) : (⋃ i ∈ s, f i) ≤ᶠ[l] (⋃ i ∈ s, g i) := by
  have := hs.to_subtype
  rw [biUnion_eq_iUnion, biUnion_eq_iUnion]
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι✝ : Sort x
l : Filter α
ι : Type u_2
s : Set ι
hs : Set.Finite s
f g : ι → Set α
hle : ∀ i ∈ s, f i ≤ᶠ[l] g i
this : Finite ↑s
⊢ ⋃ x, f ↑x ≤ᶠ[l] ⋃ x, g ↑x

Next tactic:
exact .iUnion fun i ↦ hle i.1 i.2
lemma _root_.Set.Finite.eventuallyLE_iInter {ι : Type*} {s : Set ι} (hs : s.Finite)
    {f g : ι → Set α} (hle : ∀ i ∈ s, f i ≤ᶠ[l] g i) : (⋂ i ∈ s, f i) ≤ᶠ[l] (⋂ i ∈ s, g i) := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι✝ : Sort x
l : Filter α
ι : Type u_2
s : Set ι
hs : Set.Finite s
f g : ι → Set α
hle : ∀ i ∈ s, f i ≤ᶠ[l] g i
⊢ ⋂ i ∈ s, f i ≤ᶠ[l] ⋂ i ∈ s, g i

Next tactic:
have := hs.to_subtype
lemma _root_.Set.Finite.eventuallyLE_iInter {ι : Type*} {s : Set ι} (hs : s.Finite)
    {f g : ι → Set α} (hle : ∀ i ∈ s, f i ≤ᶠ[l] g i) : (⋂ i ∈ s, f i) ≤ᶠ[l] (⋂ i ∈ s, g i) := by
  have := hs.to_subtype
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι✝ : Sort x
l : Filter α
ι : Type u_2
s : Set ι
hs : Set.Finite s
f g : ι → Set α
hle : ∀ i ∈ s, f i ≤ᶠ[l] g i
this : Finite ↑s
⊢ ⋂ i ∈ s, f i ≤ᶠ[l] ⋂ i ∈ s, g i

Next tactic:
rw [biInter_eq_iInter, biInter_eq_iInter]
lemma _root_.Set.Finite.eventuallyLE_iInter {ι : Type*} {s : Set ι} (hs : s.Finite)
    {f g : ι → Set α} (hle : ∀ i ∈ s, f i ≤ᶠ[l] g i) : (⋂ i ∈ s, f i) ≤ᶠ[l] (⋂ i ∈ s, g i) := by
  have := hs.to_subtype
  rw [biInter_eq_iInter, biInter_eq_iInter]
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι✝ : Sort x
l : Filter α
ι : Type u_2
s : Set ι
hs : Set.Finite s
f g : ι → Set α
hle : ∀ i ∈ s, f i ≤ᶠ[l] g i
this : Finite ↑s
⊢ ⋂ x, f ↑x ≤ᶠ[l] ⋂ x, g ↑x

Next tactic:
exact .iInter fun i ↦ hle i.1 i.2
theorem set_eventuallyLE_iff_inf_principal_le {s t : Set α} {l : Filter α} :
    s ≤ᶠ[l] t ↔ l ⊓ 𝓟 s ≤ l ⊓ 𝓟 t :=
  set_eventuallyLE_iff_mem_inf_principal.trans <| by
    

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
s t : Set α
l : Filter α
⊢ t ∈ l ⊓ 𝓟 s ↔ l ⊓ 𝓟 s ≤ l ⊓ 𝓟 t

Next tactic:
simp only [le_inf_iff, inf_le_left, true_and_iff, le_principal_iff]
theorem set_eventuallyEq_iff_inf_principal {s t : Set α} {l : Filter α} :
    s =ᶠ[l] t ↔ l ⊓ 𝓟 s = l ⊓ 𝓟 t := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
s t : Set α
l : Filter α
⊢ s =ᶠ[l] t ↔ l ⊓ 𝓟 s = l ⊓ 𝓟 t

Next tactic:
simp only [eventuallyLE_antisymm_iff, le_antisymm_iff, set_eventuallyLE_iff_inf_principal_le]
theorem EventuallyLE.mul_le_mul [MulZeroClass β] [PartialOrder β] [PosMulMono β] [MulPosMono β]
    {l : Filter α} {f₁ f₂ g₁ g₂ : α → β} (hf : f₁ ≤ᶠ[l] f₂) (hg : g₁ ≤ᶠ[l] g₂) (hg₀ : 0 ≤ᶠ[l] g₁)
    (hf₀ : 0 ≤ᶠ[l] f₂) : f₁ * g₁ ≤ᶠ[l] f₂ * g₂ := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
inst✝³ : MulZeroClass β
inst✝² : PartialOrder β
inst✝¹ : PosMulMono β
inst✝ : MulPosMono β
l : Filter α
f₁ f₂ g₁ g₂ : α → β
hf : f₁ ≤ᶠ[l] f₂
hg : g₁ ≤ᶠ[l] g₂
hg₀ : 0 ≤ᶠ[l] g₁
hf₀ : 0 ≤ᶠ[l] f₂
⊢ f₁ * g₁ ≤ᶠ[l] f₂ * g₂

Next tactic:
filter_upwards [hf, hg, hg₀, hf₀] with x using _root_.mul_le_mul
@[to_additive EventuallyLE.add_le_add]
theorem EventuallyLE.mul_le_mul' [Mul β] [Preorder β] [CovariantClass β β (· * ·) (· ≤ ·)]
    [CovariantClass β β (swap (· * ·)) (· ≤ ·)] {l : Filter α} {f₁ f₂ g₁ g₂ : α → β}
    (hf : f₁ ≤ᶠ[l] f₂) (hg : g₁ ≤ᶠ[l] g₂) : f₁ * g₁ ≤ᶠ[l] f₂ * g₂ := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
inst✝³ : Mul β
inst✝² : Preorder β
inst✝¹ : CovariantClass β β (fun x x_1 => x * x_1) fun x x_1 => x ≤ x_1
inst✝ : CovariantClass β β (swap fun x x_1 => x * x_1) fun x x_1 => x ≤ x_1
l : Filter α
f₁ f₂ g₁ g₂ : α → β
hf : f₁ ≤ᶠ[l] f₂
hg : g₁ ≤ᶠ[l] g₂
⊢ f₁ * g₁ ≤ᶠ[l] f₂ * g₂

Next tactic:
filter_upwards [hf, hg] with x hfx hgx using _root_.mul_le_mul' hfx hgx
theorem EventuallyLE.mul_nonneg [OrderedSemiring β] {l : Filter α} {f g : α → β} (hf : 0 ≤ᶠ[l] f)
    (hg : 0 ≤ᶠ[l] g) : 0 ≤ᶠ[l] f * g := by 

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
inst✝ : OrderedSemiring β
l : Filter α
f g : α → β
hf : 0 ≤ᶠ[l] f
hg : 0 ≤ᶠ[l] g
⊢ 0 ≤ᶠ[l] f * g

Next tactic:
filter_upwards [hf, hg] with x using _root_.mul_nonneg
theorem EventuallyLE.sup [SemilatticeSup β] {l : Filter α} {f₁ f₂ g₁ g₂ : α → β} (hf : f₁ ≤ᶠ[l] f₂)
    (hg : g₁ ≤ᶠ[l] g₂) : f₁ ⊔ g₁ ≤ᶠ[l] f₂ ⊔ g₂ := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
inst✝ : SemilatticeSup β
l : Filter α
f₁ f₂ g₁ g₂ : α → β
hf : f₁ ≤ᶠ[l] f₂
hg : g₁ ≤ᶠ[l] g₂
⊢ f₁ ⊔ g₁ ≤ᶠ[l] f₂ ⊔ g₂

Next tactic:
filter_upwards [hf, hg] with x hfx hgx using sup_le_sup hfx hgx
theorem EventuallyLE.sup_le [SemilatticeSup β] {l : Filter α} {f g h : α → β} (hf : f ≤ᶠ[l] h)
    (hg : g ≤ᶠ[l] h) : f ⊔ g ≤ᶠ[l] h := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
inst✝ : SemilatticeSup β
l : Filter α
f g h : α → β
hf : f ≤ᶠ[l] h
hg : g ≤ᶠ[l] h
⊢ f ⊔ g ≤ᶠ[l] h

Next tactic:
filter_upwards [hf, hg] with x hfx hgx using _root_.sup_le hfx hgx
@[simp 1100, nolint simpNF]
theorem image_mem_map_iff (hf : Injective m) : m '' s ∈ map m f ↔ s ∈ f :=
  ⟨fun h => by 

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f : Filter α
m : α → β
m' : β → γ
s : Set α
t : Set β
hf : Injective m
h : m '' s ∈ map m f
⊢ s ∈ f

Next tactic:
rwa [← preimage_image_eq s hf]
theorem range_mem_map : range m ∈ map m f := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f : Filter α
m : α → β
m' : β → γ
s : Set α
t : Set β
⊢ range m ∈ map m f

Next tactic:
rw [← image_univ]
theorem range_mem_map : range m ∈ map m f := by
  rw [← image_univ]
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f : Filter α
m : α → β
m' : β → γ
s : Set α
t : Set β
⊢ m '' univ ∈ map m f

Next tactic:
exact image_mem_map univ_mem
/-- The inverse map of a filter. A set `s` belongs to `Filter.comap m f` if either of the following
equivalent conditions hold.

1. There exists a set `t ∈ f` such that `m ⁻¹' t ⊆ s`. This is used as a definition.
2. The set `kernImage m s = {y | ∀ x, m x = y → x ∈ s}` belongs to `f`, see `Filter.mem_comap'`.
3. The set `(m '' sᶜ)ᶜ` belongs to `f`, see `Filter.mem_comap_iff_compl` and
`Filter.compl_mem_comap`. -/
def comap (m : α → β) (f : Filter β) : Filter α
    where
  sets := { s | ∃ t ∈ f, m ⁻¹' t ⊆ s }
  univ_sets := ⟨univ, univ_mem, by 

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
m : α → β
f : Filter β
⊢ m ⁻¹' univ ⊆ univ

Next tactic:
simp only [subset_univ, preimage_univ]
theorem mem_comap' : s ∈ comap f l ↔ { y | ∀ ⦃x⦄, f x = y → x ∈ s } ∈ l :=
  ⟨fun ⟨t, ht, hts⟩ => mem_of_superset ht fun y hy x hx => hts <| mem_preimage.2 <| by 

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f : α → β
l : Filter β
p : α → Prop
s : Set α
x✝ : s ∈ comap f l
t : Set β
ht : t ∈ l
hts : f ⁻¹' t ⊆ s
y : β
hy : y ∈ t
x : α
hx : f x = y
⊢ f x ∈ t

Next tactic:
rwa [hx]
/-- RHS form is used, e.g., in the definition of `UniformSpace`. -/
lemma mem_comap_prod_mk {x : α} {s : Set β} {F : Filter (α × β)} :
    s ∈ comap (Prod.mk x) F ↔ {p : α × β | p.fst = x → p.snd ∈ s} ∈ F := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f : α → β
l : Filter β
p : α → Prop
s✝ : Set α
x : α
s : Set β
F : Filter (α × β)
⊢ s ∈ comap (Prod.mk x) F ↔ {p | p.1 = x → p.2 ∈ s} ∈ F

Next tactic:
simp_rw [mem_comap', Prod.ext_iff, and_imp, @forall_swap β (_ = _), forall_eq, eq_comm]
@[simp]
theorem frequently_comap : (∃ᶠ a in comap f l, p a) ↔ ∃ᶠ b in l, ∃ a, f a = b ∧ p a := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f : α → β
l : Filter β
p : α → Prop
s : Set α
⊢ (∃ᶠ (a : α) in comap f l, p a) ↔ ∃ᶠ (b : β) in l, ∃ a, f a = b ∧ p a

Next tactic:
simp only [Filter.Frequently, eventually_comap, not_exists, not_and]
theorem mem_comap_iff_compl : s ∈ comap f l ↔ (f '' sᶜ)ᶜ ∈ l := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f : α → β
l : Filter β
p : α → Prop
s : Set α
⊢ s ∈ comap f l ↔ (f '' sᶜ)ᶜ ∈ l

Next tactic:
simp only [mem_comap'', kernImage_eq_compl]
theorem compl_mem_comap : sᶜ ∈ comap f l ↔ (f '' s)ᶜ ∈ l := by 

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f : α → β
l : Filter β
p : α → Prop
s : Set α
⊢ sᶜ ∈ comap f l ↔ (f '' s)ᶜ ∈ l

Next tactic:
rw [mem_comap_iff_compl, compl_compl]
/-- The analog of `kernImage` for filters. A set `s` belongs to `Filter.kernMap m f` if either of
the following equivalent conditions hold.

1. There exists a set `t ∈ f` such that `s = kernImage m t`. This is used as a definition.
2. There exists a set `t` such that `tᶜ ∈ f` and `sᶜ = m '' t`, see `Filter.mem_kernMap_iff_compl`
and `Filter.compl_mem_kernMap`.

This definition because it gives a right adjoint to `Filter.comap`, and because it has a nice
interpretation when working with `co-` filters (`Filter.cocompact`, `Filter.cofinite`, ...).
For example, `kernMap m (cocompact α)` is the filter generated by the complements of the sets
`m '' K` where `K` is a compact subset of `α`. -/
def kernMap (m : α → β) (f : Filter α) : Filter β where
  sets := (kernImage m) '' f.sets
  univ_sets := ⟨univ, f.univ_sets, by 

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
m : α → β
f : Filter α
⊢ kernImage m univ = univ

Next tactic:
simp [kernImage_eq_compl]
/-- The analog of `kernImage` for filters. A set `s` belongs to `Filter.kernMap m f` if either of
the following equivalent conditions hold.

1. There exists a set `t ∈ f` such that `s = kernImage m t`. This is used as a definition.
2. There exists a set `t` such that `tᶜ ∈ f` and `sᶜ = m '' t`, see `Filter.mem_kernMap_iff_compl`
and `Filter.compl_mem_kernMap`.

This definition because it gives a right adjoint to `Filter.comap`, and because it has a nice
interpretation when working with `co-` filters (`Filter.cocompact`, `Filter.cofinite`, ...).
For example, `kernMap m (cocompact α)` is the filter generated by the complements of the sets
`m '' K` where `K` is a compact subset of `α`. -/
def kernMap (m : α → β) (f : Filter α) : Filter β where
  sets := (kernImage m) '' f.sets
  univ_sets := ⟨univ, f.univ_sets, by simp [kernImage_eq_compl]⟩
  sets_of_superset := by
    

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
m : α → β
f : Filter α
⊢ ∀ {x y : Set β}, x ∈ kernImage m '' f.sets → x ⊆ y → y ∈ kernImage m '' f.sets

Next tactic:
rintro _ t ⟨s, hs, rfl⟩ hst
/-- The analog of `kernImage` for filters. A set `s` belongs to `Filter.kernMap m f` if either of
the following equivalent conditions hold.

1. There exists a set `t ∈ f` such that `s = kernImage m t`. This is used as a definition.
2. There exists a set `t` such that `tᶜ ∈ f` and `sᶜ = m '' t`, see `Filter.mem_kernMap_iff_compl`
and `Filter.compl_mem_kernMap`.

This definition because it gives a right adjoint to `Filter.comap`, and because it has a nice
interpretation when working with `co-` filters (`Filter.cocompact`, `Filter.cofinite`, ...).
For example, `kernMap m (cocompact α)` is the filter generated by the complements of the sets
`m '' K` where `K` is a compact subset of `α`. -/
def kernMap (m : α → β) (f : Filter α) : Filter β where
  sets := (kernImage m) '' f.sets
  univ_sets := ⟨univ, f.univ_sets, by simp [kernImage_eq_compl]⟩
  sets_of_superset := by
    rintro _ t ⟨s, hs, rfl⟩ hst
    

Proof state:
case intro.intro
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
m : α → β
f : Filter α
t : Set β
s : Set α
hs : s ∈ f.sets
hst : kernImage m s ⊆ t
⊢ t ∈ kernImage m '' f.sets

Next tactic:
refine ⟨s ∪ m ⁻¹' t, mem_of_superset hs (subset_union_left s _), ?_⟩
/-- The analog of `kernImage` for filters. A set `s` belongs to `Filter.kernMap m f` if either of
the following equivalent conditions hold.

1. There exists a set `t ∈ f` such that `s = kernImage m t`. This is used as a definition.
2. There exists a set `t` such that `tᶜ ∈ f` and `sᶜ = m '' t`, see `Filter.mem_kernMap_iff_compl`
and `Filter.compl_mem_kernMap`.

This definition because it gives a right adjoint to `Filter.comap`, and because it has a nice
interpretation when working with `co-` filters (`Filter.cocompact`, `Filter.cofinite`, ...).
For example, `kernMap m (cocompact α)` is the filter generated by the complements of the sets
`m '' K` where `K` is a compact subset of `α`. -/
def kernMap (m : α → β) (f : Filter α) : Filter β where
  sets := (kernImage m) '' f.sets
  univ_sets := ⟨univ, f.univ_sets, by simp [kernImage_eq_compl]⟩
  sets_of_superset := by
    rintro _ t ⟨s, hs, rfl⟩ hst
    refine ⟨s ∪ m ⁻¹' t, mem_of_superset hs (subset_union_left s _), ?_⟩
    

Proof state:
case intro.intro
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
m : α → β
f : Filter α
t : Set β
s : Set α
hs : s ∈ f.sets
hst : kernImage m s ⊆ t
⊢ kernImage m (s ∪ m ⁻¹' t) = t

Next tactic:
rw [kernImage_union_preimage, union_eq_right.mpr hst]
/-- The analog of `kernImage` for filters. A set `s` belongs to `Filter.kernMap m f` if either of
the following equivalent conditions hold.

1. There exists a set `t ∈ f` such that `s = kernImage m t`. This is used as a definition.
2. There exists a set `t` such that `tᶜ ∈ f` and `sᶜ = m '' t`, see `Filter.mem_kernMap_iff_compl`
and `Filter.compl_mem_kernMap`.

This definition because it gives a right adjoint to `Filter.comap`, and because it has a nice
interpretation when working with `co-` filters (`Filter.cocompact`, `Filter.cofinite`, ...).
For example, `kernMap m (cocompact α)` is the filter generated by the complements of the sets
`m '' K` where `K` is a compact subset of `α`. -/
def kernMap (m : α → β) (f : Filter α) : Filter β where
  sets := (kernImage m) '' f.sets
  univ_sets := ⟨univ, f.univ_sets, by simp [kernImage_eq_compl]⟩
  sets_of_superset := by
    rintro _ t ⟨s, hs, rfl⟩ hst
    refine ⟨s ∪ m ⁻¹' t, mem_of_superset hs (subset_union_left s _), ?_⟩
    rw [kernImage_union_preimage, union_eq_right.mpr hst]
  inter_sets := by
    

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
m : α → β
f : Filter α
⊢ ∀ {x y : Set β}, x ∈ kernImage m '' f.sets → y ∈ kernImage m '' f.sets → x ∩ y ∈ kernImage m '' f.sets

Next tactic:
rintro _ _ ⟨s₁, h₁, rfl⟩ ⟨s₂, h₂, rfl⟩