l3lab/ntp-mathlib huggingface dataset:
/-- A lemma commonly useful when `e` and `e'` are charts of a manifold. -/
theorem mem_symm_trans_source {e' : PartialEquiv α γ} {x : α} (he : x ∈ e.source)
    (he' : x ∈ e'.source) : e x ∈ (e.symm.trans e').source :=
  ⟨e.mapsTo he, by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e : PartialEquiv α β
e'✝ : PartialEquiv β γ
e' : PartialEquiv α γ
x : α
he : x ∈ e.source
he' : x ∈ e'.source
⊢ ↑e x ∈ ↑(PartialEquiv.symm (PartialEquiv.symm (PartialEquiv.symm e))) ⁻¹' e'.source

Next tactic:
rwa [mem_preimage, PartialEquiv.symm_symm, e.left_inv he]
/-- `EqOnSource` is an equivalence relation. This instance provides the `≈` notation between two
`PartialEquiv`s. -/
instance eqOnSourceSetoid : Setoid (PartialEquiv α β) where
  r := EqOnSource
  iseqv := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e : PartialEquiv α β
e' : PartialEquiv β γ
⊢ Equivalence EqOnSource

Next tactic:
constructor
/-- `EqOnSource` is an equivalence relation. This instance provides the `≈` notation between two
`PartialEquiv`s. -/
instance eqOnSourceSetoid : Setoid (PartialEquiv α β) where
  r := EqOnSource
  iseqv := by constructor <;> 

Proof state:
case refl
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e : PartialEquiv α β
e' : PartialEquiv β γ
⊢ ∀ (x : PartialEquiv α β), EqOnSource x x

Next tactic:
simp only [Equivalence, EqOnSource, EqOn]
/-- `EqOnSource` is an equivalence relation. This instance provides the `≈` notation between two
`PartialEquiv`s. -/
instance eqOnSourceSetoid : Setoid (PartialEquiv α β) where
  r := EqOnSource
  iseqv := by constructor <;> 

Proof state:
case symm
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e : PartialEquiv α β
e' : PartialEquiv β γ
⊢ ∀ {x y : PartialEquiv α β}, EqOnSource x y → EqOnSource y x

Next tactic:
simp only [Equivalence, EqOnSource, EqOn]
/-- `EqOnSource` is an equivalence relation. This instance provides the `≈` notation between two
`PartialEquiv`s. -/
instance eqOnSourceSetoid : Setoid (PartialEquiv α β) where
  r := EqOnSource
  iseqv := by constructor <;> 

Proof state:
case trans
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e : PartialEquiv α β
e' : PartialEquiv β γ
⊢ ∀ {x y z : PartialEquiv α β}, EqOnSource x y → EqOnSource y z → EqOnSource x z

Next tactic:
simp only [Equivalence, EqOnSource, EqOn]
/-- `EqOnSource` is an equivalence relation. This instance provides the `≈` notation between two
`PartialEquiv`s. -/
instance eqOnSourceSetoid : Setoid (PartialEquiv α β) where
  r := EqOnSource
  iseqv := by constructor <;> simp only [Equivalence, EqOnSource, EqOn] <;> 

Proof state:
case refl
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e : PartialEquiv α β
e' : PartialEquiv β γ
⊢ ∀ (x : PartialEquiv α β), True ∧ ∀ ⦃x_1 : α⦄, x_1 ∈ x.source → True

Next tactic:
aesop
/-- `EqOnSource` is an equivalence relation. This instance provides the `≈` notation between two
`PartialEquiv`s. -/
instance eqOnSourceSetoid : Setoid (PartialEquiv α β) where
  r := EqOnSource
  iseqv := by constructor <;> simp only [Equivalence, EqOnSource, EqOn] <;> 

Proof state:
case symm
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e : PartialEquiv α β
e' : PartialEquiv β γ
⊢ ∀ {x y : PartialEquiv α β},
    (x.source = y.source ∧ ∀ ⦃x_1 : α⦄, x_1 ∈ x.source → ↑x x_1 = ↑y x_1) →
      y.source = x.source ∧ ∀ ⦃x_1 : α⦄, x_1 ∈ y.source → ↑y x_1 = ↑x x_1

Next tactic:
aesop
/-- `EqOnSource` is an equivalence relation. This instance provides the `≈` notation between two
`PartialEquiv`s. -/
instance eqOnSourceSetoid : Setoid (PartialEquiv α β) where
  r := EqOnSource
  iseqv := by constructor <;> simp only [Equivalence, EqOnSource, EqOn] <;> 

Proof state:
case trans
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e : PartialEquiv α β
e' : PartialEquiv β γ
⊢ ∀ {x y z : PartialEquiv α β},
    (x.source = y.source ∧ ∀ ⦃x_1 : α⦄, x_1 ∈ x.source → ↑x x_1 = ↑y x_1) →
      (y.source = z.source ∧ ∀ ⦃x : α⦄, x ∈ y.source → ↑y x = ↑z x) →
        x.source = z.source ∧ ∀ ⦃x_1 : α⦄, x_1 ∈ x.source → ↑x x_1 = ↑z x_1

Next tactic:
aesop
/-- Two equivalent partial equivs have the same target. -/
theorem EqOnSource.target_eq {e e' : PartialEquiv α β} (h : e ≈ e') : e.target = e'.target := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e✝ : PartialEquiv α β
e'✝ : PartialEquiv β γ
e e' : PartialEquiv α β
h : e ≈ e'
⊢ e.target = e'.target

Next tactic:
simp only [← image_source_eq_target, ← source_eq h, h.2.image_eq]
/-- If two partial equivs are equivalent, so are their inverses. -/
theorem EqOnSource.symm' {e e' : PartialEquiv α β} (h : e ≈ e') : e.symm ≈ e'.symm := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e✝ : PartialEquiv α β
e'✝ : PartialEquiv β γ
e e' : PartialEquiv α β
h : e ≈ e'
⊢ PartialEquiv.symm e ≈ PartialEquiv.symm e'

Next tactic:
refine' ⟨target_eq h, eqOn_of_leftInvOn_of_rightInvOn e.leftInvOn _ _⟩
/-- If two partial equivs are equivalent, so are their inverses. -/
theorem EqOnSource.symm' {e e' : PartialEquiv α β} (h : e ≈ e') : e.symm ≈ e'.symm := by
  refine' ⟨target_eq h, eqOn_of_leftInvOn_of_rightInvOn e.leftInvOn _ _⟩ <;>
    

Proof state:
case refine'_1
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e✝ : PartialEquiv α β
e'✝ : PartialEquiv β γ
e e' : PartialEquiv α β
h : e ≈ e'
⊢ RightInvOn (↑(PartialEquiv.symm e')) (↑e) (PartialEquiv.symm e).source

Next tactic:
simp only [symm_source, target_eq h, source_eq h, e'.symm_mapsTo]
/-- If two partial equivs are equivalent, so are their inverses. -/
theorem EqOnSource.symm' {e e' : PartialEquiv α β} (h : e ≈ e') : e.symm ≈ e'.symm := by
  refine' ⟨target_eq h, eqOn_of_leftInvOn_of_rightInvOn e.leftInvOn _ _⟩ <;>
    

Proof state:
case refine'_2
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e✝ : PartialEquiv α β
e'✝ : PartialEquiv β γ
e e' : PartialEquiv α β
h : e ≈ e'
⊢ MapsTo (↑(PartialEquiv.symm e')) (PartialEquiv.symm e).source e.source

Next tactic:
simp only [symm_source, target_eq h, source_eq h, e'.symm_mapsTo]
/-- If two partial equivs are equivalent, so are their inverses. -/
theorem EqOnSource.symm' {e e' : PartialEquiv α β} (h : e ≈ e') : e.symm ≈ e'.symm := by
  refine' ⟨target_eq h, eqOn_of_leftInvOn_of_rightInvOn e.leftInvOn _ _⟩ <;>
    simp only [symm_source, target_eq h, source_eq h, e'.symm_mapsTo]
  

Proof state:
case refine'_1
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e✝ : PartialEquiv α β
e'✝ : PartialEquiv β γ
e e' : PartialEquiv α β
h : e ≈ e'
⊢ RightInvOn (↑(PartialEquiv.symm e')) (↑e) e'.target

Next tactic:
exact e'.rightInvOn.congr_right e'.symm_mapsTo (source_eq h ▸ h.eqOn.symm)
/-- Composition of partial equivs respects equivalence. -/
theorem EqOnSource.trans' {e e' : PartialEquiv α β} {f f' : PartialEquiv β γ} (he : e ≈ e')
    (hf : f ≈ f') : e.trans f ≈ e'.trans f' := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e✝ : PartialEquiv α β
e'✝ : PartialEquiv β γ
e e' : PartialEquiv α β
f f' : PartialEquiv β γ
he : e ≈ e'
hf : f ≈ f'
⊢ PartialEquiv.trans e f ≈ PartialEquiv.trans e' f'

Next tactic:
constructor
/-- Composition of partial equivs respects equivalence. -/
theorem EqOnSource.trans' {e e' : PartialEquiv α β} {f f' : PartialEquiv β γ} (he : e ≈ e')
    (hf : f ≈ f') : e.trans f ≈ e'.trans f' := by
  constructor
  · 

Proof state:
case left
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e✝ : PartialEquiv α β
e'✝ : PartialEquiv β γ
e e' : PartialEquiv α β
f f' : PartialEquiv β γ
he : e ≈ e'
hf : f ≈ f'
⊢ (PartialEquiv.trans e f).source = (PartialEquiv.trans e' f').source

Next tactic:
rw [trans_source'', trans_source'', ← target_eq he, ← hf.1]
/-- Composition of partial equivs respects equivalence. -/
theorem EqOnSource.trans' {e e' : PartialEquiv α β} {f f' : PartialEquiv β γ} (he : e ≈ e')
    (hf : f ≈ f') : e.trans f ≈ e'.trans f' := by
  constructor
  · rw [trans_source'', trans_source'', ← target_eq he, ← hf.1]
    

Proof state:
case left
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e✝ : PartialEquiv α β
e'✝ : PartialEquiv β γ
e e' : PartialEquiv α β
f f' : PartialEquiv β γ
he : e ≈ e'
hf : f ≈ f'
⊢ ↑(PartialEquiv.symm e) '' (e.target ∩ f.source) = ↑(PartialEquiv.symm e') '' (e.target ∩ f.source)

Next tactic:
exact (he.symm'.eqOn.mono <| inter_subset_left _ _).image_eq
/-- Composition of partial equivs respects equivalence. -/
theorem EqOnSource.trans' {e e' : PartialEquiv α β} {f f' : PartialEquiv β γ} (he : e ≈ e')
    (hf : f ≈ f') : e.trans f ≈ e'.trans f' := by
  constructor
  · rw [trans_source'', trans_source'', ← target_eq he, ← hf.1]
    exact (he.symm'.eqOn.mono <| inter_subset_left _ _).image_eq
  · 

Proof state:
case right
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e✝ : PartialEquiv α β
e'✝ : PartialEquiv β γ
e e' : PartialEquiv α β
f f' : PartialEquiv β γ
he : e ≈ e'
hf : f ≈ f'
⊢ EqOn (↑(PartialEquiv.trans e f)) (↑(PartialEquiv.trans e' f')) (PartialEquiv.trans e f).source

Next tactic:
intro x hx
/-- Composition of partial equivs respects equivalence. -/
theorem EqOnSource.trans' {e e' : PartialEquiv α β} {f f' : PartialEquiv β γ} (he : e ≈ e')
    (hf : f ≈ f') : e.trans f ≈ e'.trans f' := by
  constructor
  · rw [trans_source'', trans_source'', ← target_eq he, ← hf.1]
    exact (he.symm'.eqOn.mono <| inter_subset_left _ _).image_eq
  · intro x hx
    

Proof state:
case right
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e✝ : PartialEquiv α β
e'✝ : PartialEquiv β γ
e e' : PartialEquiv α β
f f' : PartialEquiv β γ
he : e ≈ e'
hf : f ≈ f'
x : α
hx : x ∈ (PartialEquiv.trans e f).source
⊢ ↑(PartialEquiv.trans e f) x = ↑(PartialEquiv.trans e' f') x

Next tactic:
rw [trans_source] at hx
/-- Composition of partial equivs respects equivalence. -/
theorem EqOnSource.trans' {e e' : PartialEquiv α β} {f f' : PartialEquiv β γ} (he : e ≈ e')
    (hf : f ≈ f') : e.trans f ≈ e'.trans f' := by
  constructor
  · rw [trans_source'', trans_source'', ← target_eq he, ← hf.1]
    exact (he.symm'.eqOn.mono <| inter_subset_left _ _).image_eq
  · intro x hx
    rw [trans_source] at hx
    

Proof state:
case right
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e✝ : PartialEquiv α β
e'✝ : PartialEquiv β γ
e e' : PartialEquiv α β
f f' : PartialEquiv β γ
he : e ≈ e'
hf : f ≈ f'
x : α
hx : x ∈ e.source ∩ ↑e ⁻¹' f.source
⊢ ↑(PartialEquiv.trans e f) x = ↑(PartialEquiv.trans e' f') x

Next tactic:
simp [Function.comp_apply, PartialEquiv.coe_trans, (he.2 hx.1).symm, hf.2 hx.2]
/-- Restriction of partial equivs respects equivalence. -/
theorem EqOnSource.restr {e e' : PartialEquiv α β} (he : e ≈ e') (s : Set α) :
    e.restr s ≈ e'.restr s := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e✝ : PartialEquiv α β
e'✝ : PartialEquiv β γ
e e' : PartialEquiv α β
he : e ≈ e'
s : Set α
⊢ PartialEquiv.restr e s ≈ PartialEquiv.restr e' s

Next tactic:
constructor
/-- Restriction of partial equivs respects equivalence. -/
theorem EqOnSource.restr {e e' : PartialEquiv α β} (he : e ≈ e') (s : Set α) :
    e.restr s ≈ e'.restr s := by
  constructor
  · 

Proof state:
case left
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e✝ : PartialEquiv α β
e'✝ : PartialEquiv β γ
e e' : PartialEquiv α β
he : e ≈ e'
s : Set α
⊢ (PartialEquiv.restr e s).source = (PartialEquiv.restr e' s).source

Next tactic:
simp [he.1]
/-- Restriction of partial equivs respects equivalence. -/
theorem EqOnSource.restr {e e' : PartialEquiv α β} (he : e ≈ e') (s : Set α) :
    e.restr s ≈ e'.restr s := by
  constructor
  · simp [he.1]
  · 

Proof state:
case right
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e✝ : PartialEquiv α β
e'✝ : PartialEquiv β γ
e e' : PartialEquiv α β
he : e ≈ e'
s : Set α
⊢ EqOn (↑(PartialEquiv.restr e s)) (↑(PartialEquiv.restr e' s)) (PartialEquiv.restr e s).source

Next tactic:
intro x hx
/-- Restriction of partial equivs respects equivalence. -/
theorem EqOnSource.restr {e e' : PartialEquiv α β} (he : e ≈ e') (s : Set α) :
    e.restr s ≈ e'.restr s := by
  constructor
  · simp [he.1]
  · intro x hx
    

Proof state:
case right
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e✝ : PartialEquiv α β
e'✝ : PartialEquiv β γ
e e' : PartialEquiv α β
he : e ≈ e'
s : Set α
x : α
hx : x ∈ (PartialEquiv.restr e s).source
⊢ ↑(PartialEquiv.restr e s) x = ↑(PartialEquiv.restr e' s) x

Next tactic:
simp only [mem_inter_iff, restr_source] at hx
/-- Restriction of partial equivs respects equivalence. -/
theorem EqOnSource.restr {e e' : PartialEquiv α β} (he : e ≈ e') (s : Set α) :
    e.restr s ≈ e'.restr s := by
  constructor
  · simp [he.1]
  · intro x hx
    simp only [mem_inter_iff, restr_source] at hx
    

Proof state:
case right
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e✝ : PartialEquiv α β
e'✝ : PartialEquiv β γ
e e' : PartialEquiv α β
he : e ≈ e'
s : Set α
x : α
hx : x ∈ e.source ∧ x ∈ s
⊢ ↑(PartialEquiv.restr e s) x = ↑(PartialEquiv.restr e' s) x

Next tactic:
exact he.2 hx.1
/-- Preimages are respected by equivalence. -/
theorem EqOnSource.source_inter_preimage_eq {e e' : PartialEquiv α β} (he : e ≈ e') (s : Set β) :
    e.source ∩ e ⁻¹' s = e'.source ∩ e' ⁻¹' s := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e✝ : PartialEquiv α β
e'✝ : PartialEquiv β γ
e e' : PartialEquiv α β
he : e ≈ e'
s : Set β
⊢ e.source ∩ ↑e ⁻¹' s = e'.source ∩ ↑e' ⁻¹' s

Next tactic:
rw [he.eqOn.inter_preimage_eq, source_eq he]
/-- Composition of a partial equivlance and its inverse is equivalent to
the restriction of the identity to the source. -/
theorem trans_self_symm : e.trans e.symm ≈ ofSet e.source := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e : PartialEquiv α β
e' : PartialEquiv β γ
⊢ PartialEquiv.trans e (PartialEquiv.symm e) ≈ ofSet e.source

Next tactic:
have A : (e.trans e.symm).source = e.source := by mfld_set_tac
/-- Composition of a partial equivlance and its inverse is equivalent to
the restriction of the identity to the source. -/
theorem trans_self_symm : e.trans e.symm ≈ ofSet e.source := by
  have A : (e.trans e.symm).source = e.source := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e : PartialEquiv α β
e' : PartialEquiv β γ
⊢ (PartialEquiv.trans e (PartialEquiv.symm e)).source = e.source

Next tactic:
mfld_set_tac
/-- Composition of a partial equivlance and its inverse is equivalent to
the restriction of the identity to the source. -/
theorem trans_self_symm : e.trans e.symm ≈ ofSet e.source := by
  have A : (e.trans e.symm).source = e.source := by mfld_set_tac
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e : PartialEquiv α β
e' : PartialEquiv β γ
A : (PartialEquiv.trans e (PartialEquiv.symm e)).source = e.source
⊢ PartialEquiv.trans e (PartialEquiv.symm e) ≈ ofSet e.source

Next tactic:
refine' ⟨by rw [A, ofSet_source], fun x hx => _⟩
/-- Composition of a partial equivlance and its inverse is equivalent to
the restriction of the identity to the source. -/
theorem trans_self_symm : e.trans e.symm ≈ ofSet e.source := by
  have A : (e.trans e.symm).source = e.source := by mfld_set_tac
  refine' ⟨by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e : PartialEquiv α β
e' : PartialEquiv β γ
A : (PartialEquiv.trans e (PartialEquiv.symm e)).source = e.source
⊢ (PartialEquiv.trans e (PartialEquiv.symm e)).source = (ofSet e.source).source

Next tactic:
rw [A, ofSet_source]
/-- Composition of a partial equivlance and its inverse is equivalent to
the restriction of the identity to the source. -/
theorem trans_self_symm : e.trans e.symm ≈ ofSet e.source := by
  have A : (e.trans e.symm).source = e.source := by mfld_set_tac
  refine' ⟨by rw [A, ofSet_source], fun x hx => _⟩
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e : PartialEquiv α β
e' : PartialEquiv β γ
A : (PartialEquiv.trans e (PartialEquiv.symm e)).source = e.source
x : α
hx : x ∈ (PartialEquiv.trans e (PartialEquiv.symm e)).source
⊢ ↑(PartialEquiv.trans e (PartialEquiv.symm e)) x = ↑(ofSet e.source) x

Next tactic:
rw [A] at hx
/-- Composition of a partial equivlance and its inverse is equivalent to
the restriction of the identity to the source. -/
theorem trans_self_symm : e.trans e.symm ≈ ofSet e.source := by
  have A : (e.trans e.symm).source = e.source := by mfld_set_tac
  refine' ⟨by rw [A, ofSet_source], fun x hx => _⟩
  rw [A] at hx
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e : PartialEquiv α β
e' : PartialEquiv β γ
A : (PartialEquiv.trans e (PartialEquiv.symm e)).source = e.source
x : α
hx : x ∈ e.source
⊢ ↑(PartialEquiv.trans e (PartialEquiv.symm e)) x = ↑(ofSet e.source) x

Next tactic:
simp only [hx, mfld_simps]
/-- Two equivalent partial equivs are equal when the source and target are `univ`. -/
theorem eq_of_eqOnSource_univ (e e' : PartialEquiv α β) (h : e ≈ e') (s : e.source = univ)
    (t : e.target = univ) : e = e' := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e✝ : PartialEquiv α β
e'✝ : PartialEquiv β γ
e e' : PartialEquiv α β
h : e ≈ e'
s : e.source = univ
t : e.target = univ
⊢ e = e'

Next tactic:
refine PartialEquiv.ext (fun x => ?_) (fun x => ?_) h.1
/-- Two equivalent partial equivs are equal when the source and target are `univ`. -/
theorem eq_of_eqOnSource_univ (e e' : PartialEquiv α β) (h : e ≈ e') (s : e.source = univ)
    (t : e.target = univ) : e = e' := by
  refine PartialEquiv.ext (fun x => ?_) (fun x => ?_) h.1
  · 

Proof state:
case refine_1
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e✝ : PartialEquiv α β
e'✝ : PartialEquiv β γ
e e' : PartialEquiv α β
h : e ≈ e'
s : e.source = univ
t : e.target = univ
x : α
⊢ ↑e x = ↑e' x

Next tactic:
apply h.2
/-- Two equivalent partial equivs are equal when the source and target are `univ`. -/
theorem eq_of_eqOnSource_univ (e e' : PartialEquiv α β) (h : e ≈ e') (s : e.source = univ)
    (t : e.target = univ) : e = e' := by
  refine PartialEquiv.ext (fun x => ?_) (fun x => ?_) h.1
  · apply h.2
    

Proof state:
case refine_1.a
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e✝ : PartialEquiv α β
e'✝ : PartialEquiv β γ
e e' : PartialEquiv α β
h : e ≈ e'
s : e.source = univ
t : e.target = univ
x : α
⊢ x ∈ e.source

Next tactic:
rw [s]
/-- Two equivalent partial equivs are equal when the source and target are `univ`. -/
theorem eq_of_eqOnSource_univ (e e' : PartialEquiv α β) (h : e ≈ e') (s : e.source = univ)
    (t : e.target = univ) : e = e' := by
  refine PartialEquiv.ext (fun x => ?_) (fun x => ?_) h.1
  · apply h.2
    rw [s]
    

Proof state:
case refine_1.a
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e✝ : PartialEquiv α β
e'✝ : PartialEquiv β γ
e e' : PartialEquiv α β
h : e ≈ e'
s : e.source = univ
t : e.target = univ
x : α
⊢ x ∈ univ

Next tactic:
exact mem_univ _
/-- Two equivalent partial equivs are equal when the source and target are `univ`. -/
theorem eq_of_eqOnSource_univ (e e' : PartialEquiv α β) (h : e ≈ e') (s : e.source = univ)
    (t : e.target = univ) : e = e' := by
  refine PartialEquiv.ext (fun x => ?_) (fun x => ?_) h.1
  · apply h.2
    rw [s]
    exact mem_univ _
  · 

Proof state:
case refine_2
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e✝ : PartialEquiv α β
e'✝ : PartialEquiv β γ
e e' : PartialEquiv α β
h : e ≈ e'
s : e.source = univ
t : e.target = univ
x : β
⊢ ↑(PartialEquiv.symm e) x = ↑(PartialEquiv.symm e') x

Next tactic:
apply h.symm'.2
/-- Two equivalent partial equivs are equal when the source and target are `univ`. -/
theorem eq_of_eqOnSource_univ (e e' : PartialEquiv α β) (h : e ≈ e') (s : e.source = univ)
    (t : e.target = univ) : e = e' := by
  refine PartialEquiv.ext (fun x => ?_) (fun x => ?_) h.1
  · apply h.2
    rw [s]
    exact mem_univ _
  · apply h.symm'.2
    

Proof state:
case refine_2.a
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e✝ : PartialEquiv α β
e'✝ : PartialEquiv β γ
e e' : PartialEquiv α β
h : e ≈ e'
s : e.source = univ
t : e.target = univ
x : β
⊢ x ∈ (PartialEquiv.symm e).source

Next tactic:
rw [symm_source, t]
/-- Two equivalent partial equivs are equal when the source and target are `univ`. -/
theorem eq_of_eqOnSource_univ (e e' : PartialEquiv α β) (h : e ≈ e') (s : e.source = univ)
    (t : e.target = univ) : e = e' := by
  refine PartialEquiv.ext (fun x => ?_) (fun x => ?_) h.1
  · apply h.2
    rw [s]
    exact mem_univ _
  · apply h.symm'.2
    rw [symm_source, t]
    

Proof state:
case refine_2.a
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e✝ : PartialEquiv α β
e'✝ : PartialEquiv β γ
e e' : PartialEquiv α β
h : e ≈ e'
s : e.source = univ
t : e.target = univ
x : β
⊢ x ∈ univ

Next tactic:
exact mem_univ _
/-- The product of two partial equivalences, as a partial equivalence on the product. -/
def prod (e : PartialEquiv α β) (e' : PartialEquiv γ δ) : PartialEquiv (α × γ) (β × δ) where
  source := e.source ×ˢ e'.source
  target := e.target ×ˢ e'.target
  toFun p := (e p.1, e' p.2)
  invFun p := (e.symm p.1, e'.symm p.2)
  map_source' p hp := by
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e✝ : PartialEquiv α β
e'✝ : PartialEquiv β γ
e : PartialEquiv α β
e' : PartialEquiv γ δ
p : α × γ
hp : p ∈ e.source ×ˢ e'.source
⊢ (fun p => (↑e p.1, ↑e' p.2)) p ∈ e.target ×ˢ e'.target

Next tactic:
simp at hp
/-- The product of two partial equivalences, as a partial equivalence on the product. -/
def prod (e : PartialEquiv α β) (e' : PartialEquiv γ δ) : PartialEquiv (α × γ) (β × δ) where
  source := e.source ×ˢ e'.source
  target := e.target ×ˢ e'.target
  toFun p := (e p.1, e' p.2)
  invFun p := (e.symm p.1, e'.symm p.2)
  map_source' p hp := by
    simp at hp
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e✝ : PartialEquiv α β
e'✝ : PartialEquiv β γ
e : PartialEquiv α β
e' : PartialEquiv γ δ
p : α × γ
hp : p.1 ∈ e.source ∧ p.2 ∈ e'.source
⊢ (fun p => (↑e p.1, ↑e' p.2)) p ∈ e.target ×ˢ e'.target

Next tactic:
simp [hp]
/-- The product of two partial equivalences, as a partial equivalence on the product. -/
def prod (e : PartialEquiv α β) (e' : PartialEquiv γ δ) : PartialEquiv (α × γ) (β × δ) where
  source := e.source ×ˢ e'.source
  target := e.target ×ˢ e'.target
  toFun p := (e p.1, e' p.2)
  invFun p := (e.symm p.1, e'.symm p.2)
  map_source' p hp := by
    simp at hp
    simp [hp]
  map_target' p hp := by
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e✝ : PartialEquiv α β
e'✝ : PartialEquiv β γ
e : PartialEquiv α β
e' : PartialEquiv γ δ
p : β × δ
hp : p ∈ e.target ×ˢ e'.target
⊢ (fun p => (↑(PartialEquiv.symm e) p.1, ↑(PartialEquiv.symm e') p.2)) p ∈ e.source ×ˢ e'.source

Next tactic:
simp at hp
/-- The product of two partial equivalences, as a partial equivalence on the product. -/
def prod (e : PartialEquiv α β) (e' : PartialEquiv γ δ) : PartialEquiv (α × γ) (β × δ) where
  source := e.source ×ˢ e'.source
  target := e.target ×ˢ e'.target
  toFun p := (e p.1, e' p.2)
  invFun p := (e.symm p.1, e'.symm p.2)
  map_source' p hp := by
    simp at hp
    simp [hp]
  map_target' p hp := by
    simp at hp
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e✝ : PartialEquiv α β
e'✝ : PartialEquiv β γ
e : PartialEquiv α β
e' : PartialEquiv γ δ
p : β × δ
hp : p.1 ∈ e.target ∧ p.2 ∈ e'.target
⊢ (fun p => (↑(PartialEquiv.symm e) p.1, ↑(PartialEquiv.symm e') p.2)) p ∈ e.source ×ˢ e'.source

Next tactic:
simp [map_target, hp]
/-- The product of two partial equivalences, as a partial equivalence on the product. -/
def prod (e : PartialEquiv α β) (e' : PartialEquiv γ δ) : PartialEquiv (α × γ) (β × δ) where
  source := e.source ×ˢ e'.source
  target := e.target ×ˢ e'.target
  toFun p := (e p.1, e' p.2)
  invFun p := (e.symm p.1, e'.symm p.2)
  map_source' p hp := by
    simp at hp
    simp [hp]
  map_target' p hp := by
    simp at hp
    simp [map_target, hp]
  left_inv' p hp := by
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
e✝ : PartialEquiv α β
e'✝ : PartialEquiv β γ
e : PartialEquiv α β
e' : PartialEquiv γ δ
p : α × γ
hp : p ∈ e.source ×ˢ e'.source
⊢ (fun p => (↑(PartialEquiv.symm e) p.1, ↑(PartialEquiv.symm e') p.2)) ((fun p => (↑e p.1, ↑e' p.2)) p) = p

Next tactic:
simp at hp