l3lab/ntp-mathlib huggingface dataset:
theorem sumDiffSubset_symm_apply_of_not_mem {α} {s t : Set α} (h : s ⊆ t) [DecidablePred (· ∈ s)]
    {x : t} (hx : x.1 ∉ s) : (Equiv.Set.sumDiffSubset h).symm x = Sum.inr ⟨x, ⟨x.2, hx⟩⟩ := by
  

Proof state:
α✝ : Sort u
β : Sort v
γ : Sort w
α : Type u_1
s t : Set α
h : s ⊆ t
inst✝ : DecidablePred fun x => x ∈ s
x : ↑t
hx : ↑x ∉ s
⊢ (Set.sumDiffSubset h).symm x = Sum.inr { val := ↑x, property := (_ : ↑x ∈ t ∧ ↑x ∉ s) }

Next tactic:
apply (Equiv.Set.sumDiffSubset h).injective
theorem sumDiffSubset_symm_apply_of_not_mem {α} {s t : Set α} (h : s ⊆ t) [DecidablePred (· ∈ s)]
    {x : t} (hx : x.1 ∉ s) : (Equiv.Set.sumDiffSubset h).symm x = Sum.inr ⟨x, ⟨x.2, hx⟩⟩ := by
  apply (Equiv.Set.sumDiffSubset h).injective
  

Proof state:
case a
α✝ : Sort u
β : Sort v
γ : Sort w
α : Type u_1
s t : Set α
h : s ⊆ t
inst✝ : DecidablePred fun x => x ∈ s
x : ↑t
hx : ↑x ∉ s
⊢ (Set.sumDiffSubset h) ((Set.sumDiffSubset h).symm x) =
    (Set.sumDiffSubset h) (Sum.inr { val := ↑x, property := (_ : ↑x ∈ t ∧ ↑x ∉ s) })

Next tactic:
simp only [apply_symm_apply, sumDiffSubset_apply_inr]
theorem sumDiffSubset_symm_apply_of_not_mem {α} {s t : Set α} (h : s ⊆ t) [DecidablePred (· ∈ s)]
    {x : t} (hx : x.1 ∉ s) : (Equiv.Set.sumDiffSubset h).symm x = Sum.inr ⟨x, ⟨x.2, hx⟩⟩ := by
  apply (Equiv.Set.sumDiffSubset h).injective
  simp only [apply_symm_apply, sumDiffSubset_apply_inr]
  

Proof state:
case a
α✝ : Sort u
β : Sort v
γ : Sort w
α : Type u_1
s t : Set α
h : s ⊆ t
inst✝ : DecidablePred fun x => x ∈ s
x : ↑t
hx : ↑x ∉ s
⊢ x = inclusion (_ : t \ s ⊆ t) { val := ↑x, property := (_ : ↑x ∈ t ∧ ↑x ∉ s) }

Next tactic:
exact Subtype.eq rfl
/-- If `s` is a set with decidable membership, then the sum of `s ∪ t` and `s ∩ t` is equivalent
to `s ⊕ t`. -/
protected def unionSumInter {α : Type u} (s t : Set α) [DecidablePred (· ∈ s)] :
    Sum (s ∪ t : Set α) (s ∩ t : Set α) ≃ Sum s t :=
  calc
    Sum (s ∪ t : Set α) (s ∩ t : Set α)
      ≃ Sum (s ∪ t \ s : Set α) (s ∩ t : Set α) := by 

Proof state:
α✝ : Sort u
β : Sort v
γ : Sort w
α : Type u
s t : Set α
inst✝ : DecidablePred fun x => x ∈ s
⊢ ↑(s ∪ t) ⊕ ↑(s ∩ t) ≃ ↑(s ∪ t \ s) ⊕ ↑(s ∩ t)

Next tactic:
rw [union_diff_self]
/-- If `s` is a set with decidable membership, then the sum of `s ∪ t` and `s ∩ t` is equivalent
to `s ⊕ t`. -/
protected def unionSumInter {α : Type u} (s t : Set α) [DecidablePred (· ∈ s)] :
    Sum (s ∪ t : Set α) (s ∩ t : Set α) ≃ Sum s t :=
  calc
    Sum (s ∪ t : Set α) (s ∩ t : Set α)
      ≃ Sum (s ∪ t \ s : Set α) (s ∩ t : Set α) := by rw [union_diff_self]
    _ ≃ Sum (Sum s (t \ s : Set α)) (s ∩ t : Set α) :=
      sumCongr (Set.union <| subset_empty_iff.2 (inter_diff_self _ _)) (Equiv.refl _)
    _ ≃ Sum s (Sum (t \ s : Set α) (s ∩ t : Set α)) := sumAssoc _ _ _
    _ ≃ Sum s (t \ s ∪ s ∩ t : Set α) :=
      sumCongr (Equiv.refl _)
        (by
          

Proof state:
α✝ : Sort u
β : Sort v
γ : Sort w
α : Type u
s t : Set α
inst✝ : DecidablePred fun x => x ∈ s
⊢ ↑(t \ s) ⊕ ↑(s ∩ t) ≃ ↑(t \ s ∪ s ∩ t)

Next tactic:
refine' (Set.union' (· ∉ s) _ _).symm
/-- If `s` is a set with decidable membership, then the sum of `s ∪ t` and `s ∩ t` is equivalent
to `s ⊕ t`. -/
protected def unionSumInter {α : Type u} (s t : Set α) [DecidablePred (· ∈ s)] :
    Sum (s ∪ t : Set α) (s ∩ t : Set α) ≃ Sum s t :=
  calc
    Sum (s ∪ t : Set α) (s ∩ t : Set α)
      ≃ Sum (s ∪ t \ s : Set α) (s ∩ t : Set α) := by rw [union_diff_self]
    _ ≃ Sum (Sum s (t \ s : Set α)) (s ∩ t : Set α) :=
      sumCongr (Set.union <| subset_empty_iff.2 (inter_diff_self _ _)) (Equiv.refl _)
    _ ≃ Sum s (Sum (t \ s : Set α) (s ∩ t : Set α)) := sumAssoc _ _ _
    _ ≃ Sum s (t \ s ∪ s ∩ t : Set α) :=
      sumCongr (Equiv.refl _)
        (by
          refine' (Set.union' (· ∉ s) _ _).symm
          

Proof state:
case refine'_1
α✝ : Sort u
β : Sort v
γ : Sort w
α : Type u
s t : Set α
inst✝ : DecidablePred fun x => x ∈ s
⊢ ∀ x ∈ t \ s, (fun x => x ∉ s) x
case refine'_2
α✝ : Sort u
β : Sort v
γ : Sort w
α : Type u
s t : Set α
inst✝ : DecidablePred fun x => x ∈ s
⊢ ∀ x ∈ s ∩ t, ¬(fun x => x ∉ s) x

Next tactic:
exacts [fun x hx => hx.2, fun x hx => not_not_intro hx.1]
/-- If `s` is a set with decidable membership, then the sum of `s ∪ t` and `s ∩ t` is equivalent
to `s ⊕ t`. -/
protected def unionSumInter {α : Type u} (s t : Set α) [DecidablePred (· ∈ s)] :
    Sum (s ∪ t : Set α) (s ∩ t : Set α) ≃ Sum s t :=
  calc
    Sum (s ∪ t : Set α) (s ∩ t : Set α)
      ≃ Sum (s ∪ t \ s : Set α) (s ∩ t : Set α) := by rw [union_diff_self]
    _ ≃ Sum (Sum s (t \ s : Set α)) (s ∩ t : Set α) :=
      sumCongr (Set.union <| subset_empty_iff.2 (inter_diff_self _ _)) (Equiv.refl _)
    _ ≃ Sum s (Sum (t \ s : Set α) (s ∩ t : Set α)) := sumAssoc _ _ _
    _ ≃ Sum s (t \ s ∪ s ∩ t : Set α) :=
      sumCongr (Equiv.refl _)
        (by
          refine' (Set.union' (· ∉ s) _ _).symm
          exacts [fun x hx => hx.2, fun x hx => not_not_intro hx.1])
    _ ≃ Sum s t := by
      

Proof state:
α✝ : Sort u
β : Sort v
γ : Sort w
α : Type u
s t : Set α
inst✝ : DecidablePred fun x => x ∈ s
⊢ ↑s ⊕ ↑(t \ s ∪ s ∩ t) ≃ ↑s ⊕ ↑t

Next tactic:
{ rw [(_ : t \ s ∪ s ∩ t = t)]
        rw [union_comm, inter_comm, inter_union_diff] }
/-- If `s` is a set with decidable membership, then the sum of `s ∪ t` and `s ∩ t` is equivalent
to `s ⊕ t`. -/
protected def unionSumInter {α : Type u} (s t : Set α) [DecidablePred (· ∈ s)] :
    Sum (s ∪ t : Set α) (s ∩ t : Set α) ≃ Sum s t :=
  calc
    Sum (s ∪ t : Set α) (s ∩ t : Set α)
      ≃ Sum (s ∪ t \ s : Set α) (s ∩ t : Set α) := by rw [union_diff_self]
    _ ≃ Sum (Sum s (t \ s : Set α)) (s ∩ t : Set α) :=
      sumCongr (Set.union <| subset_empty_iff.2 (inter_diff_self _ _)) (Equiv.refl _)
    _ ≃ Sum s (Sum (t \ s : Set α) (s ∩ t : Set α)) := sumAssoc _ _ _
    _ ≃ Sum s (t \ s ∪ s ∩ t : Set α) :=
      sumCongr (Equiv.refl _)
        (by
          refine' (Set.union' (· ∉ s) _ _).symm
          exacts [fun x hx => hx.2, fun x hx => not_not_intro hx.1])
    _ ≃ Sum s t := by
      { 

Proof state:
α✝ : Sort u
β : Sort v
γ : Sort w
α : Type u
s t : Set α
inst✝ : DecidablePred fun x => x ∈ s
⊢ ↑s ⊕ ↑(t \ s ∪ s ∩ t) ≃ ↑s ⊕ ↑t

Next tactic:
rw [(_ : t \ s ∪ s ∩ t = t)]
/-- If `s` is a set with decidable membership, then the sum of `s ∪ t` and `s ∩ t` is equivalent
to `s ⊕ t`. -/
protected def unionSumInter {α : Type u} (s t : Set α) [DecidablePred (· ∈ s)] :
    Sum (s ∪ t : Set α) (s ∩ t : Set α) ≃ Sum s t :=
  calc
    Sum (s ∪ t : Set α) (s ∩ t : Set α)
      ≃ Sum (s ∪ t \ s : Set α) (s ∩ t : Set α) := by rw [union_diff_self]
    _ ≃ Sum (Sum s (t \ s : Set α)) (s ∩ t : Set α) :=
      sumCongr (Set.union <| subset_empty_iff.2 (inter_diff_self _ _)) (Equiv.refl _)
    _ ≃ Sum s (Sum (t \ s : Set α) (s ∩ t : Set α)) := sumAssoc _ _ _
    _ ≃ Sum s (t \ s ∪ s ∩ t : Set α) :=
      sumCongr (Equiv.refl _)
        (by
          refine' (Set.union' (· ∉ s) _ _).symm
          exacts [fun x hx => hx.2, fun x hx => not_not_intro hx.1])
    _ ≃ Sum s t := by
      { rw [(_ : t \ s ∪ s ∩ t = t)]
        

Proof state:
α✝ : Sort u
β : Sort v
γ : Sort w
α : Type u
s t : Set α
inst✝ : DecidablePred fun x => x ∈ s
⊢ t \ s ∪ s ∩ t = t

Next tactic:
rw [union_comm, inter_comm, inter_union_diff]
/-- Given an equivalence `e₀` between sets `s : Set α` and `t : Set β`, the set of equivalences
`e : α ≃ β` such that `e ↑x = ↑(e₀ x)` for each `x : s` is equivalent to the set of equivalences
between `sᶜ` and `tᶜ`. -/
protected def compl {α : Type u} {β : Type v} {s : Set α} {t : Set β} [DecidablePred (· ∈ s)]
    [DecidablePred (· ∈ t)] (e₀ : s ≃ t) :
    { e : α ≃ β // ∀ x : s, e x = e₀ x } ≃ ((sᶜ : Set α) ≃ (tᶜ : Set β)) where
  toFun e :=
    subtypeEquiv e fun a =>
      not_congr <|
        Iff.symm <|
          MapsTo.mem_iff (mapsTo_iff_exists_map_subtype.2 ⟨e₀, e.2⟩)
            (SurjOn.mapsTo_compl
              (surjOn_iff_exists_map_subtype.2 ⟨t, e₀, Subset.refl t, e₀.surjective, e.2⟩)
              e.1.injective)
  invFun e₁ :=
    Subtype.mk
      (calc
        α ≃ Sum s (sᶜ : Set α) := (Set.sumCompl s).symm
        _ ≃ Sum t (tᶜ : Set β) := e₀.sumCongr e₁
        _ ≃ β := Set.sumCompl t
        )
      fun x => by
      

Proof state:
α✝ : Sort u
β✝ : Sort v
γ : Sort w
α : Type u
β : Type v
s : Set α
t : Set β
inst✝¹ : DecidablePred fun x => x ∈ s
inst✝ : DecidablePred fun x => x ∈ t
e₀ : ↑s ≃ ↑t
e₁ : ↑sᶜ ≃ ↑tᶜ
x : ↑s
⊢ (Trans.trans (Trans.trans (Set.sumCompl s).symm (sumCongr e₀ e₁)) (Set.sumCompl t)) ↑x = ↑(e₀ x)

Next tactic:
simp only [Sum.map_inl, trans_apply, sumCongr_apply, Set.sumCompl_apply_inl,
        Set.sumCompl_symm_apply, Trans.trans]
/-- Given an equivalence `e₀` between sets `s : Set α` and `t : Set β`, the set of equivalences
`e : α ≃ β` such that `e ↑x = ↑(e₀ x)` for each `x : s` is equivalent to the set of equivalences
between `sᶜ` and `tᶜ`. -/
protected def compl {α : Type u} {β : Type v} {s : Set α} {t : Set β} [DecidablePred (· ∈ s)]
    [DecidablePred (· ∈ t)] (e₀ : s ≃ t) :
    { e : α ≃ β // ∀ x : s, e x = e₀ x } ≃ ((sᶜ : Set α) ≃ (tᶜ : Set β)) where
  toFun e :=
    subtypeEquiv e fun a =>
      not_congr <|
        Iff.symm <|
          MapsTo.mem_iff (mapsTo_iff_exists_map_subtype.2 ⟨e₀, e.2⟩)
            (SurjOn.mapsTo_compl
              (surjOn_iff_exists_map_subtype.2 ⟨t, e₀, Subset.refl t, e₀.surjective, e.2⟩)
              e.1.injective)
  invFun e₁ :=
    Subtype.mk
      (calc
        α ≃ Sum s (sᶜ : Set α) := (Set.sumCompl s).symm
        _ ≃ Sum t (tᶜ : Set β) := e₀.sumCongr e₁
        _ ≃ β := Set.sumCompl t
        )
      fun x => by
      simp only [Sum.map_inl, trans_apply, sumCongr_apply, Set.sumCompl_apply_inl,
        Set.sumCompl_symm_apply, Trans.trans]
  left_inv e := by
    

Proof state:
α✝ : Sort u
β✝ : Sort v
γ : Sort w
α : Type u
β : Type v
s : Set α
t : Set β
inst✝¹ : DecidablePred fun x => x ∈ s
inst✝ : DecidablePred fun x => x ∈ t
e₀ : ↑s ≃ ↑t
e : { e // ∀ (x : ↑s), e ↑x = ↑(e₀ x) }
⊢ (fun e₁ =>
        { val := Trans.trans (Trans.trans (Set.sumCompl s).symm (sumCongr e₀ e₁)) (Set.sumCompl t),
          property := (_ : ∀ (x : ↑s), (Set.sumCompl t) ((sumCongr e₀ e₁) ((Set.sumCompl s).symm ↑x)) = ↑(e₀ x)) })
      ((fun e => subtypeEquiv ↑e (_ : ∀ (a : α), a ∉ s ↔ ↑e a ∉ t)) e) =
    e

Next tactic:
ext x
/-- Given an equivalence `e₀` between sets `s : Set α` and `t : Set β`, the set of equivalences
`e : α ≃ β` such that `e ↑x = ↑(e₀ x)` for each `x : s` is equivalent to the set of equivalences
between `sᶜ` and `tᶜ`. -/
protected def compl {α : Type u} {β : Type v} {s : Set α} {t : Set β} [DecidablePred (· ∈ s)]
    [DecidablePred (· ∈ t)] (e₀ : s ≃ t) :
    { e : α ≃ β // ∀ x : s, e x = e₀ x } ≃ ((sᶜ : Set α) ≃ (tᶜ : Set β)) where
  toFun e :=
    subtypeEquiv e fun a =>
      not_congr <|
        Iff.symm <|
          MapsTo.mem_iff (mapsTo_iff_exists_map_subtype.2 ⟨e₀, e.2⟩)
            (SurjOn.mapsTo_compl
              (surjOn_iff_exists_map_subtype.2 ⟨t, e₀, Subset.refl t, e₀.surjective, e.2⟩)
              e.1.injective)
  invFun e₁ :=
    Subtype.mk
      (calc
        α ≃ Sum s (sᶜ : Set α) := (Set.sumCompl s).symm
        _ ≃ Sum t (tᶜ : Set β) := e₀.sumCongr e₁
        _ ≃ β := Set.sumCompl t
        )
      fun x => by
      simp only [Sum.map_inl, trans_apply, sumCongr_apply, Set.sumCompl_apply_inl,
        Set.sumCompl_symm_apply, Trans.trans]
  left_inv e := by
    ext x
    

Proof state:
case a.H
α✝ : Sort u
β✝ : Sort v
γ : Sort w
α : Type u
β : Type v
s : Set α
t : Set β
inst✝¹ : DecidablePred fun x => x ∈ s
inst✝ : DecidablePred fun x => x ∈ t
e₀ : ↑s ≃ ↑t
e : { e // ∀ (x : ↑s), e ↑x = ↑(e₀ x) }
x : α
⊢ ↑((fun e₁ =>
            { val := Trans.trans (Trans.trans (Set.sumCompl s).symm (sumCongr e₀ e₁)) (Set.sumCompl t),
              property := (_ : ∀ (x : ↑s), (Set.sumCompl t) ((sumCongr e₀ e₁) ((Set.sumCompl s).symm ↑x)) = ↑(e₀ x)) })
          ((fun e => subtypeEquiv ↑e (_ : ∀ (a : α), a ∉ s ↔ ↑e a ∉ t)) e))
      x =
    ↑e x

Next tactic:
by_cases hx : x ∈ s
/-- Given an equivalence `e₀` between sets `s : Set α` and `t : Set β`, the set of equivalences
`e : α ≃ β` such that `e ↑x = ↑(e₀ x)` for each `x : s` is equivalent to the set of equivalences
between `sᶜ` and `tᶜ`. -/
protected def compl {α : Type u} {β : Type v} {s : Set α} {t : Set β} [DecidablePred (· ∈ s)]
    [DecidablePred (· ∈ t)] (e₀ : s ≃ t) :
    { e : α ≃ β // ∀ x : s, e x = e₀ x } ≃ ((sᶜ : Set α) ≃ (tᶜ : Set β)) where
  toFun e :=
    subtypeEquiv e fun a =>
      not_congr <|
        Iff.symm <|
          MapsTo.mem_iff (mapsTo_iff_exists_map_subtype.2 ⟨e₀, e.2⟩)
            (SurjOn.mapsTo_compl
              (surjOn_iff_exists_map_subtype.2 ⟨t, e₀, Subset.refl t, e₀.surjective, e.2⟩)
              e.1.injective)
  invFun e₁ :=
    Subtype.mk
      (calc
        α ≃ Sum s (sᶜ : Set α) := (Set.sumCompl s).symm
        _ ≃ Sum t (tᶜ : Set β) := e₀.sumCongr e₁
        _ ≃ β := Set.sumCompl t
        )
      fun x => by
      simp only [Sum.map_inl, trans_apply, sumCongr_apply, Set.sumCompl_apply_inl,
        Set.sumCompl_symm_apply, Trans.trans]
  left_inv e := by
    ext x
    by_cases hx : x ∈ s
    · 

Proof state:
case pos
α✝ : Sort u
β✝ : Sort v
γ : Sort w
α : Type u
β : Type v
s : Set α
t : Set β
inst✝¹ : DecidablePred fun x => x ∈ s
inst✝ : DecidablePred fun x => x ∈ t
e₀ : ↑s ≃ ↑t
e : { e // ∀ (x : ↑s), e ↑x = ↑(e₀ x) }
x : α
hx : x ∈ s
⊢ ↑((fun e₁ =>
            { val := Trans.trans (Trans.trans (Set.sumCompl s).symm (sumCongr e₀ e₁)) (Set.sumCompl t),
              property := (_ : ∀ (x : ↑s), (Set.sumCompl t) ((sumCongr e₀ e₁) ((Set.sumCompl s).symm ↑x)) = ↑(e₀ x)) })
          ((fun e => subtypeEquiv ↑e (_ : ∀ (a : α), a ∉ s ↔ ↑e a ∉ t)) e))
      x =
    ↑e x

Next tactic:
simp only [Set.sumCompl_symm_apply_of_mem hx, ← e.prop ⟨x, hx⟩, Sum.map_inl, sumCongr_apply,
        trans_apply, Subtype.coe_mk, Set.sumCompl_apply_inl, Trans.trans]
/-- Given an equivalence `e₀` between sets `s : Set α` and `t : Set β`, the set of equivalences
`e : α ≃ β` such that `e ↑x = ↑(e₀ x)` for each `x : s` is equivalent to the set of equivalences
between `sᶜ` and `tᶜ`. -/
protected def compl {α : Type u} {β : Type v} {s : Set α} {t : Set β} [DecidablePred (· ∈ s)]
    [DecidablePred (· ∈ t)] (e₀ : s ≃ t) :
    { e : α ≃ β // ∀ x : s, e x = e₀ x } ≃ ((sᶜ : Set α) ≃ (tᶜ : Set β)) where
  toFun e :=
    subtypeEquiv e fun a =>
      not_congr <|
        Iff.symm <|
          MapsTo.mem_iff (mapsTo_iff_exists_map_subtype.2 ⟨e₀, e.2⟩)
            (SurjOn.mapsTo_compl
              (surjOn_iff_exists_map_subtype.2 ⟨t, e₀, Subset.refl t, e₀.surjective, e.2⟩)
              e.1.injective)
  invFun e₁ :=
    Subtype.mk
      (calc
        α ≃ Sum s (sᶜ : Set α) := (Set.sumCompl s).symm
        _ ≃ Sum t (tᶜ : Set β) := e₀.sumCongr e₁
        _ ≃ β := Set.sumCompl t
        )
      fun x => by
      simp only [Sum.map_inl, trans_apply, sumCongr_apply, Set.sumCompl_apply_inl,
        Set.sumCompl_symm_apply, Trans.trans]
  left_inv e := by
    ext x
    by_cases hx : x ∈ s
    · simp only [Set.sumCompl_symm_apply_of_mem hx, ← e.prop ⟨x, hx⟩, Sum.map_inl, sumCongr_apply,
        trans_apply, Subtype.coe_mk, Set.sumCompl_apply_inl, Trans.trans]
    · 

Proof state:
case neg
α✝ : Sort u
β✝ : Sort v
γ : Sort w
α : Type u
β : Type v
s : Set α
t : Set β
inst✝¹ : DecidablePred fun x => x ∈ s
inst✝ : DecidablePred fun x => x ∈ t
e₀ : ↑s ≃ ↑t
e : { e // ∀ (x : ↑s), e ↑x = ↑(e₀ x) }
x : α
hx : x ∉ s
⊢ ↑((fun e₁ =>
            { val := Trans.trans (Trans.trans (Set.sumCompl s).symm (sumCongr e₀ e₁)) (Set.sumCompl t),
              property := (_ : ∀ (x : ↑s), (Set.sumCompl t) ((sumCongr e₀ e₁) ((Set.sumCompl s).symm ↑x)) = ↑(e₀ x)) })
          ((fun e => subtypeEquiv ↑e (_ : ∀ (a : α), a ∉ s ↔ ↑e a ∉ t)) e))
      x =
    ↑e x

Next tactic:
simp only [Set.sumCompl_symm_apply_of_not_mem hx, Sum.map_inr, subtypeEquiv_apply,
        Set.sumCompl_apply_inr, trans_apply, sumCongr_apply, Subtype.coe_mk, Trans.trans]
/-- Given an equivalence `e₀` between sets `s : Set α` and `t : Set β`, the set of equivalences
`e : α ≃ β` such that `e ↑x = ↑(e₀ x)` for each `x : s` is equivalent to the set of equivalences
between `sᶜ` and `tᶜ`. -/
protected def compl {α : Type u} {β : Type v} {s : Set α} {t : Set β} [DecidablePred (· ∈ s)]
    [DecidablePred (· ∈ t)] (e₀ : s ≃ t) :
    { e : α ≃ β // ∀ x : s, e x = e₀ x } ≃ ((sᶜ : Set α) ≃ (tᶜ : Set β)) where
  toFun e :=
    subtypeEquiv e fun a =>
      not_congr <|
        Iff.symm <|
          MapsTo.mem_iff (mapsTo_iff_exists_map_subtype.2 ⟨e₀, e.2⟩)
            (SurjOn.mapsTo_compl
              (surjOn_iff_exists_map_subtype.2 ⟨t, e₀, Subset.refl t, e₀.surjective, e.2⟩)
              e.1.injective)
  invFun e₁ :=
    Subtype.mk
      (calc
        α ≃ Sum s (sᶜ : Set α) := (Set.sumCompl s).symm
        _ ≃ Sum t (tᶜ : Set β) := e₀.sumCongr e₁
        _ ≃ β := Set.sumCompl t
        )
      fun x => by
      simp only [Sum.map_inl, trans_apply, sumCongr_apply, Set.sumCompl_apply_inl,
        Set.sumCompl_symm_apply, Trans.trans]
  left_inv e := by
    ext x
    by_cases hx : x ∈ s
    · simp only [Set.sumCompl_symm_apply_of_mem hx, ← e.prop ⟨x, hx⟩, Sum.map_inl, sumCongr_apply,
        trans_apply, Subtype.coe_mk, Set.sumCompl_apply_inl, Trans.trans]
    · simp only [Set.sumCompl_symm_apply_of_not_mem hx, Sum.map_inr, subtypeEquiv_apply,
        Set.sumCompl_apply_inr, trans_apply, sumCongr_apply, Subtype.coe_mk, Trans.trans]
  right_inv e :=
    Equiv.ext fun x => by
      

Proof state:
α✝ : Sort u
β✝ : Sort v
γ : Sort w
α : Type u
β : Type v
s : Set α
t : Set β
inst✝¹ : DecidablePred fun x => x ∈ s
inst✝ : DecidablePred fun x => x ∈ t
e₀ : ↑s ≃ ↑t
e : ↑sᶜ ≃ ↑tᶜ
x : { a // a ∈ sᶜ }
⊢ ((fun e => subtypeEquiv ↑e (_ : ∀ (a : α), a ∉ s ↔ ↑e a ∉ t))
        ((fun e₁ =>
            { val := Trans.trans (Trans.trans (Set.sumCompl s).symm (sumCongr e₀ e₁)) (Set.sumCompl t),
              property := (_ : ∀ (x : ↑s), (Set.sumCompl t) ((sumCongr e₀ e₁) ((Set.sumCompl s).symm ↑x)) = ↑(e₀ x)) })
          e))
      x =
    e x

Next tactic:
simp only [Sum.map_inr, subtypeEquiv_apply, Set.sumCompl_apply_inr, Function.comp_apply,
        sumCongr_apply, Equiv.coe_trans, Subtype.coe_eta, Subtype.coe_mk, Trans.trans,
        Set.sumCompl_symm_apply_compl]
/-- The set `Set.pi Set.univ s` is equivalent to `Π a, s a`. -/
@[simps]
protected def univPi {α : Type*} {β : α → Type*} (s : ∀ a, Set (β a)) :
    pi univ s ≃ ∀ a, s a where
  toFun f a := ⟨(f : ∀ a, β a) a, f.2 a (mem_univ a)⟩
  invFun f := ⟨fun a => f a, fun a _ => (f a).2⟩
  left_inv := fun ⟨f, hf⟩ => by
    

Proof state:
α✝ : Sort u
β✝ : Sort v
γ : Sort w
α : Type u_1
β : α → Type u_2
s : (a : α) → Set (β a)
x✝ : ↑(pi univ s)
f : (i : α) → β i
hf : f ∈ pi univ s
⊢ (fun f => { val := fun a => ↑(f a), property := (_ : ∀ a ∈ univ, ↑(f a) ∈ s a) })
      ((fun f a => { val := ↑f a, property := (_ : ↑f a ∈ s a) }) { val := f, property := hf }) =
    { val := f, property := hf }

Next tactic:
ext a
/-- The set `Set.pi Set.univ s` is equivalent to `Π a, s a`. -/
@[simps]
protected def univPi {α : Type*} {β : α → Type*} (s : ∀ a, Set (β a)) :
    pi univ s ≃ ∀ a, s a where
  toFun f a := ⟨(f : ∀ a, β a) a, f.2 a (mem_univ a)⟩
  invFun f := ⟨fun a => f a, fun a _ => (f a).2⟩
  left_inv := fun ⟨f, hf⟩ => by
    ext a
    

Proof state:
case a.h
α✝ : Sort u
β✝ : Sort v
γ : Sort w
α : Type u_1
β : α → Type u_2
s : (a : α) → Set (β a)
x✝ : ↑(pi univ s)
f : (i : α) → β i
hf : f ∈ pi univ s
a : α
⊢ ↑((fun f => { val := fun a => ↑(f a), property := (_ : ∀ a ∈ univ, ↑(f a) ∈ s a) })
          ((fun f a => { val := ↑f a, property := (_ : ↑f a ∈ s a) }) { val := f, property := hf }))
      a =
    ↑{ val := f, property := hf } a

Next tactic:
rfl
/-- The set `Set.pi Set.univ s` is equivalent to `Π a, s a`. -/
@[simps]
protected def univPi {α : Type*} {β : α → Type*} (s : ∀ a, Set (β a)) :
    pi univ s ≃ ∀ a, s a where
  toFun f a := ⟨(f : ∀ a, β a) a, f.2 a (mem_univ a)⟩
  invFun f := ⟨fun a => f a, fun a _ => (f a).2⟩
  left_inv := fun ⟨f, hf⟩ => by
    ext a
    rfl
  right_inv f := by
    

Proof state:
α✝ : Sort u
β✝ : Sort v
γ : Sort w
α : Type u_1
β : α → Type u_2
s : (a : α) → Set (β a)
f : (a : α) → ↑(s a)
⊢ (fun f a => { val := ↑f a, property := (_ : ↑f a ∈ s a) })
      ((fun f => { val := fun a => ↑(f a), property := (_ : ∀ a ∈ univ, ↑(f a) ∈ s a) }) f) =
    f

Next tactic:
ext a
/-- The set `Set.pi Set.univ s` is equivalent to `Π a, s a`. -/
@[simps]
protected def univPi {α : Type*} {β : α → Type*} (s : ∀ a, Set (β a)) :
    pi univ s ≃ ∀ a, s a where
  toFun f a := ⟨(f : ∀ a, β a) a, f.2 a (mem_univ a)⟩
  invFun f := ⟨fun a => f a, fun a _ => (f a).2⟩
  left_inv := fun ⟨f, hf⟩ => by
    ext a
    rfl
  right_inv f := by
    ext a
    

Proof state:
case h.a
α✝ : Sort u
β✝ : Sort v
γ : Sort w
α : Type u_1
β : α → Type u_2
s : (a : α) → Set (β a)
f : (a : α) → ↑(s a)
a : α
⊢ ↑((fun f a => { val := ↑f a, property := (_ : ↑f a ∈ s a) })
        ((fun f => { val := fun a => ↑(f a), property := (_ : ∀ a ∈ univ, ↑(f a) ∈ s a) }) f) a) =
    ↑(f a)

Next tactic:
rfl
theorem image_symm_preimage {α β} {f : α → β} (hf : Injective f) (u s : Set α) :
    (fun x => (Set.image f s hf).symm x : f '' s → α) ⁻¹' u = Subtype.val ⁻¹' (f '' u) := by
  

Proof state:
α✝ : Sort u
β✝ : Sort v
γ : Sort w
α : Type u_1
β : Type u_2
f : α → β
hf : Injective f
u s : Set α
⊢ (fun x => ↑((Set.image f s hf).symm x)) ⁻¹' u = Subtype.val ⁻¹' (f '' u)

Next tactic:
ext ⟨b, a, has, rfl⟩
theorem image_symm_preimage {α β} {f : α → β} (hf : Injective f) (u s : Set α) :
    (fun x => (Set.image f s hf).symm x : f '' s → α) ⁻¹' u = Subtype.val ⁻¹' (f '' u) := by
  ext ⟨b, a, has, rfl⟩
  

Proof state:
case h.mk.intro.intro
α✝ : Sort u
β✝ : Sort v
γ : Sort w
α : Type u_1
β : Type u_2
f : α → β
hf : Injective f
u s : Set α
a : α
has : a ∈ s
⊢ { val := f a, property := (_ : ∃ a_1 ∈ s, f a_1 = f a) } ∈ (fun x => ↑((Set.image f s hf).symm x)) ⁻¹' u ↔
    { val := f a, property := (_ : ∃ a_1 ∈ s, f a_1 = f a) } ∈ Subtype.val ⁻¹' (f '' u)

Next tactic:
simp [hf.eq_iff]
/-- The set `𝒫 S := {x | x ⊆ S}` is equivalent to the type `Set S`. -/
protected def powerset {α} (S : Set α) :
    𝒫 S ≃ Set S where
  toFun := fun x : 𝒫 S => Subtype.val ⁻¹' (x : Set α)
  invFun := fun x : Set S => ⟨Subtype.val '' x, by 

Proof state:
α✝ : Sort u
β : Sort v
γ : Sort w
α : Type ?u.49510
S : Set α
x : Set ↑S
⊢ Subtype.val '' x ∈ 𝒫 S

Next tactic:
rintro _ ⟨a : S, _, rfl⟩
/-- The set `𝒫 S := {x | x ⊆ S}` is equivalent to the type `Set S`. -/
protected def powerset {α} (S : Set α) :
    𝒫 S ≃ Set S where
  toFun := fun x : 𝒫 S => Subtype.val ⁻¹' (x : Set α)
  invFun := fun x : Set S => ⟨Subtype.val '' x, by rintro _ ⟨a : S, _, rfl⟩; 

Proof state:
case intro.intro
α✝ : Sort u
β : Sort v
γ : Sort w
α : Type ?u.49510
S : Set α
x : Set ↑S
a : ↑S
left✝ : a ∈ x
⊢ ↑a ∈ S

Next tactic:
exact a.2
/-- The set `𝒫 S := {x | x ⊆ S}` is equivalent to the type `Set S`. -/
protected def powerset {α} (S : Set α) :
    𝒫 S ≃ Set S where
  toFun := fun x : 𝒫 S => Subtype.val ⁻¹' (x : Set α)
  invFun := fun x : Set S => ⟨Subtype.val '' x, by rintro _ ⟨a : S, _, rfl⟩; exact a.2⟩
  left_inv x := by 

Proof state:
α✝ : Sort u
β : Sort v
γ : Sort w
α : Type ?u.49510
S : Set α
x : ↑(𝒫 S)
⊢ (fun x => { val := Subtype.val '' x, property := (_ : ∀ ⦃a : α⦄, a ∈ Subtype.val '' x → a ∈ S) })
      ((fun x => Subtype.val ⁻¹' ↑x) x) =
    x

Next tactic:
ext y
/-- The set `𝒫 S := {x | x ⊆ S}` is equivalent to the type `Set S`. -/
protected def powerset {α} (S : Set α) :
    𝒫 S ≃ Set S where
  toFun := fun x : 𝒫 S => Subtype.val ⁻¹' (x : Set α)
  invFun := fun x : Set S => ⟨Subtype.val '' x, by rintro _ ⟨a : S, _, rfl⟩; exact a.2⟩
  left_inv x := by ext y;

Proof state:
case a.h
α✝ : Sort u
β : Sort v
γ : Sort w
α : Type ?u.49510
S : Set α
x : ↑(𝒫 S)
y : α
⊢ y ∈
      ↑((fun x => { val := Subtype.val '' x, property := (_ : ∀ ⦃a : α⦄, a ∈ Subtype.val '' x → a ∈ S) })
          ((fun x => Subtype.val ⁻¹' ↑x) x)) ↔
    y ∈ ↑x

Next tactic:
exact ⟨fun ⟨⟨_, _⟩, h, rfl⟩ => h, fun h => ⟨⟨_, x.2 h⟩, h, rfl⟩⟩