l3lab/ntp-mathlib huggingface dataset:
/-- 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
    rintro _ _ ⟨s₁, h₁, rfl⟩ ⟨s₂, h₂, rfl⟩
    

Proof state:
case intro.intro.intro.intro
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
m : α → β
f : Filter α
s₁ : Set α
h₁ : s₁ ∈ f.sets
s₂ : Set α
h₂ : s₂ ∈ f.sets
⊢ kernImage m s₁ ∩ kernImage m s₂ ∈ kernImage m '' f.sets

Next tactic:
exact ⟨s₁ ∩ s₂, f.inter_sets h₁ h₂, Set.preimage_kernImage.u_inf⟩
theorem mem_kernMap_iff_compl {s : Set β} : s ∈ kernMap m f ↔ ∃ t, tᶜ ∈ f ∧ m '' t = sᶜ := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
m : α → β
f : Filter α
s : Set β
⊢ s ∈ kernMap m f ↔ ∃ t, tᶜ ∈ f ∧ m '' t = sᶜ

Next tactic:
rw [mem_kernMap, compl_surjective.exists]
theorem mem_kernMap_iff_compl {s : Set β} : s ∈ kernMap m f ↔ ∃ t, tᶜ ∈ f ∧ m '' t = sᶜ := by
  rw [mem_kernMap, compl_surjective.exists]
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
m : α → β
f : Filter α
s : Set β
⊢ (∃ x, xᶜ ∈ f ∧ kernImage m xᶜ = s) ↔ ∃ t, tᶜ ∈ f ∧ m '' t = sᶜ

Next tactic:
refine exists_congr (fun x ↦ and_congr_right fun _ ↦ ?_)
theorem mem_kernMap_iff_compl {s : Set β} : s ∈ kernMap m f ↔ ∃ t, tᶜ ∈ f ∧ m '' t = sᶜ := by
  rw [mem_kernMap, compl_surjective.exists]
  refine exists_congr (fun x ↦ and_congr_right fun _ ↦ ?_)
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
m : α → β
f : Filter α
s : Set β
x : Set α
x✝ : xᶜ ∈ f
⊢ kernImage m xᶜ = s ↔ m '' x = sᶜ

Next tactic:
rw [kernImage_compl, compl_eq_comm, eq_comm]
theorem compl_mem_kernMap {s : Set β} : sᶜ ∈ kernMap m f ↔ ∃ t, tᶜ ∈ f ∧ m '' t = s := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
m : α → β
f : Filter α
s : Set β
⊢ sᶜ ∈ kernMap m f ↔ ∃ t, tᶜ ∈ f ∧ m '' t = s

Next tactic:
simp_rw [mem_kernMap_iff_compl, compl_compl]
@[simp]
theorem principal_singleton (a : α) : 𝓟 {a} = pure a :=
  Filter.ext fun s => by 

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
a : α
s : Set α
⊢ s ∈ 𝓟 {a} ↔ s ∈ pure a

Next tactic:
simp only [mem_pure, mem_principal, singleton_subset_iff]
@[simp]
theorem pure_bind (a : α) (m : α → Filter β) : bind (pure a) m = m a := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
a : α
m : α → Filter β
⊢ bind (pure a) m = m a

Next tactic:
simp only [Bind.bind, bind, map_pure, join_pure]
theorem map_const [NeBot f] {c : β} : (f.map fun _ => c) = pure c := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m : α → β
m' : β → γ
s : Set α
t : Set β
inst✝ : NeBot f
c : β
⊢ map (fun x => c) f = pure c

Next tactic:
ext s
theorem map_const [NeBot f] {c : β} : (f.map fun _ => c) = pure c := by
  ext s
  

Proof state:
case a
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m : α → β
m' : β → γ
s✝ : Set α
t : Set β
inst✝ : NeBot f
c : β
s : Set β
⊢ s ∈ map (fun x => c) f ↔ s ∈ pure c

Next tactic:
by_cases h : c ∈ s
theorem map_const [NeBot f] {c : β} : (f.map fun _ => c) = pure c := by
  ext s
  by_cases h : c ∈ s <;> 

Proof state:
case pos
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m : α → β
m' : β → γ
s✝ : Set α
t : Set β
inst✝ : NeBot f
c : β
s : Set β
h : c ∈ s
⊢ s ∈ map (fun x => c) f ↔ s ∈ pure c

Next tactic:
simp [h]
theorem map_const [NeBot f] {c : β} : (f.map fun _ => c) = pure c := by
  ext s
  by_cases h : c ∈ s <;> 

Proof state:
case neg
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m : α → β
m' : β → γ
s✝ : Set α
t : Set β
inst✝ : NeBot f
c : β
s : Set β
h : c ∉ s
⊢ s ∈ map (fun x => c) f ↔ s ∈ pure c

Next tactic:
simp [h]
theorem comap_comap {m : γ → β} {n : β → α} : comap m (comap n f) = comap (n ∘ m) f :=
  Filter.coext fun s => by 

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m✝ : α → β
m' : β → γ
s✝ : Set α
t : Set β
m : γ → β
n : β → α
s : Set γ
⊢ sᶜ ∈ comap m (comap n f) ↔ sᶜ ∈ comap (n ∘ m) f

Next tactic:
simp only [compl_mem_comap, image_image, (· ∘ ·)]
theorem map_comm (F : Filter α) : map ψ (map φ F) = map ρ (map θ F) := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m : α → β
m' : β → γ
s : Set α
t : Set β
φ : α → β
θ : α → γ
ψ : β → δ
ρ : γ → δ
H : ψ ∘ φ = ρ ∘ θ
F : Filter α
⊢ map ψ (map φ F) = map ρ (map θ F)

Next tactic:
rw [Filter.map_map, H, ← Filter.map_map]
theorem comap_comm (G : Filter δ) : comap φ (comap ψ G) = comap θ (comap ρ G) := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m : α → β
m' : β → γ
s : Set α
t : Set β
φ : α → β
θ : α → γ
ψ : β → δ
ρ : γ → δ
H : ψ ∘ φ = ρ ∘ θ
G : Filter δ
⊢ comap φ (comap ψ G) = comap θ (comap ρ G)

Next tactic:
rw [Filter.comap_comap, H, ← Filter.comap_comap]
@[simp]
theorem comap_pure {b : β} : comap m (pure b) = 𝓟 (m ⁻¹' {b}) := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m : α → β
m' : β → γ
s : Set α
t : Set β
b : β
⊢ comap m (pure b) = 𝓟 (m ⁻¹' {b})

Next tactic:
rw [← principal_singleton, comap_principal]
theorem comap_le_iff_le_kernMap : comap m g ≤ f ↔ g ≤ kernMap m f := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m : α → β
m' : β → γ
s : Set α
t : Set β
⊢ comap m g ≤ f ↔ g ≤ kernMap m f

Next tactic:
simp [Filter.le_def, mem_comap'', mem_kernMap, -mem_comap]
theorem kernMap_principal {s : Set α} : kernMap m (𝓟 s) = 𝓟 (kernImage m s) := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m : α → β
m' : β → γ
s✝ : Set α
t : Set β
s : Set α
⊢ kernMap m (𝓟 s) = 𝓟 (kernImage m s)

Next tactic:
refine eq_of_forall_le_iff (fun g ↦ ?_)
theorem kernMap_principal {s : Set α} : kernMap m (𝓟 s) = 𝓟 (kernImage m s) := by
  refine eq_of_forall_le_iff (fun g ↦ ?_)
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f f₁ f₂ : Filter α
g✝ g₁ g₂ : Filter β
m : α → β
m' : β → γ
s✝ : Set α
t : Set β
s : Set α
g : Filter β
⊢ g ≤ kernMap m (𝓟 s) ↔ g ≤ 𝓟 (kernImage m s)

Next tactic:
rw [← comap_le_iff_le_kernMap, le_principal_iff, le_principal_iff, mem_comap'']
@[simp]
theorem map_top (f : α → β) : map f ⊤ = 𝓟 (range f) := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f✝ f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m : α → β
m' : β → γ
s : Set α
t : Set β
f : α → β
⊢ map f ⊤ = 𝓟 (range f)

Next tactic:
rw [← principal_univ, map_principal, image_univ]
theorem le_comap_top (f : α → β) (l : Filter α) : l ≤ comap f ⊤ := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f✝ f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m : α → β
m' : β → γ
s : Set α
t : Set β
f : α → β
l : Filter α
⊢ l ≤ comap f ⊤

Next tactic:
rw [comap_top]
theorem le_comap_top (f : α → β) (l : Filter α) : l ≤ comap f ⊤ := by
  rw [comap_top]
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f✝ f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m : α → β
m' : β → γ
s : Set α
t : Set β
f : α → β
l : Filter α
⊢ l ≤ ⊤

Next tactic:
exact le_top
@[simp]
theorem comap_bot : comap m ⊥ = ⊥ :=
  bot_unique fun s _ => ⟨∅, mem_bot, by 

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m : α → β
m' : β → γ
s✝ : Set α
t : Set β
s : Set α
x✝ : s ∈ ⊥
⊢ m ⁻¹' ∅ ⊆ s

Next tactic:
simp only [empty_subset, preimage_empty]
theorem neBot_of_comap (h : (comap m g).NeBot) : g.NeBot := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m : α → β
m' : β → γ
s : Set α
t : Set β
h : NeBot (comap m g)
⊢ NeBot g

Next tactic:
rw [neBot_iff] at *
theorem neBot_of_comap (h : (comap m g).NeBot) : g.NeBot := by
  rw [neBot_iff] at *
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m : α → β
m' : β → γ
s : Set α
t : Set β
h : comap m g ≠ ⊥
⊢ g ≠ ⊥

Next tactic:
contrapose! h
theorem neBot_of_comap (h : (comap m g).NeBot) : g.NeBot := by
  rw [neBot_iff] at *
  contrapose! h
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m : α → β
m' : β → γ
s : Set α
t : Set β
h : g = ⊥
⊢ comap m g = ⊥

Next tactic:
rw [h]
theorem neBot_of_comap (h : (comap m g).NeBot) : g.NeBot := by
  rw [neBot_iff] at *
  contrapose! h
  rw [h]
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m : α → β
m' : β → γ
s : Set α
t : Set β
h : g = ⊥
⊢ comap m ⊥ = ⊥

Next tactic:
exact comap_bot
theorem comap_inf_principal_range : comap m (g ⊓ 𝓟 (range m)) = comap m g := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m : α → β
m' : β → γ
s : Set α
t : Set β
⊢ comap m (g ⊓ 𝓟 (range m)) = comap m g

Next tactic:
simpa only [le_principal_iff, comap_inf, comap_principal, preimage_range, principal_univ,
    inf_eq_left] using le_top
theorem disjoint_comap (h : Disjoint g₁ g₂) : Disjoint (comap m g₁) (comap m g₂) := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m : α → β
m' : β → γ
s : Set α
t : Set β
h : Disjoint g₁ g₂
⊢ Disjoint (comap m g₁) (comap m g₂)

Next tactic:
simp only [disjoint_iff, ← comap_inf, h.eq_bot, comap_bot]
theorem comap_sSup {s : Set (Filter β)} {m : α → β} : comap m (sSup s) = ⨆ f ∈ s, comap m f := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m✝ : α → β
m' : β → γ
s✝ : Set α
t : Set β
s : Set (Filter β)
m : α → β
⊢ comap m (sSup s) = ⨆ f ∈ s, comap m f

Next tactic:
simp only [sSup_eq_iSup, comap_iSup, eq_self_iff_true]
theorem comap_sup : comap m (g₁ ⊔ g₂) = comap m g₁ ⊔ comap m g₂ := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m : α → β
m' : β → γ
s : Set α
t : Set β
⊢ comap m (g₁ ⊔ g₂) = comap m g₁ ⊔ comap m g₂

Next tactic:
rw [sup_eq_iSup, comap_iSup, iSup_bool_eq, Bool.cond_true, Bool.cond_false]
theorem map_comap (f : Filter β) (m : α → β) : (f.comap m).map m = f ⊓ 𝓟 (range m) := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f✝ f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m✝ : α → β
m' : β → γ
s : Set α
t : Set β
f : Filter β
m : α → β
⊢ map m (comap m f) = f ⊓ 𝓟 (range m)

Next tactic:
refine' le_antisymm (le_inf map_comap_le <| le_principal_iff.2 range_mem_map) _
theorem map_comap (f : Filter β) (m : α → β) : (f.comap m).map m = f ⊓ 𝓟 (range m) := by
  refine' le_antisymm (le_inf map_comap_le <| le_principal_iff.2 range_mem_map) _
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f✝ f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m✝ : α → β
m' : β → γ
s : Set α
t : Set β
f : Filter β
m : α → β
⊢ f ⊓ 𝓟 (range m) ≤ map m (comap m f)

Next tactic:
rintro t' ⟨t, ht, sub⟩
theorem map_comap (f : Filter β) (m : α → β) : (f.comap m).map m = f ⊓ 𝓟 (range m) := by
  refine' le_antisymm (le_inf map_comap_le <| le_principal_iff.2 range_mem_map) _
  rintro t' ⟨t, ht, sub⟩
  

Proof state:
case intro.intro
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f✝ f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m✝ : α → β
m' : β → γ
s : Set α
t✝ : Set β
f : Filter β
m : α → β
t' t : Set β
ht : t ∈ f
sub : m ⁻¹' t ⊆ m ⁻¹' t'
⊢ t' ∈ f ⊓ 𝓟 (range m)

Next tactic:
refine' mem_inf_principal.2 (mem_of_superset ht _)
theorem map_comap (f : Filter β) (m : α → β) : (f.comap m).map m = f ⊓ 𝓟 (range m) := by
  refine' le_antisymm (le_inf map_comap_le <| le_principal_iff.2 range_mem_map) _
  rintro t' ⟨t, ht, sub⟩
  refine' mem_inf_principal.2 (mem_of_superset ht _)
  

Proof state:
case intro.intro
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f✝ f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m✝ : α → β
m' : β → γ
s : Set α
t✝ : Set β
f : Filter β
m : α → β
t' t : Set β
ht : t ∈ f
sub : m ⁻¹' t ⊆ m ⁻¹' t'
⊢ t ⊆ {x | x ∈ range m → x ∈ t'}

Next tactic:
rintro _ hxt ⟨x, rfl⟩
theorem map_comap (f : Filter β) (m : α → β) : (f.comap m).map m = f ⊓ 𝓟 (range m) := by
  refine' le_antisymm (le_inf map_comap_le <| le_principal_iff.2 range_mem_map) _
  rintro t' ⟨t, ht, sub⟩
  refine' mem_inf_principal.2 (mem_of_superset ht _)
  rintro _ hxt ⟨x, rfl⟩
  

Proof state:
case intro.intro.intro
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f✝ f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m✝ : α → β
m' : β → γ
s : Set α
t✝ : Set β
f : Filter β
m : α → β
t' t : Set β
ht : t ∈ f
sub : m ⁻¹' t ⊆ m ⁻¹' t'
x : α
hxt : m x ∈ t
⊢ m x ∈ t'

Next tactic:
exact sub hxt
theorem map_comap_setCoe_val (f : Filter β) (s : Set β) :
    (f.comap ((↑) : s → β)).map (↑) = f ⊓ 𝓟 s := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f✝ f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m : α → β
m' : β → γ
s✝ : Set α
t : Set β
f : Filter β
s : Set β
⊢ map Subtype.val (comap Subtype.val f) = f ⊓ 𝓟 s

Next tactic:
rw [map_comap, Subtype.range_val]
theorem map_comap_of_mem {f : Filter β} {m : α → β} (hf : range m ∈ f) : (f.comap m).map m = f := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f✝ f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m✝ : α → β
m' : β → γ
s : Set α
t : Set β
f : Filter β
m : α → β
hf : range m ∈ f
⊢ map m (comap m f) = f

Next tactic:
rw [map_comap, inf_eq_left.2 (le_principal_iff.2 hf)]
theorem map_comap_of_surjective {f : α → β} (hf : Surjective f) (l : Filter β) :
    map f (comap f l) = l :=
  map_comap_of_mem <| by 

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f✝ f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m : α → β
m' : β → γ
s : Set α
t : Set β
f : α → β
hf : Surjective f
l : Filter β
⊢ range f ∈ l

Next tactic:
simp only [hf.range_eq, univ_mem]
theorem subtype_coe_map_comap (s : Set α) (f : Filter α) :
    map ((↑) : s → α) (comap ((↑) : s → α) f) = f ⊓ 𝓟 s := by 

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f✝ f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m : α → β
m' : β → γ
s✝ : Set α
t : Set β
s : Set α
f : Filter α
⊢ map Subtype.val (comap Subtype.val f) = f ⊓ 𝓟 s

Next tactic:
rw [map_comap, Subtype.range_coe]
theorem image_mem_of_mem_comap {f : Filter α} {c : β → α} (h : range c ∈ f) {W : Set β}
    (W_in : W ∈ comap c f) : c '' W ∈ f := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f✝ f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m : α → β
m' : β → γ
s : Set α
t : Set β
f : Filter α
c : β → α
h : range c ∈ f
W : Set β
W_in : W ∈ comap c f
⊢ c '' W ∈ f

Next tactic:
rw [← map_comap_of_mem h]
theorem image_mem_of_mem_comap {f : Filter α} {c : β → α} (h : range c ∈ f) {W : Set β}
    (W_in : W ∈ comap c f) : c '' W ∈ f := by
  rw [← map_comap_of_mem h]
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f✝ f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m : α → β
m' : β → γ
s : Set α
t : Set β
f : Filter α
c : β → α
h : range c ∈ f
W : Set β
W_in : W ∈ comap c f
⊢ c '' W ∈ map c (comap c f)

Next tactic:
exact image_mem_map W_in
theorem image_coe_mem_of_mem_comap {f : Filter α} {U : Set α} (h : U ∈ f) {W : Set U}
    (W_in : W ∈ comap ((↑) : U → α) f) : (↑) '' W ∈ f :=
  image_mem_of_mem_comap (by 

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f✝ f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m : α → β
m' : β → γ
s : Set α
t : Set β
f : Filter α
U : Set α
h : U ∈ f
W : Set ↑U
W_in : W ∈ comap Subtype.val f
⊢ range Subtype.val ∈ f

Next tactic:
simp [h]
theorem comap_map {f : Filter α} {m : α → β} (h : Injective m) : comap m (map m f) = f :=
  le_antisymm
    (fun s hs =>
      mem_of_superset (preimage_mem_comap <| image_mem_map hs) <| by
        

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f✝ f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m✝ : α → β
m' : β → γ
s✝ : Set α
t : Set β
f : Filter α
m : α → β
h : Injective m
s : Set α
hs : s ∈ f
⊢ m ⁻¹' (m '' s) ⊆ s

Next tactic:
simp only [preimage_image_eq s h, Subset.rfl]
theorem mem_comap_iff {f : Filter β} {m : α → β} (inj : Injective m) (large : Set.range m ∈ f)
    {S : Set α} : S ∈ comap m f ↔ m '' S ∈ f := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f✝ f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m✝ : α → β
m' : β → γ
s : Set α
t : Set β
f : Filter β
m : α → β
inj : Injective m
large : range m ∈ f
S : Set α
⊢ S ∈ comap m f ↔ m '' S ∈ f

Next tactic:
rw [← image_mem_map_iff inj, map_comap_of_mem large]
theorem map_le_map_iff {f g : Filter α} {m : α → β} (hm : Injective m) :
    map m f ≤ map m g ↔ f ≤ g := by 

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f✝ f₁ f₂ : Filter α
g✝ g₁ g₂ : Filter β
m✝ : α → β
m' : β → γ
s : Set α
t : Set β
f g : Filter α
m : α → β
hm : Injective m
⊢ map m f ≤ map m g ↔ f ≤ g

Next tactic:
rw [map_le_iff_le_comap, comap_map hm]
theorem map_eq_map_iff_of_injOn {f g : Filter α} {m : α → β} {s : Set α} (hsf : s ∈ f) (hsg : s ∈ g)
    (hm : InjOn m s) : map m f = map m g ↔ f = g := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f✝ f₁ f₂ : Filter α
g✝ g₁ g₂ : Filter β
m✝ : α → β
m' : β → γ
s✝ : Set α
t : Set β
f g : Filter α
m : α → β
s : Set α
hsf : s ∈ f
hsg : s ∈ g
hm : InjOn m s
⊢ map m f = map m g ↔ f = g

Next tactic:
simp only [le_antisymm_iff, map_le_map_iff_of_injOn hsf hsg hm,
    map_le_map_iff_of_injOn hsg hsf hm]
theorem comap_neBot_iff {f : Filter β} {m : α → β} : NeBot (comap m f) ↔ ∀ t ∈ f, ∃ a, m a ∈ t := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f✝ f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m✝ : α → β
m' : β → γ
s : Set α
t : Set β
f : Filter β
m : α → β
⊢ NeBot (comap m f) ↔ ∀ t ∈ f, ∃ a, m a ∈ t

Next tactic:
simp only [← forall_mem_nonempty_iff_neBot, mem_comap, forall_exists_index, and_imp]
theorem comap_neBot_iff {f : Filter β} {m : α → β} : NeBot (comap m f) ↔ ∀ t ∈ f, ∃ a, m a ∈ t := by
  simp only [← forall_mem_nonempty_iff_neBot, mem_comap, forall_exists_index, and_imp]
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f✝ f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m✝ : α → β
m' : β → γ
s : Set α
t : Set β
f : Filter β
m : α → β
⊢ (∀ (s : Set α), ∀ x ∈ f, m ⁻¹' x ⊆ s → Set.Nonempty s) ↔ ∀ t ∈ f, ∃ a, m a ∈ t

Next tactic:
exact ⟨fun h t t_in => h (m ⁻¹' t) t t_in Subset.rfl, fun h s t ht hst => (h t ht).imp hst⟩
theorem comap_neBot_iff_frequently {f : Filter β} {m : α → β} :
    NeBot (comap m f) ↔ ∃ᶠ y in f, y ∈ range m := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f✝ f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m✝ : α → β
m' : β → γ
s : Set α
t : Set β
f : Filter β
m : α → β
⊢ NeBot (comap m f) ↔ ∃ᶠ (y : β) in f, y ∈ range m

Next tactic:
simp only [comap_neBot_iff, frequently_iff, mem_range, @and_comm (_ ∈ _), exists_exists_eq_and]
theorem comap_surjective_eq_bot {f : Filter β} {m : α → β} (hm : Surjective m) :
    comap m f = ⊥ ↔ f = ⊥ := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f✝ f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m✝ : α → β
m' : β → γ
s : Set α
t : Set β
f : Filter β
m : α → β
hm : Surjective m
⊢ comap m f = ⊥ ↔ f = ⊥

Next tactic:
rw [comap_eq_bot_iff_compl_range, hm.range_eq, compl_univ, empty_mem_iff_bot]
theorem disjoint_comap_iff (h : Surjective m) :
    Disjoint (comap m g₁) (comap m g₂) ↔ Disjoint g₁ g₂ := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m : α → β
m' : β → γ
s : Set α
t : Set β
h : Surjective m
⊢ Disjoint (comap m g₁) (comap m g₂) ↔ Disjoint g₁ g₂

Next tactic:
rw [disjoint_iff, disjoint_iff, ← comap_inf, comap_surjective_eq_bot h]
@[simp]
theorem comap_fst_neBot_iff {f : Filter α} :
    (f.comap (Prod.fst : α × β → α)).NeBot ↔ f.NeBot ∧ Nonempty β := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f✝ f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m : α → β
m' : β → γ
s : Set α
t : Set β
f : Filter α
⊢ NeBot (comap Prod.fst f) ↔ NeBot f ∧ Nonempty β

Next tactic:
cases isEmpty_or_nonempty β
@[simp]
theorem comap_fst_neBot_iff {f : Filter α} :
    (f.comap (Prod.fst : α × β → α)).NeBot ↔ f.NeBot ∧ Nonempty β := by
  cases isEmpty_or_nonempty β
  · 

Proof state:
case inl
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f✝ f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m : α → β
m' : β → γ
s : Set α
t : Set β
f : Filter α
h✝ : IsEmpty β
⊢ NeBot (comap Prod.fst f) ↔ NeBot f ∧ Nonempty β

Next tactic:
rw [filter_eq_bot_of_isEmpty (f.comap _), ← not_iff_not]
@[simp]
theorem comap_fst_neBot_iff {f : Filter α} :
    (f.comap (Prod.fst : α × β → α)).NeBot ↔ f.NeBot ∧ Nonempty β := by
  cases isEmpty_or_nonempty β
  · rw [filter_eq_bot_of_isEmpty (f.comap _), ← not_iff_not]; 

Proof state:
case inl
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f✝ f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m : α → β
m' : β → γ
s : Set α
t : Set β
f : Filter α
h✝ : IsEmpty β
⊢ ¬NeBot ⊥ ↔ ¬(NeBot f ∧ Nonempty β)

Next tactic:
simp [*]
@[simp]
theorem comap_fst_neBot_iff {f : Filter α} :
    (f.comap (Prod.fst : α × β → α)).NeBot ↔ f.NeBot ∧ Nonempty β := by
  cases isEmpty_or_nonempty β
  · rw [filter_eq_bot_of_isEmpty (f.comap _), ← not_iff_not]; simp [*]
  · 

Proof state:
case inr
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f✝ f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m : α → β
m' : β → γ
s : Set α
t : Set β
f : Filter α
h✝ : Nonempty β
⊢ NeBot (comap Prod.fst f) ↔ NeBot f ∧ Nonempty β

Next tactic:
simp [comap_neBot_iff_frequently, *]
@[simp]
theorem comap_snd_neBot_iff {f : Filter β} :
    (f.comap (Prod.snd : α × β → β)).NeBot ↔ Nonempty α ∧ f.NeBot := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f✝ f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m : α → β
m' : β → γ
s : Set α
t : Set β
f : Filter β
⊢ NeBot (comap Prod.snd f) ↔ Nonempty α ∧ NeBot f

Next tactic:
cases' isEmpty_or_nonempty α with hα hα
@[simp]
theorem comap_snd_neBot_iff {f : Filter β} :
    (f.comap (Prod.snd : α × β → β)).NeBot ↔ Nonempty α ∧ f.NeBot := by
  cases' isEmpty_or_nonempty α with hα hα
  · 

Proof state:
case inl
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f✝ f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m : α → β
m' : β → γ
s : Set α
t : Set β
f : Filter β
hα : IsEmpty α
⊢ NeBot (comap Prod.snd f) ↔ Nonempty α ∧ NeBot f

Next tactic:
rw [filter_eq_bot_of_isEmpty (f.comap _), ← not_iff_not]
@[simp]
theorem comap_snd_neBot_iff {f : Filter β} :
    (f.comap (Prod.snd : α × β → β)).NeBot ↔ Nonempty α ∧ f.NeBot := by
  cases' isEmpty_or_nonempty α with hα hα
  · rw [filter_eq_bot_of_isEmpty (f.comap _), ← not_iff_not]; 

Proof state:
case inl
α : Type u
β : Type v
γ : Type w
δ : Type u_1
ι : Sort x
f✝ f₁ f₂ : Filter α
g g₁ g₂ : Filter β
m : α → β
m' : β → γ
s : Set α
t : Set β
f : Filter β
hα : IsEmpty α
⊢ ¬NeBot ⊥ ↔ ¬(Nonempty α ∧ NeBot f)

Next tactic:
simp