l3lab/ntp-mathlib huggingface dataset:
/-- A product of types can be split as the binary product of one of the types and the product
  of all the remaining types. -/
@[simps]
def piSplitAt {α : Type*} [DecidableEq α] (i : α) (β : α → Type*) :
    (∀ j, β j) ≃ β i × ∀ j : { j // j ≠ i }, β j where
  toFun f := ⟨f i, fun j => f j⟩
  invFun f j := if h : j = i then h.symm.rec f.1 else f.2 ⟨j, h⟩
  right_inv f := by
    ext x
    exacts [dif_pos rfl, (dif_neg x.2).trans (by cases x; rfl)]
  left_inv f := by
    ext x
    dsimp only
    split_ifs with h
    · subst h; 

Proof state:
case pos
α : Type u_1
inst✝ : DecidableEq α
β : α → Type u_2
f : (j : α) → β j
x : α
⊢ (_ : x = x) ▸ f x = f x

Next tactic:
rfl
/-- A product of types can be split as the binary product of one of the types and the product
  of all the remaining types. -/
@[simps]
def piSplitAt {α : Type*} [DecidableEq α] (i : α) (β : α → Type*) :
    (∀ j, β j) ≃ β i × ∀ j : { j // j ≠ i }, β j where
  toFun f := ⟨f i, fun j => f j⟩
  invFun f j := if h : j = i then h.symm.rec f.1 else f.2 ⟨j, h⟩
  right_inv f := by
    ext x
    exacts [dif_pos rfl, (dif_neg x.2).trans (by cases x; rfl)]
  left_inv f := by
    ext x
    dsimp only
    split_ifs with h
    · subst h; rfl
    · 

Proof state:
case neg
α : Type u_1
inst✝ : DecidableEq α
i : α
β : α → Type u_2
f : (j : α) → β j
x : α
h : ¬x = i
⊢ f x = f x

Next tactic:
rfl
/-- A product of types can be split as the binary product of one of the types and the product
  of all the remaining types. -/
@[simps]
def piSplitAt {α : Type*} [DecidableEq α] (i : α) (β : α → Type*) :
    (∀ j, β j) ≃ β i × ∀ j : { j // j ≠ i }, β j where
  toFun f := ⟨f i, fun j => f j⟩
  invFun f j := if h : j = i then h.symm.rec f.1 else f.2 ⟨j, h⟩
  right_inv f := by
    

Proof state:
α : Type u_1
inst✝ : DecidableEq α
i : α
β : α → Type u_2
f : β i × ((j : { j // j ≠ i }) → β ↑j)
⊢ (fun f => (f i, fun j => f ↑j))
      ((fun f j => if h : j = i then (_ : i = j) ▸ f.1 else f.2 { val := j, property := h }) f) =
    f

Next tactic:
ext x
/-- A product of types can be split as the binary product of one of the types and the product
  of all the remaining types. -/
@[simps]
def piSplitAt {α : Type*} [DecidableEq α] (i : α) (β : α → Type*) :
    (∀ j, β j) ≃ β i × ∀ j : { j // j ≠ i }, β j where
  toFun f := ⟨f i, fun j => f j⟩
  invFun f j := if h : j = i then h.symm.rec f.1 else f.2 ⟨j, h⟩
  right_inv f := by
    ext x
    

Proof state:
case a
α : Type u_1
inst✝ : DecidableEq α
i : α
β : α → Type u_2
f : β i × ((j : { j // j ≠ i }) → β ↑j)
⊢ ((fun f => (f i, fun j => f ↑j))
        ((fun f j => if h : j = i then (_ : i = j) ▸ f.1 else f.2 { val := j, property := h }) f)).1 =
    f.1
case a.h
α : Type u_1
inst✝ : DecidableEq α
i : α
β : α → Type u_2
f : β i × ((j : { j // j ≠ i }) → β ↑j)
x : { j // j ≠ i }
⊢ ((fun f => (f i, fun j => f ↑j))
          ((fun f j => if h : j = i then (_ : i = j) ▸ f.1 else f.2 { val := j, property := h }) f)).2
      x =
    f.2 x

Next tactic:
exacts [dif_pos rfl, (dif_neg x.2).trans (by cases x; rfl)]
/-- A product of types can be split as the binary product of one of the types and the product
  of all the remaining types. -/
@[simps]
def piSplitAt {α : Type*} [DecidableEq α] (i : α) (β : α → Type*) :
    (∀ j, β j) ≃ β i × ∀ j : { j // j ≠ i }, β j where
  toFun f := ⟨f i, fun j => f j⟩
  invFun f j := if h : j = i then h.symm.rec f.1 else f.2 ⟨j, h⟩
  right_inv f := by
    ext x
    exacts [dif_pos rfl, (dif_neg x.2).trans (by 

Proof state:
α : Type u_1
inst✝ : DecidableEq α
i : α
β : α → Type u_2
f : β i × ((j : { j // j ≠ i }) → β ↑j)
x : { j // j ≠ i }
⊢ (fun h => f.2 { val := ↑x, property := h }) (_ : ↑x ≠ i) = f.2 x

Next tactic:
cases x
/-- A product of types can be split as the binary product of one of the types and the product
  of all the remaining types. -/
@[simps]
def piSplitAt {α : Type*} [DecidableEq α] (i : α) (β : α → Type*) :
    (∀ j, β j) ≃ β i × ∀ j : { j // j ≠ i }, β j where
  toFun f := ⟨f i, fun j => f j⟩
  invFun f j := if h : j = i then h.symm.rec f.1 else f.2 ⟨j, h⟩
  right_inv f := by
    ext x
    exacts [dif_pos rfl, (dif_neg x.2).trans (by cases x; 

Proof state:
case mk
α : Type u_1
inst✝ : DecidableEq α
i : α
β : α → Type u_2
f : β i × ((j : { j // j ≠ i }) → β ↑j)
val✝ : α
property✝ : val✝ ≠ i
⊢ (fun h => f.2 { val := ↑{ val := val✝, property := property✝ }, property := h })
      (_ : ↑{ val := val✝, property := property✝ } ≠ i) =
    f.2 { val := val✝, property := property✝ }

Next tactic:
rfl
theorem coe_subtypeEquivCodomain_symm (f : { x' // x' ≠ x } → Y) :
    ((subtypeEquivCodomain f).symm : Y → _) = fun y =>
      ⟨fun x' => if h : x' ≠ x then f ⟨x', h⟩ else y, by
        

Proof state:
X : Sort ?u.87457
inst✝ : DecidableEq X
x : X
Y : Sort ?u.87493
f : { x' // x' ≠ x } → Y
y : Y
⊢ (fun x' => if h : x' ≠ x then f { val := x', property := h } else y) ∘ Subtype.val = f

Next tactic:
funext x'
theorem coe_subtypeEquivCodomain_symm (f : { x' // x' ≠ x } → Y) :
    ((subtypeEquivCodomain f).symm : Y → _) = fun y =>
      ⟨fun x' => if h : x' ≠ x then f ⟨x', h⟩ else y, by
        funext x'
        

Proof state:
case h
X : Sort ?u.87457
inst✝ : DecidableEq X
x : X
Y : Sort ?u.87493
f : { x' // x' ≠ x } → Y
y : Y
x' : { x' // x' ≠ x }
⊢ ((fun x' => if h : x' ≠ x then f { val := x', property := h } else y) ∘ Subtype.val) x' = f x'

Next tactic:
simp only [ne_eq, dite_not, comp_apply, Subtype.coe_eta, dite_eq_ite, ite_eq_right_iff]
theorem coe_subtypeEquivCodomain_symm (f : { x' // x' ≠ x } → Y) :
    ((subtypeEquivCodomain f).symm : Y → _) = fun y =>
      ⟨fun x' => if h : x' ≠ x then f ⟨x', h⟩ else y, by
        funext x'
        simp only [ne_eq, dite_not, comp_apply, Subtype.coe_eta, dite_eq_ite, ite_eq_right_iff]
        

Proof state:
case h
X : Sort ?u.87457
inst✝ : DecidableEq X
x : X
Y : Sort ?u.87493
f : { x' // x' ≠ x } → Y
y : Y
x' : { x' // x' ≠ x }
⊢ ↑x' = x → y = f x'

Next tactic:
intro w
theorem coe_subtypeEquivCodomain_symm (f : { x' // x' ≠ x } → Y) :
    ((subtypeEquivCodomain f).symm : Y → _) = fun y =>
      ⟨fun x' => if h : x' ≠ x then f ⟨x', h⟩ else y, by
        funext x'
        simp only [ne_eq, dite_not, comp_apply, Subtype.coe_eta, dite_eq_ite, ite_eq_right_iff]
        intro w
        

Proof state:
case h
X : Sort ?u.87457
inst✝ : DecidableEq X
x : X
Y : Sort ?u.87493
f : { x' // x' ≠ x } → Y
y : Y
x' : { x' // x' ≠ x }
w : ↑x' = x
⊢ y = f x'

Next tactic:
exfalso
theorem coe_subtypeEquivCodomain_symm (f : { x' // x' ≠ x } → Y) :
    ((subtypeEquivCodomain f).symm : Y → _) = fun y =>
      ⟨fun x' => if h : x' ≠ x then f ⟨x', h⟩ else y, by
        funext x'
        simp only [ne_eq, dite_not, comp_apply, Subtype.coe_eta, dite_eq_ite, ite_eq_right_iff]
        intro w
        exfalso
        

Proof state:
case h.h
X : Sort ?u.87457
inst✝ : DecidableEq X
x : X
Y : Sort ?u.87493
f : { x' // x' ≠ x } → Y
y : Y
x' : { x' // x' ≠ x }
w : ↑x' = x
⊢ False

Next tactic:
exact x'.property w
@[simp]
theorem Perm.extendDomain_apply_image (a : α') : e.extendDomain f (f a) = f (e a) := by
  

Proof state:
α' : Type u_1
β' : Type u_2
e : Perm α'
p : β' → Prop
inst✝ : DecidablePred p
f : α' ≃ Subtype p
a : α'
⊢ (extendDomain e f) ↑(f a) = ↑(f (e a))

Next tactic:
simp [Perm.extendDomain]
theorem Perm.extendDomain_apply_subtype {b : β'} (h : p b) :
    e.extendDomain f b = f (e (f.symm ⟨b, h⟩)) := by
  

Proof state:
α' : Type u_1
β' : Type u_2
e : Perm α'
p : β' → Prop
inst✝ : DecidablePred p
f : α' ≃ Subtype p
b : β'
h : p b
⊢ (extendDomain e f) b = ↑(f (e (f.symm { val := b, property := h })))

Next tactic:
simp [Perm.extendDomain, h]
theorem Perm.extendDomain_apply_not_subtype {b : β'} (h : ¬p b) : e.extendDomain f b = b := by
  

Proof state:
α' : Type u_1
β' : Type u_2
e : Perm α'
p : β' → Prop
inst✝ : DecidablePred p
f : α' ≃ Subtype p
b : β'
h : ¬p b
⊢ (extendDomain e f) b = b

Next tactic:
simp [Perm.extendDomain, h]
@[simp]
theorem Perm.extendDomain_refl : Perm.extendDomain (Equiv.refl _) f = Equiv.refl _ := by
  

Proof state:
α' : Type u_1
β' : Type u_2
e : Perm α'
p : β' → Prop
inst✝ : DecidablePred p
f : α' ≃ Subtype p
⊢ extendDomain (Equiv.refl α') f = Equiv.refl β'

Next tactic:
simp [Perm.extendDomain]
theorem Perm.extendDomain_trans (e e' : Perm α') :
    (e.extendDomain f).trans (e'.extendDomain f) = Perm.extendDomain (e.trans e') f := by
  

Proof state:
α' : Type u_1
β' : Type u_2
e✝ : Perm α'
p : β' → Prop
inst✝ : DecidablePred p
f : α' ≃ Subtype p
e e' : Perm α'
⊢ (extendDomain e f).trans (extendDomain e' f) = extendDomain (e.trans e') f

Next tactic:
simp [Perm.extendDomain, permCongr_trans]
/-- Subtype of the quotient is equivalent to the quotient of the subtype. Let `α` be a setoid with
equivalence relation `~`. Let `p₂` be a predicate on the quotient type `α/~`, and `p₁` be the lift
of this predicate to `α`: `p₁ a ↔ p₂ ⟦a⟧`. Let `~₂` be the restriction of `~` to `{x // p₁ x}`.
Then `{x // p₂ x}` is equivalent to the quotient of `{x // p₁ x}` by `~₂`. -/
def subtypeQuotientEquivQuotientSubtype (p₁ : α → Prop) [s₁ : Setoid α] [s₂ : Setoid (Subtype p₁)]
    (p₂ : Quotient s₁ → Prop) (hp₂ : ∀ a, p₁ a ↔ p₂ ⟦a⟧)
    (h : ∀ x y : Subtype p₁, @Setoid.r _ s₂ x y ↔ (x : α) ≈ y) :
    { x // p₂ x } ≃ Quotient s₂ where
  toFun a :=
    Quotient.hrecOn a.1 (fun a h => ⟦⟨a, (hp₂ _).2 h⟩⟧)
      (fun a b hab => hfunext (by 

Proof state:
α : Sort ?u.94967
p₁ : α → Prop
s₁ : Setoid α
s₂ : Setoid (Subtype p₁)
p₂ : Quotient s₁ → Prop
hp₂ : ∀ (a : α), p₁ a ↔ p₂ ⟦a⟧
h : ∀ (x y : Subtype p₁), Setoid.r x y ↔ ↑x ≈ ↑y
a✝ : { x // p₂ x }
a b : α
hab : a ≈ b
⊢ p₂ ⟦a⟧ = p₂ ⟦b⟧

Next tactic:
rw [Quotient.sound hab]
/-- Subtype of the quotient is equivalent to the quotient of the subtype. Let `α` be a setoid with
equivalence relation `~`. Let `p₂` be a predicate on the quotient type `α/~`, and `p₁` be the lift
of this predicate to `α`: `p₁ a ↔ p₂ ⟦a⟧`. Let `~₂` be the restriction of `~` to `{x // p₁ x}`.
Then `{x // p₂ x}` is equivalent to the quotient of `{x // p₁ x}` by `~₂`. -/
def subtypeQuotientEquivQuotientSubtype (p₁ : α → Prop) [s₁ : Setoid α] [s₂ : Setoid (Subtype p₁)]
    (p₂ : Quotient s₁ → Prop) (hp₂ : ∀ a, p₁ a ↔ p₂ ⟦a⟧)
    (h : ∀ x y : Subtype p₁, @Setoid.r _ s₂ x y ↔ (x : α) ≈ y) :
    { x // p₂ x } ≃ Quotient s₂ where
  toFun a :=
    Quotient.hrecOn a.1 (fun a h => ⟦⟨a, (hp₂ _).2 h⟩⟧)
      (fun a b hab => hfunext (by rw [Quotient.sound hab]) fun h₁ h₂ _ =>
        heq_of_eq (Quotient.sound ((h _ _).2 hab)))
      a.2
  invFun a :=
    Quotient.liftOn a (fun a => (⟨⟦a.1⟧, (hp₂ _).1 a.2⟩ : { x // p₂ x })) fun a b hab =>
      Subtype.ext_val (Quotient.sound ((h _ _).1 hab))
  left_inv := by 

Proof state:
α : Sort ?u.94967
p₁ : α → Prop
s₁ : Setoid α
s₂ : Setoid (Subtype p₁)
p₂ : Quotient s₁ → Prop
hp₂ : ∀ (a : α), p₁ a ↔ p₂ ⟦a⟧
h : ∀ (x y : Subtype p₁), Setoid.r x y ↔ ↑x ≈ ↑y
⊢ LeftInverse
    (fun a =>
      Quotient.liftOn a (fun a => { val := ⟦↑a⟧, property := (_ : p₂ ⟦↑a⟧) })
        (_ :
          ∀ (a b : Subtype p₁),
            a ≈ b →
              (fun a => { val := ⟦↑a⟧, property := (_ : p₂ ⟦↑a⟧) }) a =
                (fun a => { val := ⟦↑a⟧, property := (_ : p₂ ⟦↑a⟧) }) b))
    fun a =>
    Quotient.hrecOn (motive := fun x => p₂ x → Quotient s₂) (↑a) (fun a h => ⟦{ val := a, property := (_ : p₁ a) }⟧)
      (_ : ∀ (a_1 b : α), a_1 ≈ b → HEq (?m.95316 a a_1) (?m.95317 a b)) (_ : p₂ ↑a)

Next tactic:
exact fun ⟨a, ha⟩ => Quotient.inductionOn a (fun b hb => rfl) ha
theorem swapCore_self (r a : α) : swapCore a a r = r := by
  

Proof state:
α : Sort u_1
inst✝ : DecidableEq α
r a : α
⊢ swapCore a a r = r

Next tactic:
unfold swapCore
theorem swapCore_self (r a : α) : swapCore a a r = r := by
  unfold swapCore
  

Proof state:
α : Sort u_1
inst✝ : DecidableEq α
r a : α
⊢ (if r = a then a else if r = a then a else r) = r

Next tactic:
split_ifs
theorem swapCore_self (r a : α) : swapCore a a r = r := by
  unfold swapCore
  split_ifs <;> 

Proof state:
case pos
α : Sort u_1
inst✝ : DecidableEq α
r a : α
h✝ : r = a
⊢ a = r

Next tactic:
simp [*]
theorem swapCore_self (r a : α) : swapCore a a r = r := by
  unfold swapCore
  split_ifs <;> 

Proof state:
case neg
α : Sort u_1
inst✝ : DecidableEq α
r a : α
h✝ : ¬r = a
⊢ r = r

Next tactic:
simp [*]
theorem swapCore_swapCore (r a b : α) : swapCore a b (swapCore a b r) = r := by
  

Proof state:
α : Sort u_1
inst✝ : DecidableEq α
r a b : α
⊢ swapCore a b (swapCore a b r) = r

Next tactic:
unfold swapCore
theorem swapCore_swapCore (r a b : α) : swapCore a b (swapCore a b r) = r := by
  unfold swapCore
  -- Porting note: cc missing.
  -- `casesm` would work here, with `casesm _ = _, ¬ _ = _`,
  -- if it would just continue past failures on hypotheses matching the pattern
  

Proof state:
α : Sort u_1
inst✝ : DecidableEq α
r a b : α
⊢ (if (if r = a then b else if r = b then a else r) = a then b
    else if (if r = a then b else if r = b then a else r) = b then a else if r = a then b else if r = b then a else r) =
    r

Next tactic:
split_ifs with h₁ h₂ h₃ h₄ h₅
theorem swapCore_swapCore (r a b : α) : swapCore a b (swapCore a b r) = r := by
  unfold swapCore
  -- Porting note: cc missing.
  -- `casesm` would work here, with `casesm _ = _, ¬ _ = _`,
  -- if it would just continue past failures on hypotheses matching the pattern
  split_ifs with h₁ h₂ h₃ h₄ h₅
  · 

Proof state:
case pos
α : Sort u_1
inst✝ : DecidableEq α
r a b : α
h₁ : r = a
h₂ : b = a
⊢ b = r

Next tactic:
subst h₁
theorem swapCore_swapCore (r a b : α) : swapCore a b (swapCore a b r) = r := by
  unfold swapCore
  -- Porting note: cc missing.
  -- `casesm` would work here, with `casesm _ = _, ¬ _ = _`,
  -- if it would just continue past failures on hypotheses matching the pattern
  split_ifs with h₁ h₂ h₃ h₄ h₅
  · subst h₁; 

Proof state:
case pos
α : Sort u_1
inst✝ : DecidableEq α
r b : α
h₂ : b = r
⊢ b = r

Next tactic:
exact h₂
theorem swapCore_swapCore (r a b : α) : swapCore a b (swapCore a b r) = r := by
  unfold swapCore
  -- Porting note: cc missing.
  -- `casesm` would work here, with `casesm _ = _, ¬ _ = _`,
  -- if it would just continue past failures on hypotheses matching the pattern
  split_ifs with h₁ h₂ h₃ h₄ h₅
  · subst h₁; exact h₂
  · 

Proof state:
case pos
α : Sort u_1
inst✝ : DecidableEq α
r a b : α
h₁ : r = a
h₂ : ¬b = a
h₃ : b = b
⊢ a = r

Next tactic:
subst h₁
theorem swapCore_swapCore (r a b : α) : swapCore a b (swapCore a b r) = r := by
  unfold swapCore
  -- Porting note: cc missing.
  -- `casesm` would work here, with `casesm _ = _, ¬ _ = _`,
  -- if it would just continue past failures on hypotheses matching the pattern
  split_ifs with h₁ h₂ h₃ h₄ h₅
  · subst h₁; exact h₂
  · subst h₁; 

Proof state:
case pos
α : Sort u_1
inst✝ : DecidableEq α
r b : α
h₃ : b = b
h₂ : ¬b = r
⊢ r = r

Next tactic:
rfl
theorem swapCore_swapCore (r a b : α) : swapCore a b (swapCore a b r) = r := by
  unfold swapCore
  -- Porting note: cc missing.
  -- `casesm` would work here, with `casesm _ = _, ¬ _ = _`,
  -- if it would just continue past failures on hypotheses matching the pattern
  split_ifs with h₁ h₂ h₃ h₄ h₅
  · subst h₁; exact h₂
  · subst h₁; rfl
  · 

Proof state:
case neg
α : Sort u_1
inst✝ : DecidableEq α
r a b : α
h₁ : r = a
h₂ : ¬b = a
h₃ : ¬b = b
⊢ b = r

Next tactic:
cases h₃ rfl
theorem swapCore_swapCore (r a b : α) : swapCore a b (swapCore a b r) = r := by
  unfold swapCore
  -- Porting note: cc missing.
  -- `casesm` would work here, with `casesm _ = _, ¬ _ = _`,
  -- if it would just continue past failures on hypotheses matching the pattern
  split_ifs with h₁ h₂ h₃ h₄ h₅
  · subst h₁; exact h₂
  · subst h₁; rfl
  · cases h₃ rfl
  · 

Proof state:
case pos
α : Sort u_1
inst✝ : DecidableEq α
r a b : α
h₁ : ¬r = a
h₄ : r = b
h₅ : a = a
⊢ b = r

Next tactic:
exact h₄.symm
theorem swapCore_swapCore (r a b : α) : swapCore a b (swapCore a b r) = r := by
  unfold swapCore
  -- Porting note: cc missing.
  -- `casesm` would work here, with `casesm _ = _, ¬ _ = _`,
  -- if it would just continue past failures on hypotheses matching the pattern
  split_ifs with h₁ h₂ h₃ h₄ h₅
  · subst h₁; exact h₂
  · subst h₁; rfl
  · cases h₃ rfl
  · exact h₄.symm
  · 

Proof state:
case pos
α : Sort u_1
inst✝ : DecidableEq α
r a b : α
h₁ : ¬r = a
h₄ : r = b
h₅ : ¬a = a
h✝ : a = b
⊢ a = r

Next tactic:
cases h₅ rfl
theorem swapCore_swapCore (r a b : α) : swapCore a b (swapCore a b r) = r := by
  unfold swapCore
  -- Porting note: cc missing.
  -- `casesm` would work here, with `casesm _ = _, ¬ _ = _`,
  -- if it would just continue past failures on hypotheses matching the pattern
  split_ifs with h₁ h₂ h₃ h₄ h₅
  · subst h₁; exact h₂
  · subst h₁; rfl
  · cases h₃ rfl
  · exact h₄.symm
  · cases h₅ rfl
  · 

Proof state:
case neg
α : Sort u_1
inst✝ : DecidableEq α
r a b : α
h₁ : ¬r = a
h₄ : r = b
h₅ : ¬a = a
h✝ : ¬a = b
⊢ a = r

Next tactic:
cases h₅ rfl
theorem swapCore_swapCore (r a b : α) : swapCore a b (swapCore a b r) = r := by
  unfold swapCore
  -- Porting note: cc missing.
  -- `casesm` would work here, with `casesm _ = _, ¬ _ = _`,
  -- if it would just continue past failures on hypotheses matching the pattern
  split_ifs with h₁ h₂ h₃ h₄ h₅
  · subst h₁; exact h₂
  · subst h₁; rfl
  · cases h₃ rfl
  · exact h₄.symm
  · cases h₅ rfl
  · cases h₅ rfl
  · 

Proof state:
case neg
α : Sort u_1
inst✝ : DecidableEq α
r a b : α
h₁ : ¬r = a
h₄ : ¬r = b
⊢ r = r

Next tactic:
rfl
theorem swapCore_comm (r a b : α) : swapCore a b r = swapCore b a r := by
  

Proof state:
α : Sort u_1
inst✝ : DecidableEq α
r a b : α
⊢ swapCore a b r = swapCore b a r

Next tactic:
unfold swapCore
theorem swapCore_comm (r a b : α) : swapCore a b r = swapCore b a r := by
  unfold swapCore
  -- Porting note: whatever solution works for `swapCore_swapCore` will work here too.
  

Proof state:
α : Sort u_1
inst✝ : DecidableEq α
r a b : α
⊢ (if r = a then b else if r = b then a else r) = if r = b then a else if r = a then b else r

Next tactic:
split_ifs with h₁ h₂ h₃
theorem swapCore_comm (r a b : α) : swapCore a b r = swapCore b a r := by
  unfold swapCore
  -- Porting note: whatever solution works for `swapCore_swapCore` will work here too.
  split_ifs with h₁ h₂ h₃ <;> 

Proof state:
case pos
α : Sort u_1
inst✝ : DecidableEq α
r a b : α
h₁ : r = a
h₂ : r = b
⊢ b = a

Next tactic:
try simp
theorem swapCore_comm (r a b : α) : swapCore a b r = swapCore b a r := by
  unfold swapCore
  -- Porting note: whatever solution works for `swapCore_swapCore` will work here too.
  split_ifs with h₁ h₂ h₃ <;> try 

Proof state:
case pos
α : Sort u_1
inst✝ : DecidableEq α
r a b : α
h₁ : r = a
h₂ : r = b
⊢ b = a

Next tactic:
simp
theorem swapCore_comm (r a b : α) : swapCore a b r = swapCore b a r := by
  unfold swapCore
  -- Porting note: whatever solution works for `swapCore_swapCore` will work here too.
  split_ifs with h₁ h₂ h₃ <;> 

Proof state:
case neg
α : Sort u_1
inst✝ : DecidableEq α
r a b : α
h₁ : r = a
h₂ : ¬r = b
⊢ b = b

Next tactic:
try simp
theorem swapCore_comm (r a b : α) : swapCore a b r = swapCore b a r := by
  unfold swapCore
  -- Porting note: whatever solution works for `swapCore_swapCore` will work here too.
  split_ifs with h₁ h₂ h₃ <;> try 

Proof state:
case neg
α : Sort u_1
inst✝ : DecidableEq α
r a b : α
h₁ : r = a
h₂ : ¬r = b
⊢ b = b

Next tactic:
simp
theorem swapCore_comm (r a b : α) : swapCore a b r = swapCore b a r := by
  unfold swapCore
  -- Porting note: whatever solution works for `swapCore_swapCore` will work here too.
  split_ifs with h₁ h₂ h₃ <;> 

Proof state:
case pos
α : Sort u_1
inst✝ : DecidableEq α
r a b : α
h₁ : ¬r = a
h₃ : r = b
⊢ a = a

Next tactic:
try simp
theorem swapCore_comm (r a b : α) : swapCore a b r = swapCore b a r := by
  unfold swapCore
  -- Porting note: whatever solution works for `swapCore_swapCore` will work here too.
  split_ifs with h₁ h₂ h₃ <;> try 

Proof state:
case pos
α : Sort u_1
inst✝ : DecidableEq α
r a b : α
h₁ : ¬r = a
h₃ : r = b
⊢ a = a

Next tactic:
simp
theorem swapCore_comm (r a b : α) : swapCore a b r = swapCore b a r := by
  unfold swapCore
  -- Porting note: whatever solution works for `swapCore_swapCore` will work here too.
  split_ifs with h₁ h₂ h₃ <;> 

Proof state:
case neg
α : Sort u_1
inst✝ : DecidableEq α
r a b : α
h₁ : ¬r = a
h₃ : ¬r = b
⊢ r = r

Next tactic:
try simp
theorem swapCore_comm (r a b : α) : swapCore a b r = swapCore b a r := by
  unfold swapCore
  -- Porting note: whatever solution works for `swapCore_swapCore` will work here too.
  split_ifs with h₁ h₂ h₃ <;> try 

Proof state:
case neg
α : Sort u_1
inst✝ : DecidableEq α
r a b : α
h₁ : ¬r = a
h₃ : ¬r = b
⊢ r = r

Next tactic:
simp
theorem swapCore_comm (r a b : α) : swapCore a b r = swapCore b a r := by
  unfold swapCore
  -- Porting note: whatever solution works for `swapCore_swapCore` will work here too.
  split_ifs with h₁ h₂ h₃ <;> try simp
  · 

Proof state:
case pos
α : Sort u_1
inst✝ : DecidableEq α
r a b : α
h₁ : r = a
h₂ : r = b
⊢ b = a

Next tactic:
cases h₁
theorem swapCore_comm (r a b : α) : swapCore a b r = swapCore b a r := by
  unfold swapCore
  -- Porting note: whatever solution works for `swapCore_swapCore` will work here too.
  split_ifs with h₁ h₂ h₃ <;> try simp
  · cases h₁; 

Proof state:
case pos.refl
α : Sort u_1
inst✝ : DecidableEq α
r b : α
h₂ : r = b
⊢ b = r

Next tactic:
cases h₂
theorem swapCore_comm (r a b : α) : swapCore a b r = swapCore b a r := by
  unfold swapCore
  -- Porting note: whatever solution works for `swapCore_swapCore` will work here too.
  split_ifs with h₁ h₂ h₃ <;> try simp
  · cases h₁; cases h₂; 

Proof state:
case pos.refl.refl
α : Sort u_1
inst✝ : DecidableEq α
r : α
⊢ r = r

Next tactic:
rfl
@[simp]
theorem swap_apply_right (a b : α) : swap a b b = a := by
  

Proof state:
α : Sort u_1
inst✝ : DecidableEq α
a b : α
⊢ (swap a b) b = a

Next tactic:
by_cases h:b = a
@[simp]
theorem swap_apply_right (a b : α) : swap a b b = a := by
  by_cases h:b = a <;> 

Proof state:
case pos
α : Sort u_1
inst✝ : DecidableEq α
a b : α
h : b = a
⊢ (swap a b) b = a

Next tactic:
simp [swap_apply_def, h]
@[simp]
theorem swap_apply_right (a b : α) : swap a b b = a := by
  by_cases h:b = a <;> 

Proof state:
case neg
α : Sort u_1
inst✝ : DecidableEq α
a b : α
h : ¬b = a
⊢ (swap a b) b = a

Next tactic:
simp [swap_apply_def, h]
theorem swap_apply_of_ne_of_ne {a b x : α} : x ≠ a → x ≠ b → swap a b x = x := by
  

Proof state:
α : Sort u_1
inst✝ : DecidableEq α
a b x : α
⊢ x ≠ a → x ≠ b → (swap a b) x = x

Next tactic:
simp (config := { contextual := true }) [swap_apply_def]
@[simp]
theorem swap_eq_refl_iff {x y : α} : swap x y = Equiv.refl _ ↔ x = y := by
  

Proof state:
α : Sort u_1
inst✝ : DecidableEq α
x y : α
⊢ swap x y = Equiv.refl α ↔ x = y

Next tactic:
refine' ⟨fun h => (Equiv.refl _).injective _, fun h => h ▸ swap_self _⟩
@[simp]
theorem swap_eq_refl_iff {x y : α} : swap x y = Equiv.refl _ ↔ x = y := by
  refine' ⟨fun h => (Equiv.refl _).injective _, fun h => h ▸ swap_self _⟩
  

Proof state:
α : Sort u_1
inst✝ : DecidableEq α
x y : α
h : swap x y = Equiv.refl α
⊢ (Equiv.refl α) x = (Equiv.refl α) y

Next tactic:
rw [← h, swap_apply_left, h, refl_apply]
theorem swap_comp_apply {a b x : α} (π : Perm α) :
    π.trans (swap a b) x = if π x = a then b else if π x = b then a else π x := by
  

Proof state:
α : Sort u_1
inst✝ : DecidableEq α
a b x : α
π : Perm α
⊢ (π.trans (swap a b)) x = if π x = a then b else if π x = b then a else π x

Next tactic:
cases π
theorem swap_comp_apply {a b x : α} (π : Perm α) :
    π.trans (swap a b) x = if π x = a then b else if π x = b then a else π x := by
  cases π
  

Proof state:
case mk
α : Sort u_1
inst✝ : DecidableEq α
a b x : α
toFun✝ invFun✝ : α → α
left_inv✝ : LeftInverse invFun✝ toFun✝
right_inv✝ : Function.RightInverse invFun✝ toFun✝
⊢ ({ toFun := toFun✝, invFun := invFun✝, left_inv := left_inv✝, right_inv := right_inv✝ }.trans (swap a b)) x =
    if { toFun := toFun✝, invFun := invFun✝, left_inv := left_inv✝, right_inv := right_inv✝ } x = a then b
    else
      if { toFun := toFun✝, invFun := invFun✝, left_inv := left_inv✝, right_inv := right_inv✝ } x = b then a
      else { toFun := toFun✝, invFun := invFun✝, left_inv := left_inv✝, right_inv := right_inv✝ } x

Next tactic:
rfl