l3lab/ntp-mathlib huggingface dataset:
theorem continuous_coev : Continuous (coev α β) :=
  continuous_generateFrom <| by
    rintro _ ⟨s, sc, u, uo, rfl⟩
    rw [isOpen_iff_forall_mem_open]
    intro y hy
    have hy' : (↑(coev α β y) '' s ⊆ u) := hy
    -- porting notes: was below
    --change coev α β y '' s ⊆ u at hy
    rw [image_coev s] at hy'
    rcases generalized_tube_lemma isCompact_singleton sc uo hy' with ⟨v, w, vo, _, yv, sw, vwu⟩
    refine' ⟨v, _, vo, singleton_subset_iff.mp yv⟩
    intro y' hy'
    change coev α β y' '' s ⊆ u
    rw [image_coev s]
    

Proof state:
case intro.intro.intro.intro.intro.intro.intro.intro.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝² : TopologicalSpace α
inst✝¹ : TopologicalSpace β
inst✝ : TopologicalSpace γ
s : Set α
sc : IsCompact s
u : Set (β × α)
uo : IsOpen u
y : β
hy : y ∈ coev α β ⁻¹' CompactOpen.gen s u
hy'✝ : {y} ×ˢ s ⊆ u
v : Set β
w : Set α
vo : IsOpen v
left✝ : IsOpen w
yv : {y} ⊆ v
sw : s ⊆ w
vwu : v ×ˢ w ⊆ u
y' : β
hy' : y' ∈ v
⊢ {y'} ×ˢ s ⊆ u

Next tactic:
exact (prod_mono (singleton_subset_iff.mpr hy') sw).trans vwu
/-- If a map `α × β → γ` is continuous, then its curried form `α → C(β, γ)` is continuous. -/
theorem continuous_curry' (f : C(α × β, γ)) : Continuous (curry' f) :=
  have hf : curry' f = ContinuousMap.comp f ∘ coev _ _ := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝² : TopologicalSpace α
inst✝¹ : TopologicalSpace β
inst✝ : TopologicalSpace γ
f : C(α × β, γ)
⊢ curry' f = comp f ∘ coev β α

Next tactic:
ext
/-- If a map `α × β → γ` is continuous, then its curried form `α → C(β, γ)` is continuous. -/
theorem continuous_curry' (f : C(α × β, γ)) : Continuous (curry' f) :=
  have hf : curry' f = ContinuousMap.comp f ∘ coev _ _ := by ext; 

Proof state:
case h.h
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝² : TopologicalSpace α
inst✝¹ : TopologicalSpace β
inst✝ : TopologicalSpace γ
f : C(α × β, γ)
x✝ : α
a✝ : β
⊢ (curry' f x✝) a✝ = ((comp f ∘ coev β α) x✝) a✝

Next tactic:
rfl
/-- The currying process is a continuous map between function spaces. -/
theorem continuous_curry [LocallyCompactSpace (α × β)] :
    Continuous (curry : C(α × β, γ) → C(α, C(β, γ))) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝³ : TopologicalSpace α
inst✝² : TopologicalSpace β
inst✝¹ : TopologicalSpace γ
inst✝ : LocallyCompactSpace (α × β)
⊢ Continuous curry

Next tactic:
apply continuous_of_continuous_uncurry
/-- The currying process is a continuous map between function spaces. -/
theorem continuous_curry [LocallyCompactSpace (α × β)] :
    Continuous (curry : C(α × β, γ) → C(α, C(β, γ))) := by
  apply continuous_of_continuous_uncurry
  

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝³ : TopologicalSpace α
inst✝² : TopologicalSpace β
inst✝¹ : TopologicalSpace γ
inst✝ : LocallyCompactSpace (α × β)
⊢ Continuous (Function.uncurry fun x y => (curry x) y)

Next tactic:
apply continuous_of_continuous_uncurry
/-- The currying process is a continuous map between function spaces. -/
theorem continuous_curry [LocallyCompactSpace (α × β)] :
    Continuous (curry : C(α × β, γ) → C(α, C(β, γ))) := by
  apply continuous_of_continuous_uncurry
  apply continuous_of_continuous_uncurry
  

Proof state:
case h.h
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝³ : TopologicalSpace α
inst✝² : TopologicalSpace β
inst✝¹ : TopologicalSpace γ
inst✝ : LocallyCompactSpace (α × β)
⊢ Continuous (Function.uncurry fun x y => (Function.uncurry (fun x y => (curry x) y) x) y)

Next tactic:
rw [← (Homeomorph.prodAssoc _ _ _).symm.comp_continuous_iff']
/-- The currying process is a continuous map between function spaces. -/
theorem continuous_curry [LocallyCompactSpace (α × β)] :
    Continuous (curry : C(α × β, γ) → C(α, C(β, γ))) := by
  apply continuous_of_continuous_uncurry
  apply continuous_of_continuous_uncurry
  rw [← (Homeomorph.prodAssoc _ _ _).symm.comp_continuous_iff']
  

Proof state:
case h.h
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝³ : TopologicalSpace α
inst✝² : TopologicalSpace β
inst✝¹ : TopologicalSpace γ
inst✝ : LocallyCompactSpace (α × β)
⊢ Continuous
    ((Function.uncurry fun x y => (Function.uncurry (fun x y => (curry x) y) x) y) ∘
      ⇑(Homeomorph.symm (Homeomorph.prodAssoc C(α × β, γ) α β)))

Next tactic:
exact continuous_eval'
/-- The uncurrying process is a continuous map between function spaces. -/
theorem continuous_uncurry [LocallyCompactSpace α] [LocallyCompactSpace β] :
    Continuous (uncurry : C(α, C(β, γ)) → C(α × β, γ)) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝⁴ : TopologicalSpace α
inst✝³ : TopologicalSpace β
inst✝² : TopologicalSpace γ
inst✝¹ : LocallyCompactSpace α
inst✝ : LocallyCompactSpace β
⊢ Continuous uncurry

Next tactic:
apply continuous_of_continuous_uncurry
/-- The uncurrying process is a continuous map between function spaces. -/
theorem continuous_uncurry [LocallyCompactSpace α] [LocallyCompactSpace β] :
    Continuous (uncurry : C(α, C(β, γ)) → C(α × β, γ)) := by
  apply continuous_of_continuous_uncurry
  

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝⁴ : TopologicalSpace α
inst✝³ : TopologicalSpace β
inst✝² : TopologicalSpace γ
inst✝¹ : LocallyCompactSpace α
inst✝ : LocallyCompactSpace β
⊢ Continuous (Function.uncurry fun x y => (uncurry x) y)

Next tactic:
rw [← (Homeomorph.prodAssoc _ _ _).comp_continuous_iff']
/-- The uncurrying process is a continuous map between function spaces. -/
theorem continuous_uncurry [LocallyCompactSpace α] [LocallyCompactSpace β] :
    Continuous (uncurry : C(α, C(β, γ)) → C(α × β, γ)) := by
  apply continuous_of_continuous_uncurry
  rw [← (Homeomorph.prodAssoc _ _ _).comp_continuous_iff']
  

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝⁴ : TopologicalSpace α
inst✝³ : TopologicalSpace β
inst✝² : TopologicalSpace γ
inst✝¹ : LocallyCompactSpace α
inst✝ : LocallyCompactSpace β
⊢ Continuous ((Function.uncurry fun x y => (uncurry x) y) ∘ ⇑(Homeomorph.prodAssoc C(α, C(β, γ)) α β))

Next tactic:
apply continuous_eval'.comp (continuous_eval'.prod_map continuous_id)
/-- Currying as a homeomorphism between the function spaces `C(α × β, γ)` and `C(α, C(β, γ))`. -/
def curry [LocallyCompactSpace α] [LocallyCompactSpace β] : C(α × β, γ) ≃ₜ C(α, C(β, γ)) :=
  ⟨⟨ContinuousMap.curry, uncurry, by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝⁴ : TopologicalSpace α
inst✝³ : TopologicalSpace β
inst✝² : TopologicalSpace γ
inst✝¹ : LocallyCompactSpace α
inst✝ : LocallyCompactSpace β
⊢ Function.LeftInverse uncurry ContinuousMap.curry

Next tactic:
intro
/-- Currying as a homeomorphism between the function spaces `C(α × β, γ)` and `C(α, C(β, γ))`. -/
def curry [LocallyCompactSpace α] [LocallyCompactSpace β] : C(α × β, γ) ≃ₜ C(α, C(β, γ)) :=
  ⟨⟨ContinuousMap.curry, uncurry, by intro; 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝⁴ : TopologicalSpace α
inst✝³ : TopologicalSpace β
inst✝² : TopologicalSpace γ
inst✝¹ : LocallyCompactSpace α
inst✝ : LocallyCompactSpace β
x✝ : C(α × β, γ)
⊢ uncurry (ContinuousMap.curry x✝) = x✝

Next tactic:
ext
/-- Currying as a homeomorphism between the function spaces `C(α × β, γ)` and `C(α, C(β, γ))`. -/
def curry [LocallyCompactSpace α] [LocallyCompactSpace β] : C(α × β, γ) ≃ₜ C(α, C(β, γ)) :=
  ⟨⟨ContinuousMap.curry, uncurry, by intro; ext; 

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝⁴ : TopologicalSpace α
inst✝³ : TopologicalSpace β
inst✝² : TopologicalSpace γ
inst✝¹ : LocallyCompactSpace α
inst✝ : LocallyCompactSpace β
x✝ : C(α × β, γ)
a✝ : α × β
⊢ (uncurry (ContinuousMap.curry x✝)) a✝ = x✝ a✝

Next tactic:
rfl
/-- Currying as a homeomorphism between the function spaces `C(α × β, γ)` and `C(α, C(β, γ))`. -/
def curry [LocallyCompactSpace α] [LocallyCompactSpace β] : C(α × β, γ) ≃ₜ C(α, C(β, γ)) :=
  ⟨⟨ContinuousMap.curry, uncurry, by intro; ext; rfl, by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝⁴ : TopologicalSpace α
inst✝³ : TopologicalSpace β
inst✝² : TopologicalSpace γ
inst✝¹ : LocallyCompactSpace α
inst✝ : LocallyCompactSpace β
⊢ Function.RightInverse uncurry ContinuousMap.curry

Next tactic:
intro
/-- Currying as a homeomorphism between the function spaces `C(α × β, γ)` and `C(α, C(β, γ))`. -/
def curry [LocallyCompactSpace α] [LocallyCompactSpace β] : C(α × β, γ) ≃ₜ C(α, C(β, γ)) :=
  ⟨⟨ContinuousMap.curry, uncurry, by intro; ext; rfl, by intro; 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝⁴ : TopologicalSpace α
inst✝³ : TopologicalSpace β
inst✝² : TopologicalSpace γ
inst✝¹ : LocallyCompactSpace α
inst✝ : LocallyCompactSpace β
x✝ : C(α, C(β, γ))
⊢ ContinuousMap.curry (uncurry x✝) = x✝

Next tactic:
ext
/-- Currying as a homeomorphism between the function spaces `C(α × β, γ)` and `C(α, C(β, γ))`. -/
def curry [LocallyCompactSpace α] [LocallyCompactSpace β] : C(α × β, γ) ≃ₜ C(α, C(β, γ)) :=
  ⟨⟨ContinuousMap.curry, uncurry, by intro; ext; rfl, by intro; ext; 

Proof state:
case h.h
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝⁴ : TopologicalSpace α
inst✝³ : TopologicalSpace β
inst✝² : TopologicalSpace γ
inst✝¹ : LocallyCompactSpace α
inst✝ : LocallyCompactSpace β
x✝ : C(α, C(β, γ))
a✝¹ : α
a✝ : β
⊢ ((ContinuousMap.curry (uncurry x✝)) a✝¹) a✝ = (x✝ a✝¹) a✝

Next tactic:
rfl
/-- If `α` has a single element, then `β` is homeomorphic to `C(α, β)`. -/
def continuousMapOfUnique [Unique α] : β ≃ₜ C(α, β) where
  toFun := const α
  invFun f := f default
  left_inv a := rfl
  right_inv f := by
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝³ : TopologicalSpace α
inst✝² : TopologicalSpace β
inst✝¹ : TopologicalSpace γ
inst✝ : Unique α
f : C(α, β)
⊢ const α ((fun f => f default) f) = f

Next tactic:
ext a
/-- If `α` has a single element, then `β` is homeomorphic to `C(α, β)`. -/
def continuousMapOfUnique [Unique α] : β ≃ₜ C(α, β) where
  toFun := const α
  invFun f := f default
  left_inv a := rfl
  right_inv f := by
    ext a
    

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝³ : TopologicalSpace α
inst✝² : TopologicalSpace β
inst✝¹ : TopologicalSpace γ
inst✝ : Unique α
f : C(α, β)
a : α
⊢ (const α ((fun f => f default) f)) a = f a

Next tactic:
rw [Unique.eq_default a]
/-- If `α` has a single element, then `β` is homeomorphic to `C(α, β)`. -/
def continuousMapOfUnique [Unique α] : β ≃ₜ C(α, β) where
  toFun := const α
  invFun f := f default
  left_inv a := rfl
  right_inv f := by
    ext a
    rw [Unique.eq_default a]
    

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝³ : TopologicalSpace α
inst✝² : TopologicalSpace β
inst✝¹ : TopologicalSpace γ
inst✝ : Unique α
f : C(α, β)
a : α
⊢ (const α ((fun f => f default) f)) default = f default

Next tactic:
rfl
theorem QuotientMap.continuous_lift_prod_left (hf : QuotientMap f) {g : X × Y → Z}
    (hg : Continuous fun p : X₀ × Y => g (f p.1, p.2)) : Continuous g := by
  

Proof state:
X₀ : Type u_1
X : Type u_2
Y : Type u_3
Z : Type u_4
inst✝⁴ : TopologicalSpace X₀
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : LocallyCompactSpace Y
f : X₀ → X
hf : QuotientMap f
g : X × Y → Z
hg : Continuous fun p => g (f p.1, p.2)
⊢ Continuous g

Next tactic:
let Gf : C(X₀, C(Y, Z)) := ContinuousMap.curry ⟨_, hg⟩
theorem QuotientMap.continuous_lift_prod_left (hf : QuotientMap f) {g : X × Y → Z}
    (hg : Continuous fun p : X₀ × Y => g (f p.1, p.2)) : Continuous g := by
  let Gf : C(X₀, C(Y, Z)) := ContinuousMap.curry ⟨_, hg⟩
  

Proof state:
X₀ : Type u_1
X : Type u_2
Y : Type u_3
Z : Type u_4
inst✝⁴ : TopologicalSpace X₀
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : LocallyCompactSpace Y
f : X₀ → X
hf : QuotientMap f
g : X × Y → Z
hg : Continuous fun p => g (f p.1, p.2)
Gf : C(X₀, C(Y, Z)) := curry (mk fun p => g (f p.1, p.2))
⊢ Continuous g

Next tactic:
have h : ∀ x : X, Continuous fun y => g (x, y) := by
    intro x
    obtain ⟨x₀, rfl⟩ := hf.surjective x
    exact (Gf x₀).continuous
theorem QuotientMap.continuous_lift_prod_left (hf : QuotientMap f) {g : X × Y → Z}
    (hg : Continuous fun p : X₀ × Y => g (f p.1, p.2)) : Continuous g := by
  let Gf : C(X₀, C(Y, Z)) := ContinuousMap.curry ⟨_, hg⟩
  have h : ∀ x : X, Continuous fun y => g (x, y) := by
    

Proof state:
X₀ : Type u_1
X : Type u_2
Y : Type u_3
Z : Type u_4
inst✝⁴ : TopologicalSpace X₀
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : LocallyCompactSpace Y
f : X₀ → X
hf : QuotientMap f
g : X × Y → Z
hg : Continuous fun p => g (f p.1, p.2)
Gf : C(X₀, C(Y, Z)) := curry (mk fun p => g (f p.1, p.2))
⊢ ∀ (x : X), Continuous fun y => g (x, y)

Next tactic:
intro x
theorem QuotientMap.continuous_lift_prod_left (hf : QuotientMap f) {g : X × Y → Z}
    (hg : Continuous fun p : X₀ × Y => g (f p.1, p.2)) : Continuous g := by
  let Gf : C(X₀, C(Y, Z)) := ContinuousMap.curry ⟨_, hg⟩
  have h : ∀ x : X, Continuous fun y => g (x, y) := by
    intro x
    

Proof state:
X₀ : Type u_1
X : Type u_2
Y : Type u_3
Z : Type u_4
inst✝⁴ : TopologicalSpace X₀
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : LocallyCompactSpace Y
f : X₀ → X
hf : QuotientMap f
g : X × Y → Z
hg : Continuous fun p => g (f p.1, p.2)
Gf : C(X₀, C(Y, Z)) := curry (mk fun p => g (f p.1, p.2))
x : X
⊢ Continuous fun y => g (x, y)

Next tactic:
obtain ⟨x₀, rfl⟩ := hf.surjective x
theorem QuotientMap.continuous_lift_prod_left (hf : QuotientMap f) {g : X × Y → Z}
    (hg : Continuous fun p : X₀ × Y => g (f p.1, p.2)) : Continuous g := by
  let Gf : C(X₀, C(Y, Z)) := ContinuousMap.curry ⟨_, hg⟩
  have h : ∀ x : X, Continuous fun y => g (x, y) := by
    intro x
    obtain ⟨x₀, rfl⟩ := hf.surjective x
    

Proof state:
case intro
X₀ : Type u_1
X : Type u_2
Y : Type u_3
Z : Type u_4
inst✝⁴ : TopologicalSpace X₀
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : LocallyCompactSpace Y
f : X₀ → X
hf : QuotientMap f
g : X × Y → Z
hg : Continuous fun p => g (f p.1, p.2)
Gf : C(X₀, C(Y, Z)) := curry (mk fun p => g (f p.1, p.2))
x₀ : X₀
⊢ Continuous fun y => g (f x₀, y)

Next tactic:
exact (Gf x₀).continuous
theorem QuotientMap.continuous_lift_prod_left (hf : QuotientMap f) {g : X × Y → Z}
    (hg : Continuous fun p : X₀ × Y => g (f p.1, p.2)) : Continuous g := by
  let Gf : C(X₀, C(Y, Z)) := ContinuousMap.curry ⟨_, hg⟩
  have h : ∀ x : X, Continuous fun y => g (x, y) := by
    intro x
    obtain ⟨x₀, rfl⟩ := hf.surjective x
    exact (Gf x₀).continuous
  

Proof state:
X₀ : Type u_1
X : Type u_2
Y : Type u_3
Z : Type u_4
inst✝⁴ : TopologicalSpace X₀
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : LocallyCompactSpace Y
f : X₀ → X
hf : QuotientMap f
g : X × Y → Z
hg : Continuous fun p => g (f p.1, p.2)
Gf : C(X₀, C(Y, Z)) := curry (mk fun p => g (f p.1, p.2))
h : ∀ (x : X), Continuous fun y => g (x, y)
⊢ Continuous g

Next tactic:
let G : X → C(Y, Z) := fun x => ⟨_, h x⟩
theorem QuotientMap.continuous_lift_prod_left (hf : QuotientMap f) {g : X × Y → Z}
    (hg : Continuous fun p : X₀ × Y => g (f p.1, p.2)) : Continuous g := by
  let Gf : C(X₀, C(Y, Z)) := ContinuousMap.curry ⟨_, hg⟩
  have h : ∀ x : X, Continuous fun y => g (x, y) := by
    intro x
    obtain ⟨x₀, rfl⟩ := hf.surjective x
    exact (Gf x₀).continuous
  let G : X → C(Y, Z) := fun x => ⟨_, h x⟩
  

Proof state:
X₀ : Type u_1
X : Type u_2
Y : Type u_3
Z : Type u_4
inst✝⁴ : TopologicalSpace X₀
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : LocallyCompactSpace Y
f : X₀ → X
hf : QuotientMap f
g : X × Y → Z
hg : Continuous fun p => g (f p.1, p.2)
Gf : C(X₀, C(Y, Z)) := curry (mk fun p => g (f p.1, p.2))
h : ∀ (x : X), Continuous fun y => g (x, y)
G : X → C(Y, Z) := fun x => mk fun y => g (x, y)
⊢ Continuous g

Next tactic:
have : Continuous G := by
    rw [hf.continuous_iff]
    exact Gf.continuous
theorem QuotientMap.continuous_lift_prod_left (hf : QuotientMap f) {g : X × Y → Z}
    (hg : Continuous fun p : X₀ × Y => g (f p.1, p.2)) : Continuous g := by
  let Gf : C(X₀, C(Y, Z)) := ContinuousMap.curry ⟨_, hg⟩
  have h : ∀ x : X, Continuous fun y => g (x, y) := by
    intro x
    obtain ⟨x₀, rfl⟩ := hf.surjective x
    exact (Gf x₀).continuous
  let G : X → C(Y, Z) := fun x => ⟨_, h x⟩
  have : Continuous G := by
    

Proof state:
X₀ : Type u_1
X : Type u_2
Y : Type u_3
Z : Type u_4
inst✝⁴ : TopologicalSpace X₀
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : LocallyCompactSpace Y
f : X₀ → X
hf : QuotientMap f
g : X × Y → Z
hg : Continuous fun p => g (f p.1, p.2)
Gf : C(X₀, C(Y, Z)) := curry (mk fun p => g (f p.1, p.2))
h : ∀ (x : X), Continuous fun y => g (x, y)
G : X → C(Y, Z) := fun x => mk fun y => g (x, y)
⊢ Continuous G

Next tactic:
rw [hf.continuous_iff]
theorem QuotientMap.continuous_lift_prod_left (hf : QuotientMap f) {g : X × Y → Z}
    (hg : Continuous fun p : X₀ × Y => g (f p.1, p.2)) : Continuous g := by
  let Gf : C(X₀, C(Y, Z)) := ContinuousMap.curry ⟨_, hg⟩
  have h : ∀ x : X, Continuous fun y => g (x, y) := by
    intro x
    obtain ⟨x₀, rfl⟩ := hf.surjective x
    exact (Gf x₀).continuous
  let G : X → C(Y, Z) := fun x => ⟨_, h x⟩
  have : Continuous G := by
    rw [hf.continuous_iff]
    

Proof state:
X₀ : Type u_1
X : Type u_2
Y : Type u_3
Z : Type u_4
inst✝⁴ : TopologicalSpace X₀
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : LocallyCompactSpace Y
f : X₀ → X
hf : QuotientMap f
g : X × Y → Z
hg : Continuous fun p => g (f p.1, p.2)
Gf : C(X₀, C(Y, Z)) := curry (mk fun p => g (f p.1, p.2))
h : ∀ (x : X), Continuous fun y => g (x, y)
G : X → C(Y, Z) := fun x => mk fun y => g (x, y)
⊢ Continuous (G ∘ f)

Next tactic:
exact Gf.continuous
theorem QuotientMap.continuous_lift_prod_left (hf : QuotientMap f) {g : X × Y → Z}
    (hg : Continuous fun p : X₀ × Y => g (f p.1, p.2)) : Continuous g := by
  let Gf : C(X₀, C(Y, Z)) := ContinuousMap.curry ⟨_, hg⟩
  have h : ∀ x : X, Continuous fun y => g (x, y) := by
    intro x
    obtain ⟨x₀, rfl⟩ := hf.surjective x
    exact (Gf x₀).continuous
  let G : X → C(Y, Z) := fun x => ⟨_, h x⟩
  have : Continuous G := by
    rw [hf.continuous_iff]
    exact Gf.continuous
  

Proof state:
X₀ : Type u_1
X : Type u_2
Y : Type u_3
Z : Type u_4
inst✝⁴ : TopologicalSpace X₀
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : LocallyCompactSpace Y
f : X₀ → X
hf : QuotientMap f
g : X × Y → Z
hg : Continuous fun p => g (f p.1, p.2)
Gf : C(X₀, C(Y, Z)) := curry (mk fun p => g (f p.1, p.2))
h : ∀ (x : X), Continuous fun y => g (x, y)
G : X → C(Y, Z) := fun x => mk fun y => g (x, y)
this : Continuous G
⊢ Continuous g

Next tactic:
exact ContinuousMap.continuous_uncurry_of_continuous ⟨G, this⟩
theorem QuotientMap.continuous_lift_prod_right (hf : QuotientMap f) {g : Y × X → Z}
    (hg : Continuous fun p : Y × X₀ => g (p.1, f p.2)) : Continuous g := by
  

Proof state:
X₀ : Type u_1
X : Type u_2
Y : Type u_3
Z : Type u_4
inst✝⁴ : TopologicalSpace X₀
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : LocallyCompactSpace Y
f : X₀ → X
hf : QuotientMap f
g : Y × X → Z
hg : Continuous fun p => g (p.1, f p.2)
⊢ Continuous g

Next tactic:
have : Continuous fun p : X₀ × Y => g ((Prod.swap p).1, f (Prod.swap p).2) :=
    hg.comp continuous_swap
theorem QuotientMap.continuous_lift_prod_right (hf : QuotientMap f) {g : Y × X → Z}
    (hg : Continuous fun p : Y × X₀ => g (p.1, f p.2)) : Continuous g := by
  have : Continuous fun p : X₀ × Y => g ((Prod.swap p).1, f (Prod.swap p).2) :=
    hg.comp continuous_swap
  

Proof state:
X₀ : Type u_1
X : Type u_2
Y : Type u_3
Z : Type u_4
inst✝⁴ : TopologicalSpace X₀
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : LocallyCompactSpace Y
f : X₀ → X
hf : QuotientMap f
g : Y × X → Z
hg : Continuous fun p => g (p.1, f p.2)
this : Continuous fun p => g ((Prod.swap p).1, f (Prod.swap p).2)
⊢ Continuous g

Next tactic:
have : Continuous fun p : X₀ × Y => (g ∘ Prod.swap) (f p.1, p.2) := this
theorem QuotientMap.continuous_lift_prod_right (hf : QuotientMap f) {g : Y × X → Z}
    (hg : Continuous fun p : Y × X₀ => g (p.1, f p.2)) : Continuous g := by
  have : Continuous fun p : X₀ × Y => g ((Prod.swap p).1, f (Prod.swap p).2) :=
    hg.comp continuous_swap
  have : Continuous fun p : X₀ × Y => (g ∘ Prod.swap) (f p.1, p.2) := this
  

Proof state:
X₀ : Type u_1
X : Type u_2
Y : Type u_3
Z : Type u_4
inst✝⁴ : TopologicalSpace X₀
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : LocallyCompactSpace Y
f : X₀ → X
hf : QuotientMap f
g : Y × X → Z
hg : Continuous fun p => g (p.1, f p.2)
this✝ : Continuous fun p => g ((Prod.swap p).1, f (Prod.swap p).2)
this : Continuous fun p => (g ∘ Prod.swap) (f p.1, p.2)
⊢ Continuous g

Next tactic:
exact (hf.continuous_lift_prod_left this).comp continuous_swap
theorem Function.Injective.smulCommClass [SMul M α] [SMul N α] [SMul M β] [SMul N β]
    [SMulCommClass M N β] {f : α → β} (hf : Function.Injective f)
    (h₁ : ∀ (c : M) x, f (c • x) = c • f x) (h₂ : ∀ (c : N) x, f (c • x) = c • f x) :
    SMulCommClass M N α where
  smul_comm c₁ c₂ x := hf <| by 

Proof state:
M : Type u_1
N : Type u_2
G : Type u_3
A : Type u_4
B : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
δ : Type u_9
inst✝⁴ : SMul M α
inst✝³ : SMul N α
inst✝² : SMul M β
inst✝¹ : SMul N β
inst✝ : SMulCommClass M N β
f : α → β
hf : Injective f
h₁ : ∀ (c : M) (x : α), f (c • x) = c • f x
h₂ : ∀ (c : N) (x : α), f (c • x) = c • f x
c₁ : M
c₂ : N
x : α
⊢ f (c₁ • c₂ • x) = f (c₂ • c₁ • x)

Next tactic:
simp only [h₁, h₂, smul_comm c₁ c₂ (f x)]
theorem Function.Surjective.smulCommClass [SMul M α] [SMul N α] [SMul M β] [SMul N β]
    [SMulCommClass M N α] {f : α → β} (hf : Function.Surjective f)
    (h₁ : ∀ (c : M) x, f (c • x) = c • f x) (h₂ : ∀ (c : N) x, f (c • x) = c • f x) :
    SMulCommClass M N β where
  smul_comm c₁ c₂ := hf.forall.2 fun x ↦ by 

Proof state:
M : Type u_1
N : Type u_2
G : Type u_3
A : Type u_4
B : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
δ : Type u_9
inst✝⁴ : SMul M α
inst✝³ : SMul N α
inst✝² : SMul M β
inst✝¹ : SMul N β
inst✝ : SMulCommClass M N α
f : α → β
hf : Surjective f
h₁ : ∀ (c : M) (x : α), f (c • x) = c • f x
h₂ : ∀ (c : N) (x : α), f (c • x) = c • f x
c₁ : M
c₂ : N
x : α
⊢ c₁ • c₂ • f x = c₂ • c₁ • f x

Next tactic:
simp only [← h₁, ← h₂, smul_comm c₁ c₂ x]
@[to_additive]
instance smulCommClass_self (M α : Type*) [CommMonoid M] [MulAction M α] : SMulCommClass M M α :=
  ⟨fun a a' b => by 

Proof state:
M✝ : Type u_1
N : Type u_2
G : Type u_3
A : Type u_4
B : Type u_5
α✝ : Type u_6
β : Type u_7
γ : Type u_8
δ : Type u_9
M : Type u_10
α : Type u_11
inst✝¹ : CommMonoid M
inst✝ : MulAction M α
a a' : M
b : α
⊢ a • a' • b = a' • a • b

Next tactic:
rw [← mul_smul, mul_comm, mul_smul]
@[to_additive]
theorem IsCentralScalar.unop_smul_eq_smul {M α : Type*} [SMul M α] [SMul Mᵐᵒᵖ α]
    [IsCentralScalar M α] (m : Mᵐᵒᵖ) (a : α) : MulOpposite.unop m • a = m • a := by
  

Proof state:
M✝ : Type u_1
N : Type u_2
G : Type u_3
A : Type u_4
B : Type u_5
α✝ : Type u_6
β : Type u_7
γ : Type u_8
δ : Type u_9
M : Type u_10
α : Type u_11
inst✝² : SMul M α
inst✝¹ : SMul Mᵐᵒᵖ α
inst✝ : IsCentralScalar M α
m : Mᵐᵒᵖ
a : α
⊢ MulOpposite.unop m • a = m • a

Next tactic:
induction m using MulOpposite.rec'
@[to_additive]
theorem IsCentralScalar.unop_smul_eq_smul {M α : Type*} [SMul M α] [SMul Mᵐᵒᵖ α]
    [IsCentralScalar M α] (m : Mᵐᵒᵖ) (a : α) : MulOpposite.unop m • a = m • a := by
  induction m using MulOpposite.rec'
  

Proof state:
case h
M✝ : Type u_1
N : Type u_2
G : Type u_3
A : Type u_4
B : Type u_5
α✝ : Type u_6
β : Type u_7
γ : Type u_8
δ : Type u_9
M : Type u_10
α : Type u_11
inst✝² : SMul M α
inst✝¹ : SMul Mᵐᵒᵖ α
inst✝ : IsCentralScalar M α
a : α
X✝ : M
⊢ MulOpposite.unop (MulOpposite.op X✝) • a = MulOpposite.op X✝ • a

Next tactic:
exact (IsCentralScalar.op_smul_eq_smul _ a).symm