l3lab/ntp-mathlib huggingface dataset:
open scoped List in
theorem cycleFactorsFinset_eq_list_toFinset {σ : Perm α} {l : List (Perm α)} (hn : l.Nodup) :
    σ.cycleFactorsFinset = l.toFinset ↔
      (∀ f : Perm α, f ∈ l → f.IsCycle) ∧ l.Pairwise Disjoint ∧ l.prod = σ := by
  obtain ⟨⟨l', hp', hc', hd'⟩, hl⟩ := Trunc.exists_rep σ.truncCycleFactors
  have ht : cycleFactorsFinset σ = l'.toFinset := by
    rw [cycleFactorsFinset, ← hl, Trunc.lift_mk]
  rw [ht]
  constructor
  · intro h
    have hn' : l'.Nodup := nodup_of_pairwise_disjoint_cycles hc' hd'
    have hperm : l ~ l' := List.perm_of_nodup_nodup_toFinset_eq hn hn' h.symm
    refine' ⟨_, _, _⟩
    · exact fun _ h => hc' _ (hperm.subset h)
    · have := List.Perm.pairwise_iff (@Disjoint.symmetric _) hperm
      rwa [this]
    · rw [← hp', hperm.symm.prod_eq']
      refine' hd'.imp _
      exact Disjoint.commute
  · rintro ⟨hc, hd, hp⟩
    refine' List.toFinset_eq_of_perm _ _ _
    

Proof state:
case intro.mk.intro.intro.mpr.intro.intro
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f σ : Perm α
l : List (Perm α)
hn : List.Nodup l
l' : List (Perm α)
hp' : List.prod l' = σ
hc' : ∀ g ∈ l', IsCycle g
hd' : List.Pairwise Disjoint l'
hl :
  Trunc.mk { val := l', property := (_ : List.prod l' = σ ∧ (∀ g ∈ l', IsCycle g) ∧ List.Pairwise Disjoint l') } =
    truncCycleFactors σ
ht : cycleFactorsFinset σ = List.toFinset l'
hc : ∀ f ∈ l, IsCycle f
hd : List.Pairwise Disjoint l
hp : List.prod l = σ
⊢ l' ~ l

Next tactic:
refine' list_cycles_perm_list_cycles _ hc' hc hd' hd
open scoped List in
theorem cycleFactorsFinset_eq_list_toFinset {σ : Perm α} {l : List (Perm α)} (hn : l.Nodup) :
    σ.cycleFactorsFinset = l.toFinset ↔
      (∀ f : Perm α, f ∈ l → f.IsCycle) ∧ l.Pairwise Disjoint ∧ l.prod = σ := by
  obtain ⟨⟨l', hp', hc', hd'⟩, hl⟩ := Trunc.exists_rep σ.truncCycleFactors
  have ht : cycleFactorsFinset σ = l'.toFinset := by
    rw [cycleFactorsFinset, ← hl, Trunc.lift_mk]
  rw [ht]
  constructor
  · intro h
    have hn' : l'.Nodup := nodup_of_pairwise_disjoint_cycles hc' hd'
    have hperm : l ~ l' := List.perm_of_nodup_nodup_toFinset_eq hn hn' h.symm
    refine' ⟨_, _, _⟩
    · exact fun _ h => hc' _ (hperm.subset h)
    · have := List.Perm.pairwise_iff (@Disjoint.symmetric _) hperm
      rwa [this]
    · rw [← hp', hperm.symm.prod_eq']
      refine' hd'.imp _
      exact Disjoint.commute
  · rintro ⟨hc, hd, hp⟩
    refine' List.toFinset_eq_of_perm _ _ _
    refine' list_cycles_perm_list_cycles _ hc' hc hd' hd
    

Proof state:
case intro.mk.intro.intro.mpr.intro.intro
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f σ : Perm α
l : List (Perm α)
hn : List.Nodup l
l' : List (Perm α)
hp' : List.prod l' = σ
hc' : ∀ g ∈ l', IsCycle g
hd' : List.Pairwise Disjoint l'
hl :
  Trunc.mk { val := l', property := (_ : List.prod l' = σ ∧ (∀ g ∈ l', IsCycle g) ∧ List.Pairwise Disjoint l') } =
    truncCycleFactors σ
ht : cycleFactorsFinset σ = List.toFinset l'
hc : ∀ f ∈ l, IsCycle f
hd : List.Pairwise Disjoint l
hp : List.prod l = σ
⊢ List.prod l' = List.prod l

Next tactic:
rw [hp, hp']
theorem cycleFactorsFinset_eq_finset {σ : Perm α} {s : Finset (Perm α)} :
    σ.cycleFactorsFinset = s ↔
      (∀ f : Perm α, f ∈ s → f.IsCycle) ∧
        ∃ h : (s : Set (Perm α)).Pairwise Disjoint,
          s.noncommProd id (h.mono' fun _ _ => Disjoint.commute) = σ := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f σ : Perm α
s : Finset (Perm α)
⊢ cycleFactorsFinset σ = s ↔
    (∀ f ∈ s, IsCycle f) ∧
      ∃ (h : Set.Pairwise (↑s) Disjoint), noncommProd s id (_ : Set.Pairwise ↑s fun a b => Commute (id a) (id b)) = σ

Next tactic:
obtain ⟨l, hl, rfl⟩ := s.exists_list_nodup_eq
theorem cycleFactorsFinset_eq_finset {σ : Perm α} {s : Finset (Perm α)} :
    σ.cycleFactorsFinset = s ↔
      (∀ f : Perm α, f ∈ s → f.IsCycle) ∧
        ∃ h : (s : Set (Perm α)).Pairwise Disjoint,
          s.noncommProd id (h.mono' fun _ _ => Disjoint.commute) = σ := by
  obtain ⟨l, hl, rfl⟩ := s.exists_list_nodup_eq
  

Proof state:
case intro.intro
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f σ : Perm α
l : List (Perm α)
hl : List.Nodup l
⊢ cycleFactorsFinset σ = List.toFinset l ↔
    (∀ f ∈ List.toFinset l, IsCycle f) ∧
      ∃ (h : Set.Pairwise (↑(List.toFinset l)) Disjoint),
        noncommProd (List.toFinset l) id (_ : Set.Pairwise ↑(List.toFinset l) fun a b => Commute (id a) (id b)) = σ

Next tactic:
simp [cycleFactorsFinset_eq_list_toFinset, hl]
theorem mem_cycleFactorsFinset_iff {f p : Perm α} :
    p ∈ cycleFactorsFinset f ↔ p.IsCycle ∧ ∀ a ∈ p.support, p a = f a := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f✝ f p : Perm α
⊢ p ∈ cycleFactorsFinset f ↔ IsCycle p ∧ ∀ a ∈ support p, p a = f a

Next tactic:
obtain ⟨l, hl, hl'⟩ := f.cycleFactorsFinset.exists_list_nodup_eq
theorem mem_cycleFactorsFinset_iff {f p : Perm α} :
    p ∈ cycleFactorsFinset f ↔ p.IsCycle ∧ ∀ a ∈ p.support, p a = f a := by
  obtain ⟨l, hl, hl'⟩ := f.cycleFactorsFinset.exists_list_nodup_eq
  

Proof state:
case intro.intro
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f✝ f p : Perm α
l : List (Perm α)
hl : List.Nodup l
hl' : List.toFinset l = cycleFactorsFinset f
⊢ p ∈ cycleFactorsFinset f ↔ IsCycle p ∧ ∀ a ∈ support p, p a = f a

Next tactic:
rw [← hl']
theorem mem_cycleFactorsFinset_iff {f p : Perm α} :
    p ∈ cycleFactorsFinset f ↔ p.IsCycle ∧ ∀ a ∈ p.support, p a = f a := by
  obtain ⟨l, hl, hl'⟩ := f.cycleFactorsFinset.exists_list_nodup_eq
  rw [← hl']
  

Proof state:
case intro.intro
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f✝ f p : Perm α
l : List (Perm α)
hl : List.Nodup l
hl' : List.toFinset l = cycleFactorsFinset f
⊢ p ∈ List.toFinset l ↔ IsCycle p ∧ ∀ a ∈ support p, p a = f a

Next tactic:
rw [eq_comm, cycleFactorsFinset_eq_list_toFinset hl] at hl'
theorem mem_cycleFactorsFinset_iff {f p : Perm α} :
    p ∈ cycleFactorsFinset f ↔ p.IsCycle ∧ ∀ a ∈ p.support, p a = f a := by
  obtain ⟨l, hl, hl'⟩ := f.cycleFactorsFinset.exists_list_nodup_eq
  rw [← hl']
  rw [eq_comm, cycleFactorsFinset_eq_list_toFinset hl] at hl'
  

Proof state:
case intro.intro
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f✝ f p : Perm α
l : List (Perm α)
hl : List.Nodup l
hl' : (∀ f ∈ l, IsCycle f) ∧ List.Pairwise Disjoint l ∧ List.prod l = f
⊢ p ∈ List.toFinset l ↔ IsCycle p ∧ ∀ a ∈ support p, p a = f a

Next tactic:
simpa [List.mem_toFinset, Ne.def, ← hl'.right.right] using
    mem_list_cycles_iff hl'.left hl'.right.left
theorem cycleOf_mem_cycleFactorsFinset_iff {f : Perm α} {x : α} :
    cycleOf f x ∈ cycleFactorsFinset f ↔ x ∈ f.support := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f✝ f : Perm α
x : α
⊢ cycleOf f x ∈ cycleFactorsFinset f ↔ x ∈ support f

Next tactic:
rw [mem_cycleFactorsFinset_iff]
theorem cycleOf_mem_cycleFactorsFinset_iff {f : Perm α} {x : α} :
    cycleOf f x ∈ cycleFactorsFinset f ↔ x ∈ f.support := by
  rw [mem_cycleFactorsFinset_iff]
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f✝ f : Perm α
x : α
⊢ (IsCycle (cycleOf f x) ∧ ∀ a ∈ support (cycleOf f x), (cycleOf f x) a = f a) ↔ x ∈ support f

Next tactic:
constructor
theorem cycleOf_mem_cycleFactorsFinset_iff {f : Perm α} {x : α} :
    cycleOf f x ∈ cycleFactorsFinset f ↔ x ∈ f.support := by
  rw [mem_cycleFactorsFinset_iff]
  constructor
  · 

Proof state:
case mp
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f✝ f : Perm α
x : α
⊢ (IsCycle (cycleOf f x) ∧ ∀ a ∈ support (cycleOf f x), (cycleOf f x) a = f a) → x ∈ support f

Next tactic:
rintro ⟨hc, _⟩
theorem cycleOf_mem_cycleFactorsFinset_iff {f : Perm α} {x : α} :
    cycleOf f x ∈ cycleFactorsFinset f ↔ x ∈ f.support := by
  rw [mem_cycleFactorsFinset_iff]
  constructor
  · rintro ⟨hc, _⟩
    

Proof state:
case mp.intro
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f✝ f : Perm α
x : α
hc : IsCycle (cycleOf f x)
right✝ : ∀ a ∈ support (cycleOf f x), (cycleOf f x) a = f a
⊢ x ∈ support f

Next tactic:
contrapose! hc
theorem cycleOf_mem_cycleFactorsFinset_iff {f : Perm α} {x : α} :
    cycleOf f x ∈ cycleFactorsFinset f ↔ x ∈ f.support := by
  rw [mem_cycleFactorsFinset_iff]
  constructor
  · rintro ⟨hc, _⟩
    contrapose! hc
    

Proof state:
case mp.intro
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f✝ f : Perm α
x : α
right✝ : ∀ a ∈ support (cycleOf f x), (cycleOf f x) a = f a
hc : x ∉ support f
⊢ ¬IsCycle (cycleOf f x)

Next tactic:
rw [not_mem_support, ← cycleOf_eq_one_iff] at hc
theorem cycleOf_mem_cycleFactorsFinset_iff {f : Perm α} {x : α} :
    cycleOf f x ∈ cycleFactorsFinset f ↔ x ∈ f.support := by
  rw [mem_cycleFactorsFinset_iff]
  constructor
  · rintro ⟨hc, _⟩
    contrapose! hc
    rw [not_mem_support, ← cycleOf_eq_one_iff] at hc
    

Proof state:
case mp.intro
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f✝ f : Perm α
x : α
right✝ : ∀ a ∈ support (cycleOf f x), (cycleOf f x) a = f a
hc : cycleOf f x = 1
⊢ ¬IsCycle (cycleOf f x)

Next tactic:
simp [hc]
theorem cycleOf_mem_cycleFactorsFinset_iff {f : Perm α} {x : α} :
    cycleOf f x ∈ cycleFactorsFinset f ↔ x ∈ f.support := by
  rw [mem_cycleFactorsFinset_iff]
  constructor
  · rintro ⟨hc, _⟩
    contrapose! hc
    rw [not_mem_support, ← cycleOf_eq_one_iff] at hc
    simp [hc]
  · 

Proof state:
case mpr
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f✝ f : Perm α
x : α
⊢ x ∈ support f → IsCycle (cycleOf f x) ∧ ∀ a ∈ support (cycleOf f x), (cycleOf f x) a = f a

Next tactic:
intro hx
theorem cycleOf_mem_cycleFactorsFinset_iff {f : Perm α} {x : α} :
    cycleOf f x ∈ cycleFactorsFinset f ↔ x ∈ f.support := by
  rw [mem_cycleFactorsFinset_iff]
  constructor
  · rintro ⟨hc, _⟩
    contrapose! hc
    rw [not_mem_support, ← cycleOf_eq_one_iff] at hc
    simp [hc]
  · intro hx
    

Proof state:
case mpr
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f✝ f : Perm α
x : α
hx : x ∈ support f
⊢ IsCycle (cycleOf f x) ∧ ∀ a ∈ support (cycleOf f x), (cycleOf f x) a = f a

Next tactic:
refine' ⟨isCycle_cycleOf _ (mem_support.mp hx), _⟩
theorem cycleOf_mem_cycleFactorsFinset_iff {f : Perm α} {x : α} :
    cycleOf f x ∈ cycleFactorsFinset f ↔ x ∈ f.support := by
  rw [mem_cycleFactorsFinset_iff]
  constructor
  · rintro ⟨hc, _⟩
    contrapose! hc
    rw [not_mem_support, ← cycleOf_eq_one_iff] at hc
    simp [hc]
  · intro hx
    refine' ⟨isCycle_cycleOf _ (mem_support.mp hx), _⟩
    

Proof state:
case mpr
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f✝ f : Perm α
x : α
hx : x ∈ support f
⊢ ∀ a ∈ support (cycleOf f x), (cycleOf f x) a = f a

Next tactic:
intro y hy
theorem cycleOf_mem_cycleFactorsFinset_iff {f : Perm α} {x : α} :
    cycleOf f x ∈ cycleFactorsFinset f ↔ x ∈ f.support := by
  rw [mem_cycleFactorsFinset_iff]
  constructor
  · rintro ⟨hc, _⟩
    contrapose! hc
    rw [not_mem_support, ← cycleOf_eq_one_iff] at hc
    simp [hc]
  · intro hx
    refine' ⟨isCycle_cycleOf _ (mem_support.mp hx), _⟩
    intro y hy
    

Proof state:
case mpr
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f✝ f : Perm α
x : α
hx : x ∈ support f
y : α
hy : y ∈ support (cycleOf f x)
⊢ (cycleOf f x) y = f y

Next tactic:
rw [mem_support] at hy
theorem cycleOf_mem_cycleFactorsFinset_iff {f : Perm α} {x : α} :
    cycleOf f x ∈ cycleFactorsFinset f ↔ x ∈ f.support := by
  rw [mem_cycleFactorsFinset_iff]
  constructor
  · rintro ⟨hc, _⟩
    contrapose! hc
    rw [not_mem_support, ← cycleOf_eq_one_iff] at hc
    simp [hc]
  · intro hx
    refine' ⟨isCycle_cycleOf _ (mem_support.mp hx), _⟩
    intro y hy
    rw [mem_support] at hy
    

Proof state:
case mpr
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f✝ f : Perm α
x : α
hx : x ∈ support f
y : α
hy : (cycleOf f x) y ≠ y
⊢ (cycleOf f x) y = f y

Next tactic:
rw [cycleOf_apply]
theorem cycleOf_mem_cycleFactorsFinset_iff {f : Perm α} {x : α} :
    cycleOf f x ∈ cycleFactorsFinset f ↔ x ∈ f.support := by
  rw [mem_cycleFactorsFinset_iff]
  constructor
  · rintro ⟨hc, _⟩
    contrapose! hc
    rw [not_mem_support, ← cycleOf_eq_one_iff] at hc
    simp [hc]
  · intro hx
    refine' ⟨isCycle_cycleOf _ (mem_support.mp hx), _⟩
    intro y hy
    rw [mem_support] at hy
    rw [cycleOf_apply]
    

Proof state:
case mpr
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f✝ f : Perm α
x : α
hx : x ∈ support f
y : α
hy : (cycleOf f x) y ≠ y
⊢ (if SameCycle f x y then f y else y) = f y

Next tactic:
split_ifs with H
theorem cycleOf_mem_cycleFactorsFinset_iff {f : Perm α} {x : α} :
    cycleOf f x ∈ cycleFactorsFinset f ↔ x ∈ f.support := by
  rw [mem_cycleFactorsFinset_iff]
  constructor
  · rintro ⟨hc, _⟩
    contrapose! hc
    rw [not_mem_support, ← cycleOf_eq_one_iff] at hc
    simp [hc]
  · intro hx
    refine' ⟨isCycle_cycleOf _ (mem_support.mp hx), _⟩
    intro y hy
    rw [mem_support] at hy
    rw [cycleOf_apply]
    split_ifs with H
    · 

Proof state:
case pos
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f✝ f : Perm α
x : α
hx : x ∈ support f
y : α
hy : (cycleOf f x) y ≠ y
H : SameCycle f x y
⊢ f y = f y

Next tactic:
rfl
theorem cycleOf_mem_cycleFactorsFinset_iff {f : Perm α} {x : α} :
    cycleOf f x ∈ cycleFactorsFinset f ↔ x ∈ f.support := by
  rw [mem_cycleFactorsFinset_iff]
  constructor
  · rintro ⟨hc, _⟩
    contrapose! hc
    rw [not_mem_support, ← cycleOf_eq_one_iff] at hc
    simp [hc]
  · intro hx
    refine' ⟨isCycle_cycleOf _ (mem_support.mp hx), _⟩
    intro y hy
    rw [mem_support] at hy
    rw [cycleOf_apply]
    split_ifs with H
    · rfl
    · 

Proof state:
case neg
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f✝ f : Perm α
x : α
hx : x ∈ support f
y : α
hy : (cycleOf f x) y ≠ y
H : ¬SameCycle f x y
⊢ y = f y

Next tactic:
rw [cycleOf_apply_of_not_sameCycle H] at hy
theorem cycleOf_mem_cycleFactorsFinset_iff {f : Perm α} {x : α} :
    cycleOf f x ∈ cycleFactorsFinset f ↔ x ∈ f.support := by
  rw [mem_cycleFactorsFinset_iff]
  constructor
  · rintro ⟨hc, _⟩
    contrapose! hc
    rw [not_mem_support, ← cycleOf_eq_one_iff] at hc
    simp [hc]
  · intro hx
    refine' ⟨isCycle_cycleOf _ (mem_support.mp hx), _⟩
    intro y hy
    rw [mem_support] at hy
    rw [cycleOf_apply]
    split_ifs with H
    · rfl
    · rw [cycleOf_apply_of_not_sameCycle H] at hy
      

Proof state:
case neg
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f✝ f : Perm α
x : α
hx : x ∈ support f
y : α
hy : y ≠ y
H : ¬SameCycle f x y
⊢ y = f y

Next tactic:
contradiction
theorem mem_cycleFactorsFinset_support_le {p f : Perm α} (h : p ∈ cycleFactorsFinset f) :
    p.support ≤ f.support := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f✝ p f : Perm α
h : p ∈ cycleFactorsFinset f
⊢ support p ≤ support f

Next tactic:
rw [mem_cycleFactorsFinset_iff] at h
theorem mem_cycleFactorsFinset_support_le {p f : Perm α} (h : p ∈ cycleFactorsFinset f) :
    p.support ≤ f.support := by
  rw [mem_cycleFactorsFinset_iff] at h
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f✝ p f : Perm α
h : IsCycle p ∧ ∀ a ∈ support p, p a = f a
⊢ support p ≤ support f

Next tactic:
intro x hx
theorem mem_cycleFactorsFinset_support_le {p f : Perm α} (h : p ∈ cycleFactorsFinset f) :
    p.support ≤ f.support := by
  rw [mem_cycleFactorsFinset_iff] at h
  intro x hx
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f✝ p f : Perm α
h : IsCycle p ∧ ∀ a ∈ support p, p a = f a
x : α
hx : x ∈ support p
⊢ x ∈ support f

Next tactic:
rwa [mem_support, ← h.right x hx, ← mem_support]
theorem cycleFactorsFinset_eq_empty_iff {f : Perm α} : cycleFactorsFinset f = ∅ ↔ f = 1 := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f✝ f : Perm α
⊢ cycleFactorsFinset f = ∅ ↔ f = 1

Next tactic:
simpa [cycleFactorsFinset_eq_finset] using eq_comm
@[simp]
theorem cycleFactorsFinset_one : cycleFactorsFinset (1 : Perm α) = ∅ := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f : Perm α
⊢ cycleFactorsFinset 1 = ∅

Next tactic:
simp [cycleFactorsFinset_eq_empty_iff]
@[simp]
theorem cycleFactorsFinset_eq_singleton_self_iff {f : Perm α} :
    f.cycleFactorsFinset = {f} ↔ f.IsCycle := by 

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f✝ f : Perm α
⊢ cycleFactorsFinset f = {f} ↔ IsCycle f

Next tactic:
simp [cycleFactorsFinset_eq_finset]
theorem cycleFactorsFinset_eq_singleton_iff {f g : Perm α} :
    f.cycleFactorsFinset = {g} ↔ f.IsCycle ∧ f = g := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f✝ f g : Perm α
⊢ cycleFactorsFinset f = {g} ↔ IsCycle f ∧ f = g

Next tactic:
suffices f = g → (g.IsCycle ↔ f.IsCycle) by
    rw [cycleFactorsFinset_eq_finset]
    simpa [eq_comm]
theorem cycleFactorsFinset_eq_singleton_iff {f g : Perm α} :
    f.cycleFactorsFinset = {g} ↔ f.IsCycle ∧ f = g := by
  suffices f = g → (g.IsCycle ↔ f.IsCycle) by
    

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f✝ f g : Perm α
this : f = g → (IsCycle g ↔ IsCycle f)
⊢ cycleFactorsFinset f = {g} ↔ IsCycle f ∧ f = g

Next tactic:
rw [cycleFactorsFinset_eq_finset]
theorem cycleFactorsFinset_eq_singleton_iff {f g : Perm α} :
    f.cycleFactorsFinset = {g} ↔ f.IsCycle ∧ f = g := by
  suffices f = g → (g.IsCycle ↔ f.IsCycle) by
    rw [cycleFactorsFinset_eq_finset]
    

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f✝ f g : Perm α
this : f = g → (IsCycle g ↔ IsCycle f)
⊢ ((∀ f ∈ {g}, IsCycle f) ∧
      ∃ (h : Set.Pairwise (↑{g}) Disjoint),
        noncommProd {g} id (_ : Set.Pairwise ↑{g} fun a b => Commute (id a) (id b)) = f) ↔
    IsCycle f ∧ f = g

Next tactic:
simpa [eq_comm]
theorem cycleFactorsFinset_eq_singleton_iff {f g : Perm α} :
    f.cycleFactorsFinset = {g} ↔ f.IsCycle ∧ f = g := by
  suffices f = g → (g.IsCycle ↔ f.IsCycle) by
    rw [cycleFactorsFinset_eq_finset]
    simpa [eq_comm]
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f✝ f g : Perm α
⊢ f = g → (IsCycle g ↔ IsCycle f)

Next tactic:
rintro rfl
theorem cycleFactorsFinset_eq_singleton_iff {f g : Perm α} :
    f.cycleFactorsFinset = {g} ↔ f.IsCycle ∧ f = g := by
  suffices f = g → (g.IsCycle ↔ f.IsCycle) by
    rw [cycleFactorsFinset_eq_finset]
    simpa [eq_comm]
  rintro rfl
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f✝ f : Perm α
⊢ IsCycle f ↔ IsCycle f

Next tactic:
exact Iff.rfl
/-- Two permutations `f g : perm α` have the same cycle factors iff they are the same. -/
theorem cycleFactorsFinset_injective : Function.Injective (@cycleFactorsFinset α _ _) := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f : Perm α
⊢ Injective cycleFactorsFinset

Next tactic:
intro f g h
/-- Two permutations `f g : perm α` have the same cycle factors iff they are the same. -/
theorem cycleFactorsFinset_injective : Function.Injective (@cycleFactorsFinset α _ _) := by
  intro f g h
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f✝ f g : Perm α
h : cycleFactorsFinset f = cycleFactorsFinset g
⊢ f = g

Next tactic:
rw [← cycleFactorsFinset_noncommProd f]
/-- Two permutations `f g : perm α` have the same cycle factors iff they are the same. -/
theorem cycleFactorsFinset_injective : Function.Injective (@cycleFactorsFinset α _ _) := by
  intro f g h
  rw [← cycleFactorsFinset_noncommProd f]
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f✝ f g : Perm α
h : cycleFactorsFinset f = cycleFactorsFinset g
⊢ noncommProd (cycleFactorsFinset f) id (_ : Set.Pairwise (↑(cycleFactorsFinset f)) Commute) = g

Next tactic:
simpa [h] using cycleFactorsFinset_noncommProd g
theorem Disjoint.disjoint_cycleFactorsFinset {f g : Perm α} (h : Disjoint f g) :
    _root_.Disjoint (cycleFactorsFinset f) (cycleFactorsFinset g) := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f✝ f g : Perm α
h : Disjoint f g
⊢ _root_.Disjoint (cycleFactorsFinset f) (cycleFactorsFinset g)

Next tactic:
rw [disjoint_iff_disjoint_support] at h
theorem Disjoint.disjoint_cycleFactorsFinset {f g : Perm α} (h : Disjoint f g) :
    _root_.Disjoint (cycleFactorsFinset f) (cycleFactorsFinset g) := by
  rw [disjoint_iff_disjoint_support] at h
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f✝ f g : Perm α
h : _root_.Disjoint (support f) (support g)
⊢ _root_.Disjoint (cycleFactorsFinset f) (cycleFactorsFinset g)

Next tactic:
rw [Finset.disjoint_left]
theorem Disjoint.disjoint_cycleFactorsFinset {f g : Perm α} (h : Disjoint f g) :
    _root_.Disjoint (cycleFactorsFinset f) (cycleFactorsFinset g) := by
  rw [disjoint_iff_disjoint_support] at h
  rw [Finset.disjoint_left]
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f✝ f g : Perm α
h : _root_.Disjoint (support f) (support g)
⊢ ∀ ⦃a : Perm α⦄, a ∈ cycleFactorsFinset f → a ∉ cycleFactorsFinset g

Next tactic:
intro x hx hy
theorem Disjoint.disjoint_cycleFactorsFinset {f g : Perm α} (h : Disjoint f g) :
    _root_.Disjoint (cycleFactorsFinset f) (cycleFactorsFinset g) := by
  rw [disjoint_iff_disjoint_support] at h
  rw [Finset.disjoint_left]
  intro x hx hy
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f✝ f g : Perm α
h : _root_.Disjoint (support f) (support g)
x : Perm α
hx : x ∈ cycleFactorsFinset f
hy : x ∈ cycleFactorsFinset g
⊢ False

Next tactic:
simp only [mem_cycleFactorsFinset_iff, mem_support] at hx hy
theorem Disjoint.disjoint_cycleFactorsFinset {f g : Perm α} (h : Disjoint f g) :
    _root_.Disjoint (cycleFactorsFinset f) (cycleFactorsFinset g) := by
  rw [disjoint_iff_disjoint_support] at h
  rw [Finset.disjoint_left]
  intro x hx hy
  simp only [mem_cycleFactorsFinset_iff, mem_support] at hx hy
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f✝ f g : Perm α
h : _root_.Disjoint (support f) (support g)
x : Perm α
hx : IsCycle x ∧ ∀ (a : α), x a ≠ a → x a = f a
hy : IsCycle x ∧ ∀ (a : α), x a ≠ a → x a = g a
⊢ False

Next tactic:
obtain ⟨⟨⟨a, ha, -⟩, hf⟩, -, hg⟩ := hx, hy
theorem Disjoint.disjoint_cycleFactorsFinset {f g : Perm α} (h : Disjoint f g) :
    _root_.Disjoint (cycleFactorsFinset f) (cycleFactorsFinset g) := by
  rw [disjoint_iff_disjoint_support] at h
  rw [Finset.disjoint_left]
  intro x hx hy
  simp only [mem_cycleFactorsFinset_iff, mem_support] at hx hy
  obtain ⟨⟨⟨a, ha, -⟩, hf⟩, -, hg⟩ := hx, hy
  

Proof state:
case intro.intro.intro.intro
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f✝ f g : Perm α
h : _root_.Disjoint (support f) (support g)
x : Perm α
hf : ∀ (a : α), x a ≠ a → x a = f a
a : α
ha : x a ≠ a
hg : ∀ (a : α), x a ≠ a → x a = g a
⊢ False

Next tactic:
have := h.le_bot (by simp [ha, ← hf a ha, ← hg a ha] : a ∈ f.support ∩ g.support)