l3lab/ntp-mathlib huggingface dataset:
/-- If the domain of a `PEquiv` is `α` except a point, its forward direction is injective. -/
theorem injective_of_forall_ne_isSome (f : α ≃. β) (a₂ : α)
    (h : ∀ a₁ : α, a₁ ≠ a₂ → isSome (f a₁)) : Injective f :=
  HasLeftInverse.injective
    ⟨fun b => Option.recOn b a₂ fun b' => Option.recOn (f.symm b') a₂ id, fun x => by
      classical
        cases hfx : f x
        · have : x = a₂ := not_imp_comm.1 (h x) (hfx.symm ▸ by simp)
          simp [this]
        · dsimp only
          rw [(eq_some_iff f).2 hfx]
          

Proof state:
case some
α : Type u
β : Type v
γ : Type w
δ : Type x
f : α ≃. β
a₂ : α
h : ∀ (a₁ : α), a₁ ≠ a₂ → isSome (f a₁) = true
x : α
val✝ : β
hfx : f x = some val✝
⊢ Option.rec a₂ id (some x) = x

Next tactic:
rfl
/-- Creates a `PEquiv` that is the identity on `s`, and `none` outside of it. -/
def ofSet (s : Set α) [DecidablePred (· ∈ s)] :
    α ≃. α where
  toFun a := if a ∈ s then some a else none
  invFun a := if a ∈ s then some a else none
  inv a b := by
    

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type x
s✝ : Set α
inst✝¹ : DecidablePred fun x => x ∈ s✝
s : Set α
inst✝ : DecidablePred fun x => x ∈ s
a b : α
⊢ a ∈ (fun a => if a ∈ s then some a else none) b ↔ b ∈ (fun a => if a ∈ s then some a else none) a

Next tactic:
dsimp only
/-- Creates a `PEquiv` that is the identity on `s`, and `none` outside of it. -/
def ofSet (s : Set α) [DecidablePred (· ∈ s)] :
    α ≃. α where
  toFun a := if a ∈ s then some a else none
  invFun a := if a ∈ s then some a else none
  inv a b := by
    dsimp only
    

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type x
s✝ : Set α
inst✝¹ : DecidablePred fun x => x ∈ s✝
s : Set α
inst✝ : DecidablePred fun x => x ∈ s
a b : α
⊢ (a ∈ if b ∈ s then some b else none) ↔ b ∈ if a ∈ s then some a else none

Next tactic:
split_ifs with hb ha ha
/-- Creates a `PEquiv` that is the identity on `s`, and `none` outside of it. -/
def ofSet (s : Set α) [DecidablePred (· ∈ s)] :
    α ≃. α where
  toFun a := if a ∈ s then some a else none
  invFun a := if a ∈ s then some a else none
  inv a b := by
    dsimp only
    split_ifs with hb ha ha
    · 

Proof state:
case pos
α : Type u
β : Type v
γ : Type w
δ : Type x
s✝ : Set α
inst✝¹ : DecidablePred fun x => x ∈ s✝
s : Set α
inst✝ : DecidablePred fun x => x ∈ s
a b : α
hb : b ∈ s
ha : a ∈ s
⊢ a ∈ some b ↔ b ∈ some a

Next tactic:
simp [eq_comm]
/-- Creates a `PEquiv` that is the identity on `s`, and `none` outside of it. -/
def ofSet (s : Set α) [DecidablePred (· ∈ s)] :
    α ≃. α where
  toFun a := if a ∈ s then some a else none
  invFun a := if a ∈ s then some a else none
  inv a b := by
    dsimp only
    split_ifs with hb ha ha
    · simp [eq_comm]
    · 

Proof state:
case neg
α : Type u
β : Type v
γ : Type w
δ : Type x
s✝ : Set α
inst✝¹ : DecidablePred fun x => x ∈ s✝
s : Set α
inst✝ : DecidablePred fun x => x ∈ s
a b : α
hb : b ∈ s
ha : a ∉ s
⊢ a ∈ some b ↔ b ∈ none

Next tactic:
simp [ne_of_mem_of_not_mem hb ha]
/-- Creates a `PEquiv` that is the identity on `s`, and `none` outside of it. -/
def ofSet (s : Set α) [DecidablePred (· ∈ s)] :
    α ≃. α where
  toFun a := if a ∈ s then some a else none
  invFun a := if a ∈ s then some a else none
  inv a b := by
    dsimp only
    split_ifs with hb ha ha
    · simp [eq_comm]
    · simp [ne_of_mem_of_not_mem hb ha]
    · 

Proof state:
case pos
α : Type u
β : Type v
γ : Type w
δ : Type x
s✝ : Set α
inst✝¹ : DecidablePred fun x => x ∈ s✝
s : Set α
inst✝ : DecidablePred fun x => x ∈ s
a b : α
hb : b ∉ s
ha : a ∈ s
⊢ a ∈ none ↔ b ∈ some a

Next tactic:
simp [ne_of_mem_of_not_mem ha hb]
/-- Creates a `PEquiv` that is the identity on `s`, and `none` outside of it. -/
def ofSet (s : Set α) [DecidablePred (· ∈ s)] :
    α ≃. α where
  toFun a := if a ∈ s then some a else none
  invFun a := if a ∈ s then some a else none
  inv a b := by
    dsimp only
    split_ifs with hb ha ha
    · simp [eq_comm]
    · simp [ne_of_mem_of_not_mem hb ha]
    · simp [ne_of_mem_of_not_mem ha hb]
    · 

Proof state:
case neg
α : Type u
β : Type v
γ : Type w
δ : Type x
s✝ : Set α
inst✝¹ : DecidablePred fun x => x ∈ s✝
s : Set α
inst✝ : DecidablePred fun x => x ∈ s
a b : α
hb : b ∉ s
ha : a ∉ s
⊢ a ∈ none ↔ b ∈ none

Next tactic:
simp
theorem mem_ofSet_self_iff {s : Set α} [DecidablePred (· ∈ s)] {a : α} : a ∈ ofSet s a ↔ a ∈ s :=
  by 

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type x
s✝ : Set α
inst✝¹ : DecidablePred fun x => x ∈ s✝
s : Set α
inst✝ : DecidablePred fun x => x ∈ s
a : α
⊢ a ∈ (ofSet s) a ↔ a ∈ s

Next tactic:
dsimp [ofSet]
theorem mem_ofSet_self_iff {s : Set α} [DecidablePred (· ∈ s)] {a : α} : a ∈ ofSet s a ↔ a ∈ s :=
  by dsimp [ofSet]; 

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type x
s✝ : Set α
inst✝¹ : DecidablePred fun x => x ∈ s✝
s : Set α
inst✝ : DecidablePred fun x => x ∈ s
a : α
⊢ (a ∈ if a ∈ s then some a else none) ↔ a ∈ s

Next tactic:
split_ifs
theorem mem_ofSet_self_iff {s : Set α} [DecidablePred (· ∈ s)] {a : α} : a ∈ ofSet s a ↔ a ∈ s :=
  by dsimp [ofSet]; split_ifs <;> 

Proof state:
case pos
α : Type u
β : Type v
γ : Type w
δ : Type x
s✝ : Set α
inst✝¹ : DecidablePred fun x => x ∈ s✝
s : Set α
inst✝ : DecidablePred fun x => x ∈ s
a : α
h✝ : a ∈ s
⊢ a ∈ some a ↔ a ∈ s

Next tactic:
simp [*]
theorem mem_ofSet_self_iff {s : Set α} [DecidablePred (· ∈ s)] {a : α} : a ∈ ofSet s a ↔ a ∈ s :=
  by dsimp [ofSet]; split_ifs <;> 

Proof state:
case neg
α : Type u
β : Type v
γ : Type w
δ : Type x
s✝ : Set α
inst✝¹ : DecidablePred fun x => x ∈ s✝
s : Set α
inst✝ : DecidablePred fun x => x ∈ s
a : α
h✝ : a ∉ s
⊢ a ∈ none ↔ a ∈ s

Next tactic:
simp [*]
theorem mem_ofSet_iff {s : Set α} [DecidablePred (· ∈ s)] {a b : α} :
    a ∈ ofSet s b ↔ a = b ∧ a ∈ s := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type x
s✝ : Set α
inst✝¹ : DecidablePred fun x => x ∈ s✝
s : Set α
inst✝ : DecidablePred fun x => x ∈ s
a b : α
⊢ a ∈ (ofSet s) b ↔ a = b ∧ a ∈ s

Next tactic:
dsimp [ofSet]
theorem mem_ofSet_iff {s : Set α} [DecidablePred (· ∈ s)] {a b : α} :
    a ∈ ofSet s b ↔ a = b ∧ a ∈ s := by
  dsimp [ofSet]
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type x
s✝ : Set α
inst✝¹ : DecidablePred fun x => x ∈ s✝
s : Set α
inst✝ : DecidablePred fun x => x ∈ s
a b : α
⊢ (a ∈ if b ∈ s then some b else none) ↔ a = b ∧ a ∈ s

Next tactic:
split_ifs with h
theorem mem_ofSet_iff {s : Set α} [DecidablePred (· ∈ s)] {a b : α} :
    a ∈ ofSet s b ↔ a = b ∧ a ∈ s := by
  dsimp [ofSet]
  split_ifs with h
  · 

Proof state:
case pos
α : Type u
β : Type v
γ : Type w
δ : Type x
s✝ : Set α
inst✝¹ : DecidablePred fun x => x ∈ s✝
s : Set α
inst✝ : DecidablePred fun x => x ∈ s
a b : α
h : b ∈ s
⊢ a ∈ some b ↔ a = b ∧ a ∈ s

Next tactic:
simp only [mem_def, eq_comm, some.injEq, iff_self_and]
theorem mem_ofSet_iff {s : Set α} [DecidablePred (· ∈ s)] {a b : α} :
    a ∈ ofSet s b ↔ a = b ∧ a ∈ s := by
  dsimp [ofSet]
  split_ifs with h
  · simp only [mem_def, eq_comm, some.injEq, iff_self_and]
    

Proof state:
case pos
α : Type u
β : Type v
γ : Type w
δ : Type x
s✝ : Set α
inst✝¹ : DecidablePred fun x => x ∈ s✝
s : Set α
inst✝ : DecidablePred fun x => x ∈ s
a b : α
h : b ∈ s
⊢ a = b → a ∈ s

Next tactic:
rintro rfl
theorem mem_ofSet_iff {s : Set α} [DecidablePred (· ∈ s)] {a b : α} :
    a ∈ ofSet s b ↔ a = b ∧ a ∈ s := by
  dsimp [ofSet]
  split_ifs with h
  · simp only [mem_def, eq_comm, some.injEq, iff_self_and]
    rintro rfl
    

Proof state:
case pos
α : Type u
β : Type v
γ : Type w
δ : Type x
s✝ : Set α
inst✝¹ : DecidablePred fun x => x ∈ s✝
s : Set α
inst✝ : DecidablePred fun x => x ∈ s
a : α
h : a ∈ s
⊢ a ∈ s

Next tactic:
exact h
theorem mem_ofSet_iff {s : Set α} [DecidablePred (· ∈ s)] {a b : α} :
    a ∈ ofSet s b ↔ a = b ∧ a ∈ s := by
  dsimp [ofSet]
  split_ifs with h
  · simp only [mem_def, eq_comm, some.injEq, iff_self_and]
    rintro rfl
    exact h
  · 

Proof state:
case neg
α : Type u
β : Type v
γ : Type w
δ : Type x
s✝ : Set α
inst✝¹ : DecidablePred fun x => x ∈ s✝
s : Set α
inst✝ : DecidablePred fun x => x ∈ s
a b : α
h : b ∉ s
⊢ a ∈ none ↔ a = b ∧ a ∈ s

Next tactic:
simp only [mem_def, false_iff, not_and]
theorem mem_ofSet_iff {s : Set α} [DecidablePred (· ∈ s)] {a b : α} :
    a ∈ ofSet s b ↔ a = b ∧ a ∈ s := by
  dsimp [ofSet]
  split_ifs with h
  · simp only [mem_def, eq_comm, some.injEq, iff_self_and]
    rintro rfl
    exact h
  · simp only [mem_def, false_iff, not_and]
    

Proof state:
case neg
α : Type u
β : Type v
γ : Type w
δ : Type x
s✝ : Set α
inst✝¹ : DecidablePred fun x => x ∈ s✝
s : Set α
inst✝ : DecidablePred fun x => x ∈ s
a b : α
h : b ∉ s
⊢ a = b → a ∉ s

Next tactic:
rintro rfl
theorem mem_ofSet_iff {s : Set α} [DecidablePred (· ∈ s)] {a b : α} :
    a ∈ ofSet s b ↔ a = b ∧ a ∈ s := by
  dsimp [ofSet]
  split_ifs with h
  · simp only [mem_def, eq_comm, some.injEq, iff_self_and]
    rintro rfl
    exact h
  · simp only [mem_def, false_iff, not_and]
    rintro rfl
    

Proof state:
case neg
α : Type u
β : Type v
γ : Type w
δ : Type x
s✝ : Set α
inst✝¹ : DecidablePred fun x => x ∈ s✝
s : Set α
inst✝ : DecidablePred fun x => x ∈ s
a : α
h : a ∉ s
⊢ a ∉ s

Next tactic:
exact h
@[simp]
theorem ofSet_eq_refl {s : Set α} [DecidablePred (· ∈ s)] :
    ofSet s = PEquiv.refl α ↔ s = Set.univ :=
  ⟨fun h => by
    

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type x
s✝ : Set α
inst✝¹ : DecidablePred fun x => x ∈ s✝
s : Set α
inst✝ : DecidablePred fun x => x ∈ s
h : ofSet s = PEquiv.refl α
⊢ s = Set.univ

Next tactic:
rw [Set.eq_univ_iff_forall]
@[simp]
theorem ofSet_eq_refl {s : Set α} [DecidablePred (· ∈ s)] :
    ofSet s = PEquiv.refl α ↔ s = Set.univ :=
  ⟨fun h => by
    rw [Set.eq_univ_iff_forall]
    

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type x
s✝ : Set α
inst✝¹ : DecidablePred fun x => x ∈ s✝
s : Set α
inst✝ : DecidablePred fun x => x ∈ s
h : ofSet s = PEquiv.refl α
⊢ ∀ (x : α), x ∈ s

Next tactic:
intro
@[simp]
theorem ofSet_eq_refl {s : Set α} [DecidablePred (· ∈ s)] :
    ofSet s = PEquiv.refl α ↔ s = Set.univ :=
  ⟨fun h => by
    rw [Set.eq_univ_iff_forall]
    intro
    

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type x
s✝ : Set α
inst✝¹ : DecidablePred fun x => x ∈ s✝
s : Set α
inst✝ : DecidablePred fun x => x ∈ s
h : ofSet s = PEquiv.refl α
x✝ : α
⊢ x✝ ∈ s

Next tactic:
rw [← mem_ofSet_self_iff, h]
@[simp]
theorem ofSet_eq_refl {s : Set α} [DecidablePred (· ∈ s)] :
    ofSet s = PEquiv.refl α ↔ s = Set.univ :=
  ⟨fun h => by
    rw [Set.eq_univ_iff_forall]
    intro
    rw [← mem_ofSet_self_iff, h]
    

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type x
s✝ : Set α
inst✝¹ : DecidablePred fun x => x ∈ s✝
s : Set α
inst✝ : DecidablePred fun x => x ∈ s
h : ofSet s = PEquiv.refl α
x✝ : α
⊢ x✝ ∈ (PEquiv.refl α) x✝

Next tactic:
exact rfl
@[simp]
theorem ofSet_eq_refl {s : Set α} [DecidablePred (· ∈ s)] :
    ofSet s = PEquiv.refl α ↔ s = Set.univ :=
  ⟨fun h => by
    rw [Set.eq_univ_iff_forall]
    intro
    rw [← mem_ofSet_self_iff, h]
    exact rfl, fun h => by 

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type x
s✝ : Set α
inst✝¹ : DecidablePred fun x => x ∈ s✝
s : Set α
inst✝ : DecidablePred fun x => x ∈ s
h : s = Set.univ
⊢ ofSet s = PEquiv.refl α

Next tactic:
simp only [← ofSet_univ, h]
theorem self_trans_symm (f : α ≃. β) : f.trans f.symm = ofSet { a | (f a).isSome } := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type x
f : α ≃. β
⊢ PEquiv.trans f (PEquiv.symm f) = ofSet {a | isSome (f a) = true}

Next tactic:
ext
theorem self_trans_symm (f : α ≃. β) : f.trans f.symm = ofSet { a | (f a).isSome } := by
  ext
  

Proof state:
case h.a
α : Type u
β : Type v
γ : Type w
δ : Type x
f : α ≃. β
x✝ a✝ : α
⊢ a✝ ∈ (PEquiv.trans f (PEquiv.symm f)) x✝ ↔ a✝ ∈ (ofSet {a | isSome (f a) = true}) x✝

Next tactic:
dsimp [PEquiv.trans]
theorem self_trans_symm (f : α ≃. β) : f.trans f.symm = ofSet { a | (f a).isSome } := by
  ext
  dsimp [PEquiv.trans]
  

Proof state:
case h.a
α : Type u
β : Type v
γ : Type w
δ : Type x
f : α ≃. β
x✝ a✝ : α
⊢ a✝ ∈ Option.bind (f x✝) ⇑(PEquiv.symm f) ↔ a✝ ∈ (ofSet {a | isSome (f a) = true}) x✝

Next tactic:
simp only [eq_some_iff f, Option.isSome_iff_exists, Option.mem_def, bind_eq_some',
    ofSet_eq_some_iff]
theorem self_trans_symm (f : α ≃. β) : f.trans f.symm = ofSet { a | (f a).isSome } := by
  ext
  dsimp [PEquiv.trans]
  simp only [eq_some_iff f, Option.isSome_iff_exists, Option.mem_def, bind_eq_some',
    ofSet_eq_some_iff]
  

Proof state:
case h.a
α : Type u
β : Type v
γ : Type w
δ : Type x
f : α ≃. β
x✝ a✝ : α
⊢ (∃ a, f x✝ = some a ∧ f a✝ = some a) ↔ a✝ = x✝ ∧ a✝ ∈ {a | ∃ a_1, f a = some a_1}

Next tactic:
constructor
theorem self_trans_symm (f : α ≃. β) : f.trans f.symm = ofSet { a | (f a).isSome } := by
  ext
  dsimp [PEquiv.trans]
  simp only [eq_some_iff f, Option.isSome_iff_exists, Option.mem_def, bind_eq_some',
    ofSet_eq_some_iff]
  constructor
  · 

Proof state:
case h.a.mp
α : Type u
β : Type v
γ : Type w
δ : Type x
f : α ≃. β
x✝ a✝ : α
⊢ (∃ a, f x✝ = some a ∧ f a✝ = some a) → a✝ = x✝ ∧ a✝ ∈ {a | ∃ a_1, f a = some a_1}

Next tactic:
rintro ⟨b, hb₁, hb₂⟩
theorem self_trans_symm (f : α ≃. β) : f.trans f.symm = ofSet { a | (f a).isSome } := by
  ext
  dsimp [PEquiv.trans]
  simp only [eq_some_iff f, Option.isSome_iff_exists, Option.mem_def, bind_eq_some',
    ofSet_eq_some_iff]
  constructor
  · rintro ⟨b, hb₁, hb₂⟩
    

Proof state:
case h.a.mp.intro.intro
α : Type u
β : Type v
γ : Type w
δ : Type x
f : α ≃. β
x✝ a✝ : α
b : β
hb₁ : f x✝ = some b
hb₂ : f a✝ = some b
⊢ a✝ = x✝ ∧ a✝ ∈ {a | ∃ a_1, f a = some a_1}

Next tactic:
exact ⟨PEquiv.inj _ hb₂ hb₁, b, hb₂⟩
theorem self_trans_symm (f : α ≃. β) : f.trans f.symm = ofSet { a | (f a).isSome } := by
  ext
  dsimp [PEquiv.trans]
  simp only [eq_some_iff f, Option.isSome_iff_exists, Option.mem_def, bind_eq_some',
    ofSet_eq_some_iff]
  constructor
  · rintro ⟨b, hb₁, hb₂⟩
    exact ⟨PEquiv.inj _ hb₂ hb₁, b, hb₂⟩
  · 

Proof state:
case h.a.mpr
α : Type u
β : Type v
γ : Type w
δ : Type x
f : α ≃. β
x✝ a✝ : α
⊢ a✝ = x✝ ∧ a✝ ∈ {a | ∃ a_1, f a = some a_1} → ∃ a, f x✝ = some a ∧ f a✝ = some a

Next tactic:
simp (config := { contextual := true })
theorem symm_trans_self (f : α ≃. β) : f.symm.trans f = ofSet { b | (f.symm b).isSome } :=
  symm_injective <| by 

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type x
f : α ≃. β
⊢ PEquiv.symm (PEquiv.trans (PEquiv.symm f) f) = PEquiv.symm (ofSet {b | isSome ((PEquiv.symm f) b) = true})

Next tactic:
simp [symm_trans_rev, self_trans_symm, -symm_symm]
theorem trans_symm_eq_iff_forall_isSome {f : α ≃. β} :
    f.trans f.symm = PEquiv.refl α ↔ ∀ a, isSome (f a) := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type x
f : α ≃. β
⊢ PEquiv.trans f (PEquiv.symm f) = PEquiv.refl α ↔ ∀ (a : α), isSome (f a) = true

Next tactic:
rw [self_trans_symm, ofSet_eq_refl, Set.eq_univ_iff_forall]
theorem trans_symm_eq_iff_forall_isSome {f : α ≃. β} :
    f.trans f.symm = PEquiv.refl α ↔ ∀ a, isSome (f a) := by
  rw [self_trans_symm, ofSet_eq_refl, Set.eq_univ_iff_forall]; 

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type x
f : α ≃. β
⊢ (∀ (x : α), x ∈ {a | isSome (f a) = true}) ↔ ∀ (a : α), isSome (f a) = true

Next tactic:
rfl
instance instBotPEquiv : Bot (α ≃. β) :=
  ⟨{  toFun := fun _ => none
      invFun := fun _ => none
      inv := by 

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type x
⊢ ∀ (a : α) (b : β), a ∈ (fun x => none) b ↔ b ∈ (fun x => none) a

Next tactic:
simp
@[simp]
theorem trans_bot (f : α ≃. β) : f.trans (⊥ : β ≃. γ) = ⊥ := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type x
f : α ≃. β
⊢ PEquiv.trans f ⊥ = ⊥

Next tactic:
ext
@[simp]
theorem trans_bot (f : α ≃. β) : f.trans (⊥ : β ≃. γ) = ⊥ := by
  ext; 

Proof state:
case h.a
α : Type u
β : Type v
γ : Type w
δ : Type x
f : α ≃. β
x✝ : α
a✝ : γ
⊢ a✝ ∈ (PEquiv.trans f ⊥) x✝ ↔ a✝ ∈ ⊥ x✝

Next tactic:
dsimp [PEquiv.trans]
@[simp]
theorem trans_bot (f : α ≃. β) : f.trans (⊥ : β ≃. γ) = ⊥ := by
  ext; dsimp [PEquiv.trans]; 

Proof state:
case h.a
α : Type u
β : Type v
γ : Type w
δ : Type x
f : α ≃. β
x✝ : α
a✝ : γ
⊢ a✝ ∈ Option.bind (f x✝) ⇑⊥ ↔ a✝ ∈ none

Next tactic:
simp
@[simp]
theorem bot_trans (f : β ≃. γ) : (⊥ : α ≃. β).trans f = ⊥ := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type x
f : β ≃. γ
⊢ PEquiv.trans ⊥ f = ⊥

Next tactic:
ext
@[simp]
theorem bot_trans (f : β ≃. γ) : (⊥ : α ≃. β).trans f = ⊥ := by
  ext; 

Proof state:
case h.a
α : Type u
β : Type v
γ : Type w
δ : Type x
f : β ≃. γ
x✝ : α
a✝ : γ
⊢ a✝ ∈ (PEquiv.trans ⊥ f) x✝ ↔ a✝ ∈ ⊥ x✝

Next tactic:
dsimp [PEquiv.trans]
@[simp]
theorem bot_trans (f : β ≃. γ) : (⊥ : α ≃. β).trans f = ⊥ := by
  ext; dsimp [PEquiv.trans]; 

Proof state:
case h.a
α : Type u
β : Type v
γ : Type w
δ : Type x
f : β ≃. γ
x✝ : α
a✝ : γ
⊢ a✝ ∈ none ↔ a✝ ∈ none

Next tactic:
simp
theorem isSome_symm_get (f : α ≃. β) {a : α} (h : isSome (f a)) :
    isSome (f.symm (Option.get _ h)) :=
  isSome_iff_exists.2 ⟨a, by 

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type x
f : α ≃. β
a : α
h : isSome (f a) = true
⊢ (PEquiv.symm f) (Option.get (f a) h) = some a

Next tactic:
rw [f.eq_some_iff, some_get]
/-- Create a `PEquiv` which sends `a` to `b` and `b` to `a`, but is otherwise `none`. -/
def single (a : α) (b : β) :
    α ≃. β where
  toFun x := if x = a then some b else none
  invFun x := if x = b then some a else none
  inv x y := by
    

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type x
inst✝² : DecidableEq α
inst✝¹ : DecidableEq β
inst✝ : DecidableEq γ
a : α
b : β
x : α
y : β
⊢ x ∈ (fun x => if x = b then some a else none) y ↔ y ∈ (fun x => if x = a then some b else none) x

Next tactic:
dsimp only
/-- Create a `PEquiv` which sends `a` to `b` and `b` to `a`, but is otherwise `none`. -/
def single (a : α) (b : β) :
    α ≃. β where
  toFun x := if x = a then some b else none
  invFun x := if x = b then some a else none
  inv x y := by
    dsimp only
    

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type x
inst✝² : DecidableEq α
inst✝¹ : DecidableEq β
inst✝ : DecidableEq γ
a : α
b : β
x : α
y : β
⊢ (x ∈ if y = b then some a else none) ↔ y ∈ if x = a then some b else none

Next tactic:
split_ifs with h1 h2
/-- Create a `PEquiv` which sends `a` to `b` and `b` to `a`, but is otherwise `none`. -/
def single (a : α) (b : β) :
    α ≃. β where
  toFun x := if x = a then some b else none
  invFun x := if x = b then some a else none
  inv x y := by
    dsimp only
    split_ifs with h1 h2
    · 

Proof state:
case pos
α : Type u
β : Type v
γ : Type w
δ : Type x
inst✝² : DecidableEq α
inst✝¹ : DecidableEq β
inst✝ : DecidableEq γ
a : α
b : β
x : α
y : β
h1 : y = b
h2 : x = a
⊢ x ∈ some a ↔ y ∈ some b

Next tactic:
simp [*]
/-- Create a `PEquiv` which sends `a` to `b` and `b` to `a`, but is otherwise `none`. -/
def single (a : α) (b : β) :
    α ≃. β where
  toFun x := if x = a then some b else none
  invFun x := if x = b then some a else none
  inv x y := by
    dsimp only
    split_ifs with h1 h2
    · simp [*]
    · 

Proof state:
case neg
α : Type u
β : Type v
γ : Type w
δ : Type x
inst✝² : DecidableEq α
inst✝¹ : DecidableEq β
inst✝ : DecidableEq γ
a : α
b : β
x : α
y : β
h1 : y = b
h2 : ¬x = a
⊢ x ∈ some a ↔ y ∈ none

Next tactic:
simp only [mem_def, some.injEq, iff_false] at *
/-- Create a `PEquiv` which sends `a` to `b` and `b` to `a`, but is otherwise `none`. -/
def single (a : α) (b : β) :
    α ≃. β where
  toFun x := if x = a then some b else none
  invFun x := if x = b then some a else none
  inv x y := by
    dsimp only
    split_ifs with h1 h2
    · simp [*]
    · simp only [mem_def, some.injEq, iff_false] at *
      

Proof state:
case neg
α : Type u
β : Type v
γ : Type w
δ : Type x
inst✝² : DecidableEq α
inst✝¹ : DecidableEq β
inst✝ : DecidableEq γ
a : α
b : β
x : α
y : β
h1 : y = b
h2 : ¬x = a
⊢ ¬a = x

Next tactic:
exact Ne.symm h2
/-- Create a `PEquiv` which sends `a` to `b` and `b` to `a`, but is otherwise `none`. -/
def single (a : α) (b : β) :
    α ≃. β where
  toFun x := if x = a then some b else none
  invFun x := if x = b then some a else none
  inv x y := by
    dsimp only
    split_ifs with h1 h2
    · simp [*]
    · simp only [mem_def, some.injEq, iff_false] at *
      exact Ne.symm h2
    · 

Proof state:
case pos
α : Type u
β : Type v
γ : Type w
δ : Type x
inst✝² : DecidableEq α
inst✝¹ : DecidableEq β
inst✝ : DecidableEq γ
a : α
b : β
x : α
y : β
h1 : ¬y = b
h✝ : x = a
⊢ x ∈ none ↔ y ∈ some b

Next tactic:
simp only [mem_def, some.injEq, false_iff] at *
/-- Create a `PEquiv` which sends `a` to `b` and `b` to `a`, but is otherwise `none`. -/
def single (a : α) (b : β) :
    α ≃. β where
  toFun x := if x = a then some b else none
  invFun x := if x = b then some a else none
  inv x y := by
    dsimp only
    split_ifs with h1 h2
    · simp [*]
    · simp only [mem_def, some.injEq, iff_false] at *
      exact Ne.symm h2
    · simp only [mem_def, some.injEq, false_iff] at *
      

Proof state:
case pos
α : Type u
β : Type v
γ : Type w
δ : Type x
inst✝² : DecidableEq α
inst✝¹ : DecidableEq β
inst✝ : DecidableEq γ
a : α
b : β
x : α
y : β
h1 : ¬y = b
h✝ : x = a
⊢ ¬b = y

Next tactic:
exact Ne.symm h1
/-- Create a `PEquiv` which sends `a` to `b` and `b` to `a`, but is otherwise `none`. -/
def single (a : α) (b : β) :
    α ≃. β where
  toFun x := if x = a then some b else none
  invFun x := if x = b then some a else none
  inv x y := by
    dsimp only
    split_ifs with h1 h2
    · simp [*]
    · simp only [mem_def, some.injEq, iff_false] at *
      exact Ne.symm h2
    · simp only [mem_def, some.injEq, false_iff] at *
      exact Ne.symm h1
    · 

Proof state:
case neg
α : Type u
β : Type v
γ : Type w
δ : Type x
inst✝² : DecidableEq α
inst✝¹ : DecidableEq β
inst✝ : DecidableEq γ
a : α
b : β
x : α
y : β
h1 : ¬y = b
h✝ : ¬x = a
⊢ x ∈ none ↔ y ∈ none

Next tactic:
simp
theorem mem_single_iff (a₁ a₂ : α) (b₁ b₂ : β) : b₁ ∈ single a₂ b₂ a₁ ↔ a₁ = a₂ ∧ b₁ = b₂ := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type x
inst✝² : DecidableEq α
inst✝¹ : DecidableEq β
inst✝ : DecidableEq γ
a₁ a₂ : α
b₁ b₂ : β
⊢ b₁ ∈ (single a₂ b₂) a₁ ↔ a₁ = a₂ ∧ b₁ = b₂

Next tactic:
dsimp [single]
theorem mem_single_iff (a₁ a₂ : α) (b₁ b₂ : β) : b₁ ∈ single a₂ b₂ a₁ ↔ a₁ = a₂ ∧ b₁ = b₂ := by
  dsimp [single]; 

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type x
inst✝² : DecidableEq α
inst✝¹ : DecidableEq β
inst✝ : DecidableEq γ
a₁ a₂ : α
b₁ b₂ : β
⊢ (b₁ ∈ if a₁ = a₂ then some b₂ else none) ↔ a₁ = a₂ ∧ b₁ = b₂

Next tactic:
split_ifs
theorem mem_single_iff (a₁ a₂ : α) (b₁ b₂ : β) : b₁ ∈ single a₂ b₂ a₁ ↔ a₁ = a₂ ∧ b₁ = b₂ := by
  dsimp [single]; split_ifs <;> 

Proof state:
case pos
α : Type u
β : Type v
γ : Type w
δ : Type x
inst✝² : DecidableEq α
inst✝¹ : DecidableEq β
inst✝ : DecidableEq γ
a₁ a₂ : α
b₁ b₂ : β
h✝ : a₁ = a₂
⊢ b₁ ∈ some b₂ ↔ a₁ = a₂ ∧ b₁ = b₂

Next tactic:
simp [*, eq_comm]
theorem mem_single_iff (a₁ a₂ : α) (b₁ b₂ : β) : b₁ ∈ single a₂ b₂ a₁ ↔ a₁ = a₂ ∧ b₁ = b₂ := by
  dsimp [single]; split_ifs <;> 

Proof state:
case neg
α : Type u
β : Type v
γ : Type w
δ : Type x
inst✝² : DecidableEq α
inst✝¹ : DecidableEq β
inst✝ : DecidableEq γ
a₁ a₂ : α
b₁ b₂ : β
h✝ : ¬a₁ = a₂
⊢ b₁ ∈ none ↔ a₁ = a₂ ∧ b₁ = b₂

Next tactic:
simp [*, eq_comm]
theorem single_trans_of_mem (a : α) {b : β} {c : γ} {f : β ≃. γ} (h : c ∈ f b) :
    (single a b).trans f = single a c := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type x
inst✝² : DecidableEq α
inst✝¹ : DecidableEq β
inst✝ : DecidableEq γ
a : α
b : β
c : γ
f : β ≃. γ
h : c ∈ f b
⊢ PEquiv.trans (single a b) f = single a c

Next tactic:
ext
theorem single_trans_of_mem (a : α) {b : β} {c : γ} {f : β ≃. γ} (h : c ∈ f b) :
    (single a b).trans f = single a c := by
  ext
  

Proof state:
case h.a
α : Type u
β : Type v
γ : Type w
δ : Type x
inst✝² : DecidableEq α
inst✝¹ : DecidableEq β
inst✝ : DecidableEq γ
a : α
b : β
c : γ
f : β ≃. γ
h : c ∈ f b
x✝ : α
a✝ : γ
⊢ a✝ ∈ (PEquiv.trans (single a b) f) x✝ ↔ a✝ ∈ (single a c) x✝

Next tactic:
dsimp [single, PEquiv.trans]
theorem single_trans_of_mem (a : α) {b : β} {c : γ} {f : β ≃. γ} (h : c ∈ f b) :
    (single a b).trans f = single a c := by
  ext
  dsimp [single, PEquiv.trans]
  

Proof state:
case h.a
α : Type u
β : Type v
γ : Type w
δ : Type x
inst✝² : DecidableEq α
inst✝¹ : DecidableEq β
inst✝ : DecidableEq γ
a : α
b : β
c : γ
f : β ≃. γ
h : c ∈ f b
x✝ : α
a✝ : γ
⊢ a✝ ∈ Option.bind (if x✝ = a then some b else none) ⇑f ↔ a✝ ∈ if x✝ = a then some c else none

Next tactic:
split_ifs