l3lab/ntp-mathlib huggingface dataset:
/-- The product of two smooth local homeomorphisms is smooth. -/
theorem contDiffGroupoid_prod {I : ModelWithCorners 𝕜 E H} {I' : ModelWithCorners 𝕜 E' H'}
    {e : PartialHomeomorph H H} {e' : PartialHomeomorph H' H'} (he : e ∈ contDiffGroupoid ⊤ I)
    (he' : e' ∈ contDiffGroupoid ⊤ I') : e.prod e' ∈ contDiffGroupoid ⊤ (I.prod I') := by
  

Proof state:
m n : ℕ∞
𝕜 : Type u_1
inst✝⁷ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝⁶ : NormedAddCommGroup E
inst✝⁵ : NormedSpace 𝕜 E
H : Type u_3
inst✝⁴ : TopologicalSpace H
I✝ : ModelWithCorners 𝕜 E H
M : Type u_4
inst✝³ : TopologicalSpace M
E' : Type u_5
H' : Type u_6
inst✝² : NormedAddCommGroup E'
inst✝¹ : NormedSpace 𝕜 E'
inst✝ : TopologicalSpace H'
I : ModelWithCorners 𝕜 E H
I' : ModelWithCorners 𝕜 E' H'
e : PartialHomeomorph H H
e' : PartialHomeomorph H' H'
he : e ∈ contDiffGroupoid ⊤ I
he' : e' ∈ contDiffGroupoid ⊤ I'
⊢ PartialHomeomorph.prod e e' ∈ contDiffGroupoid ⊤ (ModelWithCorners.prod I I')

Next tactic:
cases' he with he he_symm
/-- The product of two smooth local homeomorphisms is smooth. -/
theorem contDiffGroupoid_prod {I : ModelWithCorners 𝕜 E H} {I' : ModelWithCorners 𝕜 E' H'}
    {e : PartialHomeomorph H H} {e' : PartialHomeomorph H' H'} (he : e ∈ contDiffGroupoid ⊤ I)
    (he' : e' ∈ contDiffGroupoid ⊤ I') : e.prod e' ∈ contDiffGroupoid ⊤ (I.prod I') := by
  cases' he with he he_symm
  cases' he' with he' he'_symm
  simp only at he he_symm he' he'_symm
  

Proof state:
case intro.intro
m n : ℕ∞
𝕜 : Type u_1
inst✝⁷ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝⁶ : NormedAddCommGroup E
inst✝⁵ : NormedSpace 𝕜 E
H : Type u_3
inst✝⁴ : TopologicalSpace H
I✝ : ModelWithCorners 𝕜 E H
M : Type u_4
inst✝³ : TopologicalSpace M
E' : Type u_5
H' : Type u_6
inst✝² : NormedAddCommGroup E'
inst✝¹ : NormedSpace 𝕜 E'
inst✝ : TopologicalSpace H'
I : ModelWithCorners 𝕜 E H
I' : ModelWithCorners 𝕜 E' H'
e : PartialHomeomorph H H
e' : PartialHomeomorph H' H'
he : ContDiffOn 𝕜 ⊤ (↑I ∘ ↑e ∘ ↑(ModelWithCorners.symm I)) (↑(ModelWithCorners.symm I) ⁻¹' e.source ∩ range ↑I)
he_symm :
  ContDiffOn 𝕜 ⊤ (↑I ∘ ↑(PartialHomeomorph.symm e) ∘ ↑(ModelWithCorners.symm I))
    (↑(ModelWithCorners.symm I) ⁻¹' e.target ∩ range ↑I)
he' : ContDiffOn 𝕜 ⊤ (↑I' ∘ ↑e' ∘ ↑(ModelWithCorners.symm I')) (↑(ModelWithCorners.symm I') ⁻¹' e'.source ∩ range ↑I')
he'_symm :
  ContDiffOn 𝕜 ⊤ (↑I' ∘ ↑(PartialHomeomorph.symm e') ∘ ↑(ModelWithCorners.symm I'))
    (↑(ModelWithCorners.symm I') ⁻¹' e'.target ∩ range ↑I')
⊢ PartialHomeomorph.prod e e' ∈ contDiffGroupoid ⊤ (ModelWithCorners.prod I I')

Next tactic:
constructor
/-- The product of two smooth local homeomorphisms is smooth. -/
theorem contDiffGroupoid_prod {I : ModelWithCorners 𝕜 E H} {I' : ModelWithCorners 𝕜 E' H'}
    {e : PartialHomeomorph H H} {e' : PartialHomeomorph H' H'} (he : e ∈ contDiffGroupoid ⊤ I)
    (he' : e' ∈ contDiffGroupoid ⊤ I') : e.prod e' ∈ contDiffGroupoid ⊤ (I.prod I') := by
  cases' he with he he_symm
  cases' he' with he' he'_symm
  simp only at he he_symm he' he'_symm
  constructor <;> simp only [PartialEquiv.prod_source, PartialHomeomorph.prod_toPartialEquiv]
  · 

Proof state:
case intro.intro.left
m n : ℕ∞
𝕜 : Type u_1
inst✝⁷ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝⁶ : NormedAddCommGroup E
inst✝⁵ : NormedSpace 𝕜 E
H : Type u_3
inst✝⁴ : TopologicalSpace H
I✝ : ModelWithCorners 𝕜 E H
M : Type u_4
inst✝³ : TopologicalSpace M
E' : Type u_5
H' : Type u_6
inst✝² : NormedAddCommGroup E'
inst✝¹ : NormedSpace 𝕜 E'
inst✝ : TopologicalSpace H'
I : ModelWithCorners 𝕜 E H
I' : ModelWithCorners 𝕜 E' H'
e : PartialHomeomorph H H
e' : PartialHomeomorph H' H'
he : ContDiffOn 𝕜 ⊤ (↑I ∘ ↑e ∘ ↑(ModelWithCorners.symm I)) (↑(ModelWithCorners.symm I) ⁻¹' e.source ∩ range ↑I)
he_symm :
  ContDiffOn 𝕜 ⊤ (↑I ∘ ↑(PartialHomeomorph.symm e) ∘ ↑(ModelWithCorners.symm I))
    (↑(ModelWithCorners.symm I) ⁻¹' e.target ∩ range ↑I)
he' : ContDiffOn 𝕜 ⊤ (↑I' ∘ ↑e' ∘ ↑(ModelWithCorners.symm I')) (↑(ModelWithCorners.symm I') ⁻¹' e'.source ∩ range ↑I')
he'_symm :
  ContDiffOn 𝕜 ⊤ (↑I' ∘ ↑(PartialHomeomorph.symm e') ∘ ↑(ModelWithCorners.symm I'))
    (↑(ModelWithCorners.symm I') ⁻¹' e'.target ∩ range ↑I')
⊢ ContDiffOn 𝕜 ⊤
    (↑(ModelWithCorners.prod I I') ∘
      ↑(PartialHomeomorph.prod e e') ∘ ↑(ModelWithCorners.symm (ModelWithCorners.prod I I')))
    (↑(ModelWithCorners.symm (ModelWithCorners.prod I I')) ⁻¹' e.source ×ˢ e'.source ∩
      range ↑(ModelWithCorners.prod I I'))

Next tactic:
have h3 := ContDiffOn.prod_map he he'
/-- The product of two smooth local homeomorphisms is smooth. -/
theorem contDiffGroupoid_prod {I : ModelWithCorners 𝕜 E H} {I' : ModelWithCorners 𝕜 E' H'}
    {e : PartialHomeomorph H H} {e' : PartialHomeomorph H' H'} (he : e ∈ contDiffGroupoid ⊤ I)
    (he' : e' ∈ contDiffGroupoid ⊤ I') : e.prod e' ∈ contDiffGroupoid ⊤ (I.prod I') := by
  cases' he with he he_symm
  cases' he' with he' he'_symm
  simp only at he he_symm he' he'_symm
  constructor <;> simp only [PartialEquiv.prod_source, PartialHomeomorph.prod_toPartialEquiv]
  · have h3 := ContDiffOn.prod_map he he'
    

Proof state:
case intro.intro.left
m n : ℕ∞
𝕜 : Type u_1
inst✝⁷ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝⁶ : NormedAddCommGroup E
inst✝⁵ : NormedSpace 𝕜 E
H : Type u_3
inst✝⁴ : TopologicalSpace H
I✝ : ModelWithCorners 𝕜 E H
M : Type u_4
inst✝³ : TopologicalSpace M
E' : Type u_5
H' : Type u_6
inst✝² : NormedAddCommGroup E'
inst✝¹ : NormedSpace 𝕜 E'
inst✝ : TopologicalSpace H'
I : ModelWithCorners 𝕜 E H
I' : ModelWithCorners 𝕜 E' H'
e : PartialHomeomorph H H
e' : PartialHomeomorph H' H'
he : ContDiffOn 𝕜 ⊤ (↑I ∘ ↑e ∘ ↑(ModelWithCorners.symm I)) (↑(ModelWithCorners.symm I) ⁻¹' e.source ∩ range ↑I)
he_symm :
  ContDiffOn 𝕜 ⊤ (↑I ∘ ↑(PartialHomeomorph.symm e) ∘ ↑(ModelWithCorners.symm I))
    (↑(ModelWithCorners.symm I) ⁻¹' e.target ∩ range ↑I)
he' : ContDiffOn 𝕜 ⊤ (↑I' ∘ ↑e' ∘ ↑(ModelWithCorners.symm I')) (↑(ModelWithCorners.symm I') ⁻¹' e'.source ∩ range ↑I')
he'_symm :
  ContDiffOn 𝕜 ⊤ (↑I' ∘ ↑(PartialHomeomorph.symm e') ∘ ↑(ModelWithCorners.symm I'))
    (↑(ModelWithCorners.symm I') ⁻¹' e'.target ∩ range ↑I')
h3 :
  ContDiffOn 𝕜 ⊤ (Prod.map (↑I ∘ ↑e ∘ ↑(ModelWithCorners.symm I)) (↑I' ∘ ↑e' ∘ ↑(ModelWithCorners.symm I')))
    ((↑(ModelWithCorners.symm I) ⁻¹' e.source ∩ range ↑I) ×ˢ (↑(ModelWithCorners.symm I') ⁻¹' e'.source ∩ range ↑I'))
⊢ ContDiffOn 𝕜 ⊤
    (↑(ModelWithCorners.prod I I') ∘
      ↑(PartialHomeomorph.prod e e') ∘ ↑(ModelWithCorners.symm (ModelWithCorners.prod I I')))
    (↑(ModelWithCorners.symm (ModelWithCorners.prod I I')) ⁻¹' e.source ×ˢ e'.source ∩
      range ↑(ModelWithCorners.prod I I'))

Next tactic:
rw [← I.image_eq, ← I'.image_eq, prod_image_image_eq] at h3
/-- The product of two smooth local homeomorphisms is smooth. -/
theorem contDiffGroupoid_prod {I : ModelWithCorners 𝕜 E H} {I' : ModelWithCorners 𝕜 E' H'}
    {e : PartialHomeomorph H H} {e' : PartialHomeomorph H' H'} (he : e ∈ contDiffGroupoid ⊤ I)
    (he' : e' ∈ contDiffGroupoid ⊤ I') : e.prod e' ∈ contDiffGroupoid ⊤ (I.prod I') := by
  cases' he with he he_symm
  cases' he' with he' he'_symm
  simp only at he he_symm he' he'_symm
  constructor <;> simp only [PartialEquiv.prod_source, PartialHomeomorph.prod_toPartialEquiv]
  · have h3 := ContDiffOn.prod_map he he'
    rw [← I.image_eq, ← I'.image_eq, prod_image_image_eq] at h3
    

Proof state:
case intro.intro.left
m n : ℕ∞
𝕜 : Type u_1
inst✝⁷ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝⁶ : NormedAddCommGroup E
inst✝⁵ : NormedSpace 𝕜 E
H : Type u_3
inst✝⁴ : TopologicalSpace H
I✝ : ModelWithCorners 𝕜 E H
M : Type u_4
inst✝³ : TopologicalSpace M
E' : Type u_5
H' : Type u_6
inst✝² : NormedAddCommGroup E'
inst✝¹ : NormedSpace 𝕜 E'
inst✝ : TopologicalSpace H'
I : ModelWithCorners 𝕜 E H
I' : ModelWithCorners 𝕜 E' H'
e : PartialHomeomorph H H
e' : PartialHomeomorph H' H'
he : ContDiffOn 𝕜 ⊤ (↑I ∘ ↑e ∘ ↑(ModelWithCorners.symm I)) (↑(ModelWithCorners.symm I) ⁻¹' e.source ∩ range ↑I)
he_symm :
  ContDiffOn 𝕜 ⊤ (↑I ∘ ↑(PartialHomeomorph.symm e) ∘ ↑(ModelWithCorners.symm I))
    (↑(ModelWithCorners.symm I) ⁻¹' e.target ∩ range ↑I)
he' : ContDiffOn 𝕜 ⊤ (↑I' ∘ ↑e' ∘ ↑(ModelWithCorners.symm I')) (↑(ModelWithCorners.symm I') ⁻¹' e'.source ∩ range ↑I')
he'_symm :
  ContDiffOn 𝕜 ⊤ (↑I' ∘ ↑(PartialHomeomorph.symm e') ∘ ↑(ModelWithCorners.symm I'))
    (↑(ModelWithCorners.symm I') ⁻¹' e'.target ∩ range ↑I')
h3 :
  ContDiffOn 𝕜 ⊤ (Prod.map (↑I ∘ ↑e ∘ ↑(ModelWithCorners.symm I)) (↑I' ∘ ↑e' ∘ ↑(ModelWithCorners.symm I')))
    ((fun p => (↑I p.1, ↑I' p.2)) '' e.source ×ˢ e'.source)
⊢ ContDiffOn 𝕜 ⊤
    (↑(ModelWithCorners.prod I I') ∘
      ↑(PartialHomeomorph.prod e e') ∘ ↑(ModelWithCorners.symm (ModelWithCorners.prod I I')))
    (↑(ModelWithCorners.symm (ModelWithCorners.prod I I')) ⁻¹' e.source ×ˢ e'.source ∩
      range ↑(ModelWithCorners.prod I I'))

Next tactic:
rw [← (I.prod I').image_eq]
/-- The product of two smooth local homeomorphisms is smooth. -/
theorem contDiffGroupoid_prod {I : ModelWithCorners 𝕜 E H} {I' : ModelWithCorners 𝕜 E' H'}
    {e : PartialHomeomorph H H} {e' : PartialHomeomorph H' H'} (he : e ∈ contDiffGroupoid ⊤ I)
    (he' : e' ∈ contDiffGroupoid ⊤ I') : e.prod e' ∈ contDiffGroupoid ⊤ (I.prod I') := by
  cases' he with he he_symm
  cases' he' with he' he'_symm
  simp only at he he_symm he' he'_symm
  constructor <;> simp only [PartialEquiv.prod_source, PartialHomeomorph.prod_toPartialEquiv]
  · have h3 := ContDiffOn.prod_map he he'
    rw [← I.image_eq, ← I'.image_eq, prod_image_image_eq] at h3
    rw [← (I.prod I').image_eq]
    

Proof state:
case intro.intro.left
m n : ℕ∞
𝕜 : Type u_1
inst✝⁷ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝⁶ : NormedAddCommGroup E
inst✝⁵ : NormedSpace 𝕜 E
H : Type u_3
inst✝⁴ : TopologicalSpace H
I✝ : ModelWithCorners 𝕜 E H
M : Type u_4
inst✝³ : TopologicalSpace M
E' : Type u_5
H' : Type u_6
inst✝² : NormedAddCommGroup E'
inst✝¹ : NormedSpace 𝕜 E'
inst✝ : TopologicalSpace H'
I : ModelWithCorners 𝕜 E H
I' : ModelWithCorners 𝕜 E' H'
e : PartialHomeomorph H H
e' : PartialHomeomorph H' H'
he : ContDiffOn 𝕜 ⊤ (↑I ∘ ↑e ∘ ↑(ModelWithCorners.symm I)) (↑(ModelWithCorners.symm I) ⁻¹' e.source ∩ range ↑I)
he_symm :
  ContDiffOn 𝕜 ⊤ (↑I ∘ ↑(PartialHomeomorph.symm e) ∘ ↑(ModelWithCorners.symm I))
    (↑(ModelWithCorners.symm I) ⁻¹' e.target ∩ range ↑I)
he' : ContDiffOn 𝕜 ⊤ (↑I' ∘ ↑e' ∘ ↑(ModelWithCorners.symm I')) (↑(ModelWithCorners.symm I') ⁻¹' e'.source ∩ range ↑I')
he'_symm :
  ContDiffOn 𝕜 ⊤ (↑I' ∘ ↑(PartialHomeomorph.symm e') ∘ ↑(ModelWithCorners.symm I'))
    (↑(ModelWithCorners.symm I') ⁻¹' e'.target ∩ range ↑I')
h3 :
  ContDiffOn 𝕜 ⊤ (Prod.map (↑I ∘ ↑e ∘ ↑(ModelWithCorners.symm I)) (↑I' ∘ ↑e' ∘ ↑(ModelWithCorners.symm I')))
    ((fun p => (↑I p.1, ↑I' p.2)) '' e.source ×ˢ e'.source)
⊢ ContDiffOn 𝕜 ⊤
    (↑(ModelWithCorners.prod I I') ∘
      ↑(PartialHomeomorph.prod e e') ∘ ↑(ModelWithCorners.symm (ModelWithCorners.prod I I')))
    (↑(ModelWithCorners.prod I I') '' e.source ×ˢ e'.source)

Next tactic:
exact h3
/-- The product of two smooth local homeomorphisms is smooth. -/
theorem contDiffGroupoid_prod {I : ModelWithCorners 𝕜 E H} {I' : ModelWithCorners 𝕜 E' H'}
    {e : PartialHomeomorph H H} {e' : PartialHomeomorph H' H'} (he : e ∈ contDiffGroupoid ⊤ I)
    (he' : e' ∈ contDiffGroupoid ⊤ I') : e.prod e' ∈ contDiffGroupoid ⊤ (I.prod I') := by
  cases' he with he he_symm
  cases' he' with he' he'_symm
  simp only at he he_symm he' he'_symm
  constructor <;> simp only [PartialEquiv.prod_source, PartialHomeomorph.prod_toPartialEquiv]
  · have h3 := ContDiffOn.prod_map he he'
    rw [← I.image_eq, ← I'.image_eq, prod_image_image_eq] at h3
    rw [← (I.prod I').image_eq]
    exact h3
  · 

Proof state:
case intro.intro.right
m n : ℕ∞
𝕜 : Type u_1
inst✝⁷ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝⁶ : NormedAddCommGroup E
inst✝⁵ : NormedSpace 𝕜 E
H : Type u_3
inst✝⁴ : TopologicalSpace H
I✝ : ModelWithCorners 𝕜 E H
M : Type u_4
inst✝³ : TopologicalSpace M
E' : Type u_5
H' : Type u_6
inst✝² : NormedAddCommGroup E'
inst✝¹ : NormedSpace 𝕜 E'
inst✝ : TopologicalSpace H'
I : ModelWithCorners 𝕜 E H
I' : ModelWithCorners 𝕜 E' H'
e : PartialHomeomorph H H
e' : PartialHomeomorph H' H'
he : ContDiffOn 𝕜 ⊤ (↑I ∘ ↑e ∘ ↑(ModelWithCorners.symm I)) (↑(ModelWithCorners.symm I) ⁻¹' e.source ∩ range ↑I)
he_symm :
  ContDiffOn 𝕜 ⊤ (↑I ∘ ↑(PartialHomeomorph.symm e) ∘ ↑(ModelWithCorners.symm I))
    (↑(ModelWithCorners.symm I) ⁻¹' e.target ∩ range ↑I)
he' : ContDiffOn 𝕜 ⊤ (↑I' ∘ ↑e' ∘ ↑(ModelWithCorners.symm I')) (↑(ModelWithCorners.symm I') ⁻¹' e'.source ∩ range ↑I')
he'_symm :
  ContDiffOn 𝕜 ⊤ (↑I' ∘ ↑(PartialHomeomorph.symm e') ∘ ↑(ModelWithCorners.symm I'))
    (↑(ModelWithCorners.symm I') ⁻¹' e'.target ∩ range ↑I')
⊢ ContDiffOn 𝕜 ⊤
    (↑(ModelWithCorners.prod I I') ∘
      ↑(PartialHomeomorph.symm (PartialHomeomorph.prod e e')) ∘ ↑(ModelWithCorners.symm (ModelWithCorners.prod I I')))
    (↑(ModelWithCorners.symm (ModelWithCorners.prod I I')) ⁻¹'
        (PartialEquiv.prod e.toPartialEquiv e'.toPartialEquiv).target ∩
      range ↑(ModelWithCorners.prod I I'))

Next tactic:
have h3 := ContDiffOn.prod_map he_symm he'_symm
/-- The product of two smooth local homeomorphisms is smooth. -/
theorem contDiffGroupoid_prod {I : ModelWithCorners 𝕜 E H} {I' : ModelWithCorners 𝕜 E' H'}
    {e : PartialHomeomorph H H} {e' : PartialHomeomorph H' H'} (he : e ∈ contDiffGroupoid ⊤ I)
    (he' : e' ∈ contDiffGroupoid ⊤ I') : e.prod e' ∈ contDiffGroupoid ⊤ (I.prod I') := by
  cases' he with he he_symm
  cases' he' with he' he'_symm
  simp only at he he_symm he' he'_symm
  constructor <;> simp only [PartialEquiv.prod_source, PartialHomeomorph.prod_toPartialEquiv]
  · have h3 := ContDiffOn.prod_map he he'
    rw [← I.image_eq, ← I'.image_eq, prod_image_image_eq] at h3
    rw [← (I.prod I').image_eq]
    exact h3
  · have h3 := ContDiffOn.prod_map he_symm he'_symm
    

Proof state:
case intro.intro.right
m n : ℕ∞
𝕜 : Type u_1
inst✝⁷ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝⁶ : NormedAddCommGroup E
inst✝⁵ : NormedSpace 𝕜 E
H : Type u_3
inst✝⁴ : TopologicalSpace H
I✝ : ModelWithCorners 𝕜 E H
M : Type u_4
inst✝³ : TopologicalSpace M
E' : Type u_5
H' : Type u_6
inst✝² : NormedAddCommGroup E'
inst✝¹ : NormedSpace 𝕜 E'
inst✝ : TopologicalSpace H'
I : ModelWithCorners 𝕜 E H
I' : ModelWithCorners 𝕜 E' H'
e : PartialHomeomorph H H
e' : PartialHomeomorph H' H'
he : ContDiffOn 𝕜 ⊤ (↑I ∘ ↑e ∘ ↑(ModelWithCorners.symm I)) (↑(ModelWithCorners.symm I) ⁻¹' e.source ∩ range ↑I)
he_symm :
  ContDiffOn 𝕜 ⊤ (↑I ∘ ↑(PartialHomeomorph.symm e) ∘ ↑(ModelWithCorners.symm I))
    (↑(ModelWithCorners.symm I) ⁻¹' e.target ∩ range ↑I)
he' : ContDiffOn 𝕜 ⊤ (↑I' ∘ ↑e' ∘ ↑(ModelWithCorners.symm I')) (↑(ModelWithCorners.symm I') ⁻¹' e'.source ∩ range ↑I')
he'_symm :
  ContDiffOn 𝕜 ⊤ (↑I' ∘ ↑(PartialHomeomorph.symm e') ∘ ↑(ModelWithCorners.symm I'))
    (↑(ModelWithCorners.symm I') ⁻¹' e'.target ∩ range ↑I')
h3 :
  ContDiffOn 𝕜 ⊤
    (Prod.map (↑I ∘ ↑(PartialHomeomorph.symm e) ∘ ↑(ModelWithCorners.symm I))
      (↑I' ∘ ↑(PartialHomeomorph.symm e') ∘ ↑(ModelWithCorners.symm I')))
    ((↑(ModelWithCorners.symm I) ⁻¹' e.target ∩ range ↑I) ×ˢ (↑(ModelWithCorners.symm I') ⁻¹' e'.target ∩ range ↑I'))
⊢ ContDiffOn 𝕜 ⊤
    (↑(ModelWithCorners.prod I I') ∘
      ↑(PartialHomeomorph.symm (PartialHomeomorph.prod e e')) ∘ ↑(ModelWithCorners.symm (ModelWithCorners.prod I I')))
    (↑(ModelWithCorners.symm (ModelWithCorners.prod I I')) ⁻¹'
        (PartialEquiv.prod e.toPartialEquiv e'.toPartialEquiv).target ∩
      range ↑(ModelWithCorners.prod I I'))

Next tactic:
rw [← I.image_eq, ← I'.image_eq, prod_image_image_eq] at h3
/-- The product of two smooth local homeomorphisms is smooth. -/
theorem contDiffGroupoid_prod {I : ModelWithCorners 𝕜 E H} {I' : ModelWithCorners 𝕜 E' H'}
    {e : PartialHomeomorph H H} {e' : PartialHomeomorph H' H'} (he : e ∈ contDiffGroupoid ⊤ I)
    (he' : e' ∈ contDiffGroupoid ⊤ I') : e.prod e' ∈ contDiffGroupoid ⊤ (I.prod I') := by
  cases' he with he he_symm
  cases' he' with he' he'_symm
  simp only at he he_symm he' he'_symm
  constructor <;> simp only [PartialEquiv.prod_source, PartialHomeomorph.prod_toPartialEquiv]
  · have h3 := ContDiffOn.prod_map he he'
    rw [← I.image_eq, ← I'.image_eq, prod_image_image_eq] at h3
    rw [← (I.prod I').image_eq]
    exact h3
  · have h3 := ContDiffOn.prod_map he_symm he'_symm
    rw [← I.image_eq, ← I'.image_eq, prod_image_image_eq] at h3
    

Proof state:
case intro.intro.right
m n : ℕ∞
𝕜 : Type u_1
inst✝⁷ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝⁶ : NormedAddCommGroup E
inst✝⁵ : NormedSpace 𝕜 E
H : Type u_3
inst✝⁴ : TopologicalSpace H
I✝ : ModelWithCorners 𝕜 E H
M : Type u_4
inst✝³ : TopologicalSpace M
E' : Type u_5
H' : Type u_6
inst✝² : NormedAddCommGroup E'
inst✝¹ : NormedSpace 𝕜 E'
inst✝ : TopologicalSpace H'
I : ModelWithCorners 𝕜 E H
I' : ModelWithCorners 𝕜 E' H'
e : PartialHomeomorph H H
e' : PartialHomeomorph H' H'
he : ContDiffOn 𝕜 ⊤ (↑I ∘ ↑e ∘ ↑(ModelWithCorners.symm I)) (↑(ModelWithCorners.symm I) ⁻¹' e.source ∩ range ↑I)
he_symm :
  ContDiffOn 𝕜 ⊤ (↑I ∘ ↑(PartialHomeomorph.symm e) ∘ ↑(ModelWithCorners.symm I))
    (↑(ModelWithCorners.symm I) ⁻¹' e.target ∩ range ↑I)
he' : ContDiffOn 𝕜 ⊤ (↑I' ∘ ↑e' ∘ ↑(ModelWithCorners.symm I')) (↑(ModelWithCorners.symm I') ⁻¹' e'.source ∩ range ↑I')
he'_symm :
  ContDiffOn 𝕜 ⊤ (↑I' ∘ ↑(PartialHomeomorph.symm e') ∘ ↑(ModelWithCorners.symm I'))
    (↑(ModelWithCorners.symm I') ⁻¹' e'.target ∩ range ↑I')
h3 :
  ContDiffOn 𝕜 ⊤
    (Prod.map (↑I ∘ ↑(PartialHomeomorph.symm e) ∘ ↑(ModelWithCorners.symm I))
      (↑I' ∘ ↑(PartialHomeomorph.symm e') ∘ ↑(ModelWithCorners.symm I')))
    ((fun p => (↑I p.1, ↑I' p.2)) '' e.target ×ˢ e'.target)
⊢ ContDiffOn 𝕜 ⊤
    (↑(ModelWithCorners.prod I I') ∘
      ↑(PartialHomeomorph.symm (PartialHomeomorph.prod e e')) ∘ ↑(ModelWithCorners.symm (ModelWithCorners.prod I I')))
    (↑(ModelWithCorners.symm (ModelWithCorners.prod I I')) ⁻¹'
        (PartialEquiv.prod e.toPartialEquiv e'.toPartialEquiv).target ∩
      range ↑(ModelWithCorners.prod I I'))

Next tactic:
rw [← (I.prod I').image_eq]
/-- The product of two smooth local homeomorphisms is smooth. -/
theorem contDiffGroupoid_prod {I : ModelWithCorners 𝕜 E H} {I' : ModelWithCorners 𝕜 E' H'}
    {e : PartialHomeomorph H H} {e' : PartialHomeomorph H' H'} (he : e ∈ contDiffGroupoid ⊤ I)
    (he' : e' ∈ contDiffGroupoid ⊤ I') : e.prod e' ∈ contDiffGroupoid ⊤ (I.prod I') := by
  cases' he with he he_symm
  cases' he' with he' he'_symm
  simp only at he he_symm he' he'_symm
  constructor <;> simp only [PartialEquiv.prod_source, PartialHomeomorph.prod_toPartialEquiv]
  · have h3 := ContDiffOn.prod_map he he'
    rw [← I.image_eq, ← I'.image_eq, prod_image_image_eq] at h3
    rw [← (I.prod I').image_eq]
    exact h3
  · have h3 := ContDiffOn.prod_map he_symm he'_symm
    rw [← I.image_eq, ← I'.image_eq, prod_image_image_eq] at h3
    rw [← (I.prod I').image_eq]
    

Proof state:
case intro.intro.right
m n : ℕ∞
𝕜 : Type u_1
inst✝⁷ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝⁶ : NormedAddCommGroup E
inst✝⁵ : NormedSpace 𝕜 E
H : Type u_3
inst✝⁴ : TopologicalSpace H
I✝ : ModelWithCorners 𝕜 E H
M : Type u_4
inst✝³ : TopologicalSpace M
E' : Type u_5
H' : Type u_6
inst✝² : NormedAddCommGroup E'
inst✝¹ : NormedSpace 𝕜 E'
inst✝ : TopologicalSpace H'
I : ModelWithCorners 𝕜 E H
I' : ModelWithCorners 𝕜 E' H'
e : PartialHomeomorph H H
e' : PartialHomeomorph H' H'
he : ContDiffOn 𝕜 ⊤ (↑I ∘ ↑e ∘ ↑(ModelWithCorners.symm I)) (↑(ModelWithCorners.symm I) ⁻¹' e.source ∩ range ↑I)
he_symm :
  ContDiffOn 𝕜 ⊤ (↑I ∘ ↑(PartialHomeomorph.symm e) ∘ ↑(ModelWithCorners.symm I))
    (↑(ModelWithCorners.symm I) ⁻¹' e.target ∩ range ↑I)
he' : ContDiffOn 𝕜 ⊤ (↑I' ∘ ↑e' ∘ ↑(ModelWithCorners.symm I')) (↑(ModelWithCorners.symm I') ⁻¹' e'.source ∩ range ↑I')
he'_symm :
  ContDiffOn 𝕜 ⊤ (↑I' ∘ ↑(PartialHomeomorph.symm e') ∘ ↑(ModelWithCorners.symm I'))
    (↑(ModelWithCorners.symm I') ⁻¹' e'.target ∩ range ↑I')
h3 :
  ContDiffOn 𝕜 ⊤
    (Prod.map (↑I ∘ ↑(PartialHomeomorph.symm e) ∘ ↑(ModelWithCorners.symm I))
      (↑I' ∘ ↑(PartialHomeomorph.symm e') ∘ ↑(ModelWithCorners.symm I')))
    ((fun p => (↑I p.1, ↑I' p.2)) '' e.target ×ˢ e'.target)
⊢ ContDiffOn 𝕜 ⊤
    (↑(ModelWithCorners.prod I I') ∘
      ↑(PartialHomeomorph.symm (PartialHomeomorph.prod e e')) ∘ ↑(ModelWithCorners.symm (ModelWithCorners.prod I I')))
    (↑(ModelWithCorners.prod I I') '' (PartialEquiv.prod e.toPartialEquiv e'.toPartialEquiv).target)

Next tactic:
exact h3
/-- The `C^n` groupoid is closed under restriction. -/
instance : ClosedUnderRestriction (contDiffGroupoid n I) :=
  (closedUnderRestriction_iff_id_le _).mpr
    (by
      

Proof state:
m n : ℕ∞
𝕜 : Type u_1
inst✝⁷ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝⁶ : NormedAddCommGroup E
inst✝⁵ : NormedSpace 𝕜 E
H : Type u_3
inst✝⁴ : TopologicalSpace H
I : ModelWithCorners 𝕜 E H
M : Type u_4
inst✝³ : TopologicalSpace M
E' : Type u_5
H' : Type u_6
inst✝² : NormedAddCommGroup E'
inst✝¹ : NormedSpace 𝕜 E'
inst✝ : TopologicalSpace H'
⊢ idRestrGroupoid ≤ contDiffGroupoid n I

Next tactic:
apply StructureGroupoid.le_iff.mpr
/-- The `C^n` groupoid is closed under restriction. -/
instance : ClosedUnderRestriction (contDiffGroupoid n I) :=
  (closedUnderRestriction_iff_id_le _).mpr
    (by
      apply StructureGroupoid.le_iff.mpr
      

Proof state:
m n : ℕ∞
𝕜 : Type u_1
inst✝⁷ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝⁶ : NormedAddCommGroup E
inst✝⁵ : NormedSpace 𝕜 E
H : Type u_3
inst✝⁴ : TopologicalSpace H
I : ModelWithCorners 𝕜 E H
M : Type u_4
inst✝³ : TopologicalSpace M
E' : Type u_5
H' : Type u_6
inst✝² : NormedAddCommGroup E'
inst✝¹ : NormedSpace 𝕜 E'
inst✝ : TopologicalSpace H'
⊢ ∀ e ∈ idRestrGroupoid, e ∈ contDiffGroupoid n I

Next tactic:
rintro e ⟨s, hs, hes⟩
/-- The `C^n` groupoid is closed under restriction. -/
instance : ClosedUnderRestriction (contDiffGroupoid n I) :=
  (closedUnderRestriction_iff_id_le _).mpr
    (by
      apply StructureGroupoid.le_iff.mpr
      rintro e ⟨s, hs, hes⟩
      

Proof state:
case intro.intro
m n : ℕ∞
𝕜 : Type u_1
inst✝⁷ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝⁶ : NormedAddCommGroup E
inst✝⁵ : NormedSpace 𝕜 E
H : Type u_3
inst✝⁴ : TopologicalSpace H
I : ModelWithCorners 𝕜 E H
M : Type u_4
inst✝³ : TopologicalSpace M
E' : Type u_5
H' : Type u_6
inst✝² : NormedAddCommGroup E'
inst✝¹ : NormedSpace 𝕜 E'
inst✝ : TopologicalSpace H'
e : PartialHomeomorph H H
s : Set H
hs : IsOpen s
hes : e ≈ PartialHomeomorph.ofSet s hs
⊢ e ∈ contDiffGroupoid n I

Next tactic:
apply (contDiffGroupoid n I).eq_on_source' _ _ _ hes
/-- The `C^n` groupoid is closed under restriction. -/
instance : ClosedUnderRestriction (contDiffGroupoid n I) :=
  (closedUnderRestriction_iff_id_le _).mpr
    (by
      apply StructureGroupoid.le_iff.mpr
      rintro e ⟨s, hs, hes⟩
      apply (contDiffGroupoid n I).eq_on_source' _ _ _ hes
      

Proof state:
m n : ℕ∞
𝕜 : Type u_1
inst✝⁷ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝⁶ : NormedAddCommGroup E
inst✝⁵ : NormedSpace 𝕜 E
H : Type u_3
inst✝⁴ : TopologicalSpace H
I : ModelWithCorners 𝕜 E H
M : Type u_4
inst✝³ : TopologicalSpace M
E' : Type u_5
H' : Type u_6
inst✝² : NormedAddCommGroup E'
inst✝¹ : NormedSpace 𝕜 E'
inst✝ : TopologicalSpace H'
e : PartialHomeomorph H H
s : Set H
hs : IsOpen s
hes : e ≈ PartialHomeomorph.ofSet s hs
⊢ PartialHomeomorph.ofSet s hs ∈ (contDiffGroupoid n I).members

Next tactic:
exact ofSet_mem_contDiffGroupoid n I hs