l3lab/ntp-mathlib huggingface dataset:
theorem map.injective {f : α → β} (hinj : Injective f) : Injective (map f) := by
  intro z z'
  refine' Quotient.ind₂ (fun z z' => _) z z'
  cases' z with x y
  cases' z' with x' y'
  repeat' 

Proof state:
case mk.mk
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β
hinj : Injective f
z z' : Sym2 α
x y x' y' : α
⊢ f x = f x' ∧ f y = f y' ∨ f x = f y' ∧ f y = f x' → x = x' ∧ y = y' ∨ x = y' ∧ y = x'

Next tactic:
rw [map_pair_eq, eq_iff]
theorem map.injective {f : α → β} (hinj : Injective f) : Injective (map f) := by
  intro z z'
  refine' Quotient.ind₂ (fun z z' => _) z z'
  cases' z with x y
  cases' z' with x' y'
  repeat' rw [map_pair_eq, eq_iff]
  

Proof state:
case mk.mk
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β
hinj : Injective f
z z' : Sym2 α
x y x' y' : α
⊢ f x = f x' ∧ f y = f y' ∨ f x = f y' ∧ f y = f x' → x = x' ∧ y = y' ∨ x = y' ∧ y = x'

Next tactic:
rintro (h | h)
theorem map.injective {f : α → β} (hinj : Injective f) : Injective (map f) := by
  intro z z'
  refine' Quotient.ind₂ (fun z z' => _) z z'
  cases' z with x y
  cases' z' with x' y'
  repeat' rw [map_pair_eq, eq_iff]
  rintro (h | h) <;> 

Proof state:
case mk.mk.inl
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β
hinj : Injective f
z z' : Sym2 α
x y x' y' : α
h : f x = f x' ∧ f y = f y'
⊢ x = x' ∧ y = y' ∨ x = y' ∧ y = x'

Next tactic:
simp [hinj h.1, hinj h.2]
theorem map.injective {f : α → β} (hinj : Injective f) : Injective (map f) := by
  intro z z'
  refine' Quotient.ind₂ (fun z z' => _) z z'
  cases' z with x y
  cases' z' with x' y'
  repeat' rw [map_pair_eq, eq_iff]
  rintro (h | h) <;> 

Proof state:
case mk.mk.inr
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β
hinj : Injective f
z z' : Sym2 α
x y x' y' : α
h : f x = f y' ∧ f y = f x'
⊢ x = x' ∧ y = y' ∨ x = y' ∧ y = x'

Next tactic:
simp [hinj h.1, hinj h.2]
@[aesop norm (rule_sets [Sym2])]
theorem mem_iff' {a b c : α} : Sym2.Mem a ⟦(b, c)⟧ ↔ a = b ∨ a = c :=
  { mp := by
      

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
a b c : α
⊢ Sym2.Mem a ⟦(b, c)⟧ → a = b ∨ a = c

Next tactic:
rintro ⟨_, h⟩
@[aesop norm (rule_sets [Sym2])]
theorem mem_iff' {a b c : α} : Sym2.Mem a ⟦(b, c)⟧ ↔ a = b ∨ a = c :=
  { mp := by
      rintro ⟨_, h⟩
      

Proof state:
case intro
α : Type u_1
β : Type u_2
γ : Type u_3
a b c w✝ : α
h : ⟦(b, c)⟧ = ⟦(a, w✝)⟧
⊢ a = b ∨ a = c

Next tactic:
rw [eq_iff] at h
@[aesop norm (rule_sets [Sym2])]
theorem mem_iff' {a b c : α} : Sym2.Mem a ⟦(b, c)⟧ ↔ a = b ∨ a = c :=
  { mp := by
      rintro ⟨_, h⟩
      rw [eq_iff] at h
      

Proof state:
case intro
α : Type u_1
β : Type u_2
γ : Type u_3
a b c w✝ : α
h : b = a ∧ c = w✝ ∨ b = w✝ ∧ c = a
⊢ a = b ∨ a = c

Next tactic:
aesop
@[aesop norm (rule_sets [Sym2])]
theorem mem_iff' {a b c : α} : Sym2.Mem a ⟦(b, c)⟧ ↔ a = b ∨ a = c :=
  { mp := by
      rintro ⟨_, h⟩
      rw [eq_iff] at h
      aesop
    mpr := by
      

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
a b c : α
⊢ a = b ∨ a = c → Sym2.Mem a ⟦(b, c)⟧

Next tactic:
rintro (rfl | rfl)
@[aesop norm (rule_sets [Sym2])]
theorem mem_iff' {a b c : α} : Sym2.Mem a ⟦(b, c)⟧ ↔ a = b ∨ a = c :=
  { mp := by
      rintro ⟨_, h⟩
      rw [eq_iff] at h
      aesop
    mpr := by
      rintro (rfl | rfl)
      · 

Proof state:
case inl
α : Type u_1
β : Type u_2
γ : Type u_3
a c : α
⊢ Sym2.Mem a ⟦(a, c)⟧

Next tactic:
exact ⟨_, rfl⟩
@[aesop norm (rule_sets [Sym2])]
theorem mem_iff' {a b c : α} : Sym2.Mem a ⟦(b, c)⟧ ↔ a = b ∨ a = c :=
  { mp := by
      rintro ⟨_, h⟩
      rw [eq_iff] at h
      aesop
    mpr := by
      rintro (rfl | rfl)
      · exact ⟨_, rfl⟩
      

Proof state:
case inr
α : Type u_1
β : Type u_2
γ : Type u_3
a b : α
⊢ Sym2.Mem a ⟦(b, a)⟧

Next tactic:
rw [eq_swap]
@[aesop norm (rule_sets [Sym2])]
theorem mem_iff' {a b c : α} : Sym2.Mem a ⟦(b, c)⟧ ↔ a = b ∨ a = c :=
  { mp := by
      rintro ⟨_, h⟩
      rw [eq_iff] at h
      aesop
    mpr := by
      rintro (rfl | rfl)
      · exact ⟨_, rfl⟩
      rw [eq_swap]
      

Proof state:
case inr
α : Type u_1
β : Type u_2
γ : Type u_3
a b : α
⊢ Sym2.Mem a ⟦(a, b)⟧

Next tactic:
exact ⟨_, rfl⟩
instance : SetLike (Sym2 α) α where
  coe z := { x | z.Mem x }
  coe_injective' z z' h := by
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
z z' : Sym2 α
h : (fun z => {x | Sym2.Mem x z}) z = (fun z => {x | Sym2.Mem x z}) z'
⊢ z = z'

Next tactic:
simp only [Set.ext_iff, Set.mem_setOf_eq] at h
instance : SetLike (Sym2 α) α where
  coe z := { x | z.Mem x }
  coe_injective' z z' h := by
    simp only [Set.ext_iff, Set.mem_setOf_eq] at h
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
z z' : Sym2 α
h : ∀ (x : α), Sym2.Mem x z ↔ Sym2.Mem x z'
⊢ z = z'

Next tactic:
induction' z using Sym2.ind with x y
instance : SetLike (Sym2 α) α where
  coe z := { x | z.Mem x }
  coe_injective' z z' h := by
    simp only [Set.ext_iff, Set.mem_setOf_eq] at h
    induction' z using Sym2.ind with x y
    

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
z' : Sym2 α
x y : α
h : ∀ (x_1 : α), Sym2.Mem x_1 ⟦(x, y)⟧ ↔ Sym2.Mem x_1 z'
⊢ ⟦(x, y)⟧ = z'

Next tactic:
induction' z' using Sym2.ind with x' y'
instance : SetLike (Sym2 α) α where
  coe z := { x | z.Mem x }
  coe_injective' z z' h := by
    simp only [Set.ext_iff, Set.mem_setOf_eq] at h
    induction' z using Sym2.ind with x y
    induction' z' using Sym2.ind with x' y'
    

Proof state:
case h.h
α : Type u_1
β : Type u_2
γ : Type u_3
x y x' y' : α
h : ∀ (x_1 : α), Sym2.Mem x_1 ⟦(x, y)⟧ ↔ Sym2.Mem x_1 ⟦(x', y')⟧
⊢ ⟦(x, y)⟧ = ⟦(x', y')⟧

Next tactic:
have hx := h x
instance : SetLike (Sym2 α) α where
  coe z := { x | z.Mem x }
  coe_injective' z z' h := by
    simp only [Set.ext_iff, Set.mem_setOf_eq] at h
    induction' z using Sym2.ind with x y
    induction' z' using Sym2.ind with x' y'
    have hx := h x; 

Proof state:
case h.h
α : Type u_1
β : Type u_2
γ : Type u_3
x y x' y' : α
h : ∀ (x_1 : α), Sym2.Mem x_1 ⟦(x, y)⟧ ↔ Sym2.Mem x_1 ⟦(x', y')⟧
hx : Sym2.Mem x ⟦(x, y)⟧ ↔ Sym2.Mem x ⟦(x', y')⟧
⊢ ⟦(x, y)⟧ = ⟦(x', y')⟧

Next tactic:
have hy := h y
instance : SetLike (Sym2 α) α where
  coe z := { x | z.Mem x }
  coe_injective' z z' h := by
    simp only [Set.ext_iff, Set.mem_setOf_eq] at h
    induction' z using Sym2.ind with x y
    induction' z' using Sym2.ind with x' y'
    have hx := h x; have hy := h y; 

Proof state:
case h.h
α : Type u_1
β : Type u_2
γ : Type u_3
x y x' y' : α
h : ∀ (x_1 : α), Sym2.Mem x_1 ⟦(x, y)⟧ ↔ Sym2.Mem x_1 ⟦(x', y')⟧
hx : Sym2.Mem x ⟦(x, y)⟧ ↔ Sym2.Mem x ⟦(x', y')⟧
hy : Sym2.Mem y ⟦(x, y)⟧ ↔ Sym2.Mem y ⟦(x', y')⟧
⊢ ⟦(x, y)⟧ = ⟦(x', y')⟧

Next tactic:
have hx' := h x'
instance : SetLike (Sym2 α) α where
  coe z := { x | z.Mem x }
  coe_injective' z z' h := by
    simp only [Set.ext_iff, Set.mem_setOf_eq] at h
    induction' z using Sym2.ind with x y
    induction' z' using Sym2.ind with x' y'
    have hx := h x; have hy := h y; have hx' := h x'; 

Proof state:
case h.h
α : Type u_1
β : Type u_2
γ : Type u_3
x y x' y' : α
h : ∀ (x_1 : α), Sym2.Mem x_1 ⟦(x, y)⟧ ↔ Sym2.Mem x_1 ⟦(x', y')⟧
hx : Sym2.Mem x ⟦(x, y)⟧ ↔ Sym2.Mem x ⟦(x', y')⟧
hy : Sym2.Mem y ⟦(x, y)⟧ ↔ Sym2.Mem y ⟦(x', y')⟧
hx' : Sym2.Mem x' ⟦(x, y)⟧ ↔ Sym2.Mem x' ⟦(x', y')⟧
⊢ ⟦(x, y)⟧ = ⟦(x', y')⟧

Next tactic:
have hy' := h y'
instance : SetLike (Sym2 α) α where
  coe z := { x | z.Mem x }
  coe_injective' z z' h := by
    simp only [Set.ext_iff, Set.mem_setOf_eq] at h
    induction' z using Sym2.ind with x y
    induction' z' using Sym2.ind with x' y'
    have hx := h x; have hy := h y; have hx' := h x'; have hy' := h y'
    

Proof state:
case h.h
α : Type u_1
β : Type u_2
γ : Type u_3
x y x' y' : α
h : ∀ (x_1 : α), Sym2.Mem x_1 ⟦(x, y)⟧ ↔ Sym2.Mem x_1 ⟦(x', y')⟧
hx : Sym2.Mem x ⟦(x, y)⟧ ↔ Sym2.Mem x ⟦(x', y')⟧
hy : Sym2.Mem y ⟦(x, y)⟧ ↔ Sym2.Mem y ⟦(x', y')⟧
hx' : Sym2.Mem x' ⟦(x, y)⟧ ↔ Sym2.Mem x' ⟦(x', y')⟧
hy' : Sym2.Mem y' ⟦(x, y)⟧ ↔ Sym2.Mem y' ⟦(x', y')⟧
⊢ ⟦(x, y)⟧ = ⟦(x', y')⟧

Next tactic:
simp only [mem_iff', eq_self_iff_true, or_true_iff, iff_true_iff,
      true_or_iff, true_iff_iff] at hx hy hx' hy'
instance : SetLike (Sym2 α) α where
  coe z := { x | z.Mem x }
  coe_injective' z z' h := by
    simp only [Set.ext_iff, Set.mem_setOf_eq] at h
    induction' z using Sym2.ind with x y
    induction' z' using Sym2.ind with x' y'
    have hx := h x; have hy := h y; have hx' := h x'; have hy' := h y'
    simp only [mem_iff', eq_self_iff_true, or_true_iff, iff_true_iff,
      true_or_iff, true_iff_iff] at hx hy hx' hy'
    

Proof state:
case h.h
α : Type u_1
β : Type u_2
γ : Type u_3
x y x' y' : α
h : ∀ (x_1 : α), Sym2.Mem x_1 ⟦(x, y)⟧ ↔ Sym2.Mem x_1 ⟦(x', y')⟧
hx : x = x' ∨ x = y'
hy : y = x' ∨ y = y'
hx' : x' = x ∨ x' = y
hy' : y' = x ∨ y' = y
⊢ ⟦(x, y)⟧ = ⟦(x', y')⟧

Next tactic:
aesop
theorem out_fst_mem (e : Sym2 α) : e.out.1 ∈ e :=
  ⟨e.out.2, by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
e : Sym2 α
⊢ e = ⟦((Quotient.out e).1, (Quotient.out e).2)⟧

Next tactic:
rw [e.out_eq]
theorem out_snd_mem (e : Sym2 α) : e.out.2 ∈ e :=
  ⟨e.out.1, by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
e : Sym2 α
⊢ e = ⟦((Quotient.out e).2, (Quotient.out e).1)⟧

Next tactic:
rw [eq_swap, e.out_eq]
theorem ball {p : α → Prop} {a b : α} : (∀ c ∈ (⟦(a, b)⟧ : Sym2 α), p c) ↔ p a ∧ p b := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
p : α → Prop
a b : α
⊢ (∀ c ∈ ⟦(a, b)⟧, p c) ↔ p a ∧ p b

Next tactic:
refine' ⟨fun h => ⟨h _ <| mem_mk''_left _ _, h _ <| mem_mk''_right _ _⟩, fun h c hc => _⟩
theorem ball {p : α → Prop} {a b : α} : (∀ c ∈ (⟦(a, b)⟧ : Sym2 α), p c) ↔ p a ∧ p b := by
  refine' ⟨fun h => ⟨h _ <| mem_mk''_left _ _, h _ <| mem_mk''_right _ _⟩, fun h c hc => _⟩
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
p : α → Prop
a b : α
h : p a ∧ p b
c : α
hc : c ∈ ⟦(a, b)⟧
⊢ p c

Next tactic:
obtain rfl | rfl := Sym2.mem_iff.1 hc
theorem ball {p : α → Prop} {a b : α} : (∀ c ∈ (⟦(a, b)⟧ : Sym2 α), p c) ↔ p a ∧ p b := by
  refine' ⟨fun h => ⟨h _ <| mem_mk''_left _ _, h _ <| mem_mk''_right _ _⟩, fun h c hc => _⟩
  obtain rfl | rfl := Sym2.mem_iff.1 hc
  · 

Proof state:
case inl
α : Type u_1
β : Type u_2
γ : Type u_3
p : α → Prop
b c : α
h : p c ∧ p b
hc : c ∈ ⟦(c, b)⟧
⊢ p c

Next tactic:
exact h.1
theorem ball {p : α → Prop} {a b : α} : (∀ c ∈ (⟦(a, b)⟧ : Sym2 α), p c) ↔ p a ∧ p b := by
  refine' ⟨fun h => ⟨h _ <| mem_mk''_left _ _, h _ <| mem_mk''_right _ _⟩, fun h c hc => _⟩
  obtain rfl | rfl := Sym2.mem_iff.1 hc
  · exact h.1
  · 

Proof state:
case inr
α : Type u_1
β : Type u_2
γ : Type u_3
p : α → Prop
a c : α
h : p a ∧ p c
hc : c ∈ ⟦(a, c)⟧
⊢ p c

Next tactic:
exact h.2
@[simp]
theorem other_spec {a : α} {z : Sym2 α} (h : a ∈ z) : ⟦(a, Mem.other h)⟧ = z := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
a : α
z : Sym2 α
h : a ∈ z
⊢ ⟦(a, Mem.other h)⟧ = z

Next tactic:
erw [← Classical.choose_spec h]
theorem other_mem {a : α} {z : Sym2 α} (h : a ∈ z) : Mem.other h ∈ z := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
a : α
z : Sym2 α
h : a ∈ z
⊢ Mem.other h ∈ z

Next tactic:
convert mem_mk''_right a <| Mem.other h
theorem other_mem {a : α} {z : Sym2 α} (h : a ∈ z) : Mem.other h ∈ z := by
  convert mem_mk''_right a <| Mem.other h
  

Proof state:
case h.e'_5
α : Type u_1
β : Type u_2
γ : Type u_3
a : α
z : Sym2 α
h : a ∈ z
⊢ z = ⟦(a, Mem.other h)⟧

Next tactic:
rw [other_spec h]
theorem mem_and_mem_iff {x y : α} {z : Sym2 α} (hne : x ≠ y) : x ∈ z ∧ y ∈ z ↔ z = ⟦(x, y)⟧ := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
x y : α
z : Sym2 α
hne : x ≠ y
⊢ x ∈ z ∧ y ∈ z ↔ z = ⟦(x, y)⟧

Next tactic:
constructor
theorem mem_and_mem_iff {x y : α} {z : Sym2 α} (hne : x ≠ y) : x ∈ z ∧ y ∈ z ↔ z = ⟦(x, y)⟧ := by
  constructor
  · 

Proof state:
case mp
α : Type u_1
β : Type u_2
γ : Type u_3
x y : α
z : Sym2 α
hne : x ≠ y
⊢ x ∈ z ∧ y ∈ z → z = ⟦(x, y)⟧

Next tactic:
induction' z using Sym2.ind with x' y'
theorem mem_and_mem_iff {x y : α} {z : Sym2 α} (hne : x ≠ y) : x ∈ z ∧ y ∈ z ↔ z = ⟦(x, y)⟧ := by
  constructor
  · induction' z using Sym2.ind with x' y'
    

Proof state:
case mp.h
α : Type u_1
β : Type u_2
γ : Type u_3
x y : α
hne : x ≠ y
x' y' : α
⊢ x ∈ ⟦(x', y')⟧ ∧ y ∈ ⟦(x', y')⟧ → ⟦(x', y')⟧ = ⟦(x, y)⟧

Next tactic:
rw [mem_iff, mem_iff]
theorem mem_and_mem_iff {x y : α} {z : Sym2 α} (hne : x ≠ y) : x ∈ z ∧ y ∈ z ↔ z = ⟦(x, y)⟧ := by
  constructor
  · induction' z using Sym2.ind with x' y'
    rw [mem_iff, mem_iff]
    

Proof state:
case mp.h
α : Type u_1
β : Type u_2
γ : Type u_3
x y : α
hne : x ≠ y
x' y' : α
⊢ (x = x' ∨ x = y') ∧ (y = x' ∨ y = y') → ⟦(x', y')⟧ = ⟦(x, y)⟧

Next tactic:
aesop
theorem mem_and_mem_iff {x y : α} {z : Sym2 α} (hne : x ≠ y) : x ∈ z ∧ y ∈ z ↔ z = ⟦(x, y)⟧ := by
  constructor
  · induction' z using Sym2.ind with x' y'
    rw [mem_iff, mem_iff]
    aesop
  · 

Proof state:
case mpr
α : Type u_1
β : Type u_2
γ : Type u_3
x y : α
z : Sym2 α
hne : x ≠ y
⊢ z = ⟦(x, y)⟧ → x ∈ z ∧ y ∈ z

Next tactic:
rintro rfl
theorem mem_and_mem_iff {x y : α} {z : Sym2 α} (hne : x ≠ y) : x ∈ z ∧ y ∈ z ↔ z = ⟦(x, y)⟧ := by
  constructor
  · induction' z using Sym2.ind with x' y'
    rw [mem_iff, mem_iff]
    aesop
  · rintro rfl
    

Proof state:
case mpr
α : Type u_1
β : Type u_2
γ : Type u_3
x y : α
hne : x ≠ y
⊢ x ∈ ⟦(x, y)⟧ ∧ y ∈ ⟦(x, y)⟧

Next tactic:
simp
@[simp]
theorem mem_map {f : α → β} {b : β} {z : Sym2 α} : b ∈ Sym2.map f z ↔ ∃ a, a ∈ z ∧ f a = b := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β
b : β
z : Sym2 α
⊢ b ∈ map f z ↔ ∃ a ∈ z, f a = b

Next tactic:
induction' z using Sym2.ind with x y
@[simp]
theorem mem_map {f : α → β} {b : β} {z : Sym2 α} : b ∈ Sym2.map f z ↔ ∃ a, a ∈ z ∧ f a = b := by
  induction' z using Sym2.ind with x y
  

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β
b : β
x y : α
⊢ b ∈ map f ⟦(x, y)⟧ ↔ ∃ a ∈ ⟦(x, y)⟧, f a = b

Next tactic:
simp only [map, Quotient.map_mk, Prod.map_mk, mem_iff]
@[simp]
theorem mem_map {f : α → β} {b : β} {z : Sym2 α} : b ∈ Sym2.map f z ↔ ∃ a, a ∈ z ∧ f a = b := by
  induction' z using Sym2.ind with x y
  simp only [map, Quotient.map_mk, Prod.map_mk, mem_iff]
  

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β
b : β
x y : α
⊢ b = f x ∨ b = f y ↔ ∃ a, (a = x ∨ a = y) ∧ f a = b

Next tactic:
constructor
@[simp]
theorem mem_map {f : α → β} {b : β} {z : Sym2 α} : b ∈ Sym2.map f z ↔ ∃ a, a ∈ z ∧ f a = b := by
  induction' z using Sym2.ind with x y
  simp only [map, Quotient.map_mk, Prod.map_mk, mem_iff]
  constructor
  · 

Proof state:
case h.mp
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β
b : β
x y : α
⊢ b = f x ∨ b = f y → ∃ a, (a = x ∨ a = y) ∧ f a = b

Next tactic:
rintro (rfl | rfl)
@[simp]
theorem mem_map {f : α → β} {b : β} {z : Sym2 α} : b ∈ Sym2.map f z ↔ ∃ a, a ∈ z ∧ f a = b := by
  induction' z using Sym2.ind with x y
  simp only [map, Quotient.map_mk, Prod.map_mk, mem_iff]
  constructor
  · rintro (rfl | rfl)
    · 

Proof state:
case h.mp.inl
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β
x y : α
⊢ ∃ a, (a = x ∨ a = y) ∧ f a = f x

Next tactic:
exact ⟨x, by simp⟩
@[simp]
theorem mem_map {f : α → β} {b : β} {z : Sym2 α} : b ∈ Sym2.map f z ↔ ∃ a, a ∈ z ∧ f a = b := by
  induction' z using Sym2.ind with x y
  simp only [map, Quotient.map_mk, Prod.map_mk, mem_iff]
  constructor
  · rintro (rfl | rfl)
    · exact ⟨x, by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β
x y : α
⊢ (x = x ∨ x = y) ∧ f x = f x

Next tactic:
simp
@[simp]
theorem mem_map {f : α → β} {b : β} {z : Sym2 α} : b ∈ Sym2.map f z ↔ ∃ a, a ∈ z ∧ f a = b := by
  induction' z using Sym2.ind with x y
  simp only [map, Quotient.map_mk, Prod.map_mk, mem_iff]
  constructor
  · rintro (rfl | rfl)
    · exact ⟨x, by simp⟩
    · 

Proof state:
case h.mp.inr
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β
x y : α
⊢ ∃ a, (a = x ∨ a = y) ∧ f a = f y

Next tactic:
exact ⟨y, by simp⟩
@[simp]
theorem mem_map {f : α → β} {b : β} {z : Sym2 α} : b ∈ Sym2.map f z ↔ ∃ a, a ∈ z ∧ f a = b := by
  induction' z using Sym2.ind with x y
  simp only [map, Quotient.map_mk, Prod.map_mk, mem_iff]
  constructor
  · rintro (rfl | rfl)
    · exact ⟨x, by simp⟩
    · exact ⟨y, by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β
x y : α
⊢ (y = x ∨ y = y) ∧ f y = f y

Next tactic:
simp
@[simp]
theorem mem_map {f : α → β} {b : β} {z : Sym2 α} : b ∈ Sym2.map f z ↔ ∃ a, a ∈ z ∧ f a = b := by
  induction' z using Sym2.ind with x y
  simp only [map, Quotient.map_mk, Prod.map_mk, mem_iff]
  constructor
  · rintro (rfl | rfl)
    · exact ⟨x, by simp⟩
    · exact ⟨y, by simp⟩
  · 

Proof state:
case h.mpr
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β
b : β
x y : α
⊢ (∃ a, (a = x ∨ a = y) ∧ f a = b) → b = f x ∨ b = f y

Next tactic:
rintro ⟨w, rfl | rfl, rfl⟩
@[simp]
theorem mem_map {f : α → β} {b : β} {z : Sym2 α} : b ∈ Sym2.map f z ↔ ∃ a, a ∈ z ∧ f a = b := by
  induction' z using Sym2.ind with x y
  simp only [map, Quotient.map_mk, Prod.map_mk, mem_iff]
  constructor
  · rintro (rfl | rfl)
    · exact ⟨x, by simp⟩
    · exact ⟨y, by simp⟩
  · rintro ⟨w, rfl | rfl, rfl⟩ <;> 

Proof state:
case h.mpr.intro.intro.inl
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β
y w : α
⊢ f w = f w ∨ f w = f y

Next tactic:
simp
@[simp]
theorem mem_map {f : α → β} {b : β} {z : Sym2 α} : b ∈ Sym2.map f z ↔ ∃ a, a ∈ z ∧ f a = b := by
  induction' z using Sym2.ind with x y
  simp only [map, Quotient.map_mk, Prod.map_mk, mem_iff]
  constructor
  · rintro (rfl | rfl)
    · exact ⟨x, by simp⟩
    · exact ⟨y, by simp⟩
  · rintro ⟨w, rfl | rfl, rfl⟩ <;> 

Proof state:
case h.mpr.intro.intro.inr
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β
x w : α
⊢ f w = f x ∨ f w = f w

Next tactic:
simp
@[congr]
theorem map_congr {f g : α → β} {s : Sym2 α} (h : ∀ x ∈ s, f x = g x) : map f s = map g s := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f g : α → β
s : Sym2 α
h : ∀ x ∈ s, f x = g x
⊢ map f s = map g s

Next tactic:
ext y
@[congr]
theorem map_congr {f g : α → β} {s : Sym2 α} (h : ∀ x ∈ s, f x = g x) : map f s = map g s := by
  ext y
  

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
f g : α → β
s : Sym2 α
h : ∀ x ∈ s, f x = g x
y : β
⊢ y ∈ map f s ↔ y ∈ map g s

Next tactic:
simp only [mem_map]
@[congr]
theorem map_congr {f g : α → β} {s : Sym2 α} (h : ∀ x ∈ s, f x = g x) : map f s = map g s := by
  ext y
  simp only [mem_map]
  

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
f g : α → β
s : Sym2 α
h : ∀ x ∈ s, f x = g x
y : β
⊢ (∃ a ∈ s, f a = y) ↔ ∃ a ∈ s, g a = y

Next tactic:
constructor
@[congr]
theorem map_congr {f g : α → β} {s : Sym2 α} (h : ∀ x ∈ s, f x = g x) : map f s = map g s := by
  ext y
  simp only [mem_map]
  constructor <;>
    · 

Proof state:
case h.mp
α : Type u_1
β : Type u_2
γ : Type u_3
f g : α → β
s : Sym2 α
h : ∀ x ∈ s, f x = g x
y : β
⊢ (∃ a ∈ s, f a = y) → ∃ a ∈ s, g a = y

Next tactic:
rintro ⟨w, hw, rfl⟩
@[congr]
theorem map_congr {f g : α → β} {s : Sym2 α} (h : ∀ x ∈ s, f x = g x) : map f s = map g s := by
  ext y
  simp only [mem_map]
  constructor <;>
    · rintro ⟨w, hw, rfl⟩
      

Proof state:
case h.mp.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
f g : α → β
s : Sym2 α
h : ∀ x ∈ s, f x = g x
w : α
hw : w ∈ s
⊢ ∃ a ∈ s, g a = f w

Next tactic:
exact ⟨w, hw, by simp [hw, h]⟩
@[congr]
theorem map_congr {f g : α → β} {s : Sym2 α} (h : ∀ x ∈ s, f x = g x) : map f s = map g s := by
  ext y
  simp only [mem_map]
  constructor <;>
    · rintro ⟨w, hw, rfl⟩
      exact ⟨w, hw, by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f g : α → β
s : Sym2 α
h : ∀ x ∈ s, f x = g x
w : α
hw : w ∈ s
⊢ g w = f w

Next tactic:
simp [hw, h]
@[congr]
theorem map_congr {f g : α → β} {s : Sym2 α} (h : ∀ x ∈ s, f x = g x) : map f s = map g s := by
  ext y
  simp only [mem_map]
  constructor <;>
    · 

Proof state:
case h.mpr
α : Type u_1
β : Type u_2
γ : Type u_3
f g : α → β
s : Sym2 α
h : ∀ x ∈ s, f x = g x
y : β
⊢ (∃ a ∈ s, g a = y) → ∃ a ∈ s, f a = y

Next tactic:
rintro ⟨w, hw, rfl⟩
@[congr]
theorem map_congr {f g : α → β} {s : Sym2 α} (h : ∀ x ∈ s, f x = g x) : map f s = map g s := by
  ext y
  simp only [mem_map]
  constructor <;>
    · rintro ⟨w, hw, rfl⟩
      

Proof state:
case h.mpr.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
f g : α → β
s : Sym2 α
h : ∀ x ∈ s, f x = g x
w : α
hw : w ∈ s
⊢ ∃ a ∈ s, f a = g w

Next tactic:
exact ⟨w, hw, by simp [hw, h]⟩
@[congr]
theorem map_congr {f g : α → β} {s : Sym2 α} (h : ∀ x ∈ s, f x = g x) : map f s = map g s := by
  ext y
  simp only [mem_map]
  constructor <;>
    · rintro ⟨w, hw, rfl⟩
      exact ⟨w, hw, by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f g : α → β
s : Sym2 α
h : ∀ x ∈ s, f x = g x
w : α
hw : w ∈ s
⊢ f w = g w

Next tactic:
simp [hw, h]
theorem diag_injective : Function.Injective (Sym2.diag : α → Sym2 α) := fun x y h => by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
e : Sym2 α
f : α → β
x y : α
h : diag x = diag y
⊢ x = y

Next tactic:
cases Quotient.exact h
theorem diag_injective : Function.Injective (Sym2.diag : α → Sym2 α) := fun x y h => by
  cases Quotient.exact h <;> 

Proof state:
case refl
α : Type u_1
β : Type u_2
γ : Type u_3
e : Sym2 α
f : α → β
x : α
h : diag x = diag x
⊢ x = x

Next tactic:
rfl
theorem diag_injective : Function.Injective (Sym2.diag : α → Sym2 α) := fun x y h => by
  cases Quotient.exact h <;> 

Proof state:
case swap
α : Type u_1
β : Type u_2
γ : Type u_3
e : Sym2 α
f : α → β
x : α
h : diag x = diag x
⊢ x = x

Next tactic:
rfl
theorem IsDiag.mem_range_diag {z : Sym2 α} : IsDiag z → z ∈ Set.range (@diag α) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
e : Sym2 α
f : α → β
z : Sym2 α
⊢ IsDiag z → z ∈ Set.range diag

Next tactic:
induction' z using Sym2.ind with x y
theorem IsDiag.mem_range_diag {z : Sym2 α} : IsDiag z → z ∈ Set.range (@diag α) := by
  induction' z using Sym2.ind with x y
  

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
e : Sym2 α
f : α → β
x y : α
⊢ IsDiag ⟦(x, y)⟧ → ⟦(x, y)⟧ ∈ Set.range diag

Next tactic:
rintro (rfl : x = y)
theorem IsDiag.mem_range_diag {z : Sym2 α} : IsDiag z → z ∈ Set.range (@diag α) := by
  induction' z using Sym2.ind with x y
  rintro (rfl : x = y)
  

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
e : Sym2 α
f : α → β
x : α
⊢ ⟦(x, x)⟧ ∈ Set.range diag

Next tactic:
exact ⟨_, rfl⟩
instance IsDiag.decidablePred (α : Type u) [DecidableEq α] : DecidablePred (@IsDiag α) := by
  

Proof state:
α✝ : Type u_1
β : Type u_2
γ : Type u_3
e : Sym2 α✝
f : α✝ → β
α : Type u
inst✝ : DecidableEq α
⊢ DecidablePred IsDiag

Next tactic:
refine' fun z => Quotient.recOnSubsingleton z fun a => _
instance IsDiag.decidablePred (α : Type u) [DecidableEq α] : DecidablePred (@IsDiag α) := by
  refine' fun z => Quotient.recOnSubsingleton z fun a => _
  

Proof state:
α✝ : Type u_1
β : Type u_2
γ : Type u_3
e : Sym2 α✝
f : α✝ → β
α : Type u
inst✝ : DecidableEq α
z : Sym2 α
a : α × α
⊢ Decidable (IsDiag ⟦a⟧)

Next tactic:
erw [isDiag_iff_proj_eq]
instance IsDiag.decidablePred (α : Type u) [DecidableEq α] : DecidablePred (@IsDiag α) := by
  refine' fun z => Quotient.recOnSubsingleton z fun a => _
  erw [isDiag_iff_proj_eq]
  

Proof state:
α✝ : Type u_1
β : Type u_2
γ : Type u_3
e : Sym2 α✝
f : α✝ → β
α : Type u
inst✝ : DecidableEq α
z : Sym2 α
a : α × α
⊢ Decidable (a.1 = a.2)

Next tactic:
infer_instance
theorem other_ne {a : α} {z : Sym2 α} (hd : ¬IsDiag z) (h : a ∈ z) : Mem.other h ≠ a := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
e : Sym2 α
f : α → β
a : α
z : Sym2 α
hd : ¬IsDiag z
h : a ∈ z
⊢ Mem.other h ≠ a

Next tactic:
contrapose! hd
theorem other_ne {a : α} {z : Sym2 α} (hd : ¬IsDiag z) (h : a ∈ z) : Mem.other h ≠ a := by
  contrapose! hd
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
e : Sym2 α
f : α → β
a : α
z : Sym2 α
h : a ∈ z
hd : Mem.other h = a
⊢ IsDiag z

Next tactic:
have h' := Sym2.other_spec h
theorem other_ne {a : α} {z : Sym2 α} (hd : ¬IsDiag z) (h : a ∈ z) : Mem.other h ≠ a := by
  contrapose! hd
  have h' := Sym2.other_spec h
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
e : Sym2 α
f : α → β
a : α
z : Sym2 α
h : a ∈ z
hd : Mem.other h = a
h' : ⟦(a, Mem.other h)⟧ = z
⊢ IsDiag z

Next tactic:
rw [hd] at h'