l3lab/ntp-mathlib huggingface dataset:
/-- The symmetric square is equivalent to length-2 vectors up to permutations.
-/
def sym2EquivSym' : Equiv (Sym2 α) (Sym' α 2)
    where
  toFun :=
    Quotient.map (fun x : α × α => ⟨[x.1, x.2], rfl⟩)
      (by
        rintro _ _ ⟨_⟩
        · constructor; apply List.Perm.refl
        apply List.Perm.swap'
        rfl)
  invFun :=
    Quotient.map fromVector
      (by
        rintro ⟨x, hx⟩ ⟨y, hy⟩ h
        cases' x with _ x; · simp at hx
        cases' x with _ x; · simp at hx
        cases' x with _ x; swap
        · exfalso
          simp at hx
        cases' y with _ y; · simp at hy
        cases' y with _ y; · simp at hy
        cases' y with _ y; swap
        · exfalso
          simp at hy
        rcases perm_card_two_iff.mp h with (⟨rfl, rfl⟩ | ⟨rfl, rfl⟩)
        · constructor
        apply Sym2.Rel.swap)
  left_inv := by apply Sym2.ind; aesop (add norm unfold [Sym2.fromVector])
  right_inv x := by
    refine' Quotient.recOnSubsingleton x fun x => _
    · cases' x with x hx
      cases' x with _ x
      · simp at hx
      cases' x with _ x
      · 

Proof state:
case mk.cons.nil
α : Type u_1
β : Type u_2
γ : Type u_3
e : Sym2 α
f : α → β
x : Sym' α 2
head✝ : α
hx : List.length [head✝] = 2
⊢ Quotient.map (fun x => { val := [x.1, x.2], property := (_ : List.length [x.1, x.2] = List.length [x.1, x.2]) })
      (_ :
        ∀ ⦃a b : α × α⦄,
          a ≈ b →
            (fun x => { val := [x.1, x.2], property := (_ : List.length [x.1, x.2] = List.length [x.1, x.2]) }) a ≈
              (fun x => { val := [x.1, x.2], property := (_ : List.length [x.1, x.2] = List.length [x.1, x.2]) }) b)
      (Quotient.map Sym2.fromVector
        (_ :
          ∀ ⦃a b : Vector α 2⦄,
            (fun x x_1 => x ≈ x_1) a b → (fun x x_1 => x ≈ x_1) (Sym2.fromVector a) (Sym2.fromVector b))
        ⟦{ val := [head✝], property := hx }⟧) =
    ⟦{ val := [head✝], property := hx }⟧

Next tactic:
simp at hx
/-- The symmetric square is equivalent to length-2 vectors up to permutations.
-/
def sym2EquivSym' : Equiv (Sym2 α) (Sym' α 2)
    where
  toFun :=
    Quotient.map (fun x : α × α => ⟨[x.1, x.2], rfl⟩)
      (by
        rintro _ _ ⟨_⟩
        · constructor; apply List.Perm.refl
        apply List.Perm.swap'
        rfl)
  invFun :=
    Quotient.map fromVector
      (by
        rintro ⟨x, hx⟩ ⟨y, hy⟩ h
        cases' x with _ x; · simp at hx
        cases' x with _ x; · simp at hx
        cases' x with _ x; swap
        · exfalso
          simp at hx
        cases' y with _ y; · simp at hy
        cases' y with _ y; · simp at hy
        cases' y with _ y; swap
        · exfalso
          simp at hy
        rcases perm_card_two_iff.mp h with (⟨rfl, rfl⟩ | ⟨rfl, rfl⟩)
        · constructor
        apply Sym2.Rel.swap)
  left_inv := by apply Sym2.ind; aesop (add norm unfold [Sym2.fromVector])
  right_inv x := by
    refine' Quotient.recOnSubsingleton x fun x => _
    · cases' x with x hx
      cases' x with _ x
      · simp at hx
      cases' x with _ x
      · simp at hx
      

Proof state:
case mk.cons.cons
α : Type u_1
β : Type u_2
γ : Type u_3
e : Sym2 α
f : α → β
x✝ : Sym' α 2
head✝¹ head✝ : α
x : List α
hx : List.length (head✝¹ :: head✝ :: x) = 2
⊢ Quotient.map (fun x => { val := [x.1, x.2], property := (_ : List.length [x.1, x.2] = List.length [x.1, x.2]) })
      (_ :
        ∀ ⦃a b : α × α⦄,
          a ≈ b →
            (fun x => { val := [x.1, x.2], property := (_ : List.length [x.1, x.2] = List.length [x.1, x.2]) }) a ≈
              (fun x => { val := [x.1, x.2], property := (_ : List.length [x.1, x.2] = List.length [x.1, x.2]) }) b)
      (Quotient.map Sym2.fromVector
        (_ :
          ∀ ⦃a b : Vector α 2⦄,
            (fun x x_1 => x ≈ x_1) a b → (fun x x_1 => x ≈ x_1) (Sym2.fromVector a) (Sym2.fromVector b))
        ⟦{ val := head✝¹ :: head✝ :: x, property := hx }⟧) =
    ⟦{ val := head✝¹ :: head✝ :: x, property := hx }⟧

Next tactic:
cases' x with _ x
/-- The symmetric square is equivalent to length-2 vectors up to permutations.
-/
def sym2EquivSym' : Equiv (Sym2 α) (Sym' α 2)
    where
  toFun :=
    Quotient.map (fun x : α × α => ⟨[x.1, x.2], rfl⟩)
      (by
        rintro _ _ ⟨_⟩
        · constructor; apply List.Perm.refl
        apply List.Perm.swap'
        rfl)
  invFun :=
    Quotient.map fromVector
      (by
        rintro ⟨x, hx⟩ ⟨y, hy⟩ h
        cases' x with _ x; · simp at hx
        cases' x with _ x; · simp at hx
        cases' x with _ x; swap
        · exfalso
          simp at hx
        cases' y with _ y; · simp at hy
        cases' y with _ y; · simp at hy
        cases' y with _ y; swap
        · exfalso
          simp at hy
        rcases perm_card_two_iff.mp h with (⟨rfl, rfl⟩ | ⟨rfl, rfl⟩)
        · constructor
        apply Sym2.Rel.swap)
  left_inv := by apply Sym2.ind; aesop (add norm unfold [Sym2.fromVector])
  right_inv x := by
    refine' Quotient.recOnSubsingleton x fun x => _
    · cases' x with x hx
      cases' x with _ x
      · simp at hx
      cases' x with _ x
      · simp at hx
      cases' x with _ x
      

Proof state:
case mk.cons.cons.nil
α : Type u_1
β : Type u_2
γ : Type u_3
e : Sym2 α
f : α → β
x : Sym' α 2
head✝¹ head✝ : α
hx : List.length [head✝¹, head✝] = 2
⊢ Quotient.map (fun x => { val := [x.1, x.2], property := (_ : List.length [x.1, x.2] = List.length [x.1, x.2]) })
      (_ :
        ∀ ⦃a b : α × α⦄,
          a ≈ b →
            (fun x => { val := [x.1, x.2], property := (_ : List.length [x.1, x.2] = List.length [x.1, x.2]) }) a ≈
              (fun x => { val := [x.1, x.2], property := (_ : List.length [x.1, x.2] = List.length [x.1, x.2]) }) b)
      (Quotient.map Sym2.fromVector
        (_ :
          ∀ ⦃a b : Vector α 2⦄,
            (fun x x_1 => x ≈ x_1) a b → (fun x x_1 => x ≈ x_1) (Sym2.fromVector a) (Sym2.fromVector b))
        ⟦{ val := [head✝¹, head✝], property := hx }⟧) =
    ⟦{ val := [head✝¹, head✝], property := hx }⟧
case mk.cons.cons.cons
α : Type u_1
β : Type u_2
γ : Type u_3
e : Sym2 α
f : α → β
x✝ : Sym' α 2
head✝² head✝¹ head✝ : α
x : List α
hx : List.length (head✝² :: head✝¹ :: head✝ :: x) = 2
⊢ Quotient.map (fun x => { val := [x.1, x.2], property := (_ : List.length [x.1, x.2] = List.length [x.1, x.2]) })
      (_ :
        ∀ ⦃a b : α × α⦄,
          a ≈ b →
            (fun x => { val := [x.1, x.2], property := (_ : List.length [x.1, x.2] = List.length [x.1, x.2]) }) a ≈
              (fun x => { val := [x.1, x.2], property := (_ : List.length [x.1, x.2] = List.length [x.1, x.2]) }) b)
      (Quotient.map Sym2.fromVector
        (_ :
          ∀ ⦃a b : Vector α 2⦄,
            (fun x x_1 => x ≈ x_1) a b → (fun x x_1 => x ≈ x_1) (Sym2.fromVector a) (Sym2.fromVector b))
        ⟦{ val := head✝² :: head✝¹ :: head✝ :: x, property := hx }⟧) =
    ⟦{ val := head✝² :: head✝¹ :: head✝ :: x, property := hx }⟧

Next tactic:
swap
/-- The symmetric square is equivalent to length-2 vectors up to permutations.
-/
def sym2EquivSym' : Equiv (Sym2 α) (Sym' α 2)
    where
  toFun :=
    Quotient.map (fun x : α × α => ⟨[x.1, x.2], rfl⟩)
      (by
        rintro _ _ ⟨_⟩
        · constructor; apply List.Perm.refl
        apply List.Perm.swap'
        rfl)
  invFun :=
    Quotient.map fromVector
      (by
        rintro ⟨x, hx⟩ ⟨y, hy⟩ h
        cases' x with _ x; · simp at hx
        cases' x with _ x; · simp at hx
        cases' x with _ x; swap
        · exfalso
          simp at hx
        cases' y with _ y; · simp at hy
        cases' y with _ y; · simp at hy
        cases' y with _ y; swap
        · exfalso
          simp at hy
        rcases perm_card_two_iff.mp h with (⟨rfl, rfl⟩ | ⟨rfl, rfl⟩)
        · constructor
        apply Sym2.Rel.swap)
  left_inv := by apply Sym2.ind; aesop (add norm unfold [Sym2.fromVector])
  right_inv x := by
    refine' Quotient.recOnSubsingleton x fun x => _
    · cases' x with x hx
      cases' x with _ x
      · simp at hx
      cases' x with _ x
      · simp at hx
      cases' x with _ x
      swap
      · 

Proof state:
case mk.cons.cons.cons
α : Type u_1
β : Type u_2
γ : Type u_3
e : Sym2 α
f : α → β
x✝ : Sym' α 2
head✝² head✝¹ head✝ : α
x : List α
hx : List.length (head✝² :: head✝¹ :: head✝ :: x) = 2
⊢ Quotient.map (fun x => { val := [x.1, x.2], property := (_ : List.length [x.1, x.2] = List.length [x.1, x.2]) })
      (_ :
        ∀ ⦃a b : α × α⦄,
          a ≈ b →
            (fun x => { val := [x.1, x.2], property := (_ : List.length [x.1, x.2] = List.length [x.1, x.2]) }) a ≈
              (fun x => { val := [x.1, x.2], property := (_ : List.length [x.1, x.2] = List.length [x.1, x.2]) }) b)
      (Quotient.map Sym2.fromVector
        (_ :
          ∀ ⦃a b : Vector α 2⦄,
            (fun x x_1 => x ≈ x_1) a b → (fun x x_1 => x ≈ x_1) (Sym2.fromVector a) (Sym2.fromVector b))
        ⟦{ val := head✝² :: head✝¹ :: head✝ :: x, property := hx }⟧) =
    ⟦{ val := head✝² :: head✝¹ :: head✝ :: x, property := hx }⟧

Next tactic:
exfalso
/-- The symmetric square is equivalent to length-2 vectors up to permutations.
-/
def sym2EquivSym' : Equiv (Sym2 α) (Sym' α 2)
    where
  toFun :=
    Quotient.map (fun x : α × α => ⟨[x.1, x.2], rfl⟩)
      (by
        rintro _ _ ⟨_⟩
        · constructor; apply List.Perm.refl
        apply List.Perm.swap'
        rfl)
  invFun :=
    Quotient.map fromVector
      (by
        rintro ⟨x, hx⟩ ⟨y, hy⟩ h
        cases' x with _ x; · simp at hx
        cases' x with _ x; · simp at hx
        cases' x with _ x; swap
        · exfalso
          simp at hx
        cases' y with _ y; · simp at hy
        cases' y with _ y; · simp at hy
        cases' y with _ y; swap
        · exfalso
          simp at hy
        rcases perm_card_two_iff.mp h with (⟨rfl, rfl⟩ | ⟨rfl, rfl⟩)
        · constructor
        apply Sym2.Rel.swap)
  left_inv := by apply Sym2.ind; aesop (add norm unfold [Sym2.fromVector])
  right_inv x := by
    refine' Quotient.recOnSubsingleton x fun x => _
    · cases' x with x hx
      cases' x with _ x
      · simp at hx
      cases' x with _ x
      · simp at hx
      cases' x with _ x
      swap
      · exfalso
        

Proof state:
case mk.cons.cons.cons.h
α : Type u_1
β : Type u_2
γ : Type u_3
e : Sym2 α
f : α → β
x✝ : Sym' α 2
head✝² head✝¹ head✝ : α
x : List α
hx : List.length (head✝² :: head✝¹ :: head✝ :: x) = 2
⊢ False

Next tactic:
simp at hx
/-- The symmetric square is equivalent to length-2 vectors up to permutations.
-/
def sym2EquivSym' : Equiv (Sym2 α) (Sym' α 2)
    where
  toFun :=
    Quotient.map (fun x : α × α => ⟨[x.1, x.2], rfl⟩)
      (by
        rintro _ _ ⟨_⟩
        · constructor; apply List.Perm.refl
        apply List.Perm.swap'
        rfl)
  invFun :=
    Quotient.map fromVector
      (by
        rintro ⟨x, hx⟩ ⟨y, hy⟩ h
        cases' x with _ x; · simp at hx
        cases' x with _ x; · simp at hx
        cases' x with _ x; swap
        · exfalso
          simp at hx
        cases' y with _ y; · simp at hy
        cases' y with _ y; · simp at hy
        cases' y with _ y; swap
        · exfalso
          simp at hy
        rcases perm_card_two_iff.mp h with (⟨rfl, rfl⟩ | ⟨rfl, rfl⟩)
        · constructor
        apply Sym2.Rel.swap)
  left_inv := by apply Sym2.ind; aesop (add norm unfold [Sym2.fromVector])
  right_inv x := by
    refine' Quotient.recOnSubsingleton x fun x => _
    · cases' x with x hx
      cases' x with _ x
      · simp at hx
      cases' x with _ x
      · simp at hx
      cases' x with _ x
      swap
      · exfalso
        simp at hx
      

Proof state:
case mk.cons.cons.nil
α : Type u_1
β : Type u_2
γ : Type u_3
e : Sym2 α
f : α → β
x : Sym' α 2
head✝¹ head✝ : α
hx : List.length [head✝¹, head✝] = 2
⊢ Quotient.map (fun x => { val := [x.1, x.2], property := (_ : List.length [x.1, x.2] = List.length [x.1, x.2]) })
      (_ :
        ∀ ⦃a b : α × α⦄,
          a ≈ b →
            (fun x => { val := [x.1, x.2], property := (_ : List.length [x.1, x.2] = List.length [x.1, x.2]) }) a ≈
              (fun x => { val := [x.1, x.2], property := (_ : List.length [x.1, x.2] = List.length [x.1, x.2]) }) b)
      (Quotient.map Sym2.fromVector
        (_ :
          ∀ ⦃a b : Vector α 2⦄,
            (fun x x_1 => x ≈ x_1) a b → (fun x x_1 => x ≈ x_1) (Sym2.fromVector a) (Sym2.fromVector b))
        ⟦{ val := [head✝¹, head✝], property := hx }⟧) =
    ⟦{ val := [head✝¹, head✝], property := hx }⟧

Next tactic:
rfl
/-- Get the other element of the unordered pair using the decidable equality.
This is the computable version of `Mem.other`.
-/
@[aesop norm unfold (rule_sets [Sym2])]
def Mem.other' [DecidableEq α] {a : α} {z : Sym2 α} (h : a ∈ z) : α :=
  Quotient.rec (fun s _ => pairOther a s) (by
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
e : Sym2 α
f : α → β
inst✝ : DecidableEq α
a : α
z : Sym2 α
h : a ∈ z
⊢ ∀ (a_1 b : α × α) (p : a_1 ≈ b),
    Eq.ndrec (motive := fun x => a ∈ x → α) (fun x => Sym2.pairOther a a_1) (_ : ⟦a_1⟧ = ⟦b⟧) = fun x =>
      Sym2.pairOther a b

Next tactic:
clear h z
/-- Get the other element of the unordered pair using the decidable equality.
This is the computable version of `Mem.other`.
-/
@[aesop norm unfold (rule_sets [Sym2])]
def Mem.other' [DecidableEq α] {a : α} {z : Sym2 α} (h : a ∈ z) : α :=
  Quotient.rec (fun s _ => pairOther a s) (by
    clear h z
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
e : Sym2 α
f : α → β
inst✝ : DecidableEq α
a : α
⊢ ∀ (a_1 b : α × α) (p : a_1 ≈ b),
    Eq.ndrec (motive := fun x => a ∈ x → α) (fun x => Sym2.pairOther a a_1) (_ : ⟦a_1⟧ = ⟦b⟧) = fun x =>
      Sym2.pairOther a b

Next tactic:
intro x y h
/-- Get the other element of the unordered pair using the decidable equality.
This is the computable version of `Mem.other`.
-/
@[aesop norm unfold (rule_sets [Sym2])]
def Mem.other' [DecidableEq α] {a : α} {z : Sym2 α} (h : a ∈ z) : α :=
  Quotient.rec (fun s _ => pairOther a s) (by
    clear h z
    intro x y h
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
e : Sym2 α
f : α → β
inst✝ : DecidableEq α
a : α
x y : α × α
h : x ≈ y
⊢ Eq.ndrec (motive := fun x => a ∈ x → α) (fun x_1 => Sym2.pairOther a x) (_ : ⟦x⟧ = ⟦y⟧) = fun x => Sym2.pairOther a y

Next tactic:
ext hy
/-- Get the other element of the unordered pair using the decidable equality.
This is the computable version of `Mem.other`.
-/
@[aesop norm unfold (rule_sets [Sym2])]
def Mem.other' [DecidableEq α] {a : α} {z : Sym2 α} (h : a ∈ z) : α :=
  Quotient.rec (fun s _ => pairOther a s) (by
    clear h z
    intro x y h
    ext hy
    

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
e : Sym2 α
f : α → β
inst✝ : DecidableEq α
a : α
x y : α × α
h : x ≈ y
hy : a ∈ ⟦y⟧
⊢ Eq.ndrec (motive := fun x => a ∈ x → α) (fun x_1 => Sym2.pairOther a x) (_ : ⟦x⟧ = ⟦y⟧) hy = Sym2.pairOther a y

Next tactic:
convert_to Sym2.pairOther a x = _
/-- Get the other element of the unordered pair using the decidable equality.
This is the computable version of `Mem.other`.
-/
@[aesop norm unfold (rule_sets [Sym2])]
def Mem.other' [DecidableEq α] {a : α} {z : Sym2 α} (h : a ∈ z) : α :=
  Quotient.rec (fun s _ => pairOther a s) (by
    clear h z
    intro x y h
    ext hy
    convert_to Sym2.pairOther a x = _
    · 

Proof state:
case h.e'_2
α : Type u_1
β : Type u_2
γ : Type u_3
e : Sym2 α
f : α → β
inst✝ : DecidableEq α
a : α
x y : α × α
h : x ≈ y
hy : a ∈ ⟦y⟧
⊢ Eq.ndrec (motive := fun x => a ∈ x → α) (fun x_1 => Sym2.pairOther a x) (_ : ⟦x⟧ = ⟦y⟧) hy = Sym2.pairOther a x

Next tactic:
have : ∀ {c e h}, @Eq.ndrec (Quotient (Rel.setoid α)) (Quotient.mk (Rel.setoid α) x)
          (fun x => a ∈ x → α) (fun _ => Sym2.pairOther a x) c e h = Sym2.pairOther a x := by
          intro _ e _; subst e; rfl
/-- Get the other element of the unordered pair using the decidable equality.
This is the computable version of `Mem.other`.
-/
@[aesop norm unfold (rule_sets [Sym2])]
def Mem.other' [DecidableEq α] {a : α} {z : Sym2 α} (h : a ∈ z) : α :=
  Quotient.rec (fun s _ => pairOther a s) (by
    clear h z
    intro x y h
    ext hy
    convert_to Sym2.pairOther a x = _
    · have : ∀ {c e h}, @Eq.ndrec (Quotient (Rel.setoid α)) (Quotient.mk (Rel.setoid α) x)
          (fun x => a ∈ x → α) (fun _ => Sym2.pairOther a x) c e h = Sym2.pairOther a x := by
          

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
e : Sym2 α
f : α → β
inst✝ : DecidableEq α
a : α
x y : α × α
h : x ≈ y
hy : a ∈ ⟦y⟧
⊢ ∀ {c : Quotient (Rel.setoid α)} {e : ⟦x⟧ = c} {h : a ∈ c},
    Eq.ndrec (motive := fun x => a ∈ x → α) (fun x_1 => Sym2.pairOther a x) e h = Sym2.pairOther a x

Next tactic:
intro _ e _
/-- Get the other element of the unordered pair using the decidable equality.
This is the computable version of `Mem.other`.
-/
@[aesop norm unfold (rule_sets [Sym2])]
def Mem.other' [DecidableEq α] {a : α} {z : Sym2 α} (h : a ∈ z) : α :=
  Quotient.rec (fun s _ => pairOther a s) (by
    clear h z
    intro x y h
    ext hy
    convert_to Sym2.pairOther a x = _
    · have : ∀ {c e h}, @Eq.ndrec (Quotient (Rel.setoid α)) (Quotient.mk (Rel.setoid α) x)
          (fun x => a ∈ x → α) (fun _ => Sym2.pairOther a x) c e h = Sym2.pairOther a x := by
          intro _ e _; 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
e✝ : Sym2 α
f : α → β
inst✝ : DecidableEq α
a : α
x y : α × α
h : x ≈ y
hy : a ∈ ⟦y⟧
c✝ : Quotient (Rel.setoid α)
e : ⟦x⟧ = c✝
h✝ : a ∈ c✝
⊢ Eq.ndrec (motive := fun x => a ∈ x → α) (fun x_1 => Sym2.pairOther a x) e h✝ = Sym2.pairOther a x

Next tactic:
subst e
/-- Get the other element of the unordered pair using the decidable equality.
This is the computable version of `Mem.other`.
-/
@[aesop norm unfold (rule_sets [Sym2])]
def Mem.other' [DecidableEq α] {a : α} {z : Sym2 α} (h : a ∈ z) : α :=
  Quotient.rec (fun s _ => pairOther a s) (by
    clear h z
    intro x y h
    ext hy
    convert_to Sym2.pairOther a x = _
    · have : ∀ {c e h}, @Eq.ndrec (Quotient (Rel.setoid α)) (Quotient.mk (Rel.setoid α) x)
          (fun x => a ∈ x → α) (fun _ => Sym2.pairOther a x) c e h = Sym2.pairOther a x := by
          intro _ e _; subst e; 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
e : Sym2 α
f : α → β
inst✝ : DecidableEq α
a : α
x y : α × α
h : x ≈ y
hy : a ∈ ⟦y⟧
h✝ : a ∈ ⟦x⟧
⊢ Eq.ndrec (motive := fun x => a ∈ x → α) (fun x_1 => Sym2.pairOther a x) (_ : ⟦x⟧ = ⟦x⟧) h✝ = Sym2.pairOther a x

Next tactic:
rfl
/-- Get the other element of the unordered pair using the decidable equality.
This is the computable version of `Mem.other`.
-/
@[aesop norm unfold (rule_sets [Sym2])]
def Mem.other' [DecidableEq α] {a : α} {z : Sym2 α} (h : a ∈ z) : α :=
  Quotient.rec (fun s _ => pairOther a s) (by
    clear h z
    intro x y h
    ext hy
    convert_to Sym2.pairOther a x = _
    · have : ∀ {c e h}, @Eq.ndrec (Quotient (Rel.setoid α)) (Quotient.mk (Rel.setoid α) x)
          (fun x => a ∈ x → α) (fun _ => Sym2.pairOther a x) c e h = Sym2.pairOther a x := by
          intro _ e _; subst e; rfl
      

Proof state:
case h.e'_2
α : Type u_1
β : Type u_2
γ : Type u_3
e : Sym2 α
f : α → β
inst✝ : DecidableEq α
a : α
x y : α × α
h : x ≈ y
hy : a ∈ ⟦y⟧
this :
  ∀ {c : Quotient (Rel.setoid α)} {e : ⟦x⟧ = c} {h : a ∈ c},
    Eq.ndrec (motive := fun x => a ∈ x → α) (fun x_1 => Sym2.pairOther a x) e h = Sym2.pairOther a x
⊢ Eq.ndrec (motive := fun x => a ∈ x → α) (fun x_1 => Sym2.pairOther a x) (_ : ⟦x⟧ = ⟦y⟧) hy = Sym2.pairOther a x

Next tactic:
apply this
/-- Get the other element of the unordered pair using the decidable equality.
This is the computable version of `Mem.other`.
-/
@[aesop norm unfold (rule_sets [Sym2])]
def Mem.other' [DecidableEq α] {a : α} {z : Sym2 α} (h : a ∈ z) : α :=
  Quotient.rec (fun s _ => pairOther a s) (by
    clear h z
    intro x y h
    ext hy
    convert_to Sym2.pairOther a x = _
    · have : ∀ {c e h}, @Eq.ndrec (Quotient (Rel.setoid α)) (Quotient.mk (Rel.setoid α) x)
          (fun x => a ∈ x → α) (fun _ => Sym2.pairOther a x) c e h = Sym2.pairOther a x := by
          intro _ e _; subst e; rfl
      apply this
    · 

Proof state:
case h.convert_2
α : Type u_1
β : Type u_2
γ : Type u_3
e : Sym2 α
f : α → β
inst✝ : DecidableEq α
a : α
x y : α × α
h : x ≈ y
hy : a ∈ ⟦y⟧
⊢ Sym2.pairOther a x = Sym2.pairOther a y

Next tactic:
rw [mem_iff] at hy
/-- Get the other element of the unordered pair using the decidable equality.
This is the computable version of `Mem.other`.
-/
@[aesop norm unfold (rule_sets [Sym2])]
def Mem.other' [DecidableEq α] {a : α} {z : Sym2 α} (h : a ∈ z) : α :=
  Quotient.rec (fun s _ => pairOther a s) (by
    clear h z
    intro x y h
    ext hy
    convert_to Sym2.pairOther a x = _
    · have : ∀ {c e h}, @Eq.ndrec (Quotient (Rel.setoid α)) (Quotient.mk (Rel.setoid α) x)
          (fun x => a ∈ x → α) (fun _ => Sym2.pairOther a x) c e h = Sym2.pairOther a x := by
          intro _ e _; subst e; rfl
      apply this
    · rw [mem_iff] at hy
      

Proof state:
case h.convert_2
α : Type u_1
β : Type u_2
γ : Type u_3
e : Sym2 α
f : α → β
inst✝ : DecidableEq α
a : α
x y : α × α
h : x ≈ y
hy : a = y.1 ∨ a = y.2
⊢ Sym2.pairOther a x = Sym2.pairOther a y

Next tactic:
aesop (add norm unfold [pairOther])
@[simp]
theorem other_spec' [DecidableEq α] {a : α} {z : Sym2 α} (h : a ∈ z) : ⟦(a, Mem.other' h)⟧ = z := by
  

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

Next tactic:
induction z using Sym2.ind
@[simp]
theorem other_spec' [DecidableEq α] {a : α} {z : Sym2 α} (h : a ∈ z) : ⟦(a, Mem.other' h)⟧ = z := by
  induction z using Sym2.ind
  

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
e : Sym2 α
f : α → β
inst✝ : DecidableEq α
a x✝ y✝ : α
h : a ∈ ⟦(x✝, y✝)⟧
⊢ ⟦(a, Mem.other' h)⟧ = ⟦(x✝, y✝)⟧

Next tactic:
have h' := mem_iff.mp h
@[simp]
theorem other_spec' [DecidableEq α] {a : α} {z : Sym2 α} (h : a ∈ z) : ⟦(a, Mem.other' h)⟧ = z := by
  induction z using Sym2.ind
  have h' := mem_iff.mp h
  

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
e : Sym2 α
f : α → β
inst✝ : DecidableEq α
a x✝ y✝ : α
h : a ∈ ⟦(x✝, y✝)⟧
h' : a = x✝ ∨ a = y✝
⊢ ⟦(a, Mem.other' h)⟧ = ⟦(x✝, y✝)⟧

Next tactic:
aesop (add norm unfold [Quotient.rec, Quot.rec]) (rule_sets [Sym2])
@[simp]
theorem other_eq_other' [DecidableEq α] {a : α} {z : Sym2 α} (h : a ∈ z) :
    Mem.other h = Mem.other' h := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
e : Sym2 α
f : α → β
inst✝ : DecidableEq α
a : α
z : Sym2 α
h : a ∈ z
⊢ Mem.other h = Mem.other' h

Next tactic:
rw [← congr_right, other_spec' h, other_spec]
theorem other_mem' [DecidableEq α] {a : α} {z : Sym2 α} (h : a ∈ z) : Mem.other' h ∈ z := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
e : Sym2 α
f : α → β
inst✝ : DecidableEq α
a : α
z : Sym2 α
h : a ∈ z
⊢ Mem.other' h ∈ z

Next tactic:
rw [← other_eq_other']
theorem other_mem' [DecidableEq α] {a : α} {z : Sym2 α} (h : a ∈ z) : Mem.other' h ∈ z := by
  rw [← other_eq_other']
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
e : Sym2 α
f : α → β
inst✝ : DecidableEq α
a : α
z : Sym2 α
h : a ∈ z
⊢ Mem.other h ∈ z

Next tactic:
exact other_mem h
theorem other_invol' [DecidableEq α] {a : α} {z : Sym2 α} (ha : a ∈ z) (hb : Mem.other' ha ∈ z) :
    Mem.other' hb = a := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
e : Sym2 α
f : α → β
inst✝ : DecidableEq α
a : α
z : Sym2 α
ha : a ∈ z
hb : Mem.other' ha ∈ z
⊢ Mem.other' hb = a

Next tactic:
induction z using Sym2.ind
theorem other_invol' [DecidableEq α] {a : α} {z : Sym2 α} (ha : a ∈ z) (hb : Mem.other' ha ∈ z) :
    Mem.other' hb = a := by
  induction z using Sym2.ind
  

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
e : Sym2 α
f : α → β
inst✝ : DecidableEq α
a x✝ y✝ : α
ha : a ∈ ⟦(x✝, y✝)⟧
hb : Mem.other' ha ∈ ⟦(x✝, y✝)⟧
⊢ Mem.other' hb = a

Next tactic:
aesop (rule_sets [Sym2]) (add norm unfold [Quotient.rec, Quot.rec])
theorem other_invol {a : α} {z : Sym2 α} (ha : a ∈ z) (hb : Mem.other ha ∈ z) : Mem.other hb = a :=
  by 

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

Next tactic:
classical
    rw [other_eq_other'] at hb ⊢
    convert other_invol' ha hb using 2
    apply other_eq_other'
theorem other_invol {a : α} {z : Sym2 α} (ha : a ∈ z) (hb : Mem.other ha ∈ z) : Mem.other hb = a :=
  by classical
    

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

Next tactic:
rw [other_eq_other'] at hb ⊢