l3lab/ntp-mathlib huggingface dataset:
/-- Suppose that `f` sends the complement to `s` to a single point `a`, and `l` is some filter.
Then `f` tends to `a` along `l` restricted to `s` if and only if it tends to `a` along `l`. -/
theorem tendsto_inf_principal_nhds_iff_of_forall_eq {f : β → α} {l : Filter β} {s : Set β} {a : α}
    (h : ∀ (x) (_ : x ∉ s), f x = a) : Tendsto f (l ⊓ 𝓟 s) (𝓝 a) ↔ Tendsto f l (𝓝 a) := by
  rw [tendsto_iff_comap, tendsto_iff_comap]
  replace h : 𝓟 sᶜ ≤ comap f (𝓝 a)
  · 

Proof state:
case h
α : Type u
β : Type v
ι : Sort w
a✝ : α
s✝ s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
f : β → α
l : Filter β
s : Set β
a : α
h : ∀ x ∉ s, f x = a
⊢ 𝓟 sᶜ ≤ comap f (𝓝 a)

Next tactic:
rintro U ⟨t, ht, htU⟩ x hx
/-- Suppose that `f` sends the complement to `s` to a single point `a`, and `l` is some filter.
Then `f` tends to `a` along `l` restricted to `s` if and only if it tends to `a` along `l`. -/
theorem tendsto_inf_principal_nhds_iff_of_forall_eq {f : β → α} {l : Filter β} {s : Set β} {a : α}
    (h : ∀ (x) (_ : x ∉ s), f x = a) : Tendsto f (l ⊓ 𝓟 s) (𝓝 a) ↔ Tendsto f l (𝓝 a) := by
  rw [tendsto_iff_comap, tendsto_iff_comap]
  replace h : 𝓟 sᶜ ≤ comap f (𝓝 a)
  · rintro U ⟨t, ht, htU⟩ x hx
    

Proof state:
case h.intro.intro
α : Type u
β : Type v
ι : Sort w
a✝ : α
s✝ s₁ s₂ t✝ : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
f : β → α
l : Filter β
s : Set β
a : α
h : ∀ x ∉ s, f x = a
U : Set β
t : Set α
ht : t ∈ 𝓝 a
htU : f ⁻¹' t ⊆ U
x : β
hx : x ∈ sᶜ
⊢ x ∈ U

Next tactic:
have : f x ∈ t := (h x hx).symm ▸ mem_of_mem_nhds ht
/-- Suppose that `f` sends the complement to `s` to a single point `a`, and `l` is some filter.
Then `f` tends to `a` along `l` restricted to `s` if and only if it tends to `a` along `l`. -/
theorem tendsto_inf_principal_nhds_iff_of_forall_eq {f : β → α} {l : Filter β} {s : Set β} {a : α}
    (h : ∀ (x) (_ : x ∉ s), f x = a) : Tendsto f (l ⊓ 𝓟 s) (𝓝 a) ↔ Tendsto f l (𝓝 a) := by
  rw [tendsto_iff_comap, tendsto_iff_comap]
  replace h : 𝓟 sᶜ ≤ comap f (𝓝 a)
  · rintro U ⟨t, ht, htU⟩ x hx
    have : f x ∈ t := (h x hx).symm ▸ mem_of_mem_nhds ht
    

Proof state:
case h.intro.intro
α : Type u
β : Type v
ι : Sort w
a✝ : α
s✝ s₁ s₂ t✝ : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
f : β → α
l : Filter β
s : Set β
a : α
h : ∀ x ∉ s, f x = a
U : Set β
t : Set α
ht : t ∈ 𝓝 a
htU : f ⁻¹' t ⊆ U
x : β
hx : x ∈ sᶜ
this : f x ∈ t
⊢ x ∈ U

Next tactic:
exact htU this
/-- Suppose that `f` sends the complement to `s` to a single point `a`, and `l` is some filter.
Then `f` tends to `a` along `l` restricted to `s` if and only if it tends to `a` along `l`. -/
theorem tendsto_inf_principal_nhds_iff_of_forall_eq {f : β → α} {l : Filter β} {s : Set β} {a : α}
    (h : ∀ (x) (_ : x ∉ s), f x = a) : Tendsto f (l ⊓ 𝓟 s) (𝓝 a) ↔ Tendsto f l (𝓝 a) := by
  rw [tendsto_iff_comap, tendsto_iff_comap]
  replace h : 𝓟 sᶜ ≤ comap f (𝓝 a)
  · rintro U ⟨t, ht, htU⟩ x hx
    have : f x ∈ t := (h x hx).symm ▸ mem_of_mem_nhds ht
    exact htU this
  

Proof state:
α : Type u
β : Type v
ι : Sort w
a✝ : α
s✝ s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
f : β → α
l : Filter β
s : Set β
a : α
h : 𝓟 sᶜ ≤ comap f (𝓝 a)
⊢ l ⊓ 𝓟 s ≤ comap f (𝓝 a) ↔ l ≤ comap f (𝓝 a)

Next tactic:
refine' ⟨fun h' => _, le_trans inf_le_left⟩
/-- Suppose that `f` sends the complement to `s` to a single point `a`, and `l` is some filter.
Then `f` tends to `a` along `l` restricted to `s` if and only if it tends to `a` along `l`. -/
theorem tendsto_inf_principal_nhds_iff_of_forall_eq {f : β → α} {l : Filter β} {s : Set β} {a : α}
    (h : ∀ (x) (_ : x ∉ s), f x = a) : Tendsto f (l ⊓ 𝓟 s) (𝓝 a) ↔ Tendsto f l (𝓝 a) := by
  rw [tendsto_iff_comap, tendsto_iff_comap]
  replace h : 𝓟 sᶜ ≤ comap f (𝓝 a)
  · rintro U ⟨t, ht, htU⟩ x hx
    have : f x ∈ t := (h x hx).symm ▸ mem_of_mem_nhds ht
    exact htU this
  refine' ⟨fun h' => _, le_trans inf_le_left⟩
  

Proof state:
α : Type u
β : Type v
ι : Sort w
a✝ : α
s✝ s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
f : β → α
l : Filter β
s : Set β
a : α
h : 𝓟 sᶜ ≤ comap f (𝓝 a)
h' : l ⊓ 𝓟 s ≤ comap f (𝓝 a)
⊢ l ≤ comap f (𝓝 a)

Next tactic:
have := sup_le h' h
/-- Suppose that `f` sends the complement to `s` to a single point `a`, and `l` is some filter.
Then `f` tends to `a` along `l` restricted to `s` if and only if it tends to `a` along `l`. -/
theorem tendsto_inf_principal_nhds_iff_of_forall_eq {f : β → α} {l : Filter β} {s : Set β} {a : α}
    (h : ∀ (x) (_ : x ∉ s), f x = a) : Tendsto f (l ⊓ 𝓟 s) (𝓝 a) ↔ Tendsto f l (𝓝 a) := by
  rw [tendsto_iff_comap, tendsto_iff_comap]
  replace h : 𝓟 sᶜ ≤ comap f (𝓝 a)
  · rintro U ⟨t, ht, htU⟩ x hx
    have : f x ∈ t := (h x hx).symm ▸ mem_of_mem_nhds ht
    exact htU this
  refine' ⟨fun h' => _, le_trans inf_le_left⟩
  have := sup_le h' h
  

Proof state:
α : Type u
β : Type v
ι : Sort w
a✝ : α
s✝ s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
f : β → α
l : Filter β
s : Set β
a : α
h : 𝓟 sᶜ ≤ comap f (𝓝 a)
h' : l ⊓ 𝓟 s ≤ comap f (𝓝 a)
this : l ⊓ 𝓟 s ⊔ 𝓟 sᶜ ≤ comap f (𝓝 a)
⊢ l ≤ comap f (𝓝 a)

Next tactic:
rw [sup_inf_right, sup_principal, union_compl_self, principal_univ, inf_top_eq, sup_le_iff]
    at this
/-- Suppose that `f` sends the complement to `s` to a single point `a`, and `l` is some filter.
Then `f` tends to `a` along `l` restricted to `s` if and only if it tends to `a` along `l`. -/
theorem tendsto_inf_principal_nhds_iff_of_forall_eq {f : β → α} {l : Filter β} {s : Set β} {a : α}
    (h : ∀ (x) (_ : x ∉ s), f x = a) : Tendsto f (l ⊓ 𝓟 s) (𝓝 a) ↔ Tendsto f l (𝓝 a) := by
  rw [tendsto_iff_comap, tendsto_iff_comap]
  replace h : 𝓟 sᶜ ≤ comap f (𝓝 a)
  · rintro U ⟨t, ht, htU⟩ x hx
    have : f x ∈ t := (h x hx).symm ▸ mem_of_mem_nhds ht
    exact htU this
  refine' ⟨fun h' => _, le_trans inf_le_left⟩
  have := sup_le h' h
  rw [sup_inf_right, sup_principal, union_compl_self, principal_univ, inf_top_eq, sup_le_iff]
    at this
  

Proof state:
α : Type u
β : Type v
ι : Sort w
a✝ : α
s✝ s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
f : β → α
l : Filter β
s : Set β
a : α
h : 𝓟 sᶜ ≤ comap f (𝓝 a)
h' : l ⊓ 𝓟 s ≤ comap f (𝓝 a)
this : l ≤ comap f (𝓝 a) ∧ 𝓟 sᶜ ≤ comap f (𝓝 a)
⊢ l ≤ comap f (𝓝 a)

Next tactic:
exact this.1
theorem continuousAt_congr {f g : α → β} {x : α} (h : f =ᶠ[𝓝 x] g) :
    ContinuousAt f x ↔ ContinuousAt g x := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : TopologicalSpace α
inst✝¹ : TopologicalSpace β
inst✝ : TopologicalSpace γ
f g : α → β
x : α
h : f =ᶠ[𝓝 x] g
⊢ ContinuousAt f x ↔ ContinuousAt g x

Next tactic:
simp only [ContinuousAt, tendsto_congr' h, h.eq_of_nhds]
theorem eventuallyEq_zero_nhds {M₀} [Zero M₀] {a : α} {f : α → M₀} :
    f =ᶠ[𝓝 a] 0 ↔ a ∉ closure (Function.support f) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝³ : TopologicalSpace α
inst✝² : TopologicalSpace β
inst✝¹ : TopologicalSpace γ
M₀ : Type u_5
inst✝ : Zero M₀
a : α
f : α → M₀
⊢ f =ᶠ[𝓝 a] 0 ↔ a ∉ closure (Function.support f)

Next tactic:
rw [← mem_compl_iff, ← interior_compl, mem_interior_iff_mem_nhds, Function.compl_support,
    EventuallyEq, eventually_iff]
theorem eventuallyEq_zero_nhds {M₀} [Zero M₀] {a : α} {f : α → M₀} :
    f =ᶠ[𝓝 a] 0 ↔ a ∉ closure (Function.support f) := by
  rw [← mem_compl_iff, ← interior_compl, mem_interior_iff_mem_nhds, Function.compl_support,
    EventuallyEq, eventually_iff]
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝³ : TopologicalSpace α
inst✝² : TopologicalSpace β
inst✝¹ : TopologicalSpace γ
M₀ : Type u_5
inst✝ : Zero M₀
a : α
f : α → M₀
⊢ {x | f x = OfNat.ofNat 0 x} ∈ 𝓝 a ↔ {x | f x = 0} ∈ 𝓝 a

Next tactic:
simp only [Pi.zero_apply]
/-- See note [comp_of_eq lemmas] -/
theorem ContinuousAt.comp_of_eq {g : β → γ} {f : α → β} {x : α} {y : β} (hg : ContinuousAt g y)
    (hf : ContinuousAt f x) (hy : f x = y) : ContinuousAt (g ∘ f) x := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : TopologicalSpace α
inst✝¹ : TopologicalSpace β
inst✝ : TopologicalSpace γ
g : β → γ
f : α → β
x : α
y : β
hg : ContinuousAt g y
hf : ContinuousAt f x
hy : f x = y
⊢ ContinuousAt (g ∘ f) x

Next tactic:
subst hy
/-- See note [comp_of_eq lemmas] -/
theorem ContinuousAt.comp_of_eq {g : β → γ} {f : α → β} {x : α} {y : β} (hg : ContinuousAt g y)
    (hf : ContinuousAt f x) (hy : f x = y) : ContinuousAt (g ∘ f) x := by subst hy; 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : TopologicalSpace α
inst✝¹ : TopologicalSpace β
inst✝ : TopologicalSpace γ
g : β → γ
f : α → β
x : α
hf : ContinuousAt f x
hg : ContinuousAt g (f x)
⊢ ContinuousAt (g ∘ f) x

Next tactic:
exact hg.comp hf
theorem continuous_iff_isClosed {f : α → β} : Continuous f ↔ ∀ s, IsClosed s → IsClosed (f ⁻¹' s) :=
  continuous_def.trans <| compl_surjective.forall.trans <| by
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : TopologicalSpace α
inst✝¹ : TopologicalSpace β
inst✝ : TopologicalSpace γ
f : α → β
⊢ (∀ (x : Set β), IsOpen xᶜ → IsOpen (f ⁻¹' xᶜ)) ↔ ∀ (s : Set β), IsClosed s → IsClosed (f ⁻¹' s)

Next tactic:
simp only [isOpen_compl_iff, preimage_compl]
theorem continuous_iff_ultrafilter {f : α → β} :
    Continuous f ↔ ∀ (x) (g : Ultrafilter α), ↑g ≤ 𝓝 x → Tendsto f g (𝓝 (f x)) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : TopologicalSpace α
inst✝¹ : TopologicalSpace β
inst✝ : TopologicalSpace γ
f : α → β
⊢ Continuous f ↔ ∀ (x : α) (g : Ultrafilter α), ↑g ≤ 𝓝 x → Tendsto f (↑g) (𝓝 (f x))

Next tactic:
simp only [continuous_iff_continuousAt, continuousAt_iff_ultrafilter]
theorem Continuous.closure_preimage_subset {f : α → β} (hf : Continuous f) (t : Set β) :
    closure (f ⁻¹' t) ⊆ f ⁻¹' closure t := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : TopologicalSpace α
inst✝¹ : TopologicalSpace β
inst✝ : TopologicalSpace γ
f : α → β
hf : Continuous f
t : Set β
⊢ closure (f ⁻¹' t) ⊆ f ⁻¹' closure t

Next tactic:
rw [← (isClosed_closure.preimage hf).closure_eq]
theorem Continuous.closure_preimage_subset {f : α → β} (hf : Continuous f) (t : Set β) :
    closure (f ⁻¹' t) ⊆ f ⁻¹' closure t := by
  rw [← (isClosed_closure.preimage hf).closure_eq]
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : TopologicalSpace α
inst✝¹ : TopologicalSpace β
inst✝ : TopologicalSpace γ
f : α → β
hf : Continuous f
t : Set β
⊢ closure (f ⁻¹' t) ⊆ closure (f ⁻¹' closure t)

Next tactic:
exact closure_mono (preimage_mono subset_closure)
/-- If a continuous map `f` maps `s` to `t`, then it maps `closure s` to `closure t`. -/
protected theorem Set.MapsTo.closure {s : Set α} {t : Set β} {f : α → β} (h : MapsTo f s t)
    (hc : Continuous f) : MapsTo f (closure s) (closure t) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : TopologicalSpace α
inst✝¹ : TopologicalSpace β
inst✝ : TopologicalSpace γ
s : Set α
t : Set β
f : α → β
h : MapsTo f s t
hc : Continuous f
⊢ MapsTo f (closure s) (closure t)

Next tactic:
simp only [MapsTo, mem_closure_iff_clusterPt]
/-- If a continuous map `f` maps `s` to `t`, then it maps `closure s` to `closure t`. -/
protected theorem Set.MapsTo.closure {s : Set α} {t : Set β} {f : α → β} (h : MapsTo f s t)
    (hc : Continuous f) : MapsTo f (closure s) (closure t) := by
  simp only [MapsTo, mem_closure_iff_clusterPt]
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : TopologicalSpace α
inst✝¹ : TopologicalSpace β
inst✝ : TopologicalSpace γ
s : Set α
t : Set β
f : α → β
h : MapsTo f s t
hc : Continuous f
⊢ ∀ ⦃x : α⦄, ClusterPt x (𝓟 s) → ClusterPt (f x) (𝓟 t)

Next tactic:
exact fun x hx => hx.map hc.continuousAt (tendsto_principal_principal.2 h)
theorem closure_subset_preimage_closure_image {f : α → β} {s : Set α} (h : Continuous f) :
    closure s ⊆ f ⁻¹' closure (f '' s) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : TopologicalSpace α
inst✝¹ : TopologicalSpace β
inst✝ : TopologicalSpace γ
f : α → β
s : Set α
h : Continuous f
⊢ closure s ⊆ f ⁻¹' closure (f '' s)

Next tactic:
rw [← Set.image_subset_iff]
theorem closure_subset_preimage_closure_image {f : α → β} {s : Set α} (h : Continuous f) :
    closure s ⊆ f ⁻¹' closure (f '' s) := by
  rw [← Set.image_subset_iff]
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : TopologicalSpace α
inst✝¹ : TopologicalSpace β
inst✝ : TopologicalSpace γ
f : α → β
s : Set α
h : Continuous f
⊢ f '' closure s ⊆ closure (f '' s)

Next tactic:
exact image_closure_subset_closure_image h
/-- A surjective map has dense range. -/
theorem Function.Surjective.denseRange (hf : Function.Surjective f) : DenseRange f := fun x => by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : TopologicalSpace α
inst✝¹ : TopologicalSpace β
inst✝ : TopologicalSpace γ
κ : Type u_5
ι : Type u_6
f : κ → β
g : β → γ
hf : Surjective f
x : β
⊢ x ∈ closure (range f)

Next tactic:
simp [hf.range_eq]
theorem Dense.denseRange_val {s : Set α} (h : Dense s) : DenseRange ((↑) : s → α) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : TopologicalSpace α
inst✝¹ : TopologicalSpace β
inst✝ : TopologicalSpace γ
κ : Type u_5
ι : Type u_6
f : κ → β
g : β → γ
s : Set α
h : Dense s
⊢ DenseRange Subtype.val

Next tactic:
simpa only [DenseRange, Subtype.range_coe_subtype]
theorem Continuous.range_subset_closure_image_dense {f : α → β} (hf : Continuous f) {s : Set α}
    (hs : Dense s) : range f ⊆ closure (f '' s) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : TopologicalSpace α
inst✝¹ : TopologicalSpace β
inst✝ : TopologicalSpace γ
κ : Type u_5
ι : Type u_6
f✝ : κ → β
g : β → γ
f : α → β
hf : Continuous f
s : Set α
hs : Dense s
⊢ range f ⊆ closure (f '' s)

Next tactic:
rw [← image_univ, ← hs.closure_eq]
theorem Continuous.range_subset_closure_image_dense {f : α → β} (hf : Continuous f) {s : Set α}
    (hs : Dense s) : range f ⊆ closure (f '' s) := by
  rw [← image_univ, ← hs.closure_eq]
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : TopologicalSpace α
inst✝¹ : TopologicalSpace β
inst✝ : TopologicalSpace γ
κ : Type u_5
ι : Type u_6
f✝ : κ → β
g : β → γ
f : α → β
hf : Continuous f
s : Set α
hs : Dense s
⊢ f '' closure s ⊆ closure (f '' s)

Next tactic:
exact image_closure_subset_closure_image hf
/-- If `f` has dense range and `s` is an open set in the codomain of `f`, then the image of the
preimage of `s` under `f` is dense in `s`. -/
theorem DenseRange.subset_closure_image_preimage_of_isOpen (hf : DenseRange f) {s : Set β}
    (hs : IsOpen s) : s ⊆ closure (f '' (f ⁻¹' s)) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : TopologicalSpace α
inst✝¹ : TopologicalSpace β
inst✝ : TopologicalSpace γ
κ : Type u_5
ι : Type u_6
f : κ → β
g : β → γ
hf : DenseRange f
s : Set β
hs : IsOpen s
⊢ s ⊆ closure (f '' (f ⁻¹' s))

Next tactic:
rw [image_preimage_eq_inter_range]
/-- If `f` has dense range and `s` is an open set in the codomain of `f`, then the image of the
preimage of `s` under `f` is dense in `s`. -/
theorem DenseRange.subset_closure_image_preimage_of_isOpen (hf : DenseRange f) {s : Set β}
    (hs : IsOpen s) : s ⊆ closure (f '' (f ⁻¹' s)) := by
  rw [image_preimage_eq_inter_range]
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : TopologicalSpace α
inst✝¹ : TopologicalSpace β
inst✝ : TopologicalSpace γ
κ : Type u_5
ι : Type u_6
f : κ → β
g : β → γ
hf : DenseRange f
s : Set β
hs : IsOpen s
⊢ s ⊆ closure (s ∩ range f)

Next tactic:
exact hf.open_subset_closure_inter hs
/-- Composition of a continuous map with dense range and a function with dense range has dense
range. -/
theorem DenseRange.comp {g : β → γ} {f : κ → β} (hg : DenseRange g) (hf : DenseRange f)
    (cg : Continuous g) : DenseRange (g ∘ f) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : TopologicalSpace α
inst✝¹ : TopologicalSpace β
inst✝ : TopologicalSpace γ
κ : Type u_5
ι : Type u_6
f✝ : κ → β
g✝ g : β → γ
f : κ → β
hg : DenseRange g
hf : DenseRange f
cg : Continuous g
⊢ DenseRange (g ∘ f)

Next tactic:
rw [DenseRange, range_comp]
/-- Composition of a continuous map with dense range and a function with dense range has dense
range. -/
theorem DenseRange.comp {g : β → γ} {f : κ → β} (hg : DenseRange g) (hf : DenseRange f)
    (cg : Continuous g) : DenseRange (g ∘ f) := by
  rw [DenseRange, range_comp]
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : TopologicalSpace α
inst✝¹ : TopologicalSpace β
inst✝ : TopologicalSpace γ
κ : Type u_5
ι : Type u_6
f✝ : κ → β
g✝ g : β → γ
f : κ → β
hg : DenseRange g
hf : DenseRange f
cg : Continuous g
⊢ Dense (g '' range f)

Next tactic:
exact hg.dense_image cg hf
/-- The `ZMod n`-algebra structure on rings whose characteristic `m` divides `n`.
See note [reducible non-instances]. -/
@[reducible]
def algebra' (h : m ∣ n) : Algebra (ZMod n) R :=
  { ZMod.castHom h R with
    smul := fun a r => a * r
    commutes' := fun a r =>
      show (a * r : R) = r * a by
        

Proof state:
R : Type u_1
inst✝¹ : Ring R
n m : ℕ
inst✝ : CharP R m
h : m ∣ n
src✝ : ZMod n →+* R := castHom h R
a : ZMod n
r : R
⊢ ↑a * r = r * ↑a

Next tactic:
rcases ZMod.int_cast_surjective a with ⟨k, rfl⟩
/-- The `ZMod n`-algebra structure on rings whose characteristic `m` divides `n`.
See note [reducible non-instances]. -/
@[reducible]
def algebra' (h : m ∣ n) : Algebra (ZMod n) R :=
  { ZMod.castHom h R with
    smul := fun a r => a * r
    commutes' := fun a r =>
      show (a * r : R) = r * a by
        rcases ZMod.int_cast_surjective a with ⟨k, rfl⟩
        

Proof state:
case intro
R : Type u_1
inst✝¹ : Ring R
n m : ℕ
inst✝ : CharP R m
h : m ∣ n
src✝ : ZMod n →+* R := castHom h R
r : R
k : ℤ
⊢ ↑↑k * r = r * ↑↑k

Next tactic:
show ZMod.castHom h R k * r = r * ZMod.castHom h R k
/-- The `ZMod n`-algebra structure on rings whose characteristic `m` divides `n`.
See note [reducible non-instances]. -/
@[reducible]
def algebra' (h : m ∣ n) : Algebra (ZMod n) R :=
  { ZMod.castHom h R with
    smul := fun a r => a * r
    commutes' := fun a r =>
      show (a * r : R) = r * a by
        rcases ZMod.int_cast_surjective a with ⟨k, rfl⟩
        show ZMod.castHom h R k * r = r * ZMod.castHom h R k
        

Proof state:
case intro
R : Type u_1
inst✝¹ : Ring R
n m : ℕ
inst✝ : CharP R m
h : m ∣ n
src✝ : ZMod n →+* R := castHom h R
r : R
k : ℤ
⊢ (castHom h R) ↑k * r = r * (castHom h R) ↑k

Next tactic:
rw [map_intCast]
/-- The `ZMod n`-algebra structure on rings whose characteristic `m` divides `n`.
See note [reducible non-instances]. -/
@[reducible]
def algebra' (h : m ∣ n) : Algebra (ZMod n) R :=
  { ZMod.castHom h R with
    smul := fun a r => a * r
    commutes' := fun a r =>
      show (a * r : R) = r * a by
        rcases ZMod.int_cast_surjective a with ⟨k, rfl⟩
        show ZMod.castHom h R k * r = r * ZMod.castHom h R k
        rw [map_intCast]
        

Proof state:
case intro
R : Type u_1
inst✝¹ : Ring R
n m : ℕ
inst✝ : CharP R m
h : m ∣ n
src✝ : ZMod n →+* R := castHom h R
r : R
k : ℤ
⊢ ↑k * r = r * ↑k

Next tactic:
exact Commute.cast_int_left r k
@[to_additive prod_mk_sum]
theorem prod_mk_prod {α β γ : Type*} [CommMonoid α] [CommMonoid β] (s : Finset γ) (f : γ → α)
    (g : γ → β) : (∏ x in s, f x, ∏ x in s, g x) = ∏ x in s, (f x, g x) :=
  haveI := Classical.decEq γ
  Finset.induction_on s rfl (by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝¹ : CommMonoid α
inst✝ : CommMonoid β
s : Finset γ
f : γ → α
g : γ → β
this : DecidableEq γ
⊢ ∀ ⦃a : γ⦄ {s : Finset γ},
    a ∉ s →
      (∏ x in s, f x, ∏ x in s, g x) = ∏ x in s, (f x, g x) →
        (∏ x in insert a s, f x, ∏ x in insert a s, g x) = ∏ x in insert a s, (f x, g x)

Next tactic:
simp (config := { contextual := true }) [Prod.ext_iff]
/-- decomposing `x : ι → R` as a sum along the canonical basis -/
theorem pi_eq_sum_univ {ι : Type*} [Fintype ι] [DecidableEq ι] {R : Type*} [Semiring R]
    (x : ι → R) : x = ∑ i, (x i) • fun j => if i = j then (1 : R) else 0 := by
  

Proof state:
ι : Type u_1
inst✝² : Fintype ι
inst✝¹ : DecidableEq ι
R : Type u_2
inst✝ : Semiring R
x : ι → R
⊢ x = ∑ i : ι, x i • fun j => if i = j then 1 else 0

Next tactic:
ext
/-- decomposing `x : ι → R` as a sum along the canonical basis -/
theorem pi_eq_sum_univ {ι : Type*} [Fintype ι] [DecidableEq ι] {R : Type*} [Semiring R]
    (x : ι → R) : x = ∑ i, (x i) • fun j => if i = j then (1 : R) else 0 := by
  ext
  

Proof state:
case h
ι : Type u_1
inst✝² : Fintype ι
inst✝¹ : DecidableEq ι
R : Type u_2
inst✝ : Semiring R
x : ι → R
x✝ : ι
⊢ x x✝ = Finset.sum Finset.univ (fun i => x i • fun j => if i = j then 1 else 0) x✝

Next tactic:
simp
@[to_additive]
theorem Finset.univ_prod_mulSingle [Fintype I] (f : ∀ i, Z i) :
    (∏ i, Pi.mulSingle i (f i)) = f := by
  

Proof state:
I : Type u_1
inst✝² : DecidableEq I
Z : I → Type u_2
inst✝¹ : (i : I) → CommMonoid (Z i)
inst✝ : Fintype I
f : (i : I) → Z i
⊢ ∏ i : I, Pi.mulSingle i (f i) = f

Next tactic:
ext a
@[to_additive]
theorem Finset.univ_prod_mulSingle [Fintype I] (f : ∀ i, Z i) :
    (∏ i, Pi.mulSingle i (f i)) = f := by
  ext a
  

Proof state:
case h
I : Type u_1
inst✝² : DecidableEq I
Z : I → Type u_2
inst✝¹ : (i : I) → CommMonoid (Z i)
inst✝ : Fintype I
f : (i : I) → Z i
a : I
⊢ Finset.prod univ (fun i => Pi.mulSingle i (f i)) a = f a

Next tactic:
simp
@[to_additive]
theorem MonoidHom.functions_ext [Finite I] (G : Type*) [CommMonoid G] (g h : (∀ i, Z i) →* G)
    (H : ∀ i x, g (Pi.mulSingle i x) = h (Pi.mulSingle i x)) : g = h := by
  

Proof state:
I : Type u_1
inst✝³ : DecidableEq I
Z : I → Type u_2
inst✝² : (i : I) → CommMonoid (Z i)
inst✝¹ : Finite I
G : Type u_3
inst✝ : CommMonoid G
g h : ((i : I) → Z i) →* G
H : ∀ (i : I) (x : Z i), g (Pi.mulSingle i x) = h (Pi.mulSingle i x)
⊢ g = h

Next tactic:
cases nonempty_fintype I
@[to_additive]
theorem MonoidHom.functions_ext [Finite I] (G : Type*) [CommMonoid G] (g h : (∀ i, Z i) →* G)
    (H : ∀ i x, g (Pi.mulSingle i x) = h (Pi.mulSingle i x)) : g = h := by
  cases nonempty_fintype I
  

Proof state:
case intro
I : Type u_1
inst✝³ : DecidableEq I
Z : I → Type u_2
inst✝² : (i : I) → CommMonoid (Z i)
inst✝¹ : Finite I
G : Type u_3
inst✝ : CommMonoid G
g h : ((i : I) → Z i) →* G
H : ∀ (i : I) (x : Z i), g (Pi.mulSingle i x) = h (Pi.mulSingle i x)
val✝ : Fintype I
⊢ g = h

Next tactic:
ext k
@[to_additive]
theorem MonoidHom.functions_ext [Finite I] (G : Type*) [CommMonoid G] (g h : (∀ i, Z i) →* G)
    (H : ∀ i x, g (Pi.mulSingle i x) = h (Pi.mulSingle i x)) : g = h := by
  cases nonempty_fintype I
  ext k
  

Proof state:
case intro.h
I : Type u_1
inst✝³ : DecidableEq I
Z : I → Type u_2
inst✝² : (i : I) → CommMonoid (Z i)
inst✝¹ : Finite I
G : Type u_3
inst✝ : CommMonoid G
g h : ((i : I) → Z i) →* G
H : ∀ (i : I) (x : Z i), g (Pi.mulSingle i x) = h (Pi.mulSingle i x)
val✝ : Fintype I
k : (i : I) → Z i
⊢ g k = h k

Next tactic:
rw [← Finset.univ_prod_mulSingle k, map_prod, map_prod]
@[to_additive]
theorem MonoidHom.functions_ext [Finite I] (G : Type*) [CommMonoid G] (g h : (∀ i, Z i) →* G)
    (H : ∀ i x, g (Pi.mulSingle i x) = h (Pi.mulSingle i x)) : g = h := by
  cases nonempty_fintype I
  ext k
  rw [← Finset.univ_prod_mulSingle k, map_prod, map_prod]
  

Proof state:
case intro.h
I : Type u_1
inst✝³ : DecidableEq I
Z : I → Type u_2
inst✝² : (i : I) → CommMonoid (Z i)
inst✝¹ : Finite I
G : Type u_3
inst✝ : CommMonoid G
g h : ((i : I) → Z i) →* G
H : ∀ (i : I) (x : Z i), g (Pi.mulSingle i x) = h (Pi.mulSingle i x)
val✝ : Fintype I
k : (i : I) → Z i
⊢ ∏ x : I, g (Pi.mulSingle x (k x)) = ∏ x : I, h (Pi.mulSingle x (k x))

Next tactic:
simp only [H]
@[to_additive (attr := simp)]
theorem prod_cons : (a :: l).prod = a * l.prod :=
  calc
    (a :: l).prod = foldl (· * ·) (a * 1) l :=
      by 

Proof state:
ι : Type u_1
α : Type u_2
M : Type u_3
N : Type u_4
P : Type u_5
M₀ : Type u_6
G : Type u_7
R : Type u_8
inst✝² : Monoid M
inst✝¹ : Monoid N
inst✝ : Monoid P
l l₁ l₂ : List M
a : M
⊢ prod (a :: l) = foldl (fun x x_1 => x * x_1) (a * 1) l

Next tactic:
simp only [List.prod, foldl_cons, one_mul, mul_one]