l3lab/ntp-mathlib huggingface dataset:
theorem two_le_of_mem_cycleType {σ : Perm α} {n : ℕ} (h : n ∈ σ.cycleType) : 2 ≤ n := by
  simp only [cycleType_def, ← Finset.mem_def, Function.comp_apply, Multiset.mem_map,
    mem_cycleFactorsFinset_iff] at h
  obtain ⟨_, ⟨hc, -⟩, rfl⟩ := h
  

Proof state:
case intro.intro.intro
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ w✝ : Perm α
hc : IsCycle w✝
⊢ 2 ≤ Finset.card (support w✝)

Next tactic:
exact hc.two_le_card_support
theorem card_cycleType_eq_one {σ : Perm α} : Multiset.card σ.cycleType = 1 ↔ σ.IsCycle := by
  

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ : Perm α
⊢ card (cycleType σ) = 1 ↔ IsCycle σ

Next tactic:
rw [card_eq_one]
theorem card_cycleType_eq_one {σ : Perm α} : Multiset.card σ.cycleType = 1 ↔ σ.IsCycle := by
  rw [card_eq_one]
  

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ : Perm α
⊢ (∃ a, cycleType σ = {a}) ↔ IsCycle σ

Next tactic:
simp_rw [cycleType_def, Multiset.map_eq_singleton, ← Finset.singleton_val, Finset.val_inj,
    cycleFactorsFinset_eq_singleton_iff]
theorem card_cycleType_eq_one {σ : Perm α} : Multiset.card σ.cycleType = 1 ↔ σ.IsCycle := by
  rw [card_eq_one]
  simp_rw [cycleType_def, Multiset.map_eq_singleton, ← Finset.singleton_val, Finset.val_inj,
    cycleFactorsFinset_eq_singleton_iff]
  

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ : Perm α
⊢ (∃ a a_1, (IsCycle σ ∧ σ = a_1) ∧ (Finset.card ∘ support) a_1 = a) ↔ IsCycle σ

Next tactic:
constructor
theorem card_cycleType_eq_one {σ : Perm α} : Multiset.card σ.cycleType = 1 ↔ σ.IsCycle := by
  rw [card_eq_one]
  simp_rw [cycleType_def, Multiset.map_eq_singleton, ← Finset.singleton_val, Finset.val_inj,
    cycleFactorsFinset_eq_singleton_iff]
  constructor
  · 

Proof state:
case mp
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ : Perm α
⊢ (∃ a a_1, (IsCycle σ ∧ σ = a_1) ∧ (Finset.card ∘ support) a_1 = a) → IsCycle σ

Next tactic:
rintro ⟨_, _, ⟨h, -⟩, -⟩
theorem card_cycleType_eq_one {σ : Perm α} : Multiset.card σ.cycleType = 1 ↔ σ.IsCycle := by
  rw [card_eq_one]
  simp_rw [cycleType_def, Multiset.map_eq_singleton, ← Finset.singleton_val, Finset.val_inj,
    cycleFactorsFinset_eq_singleton_iff]
  constructor
  · rintro ⟨_, _, ⟨h, -⟩, -⟩
    

Proof state:
case mp.intro.intro.intro.intro
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ : Perm α
w✝¹ : ℕ
w✝ : Perm α
h : IsCycle σ
⊢ IsCycle σ

Next tactic:
exact h
theorem card_cycleType_eq_one {σ : Perm α} : Multiset.card σ.cycleType = 1 ↔ σ.IsCycle := by
  rw [card_eq_one]
  simp_rw [cycleType_def, Multiset.map_eq_singleton, ← Finset.singleton_val, Finset.val_inj,
    cycleFactorsFinset_eq_singleton_iff]
  constructor
  · rintro ⟨_, _, ⟨h, -⟩, -⟩
    exact h
  · 

Proof state:
case mpr
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ : Perm α
⊢ IsCycle σ → ∃ a a_1, (IsCycle σ ∧ σ = a_1) ∧ (Finset.card ∘ support) a_1 = a

Next tactic:
intro h
theorem card_cycleType_eq_one {σ : Perm α} : Multiset.card σ.cycleType = 1 ↔ σ.IsCycle := by
  rw [card_eq_one]
  simp_rw [cycleType_def, Multiset.map_eq_singleton, ← Finset.singleton_val, Finset.val_inj,
    cycleFactorsFinset_eq_singleton_iff]
  constructor
  · rintro ⟨_, _, ⟨h, -⟩, -⟩
    exact h
  · intro h
    

Proof state:
case mpr
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ : Perm α
h : IsCycle σ
⊢ ∃ a a_1, (IsCycle σ ∧ σ = a_1) ∧ (Finset.card ∘ support) a_1 = a

Next tactic:
use σ.support.card, σ
theorem card_cycleType_eq_one {σ : Perm α} : Multiset.card σ.cycleType = 1 ↔ σ.IsCycle := by
  rw [card_eq_one]
  simp_rw [cycleType_def, Multiset.map_eq_singleton, ← Finset.singleton_val, Finset.val_inj,
    cycleFactorsFinset_eq_singleton_iff]
  constructor
  · rintro ⟨_, _, ⟨h, -⟩, -⟩
    exact h
  · intro h
    use σ.support.card, σ
    

Proof state:
case h
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ : Perm α
h : IsCycle σ
⊢ (IsCycle σ ∧ σ = σ) ∧ (Finset.card ∘ support) σ = Finset.card (support σ)

Next tactic:
simp [h]
theorem Disjoint.cycleType {σ τ : Perm α} (h : Disjoint σ τ) :
    (σ * τ).cycleType = σ.cycleType + τ.cycleType := by
  

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ τ : Perm α
h : Disjoint σ τ
⊢ Perm.cycleType (σ * τ) = Perm.cycleType σ + Perm.cycleType τ

Next tactic:
rw [cycleType_def, cycleType_def, cycleType_def, h.cycleFactorsFinset_mul_eq_union, ←
    Multiset.map_add, Finset.union_val, Multiset.add_eq_union_iff_disjoint.mpr _]
theorem Disjoint.cycleType {σ τ : Perm α} (h : Disjoint σ τ) :
    (σ * τ).cycleType = σ.cycleType + τ.cycleType := by
  rw [cycleType_def, cycleType_def, cycleType_def, h.cycleFactorsFinset_mul_eq_union, ←
    Multiset.map_add, Finset.union_val, Multiset.add_eq_union_iff_disjoint.mpr _]
  

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ τ : Perm α
h : Disjoint σ τ
⊢ Multiset.Disjoint (cycleFactorsFinset σ).val (cycleFactorsFinset τ).val

Next tactic:
exact Finset.disjoint_val.2 h.disjoint_cycleFactorsFinset
@[simp] -- porting note: new attr
theorem cycleType_inv (σ : Perm α) : σ⁻¹.cycleType = σ.cycleType :=
  cycle_induction_on (P := fun τ : Perm α => τ⁻¹.cycleType = τ.cycleType) σ rfl
    (fun σ hσ => by 

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ✝ σ : Perm α
hσ : IsCycle σ
⊢ (fun τ => cycleType τ⁻¹ = cycleType τ) σ

Next tactic:
simp only [hσ.cycleType, hσ.inv.cycleType, support_inv]
@[simp] -- porting note: new attr
theorem cycleType_inv (σ : Perm α) : σ⁻¹.cycleType = σ.cycleType :=
  cycle_induction_on (P := fun τ : Perm α => τ⁻¹.cycleType = τ.cycleType) σ rfl
    (fun σ hσ => by simp only [hσ.cycleType, hσ.inv.cycleType, support_inv])
    fun σ τ hστ _ hσ hτ => by
      

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ✝ σ τ : Perm α
hστ : Disjoint σ τ
x✝ : IsCycle σ
hσ : (fun τ => cycleType τ⁻¹ = cycleType τ) σ
hτ : (fun τ => cycleType τ⁻¹ = cycleType τ) τ
⊢ (fun τ => cycleType τ⁻¹ = cycleType τ) (σ * τ)

Next tactic:
simp only [mul_inv_rev, hστ.cycleType, hστ.symm.inv_left.inv_right.cycleType, hσ, hτ,
        add_comm]
@[simp] -- porting note: new attr
theorem cycleType_conj {σ τ : Perm α} : (τ * σ * τ⁻¹).cycleType = σ.cycleType := by
  

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ τ : Perm α
⊢ cycleType (τ * σ * τ⁻¹) = cycleType σ

Next tactic:
induction σ using cycle_induction_on with
  | base_one => simp
  | base_cycles σ hσ => rw [hσ.cycleType, hσ.conj.cycleType, card_support_conj]
  | induction_disjoint σ π hd _ hσ hπ =>
    rw [← conj_mul, hd.cycleType, (hd.conj _).cycleType, hσ, hπ]
@[simp] -- porting note: new attr
theorem cycleType_conj {σ τ : Perm α} : (τ * σ * τ⁻¹).cycleType = σ.cycleType := by
  induction σ using cycle_induction_on with
  

Proof state:
case base_one
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
τ : Perm α
⊢ cycleType (τ * 1 * τ⁻¹) = cycleType 1

Next tactic:
| base_one => simp
@[simp] -- porting note: new attr
theorem cycleType_conj {σ τ : Perm α} : (τ * σ * τ⁻¹).cycleType = σ.cycleType := by
  induction σ using cycle_induction_on with
  | base_one => 

Proof state:
case base_one
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
τ : Perm α
⊢ cycleType (τ * 1 * τ⁻¹) = cycleType 1

Next tactic:
simp
@[simp] -- porting note: new attr
theorem cycleType_conj {σ τ : Perm α} : (τ * σ * τ⁻¹).cycleType = σ.cycleType := by
  induction σ using cycle_induction_on with
  | base_one => simp
  

Proof state:
case base_cycles
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
τ σ : Perm α
hσ : IsCycle σ
⊢ cycleType (τ * σ * τ⁻¹) = cycleType σ

Next tactic:
| base_cycles σ hσ => rw [hσ.cycleType, hσ.conj.cycleType, card_support_conj]
@[simp] -- porting note: new attr
theorem cycleType_conj {σ τ : Perm α} : (τ * σ * τ⁻¹).cycleType = σ.cycleType := by
  induction σ using cycle_induction_on with
  | base_one => simp
  | base_cycles σ hσ => 

Proof state:
case base_cycles
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
τ σ : Perm α
hσ : IsCycle σ
⊢ cycleType (τ * σ * τ⁻¹) = cycleType σ

Next tactic:
rw [hσ.cycleType, hσ.conj.cycleType, card_support_conj]
@[simp] -- porting note: new attr
theorem cycleType_conj {σ τ : Perm α} : (τ * σ * τ⁻¹).cycleType = σ.cycleType := by
  induction σ using cycle_induction_on with
  | base_one => simp
  | base_cycles σ hσ => rw [hσ.cycleType, hσ.conj.cycleType, card_support_conj]
  

Proof state:
case induction_disjoint
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
τ σ π : Perm α
hd : Disjoint σ π
a✝ : IsCycle σ
hσ : cycleType (τ * σ * τ⁻¹) = cycleType σ
hπ : cycleType (τ * π * τ⁻¹) = cycleType π
⊢ cycleType (τ * (σ * π) * τ⁻¹) = cycleType (σ * π)

Next tactic:
| induction_disjoint σ π hd _ hσ hπ =>
    rw [← conj_mul, hd.cycleType, (hd.conj _).cycleType, hσ, hπ]
@[simp] -- porting note: new attr
theorem cycleType_conj {σ τ : Perm α} : (τ * σ * τ⁻¹).cycleType = σ.cycleType := by
  induction σ using cycle_induction_on with
  | base_one => simp
  | base_cycles σ hσ => rw [hσ.cycleType, hσ.conj.cycleType, card_support_conj]
  | induction_disjoint σ π hd _ hσ hπ =>
    

Proof state:
case induction_disjoint
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
τ σ π : Perm α
hd : Disjoint σ π
a✝ : IsCycle σ
hσ : cycleType (τ * σ * τ⁻¹) = cycleType σ
hπ : cycleType (τ * π * τ⁻¹) = cycleType π
⊢ cycleType (τ * (σ * π) * τ⁻¹) = cycleType (σ * π)

Next tactic:
rw [← conj_mul, hd.cycleType, (hd.conj _).cycleType, hσ, hπ]
theorem sum_cycleType (σ : Perm α) : σ.cycleType.sum = σ.support.card := by
  

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ : Perm α
⊢ sum (cycleType σ) = Finset.card (support σ)

Next tactic:
induction σ using cycle_induction_on with
  | base_one => simp
  | base_cycles σ hσ => rw [hσ.cycleType, coe_sum, List.sum_singleton]
  | induction_disjoint σ τ hd _ hσ hτ => rw [hd.cycleType, sum_add, hσ, hτ, hd.card_support_mul]
theorem sum_cycleType (σ : Perm α) : σ.cycleType.sum = σ.support.card := by
  induction σ using cycle_induction_on with
  

Proof state:
case base_one
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
⊢ sum (cycleType 1) = Finset.card (support 1)

Next tactic:
| base_one => simp
theorem sum_cycleType (σ : Perm α) : σ.cycleType.sum = σ.support.card := by
  induction σ using cycle_induction_on with
  | base_one => 

Proof state:
case base_one
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
⊢ sum (cycleType 1) = Finset.card (support 1)

Next tactic:
simp
theorem sum_cycleType (σ : Perm α) : σ.cycleType.sum = σ.support.card := by
  induction σ using cycle_induction_on with
  | base_one => simp
  

Proof state:
case base_cycles
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ : Perm α
hσ : IsCycle σ
⊢ sum (cycleType σ) = Finset.card (support σ)

Next tactic:
| base_cycles σ hσ => rw [hσ.cycleType, coe_sum, List.sum_singleton]
theorem sum_cycleType (σ : Perm α) : σ.cycleType.sum = σ.support.card := by
  induction σ using cycle_induction_on with
  | base_one => simp
  | base_cycles σ hσ => 

Proof state:
case base_cycles
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ : Perm α
hσ : IsCycle σ
⊢ sum (cycleType σ) = Finset.card (support σ)

Next tactic:
rw [hσ.cycleType, coe_sum, List.sum_singleton]
theorem sum_cycleType (σ : Perm α) : σ.cycleType.sum = σ.support.card := by
  induction σ using cycle_induction_on with
  | base_one => simp
  | base_cycles σ hσ => rw [hσ.cycleType, coe_sum, List.sum_singleton]
  

Proof state:
case induction_disjoint
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ τ : Perm α
hd : Disjoint σ τ
a✝ : IsCycle σ
hσ : sum (cycleType σ) = Finset.card (support σ)
hτ : sum (cycleType τ) = Finset.card (support τ)
⊢ sum (cycleType (σ * τ)) = Finset.card (support (σ * τ))

Next tactic:
| induction_disjoint σ τ hd _ hσ hτ => rw [hd.cycleType, sum_add, hσ, hτ, hd.card_support_mul]
theorem sum_cycleType (σ : Perm α) : σ.cycleType.sum = σ.support.card := by
  induction σ using cycle_induction_on with
  | base_one => simp
  | base_cycles σ hσ => rw [hσ.cycleType, coe_sum, List.sum_singleton]
  | induction_disjoint σ τ hd _ hσ hτ => 

Proof state:
case induction_disjoint
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ τ : Perm α
hd : Disjoint σ τ
a✝ : IsCycle σ
hσ : sum (cycleType σ) = Finset.card (support σ)
hτ : sum (cycleType τ) = Finset.card (support τ)
⊢ sum (cycleType (σ * τ)) = Finset.card (support (σ * τ))

Next tactic:
rw [hd.cycleType, sum_add, hσ, hτ, hd.card_support_mul]
theorem sign_of_cycleType' (σ : Perm α) :
    sign σ = (σ.cycleType.map fun n => -(-1 : ℤˣ) ^ n).prod := by
  

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ : Perm α
⊢ sign σ = prod (map (fun n => -(-1) ^ n) (cycleType σ))

Next tactic:
induction σ using cycle_induction_on with
  | base_one => simp
  | base_cycles σ hσ => simp [hσ.cycleType, hσ.sign]
  | induction_disjoint σ τ hd _ hσ hτ => simp [hσ, hτ, hd.cycleType]
theorem sign_of_cycleType' (σ : Perm α) :
    sign σ = (σ.cycleType.map fun n => -(-1 : ℤˣ) ^ n).prod := by
  induction σ using cycle_induction_on with
  

Proof state:
case base_one
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
⊢ sign 1 = prod (map (fun n => -(-1) ^ n) (cycleType 1))

Next tactic:
| base_one => simp
theorem sign_of_cycleType' (σ : Perm α) :
    sign σ = (σ.cycleType.map fun n => -(-1 : ℤˣ) ^ n).prod := by
  induction σ using cycle_induction_on with
  | base_one => 

Proof state:
case base_one
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
⊢ sign 1 = prod (map (fun n => -(-1) ^ n) (cycleType 1))

Next tactic:
simp
theorem sign_of_cycleType' (σ : Perm α) :
    sign σ = (σ.cycleType.map fun n => -(-1 : ℤˣ) ^ n).prod := by
  induction σ using cycle_induction_on with
  | base_one => simp
  

Proof state:
case base_cycles
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ : Perm α
hσ : IsCycle σ
⊢ sign σ = prod (map (fun n => -(-1) ^ n) (cycleType σ))

Next tactic:
| base_cycles σ hσ => simp [hσ.cycleType, hσ.sign]
theorem sign_of_cycleType' (σ : Perm α) :
    sign σ = (σ.cycleType.map fun n => -(-1 : ℤˣ) ^ n).prod := by
  induction σ using cycle_induction_on with
  | base_one => simp
  | base_cycles σ hσ => 

Proof state:
case base_cycles
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ : Perm α
hσ : IsCycle σ
⊢ sign σ = prod (map (fun n => -(-1) ^ n) (cycleType σ))

Next tactic:
simp [hσ.cycleType, hσ.sign]
theorem sign_of_cycleType' (σ : Perm α) :
    sign σ = (σ.cycleType.map fun n => -(-1 : ℤˣ) ^ n).prod := by
  induction σ using cycle_induction_on with
  | base_one => simp
  | base_cycles σ hσ => simp [hσ.cycleType, hσ.sign]
  

Proof state:
case induction_disjoint
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ τ : Perm α
hd : Disjoint σ τ
a✝ : IsCycle σ
hσ : sign σ = prod (map (fun n => -(-1) ^ n) (cycleType σ))
hτ : sign τ = prod (map (fun n => -(-1) ^ n) (cycleType τ))
⊢ sign (σ * τ) = prod (map (fun n => -(-1) ^ n) (cycleType (σ * τ)))

Next tactic:
| induction_disjoint σ τ hd _ hσ hτ => simp [hσ, hτ, hd.cycleType]
theorem sign_of_cycleType' (σ : Perm α) :
    sign σ = (σ.cycleType.map fun n => -(-1 : ℤˣ) ^ n).prod := by
  induction σ using cycle_induction_on with
  | base_one => simp
  | base_cycles σ hσ => simp [hσ.cycleType, hσ.sign]
  | induction_disjoint σ τ hd _ hσ hτ => 

Proof state:
case induction_disjoint
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ τ : Perm α
hd : Disjoint σ τ
a✝ : IsCycle σ
hσ : sign σ = prod (map (fun n => -(-1) ^ n) (cycleType σ))
hτ : sign τ = prod (map (fun n => -(-1) ^ n) (cycleType τ))
⊢ sign (σ * τ) = prod (map (fun n => -(-1) ^ n) (cycleType (σ * τ)))

Next tactic:
simp [hσ, hτ, hd.cycleType]
theorem sign_of_cycleType (f : Perm α) :
    sign f = (-1 : ℤˣ) ^ (f.cycleType.sum + Multiset.card f.cycleType) := by
  

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
f : Perm α
⊢ sign f = (-1) ^ (sum (cycleType f) + card (cycleType f))

Next tactic:
rw [sign_of_cycleType']
theorem sign_of_cycleType (f : Perm α) :
    sign f = (-1 : ℤˣ) ^ (f.cycleType.sum + Multiset.card f.cycleType) := by
  rw [sign_of_cycleType']
  

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
f : Perm α
⊢ prod (map (fun n => -(-1) ^ n) (cycleType f)) = (-1) ^ (sum (cycleType f) + card (cycleType f))

Next tactic:
induction' f.cycleType using Multiset.induction_on with a s ihs
theorem sign_of_cycleType (f : Perm α) :
    sign f = (-1 : ℤˣ) ^ (f.cycleType.sum + Multiset.card f.cycleType) := by
  rw [sign_of_cycleType']
  induction' f.cycleType using Multiset.induction_on with a s ihs
  · 

Proof state:
case empty
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
f : Perm α
⊢ prod (map (fun n => -(-1) ^ n) 0) = (-1) ^ (sum 0 + card 0)

Next tactic:
rfl
theorem sign_of_cycleType (f : Perm α) :
    sign f = (-1 : ℤˣ) ^ (f.cycleType.sum + Multiset.card f.cycleType) := by
  rw [sign_of_cycleType']
  induction' f.cycleType using Multiset.induction_on with a s ihs
  · rfl
  · 

Proof state:
case cons
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
f : Perm α
a : ℕ
s : Multiset ℕ
ihs : prod (map (fun n => -(-1) ^ n) s) = (-1) ^ (sum s + card s)
⊢ prod (map (fun n => -(-1) ^ n) (a ::ₘ s)) = (-1) ^ (sum (a ::ₘ s) + card (a ::ₘ s))

Next tactic:
rw [Multiset.map_cons, Multiset.prod_cons, Multiset.sum_cons, Multiset.card_cons, ihs]
theorem sign_of_cycleType (f : Perm α) :
    sign f = (-1 : ℤˣ) ^ (f.cycleType.sum + Multiset.card f.cycleType) := by
  rw [sign_of_cycleType']
  induction' f.cycleType using Multiset.induction_on with a s ihs
  · rfl
  · rw [Multiset.map_cons, Multiset.prod_cons, Multiset.sum_cons, Multiset.card_cons, ihs]
    

Proof state:
case cons
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
f : Perm α
a : ℕ
s : Multiset ℕ
ihs : prod (map (fun n => -(-1) ^ n) s) = (-1) ^ (sum s + card s)
⊢ -(-1) ^ a * (-1) ^ (sum s + card s) = (-1) ^ (a + sum s + (card s + 1))

Next tactic:
simp only [pow_add, pow_one, mul_neg_one, neg_mul, mul_neg, mul_assoc, mul_one]
@[simp] -- porting note: new attr
theorem lcm_cycleType (σ : Perm α) : σ.cycleType.lcm = orderOf σ := by
  

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ : Perm α
⊢ Multiset.lcm (cycleType σ) = orderOf σ

Next tactic:
induction σ using cycle_induction_on with
  | base_one => simp
  | base_cycles σ hσ => simp [hσ.cycleType, hσ.orderOf]
  | induction_disjoint σ τ hd _ hσ hτ => simp [hd.cycleType, hd.orderOf, lcm_eq_nat_lcm, hσ, hτ]
@[simp] -- porting note: new attr
theorem lcm_cycleType (σ : Perm α) : σ.cycleType.lcm = orderOf σ := by
  induction σ using cycle_induction_on with
  

Proof state:
case base_one
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
⊢ Multiset.lcm (cycleType 1) = orderOf 1

Next tactic:
| base_one => simp
@[simp] -- porting note: new attr
theorem lcm_cycleType (σ : Perm α) : σ.cycleType.lcm = orderOf σ := by
  induction σ using cycle_induction_on with
  | base_one => 

Proof state:
case base_one
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
⊢ Multiset.lcm (cycleType 1) = orderOf 1

Next tactic:
simp
@[simp] -- porting note: new attr
theorem lcm_cycleType (σ : Perm α) : σ.cycleType.lcm = orderOf σ := by
  induction σ using cycle_induction_on with
  | base_one => simp
  

Proof state:
case base_cycles
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ : Perm α
hσ : IsCycle σ
⊢ Multiset.lcm (cycleType σ) = orderOf σ

Next tactic:
| base_cycles σ hσ => simp [hσ.cycleType, hσ.orderOf]
@[simp] -- porting note: new attr
theorem lcm_cycleType (σ : Perm α) : σ.cycleType.lcm = orderOf σ := by
  induction σ using cycle_induction_on with
  | base_one => simp
  | base_cycles σ hσ => 

Proof state:
case base_cycles
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ : Perm α
hσ : IsCycle σ
⊢ Multiset.lcm (cycleType σ) = orderOf σ

Next tactic:
simp [hσ.cycleType, hσ.orderOf]
@[simp] -- porting note: new attr
theorem lcm_cycleType (σ : Perm α) : σ.cycleType.lcm = orderOf σ := by
  induction σ using cycle_induction_on with
  | base_one => simp
  | base_cycles σ hσ => simp [hσ.cycleType, hσ.orderOf]
  

Proof state:
case induction_disjoint
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ τ : Perm α
hd : Disjoint σ τ
a✝ : IsCycle σ
hσ : Multiset.lcm (cycleType σ) = orderOf σ
hτ : Multiset.lcm (cycleType τ) = orderOf τ
⊢ Multiset.lcm (cycleType (σ * τ)) = orderOf (σ * τ)

Next tactic:
| induction_disjoint σ τ hd _ hσ hτ => simp [hd.cycleType, hd.orderOf, lcm_eq_nat_lcm, hσ, hτ]
@[simp] -- porting note: new attr
theorem lcm_cycleType (σ : Perm α) : σ.cycleType.lcm = orderOf σ := by
  induction σ using cycle_induction_on with
  | base_one => simp
  | base_cycles σ hσ => simp [hσ.cycleType, hσ.orderOf]
  | induction_disjoint σ τ hd _ hσ hτ => 

Proof state:
case induction_disjoint
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ τ : Perm α
hd : Disjoint σ τ
a✝ : IsCycle σ
hσ : Multiset.lcm (cycleType σ) = orderOf σ
hτ : Multiset.lcm (cycleType τ) = orderOf τ
⊢ Multiset.lcm (cycleType (σ * τ)) = orderOf (σ * τ)

Next tactic:
simp [hd.cycleType, hd.orderOf, lcm_eq_nat_lcm, hσ, hτ]
theorem dvd_of_mem_cycleType {σ : Perm α} {n : ℕ} (h : n ∈ σ.cycleType) : n ∣ orderOf σ := by
  

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ : Perm α
n : ℕ
h : n ∈ cycleType σ
⊢ n ∣ orderOf σ

Next tactic:
rw [← lcm_cycleType]
theorem dvd_of_mem_cycleType {σ : Perm α} {n : ℕ} (h : n ∈ σ.cycleType) : n ∣ orderOf σ := by
  rw [← lcm_cycleType]
  

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ : Perm α
n : ℕ
h : n ∈ cycleType σ
⊢ n ∣ Multiset.lcm (cycleType σ)

Next tactic:
exact dvd_lcm h
theorem orderOf_cycleOf_dvd_orderOf (f : Perm α) (x : α) : orderOf (cycleOf f x) ∣ orderOf f := by
  

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
f : Perm α
x : α
⊢ orderOf (cycleOf f x) ∣ orderOf f

Next tactic:
by_cases hx : f x = x
theorem orderOf_cycleOf_dvd_orderOf (f : Perm α) (x : α) : orderOf (cycleOf f x) ∣ orderOf f := by
  by_cases hx : f x = x
  · 

Proof state:
case pos
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
f : Perm α
x : α
hx : f x = x
⊢ orderOf (cycleOf f x) ∣ orderOf f

Next tactic:
rw [← cycleOf_eq_one_iff] at hx
theorem orderOf_cycleOf_dvd_orderOf (f : Perm α) (x : α) : orderOf (cycleOf f x) ∣ orderOf f := by
  by_cases hx : f x = x
  · rw [← cycleOf_eq_one_iff] at hx
    

Proof state:
case pos
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
f : Perm α
x : α
hx : cycleOf f x = 1
⊢ orderOf (cycleOf f x) ∣ orderOf f

Next tactic:
simp [hx]
theorem orderOf_cycleOf_dvd_orderOf (f : Perm α) (x : α) : orderOf (cycleOf f x) ∣ orderOf f := by
  by_cases hx : f x = x
  · rw [← cycleOf_eq_one_iff] at hx
    simp [hx]
  · 

Proof state:
case neg
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
f : Perm α
x : α
hx : ¬f x = x
⊢ orderOf (cycleOf f x) ∣ orderOf f

Next tactic:
refine dvd_of_mem_cycleType ?_
theorem orderOf_cycleOf_dvd_orderOf (f : Perm α) (x : α) : orderOf (cycleOf f x) ∣ orderOf f := by
  by_cases hx : f x = x
  · rw [← cycleOf_eq_one_iff] at hx
    simp [hx]
  · refine dvd_of_mem_cycleType ?_
    

Proof state:
case neg
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
f : Perm α
x : α
hx : ¬f x = x
⊢ orderOf (cycleOf f x) ∈ cycleType f

Next tactic:
rw [cycleType, Multiset.mem_map]
theorem orderOf_cycleOf_dvd_orderOf (f : Perm α) (x : α) : orderOf (cycleOf f x) ∣ orderOf f := by
  by_cases hx : f x = x
  · rw [← cycleOf_eq_one_iff] at hx
    simp [hx]
  · refine dvd_of_mem_cycleType ?_
    rw [cycleType, Multiset.mem_map]
    

Proof state:
case neg
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
f : Perm α
x : α
hx : ¬f x = x
⊢ ∃ a ∈ (cycleFactorsFinset f).val, (Finset.card ∘ support) a = orderOf (cycleOf f x)

Next tactic:
refine' ⟨f.cycleOf x, _, _⟩
theorem orderOf_cycleOf_dvd_orderOf (f : Perm α) (x : α) : orderOf (cycleOf f x) ∣ orderOf f := by
  by_cases hx : f x = x
  · rw [← cycleOf_eq_one_iff] at hx
    simp [hx]
  · refine dvd_of_mem_cycleType ?_
    rw [cycleType, Multiset.mem_map]
    refine' ⟨f.cycleOf x, _, _⟩
    · 

Proof state:
case neg.refine'_1
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
f : Perm α
x : α
hx : ¬f x = x
⊢ cycleOf f x ∈ (cycleFactorsFinset f).val

Next tactic:
rwa [← Finset.mem_def, cycleOf_mem_cycleFactorsFinset_iff, mem_support]