l3lab/ntp-mathlib huggingface dataset:
theorem signAux_eq_signAux2 {n : ℕ} :
    ∀ (l : List α) (f : Perm α) (e : α ≃ Fin n) (_h : ∀ x, f x ≠ x → x ∈ l),
      signAux ((e.symm.trans f).trans e) = signAux2 l f
  | [], f, e, h => by
    have : f = 1 := Equiv.ext fun y => Classical.not_not.1 (mt (h y) (List.not_mem_nil _))
    rw [this, one_def, Equiv.trans_refl, Equiv.symm_trans_self, ← one_def, signAux_one, signAux2]
  | x::l, f, e, h => by
    rw [signAux2]
    by_cases hfx : x = f x
    · rw [if_pos hfx]
      exact
        signAux_eq_signAux2 l f _ fun y (hy : f y ≠ y) =>
          List.mem_of_ne_of_mem (fun h : y = x => by simp [h, hfx.symm] at hy) (h y hy)
    · have hy : ∀ y : α, (swap x (f x) * f) y ≠ y → y ∈ l := fun y hy =>
        have : f y ≠ y ∧ y ≠ x := ne_and_ne_of_swap_mul_apply_ne_self hy
        List.mem_of_ne_of_mem this.2 (h _ this.1)
      have : (e.symm.trans (swap x (f x) * f)).trans e =
          swap (e x) (e (f x)) * (e.symm.trans f).trans e := by
        ext
        rw [← Equiv.symm_trans_swap_trans, mul_def, Equiv.symm_trans_swap_trans, mul_def]
        repeat (rw [trans_apply])
        simp [swap, swapCore]
        split_ifs <;> 

Proof state:
case neg
α : Type u
β : Type v
inst✝ : DecidableEq α
n : ℕ
x : α
l : List α
f : Perm α
e : α ≃ Fin n
h : ∀ (x_1 : α), f x_1 ≠ x_1 → x_1 ∈ x :: l
hfx : ¬x = f x
hy : ∀ (y : α), (swap x (f x) * f) y ≠ y → y ∈ l
x✝ : Fin n
h✝¹ : ¬f (e.symm x✝) = x
h✝ : ¬e.symm x✝ = x
⊢ ↑(e (f (e.symm x✝))) = ↑(e (f (e.symm x✝)))

Next tactic:
rfl
theorem signAux_eq_signAux2 {n : ℕ} :
    ∀ (l : List α) (f : Perm α) (e : α ≃ Fin n) (_h : ∀ x, f x ≠ x → x ∈ l),
      signAux ((e.symm.trans f).trans e) = signAux2 l f
  | [], f, e, h => by
    have : f = 1 := Equiv.ext fun y => Classical.not_not.1 (mt (h y) (List.not_mem_nil _))
    rw [this, one_def, Equiv.trans_refl, Equiv.symm_trans_self, ← one_def, signAux_one, signAux2]
  | x::l, f, e, h => by
    rw [signAux2]
    by_cases hfx : x = f x
    · rw [if_pos hfx]
      exact
        signAux_eq_signAux2 l f _ fun y (hy : f y ≠ y) =>
          List.mem_of_ne_of_mem (fun h : y = x => by simp [h, hfx.symm] at hy) (h y hy)
    · have hy : ∀ y : α, (swap x (f x) * f) y ≠ y → y ∈ l := fun y hy =>
        have : f y ≠ y ∧ y ≠ x := ne_and_ne_of_swap_mul_apply_ne_self hy
        List.mem_of_ne_of_mem this.2 (h _ this.1)
      have : (e.symm.trans (swap x (f x) * f)).trans e =
          swap (e x) (e (f x)) * (e.symm.trans f).trans e := by
        ext
        rw [← Equiv.symm_trans_swap_trans, mul_def, Equiv.symm_trans_swap_trans, mul_def]
        repeat (rw [trans_apply])
        simp [swap, swapCore]
        split_ifs <;> rfl
      

Proof state:
case neg
α : Type u
β : Type v
inst✝ : DecidableEq α
n : ℕ
x : α
l : List α
f : Perm α
e : α ≃ Fin n
h : ∀ (x_1 : α), f x_1 ≠ x_1 → x_1 ∈ x :: l
hfx : ¬x = f x
hy : ∀ (y : α), (swap x (f x) * f) y ≠ y → y ∈ l
this : (e.symm.trans (swap x (f x) * f)).trans e = swap (e x) (e (f x)) * (e.symm.trans f).trans e
⊢ signAux ((e.symm.trans f).trans e) = if x = f x then signAux2 l f else -signAux2 l (swap x (f x) * f)

Next tactic:
have hefx : e x ≠ e (f x) := mt e.injective.eq_iff.1 hfx
theorem signAux_eq_signAux2 {n : ℕ} :
    ∀ (l : List α) (f : Perm α) (e : α ≃ Fin n) (_h : ∀ x, f x ≠ x → x ∈ l),
      signAux ((e.symm.trans f).trans e) = signAux2 l f
  | [], f, e, h => by
    have : f = 1 := Equiv.ext fun y => Classical.not_not.1 (mt (h y) (List.not_mem_nil _))
    rw [this, one_def, Equiv.trans_refl, Equiv.symm_trans_self, ← one_def, signAux_one, signAux2]
  | x::l, f, e, h => by
    rw [signAux2]
    by_cases hfx : x = f x
    · rw [if_pos hfx]
      exact
        signAux_eq_signAux2 l f _ fun y (hy : f y ≠ y) =>
          List.mem_of_ne_of_mem (fun h : y = x => by simp [h, hfx.symm] at hy) (h y hy)
    · have hy : ∀ y : α, (swap x (f x) * f) y ≠ y → y ∈ l := fun y hy =>
        have : f y ≠ y ∧ y ≠ x := ne_and_ne_of_swap_mul_apply_ne_self hy
        List.mem_of_ne_of_mem this.2 (h _ this.1)
      have : (e.symm.trans (swap x (f x) * f)).trans e =
          swap (e x) (e (f x)) * (e.symm.trans f).trans e := by
        ext
        rw [← Equiv.symm_trans_swap_trans, mul_def, Equiv.symm_trans_swap_trans, mul_def]
        repeat (rw [trans_apply])
        simp [swap, swapCore]
        split_ifs <;> rfl
      have hefx : e x ≠ e (f x) := mt e.injective.eq_iff.1 hfx
      

Proof state:
case neg
α : Type u
β : Type v
inst✝ : DecidableEq α
n : ℕ
x : α
l : List α
f : Perm α
e : α ≃ Fin n
h : ∀ (x_1 : α), f x_1 ≠ x_1 → x_1 ∈ x :: l
hfx : ¬x = f x
hy : ∀ (y : α), (swap x (f x) * f) y ≠ y → y ∈ l
this : (e.symm.trans (swap x (f x) * f)).trans e = swap (e x) (e (f x)) * (e.symm.trans f).trans e
hefx : e x ≠ e (f x)
⊢ signAux ((e.symm.trans f).trans e) = if x = f x then signAux2 l f else -signAux2 l (swap x (f x) * f)

Next tactic:
rw [if_neg hfx, ← signAux_eq_signAux2 _ _ e hy, this, signAux_mul, signAux_swap hefx]
theorem signAux_eq_signAux2 {n : ℕ} :
    ∀ (l : List α) (f : Perm α) (e : α ≃ Fin n) (_h : ∀ x, f x ≠ x → x ∈ l),
      signAux ((e.symm.trans f).trans e) = signAux2 l f
  | [], f, e, h => by
    have : f = 1 := Equiv.ext fun y => Classical.not_not.1 (mt (h y) (List.not_mem_nil _))
    rw [this, one_def, Equiv.trans_refl, Equiv.symm_trans_self, ← one_def, signAux_one, signAux2]
  | x::l, f, e, h => by
    rw [signAux2]
    by_cases hfx : x = f x
    · rw [if_pos hfx]
      exact
        signAux_eq_signAux2 l f _ fun y (hy : f y ≠ y) =>
          List.mem_of_ne_of_mem (fun h : y = x => by simp [h, hfx.symm] at hy) (h y hy)
    · have hy : ∀ y : α, (swap x (f x) * f) y ≠ y → y ∈ l := fun y hy =>
        have : f y ≠ y ∧ y ≠ x := ne_and_ne_of_swap_mul_apply_ne_self hy
        List.mem_of_ne_of_mem this.2 (h _ this.1)
      have : (e.symm.trans (swap x (f x) * f)).trans e =
          swap (e x) (e (f x)) * (e.symm.trans f).trans e := by
        ext
        rw [← Equiv.symm_trans_swap_trans, mul_def, Equiv.symm_trans_swap_trans, mul_def]
        repeat (rw [trans_apply])
        simp [swap, swapCore]
        split_ifs <;> rfl
      have hefx : e x ≠ e (f x) := mt e.injective.eq_iff.1 hfx
      rw [if_neg hfx, ← signAux_eq_signAux2 _ _ e hy, this, signAux_mul, signAux_swap hefx]
      

Proof state:
case neg
α : Type u
β : Type v
inst✝ : DecidableEq α
n : ℕ
x : α
l : List α
f : Perm α
e : α ≃ Fin n
h : ∀ (x_1 : α), f x_1 ≠ x_1 → x_1 ∈ x :: l
hfx : ¬x = f x
hy : ∀ (y : α), (swap x (f x) * f) y ≠ y → y ∈ l
this : (e.symm.trans (swap x (f x) * f)).trans e = swap (e x) (e (f x)) * (e.symm.trans f).trans e
hefx : e x ≠ e (f x)
⊢ signAux ((e.symm.trans f).trans e) = -(-1 * signAux ((e.symm.trans f).trans e))

Next tactic:
simp only [neg_neg, one_mul, neg_mul]
/-- When the multiset `s : Multiset α` contains all nonfixed points of the permutation `f : Perm α`,
  `signAux2 f _` recursively calculates the sign of `f`. -/
def signAux3 [Fintype α] (f : Perm α) {s : Multiset α} : (∀ x, x ∈ s) → ℤˣ :=
  Quotient.hrecOn s (fun l _ => signAux2 l f)
    (Trunc.induction_on (Fintype.truncEquivFin α) fun e l₁ l₂ h =>
      Function.hfunext (show (∀ x, x ∈ l₁) = ∀ x, x ∈ l₂ by 

Proof state:
α : Type u
β : Type v
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f : Perm α
s : Multiset α
e : α ≃ Fin (Fintype.card α)
l₁ l₂ : List α
h : l₁ ≈ l₂
⊢ (∀ (x : α), x ∈ l₁) = ∀ (x : α), x ∈ l₂

Next tactic:
simp only [h.mem_iff]
/-- When the multiset `s : Multiset α` contains all nonfixed points of the permutation `f : Perm α`,
  `signAux2 f _` recursively calculates the sign of `f`. -/
def signAux3 [Fintype α] (f : Perm α) {s : Multiset α} : (∀ x, x ∈ s) → ℤˣ :=
  Quotient.hrecOn s (fun l _ => signAux2 l f)
    (Trunc.induction_on (Fintype.truncEquivFin α) fun e l₁ l₂ h =>
      Function.hfunext (show (∀ x, x ∈ l₁) = ∀ x, x ∈ l₂ by simp only [h.mem_iff]) fun h₁ h₂ _ => by
        

Proof state:
α : Type u
β : Type v
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f : Perm α
s : Multiset α
e : α ≃ Fin (Fintype.card α)
l₁ l₂ : List α
h : l₁ ≈ l₂
h₁ : ∀ (x : α), x ∈ ⟦l₁⟧
h₂ : ∀ (x : α), x ∈ ⟦l₂⟧
x✝ : HEq h₁ h₂
⊢ HEq (signAux2 l₁ f) (signAux2 l₂ f)

Next tactic:
rw [← signAux_eq_signAux2 _ _ e fun _ _ => h₁ _,
            ← signAux_eq_signAux2 _ _ e fun _ _ => h₂ _]
theorem signAux3_mul_and_swap [Fintype α] (f g : Perm α) (s : Multiset α) (hs : ∀ x, x ∈ s) :
    signAux3 (f * g) hs = signAux3 f hs * signAux3 g hs ∧
      ∀ x y, x ≠ y → signAux3 (swap x y) hs = -1 := by
  

Proof state:
α : Type u
β : Type v
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f g : Perm α
s : Multiset α
hs : ∀ (x : α), x ∈ s
⊢ signAux3 (f * g) hs = signAux3 f hs * signAux3 g hs ∧ ∀ (x y : α), x ≠ y → signAux3 (swap x y) hs = -1

Next tactic:
let ⟨l, hl⟩ := Quotient.exists_rep s
theorem signAux3_mul_and_swap [Fintype α] (f g : Perm α) (s : Multiset α) (hs : ∀ x, x ∈ s) :
    signAux3 (f * g) hs = signAux3 f hs * signAux3 g hs ∧
      ∀ x y, x ≠ y → signAux3 (swap x y) hs = -1 := by
  let ⟨l, hl⟩ := Quotient.exists_rep s
  

Proof state:
α : Type u
β : Type v
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f g : Perm α
s : Multiset α
hs : ∀ (x : α), x ∈ s
l : List α
hl : ⟦l⟧ = s
⊢ signAux3 (f * g) hs = signAux3 f hs * signAux3 g hs ∧ ∀ (x y : α), x ≠ y → signAux3 (swap x y) hs = -1

Next tactic:
let e := equivFin α
theorem signAux3_mul_and_swap [Fintype α] (f g : Perm α) (s : Multiset α) (hs : ∀ x, x ∈ s) :
    signAux3 (f * g) hs = signAux3 f hs * signAux3 g hs ∧
      ∀ x y, x ≠ y → signAux3 (swap x y) hs = -1 := by
  let ⟨l, hl⟩ := Quotient.exists_rep s
  let e := equivFin α
  --clear _let_match
  

Proof state:
α : Type u
β : Type v
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f g : Perm α
s : Multiset α
hs : ∀ (x : α), x ∈ s
l : List α
hl : ⟦l⟧ = s
e : α ≃ Fin (Fintype.card α) := Fintype.equivFin α
⊢ signAux3 (f * g) hs = signAux3 f hs * signAux3 g hs ∧ ∀ (x y : α), x ≠ y → signAux3 (swap x y) hs = -1

Next tactic:
subst hl
theorem signAux3_mul_and_swap [Fintype α] (f g : Perm α) (s : Multiset α) (hs : ∀ x, x ∈ s) :
    signAux3 (f * g) hs = signAux3 f hs * signAux3 g hs ∧
      ∀ x y, x ≠ y → signAux3 (swap x y) hs = -1 := by
  let ⟨l, hl⟩ := Quotient.exists_rep s
  let e := equivFin α
  --clear _let_match
  subst hl
  

Proof state:
α : Type u
β : Type v
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f g : Perm α
l : List α
e : α ≃ Fin (Fintype.card α) := Fintype.equivFin α
hs : ∀ (x : α), x ∈ ⟦l⟧
⊢ signAux3 (f * g) hs = signAux3 f hs * signAux3 g hs ∧ ∀ (x y : α), x ≠ y → signAux3 (swap x y) hs = -1

Next tactic:
show
    signAux2 l (f * g) = signAux2 l f * signAux2 l g ∧ ∀ x y, x ≠ y → signAux2 l (swap x y) = -1
theorem signAux3_mul_and_swap [Fintype α] (f g : Perm α) (s : Multiset α) (hs : ∀ x, x ∈ s) :
    signAux3 (f * g) hs = signAux3 f hs * signAux3 g hs ∧
      ∀ x y, x ≠ y → signAux3 (swap x y) hs = -1 := by
  let ⟨l, hl⟩ := Quotient.exists_rep s
  let e := equivFin α
  --clear _let_match
  subst hl
  show
    signAux2 l (f * g) = signAux2 l f * signAux2 l g ∧ ∀ x y, x ≠ y → signAux2 l (swap x y) = -1
  

Proof state:
α : Type u
β : Type v
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f g : Perm α
l : List α
e : α ≃ Fin (Fintype.card α) := Fintype.equivFin α
hs : ∀ (x : α), x ∈ ⟦l⟧
⊢ signAux2 l (f * g) = signAux2 l f * signAux2 l g ∧ ∀ (x y : α), x ≠ y → signAux2 l (swap x y) = -1

Next tactic:
have hfg : (e.symm.trans (f * g)).trans e = (e.symm.trans f).trans e * (e.symm.trans g).trans e :=
    Equiv.ext fun h => by simp [mul_apply]
theorem signAux3_mul_and_swap [Fintype α] (f g : Perm α) (s : Multiset α) (hs : ∀ x, x ∈ s) :
    signAux3 (f * g) hs = signAux3 f hs * signAux3 g hs ∧
      ∀ x y, x ≠ y → signAux3 (swap x y) hs = -1 := by
  let ⟨l, hl⟩ := Quotient.exists_rep s
  let e := equivFin α
  --clear _let_match
  subst hl
  show
    signAux2 l (f * g) = signAux2 l f * signAux2 l g ∧ ∀ x y, x ≠ y → signAux2 l (swap x y) = -1
  have hfg : (e.symm.trans (f * g)).trans e = (e.symm.trans f).trans e * (e.symm.trans g).trans e :=
    Equiv.ext fun h => by 

Proof state:
α : Type u
β : Type v
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f g : Perm α
l : List α
e : α ≃ Fin (Fintype.card α) := Fintype.equivFin α
hs : ∀ (x : α), x ∈ ⟦l⟧
h : Fin (Fintype.card α)
⊢ ((e.symm.trans (f * g)).trans e) h = ((e.symm.trans f).trans e * (e.symm.trans g).trans e) h

Next tactic:
simp [mul_apply]
theorem signAux3_mul_and_swap [Fintype α] (f g : Perm α) (s : Multiset α) (hs : ∀ x, x ∈ s) :
    signAux3 (f * g) hs = signAux3 f hs * signAux3 g hs ∧
      ∀ x y, x ≠ y → signAux3 (swap x y) hs = -1 := by
  let ⟨l, hl⟩ := Quotient.exists_rep s
  let e := equivFin α
  --clear _let_match
  subst hl
  show
    signAux2 l (f * g) = signAux2 l f * signAux2 l g ∧ ∀ x y, x ≠ y → signAux2 l (swap x y) = -1
  have hfg : (e.symm.trans (f * g)).trans e = (e.symm.trans f).trans e * (e.symm.trans g).trans e :=
    Equiv.ext fun h => by simp [mul_apply]
  

Proof state:
α : Type u
β : Type v
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f g : Perm α
l : List α
e : α ≃ Fin (Fintype.card α) := Fintype.equivFin α
hs : ∀ (x : α), x ∈ ⟦l⟧
hfg : (e.symm.trans (f * g)).trans e = (e.symm.trans f).trans e * (e.symm.trans g).trans e
⊢ signAux2 l (f * g) = signAux2 l f * signAux2 l g ∧ ∀ (x y : α), x ≠ y → signAux2 l (swap x y) = -1

Next tactic:
constructor
theorem signAux3_mul_and_swap [Fintype α] (f g : Perm α) (s : Multiset α) (hs : ∀ x, x ∈ s) :
    signAux3 (f * g) hs = signAux3 f hs * signAux3 g hs ∧
      ∀ x y, x ≠ y → signAux3 (swap x y) hs = -1 := by
  let ⟨l, hl⟩ := Quotient.exists_rep s
  let e := equivFin α
  --clear _let_match
  subst hl
  show
    signAux2 l (f * g) = signAux2 l f * signAux2 l g ∧ ∀ x y, x ≠ y → signAux2 l (swap x y) = -1
  have hfg : (e.symm.trans (f * g)).trans e = (e.symm.trans f).trans e * (e.symm.trans g).trans e :=
    Equiv.ext fun h => by simp [mul_apply]
  constructor
  · 

Proof state:
case left
α : Type u
β : Type v
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f g : Perm α
l : List α
e : α ≃ Fin (Fintype.card α) := Fintype.equivFin α
hs : ∀ (x : α), x ∈ ⟦l⟧
hfg : (e.symm.trans (f * g)).trans e = (e.symm.trans f).trans e * (e.symm.trans g).trans e
⊢ signAux2 l (f * g) = signAux2 l f * signAux2 l g

Next tactic:
rw [← signAux_eq_signAux2 _ _ e fun _ _ => hs _, ←
      signAux_eq_signAux2 _ _ e fun _ _ => hs _, ← signAux_eq_signAux2 _ _ e fun _ _ => hs _,
      hfg, signAux_mul]
theorem signAux3_mul_and_swap [Fintype α] (f g : Perm α) (s : Multiset α) (hs : ∀ x, x ∈ s) :
    signAux3 (f * g) hs = signAux3 f hs * signAux3 g hs ∧
      ∀ x y, x ≠ y → signAux3 (swap x y) hs = -1 := by
  let ⟨l, hl⟩ := Quotient.exists_rep s
  let e := equivFin α
  --clear _let_match
  subst hl
  show
    signAux2 l (f * g) = signAux2 l f * signAux2 l g ∧ ∀ x y, x ≠ y → signAux2 l (swap x y) = -1
  have hfg : (e.symm.trans (f * g)).trans e = (e.symm.trans f).trans e * (e.symm.trans g).trans e :=
    Equiv.ext fun h => by simp [mul_apply]
  constructor
  · rw [← signAux_eq_signAux2 _ _ e fun _ _ => hs _, ←
      signAux_eq_signAux2 _ _ e fun _ _ => hs _, ← signAux_eq_signAux2 _ _ e fun _ _ => hs _,
      hfg, signAux_mul]
  · 

Proof state:
case right
α : Type u
β : Type v
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f g : Perm α
l : List α
e : α ≃ Fin (Fintype.card α) := Fintype.equivFin α
hs : ∀ (x : α), x ∈ ⟦l⟧
hfg : (e.symm.trans (f * g)).trans e = (e.symm.trans f).trans e * (e.symm.trans g).trans e
⊢ ∀ (x y : α), x ≠ y → signAux2 l (swap x y) = -1

Next tactic:
intro x y hxy
theorem signAux3_mul_and_swap [Fintype α] (f g : Perm α) (s : Multiset α) (hs : ∀ x, x ∈ s) :
    signAux3 (f * g) hs = signAux3 f hs * signAux3 g hs ∧
      ∀ x y, x ≠ y → signAux3 (swap x y) hs = -1 := by
  let ⟨l, hl⟩ := Quotient.exists_rep s
  let e := equivFin α
  --clear _let_match
  subst hl
  show
    signAux2 l (f * g) = signAux2 l f * signAux2 l g ∧ ∀ x y, x ≠ y → signAux2 l (swap x y) = -1
  have hfg : (e.symm.trans (f * g)).trans e = (e.symm.trans f).trans e * (e.symm.trans g).trans e :=
    Equiv.ext fun h => by simp [mul_apply]
  constructor
  · rw [← signAux_eq_signAux2 _ _ e fun _ _ => hs _, ←
      signAux_eq_signAux2 _ _ e fun _ _ => hs _, ← signAux_eq_signAux2 _ _ e fun _ _ => hs _,
      hfg, signAux_mul]
  · intro x y hxy
    

Proof state:
case right
α : Type u
β : Type v
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f g : Perm α
l : List α
e : α ≃ Fin (Fintype.card α) := Fintype.equivFin α
hs : ∀ (x : α), x ∈ ⟦l⟧
hfg : (e.symm.trans (f * g)).trans e = (e.symm.trans f).trans e * (e.symm.trans g).trans e
x y : α
hxy : x ≠ y
⊢ signAux2 l (swap x y) = -1

Next tactic:
have hexy : e x ≠ e y := mt e.injective.eq_iff.1 hxy
theorem signAux3_mul_and_swap [Fintype α] (f g : Perm α) (s : Multiset α) (hs : ∀ x, x ∈ s) :
    signAux3 (f * g) hs = signAux3 f hs * signAux3 g hs ∧
      ∀ x y, x ≠ y → signAux3 (swap x y) hs = -1 := by
  let ⟨l, hl⟩ := Quotient.exists_rep s
  let e := equivFin α
  --clear _let_match
  subst hl
  show
    signAux2 l (f * g) = signAux2 l f * signAux2 l g ∧ ∀ x y, x ≠ y → signAux2 l (swap x y) = -1
  have hfg : (e.symm.trans (f * g)).trans e = (e.symm.trans f).trans e * (e.symm.trans g).trans e :=
    Equiv.ext fun h => by simp [mul_apply]
  constructor
  · rw [← signAux_eq_signAux2 _ _ e fun _ _ => hs _, ←
      signAux_eq_signAux2 _ _ e fun _ _ => hs _, ← signAux_eq_signAux2 _ _ e fun _ _ => hs _,
      hfg, signAux_mul]
  · intro x y hxy
    have hexy : e x ≠ e y := mt e.injective.eq_iff.1 hxy
    

Proof state:
case right
α : Type u
β : Type v
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f g : Perm α
l : List α
e : α ≃ Fin (Fintype.card α) := Fintype.equivFin α
hs : ∀ (x : α), x ∈ ⟦l⟧
hfg : (e.symm.trans (f * g)).trans e = (e.symm.trans f).trans e * (e.symm.trans g).trans e
x y : α
hxy : x ≠ y
hexy : e x ≠ e y
⊢ signAux2 l (swap x y) = -1

Next tactic:
rw [← signAux_eq_signAux2 _ _ e fun _ _ => hs _, symm_trans_swap_trans, signAux_swap hexy]
@[simp]
theorem sign_trans (f g : Perm α) : sign (f.trans g) = sign g * sign f := by
  

Proof state:
α : Type u
β : Type v
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f g : Perm α
⊢ sign (f.trans g) = sign g * sign f

Next tactic:
rw [← mul_def, sign_mul]
theorem sign_inv (f : Perm α) : sign f⁻¹ = sign f := by
  

Proof state:
α : Type u
β : Type v
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f : Perm α
⊢ sign f⁻¹ = sign f

Next tactic:
rw [MonoidHom.map_inv sign f, Int.units_inv_eq_self]
@[simp]
theorem sign_swap' {x y : α} : sign (swap x y) = if x = y then 1 else -1 :=
  if H : x = y then by 

Proof state:
α : Type u
β : Type v
inst✝¹ : DecidableEq α
inst✝ : Fintype α
x y : α
H : x = y
⊢ sign (swap x y) = if x = y then 1 else -1

Next tactic:
simp [H, swap_self]
@[simp]
theorem sign_swap' {x y : α} : sign (swap x y) = if x = y then 1 else -1 :=
  if H : x = y then by simp [H, swap_self] else by 

Proof state:
α : Type u
β : Type v
inst✝¹ : DecidableEq α
inst✝ : Fintype α
x y : α
H : ¬x = y
⊢ sign (swap x y) = if x = y then 1 else -1

Next tactic:
simp [sign_swap H, H]
theorem signAux3_symm_trans_trans [DecidableEq β] [Fintype β] (f : Perm α) (e : α ≃ β)
    {s : Multiset α} {t : Multiset β} (hs : ∀ x, x ∈ s) (ht : ∀ x, x ∈ t) :
    signAux3 ((e.symm.trans f).trans e) ht = signAux3 f hs := by
  -- porting note: switched from term mode to tactic mode
  

Proof state:
α : Type u
β : Type v
inst✝³ : DecidableEq α
inst✝² : Fintype α
inst✝¹ : DecidableEq β
inst✝ : Fintype β
f : Perm α
e : α ≃ β
s : Multiset α
t : Multiset β
hs : ∀ (x : α), x ∈ s
ht : ∀ (x : β), x ∈ t
⊢ signAux3 ((e.symm.trans f).trans e) ht = signAux3 f hs

Next tactic:
induction' t, s using Quotient.inductionOn₂ with t s ht hs
theorem signAux3_symm_trans_trans [DecidableEq β] [Fintype β] (f : Perm α) (e : α ≃ β)
    {s : Multiset α} {t : Multiset β} (hs : ∀ x, x ∈ s) (ht : ∀ x, x ∈ t) :
    signAux3 ((e.symm.trans f).trans e) ht = signAux3 f hs := by
  -- porting note: switched from term mode to tactic mode
  induction' t, s using Quotient.inductionOn₂ with t s ht hs
  

Proof state:
case h
α : Type u
β : Type v
inst✝³ : DecidableEq α
inst✝² : Fintype α
inst✝¹ : DecidableEq β
inst✝ : Fintype β
f : Perm α
e : α ≃ β
t : List β
s : List α
hs : ∀ (x : α), x ∈ ⟦s⟧
ht : ∀ (x : β), x ∈ ⟦t⟧
⊢ signAux3 ((e.symm.trans f).trans e) ht = signAux3 f hs

Next tactic:
show signAux2 _ _ = signAux2 _ _
theorem signAux3_symm_trans_trans [DecidableEq β] [Fintype β] (f : Perm α) (e : α ≃ β)
    {s : Multiset α} {t : Multiset β} (hs : ∀ x, x ∈ s) (ht : ∀ x, x ∈ t) :
    signAux3 ((e.symm.trans f).trans e) ht = signAux3 f hs := by
  -- porting note: switched from term mode to tactic mode
  induction' t, s using Quotient.inductionOn₂ with t s ht hs
  show signAux2 _ _ = signAux2 _ _
  

Proof state:
case h
α : Type u
β : Type v
inst✝³ : DecidableEq α
inst✝² : Fintype α
inst✝¹ : DecidableEq β
inst✝ : Fintype β
f : Perm α
e : α ≃ β
t : List β
s : List α
hs : ∀ (x : α), x ∈ ⟦s⟧
ht : ∀ (x : β), x ∈ ⟦t⟧
⊢ signAux2 t ((e.symm.trans f).trans e) = signAux2 s f

Next tactic:
let n := equivFin β
theorem signAux3_symm_trans_trans [DecidableEq β] [Fintype β] (f : Perm α) (e : α ≃ β)
    {s : Multiset α} {t : Multiset β} (hs : ∀ x, x ∈ s) (ht : ∀ x, x ∈ t) :
    signAux3 ((e.symm.trans f).trans e) ht = signAux3 f hs := by
  -- porting note: switched from term mode to tactic mode
  induction' t, s using Quotient.inductionOn₂ with t s ht hs
  show signAux2 _ _ = signAux2 _ _
  let n := equivFin β
  

Proof state:
case h
α : Type u
β : Type v
inst✝³ : DecidableEq α
inst✝² : Fintype α
inst✝¹ : DecidableEq β
inst✝ : Fintype β
f : Perm α
e : α ≃ β
t : List β
s : List α
hs : ∀ (x : α), x ∈ ⟦s⟧
ht : ∀ (x : β), x ∈ ⟦t⟧
n : β ≃ Fin (Fintype.card β) := Fintype.equivFin β
⊢ signAux2 t ((e.symm.trans f).trans e) = signAux2 s f

Next tactic:
rw [← signAux_eq_signAux2 _ _ n fun _ _ => ht _,
    ← signAux_eq_signAux2 _ _ (e.trans n) fun _ _ => hs _]
theorem signAux3_symm_trans_trans [DecidableEq β] [Fintype β] (f : Perm α) (e : α ≃ β)
    {s : Multiset α} {t : Multiset β} (hs : ∀ x, x ∈ s) (ht : ∀ x, x ∈ t) :
    signAux3 ((e.symm.trans f).trans e) ht = signAux3 f hs := by
  -- porting note: switched from term mode to tactic mode
  induction' t, s using Quotient.inductionOn₂ with t s ht hs
  show signAux2 _ _ = signAux2 _ _
  let n := equivFin β
  rw [← signAux_eq_signAux2 _ _ n fun _ _ => ht _,
    ← signAux_eq_signAux2 _ _ (e.trans n) fun _ _ => hs _]
  

Proof state:
case h
α : Type u
β : Type v
inst✝³ : DecidableEq α
inst✝² : Fintype α
inst✝¹ : DecidableEq β
inst✝ : Fintype β
f : Perm α
e : α ≃ β
t : List β
s : List α
hs : ∀ (x : α), x ∈ ⟦s⟧
ht : ∀ (x : β), x ∈ ⟦t⟧
n : β ≃ Fin (Fintype.card β) := Fintype.equivFin β
⊢ signAux ((n.symm.trans ((e.symm.trans f).trans e)).trans n) = signAux (((e.trans n).symm.trans f).trans (e.trans n))

Next tactic:
exact congr_arg signAux
    (Equiv.ext fun x => by simp [Equiv.coe_trans, apply_eq_iff_eq, symm_trans_apply])
theorem signAux3_symm_trans_trans [DecidableEq β] [Fintype β] (f : Perm α) (e : α ≃ β)
    {s : Multiset α} {t : Multiset β} (hs : ∀ x, x ∈ s) (ht : ∀ x, x ∈ t) :
    signAux3 ((e.symm.trans f).trans e) ht = signAux3 f hs := by
  -- porting note: switched from term mode to tactic mode
  induction' t, s using Quotient.inductionOn₂ with t s ht hs
  show signAux2 _ _ = signAux2 _ _
  let n := equivFin β
  rw [← signAux_eq_signAux2 _ _ n fun _ _ => ht _,
    ← signAux_eq_signAux2 _ _ (e.trans n) fun _ _ => hs _]
  exact congr_arg signAux
    (Equiv.ext fun x => by 

Proof state:
α : Type u
β : Type v
inst✝³ : DecidableEq α
inst✝² : Fintype α
inst✝¹ : DecidableEq β
inst✝ : Fintype β
f : Perm α
e : α ≃ β
t : List β
s : List α
hs : ∀ (x : α), x ∈ ⟦s⟧
ht : ∀ (x : β), x ∈ ⟦t⟧
n : β ≃ Fin (Fintype.card β) := Fintype.equivFin β
x : Fin (Fintype.card β)
⊢ ((n.symm.trans ((e.symm.trans f).trans e)).trans n) x = (((e.trans n).symm.trans f).trans (e.trans n)) x

Next tactic:
simp [Equiv.coe_trans, apply_eq_iff_eq, symm_trans_apply]
theorem sign_prod_list_swap {l : List (Perm α)} (hl : ∀ g ∈ l, IsSwap g) :
    sign l.prod = (-1) ^ l.length := by
  

Proof state:
α : Type u
β : Type v
inst✝¹ : DecidableEq α
inst✝ : Fintype α
l : List (Perm α)
hl : ∀ g ∈ l, IsSwap g
⊢ sign (List.prod l) = (-1) ^ List.length l

Next tactic:
have h₁ : l.map sign = List.replicate l.length (-1) :=
    List.eq_replicate.2
      ⟨by simp, fun u hu =>
        let ⟨g, hg⟩ := List.mem_map.1 hu
        hg.2 ▸ (hl _ hg.1).sign_eq⟩