l3lab/ntp-mathlib huggingface dataset:
open scoped List in
/-- Given a list `l : List α` and a permutation `f : perm α` whose nonfixed points are all in `l`,
  recursively factors `f` into cycles. -/
def cycleFactorsAux [Fintype α] :
    ∀ (l : List α) (f : Perm α),
      (∀ {x}, f x ≠ x → x ∈ l) →
        { l : List (Perm α) // l.prod = f ∧ (∀ g ∈ l, IsCycle g) ∧ l.Pairwise Disjoint } := by
  intro l f h
  exact match l with
  | [] => ⟨[], by
      { simp only [imp_false, List.Pairwise.nil, List.not_mem_nil, forall_const, and_true_iff,
          forall_prop_of_false, Classical.not_not, not_false_iff, List.prod_nil] at *
        ext
        simp [*]}⟩
  | x::l =>
    if hx : f x = x then cycleFactorsAux l f (by
        intro y hy; exact List.mem_of_ne_of_mem (fun h => hy (by rwa [h])) (h hy))
    else
      let ⟨m, hm₁, hm₂, hm₃⟩ :=
        cycleFactorsAux l ((cycleOf f x)⁻¹ * f) (by
        intro y hy
        exact List.mem_of_ne_of_mem
            (fun h : y = x => by
              rw [h, mul_apply, Ne.def, inv_eq_iff_eq, cycleOf_apply_self] at hy
              exact hy rfl)
            (h fun h : f y = y => by
              

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
l✝ : List α
f : Perm α
x : α
l : List α
h✝ : ∀ {x_1 : α}, f x_1 ≠ x_1 → x_1 ∈ x :: l
hx : ¬f x = x
y : α
hy : ((cycleOf f x)⁻¹ * f) y ≠ y
h : f y = y
⊢ False

Next tactic:
rw [mul_apply, h, Ne.def, inv_eq_iff_eq, cycleOf_apply] at hy
open scoped List in
/-- Given a list `l : List α` and a permutation `f : perm α` whose nonfixed points are all in `l`,
  recursively factors `f` into cycles. -/
def cycleFactorsAux [Fintype α] :
    ∀ (l : List α) (f : Perm α),
      (∀ {x}, f x ≠ x → x ∈ l) →
        { l : List (Perm α) // l.prod = f ∧ (∀ g ∈ l, IsCycle g) ∧ l.Pairwise Disjoint } := by
  intro l f h
  exact match l with
  | [] => ⟨[], by
      { simp only [imp_false, List.Pairwise.nil, List.not_mem_nil, forall_const, and_true_iff,
          forall_prop_of_false, Classical.not_not, not_false_iff, List.prod_nil] at *
        ext
        simp [*]}⟩
  | x::l =>
    if hx : f x = x then cycleFactorsAux l f (by
        intro y hy; exact List.mem_of_ne_of_mem (fun h => hy (by rwa [h])) (h hy))
    else
      let ⟨m, hm₁, hm₂, hm₃⟩ :=
        cycleFactorsAux l ((cycleOf f x)⁻¹ * f) (by
        intro y hy
        exact List.mem_of_ne_of_mem
            (fun h : y = x => by
              rw [h, mul_apply, Ne.def, inv_eq_iff_eq, cycleOf_apply_self] at hy
              exact hy rfl)
            (h fun h : f y = y => by
              rw [mul_apply, h, Ne.def, inv_eq_iff_eq, cycleOf_apply] at hy
              

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
l✝ : List α
f : Perm α
x : α
l : List α
h✝ : ∀ {x_1 : α}, f x_1 ≠ x_1 → x_1 ∈ x :: l
hx : ¬f x = x
y : α
hy : ¬y = if SameCycle f x y then f y else y
h : f y = y
⊢ False

Next tactic:
split_ifs at hy
open scoped List in
/-- Given a list `l : List α` and a permutation `f : perm α` whose nonfixed points are all in `l`,
  recursively factors `f` into cycles. -/
def cycleFactorsAux [Fintype α] :
    ∀ (l : List α) (f : Perm α),
      (∀ {x}, f x ≠ x → x ∈ l) →
        { l : List (Perm α) // l.prod = f ∧ (∀ g ∈ l, IsCycle g) ∧ l.Pairwise Disjoint } := by
  intro l f h
  exact match l with
  | [] => ⟨[], by
      { simp only [imp_false, List.Pairwise.nil, List.not_mem_nil, forall_const, and_true_iff,
          forall_prop_of_false, Classical.not_not, not_false_iff, List.prod_nil] at *
        ext
        simp [*]}⟩
  | x::l =>
    if hx : f x = x then cycleFactorsAux l f (by
        intro y hy; exact List.mem_of_ne_of_mem (fun h => hy (by rwa [h])) (h hy))
    else
      let ⟨m, hm₁, hm₂, hm₃⟩ :=
        cycleFactorsAux l ((cycleOf f x)⁻¹ * f) (by
        intro y hy
        exact List.mem_of_ne_of_mem
            (fun h : y = x => by
              rw [h, mul_apply, Ne.def, inv_eq_iff_eq, cycleOf_apply_self] at hy
              exact hy rfl)
            (h fun h : f y = y => by
              rw [mul_apply, h, Ne.def, inv_eq_iff_eq, cycleOf_apply] at hy
              split_ifs at hy <;> 

Proof state:
case pos
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
l✝ : List α
f : Perm α
x : α
l : List α
h✝¹ : ∀ {x_1 : α}, f x_1 ≠ x_1 → x_1 ∈ x :: l
hx : ¬f x = x
y : α
h : f y = y
h✝ : SameCycle f x y
hy : ¬y = f y
⊢ False

Next tactic:
tauto
open scoped List in
/-- Given a list `l : List α` and a permutation `f : perm α` whose nonfixed points are all in `l`,
  recursively factors `f` into cycles. -/
def cycleFactorsAux [Fintype α] :
    ∀ (l : List α) (f : Perm α),
      (∀ {x}, f x ≠ x → x ∈ l) →
        { l : List (Perm α) // l.prod = f ∧ (∀ g ∈ l, IsCycle g) ∧ l.Pairwise Disjoint } := by
  intro l f h
  exact match l with
  | [] => ⟨[], by
      { simp only [imp_false, List.Pairwise.nil, List.not_mem_nil, forall_const, and_true_iff,
          forall_prop_of_false, Classical.not_not, not_false_iff, List.prod_nil] at *
        ext
        simp [*]}⟩
  | x::l =>
    if hx : f x = x then cycleFactorsAux l f (by
        intro y hy; exact List.mem_of_ne_of_mem (fun h => hy (by rwa [h])) (h hy))
    else
      let ⟨m, hm₁, hm₂, hm₃⟩ :=
        cycleFactorsAux l ((cycleOf f x)⁻¹ * f) (by
        intro y hy
        exact List.mem_of_ne_of_mem
            (fun h : y = x => by
              rw [h, mul_apply, Ne.def, inv_eq_iff_eq, cycleOf_apply_self] at hy
              exact hy rfl)
            (h fun h : f y = y => by
              rw [mul_apply, h, Ne.def, inv_eq_iff_eq, cycleOf_apply] at hy
              split_ifs at hy <;> 

Proof state:
case neg
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
l✝ : List α
f : Perm α
x : α
l : List α
h✝¹ : ∀ {x_1 : α}, f x_1 ≠ x_1 → x_1 ∈ x :: l
hx : ¬f x = x
y : α
h : f y = y
h✝ : ¬SameCycle f x y
hy : ¬y = y
⊢ False

Next tactic:
tauto
open scoped List in
/-- Given a list `l : List α` and a permutation `f : perm α` whose nonfixed points are all in `l`,
  recursively factors `f` into cycles. -/
def cycleFactorsAux [Fintype α] :
    ∀ (l : List α) (f : Perm α),
      (∀ {x}, f x ≠ x → x ∈ l) →
        { l : List (Perm α) // l.prod = f ∧ (∀ g ∈ l, IsCycle g) ∧ l.Pairwise Disjoint } := by
  intro l f h
  exact match l with
  | [] => ⟨[], by
      { simp only [imp_false, List.Pairwise.nil, List.not_mem_nil, forall_const, and_true_iff,
          forall_prop_of_false, Classical.not_not, not_false_iff, List.prod_nil] at *
        ext
        simp [*]}⟩
  | x::l =>
    if hx : f x = x then cycleFactorsAux l f (by
        intro y hy; exact List.mem_of_ne_of_mem (fun h => hy (by rwa [h])) (h hy))
    else
      let ⟨m, hm₁, hm₂, hm₃⟩ :=
        cycleFactorsAux l ((cycleOf f x)⁻¹ * f) (by
        intro y hy
        exact List.mem_of_ne_of_mem
            (fun h : y = x => by
              rw [h, mul_apply, Ne.def, inv_eq_iff_eq, cycleOf_apply_self] at hy
              exact hy rfl)
            (h fun h : f y = y => by
              rw [mul_apply, h, Ne.def, inv_eq_iff_eq, cycleOf_apply] at hy
              split_ifs at hy <;> tauto))
      ⟨cycleOf f x::m, by
        

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
l✝ : List α
f : Perm α
x : α
l : List α
h : ∀ {x_1 : α}, f x_1 ≠ x_1 → x_1 ∈ x :: l
hx : ¬f x = x
m : List (Perm α)
hm₁ : List.prod m = (cycleOf f x)⁻¹ * f
hm₂ : ∀ g ∈ m, IsCycle g
hm₃ : List.Pairwise Disjoint m
⊢ List.prod (cycleOf f x :: m) = f

Next tactic:
rw [List.prod_cons, hm₁]
open scoped List in
/-- Given a list `l : List α` and a permutation `f : perm α` whose nonfixed points are all in `l`,
  recursively factors `f` into cycles. -/
def cycleFactorsAux [Fintype α] :
    ∀ (l : List α) (f : Perm α),
      (∀ {x}, f x ≠ x → x ∈ l) →
        { l : List (Perm α) // l.prod = f ∧ (∀ g ∈ l, IsCycle g) ∧ l.Pairwise Disjoint } := by
  intro l f h
  exact match l with
  | [] => ⟨[], by
      { simp only [imp_false, List.Pairwise.nil, List.not_mem_nil, forall_const, and_true_iff,
          forall_prop_of_false, Classical.not_not, not_false_iff, List.prod_nil] at *
        ext
        simp [*]}⟩
  | x::l =>
    if hx : f x = x then cycleFactorsAux l f (by
        intro y hy; exact List.mem_of_ne_of_mem (fun h => hy (by rwa [h])) (h hy))
    else
      let ⟨m, hm₁, hm₂, hm₃⟩ :=
        cycleFactorsAux l ((cycleOf f x)⁻¹ * f) (by
        intro y hy
        exact List.mem_of_ne_of_mem
            (fun h : y = x => by
              rw [h, mul_apply, Ne.def, inv_eq_iff_eq, cycleOf_apply_self] at hy
              exact hy rfl)
            (h fun h : f y = y => by
              rw [mul_apply, h, Ne.def, inv_eq_iff_eq, cycleOf_apply] at hy
              split_ifs at hy <;> tauto))
      ⟨cycleOf f x::m, by
        rw [List.prod_cons, hm₁]
        

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
l✝ : List α
f : Perm α
x : α
l : List α
h : ∀ {x_1 : α}, f x_1 ≠ x_1 → x_1 ∈ x :: l
hx : ¬f x = x
m : List (Perm α)
hm₁ : List.prod m = (cycleOf f x)⁻¹ * f
hm₂ : ∀ g ∈ m, IsCycle g
hm₃ : List.Pairwise Disjoint m
⊢ cycleOf f x * ((cycleOf f x)⁻¹ * f) = f

Next tactic:
simp
open scoped List in
/-- Given a list `l : List α` and a permutation `f : perm α` whose nonfixed points are all in `l`,
  recursively factors `f` into cycles. -/
def cycleFactorsAux [Fintype α] :
    ∀ (l : List α) (f : Perm α),
      (∀ {x}, f x ≠ x → x ∈ l) →
        { l : List (Perm α) // l.prod = f ∧ (∀ g ∈ l, IsCycle g) ∧ l.Pairwise Disjoint } := by
  intro l f h
  exact match l with
  | [] => ⟨[], by
      { simp only [imp_false, List.Pairwise.nil, List.not_mem_nil, forall_const, and_true_iff,
          forall_prop_of_false, Classical.not_not, not_false_iff, List.prod_nil] at *
        ext
        simp [*]}⟩
  | x::l =>
    if hx : f x = x then cycleFactorsAux l f (by
        intro y hy; exact List.mem_of_ne_of_mem (fun h => hy (by rwa [h])) (h hy))
    else
      let ⟨m, hm₁, hm₂, hm₃⟩ :=
        cycleFactorsAux l ((cycleOf f x)⁻¹ * f) (by
        intro y hy
        exact List.mem_of_ne_of_mem
            (fun h : y = x => by
              rw [h, mul_apply, Ne.def, inv_eq_iff_eq, cycleOf_apply_self] at hy
              exact hy rfl)
            (h fun h : f y = y => by
              rw [mul_apply, h, Ne.def, inv_eq_iff_eq, cycleOf_apply] at hy
              split_ifs at hy <;> tauto))
      ⟨cycleOf f x::m, by
        rw [List.prod_cons, hm₁]
        simp,
        fun g hg ↦ ((List.mem_cons).1 hg).elim (fun hg => hg.symm ▸ isCycle_cycleOf _ hx) (hm₂ g),
        List.pairwise_cons.2
          ⟨fun g hg y =>
            or_iff_not_imp_left.2 fun hfy =>
              have hxy : SameCycle f x y :=
                Classical.not_not.1 (mt cycleOf_apply_of_not_sameCycle hfy)
              have hgm : (g::m.erase g) ~ m :=
                List.cons_perm_iff_perm_erase.2 ⟨hg, List.Perm.refl _⟩
              have : ∀ h ∈ m.erase g, Disjoint g h :=
                (List.pairwise_cons.1
                    ((hgm.pairwise_iff @fun a b (h : Disjoint a b) => h.symm).2 hm₃)).1
              by_cases id fun hgy : g y ≠ y =>
                (disjoint_prod_right _ this y).resolve_right <| by
                  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
l✝ : List α
f : Perm α
x : α
l : List α
h : ∀ {x_1 : α}, f x_1 ≠ x_1 → x_1 ∈ x :: l
hx : ¬f x = x
m : List (Perm α)
hm₁ : List.prod m = (cycleOf f x)⁻¹ * f
hm₂ : ∀ g ∈ m, IsCycle g
hm₃ : List.Pairwise Disjoint m
g : Perm α
hg : g ∈ m
y : α
hfy : ¬(cycleOf f x) y = y
hxy : SameCycle f x y
hgm : g :: List.erase m g ~ m
this : ∀ h ∈ List.erase m g, Disjoint g h
hgy : g y ≠ y
⊢ ¬(List.prod (List.erase m g)) y = y

Next tactic:
have hsc : SameCycle f⁻¹ x (f y) := by
                    rwa [sameCycle_inv, sameCycle_apply_right]
open scoped List in
/-- Given a list `l : List α` and a permutation `f : perm α` whose nonfixed points are all in `l`,
  recursively factors `f` into cycles. -/
def cycleFactorsAux [Fintype α] :
    ∀ (l : List α) (f : Perm α),
      (∀ {x}, f x ≠ x → x ∈ l) →
        { l : List (Perm α) // l.prod = f ∧ (∀ g ∈ l, IsCycle g) ∧ l.Pairwise Disjoint } := by
  intro l f h
  exact match l with
  | [] => ⟨[], by
      { simp only [imp_false, List.Pairwise.nil, List.not_mem_nil, forall_const, and_true_iff,
          forall_prop_of_false, Classical.not_not, not_false_iff, List.prod_nil] at *
        ext
        simp [*]}⟩
  | x::l =>
    if hx : f x = x then cycleFactorsAux l f (by
        intro y hy; exact List.mem_of_ne_of_mem (fun h => hy (by rwa [h])) (h hy))
    else
      let ⟨m, hm₁, hm₂, hm₃⟩ :=
        cycleFactorsAux l ((cycleOf f x)⁻¹ * f) (by
        intro y hy
        exact List.mem_of_ne_of_mem
            (fun h : y = x => by
              rw [h, mul_apply, Ne.def, inv_eq_iff_eq, cycleOf_apply_self] at hy
              exact hy rfl)
            (h fun h : f y = y => by
              rw [mul_apply, h, Ne.def, inv_eq_iff_eq, cycleOf_apply] at hy
              split_ifs at hy <;> tauto))
      ⟨cycleOf f x::m, by
        rw [List.prod_cons, hm₁]
        simp,
        fun g hg ↦ ((List.mem_cons).1 hg).elim (fun hg => hg.symm ▸ isCycle_cycleOf _ hx) (hm₂ g),
        List.pairwise_cons.2
          ⟨fun g hg y =>
            or_iff_not_imp_left.2 fun hfy =>
              have hxy : SameCycle f x y :=
                Classical.not_not.1 (mt cycleOf_apply_of_not_sameCycle hfy)
              have hgm : (g::m.erase g) ~ m :=
                List.cons_perm_iff_perm_erase.2 ⟨hg, List.Perm.refl _⟩
              have : ∀ h ∈ m.erase g, Disjoint g h :=
                (List.pairwise_cons.1
                    ((hgm.pairwise_iff @fun a b (h : Disjoint a b) => h.symm).2 hm₃)).1
              by_cases id fun hgy : g y ≠ y =>
                (disjoint_prod_right _ this y).resolve_right <| by
                  have hsc : SameCycle f⁻¹ x (f y) := by
                    

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
l✝ : List α
f : Perm α
x : α
l : List α
h : ∀ {x_1 : α}, f x_1 ≠ x_1 → x_1 ∈ x :: l
hx : ¬f x = x
m : List (Perm α)
hm₁ : List.prod m = (cycleOf f x)⁻¹ * f
hm₂ : ∀ g ∈ m, IsCycle g
hm₃ : List.Pairwise Disjoint m
g : Perm α
hg : g ∈ m
y : α
hfy : ¬(cycleOf f x) y = y
hxy : SameCycle f x y
hgm : g :: List.erase m g ~ m
this : ∀ h ∈ List.erase m g, Disjoint g h
hgy : g y ≠ y
⊢ SameCycle f⁻¹ x (f y)

Next tactic:
rwa [sameCycle_inv, sameCycle_apply_right]
open scoped List in
/-- Given a list `l : List α` and a permutation `f : perm α` whose nonfixed points are all in `l`,
  recursively factors `f` into cycles. -/
def cycleFactorsAux [Fintype α] :
    ∀ (l : List α) (f : Perm α),
      (∀ {x}, f x ≠ x → x ∈ l) →
        { l : List (Perm α) // l.prod = f ∧ (∀ g ∈ l, IsCycle g) ∧ l.Pairwise Disjoint } := by
  intro l f h
  exact match l with
  | [] => ⟨[], by
      { simp only [imp_false, List.Pairwise.nil, List.not_mem_nil, forall_const, and_true_iff,
          forall_prop_of_false, Classical.not_not, not_false_iff, List.prod_nil] at *
        ext
        simp [*]}⟩
  | x::l =>
    if hx : f x = x then cycleFactorsAux l f (by
        intro y hy; exact List.mem_of_ne_of_mem (fun h => hy (by rwa [h])) (h hy))
    else
      let ⟨m, hm₁, hm₂, hm₃⟩ :=
        cycleFactorsAux l ((cycleOf f x)⁻¹ * f) (by
        intro y hy
        exact List.mem_of_ne_of_mem
            (fun h : y = x => by
              rw [h, mul_apply, Ne.def, inv_eq_iff_eq, cycleOf_apply_self] at hy
              exact hy rfl)
            (h fun h : f y = y => by
              rw [mul_apply, h, Ne.def, inv_eq_iff_eq, cycleOf_apply] at hy
              split_ifs at hy <;> tauto))
      ⟨cycleOf f x::m, by
        rw [List.prod_cons, hm₁]
        simp,
        fun g hg ↦ ((List.mem_cons).1 hg).elim (fun hg => hg.symm ▸ isCycle_cycleOf _ hx) (hm₂ g),
        List.pairwise_cons.2
          ⟨fun g hg y =>
            or_iff_not_imp_left.2 fun hfy =>
              have hxy : SameCycle f x y :=
                Classical.not_not.1 (mt cycleOf_apply_of_not_sameCycle hfy)
              have hgm : (g::m.erase g) ~ m :=
                List.cons_perm_iff_perm_erase.2 ⟨hg, List.Perm.refl _⟩
              have : ∀ h ∈ m.erase g, Disjoint g h :=
                (List.pairwise_cons.1
                    ((hgm.pairwise_iff @fun a b (h : Disjoint a b) => h.symm).2 hm₃)).1
              by_cases id fun hgy : g y ≠ y =>
                (disjoint_prod_right _ this y).resolve_right <| by
                  have hsc : SameCycle f⁻¹ x (f y) := by
                    rwa [sameCycle_inv, sameCycle_apply_right]
                  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
l✝ : List α
f : Perm α
x : α
l : List α
h : ∀ {x_1 : α}, f x_1 ≠ x_1 → x_1 ∈ x :: l
hx : ¬f x = x
m : List (Perm α)
hm₁ : List.prod m = (cycleOf f x)⁻¹ * f
hm₂ : ∀ g ∈ m, IsCycle g
hm₃ : List.Pairwise Disjoint m
g : Perm α
hg : g ∈ m
y : α
hfy : ¬(cycleOf f x) y = y
hxy : SameCycle f x y
hgm : g :: List.erase m g ~ m
this : ∀ h ∈ List.erase m g, Disjoint g h
hgy : g y ≠ y
hsc : SameCycle f⁻¹ x (f y)
⊢ ¬(List.prod (List.erase m g)) y = y

Next tactic:
rw [disjoint_prod_perm hm₃ hgm.symm, List.prod_cons,
                      ← eq_inv_mul_iff_mul_eq] at hm₁
open scoped List in
/-- Given a list `l : List α` and a permutation `f : perm α` whose nonfixed points are all in `l`,
  recursively factors `f` into cycles. -/
def cycleFactorsAux [Fintype α] :
    ∀ (l : List α) (f : Perm α),
      (∀ {x}, f x ≠ x → x ∈ l) →
        { l : List (Perm α) // l.prod = f ∧ (∀ g ∈ l, IsCycle g) ∧ l.Pairwise Disjoint } := by
  intro l f h
  exact match l with
  | [] => ⟨[], by
      { simp only [imp_false, List.Pairwise.nil, List.not_mem_nil, forall_const, and_true_iff,
          forall_prop_of_false, Classical.not_not, not_false_iff, List.prod_nil] at *
        ext
        simp [*]}⟩
  | x::l =>
    if hx : f x = x then cycleFactorsAux l f (by
        intro y hy; exact List.mem_of_ne_of_mem (fun h => hy (by rwa [h])) (h hy))
    else
      let ⟨m, hm₁, hm₂, hm₃⟩ :=
        cycleFactorsAux l ((cycleOf f x)⁻¹ * f) (by
        intro y hy
        exact List.mem_of_ne_of_mem
            (fun h : y = x => by
              rw [h, mul_apply, Ne.def, inv_eq_iff_eq, cycleOf_apply_self] at hy
              exact hy rfl)
            (h fun h : f y = y => by
              rw [mul_apply, h, Ne.def, inv_eq_iff_eq, cycleOf_apply] at hy
              split_ifs at hy <;> tauto))
      ⟨cycleOf f x::m, by
        rw [List.prod_cons, hm₁]
        simp,
        fun g hg ↦ ((List.mem_cons).1 hg).elim (fun hg => hg.symm ▸ isCycle_cycleOf _ hx) (hm₂ g),
        List.pairwise_cons.2
          ⟨fun g hg y =>
            or_iff_not_imp_left.2 fun hfy =>
              have hxy : SameCycle f x y :=
                Classical.not_not.1 (mt cycleOf_apply_of_not_sameCycle hfy)
              have hgm : (g::m.erase g) ~ m :=
                List.cons_perm_iff_perm_erase.2 ⟨hg, List.Perm.refl _⟩
              have : ∀ h ∈ m.erase g, Disjoint g h :=
                (List.pairwise_cons.1
                    ((hgm.pairwise_iff @fun a b (h : Disjoint a b) => h.symm).2 hm₃)).1
              by_cases id fun hgy : g y ≠ y =>
                (disjoint_prod_right _ this y).resolve_right <| by
                  have hsc : SameCycle f⁻¹ x (f y) := by
                    rwa [sameCycle_inv, sameCycle_apply_right]
                  rw [disjoint_prod_perm hm₃ hgm.symm, List.prod_cons,
                      ← eq_inv_mul_iff_mul_eq] at hm₁
                  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
l✝ : List α
f : Perm α
x : α
l : List α
h : ∀ {x_1 : α}, f x_1 ≠ x_1 → x_1 ∈ x :: l
hx : ¬f x = x
m : List (Perm α)
hm₂ : ∀ g ∈ m, IsCycle g
hm₃ : List.Pairwise Disjoint m
g : Perm α
hm₁ : List.prod (List.erase m g) = g⁻¹ * ((cycleOf f x)⁻¹ * f)
hg : g ∈ m
y : α
hfy : ¬(cycleOf f x) y = y
hxy : SameCycle f x y
hgm : g :: List.erase m g ~ m
this : ∀ h ∈ List.erase m g, Disjoint g h
hgy : g y ≠ y
hsc : SameCycle f⁻¹ x (f y)
⊢ ¬(List.prod (List.erase m g)) y = y

Next tactic:
rwa [hm₁, mul_apply, mul_apply, cycleOf_inv, hsc.cycleOf_apply, inv_apply_self,
                    inv_eq_iff_eq, eq_comm]
theorem mem_list_cycles_iff {α : Type*} [Finite α] {l : List (Perm α)}
    (h1 : ∀ σ : Perm α, σ ∈ l → σ.IsCycle) (h2 : l.Pairwise Disjoint) {σ : Perm α} :
    σ ∈ l ↔ σ.IsCycle ∧ ∀ a, σ a ≠ a → σ a = l.prod a := by
  

Proof state:
ι : Type u_1
α✝ : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α✝
α : Type u_4
inst✝ : Finite α
l : List (Perm α)
h1 : ∀ σ ∈ l, IsCycle σ
h2 : List.Pairwise Disjoint l
σ : Perm α
⊢ σ ∈ l ↔ IsCycle σ ∧ ∀ (a : α), σ a ≠ a → σ a = (List.prod l) a

Next tactic:
suffices σ.IsCycle → (σ ∈ l ↔ ∀ a, σ a ≠ a → σ a = l.prod a) by
    exact ⟨fun hσ => ⟨h1 σ hσ, (this (h1 σ hσ)).mp hσ⟩, fun hσ => (this hσ.1).mpr hσ.2⟩
theorem mem_list_cycles_iff {α : Type*} [Finite α] {l : List (Perm α)}
    (h1 : ∀ σ : Perm α, σ ∈ l → σ.IsCycle) (h2 : l.Pairwise Disjoint) {σ : Perm α} :
    σ ∈ l ↔ σ.IsCycle ∧ ∀ a, σ a ≠ a → σ a = l.prod a := by
  suffices σ.IsCycle → (σ ∈ l ↔ ∀ a, σ a ≠ a → σ a = l.prod a) by
    

Proof state:
ι : Type u_1
α✝ : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α✝
α : Type u_4
inst✝ : Finite α
l : List (Perm α)
h1 : ∀ σ ∈ l, IsCycle σ
h2 : List.Pairwise Disjoint l
σ : Perm α
this : IsCycle σ → (σ ∈ l ↔ ∀ (a : α), σ a ≠ a → σ a = (List.prod l) a)
⊢ σ ∈ l ↔ IsCycle σ ∧ ∀ (a : α), σ a ≠ a → σ a = (List.prod l) a

Next tactic:
exact ⟨fun hσ => ⟨h1 σ hσ, (this (h1 σ hσ)).mp hσ⟩, fun hσ => (this hσ.1).mpr hσ.2⟩
theorem mem_list_cycles_iff {α : Type*} [Finite α] {l : List (Perm α)}
    (h1 : ∀ σ : Perm α, σ ∈ l → σ.IsCycle) (h2 : l.Pairwise Disjoint) {σ : Perm α} :
    σ ∈ l ↔ σ.IsCycle ∧ ∀ a, σ a ≠ a → σ a = l.prod a := by
  suffices σ.IsCycle → (σ ∈ l ↔ ∀ a, σ a ≠ a → σ a = l.prod a) by
    exact ⟨fun hσ => ⟨h1 σ hσ, (this (h1 σ hσ)).mp hσ⟩, fun hσ => (this hσ.1).mpr hσ.2⟩
  

Proof state:
ι : Type u_1
α✝ : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α✝
α : Type u_4
inst✝ : Finite α
l : List (Perm α)
h1 : ∀ σ ∈ l, IsCycle σ
h2 : List.Pairwise Disjoint l
σ : Perm α
⊢ IsCycle σ → (σ ∈ l ↔ ∀ (a : α), σ a ≠ a → σ a = (List.prod l) a)

Next tactic:
intro h3
theorem mem_list_cycles_iff {α : Type*} [Finite α] {l : List (Perm α)}
    (h1 : ∀ σ : Perm α, σ ∈ l → σ.IsCycle) (h2 : l.Pairwise Disjoint) {σ : Perm α} :
    σ ∈ l ↔ σ.IsCycle ∧ ∀ a, σ a ≠ a → σ a = l.prod a := by
  suffices σ.IsCycle → (σ ∈ l ↔ ∀ a, σ a ≠ a → σ a = l.prod a) by
    exact ⟨fun hσ => ⟨h1 σ hσ, (this (h1 σ hσ)).mp hσ⟩, fun hσ => (this hσ.1).mpr hσ.2⟩
  intro h3
  

Proof state:
ι : Type u_1
α✝ : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α✝
α : Type u_4
inst✝ : Finite α
l : List (Perm α)
h1 : ∀ σ ∈ l, IsCycle σ
h2 : List.Pairwise Disjoint l
σ : Perm α
h3 : IsCycle σ
⊢ σ ∈ l ↔ ∀ (a : α), σ a ≠ a → σ a = (List.prod l) a

Next tactic:
classical
    cases nonempty_fintype α
    constructor
    · intro h a ha
      exact eq_on_support_mem_disjoint h h2 _ (mem_support.mpr ha)
    · intro h
      have hσl : σ.support ⊆ l.prod.support := by
        intro x hx
        rw [mem_support] at hx
        rwa [mem_support, ← h _ hx]
      obtain ⟨a, ha, -⟩ := id h3
      rw [← mem_support] at ha
      obtain ⟨τ, hτ, hτa⟩ := exists_mem_support_of_mem_support_prod (hσl ha)
      have hτl : ∀ x ∈ τ.support, τ x = l.prod x := eq_on_support_mem_disjoint hτ h2
      have key : ∀ x ∈ σ.support ∩ τ.support, σ x = τ x := by
        intro x hx
        rw [h x (mem_support.mp (mem_of_mem_inter_left hx)), hτl x (mem_of_mem_inter_right hx)]
      convert hτ
      refine' h3.eq_on_support_inter_nonempty_congr (h1 _ hτ) key _ ha
      exact key a (mem_inter_of_mem ha hτa)
theorem mem_list_cycles_iff {α : Type*} [Finite α] {l : List (Perm α)}
    (h1 : ∀ σ : Perm α, σ ∈ l → σ.IsCycle) (h2 : l.Pairwise Disjoint) {σ : Perm α} :
    σ ∈ l ↔ σ.IsCycle ∧ ∀ a, σ a ≠ a → σ a = l.prod a := by
  suffices σ.IsCycle → (σ ∈ l ↔ ∀ a, σ a ≠ a → σ a = l.prod a) by
    exact ⟨fun hσ => ⟨h1 σ hσ, (this (h1 σ hσ)).mp hσ⟩, fun hσ => (this hσ.1).mpr hσ.2⟩
  intro h3
  classical
    

Proof state:
ι : Type u_1
α✝ : Type u_2
β : Type u_3
inst✝¹ : DecidableEq α✝
α : Type u_4
inst✝ : Finite α
l : List (Perm α)
h1 : ∀ σ ∈ l, IsCycle σ
h2 : List.Pairwise Disjoint l
σ : Perm α
h3 : IsCycle σ
⊢ σ ∈ l ↔ ∀ (a : α), σ a ≠ a → σ a = (List.prod l) a

Next tactic:
cases nonempty_fintype α