l3lab/ntp-mathlib huggingface dataset:
theorem _root_.Set.Countable.exists_cycleOn (hs : s.Countable) :
    ∃ f : Perm α, f.IsCycleOn s ∧ { x | f x ≠ x } ⊆ s := by
  classical
    obtain hs' | hs' := s.finite_or_infinite
    · refine'
        ⟨hs'.toFinset.toList.formPerm, _, fun x hx => by
          simpa using List.mem_of_formPerm_apply_ne _ _ hx⟩
      convert hs'.toFinset.nodup_toList.isCycleOn_formPerm
      simp
    haveI := hs.to_subtype
    

Proof state:
case inr
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : DecidableEq α
f : Perm α
s : Set α
hs : Set.Countable s
hs' : Set.Infinite s
this : Countable ↑s
⊢ ∃ f, IsCycleOn f s ∧ {x | f x ≠ x} ⊆ s

Next tactic:
haveI := hs'.to_subtype
theorem _root_.Set.Countable.exists_cycleOn (hs : s.Countable) :
    ∃ f : Perm α, f.IsCycleOn s ∧ { x | f x ≠ x } ⊆ s := by
  classical
    obtain hs' | hs' := s.finite_or_infinite
    · refine'
        ⟨hs'.toFinset.toList.formPerm, _, fun x hx => by
          simpa using List.mem_of_formPerm_apply_ne _ _ hx⟩
      convert hs'.toFinset.nodup_toList.isCycleOn_formPerm
      simp
    haveI := hs.to_subtype
    haveI := hs'.to_subtype
    

Proof state:
case inr
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : DecidableEq α
f : Perm α
s : Set α
hs : Set.Countable s
hs' : Set.Infinite s
this✝ : Countable ↑s
this : Infinite ↑s
⊢ ∃ f, IsCycleOn f s ∧ {x | f x ≠ x} ⊆ s

Next tactic:
obtain ⟨f⟩ : Nonempty (ℤ ≃ s) := inferInstance
theorem _root_.Set.Countable.exists_cycleOn (hs : s.Countable) :
    ∃ f : Perm α, f.IsCycleOn s ∧ { x | f x ≠ x } ⊆ s := by
  classical
    obtain hs' | hs' := s.finite_or_infinite
    · refine'
        ⟨hs'.toFinset.toList.formPerm, _, fun x hx => by
          simpa using List.mem_of_formPerm_apply_ne _ _ hx⟩
      convert hs'.toFinset.nodup_toList.isCycleOn_formPerm
      simp
    haveI := hs.to_subtype
    haveI := hs'.to_subtype
    obtain ⟨f⟩ : Nonempty (ℤ ≃ s) := inferInstance
    

Proof state:
case inr.intro
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : DecidableEq α
f✝ : Perm α
s : Set α
hs : Set.Countable s
hs' : Set.Infinite s
this✝ : Countable ↑s
this : Infinite ↑s
f : ℤ ≃ ↑s
⊢ ∃ f, IsCycleOn f s ∧ {x | f x ≠ x} ⊆ s

Next tactic:
refine'
      ⟨(Equiv.addRight 1).extendDomain f, _, fun x hx =>
        of_not_not fun h => hx <| Perm.extendDomain_apply_not_subtype _ _ h⟩
theorem _root_.Set.Countable.exists_cycleOn (hs : s.Countable) :
    ∃ f : Perm α, f.IsCycleOn s ∧ { x | f x ≠ x } ⊆ s := by
  classical
    obtain hs' | hs' := s.finite_or_infinite
    · refine'
        ⟨hs'.toFinset.toList.formPerm, _, fun x hx => by
          simpa using List.mem_of_formPerm_apply_ne _ _ hx⟩
      convert hs'.toFinset.nodup_toList.isCycleOn_formPerm
      simp
    haveI := hs.to_subtype
    haveI := hs'.to_subtype
    obtain ⟨f⟩ : Nonempty (ℤ ≃ s) := inferInstance
    refine'
      ⟨(Equiv.addRight 1).extendDomain f, _, fun x hx =>
        of_not_not fun h => hx <| Perm.extendDomain_apply_not_subtype _ _ h⟩
    

Proof state:
case inr.intro
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : DecidableEq α
f✝ : Perm α
s : Set α
hs : Set.Countable s
hs' : Set.Infinite s
this✝ : Countable ↑s
this : Infinite ↑s
f : ℤ ≃ ↑s
⊢ IsCycleOn (extendDomain (Equiv.addRight 1) f) s

Next tactic:
convert Int.addRight_one_isCycle.isCycleOn.extendDomain f
theorem _root_.Set.Countable.exists_cycleOn (hs : s.Countable) :
    ∃ f : Perm α, f.IsCycleOn s ∧ { x | f x ≠ x } ⊆ s := by
  classical
    obtain hs' | hs' := s.finite_or_infinite
    · refine'
        ⟨hs'.toFinset.toList.formPerm, _, fun x hx => by
          simpa using List.mem_of_formPerm_apply_ne _ _ hx⟩
      convert hs'.toFinset.nodup_toList.isCycleOn_formPerm
      simp
    haveI := hs.to_subtype
    haveI := hs'.to_subtype
    obtain ⟨f⟩ : Nonempty (ℤ ≃ s) := inferInstance
    refine'
      ⟨(Equiv.addRight 1).extendDomain f, _, fun x hx =>
        of_not_not fun h => hx <| Perm.extendDomain_apply_not_subtype _ _ h⟩
    convert Int.addRight_one_isCycle.isCycleOn.extendDomain f
    

Proof state:
case h.e'_3
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : DecidableEq α
f✝ : Perm α
s : Set α
hs : Set.Countable s
hs' : Set.Infinite s
this✝ : Countable ↑s
this : Infinite ↑s
f : ℤ ≃ ↑s
⊢ s = Subtype.val ∘ ⇑f '' {x | (Equiv.addRight 1) x ≠ x}

Next tactic:
rw [Set.image_comp, Equiv.image_eq_preimage]
theorem _root_.Set.Countable.exists_cycleOn (hs : s.Countable) :
    ∃ f : Perm α, f.IsCycleOn s ∧ { x | f x ≠ x } ⊆ s := by
  classical
    obtain hs' | hs' := s.finite_or_infinite
    · refine'
        ⟨hs'.toFinset.toList.formPerm, _, fun x hx => by
          simpa using List.mem_of_formPerm_apply_ne _ _ hx⟩
      convert hs'.toFinset.nodup_toList.isCycleOn_formPerm
      simp
    haveI := hs.to_subtype
    haveI := hs'.to_subtype
    obtain ⟨f⟩ : Nonempty (ℤ ≃ s) := inferInstance
    refine'
      ⟨(Equiv.addRight 1).extendDomain f, _, fun x hx =>
        of_not_not fun h => hx <| Perm.extendDomain_apply_not_subtype _ _ h⟩
    convert Int.addRight_one_isCycle.isCycleOn.extendDomain f
    rw [Set.image_comp, Equiv.image_eq_preimage]
    

Proof state:
case h.e'_3
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : DecidableEq α
f✝ : Perm α
s : Set α
hs : Set.Countable s
hs' : Set.Infinite s
this✝ : Countable ↑s
this : Infinite ↑s
f : ℤ ≃ ↑s
⊢ s = Subtype.val '' (⇑f.symm ⁻¹' {x | (Equiv.addRight 1) x ≠ x})

Next tactic:
ext
theorem _root_.Set.Countable.exists_cycleOn (hs : s.Countable) :
    ∃ f : Perm α, f.IsCycleOn s ∧ { x | f x ≠ x } ⊆ s := by
  classical
    obtain hs' | hs' := s.finite_or_infinite
    · refine'
        ⟨hs'.toFinset.toList.formPerm, _, fun x hx => by
          simpa using List.mem_of_formPerm_apply_ne _ _ hx⟩
      convert hs'.toFinset.nodup_toList.isCycleOn_formPerm
      simp
    haveI := hs.to_subtype
    haveI := hs'.to_subtype
    obtain ⟨f⟩ : Nonempty (ℤ ≃ s) := inferInstance
    refine'
      ⟨(Equiv.addRight 1).extendDomain f, _, fun x hx =>
        of_not_not fun h => hx <| Perm.extendDomain_apply_not_subtype _ _ h⟩
    convert Int.addRight_one_isCycle.isCycleOn.extendDomain f
    rw [Set.image_comp, Equiv.image_eq_preimage]
    ext
    

Proof state:
case h.e'_3.h
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : DecidableEq α
f✝ : Perm α
s : Set α
hs : Set.Countable s
hs' : Set.Infinite s
this✝ : Countable ↑s
this : Infinite ↑s
f : ℤ ≃ ↑s
x✝ : α
⊢ x✝ ∈ s ↔ x✝ ∈ Subtype.val '' (⇑f.symm ⁻¹' {x | (Equiv.addRight 1) x ≠ x})

Next tactic:
simp
theorem _root_.Set.prod_self_eq_iUnion_perm (hf : f.IsCycleOn s) :
    s ×ˢ s = ⋃ n : ℤ, (fun a => (a, (f ^ n) a)) '' s := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : DecidableEq α
f : Perm α
s : Set α
hf : IsCycleOn f s
⊢ s ×ˢ s = ⋃ n, (fun a => (a, (f ^ n) a)) '' s

Next tactic:
ext ⟨a, b⟩
theorem _root_.Set.prod_self_eq_iUnion_perm (hf : f.IsCycleOn s) :
    s ×ˢ s = ⋃ n : ℤ, (fun a => (a, (f ^ n) a)) '' s := by
  ext ⟨a, b⟩
  

Proof state:
case h.mk
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : DecidableEq α
f : Perm α
s : Set α
hf : IsCycleOn f s
a b : α
⊢ (a, b) ∈ s ×ˢ s ↔ (a, b) ∈ ⋃ n, (fun a => (a, (f ^ n) a)) '' s

Next tactic:
simp only [Set.mem_prod, Set.mem_iUnion, Set.mem_image]
theorem _root_.Set.prod_self_eq_iUnion_perm (hf : f.IsCycleOn s) :
    s ×ˢ s = ⋃ n : ℤ, (fun a => (a, (f ^ n) a)) '' s := by
  ext ⟨a, b⟩
  simp only [Set.mem_prod, Set.mem_iUnion, Set.mem_image]
  

Proof state:
case h.mk
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : DecidableEq α
f : Perm α
s : Set α
hf : IsCycleOn f s
a b : α
⊢ a ∈ s ∧ b ∈ s ↔ ∃ i, ∃ x ∈ s, (x, (f ^ i) x) = (a, b)

Next tactic:
refine' ⟨fun hx => _, _⟩
theorem _root_.Set.prod_self_eq_iUnion_perm (hf : f.IsCycleOn s) :
    s ×ˢ s = ⋃ n : ℤ, (fun a => (a, (f ^ n) a)) '' s := by
  ext ⟨a, b⟩
  simp only [Set.mem_prod, Set.mem_iUnion, Set.mem_image]
  refine' ⟨fun hx => _, _⟩
  · 

Proof state:
case h.mk.refine'_1
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : DecidableEq α
f : Perm α
s : Set α
hf : IsCycleOn f s
a b : α
hx : a ∈ s ∧ b ∈ s
⊢ ∃ i, ∃ x ∈ s, (x, (f ^ i) x) = (a, b)

Next tactic:
obtain ⟨n, rfl⟩ := hf.2 hx.1 hx.2
theorem _root_.Set.prod_self_eq_iUnion_perm (hf : f.IsCycleOn s) :
    s ×ˢ s = ⋃ n : ℤ, (fun a => (a, (f ^ n) a)) '' s := by
  ext ⟨a, b⟩
  simp only [Set.mem_prod, Set.mem_iUnion, Set.mem_image]
  refine' ⟨fun hx => _, _⟩
  · obtain ⟨n, rfl⟩ := hf.2 hx.1 hx.2
    

Proof state:
case h.mk.refine'_1.intro
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : DecidableEq α
f : Perm α
s : Set α
hf : IsCycleOn f s
a : α
n : ℤ
hx : a ∈ s ∧ (f ^ n) a ∈ s
⊢ ∃ i, ∃ x ∈ s, (x, (f ^ i) x) = (a, (f ^ n) a)

Next tactic:
exact ⟨_, _, hx.1, rfl⟩
theorem _root_.Set.prod_self_eq_iUnion_perm (hf : f.IsCycleOn s) :
    s ×ˢ s = ⋃ n : ℤ, (fun a => (a, (f ^ n) a)) '' s := by
  ext ⟨a, b⟩
  simp only [Set.mem_prod, Set.mem_iUnion, Set.mem_image]
  refine' ⟨fun hx => _, _⟩
  · obtain ⟨n, rfl⟩ := hf.2 hx.1 hx.2
    exact ⟨_, _, hx.1, rfl⟩
  · 

Proof state:
case h.mk.refine'_2
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : DecidableEq α
f : Perm α
s : Set α
hf : IsCycleOn f s
a b : α
⊢ (∃ i, ∃ x ∈ s, (x, (f ^ i) x) = (a, b)) → a ∈ s ∧ b ∈ s

Next tactic:
rintro ⟨n, a, ha, ⟨⟩⟩
theorem _root_.Set.prod_self_eq_iUnion_perm (hf : f.IsCycleOn s) :
    s ×ˢ s = ⋃ n : ℤ, (fun a => (a, (f ^ n) a)) '' s := by
  ext ⟨a, b⟩
  simp only [Set.mem_prod, Set.mem_iUnion, Set.mem_image]
  refine' ⟨fun hx => _, _⟩
  · obtain ⟨n, rfl⟩ := hf.2 hx.1 hx.2
    exact ⟨_, _, hx.1, rfl⟩
  · rintro ⟨n, a, ha, ⟨⟩⟩
    

Proof state:
case h.mk.refine'_2.intro.intro.intro.refl
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : DecidableEq α
f : Perm α
s : Set α
hf : IsCycleOn f s
a : α
n : ℤ
ha : a ∈ s
⊢ a ∈ s ∧ (f ^ n) a ∈ s

Next tactic:
exact ⟨ha, (hf.1.perm_zpow _).mapsTo ha⟩
theorem _root_.Finset.product_self_eq_disjiUnion_perm_aux (hf : f.IsCycleOn s) :
    (range s.card : Set ℕ).PairwiseDisjoint fun k =>
      s.map ⟨fun i => (i, (f ^ k) i), fun i j => congr_arg Prod.fst⟩ := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : DecidableEq α
f : Perm α
s : Finset α
hf : IsCycleOn f ↑s
⊢ Set.PairwiseDisjoint ↑(range (card s)) fun k =>
    map
      { toFun := fun i => (i, (f ^ k) i),
        inj' :=
          (_ :
            ∀ (i j : α),
              (fun i => (i, (f ^ k) i)) i = (fun i => (i, (f ^ k) i)) j →
                ((fun i => (i, (f ^ k) i)) i).1 = ((fun i => (i, (f ^ k) i)) j).1) }
      s

Next tactic:
obtain hs | _ := (s : Set α).subsingleton_or_nontrivial
theorem _root_.Finset.product_self_eq_disjiUnion_perm_aux (hf : f.IsCycleOn s) :
    (range s.card : Set ℕ).PairwiseDisjoint fun k =>
      s.map ⟨fun i => (i, (f ^ k) i), fun i j => congr_arg Prod.fst⟩ := by
  obtain hs | _ := (s : Set α).subsingleton_or_nontrivial
  · 

Proof state:
case inl
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : DecidableEq α
f : Perm α
s : Finset α
hf : IsCycleOn f ↑s
hs : Set.Subsingleton ↑s
⊢ Set.PairwiseDisjoint ↑(range (card s)) fun k =>
    map
      { toFun := fun i => (i, (f ^ k) i),
        inj' :=
          (_ :
            ∀ (i j : α),
              (fun i => (i, (f ^ k) i)) i = (fun i => (i, (f ^ k) i)) j →
                ((fun i => (i, (f ^ k) i)) i).1 = ((fun i => (i, (f ^ k) i)) j).1) }
      s

Next tactic:
refine' Set.Subsingleton.pairwise _ _
theorem _root_.Finset.product_self_eq_disjiUnion_perm_aux (hf : f.IsCycleOn s) :
    (range s.card : Set ℕ).PairwiseDisjoint fun k =>
      s.map ⟨fun i => (i, (f ^ k) i), fun i j => congr_arg Prod.fst⟩ := by
  obtain hs | _ := (s : Set α).subsingleton_or_nontrivial
  · refine' Set.Subsingleton.pairwise _ _
    

Proof state:
case inl
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : DecidableEq α
f : Perm α
s : Finset α
hf : IsCycleOn f ↑s
hs : Set.Subsingleton ↑s
⊢ Set.Subsingleton ↑(range (card s))

Next tactic:
simp_rw [Set.Subsingleton, mem_coe, ← card_le_one] at hs ⊢
theorem _root_.Finset.product_self_eq_disjiUnion_perm_aux (hf : f.IsCycleOn s) :
    (range s.card : Set ℕ).PairwiseDisjoint fun k =>
      s.map ⟨fun i => (i, (f ^ k) i), fun i j => congr_arg Prod.fst⟩ := by
  obtain hs | _ := (s : Set α).subsingleton_or_nontrivial
  · refine' Set.Subsingleton.pairwise _ _
    simp_rw [Set.Subsingleton, mem_coe, ← card_le_one] at hs ⊢
    

Proof state:
case inl
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : DecidableEq α
f : Perm α
s : Finset α
hf : IsCycleOn f ↑s
hs : card s ≤ 1
⊢ card (range (card s)) ≤ 1

Next tactic:
rwa [card_range]
theorem _root_.Finset.product_self_eq_disjiUnion_perm_aux (hf : f.IsCycleOn s) :
    (range s.card : Set ℕ).PairwiseDisjoint fun k =>
      s.map ⟨fun i => (i, (f ^ k) i), fun i j => congr_arg Prod.fst⟩ := by
  obtain hs | _ := (s : Set α).subsingleton_or_nontrivial
  · refine' Set.Subsingleton.pairwise _ _
    simp_rw [Set.Subsingleton, mem_coe, ← card_le_one] at hs ⊢
    rwa [card_range]
  

Proof state:
case inr
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : DecidableEq α
f : Perm α
s : Finset α
hf : IsCycleOn f ↑s
h✝ : Set.Nontrivial ↑s
⊢ Set.PairwiseDisjoint ↑(range (card s)) fun k =>
    map
      { toFun := fun i => (i, (f ^ k) i),
        inj' :=
          (_ :
            ∀ (i j : α),
              (fun i => (i, (f ^ k) i)) i = (fun i => (i, (f ^ k) i)) j →
                ((fun i => (i, (f ^ k) i)) i).1 = ((fun i => (i, (f ^ k) i)) j).1) }
      s

Next tactic:
classical
    rintro m hm n hn hmn
    simp only [disjoint_left, Function.onFun, mem_map, Function.Embedding.coeFn_mk, exists_prop,
      not_exists, not_and, forall_exists_index, and_imp, Prod.forall, Prod.mk.inj_iff]
    rintro _ _ _ - rfl rfl a ha rfl h
    rw [hf.pow_apply_eq_pow_apply ha] at h
    rw [mem_coe, mem_range] at hm hn
    exact hmn.symm (h.eq_of_lt_of_lt hn hm)
theorem _root_.Finset.product_self_eq_disjiUnion_perm_aux (hf : f.IsCycleOn s) :
    (range s.card : Set ℕ).PairwiseDisjoint fun k =>
      s.map ⟨fun i => (i, (f ^ k) i), fun i j => congr_arg Prod.fst⟩ := by
  obtain hs | _ := (s : Set α).subsingleton_or_nontrivial
  · refine' Set.Subsingleton.pairwise _ _
    simp_rw [Set.Subsingleton, mem_coe, ← card_le_one] at hs ⊢
    rwa [card_range]
  classical
    

Proof state:
case inr
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : DecidableEq α
f : Perm α
s : Finset α
hf : IsCycleOn f ↑s
h✝ : Set.Nontrivial ↑s
⊢ Set.PairwiseDisjoint ↑(range (card s)) fun k =>
    map
      { toFun := fun i => (i, (f ^ k) i),
        inj' :=
          (_ :
            ∀ (i j : α),
              (fun i => (i, (f ^ k) i)) i = (fun i => (i, (f ^ k) i)) j →
                ((fun i => (i, (f ^ k) i)) i).1 = ((fun i => (i, (f ^ k) i)) j).1) }
      s

Next tactic:
rintro m hm n hn hmn
theorem _root_.Finset.product_self_eq_disjiUnion_perm_aux (hf : f.IsCycleOn s) :
    (range s.card : Set ℕ).PairwiseDisjoint fun k =>
      s.map ⟨fun i => (i, (f ^ k) i), fun i j => congr_arg Prod.fst⟩ := by
  obtain hs | _ := (s : Set α).subsingleton_or_nontrivial
  · refine' Set.Subsingleton.pairwise _ _
    simp_rw [Set.Subsingleton, mem_coe, ← card_le_one] at hs ⊢
    rwa [card_range]
  classical
    rintro m hm n hn hmn
    

Proof state:
case inr
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : DecidableEq α
f : Perm α
s : Finset α
hf : IsCycleOn f ↑s
h✝ : Set.Nontrivial ↑s
m : ℕ
hm : m ∈ ↑(range (card s))
n : ℕ
hn : n ∈ ↑(range (card s))
hmn : m ≠ n
⊢ (_root_.Disjoint on fun k =>
      map
        { toFun := fun i => (i, (f ^ k) i),
          inj' :=
            (_ :
              ∀ (i j : α),
                (fun i => (i, (f ^ k) i)) i = (fun i => (i, (f ^ k) i)) j →
                  ((fun i => (i, (f ^ k) i)) i).1 = ((fun i => (i, (f ^ k) i)) j).1) }
        s)
    m n

Next tactic:
simp only [disjoint_left, Function.onFun, mem_map, Function.Embedding.coeFn_mk, exists_prop,
      not_exists, not_and, forall_exists_index, and_imp, Prod.forall, Prod.mk.inj_iff]
theorem _root_.Finset.product_self_eq_disjiUnion_perm_aux (hf : f.IsCycleOn s) :
    (range s.card : Set ℕ).PairwiseDisjoint fun k =>
      s.map ⟨fun i => (i, (f ^ k) i), fun i j => congr_arg Prod.fst⟩ := by
  obtain hs | _ := (s : Set α).subsingleton_or_nontrivial
  · refine' Set.Subsingleton.pairwise _ _
    simp_rw [Set.Subsingleton, mem_coe, ← card_le_one] at hs ⊢
    rwa [card_range]
  classical
    rintro m hm n hn hmn
    simp only [disjoint_left, Function.onFun, mem_map, Function.Embedding.coeFn_mk, exists_prop,
      not_exists, not_and, forall_exists_index, and_imp, Prod.forall, Prod.mk.inj_iff]
    

Proof state:
case inr
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : DecidableEq α
f : Perm α
s : Finset α
hf : IsCycleOn f ↑s
h✝ : Set.Nontrivial ↑s
m : ℕ
hm : m ∈ ↑(range (card s))
n : ℕ
hn : n ∈ ↑(range (card s))
hmn : m ≠ n
⊢ ∀ (a b x : α), x ∈ s → x = a → (f ^ m) x = b → ∀ x ∈ s, x = a → ¬(f ^ n) x = b

Next tactic:
rintro _ _ _ - rfl rfl a ha rfl h
theorem _root_.Finset.product_self_eq_disjiUnion_perm_aux (hf : f.IsCycleOn s) :
    (range s.card : Set ℕ).PairwiseDisjoint fun k =>
      s.map ⟨fun i => (i, (f ^ k) i), fun i j => congr_arg Prod.fst⟩ := by
  obtain hs | _ := (s : Set α).subsingleton_or_nontrivial
  · refine' Set.Subsingleton.pairwise _ _
    simp_rw [Set.Subsingleton, mem_coe, ← card_le_one] at hs ⊢
    rwa [card_range]
  classical
    rintro m hm n hn hmn
    simp only [disjoint_left, Function.onFun, mem_map, Function.Embedding.coeFn_mk, exists_prop,
      not_exists, not_and, forall_exists_index, and_imp, Prod.forall, Prod.mk.inj_iff]
    rintro _ _ _ - rfl rfl a ha rfl h
    

Proof state:
case inr
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : DecidableEq α
f : Perm α
s : Finset α
hf : IsCycleOn f ↑s
h✝ : Set.Nontrivial ↑s
m : ℕ
hm : m ∈ ↑(range (card s))
n : ℕ
hn : n ∈ ↑(range (card s))
hmn : m ≠ n
a : α
ha : a ∈ s
h : (f ^ n) a = (f ^ m) a
⊢ False

Next tactic:
rw [hf.pow_apply_eq_pow_apply ha] at h
theorem _root_.Finset.product_self_eq_disjiUnion_perm_aux (hf : f.IsCycleOn s) :
    (range s.card : Set ℕ).PairwiseDisjoint fun k =>
      s.map ⟨fun i => (i, (f ^ k) i), fun i j => congr_arg Prod.fst⟩ := by
  obtain hs | _ := (s : Set α).subsingleton_or_nontrivial
  · refine' Set.Subsingleton.pairwise _ _
    simp_rw [Set.Subsingleton, mem_coe, ← card_le_one] at hs ⊢
    rwa [card_range]
  classical
    rintro m hm n hn hmn
    simp only [disjoint_left, Function.onFun, mem_map, Function.Embedding.coeFn_mk, exists_prop,
      not_exists, not_and, forall_exists_index, and_imp, Prod.forall, Prod.mk.inj_iff]
    rintro _ _ _ - rfl rfl a ha rfl h
    rw [hf.pow_apply_eq_pow_apply ha] at h
    

Proof state:
case inr
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : DecidableEq α
f : Perm α
s : Finset α
hf : IsCycleOn f ↑s
h✝ : Set.Nontrivial ↑s
m : ℕ
hm : m ∈ ↑(range (card s))
n : ℕ
hn : n ∈ ↑(range (card s))
hmn : m ≠ n
a : α
ha : a ∈ s
h : n ≡ m [MOD card s]
⊢ False

Next tactic:
rw [mem_coe, mem_range] at hm hn
theorem _root_.Finset.product_self_eq_disjiUnion_perm_aux (hf : f.IsCycleOn s) :
    (range s.card : Set ℕ).PairwiseDisjoint fun k =>
      s.map ⟨fun i => (i, (f ^ k) i), fun i j => congr_arg Prod.fst⟩ := by
  obtain hs | _ := (s : Set α).subsingleton_or_nontrivial
  · refine' Set.Subsingleton.pairwise _ _
    simp_rw [Set.Subsingleton, mem_coe, ← card_le_one] at hs ⊢
    rwa [card_range]
  classical
    rintro m hm n hn hmn
    simp only [disjoint_left, Function.onFun, mem_map, Function.Embedding.coeFn_mk, exists_prop,
      not_exists, not_and, forall_exists_index, and_imp, Prod.forall, Prod.mk.inj_iff]
    rintro _ _ _ - rfl rfl a ha rfl h
    rw [hf.pow_apply_eq_pow_apply ha] at h
    rw [mem_coe, mem_range] at hm hn
    

Proof state:
case inr
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : DecidableEq α
f : Perm α
s : Finset α
hf : IsCycleOn f ↑s
h✝ : Set.Nontrivial ↑s
m : ℕ
hm : m < card s
n : ℕ
hn : n < card s
hmn : m ≠ n
a : α
ha : a ∈ s
h : n ≡ m [MOD card s]
⊢ False

Next tactic:
exact hmn.symm (h.eq_of_lt_of_lt hn hm)
/-- We can partition the square `s ×ˢ s` into shifted diagonals as such:
```
01234
40123
34012
23401
12340
```

The diagonals are given by the cycle `f`.
-/
theorem _root_.Finset.product_self_eq_disjiUnion_perm (hf : f.IsCycleOn s) :
    s ×ˢ s =
      (range s.card).disjiUnion
        (fun k => s.map ⟨fun i => (i, (f ^ k) i), fun i j => congr_arg Prod.fst⟩)
        (product_self_eq_disjiUnion_perm_aux hf) := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : DecidableEq α
f : Perm α
s : Finset α
hf : IsCycleOn f ↑s
⊢ s ×ˢ s =
    disjiUnion (range (card s))
      (fun k =>
        map
          { toFun := fun i => (i, (f ^ k) i),
            inj' :=
              (_ :
                ∀ (i j : α),
                  (fun i => (i, (f ^ k) i)) i = (fun i => (i, (f ^ k) i)) j →
                    ((fun i => (i, (f ^ k) i)) i).1 = ((fun i => (i, (f ^ k) i)) j).1) }
          s)
      (_ :
        Set.PairwiseDisjoint ↑(range (card s)) fun k =>
          map
            { toFun := fun i => (i, (f ^ k) i),
              inj' :=
                (_ :
                  ∀ (i j : α),
                    (fun i => (i, (f ^ k) i)) i = (fun i => (i, (f ^ k) i)) j →
                      ((fun i => (i, (f ^ k) i)) i).1 = ((fun i => (i, (f ^ k) i)) j).1) }
            s)

Next tactic:
ext ⟨a, b⟩
/-- We can partition the square `s ×ˢ s` into shifted diagonals as such:
```
01234
40123
34012
23401
12340
```

The diagonals are given by the cycle `f`.
-/
theorem _root_.Finset.product_self_eq_disjiUnion_perm (hf : f.IsCycleOn s) :
    s ×ˢ s =
      (range s.card).disjiUnion
        (fun k => s.map ⟨fun i => (i, (f ^ k) i), fun i j => congr_arg Prod.fst⟩)
        (product_self_eq_disjiUnion_perm_aux hf) := by
  ext ⟨a, b⟩
  

Proof state:
case a.mk
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : DecidableEq α
f : Perm α
s : Finset α
hf : IsCycleOn f ↑s
a b : α
⊢ (a, b) ∈ s ×ˢ s ↔
    (a, b) ∈
      disjiUnion (range (card s))
        (fun k =>
          map
            { toFun := fun i => (i, (f ^ k) i),
              inj' :=
                (_ :
                  ∀ (i j : α),
                    (fun i => (i, (f ^ k) i)) i = (fun i => (i, (f ^ k) i)) j →
                      ((fun i => (i, (f ^ k) i)) i).1 = ((fun i => (i, (f ^ k) i)) j).1) }
            s)
        (_ :
          Set.PairwiseDisjoint ↑(range (card s)) fun k =>
            map
              { toFun := fun i => (i, (f ^ k) i),
                inj' :=
                  (_ :
                    ∀ (i j : α),
                      (fun i => (i, (f ^ k) i)) i = (fun i => (i, (f ^ k) i)) j →
                        ((fun i => (i, (f ^ k) i)) i).1 = ((fun i => (i, (f ^ k) i)) j).1) }
              s)

Next tactic:
simp only [mem_product, Equiv.Perm.coe_pow, mem_disjiUnion, mem_range, mem_map,
    Function.Embedding.coeFn_mk, Prod.mk.inj_iff, exists_prop]
/-- We can partition the square `s ×ˢ s` into shifted diagonals as such:
```
01234
40123
34012
23401
12340
```

The diagonals are given by the cycle `f`.
-/
theorem _root_.Finset.product_self_eq_disjiUnion_perm (hf : f.IsCycleOn s) :
    s ×ˢ s =
      (range s.card).disjiUnion
        (fun k => s.map ⟨fun i => (i, (f ^ k) i), fun i j => congr_arg Prod.fst⟩)
        (product_self_eq_disjiUnion_perm_aux hf) := by
  ext ⟨a, b⟩
  simp only [mem_product, Equiv.Perm.coe_pow, mem_disjiUnion, mem_range, mem_map,
    Function.Embedding.coeFn_mk, Prod.mk.inj_iff, exists_prop]
  

Proof state:
case a.mk
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : DecidableEq α
f : Perm α
s : Finset α
hf : IsCycleOn f ↑s
a b : α
⊢ a ∈ s ∧ b ∈ s ↔ ∃ a_1 < card s, ∃ a_2 ∈ s, a_2 = a ∧ (⇑f)^[a_1] a_2 = b

Next tactic:
refine' ⟨fun hx => _, _⟩
/-- We can partition the square `s ×ˢ s` into shifted diagonals as such:
```
01234
40123
34012
23401
12340
```

The diagonals are given by the cycle `f`.
-/
theorem _root_.Finset.product_self_eq_disjiUnion_perm (hf : f.IsCycleOn s) :
    s ×ˢ s =
      (range s.card).disjiUnion
        (fun k => s.map ⟨fun i => (i, (f ^ k) i), fun i j => congr_arg Prod.fst⟩)
        (product_self_eq_disjiUnion_perm_aux hf) := by
  ext ⟨a, b⟩
  simp only [mem_product, Equiv.Perm.coe_pow, mem_disjiUnion, mem_range, mem_map,
    Function.Embedding.coeFn_mk, Prod.mk.inj_iff, exists_prop]
  refine' ⟨fun hx => _, _⟩
  · 

Proof state:
case a.mk.refine'_1
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : DecidableEq α
f : Perm α
s : Finset α
hf : IsCycleOn f ↑s
a b : α
hx : a ∈ s ∧ b ∈ s
⊢ ∃ a_1 < card s, ∃ a_2 ∈ s, a_2 = a ∧ (⇑f)^[a_1] a_2 = b

Next tactic:
obtain ⟨n, hn, rfl⟩ := hf.exists_pow_eq hx.1 hx.2