l3lab/ntp-mathlib huggingface dataset:
theorem Disjoint.extendDomain {α : Type*} {p : β → Prop} [DecidablePred p] (f : α ≃ Subtype p)
    {σ τ : Perm α} (h : Disjoint σ τ) : Disjoint (σ.extendDomain f) (τ.extendDomain f) := by
  intro b
  by_cases pb : p b
  · refine' (h (f.symm ⟨b, pb⟩)).imp _ _ <;>
      · 

Proof state:
case pos.refine'_1
α✝ : Type u
β : Type v
α : Type u_1
p : β → Prop
inst✝ : DecidablePred p
f : α ≃ Subtype p
σ τ : Perm α
h : Disjoint σ τ
b : β
pb : p b
⊢ σ (f.symm { val := b, property := pb }) = f.symm { val := b, property := pb } → (Perm.extendDomain σ f) b = b

Next tactic:
intro h
theorem Disjoint.extendDomain {α : Type*} {p : β → Prop} [DecidablePred p] (f : α ≃ Subtype p)
    {σ τ : Perm α} (h : Disjoint σ τ) : Disjoint (σ.extendDomain f) (τ.extendDomain f) := by
  intro b
  by_cases pb : p b
  · refine' (h (f.symm ⟨b, pb⟩)).imp _ _ <;>
      · intro h
        

Proof state:
case pos.refine'_1
α✝ : Type u
β : Type v
α : Type u_1
p : β → Prop
inst✝ : DecidablePred p
f : α ≃ Subtype p
σ τ : Perm α
h✝ : Disjoint σ τ
b : β
pb : p b
h : σ (f.symm { val := b, property := pb }) = f.symm { val := b, property := pb }
⊢ (Perm.extendDomain σ f) b = b

Next tactic:
rw [extendDomain_apply_subtype _ _ pb, h, apply_symm_apply, Subtype.coe_mk]
theorem Disjoint.extendDomain {α : Type*} {p : β → Prop} [DecidablePred p] (f : α ≃ Subtype p)
    {σ τ : Perm α} (h : Disjoint σ τ) : Disjoint (σ.extendDomain f) (τ.extendDomain f) := by
  intro b
  by_cases pb : p b
  · refine' (h (f.symm ⟨b, pb⟩)).imp _ _ <;>
      · 

Proof state:
case pos.refine'_2
α✝ : Type u
β : Type v
α : Type u_1
p : β → Prop
inst✝ : DecidablePred p
f : α ≃ Subtype p
σ τ : Perm α
h : Disjoint σ τ
b : β
pb : p b
⊢ τ (f.symm { val := b, property := pb }) = f.symm { val := b, property := pb } → (Perm.extendDomain τ f) b = b

Next tactic:
intro h
theorem Disjoint.extendDomain {α : Type*} {p : β → Prop} [DecidablePred p] (f : α ≃ Subtype p)
    {σ τ : Perm α} (h : Disjoint σ τ) : Disjoint (σ.extendDomain f) (τ.extendDomain f) := by
  intro b
  by_cases pb : p b
  · refine' (h (f.symm ⟨b, pb⟩)).imp _ _ <;>
      · intro h
        

Proof state:
case pos.refine'_2
α✝ : Type u
β : Type v
α : Type u_1
p : β → Prop
inst✝ : DecidablePred p
f : α ≃ Subtype p
σ τ : Perm α
h✝ : Disjoint σ τ
b : β
pb : p b
h : τ (f.symm { val := b, property := pb }) = f.symm { val := b, property := pb }
⊢ (Perm.extendDomain τ f) b = b

Next tactic:
rw [extendDomain_apply_subtype _ _ pb, h, apply_symm_apply, Subtype.coe_mk]
theorem Disjoint.extendDomain {α : Type*} {p : β → Prop} [DecidablePred p] (f : α ≃ Subtype p)
    {σ τ : Perm α} (h : Disjoint σ τ) : Disjoint (σ.extendDomain f) (τ.extendDomain f) := by
  intro b
  by_cases pb : p b
  · refine' (h (f.symm ⟨b, pb⟩)).imp _ _ <;>
      · intro h
        rw [extendDomain_apply_subtype _ _ pb, h, apply_symm_apply, Subtype.coe_mk]
  · 

Proof state:
case neg
α✝ : Type u
β : Type v
α : Type u_1
p : β → Prop
inst✝ : DecidablePred p
f : α ≃ Subtype p
σ τ : Perm α
h : Disjoint σ τ
b : β
pb : ¬p b
⊢ (Perm.extendDomain σ f) b = b ∨ (Perm.extendDomain τ f) b = b

Next tactic:
left
theorem Disjoint.extendDomain {α : Type*} {p : β → Prop} [DecidablePred p] (f : α ≃ Subtype p)
    {σ τ : Perm α} (h : Disjoint σ τ) : Disjoint (σ.extendDomain f) (τ.extendDomain f) := by
  intro b
  by_cases pb : p b
  · refine' (h (f.symm ⟨b, pb⟩)).imp _ _ <;>
      · intro h
        rw [extendDomain_apply_subtype _ _ pb, h, apply_symm_apply, Subtype.coe_mk]
  · left
    

Proof state:
case neg.h
α✝ : Type u
β : Type v
α : Type u_1
p : β → Prop
inst✝ : DecidablePred p
f : α ≃ Subtype p
σ τ : Perm α
h : Disjoint σ τ
b : β
pb : ¬p b
⊢ (Perm.extendDomain σ f) b = b

Next tactic:
rw [extendDomain_apply_not_subtype _ _ pb]
theorem support_pow_coprime {σ : Perm α} {n : ℕ} (h : Nat.Coprime n (orderOf σ)) :
    (σ ^ n).support = σ.support := by
  

Proof state:
α : Type u
β : Type v
inst✝¹ : DecidableEq α
inst✝ : Fintype α
σ : Perm α
n : ℕ
h : Nat.Coprime n (orderOf σ)
⊢ support (σ ^ n) = support σ

Next tactic:
obtain ⟨m, hm⟩ := exists_pow_eq_self_of_coprime h
theorem support_pow_coprime {σ : Perm α} {n : ℕ} (h : Nat.Coprime n (orderOf σ)) :
    (σ ^ n).support = σ.support := by
  obtain ⟨m, hm⟩ := exists_pow_eq_self_of_coprime h
  

Proof state:
case intro
α : Type u
β : Type v
inst✝¹ : DecidableEq α
inst✝ : Fintype α
σ : Perm α
n : ℕ
h : Nat.Coprime n (orderOf σ)
m : ℕ
hm : (σ ^ n) ^ m = σ
⊢ support (σ ^ n) = support σ

Next tactic:
exact
    le_antisymm (support_pow_le σ n)
      (le_trans (ge_of_eq (congr_arg support hm)) (support_pow_le (σ ^ n) m))
/-- Given a list `l : List α` and a permutation `f : Perm α` such that the nonfixed points of `f`
  are in `l`, recursively factors `f` as a product of transpositions. -/
def swapFactorsAux :
    ∀ (l : List α) (f : Perm α),
      (∀ {x}, f x ≠ x → x ∈ l) → { l : List (Perm α) // l.prod = f ∧ ∀ g ∈ l, IsSwap g }
  | [] => fun f h =>
    ⟨[],
      Equiv.ext fun x => by
        

Proof state:
α : Type u
β : Type v
inst✝ : DecidableEq α
f : Perm α
h : ∀ {x : α}, f x ≠ x → x ∈ []
x : α
⊢ (List.prod []) x = f x

Next tactic:
rw [List.prod_nil]
/-- Given a list `l : List α` and a permutation `f : Perm α` such that the nonfixed points of `f`
  are in `l`, recursively factors `f` as a product of transpositions. -/
def swapFactorsAux :
    ∀ (l : List α) (f : Perm α),
      (∀ {x}, f x ≠ x → x ∈ l) → { l : List (Perm α) // l.prod = f ∧ ∀ g ∈ l, IsSwap g }
  | [] => fun f h =>
    ⟨[],
      Equiv.ext fun x => by
        rw [List.prod_nil]
        

Proof state:
α : Type u
β : Type v
inst✝ : DecidableEq α
f : Perm α
h : ∀ {x : α}, f x ≠ x → x ∈ []
x : α
⊢ 1 x = f x

Next tactic:
exact (Classical.not_not.1 (mt h (List.not_mem_nil _))).symm
/-- Given a list `l : List α` and a permutation `f : Perm α` such that the nonfixed points of `f`
  are in `l`, recursively factors `f` as a product of transpositions. -/
def swapFactorsAux :
    ∀ (l : List α) (f : Perm α),
      (∀ {x}, f x ≠ x → x ∈ l) → { l : List (Perm α) // l.prod = f ∧ ∀ g ∈ l, IsSwap g }
  | [] => fun f h =>
    ⟨[],
      Equiv.ext fun x => by
        rw [List.prod_nil]
        exact (Classical.not_not.1 (mt h (List.not_mem_nil _))).symm,
      by 

Proof state:
α : Type u
β : Type v
inst✝ : DecidableEq α
f : Perm α
h : ∀ {x : α}, f x ≠ x → x ∈ []
⊢ ∀ g ∈ [], IsSwap g

Next tactic:
simp
/-- Given a list `l : List α` and a permutation `f : Perm α` such that the nonfixed points of `f`
  are in `l`, recursively factors `f` as a product of transpositions. -/
def swapFactorsAux :
    ∀ (l : List α) (f : Perm α),
      (∀ {x}, f x ≠ x → x ∈ l) → { l : List (Perm α) // l.prod = f ∧ ∀ g ∈ l, IsSwap g }
  | [] => fun f h =>
    ⟨[],
      Equiv.ext fun x => by
        rw [List.prod_nil]
        exact (Classical.not_not.1 (mt h (List.not_mem_nil _))).symm,
      by simp⟩
  | x::l => fun f h =>
    if hfx : x = f x then
      swapFactorsAux l f fun {y} hy =>
        List.mem_of_ne_of_mem (fun h : y = x => by 

Proof state:
α : Type u
β : Type v
inst✝ : DecidableEq α
x : α
l : List α
f : Perm α
h✝ : ∀ {x_1 : α}, f x_1 ≠ x_1 → x_1 ∈ x :: l
hfx : x = f x
y : α
hy : f y ≠ y
h : y = x
⊢ False

Next tactic:
simp [h, hfx.symm] at hy
/-- Given a list `l : List α` and a permutation `f : Perm α` such that the nonfixed points of `f`
  are in `l`, recursively factors `f` as a product of transpositions. -/
def swapFactorsAux :
    ∀ (l : List α) (f : Perm α),
      (∀ {x}, f x ≠ x → x ∈ l) → { l : List (Perm α) // l.prod = f ∧ ∀ g ∈ l, IsSwap g }
  | [] => fun f h =>
    ⟨[],
      Equiv.ext fun x => by
        rw [List.prod_nil]
        exact (Classical.not_not.1 (mt h (List.not_mem_nil _))).symm,
      by simp⟩
  | x::l => fun f h =>
    if hfx : x = f x then
      swapFactorsAux l f fun {y} hy =>
        List.mem_of_ne_of_mem (fun h : y = x => by simp [h, hfx.symm] at hy) (h hy)
    else
      let m :=
        swapFactorsAux l (swap x (f x) * f) 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)
      ⟨swap x (f x)::m.1, by
        

Proof state:
α : Type u
β : Type v
inst✝ : DecidableEq α
x : α
l : List α
f : Perm α
h : ∀ {x_1 : α}, f x_1 ≠ x_1 → x_1 ∈ x :: l
hfx : ¬x = f x
m : { l // List.prod l = swap x (f x) * f ∧ ∀ g ∈ l, IsSwap g } :=
  swapFactorsAux l (swap x (f x) * f) (_ : ∀ {y : α}, (swap x (f x) * f) y ≠ y → y ∈ l)
⊢ List.prod (swap x (f x) :: ↑m) = f

Next tactic:
rw [List.prod_cons, m.2.1, ← mul_assoc, mul_def (swap x (f x)), swap_swap, ← one_def,
          one_mul]
/-- An induction principle for permutations. If `P` holds for the identity permutation, and
is preserved under composition with a non-trivial swap, then `P` holds for all permutations. -/
@[elab_as_elim]
theorem swap_induction_on [Finite α] {P : Perm α → Prop} (f : Perm α) :
    P 1 → (∀ f x y, x ≠ y → P f → P (swap x y * f)) → P f := by
  

Proof state:
α : Type u
β : Type v
inst✝¹ : DecidableEq α
inst✝ : Finite α
P : Perm α → Prop
f : Perm α
⊢ P 1 → (∀ (f : Perm α) (x y : α), x ≠ y → P f → P (swap x y * f)) → P f

Next tactic:
cases nonempty_fintype α
/-- An induction principle for permutations. If `P` holds for the identity permutation, and
is preserved under composition with a non-trivial swap, then `P` holds for all permutations. -/
@[elab_as_elim]
theorem swap_induction_on [Finite α] {P : Perm α → Prop} (f : Perm α) :
    P 1 → (∀ f x y, x ≠ y → P f → P (swap x y * f)) → P f := by
  cases nonempty_fintype α
  

Proof state:
case intro
α : Type u
β : Type v
inst✝¹ : DecidableEq α
inst✝ : Finite α
P : Perm α → Prop
f : Perm α
val✝ : Fintype α
⊢ P 1 → (∀ (f : Perm α) (x y : α), x ≠ y → P f → P (swap x y * f)) → P f

Next tactic:
cases' (truncSwapFactors f).out with l hl
/-- An induction principle for permutations. If `P` holds for the identity permutation, and
is preserved under composition with a non-trivial swap, then `P` holds for all permutations. -/
@[elab_as_elim]
theorem swap_induction_on [Finite α] {P : Perm α → Prop} (f : Perm α) :
    P 1 → (∀ f x y, x ≠ y → P f → P (swap x y * f)) → P f := by
  cases nonempty_fintype α
  cases' (truncSwapFactors f).out with l hl
  

Proof state:
case intro.mk
α : Type u
β : Type v
inst✝¹ : DecidableEq α
inst✝ : Finite α
P : Perm α → Prop
f : Perm α
val✝ : Fintype α
l : List (Perm α)
hl : List.prod l = f ∧ ∀ g ∈ l, IsSwap g
⊢ P 1 → (∀ (f : Perm α) (x y : α), x ≠ y → P f → P (swap x y * f)) → P f

Next tactic:
induction' l with g l ih generalizing f
/-- An induction principle for permutations. If `P` holds for the identity permutation, and
is preserved under composition with a non-trivial swap, then `P` holds for all permutations. -/
@[elab_as_elim]
theorem swap_induction_on [Finite α] {P : Perm α → Prop} (f : Perm α) :
    P 1 → (∀ f x y, x ≠ y → P f → P (swap x y * f)) → P f := by
  cases nonempty_fintype α
  cases' (truncSwapFactors f).out with l hl
  induction' l with g l ih generalizing f
  · 

Proof state:
case intro.mk.nil
α : Type u
β : Type v
inst✝¹ : DecidableEq α
inst✝ : Finite α
P : Perm α → Prop
val✝ : Fintype α
f : Perm α
hl : List.prod [] = f ∧ ∀ g ∈ [], IsSwap g
⊢ P 1 → (∀ (f : Perm α) (x y : α), x ≠ y → P f → P (swap x y * f)) → P f

Next tactic:
simp (config := { contextual := true }) only [hl.left.symm, List.prod_nil, forall_true_iff]
/-- An induction principle for permutations. If `P` holds for the identity permutation, and
is preserved under composition with a non-trivial swap, then `P` holds for all permutations. -/
@[elab_as_elim]
theorem swap_induction_on [Finite α] {P : Perm α → Prop} (f : Perm α) :
    P 1 → (∀ f x y, x ≠ y → P f → P (swap x y * f)) → P f := by
  cases nonempty_fintype α
  cases' (truncSwapFactors f).out with l hl
  induction' l with g l ih generalizing f
  · simp (config := { contextual := true }) only [hl.left.symm, List.prod_nil, forall_true_iff]
  · 

Proof state:
case intro.mk.cons
α : Type u
β : Type v
inst✝¹ : DecidableEq α
inst✝ : Finite α
P : Perm α → Prop
val✝ : Fintype α
g : Perm α
l : List (Perm α)
ih :
  ∀ (f : Perm α),
    (List.prod l = f ∧ ∀ g ∈ l, IsSwap g) → P 1 → (∀ (f : Perm α) (x y : α), x ≠ y → P f → P (swap x y * f)) → P f
f : Perm α
hl : List.prod (g :: l) = f ∧ ∀ g_1 ∈ g :: l, IsSwap g_1
⊢ P 1 → (∀ (f : Perm α) (x y : α), x ≠ y → P f → P (swap x y * f)) → P f

Next tactic:
intro h1 hmul_swap
/-- An induction principle for permutations. If `P` holds for the identity permutation, and
is preserved under composition with a non-trivial swap, then `P` holds for all permutations. -/
@[elab_as_elim]
theorem swap_induction_on [Finite α] {P : Perm α → Prop} (f : Perm α) :
    P 1 → (∀ f x y, x ≠ y → P f → P (swap x y * f)) → P f := by
  cases nonempty_fintype α
  cases' (truncSwapFactors f).out with l hl
  induction' l with g l ih generalizing f
  · simp (config := { contextual := true }) only [hl.left.symm, List.prod_nil, forall_true_iff]
  · intro h1 hmul_swap
    

Proof state:
case intro.mk.cons
α : Type u
β : Type v
inst✝¹ : DecidableEq α
inst✝ : Finite α
P : Perm α → Prop
val✝ : Fintype α
g : Perm α
l : List (Perm α)
ih :
  ∀ (f : Perm α),
    (List.prod l = f ∧ ∀ g ∈ l, IsSwap g) → P 1 → (∀ (f : Perm α) (x y : α), x ≠ y → P f → P (swap x y * f)) → P f
f : Perm α
hl : List.prod (g :: l) = f ∧ ∀ g_1 ∈ g :: l, IsSwap g_1
h1 : P 1
hmul_swap : ∀ (f : Perm α) (x y : α), x ≠ y → P f → P (swap x y * f)
⊢ P f

Next tactic:
rcases hl.2 g (by simp) with ⟨x, y, hxy⟩
/-- An induction principle for permutations. If `P` holds for the identity permutation, and
is preserved under composition with a non-trivial swap, then `P` holds for all permutations. -/
@[elab_as_elim]
theorem swap_induction_on [Finite α] {P : Perm α → Prop} (f : Perm α) :
    P 1 → (∀ f x y, x ≠ y → P f → P (swap x y * f)) → P f := by
  cases nonempty_fintype α
  cases' (truncSwapFactors f).out with l hl
  induction' l with g l ih generalizing f
  · simp (config := { contextual := true }) only [hl.left.symm, List.prod_nil, forall_true_iff]
  · intro h1 hmul_swap
    rcases hl.2 g (by 

Proof state:
α : Type u
β : Type v
inst✝¹ : DecidableEq α
inst✝ : Finite α
P : Perm α → Prop
val✝ : Fintype α
g : Perm α
l : List (Perm α)
ih :
  ∀ (f : Perm α),
    (List.prod l = f ∧ ∀ g ∈ l, IsSwap g) → P 1 → (∀ (f : Perm α) (x y : α), x ≠ y → P f → P (swap x y * f)) → P f
f : Perm α
hl : List.prod (g :: l) = f ∧ ∀ g_1 ∈ g :: l, IsSwap g_1
h1 : P 1
hmul_swap : ∀ (f : Perm α) (x y : α), x ≠ y → P f → P (swap x y * f)
⊢ g ∈ g :: l

Next tactic:
simp
/-- An induction principle for permutations. If `P` holds for the identity permutation, and
is preserved under composition with a non-trivial swap, then `P` holds for all permutations. -/
@[elab_as_elim]
theorem swap_induction_on [Finite α] {P : Perm α → Prop} (f : Perm α) :
    P 1 → (∀ f x y, x ≠ y → P f → P (swap x y * f)) → P f := by
  cases nonempty_fintype α
  cases' (truncSwapFactors f).out with l hl
  induction' l with g l ih generalizing f
  · simp (config := { contextual := true }) only [hl.left.symm, List.prod_nil, forall_true_iff]
  · intro h1 hmul_swap
    rcases hl.2 g (by simp) with ⟨x, y, hxy⟩
    

Proof state:
case intro.mk.cons.intro.intro
α : Type u
β : Type v
inst✝¹ : DecidableEq α
inst✝ : Finite α
P : Perm α → Prop
val✝ : Fintype α
g : Perm α
l : List (Perm α)
ih :
  ∀ (f : Perm α),
    (List.prod l = f ∧ ∀ g ∈ l, IsSwap g) → P 1 → (∀ (f : Perm α) (x y : α), x ≠ y → P f → P (swap x y * f)) → P f
f : Perm α
hl : List.prod (g :: l) = f ∧ ∀ g_1 ∈ g :: l, IsSwap g_1
h1 : P 1
hmul_swap : ∀ (f : Perm α) (x y : α), x ≠ y → P f → P (swap x y * f)
x y : α
hxy : x ≠ y ∧ g = swap x y
⊢ P f

Next tactic:
rw [← hl.1, List.prod_cons, hxy.2]
/-- An induction principle for permutations. If `P` holds for the identity permutation, and
is preserved under composition with a non-trivial swap, then `P` holds for all permutations. -/
@[elab_as_elim]
theorem swap_induction_on [Finite α] {P : Perm α → Prop} (f : Perm α) :
    P 1 → (∀ f x y, x ≠ y → P f → P (swap x y * f)) → P f := by
  cases nonempty_fintype α
  cases' (truncSwapFactors f).out with l hl
  induction' l with g l ih generalizing f
  · simp (config := { contextual := true }) only [hl.left.symm, List.prod_nil, forall_true_iff]
  · intro h1 hmul_swap
    rcases hl.2 g (by simp) with ⟨x, y, hxy⟩
    rw [← hl.1, List.prod_cons, hxy.2]
    

Proof state:
case intro.mk.cons.intro.intro
α : Type u
β : Type v
inst✝¹ : DecidableEq α
inst✝ : Finite α
P : Perm α → Prop
val✝ : Fintype α
g : Perm α
l : List (Perm α)
ih :
  ∀ (f : Perm α),
    (List.prod l = f ∧ ∀ g ∈ l, IsSwap g) → P 1 → (∀ (f : Perm α) (x y : α), x ≠ y → P f → P (swap x y * f)) → P f
f : Perm α
hl : List.prod (g :: l) = f ∧ ∀ g_1 ∈ g :: l, IsSwap g_1
h1 : P 1
hmul_swap : ∀ (f : Perm α) (x y : α), x ≠ y → P f → P (swap x y * f)
x y : α
hxy : x ≠ y ∧ g = swap x y
⊢ P (swap x y * List.prod l)

Next tactic:
exact
      hmul_swap _ _ _ hxy.1
        (ih _ ⟨rfl, fun v hv => hl.2 _ (List.mem_cons_of_mem _ hv)⟩ h1 hmul_swap)
theorem closure_isSwap [Finite α] : Subgroup.closure { σ : Perm α | IsSwap σ } = ⊤ := by
  

Proof state:
α : Type u
β : Type v
inst✝¹ : DecidableEq α
inst✝ : Finite α
⊢ Subgroup.closure {σ | IsSwap σ} = ⊤

Next tactic:
cases nonempty_fintype α
theorem closure_isSwap [Finite α] : Subgroup.closure { σ : Perm α | IsSwap σ } = ⊤ := by
  cases nonempty_fintype α
  

Proof state:
case intro
α : Type u
β : Type v
inst✝¹ : DecidableEq α
inst✝ : Finite α
val✝ : Fintype α
⊢ Subgroup.closure {σ | IsSwap σ} = ⊤

Next tactic:
refine' eq_top_iff.mpr fun x _ => _
theorem closure_isSwap [Finite α] : Subgroup.closure { σ : Perm α | IsSwap σ } = ⊤ := by
  cases nonempty_fintype α
  refine' eq_top_iff.mpr fun x _ => _
  

Proof state:
case intro
α : Type u
β : Type v
inst✝¹ : DecidableEq α
inst✝ : Finite α
val✝ : Fintype α
x : Perm α
x✝ : x ∈ ⊤
⊢ x ∈ Subgroup.closure {σ | IsSwap σ}

Next tactic:
obtain ⟨h1, h2⟩ := Subtype.mem (truncSwapFactors x).out
theorem closure_isSwap [Finite α] : Subgroup.closure { σ : Perm α | IsSwap σ } = ⊤ := by
  cases nonempty_fintype α
  refine' eq_top_iff.mpr fun x _ => _
  obtain ⟨h1, h2⟩ := Subtype.mem (truncSwapFactors x).out
  

Proof state:
case intro.intro
α : Type u
β : Type v
inst✝¹ : DecidableEq α
inst✝ : Finite α
val✝ : Fintype α
x : Perm α
x✝ : x ∈ ⊤
h1 : List.prod ↑(Trunc.out (truncSwapFactors x)) = x
h2 : ∀ g ∈ ↑(Trunc.out (truncSwapFactors x)), IsSwap g
⊢ x ∈ Subgroup.closure {σ | IsSwap σ}

Next tactic:
rw [← h1]
theorem closure_isSwap [Finite α] : Subgroup.closure { σ : Perm α | IsSwap σ } = ⊤ := by
  cases nonempty_fintype α
  refine' eq_top_iff.mpr fun x _ => _
  obtain ⟨h1, h2⟩ := Subtype.mem (truncSwapFactors x).out
  rw [← h1]
  

Proof state:
case intro.intro
α : Type u
β : Type v
inst✝¹ : DecidableEq α
inst✝ : Finite α
val✝ : Fintype α
x : Perm α
x✝ : x ∈ ⊤
h1 : List.prod ↑(Trunc.out (truncSwapFactors x)) = x
h2 : ∀ g ∈ ↑(Trunc.out (truncSwapFactors x)), IsSwap g
⊢ List.prod ↑(Trunc.out (truncSwapFactors x)) ∈ Subgroup.closure {σ | IsSwap σ}

Next tactic:
exact Subgroup.list_prod_mem _ fun y hy => Subgroup.subset_closure (h2 y hy)
theorem isConj_swap {w x y z : α} (hwx : w ≠ x) (hyz : y ≠ z) : IsConj (swap w x) (swap y z) :=
  isConj_iff.2
    (have h :
      ∀ {y z : α},
        y ≠ z → w ≠ z → swap w y * swap x z * swap w x * (swap w y * swap x z)⁻¹ = swap y z :=
      fun {y z} hyz hwz => by
      

Proof state:
α : Type u
β : Type v
inst✝ : DecidableEq α
w x y✝ z✝ : α
hwx : w ≠ x
hyz✝ : y✝ ≠ z✝
y z : α
hyz : y ≠ z
hwz : w ≠ z
⊢ swap w y * swap x z * swap w x * (swap w y * swap x z)⁻¹ = swap y z

Next tactic:
rw [mul_inv_rev, swap_inv, swap_inv, mul_assoc (swap w y), mul_assoc (swap w y), ←
        mul_assoc _ (swap x z), swap_mul_swap_mul_swap hwx hwz, ← mul_assoc,
        swap_mul_swap_mul_swap hwz.symm hyz.symm]
theorem isConj_swap {w x y z : α} (hwx : w ≠ x) (hyz : y ≠ z) : IsConj (swap w x) (swap y z) :=
  isConj_iff.2
    (have h :
      ∀ {y z : α},
        y ≠ z → w ≠ z → swap w y * swap x z * swap w x * (swap w y * swap x z)⁻¹ = swap y z :=
      fun {y z} hyz hwz => by
      rw [mul_inv_rev, swap_inv, swap_inv, mul_assoc (swap w y), mul_assoc (swap w y), ←
        mul_assoc _ (swap x z), swap_mul_swap_mul_swap hwx hwz, ← mul_assoc,
        swap_mul_swap_mul_swap hwz.symm hyz.symm]
    if hwz : w = z then
      have hwy : w ≠ y := by 

Proof state:
α : Type u
β : Type v
inst✝ : DecidableEq α
w x y z : α
hwx : w ≠ x
hyz : y ≠ z
h : ∀ {y z : α}, y ≠ z → w ≠ z → swap w y * swap x z * swap w x * (swap w y * swap x z)⁻¹ = swap y z
hwz : w = z
⊢ w ≠ y

Next tactic:
rw [hwz]
theorem isConj_swap {w x y z : α} (hwx : w ≠ x) (hyz : y ≠ z) : IsConj (swap w x) (swap y z) :=
  isConj_iff.2
    (have h :
      ∀ {y z : α},
        y ≠ z → w ≠ z → swap w y * swap x z * swap w x * (swap w y * swap x z)⁻¹ = swap y z :=
      fun {y z} hyz hwz => by
      rw [mul_inv_rev, swap_inv, swap_inv, mul_assoc (swap w y), mul_assoc (swap w y), ←
        mul_assoc _ (swap x z), swap_mul_swap_mul_swap hwx hwz, ← mul_assoc,
        swap_mul_swap_mul_swap hwz.symm hyz.symm]
    if hwz : w = z then
      have hwy : w ≠ y := by rw [hwz]; 

Proof state:
α : Type u
β : Type v
inst✝ : DecidableEq α
w x y z : α
hwx : w ≠ x
hyz : y ≠ z
h : ∀ {y z : α}, y ≠ z → w ≠ z → swap w y * swap x z * swap w x * (swap w y * swap x z)⁻¹ = swap y z
hwz : w = z
⊢ z ≠ y

Next tactic:
exact hyz.symm
theorem isConj_swap {w x y z : α} (hwx : w ≠ x) (hyz : y ≠ z) : IsConj (swap w x) (swap y z) :=
  isConj_iff.2
    (have h :
      ∀ {y z : α},
        y ≠ z → w ≠ z → swap w y * swap x z * swap w x * (swap w y * swap x z)⁻¹ = swap y z :=
      fun {y z} hyz hwz => by
      rw [mul_inv_rev, swap_inv, swap_inv, mul_assoc (swap w y), mul_assoc (swap w y), ←
        mul_assoc _ (swap x z), swap_mul_swap_mul_swap hwx hwz, ← mul_assoc,
        swap_mul_swap_mul_swap hwz.symm hyz.symm]
    if hwz : w = z then
      have hwy : w ≠ y := by rw [hwz]; exact hyz.symm
      ⟨swap w z * swap x y, by 

Proof state:
α : Type u
β : Type v
inst✝ : DecidableEq α
w x y z : α
hwx : w ≠ x
hyz : y ≠ z
h : ∀ {y z : α}, y ≠ z → w ≠ z → swap w y * swap x z * swap w x * (swap w y * swap x z)⁻¹ = swap y z
hwz : w = z
hwy : w ≠ y
⊢ swap w z * swap x y * swap w x * (swap w z * swap x y)⁻¹ = swap y z

Next tactic:
rw [swap_comm y z, h hyz.symm hwy]
theorem mem_finPairsLT {n : ℕ} {a : Σ_ : Fin n, Fin n} : a ∈ finPairsLT n ↔ a.2 < a.1 := by
  

Proof state:
α : Type u
β : Type v
inst✝ : DecidableEq α
n : ℕ
a : (_ : Fin n) × Fin n
⊢ a ∈ finPairsLT n ↔ a.snd < a.fst

Next tactic:
simp only [finPairsLT, Fin.lt_iff_val_lt_val, true_and_iff, mem_attachFin, mem_range, mem_univ,
    mem_sigma]
@[simp]
theorem signAux_one (n : ℕ) : signAux (1 : Perm (Fin n)) = 1 := by
  

Proof state:
α : Type u
β : Type v
inst✝ : DecidableEq α
n : ℕ
⊢ signAux 1 = 1

Next tactic:
unfold signAux
@[simp]
theorem signAux_one (n : ℕ) : signAux (1 : Perm (Fin n)) = 1 := by
  unfold signAux
  

Proof state:
α : Type u
β : Type v
inst✝ : DecidableEq α
n : ℕ
⊢ (∏ x in finPairsLT n, if 1 x.fst ≤ 1 x.snd then -1 else 1) = 1

Next tactic:
conv => rhs; rw [← @Finset.prod_const_one ℤˣ _ (finPairsLT n)]
@[simp]
theorem signAux_one (n : ℕ) : signAux (1 : Perm (Fin n)) = 1 := by
  unfold signAux
  conv => 

Proof state:
α : Type u
β : Type v
inst✝ : DecidableEq α
n : ℕ
| (∏ x in finPairsLT n, if 1 x.fst ≤ 1 x.snd then -1 else 1) = 1

Next tactic:
rhs; rw [← @Finset.prod_const_one ℤˣ _ (finPairsLT n)]
@[simp]
theorem signAux_one (n : ℕ) : signAux (1 : Perm (Fin n)) = 1 := by
  unfold signAux
  conv => 

Proof state:
α : Type u
β : Type v
inst✝ : DecidableEq α
n : ℕ
| (∏ x in finPairsLT n, if 1 x.fst ≤ 1 x.snd then -1 else 1) = 1

Next tactic:
rhs
@[simp]
theorem signAux_one (n : ℕ) : signAux (1 : Perm (Fin n)) = 1 := by
  unfold signAux
  conv => rhs; 

Proof state:
α : Type u
β : Type v
inst✝ : DecidableEq α
n : ℕ
| 1

Next tactic:
rw [← @Finset.prod_const_one ℤˣ _ (finPairsLT n)]
@[simp]
theorem signAux_one (n : ℕ) : signAux (1 : Perm (Fin n)) = 1 := by
  unfold signAux
  conv => rhs; rw [← @Finset.prod_const_one ℤˣ _ (finPairsLT n)]
  

Proof state:
α : Type u
β : Type v
inst✝ : DecidableEq α
n : ℕ
⊢ (∏ x in finPairsLT n, if 1 x.fst ≤ 1 x.snd then -1 else 1) = ∏ _x in finPairsLT n, 1

Next tactic:
exact Finset.prod_congr rfl fun a ha => if_neg (mem_finPairsLT.1 ha).not_le