l3lab/ntp-mathlib huggingface dataset:
theorem IsCycle.existsUnique_cycle {f : Perm α} (hf : IsCycle f) :
    ∃! s : Cycle α, ∃ h : s.Nodup, s.formPerm h = f := by
  cases nonempty_fintype α
  obtain ⟨x, hx, hy⟩ := id hf
  refine' ⟨f.toList x, ⟨nodup_toList f x, _⟩, _⟩
  · simp [formPerm_toList, hf.cycleOf_eq hx]
  · rintro ⟨l⟩ ⟨hn, rfl⟩
    simp only [Cycle.mk_eq_coe, Cycle.coe_eq_coe, Subtype.coe_mk, Cycle.formPerm_coe]
    refine' (toList_formPerm_isRotated_self _ _ hn _ _).symm
    · contrapose! hx
      suffices formPerm l = 1 by 

Proof state:
α : Type u_1
inst✝¹ : Finite α
inst✝ : DecidableEq α
val✝ : Fintype α
x : α
y✝ : Cycle α
l : List α
hn : Cycle.Nodup (Quot.mk Setoid.r l)
hf : IsCycle (Cycle.formPerm (Quot.mk Setoid.r l) hn)
hy : ∀ ⦃y : α⦄, (Cycle.formPerm (Quot.mk Setoid.r l) hn) y ≠ y → SameCycle (Cycle.formPerm (Quot.mk Setoid.r l) hn) x y
hx : length l < 2
this : formPerm l = 1
⊢ (Cycle.formPerm (Quot.mk Setoid.r l) hn) x = x

Next tactic:
simp [this]
theorem IsCycle.existsUnique_cycle {f : Perm α} (hf : IsCycle f) :
    ∃! s : Cycle α, ∃ h : s.Nodup, s.formPerm h = f := by
  cases nonempty_fintype α
  obtain ⟨x, hx, hy⟩ := id hf
  refine' ⟨f.toList x, ⟨nodup_toList f x, _⟩, _⟩
  · simp [formPerm_toList, hf.cycleOf_eq hx]
  · rintro ⟨l⟩ ⟨hn, rfl⟩
    simp only [Cycle.mk_eq_coe, Cycle.coe_eq_coe, Subtype.coe_mk, Cycle.formPerm_coe]
    refine' (toList_formPerm_isRotated_self _ _ hn _ _).symm
    · contrapose! hx
      suffices formPerm l = 1 by simp [this]
      

Proof state:
case intro.intro.intro.refine'_2.mk.intro.refine'_1
α : Type u_1
inst✝¹ : Finite α
inst✝ : DecidableEq α
val✝ : Fintype α
x : α
y✝ : Cycle α
l : List α
hn : Cycle.Nodup (Quot.mk Setoid.r l)
hf : IsCycle (Cycle.formPerm (Quot.mk Setoid.r l) hn)
hy : ∀ ⦃y : α⦄, (Cycle.formPerm (Quot.mk Setoid.r l) hn) y ≠ y → SameCycle (Cycle.formPerm (Quot.mk Setoid.r l) hn) x y
hx : length l < 2
⊢ formPerm l = 1

Next tactic:
rw [formPerm_eq_one_iff _ hn]
theorem IsCycle.existsUnique_cycle {f : Perm α} (hf : IsCycle f) :
    ∃! s : Cycle α, ∃ h : s.Nodup, s.formPerm h = f := by
  cases nonempty_fintype α
  obtain ⟨x, hx, hy⟩ := id hf
  refine' ⟨f.toList x, ⟨nodup_toList f x, _⟩, _⟩
  · simp [formPerm_toList, hf.cycleOf_eq hx]
  · rintro ⟨l⟩ ⟨hn, rfl⟩
    simp only [Cycle.mk_eq_coe, Cycle.coe_eq_coe, Subtype.coe_mk, Cycle.formPerm_coe]
    refine' (toList_formPerm_isRotated_self _ _ hn _ _).symm
    · contrapose! hx
      suffices formPerm l = 1 by simp [this]
      rw [formPerm_eq_one_iff _ hn]
      

Proof state:
case intro.intro.intro.refine'_2.mk.intro.refine'_1
α : Type u_1
inst✝¹ : Finite α
inst✝ : DecidableEq α
val✝ : Fintype α
x : α
y✝ : Cycle α
l : List α
hn : Cycle.Nodup (Quot.mk Setoid.r l)
hf : IsCycle (Cycle.formPerm (Quot.mk Setoid.r l) hn)
hy : ∀ ⦃y : α⦄, (Cycle.formPerm (Quot.mk Setoid.r l) hn) y ≠ y → SameCycle (Cycle.formPerm (Quot.mk Setoid.r l) hn) x y
hx : length l < 2
⊢ length l ≤ 1

Next tactic:
exact Nat.le_of_lt_succ hx
theorem IsCycle.existsUnique_cycle {f : Perm α} (hf : IsCycle f) :
    ∃! s : Cycle α, ∃ h : s.Nodup, s.formPerm h = f := by
  cases nonempty_fintype α
  obtain ⟨x, hx, hy⟩ := id hf
  refine' ⟨f.toList x, ⟨nodup_toList f x, _⟩, _⟩
  · simp [formPerm_toList, hf.cycleOf_eq hx]
  · rintro ⟨l⟩ ⟨hn, rfl⟩
    simp only [Cycle.mk_eq_coe, Cycle.coe_eq_coe, Subtype.coe_mk, Cycle.formPerm_coe]
    refine' (toList_formPerm_isRotated_self _ _ hn _ _).symm
    · contrapose! hx
      suffices formPerm l = 1 by simp [this]
      rw [formPerm_eq_one_iff _ hn]
      exact Nat.le_of_lt_succ hx
    · 

Proof state:
case intro.intro.intro.refine'_2.mk.intro.refine'_2
α : Type u_1
inst✝¹ : Finite α
inst✝ : DecidableEq α
val✝ : Fintype α
x : α
y✝ : Cycle α
l : List α
hn : Cycle.Nodup (Quot.mk Setoid.r l)
hf : IsCycle (Cycle.formPerm (Quot.mk Setoid.r l) hn)
hx : (Cycle.formPerm (Quot.mk Setoid.r l) hn) x ≠ x
hy : ∀ ⦃y : α⦄, (Cycle.formPerm (Quot.mk Setoid.r l) hn) y ≠ y → SameCycle (Cycle.formPerm (Quot.mk Setoid.r l) hn) x y
⊢ x ∈ l

Next tactic:
rw [← mem_toFinset]
theorem IsCycle.existsUnique_cycle {f : Perm α} (hf : IsCycle f) :
    ∃! s : Cycle α, ∃ h : s.Nodup, s.formPerm h = f := by
  cases nonempty_fintype α
  obtain ⟨x, hx, hy⟩ := id hf
  refine' ⟨f.toList x, ⟨nodup_toList f x, _⟩, _⟩
  · simp [formPerm_toList, hf.cycleOf_eq hx]
  · rintro ⟨l⟩ ⟨hn, rfl⟩
    simp only [Cycle.mk_eq_coe, Cycle.coe_eq_coe, Subtype.coe_mk, Cycle.formPerm_coe]
    refine' (toList_formPerm_isRotated_self _ _ hn _ _).symm
    · contrapose! hx
      suffices formPerm l = 1 by simp [this]
      rw [formPerm_eq_one_iff _ hn]
      exact Nat.le_of_lt_succ hx
    · rw [← mem_toFinset]
      

Proof state:
case intro.intro.intro.refine'_2.mk.intro.refine'_2
α : Type u_1
inst✝¹ : Finite α
inst✝ : DecidableEq α
val✝ : Fintype α
x : α
y✝ : Cycle α
l : List α
hn : Cycle.Nodup (Quot.mk Setoid.r l)
hf : IsCycle (Cycle.formPerm (Quot.mk Setoid.r l) hn)
hx : (Cycle.formPerm (Quot.mk Setoid.r l) hn) x ≠ x
hy : ∀ ⦃y : α⦄, (Cycle.formPerm (Quot.mk Setoid.r l) hn) y ≠ y → SameCycle (Cycle.formPerm (Quot.mk Setoid.r l) hn) x y
⊢ x ∈ toFinset l

Next tactic:
refine' support_formPerm_le l _
theorem IsCycle.existsUnique_cycle {f : Perm α} (hf : IsCycle f) :
    ∃! s : Cycle α, ∃ h : s.Nodup, s.formPerm h = f := by
  cases nonempty_fintype α
  obtain ⟨x, hx, hy⟩ := id hf
  refine' ⟨f.toList x, ⟨nodup_toList f x, _⟩, _⟩
  · simp [formPerm_toList, hf.cycleOf_eq hx]
  · rintro ⟨l⟩ ⟨hn, rfl⟩
    simp only [Cycle.mk_eq_coe, Cycle.coe_eq_coe, Subtype.coe_mk, Cycle.formPerm_coe]
    refine' (toList_formPerm_isRotated_self _ _ hn _ _).symm
    · contrapose! hx
      suffices formPerm l = 1 by simp [this]
      rw [formPerm_eq_one_iff _ hn]
      exact Nat.le_of_lt_succ hx
    · rw [← mem_toFinset]
      refine' support_formPerm_le l _
      

Proof state:
case intro.intro.intro.refine'_2.mk.intro.refine'_2
α : Type u_1
inst✝¹ : Finite α
inst✝ : DecidableEq α
val✝ : Fintype α
x : α
y✝ : Cycle α
l : List α
hn : Cycle.Nodup (Quot.mk Setoid.r l)
hf : IsCycle (Cycle.formPerm (Quot.mk Setoid.r l) hn)
hx : (Cycle.formPerm (Quot.mk Setoid.r l) hn) x ≠ x
hy : ∀ ⦃y : α⦄, (Cycle.formPerm (Quot.mk Setoid.r l) hn) y ≠ y → SameCycle (Cycle.formPerm (Quot.mk Setoid.r l) hn) x y
⊢ x ∈ support (formPerm l)

Next tactic:
simpa using hx
theorem IsCycle.existsUnique_cycle_subtype {f : Perm α} (hf : IsCycle f) :
    ∃! s : { s : Cycle α // s.Nodup }, (s : Cycle α).formPerm s.prop = f := by
  

Proof state:
α : Type u_1
inst✝¹ : Finite α
inst✝ : DecidableEq α
f : Perm α
hf : IsCycle f
⊢ ∃! s, Cycle.formPerm ↑s (_ : Cycle.Nodup ↑s) = f

Next tactic:
obtain ⟨s, ⟨hs, rfl⟩, hs'⟩ := hf.existsUnique_cycle
theorem IsCycle.existsUnique_cycle_subtype {f : Perm α} (hf : IsCycle f) :
    ∃! s : { s : Cycle α // s.Nodup }, (s : Cycle α).formPerm s.prop = f := by
  obtain ⟨s, ⟨hs, rfl⟩, hs'⟩ := hf.existsUnique_cycle
  

Proof state:
case intro.intro.intro
α : Type u_1
inst✝¹ : Finite α
inst✝ : DecidableEq α
s : Cycle α
hs : Cycle.Nodup s
hf : IsCycle (Cycle.formPerm s hs)
hs' : ∀ (y : Cycle α), (fun s_1 => ∃ (h : Cycle.Nodup s_1), Cycle.formPerm s_1 h = Cycle.formPerm s hs) y → y = s
⊢ ∃! s_1, Cycle.formPerm ↑s_1 (_ : Cycle.Nodup ↑s_1) = Cycle.formPerm s hs

Next tactic:
refine' ⟨⟨s, hs⟩, rfl, _⟩
theorem IsCycle.existsUnique_cycle_subtype {f : Perm α} (hf : IsCycle f) :
    ∃! s : { s : Cycle α // s.Nodup }, (s : Cycle α).formPerm s.prop = f := by
  obtain ⟨s, ⟨hs, rfl⟩, hs'⟩ := hf.existsUnique_cycle
  refine' ⟨⟨s, hs⟩, rfl, _⟩
  

Proof state:
case intro.intro.intro
α : Type u_1
inst✝¹ : Finite α
inst✝ : DecidableEq α
s : Cycle α
hs : Cycle.Nodup s
hf : IsCycle (Cycle.formPerm s hs)
hs' : ∀ (y : Cycle α), (fun s_1 => ∃ (h : Cycle.Nodup s_1), Cycle.formPerm s_1 h = Cycle.formPerm s hs) y → y = s
⊢ ∀ (y : { s // Cycle.Nodup s }),
    (fun s_1 => Cycle.formPerm ↑s_1 (_ : Cycle.Nodup ↑s_1) = Cycle.formPerm s hs) y → y = { val := s, property := hs }

Next tactic:
rintro ⟨t, ht⟩ ht'
theorem IsCycle.existsUnique_cycle_subtype {f : Perm α} (hf : IsCycle f) :
    ∃! s : { s : Cycle α // s.Nodup }, (s : Cycle α).formPerm s.prop = f := by
  obtain ⟨s, ⟨hs, rfl⟩, hs'⟩ := hf.existsUnique_cycle
  refine' ⟨⟨s, hs⟩, rfl, _⟩
  rintro ⟨t, ht⟩ ht'
  

Proof state:
case intro.intro.intro.mk
α : Type u_1
inst✝¹ : Finite α
inst✝ : DecidableEq α
s : Cycle α
hs : Cycle.Nodup s
hf : IsCycle (Cycle.formPerm s hs)
hs' : ∀ (y : Cycle α), (fun s_1 => ∃ (h : Cycle.Nodup s_1), Cycle.formPerm s_1 h = Cycle.formPerm s hs) y → y = s
t : Cycle α
ht : Cycle.Nodup t
ht' : Cycle.formPerm ↑{ val := t, property := ht } (_ : Cycle.Nodup ↑{ val := t, property := ht }) = Cycle.formPerm s hs
⊢ { val := t, property := ht } = { val := s, property := hs }

Next tactic:
simpa using hs' _ ⟨ht, ht'⟩
theorem IsCycle.existsUnique_cycle_nontrivial_subtype {f : Perm α} (hf : IsCycle f) :
    ∃! s : { s : Cycle α // s.Nodup ∧ s.Nontrivial }, (s : Cycle α).formPerm s.prop.left = f := by
  

Proof state:
α : Type u_1
inst✝¹ : Finite α
inst✝ : DecidableEq α
f : Perm α
hf : IsCycle f
⊢ ∃! s, Cycle.formPerm ↑s (_ : Cycle.Nodup ↑s) = f

Next tactic:
obtain ⟨⟨s, hn⟩, hs, hs'⟩ := hf.existsUnique_cycle_subtype
theorem IsCycle.existsUnique_cycle_nontrivial_subtype {f : Perm α} (hf : IsCycle f) :
    ∃! s : { s : Cycle α // s.Nodup ∧ s.Nontrivial }, (s : Cycle α).formPerm s.prop.left = f := by
  obtain ⟨⟨s, hn⟩, hs, hs'⟩ := hf.existsUnique_cycle_subtype
  

Proof state:
case intro.mk.intro
α : Type u_1
inst✝¹ : Finite α
inst✝ : DecidableEq α
f : Perm α
hf : IsCycle f
s : Cycle α
hn : Cycle.Nodup s
hs : Cycle.formPerm ↑{ val := s, property := hn } (_ : Cycle.Nodup ↑{ val := s, property := hn }) = f
hs' :
  ∀ (y : { s // Cycle.Nodup s }),
    (fun s => Cycle.formPerm ↑s (_ : Cycle.Nodup ↑s) = f) y → y = { val := s, property := hn }
⊢ ∃! s, Cycle.formPerm ↑s (_ : Cycle.Nodup ↑s) = f

Next tactic:
refine' ⟨⟨s, hn, _⟩, _, _⟩
theorem IsCycle.existsUnique_cycle_nontrivial_subtype {f : Perm α} (hf : IsCycle f) :
    ∃! s : { s : Cycle α // s.Nodup ∧ s.Nontrivial }, (s : Cycle α).formPerm s.prop.left = f := by
  obtain ⟨⟨s, hn⟩, hs, hs'⟩ := hf.existsUnique_cycle_subtype
  refine' ⟨⟨s, hn, _⟩, _, _⟩
  · 

Proof state:
case intro.mk.intro.refine'_1
α : Type u_1
inst✝¹ : Finite α
inst✝ : DecidableEq α
f : Perm α
hf : IsCycle f
s : Cycle α
hn : Cycle.Nodup s
hs : Cycle.formPerm ↑{ val := s, property := hn } (_ : Cycle.Nodup ↑{ val := s, property := hn }) = f
hs' :
  ∀ (y : { s // Cycle.Nodup s }),
    (fun s => Cycle.formPerm ↑s (_ : Cycle.Nodup ↑s) = f) y → y = { val := s, property := hn }
⊢ Cycle.Nontrivial s

Next tactic:
rw [hn.nontrivial_iff]
theorem IsCycle.existsUnique_cycle_nontrivial_subtype {f : Perm α} (hf : IsCycle f) :
    ∃! s : { s : Cycle α // s.Nodup ∧ s.Nontrivial }, (s : Cycle α).formPerm s.prop.left = f := by
  obtain ⟨⟨s, hn⟩, hs, hs'⟩ := hf.existsUnique_cycle_subtype
  refine' ⟨⟨s, hn, _⟩, _, _⟩
  · rw [hn.nontrivial_iff]
    

Proof state:
case intro.mk.intro.refine'_1
α : Type u_1
inst✝¹ : Finite α
inst✝ : DecidableEq α
f : Perm α
hf : IsCycle f
s : Cycle α
hn : Cycle.Nodup s
hs : Cycle.formPerm ↑{ val := s, property := hn } (_ : Cycle.Nodup ↑{ val := s, property := hn }) = f
hs' :
  ∀ (y : { s // Cycle.Nodup s }),
    (fun s => Cycle.formPerm ↑s (_ : Cycle.Nodup ↑s) = f) y → y = { val := s, property := hn }
⊢ ¬Cycle.Subsingleton s

Next tactic:
subst f
theorem IsCycle.existsUnique_cycle_nontrivial_subtype {f : Perm α} (hf : IsCycle f) :
    ∃! s : { s : Cycle α // s.Nodup ∧ s.Nontrivial }, (s : Cycle α).formPerm s.prop.left = f := by
  obtain ⟨⟨s, hn⟩, hs, hs'⟩ := hf.existsUnique_cycle_subtype
  refine' ⟨⟨s, hn, _⟩, _, _⟩
  · rw [hn.nontrivial_iff]
    subst f
    

Proof state:
case intro.mk.intro.refine'_1
α : Type u_1
inst✝¹ : Finite α
inst✝ : DecidableEq α
s : Cycle α
hn : Cycle.Nodup s
hf : IsCycle (Cycle.formPerm ↑{ val := s, property := hn } (_ : Cycle.Nodup ↑{ val := s, property := hn }))
hs' :
  ∀ (y : { s // Cycle.Nodup s }),
    (fun s_1 =>
          Cycle.formPerm ↑s_1 (_ : Cycle.Nodup ↑s_1) =
            Cycle.formPerm ↑{ val := s, property := hn } (_ : Cycle.Nodup ↑{ val := s, property := hn }))
        y →
      y = { val := s, property := hn }
⊢ ¬Cycle.Subsingleton s

Next tactic:
intro H
theorem IsCycle.existsUnique_cycle_nontrivial_subtype {f : Perm α} (hf : IsCycle f) :
    ∃! s : { s : Cycle α // s.Nodup ∧ s.Nontrivial }, (s : Cycle α).formPerm s.prop.left = f := by
  obtain ⟨⟨s, hn⟩, hs, hs'⟩ := hf.existsUnique_cycle_subtype
  refine' ⟨⟨s, hn, _⟩, _, _⟩
  · rw [hn.nontrivial_iff]
    subst f
    intro H
    

Proof state:
case intro.mk.intro.refine'_1
α : Type u_1
inst✝¹ : Finite α
inst✝ : DecidableEq α
s : Cycle α
hn : Cycle.Nodup s
hf : IsCycle (Cycle.formPerm ↑{ val := s, property := hn } (_ : Cycle.Nodup ↑{ val := s, property := hn }))
hs' :
  ∀ (y : { s // Cycle.Nodup s }),
    (fun s_1 =>
          Cycle.formPerm ↑s_1 (_ : Cycle.Nodup ↑s_1) =
            Cycle.formPerm ↑{ val := s, property := hn } (_ : Cycle.Nodup ↑{ val := s, property := hn }))
        y →
      y = { val := s, property := hn }
H : Cycle.Subsingleton s
⊢ False

Next tactic:
refine' hf.ne_one _
theorem IsCycle.existsUnique_cycle_nontrivial_subtype {f : Perm α} (hf : IsCycle f) :
    ∃! s : { s : Cycle α // s.Nodup ∧ s.Nontrivial }, (s : Cycle α).formPerm s.prop.left = f := by
  obtain ⟨⟨s, hn⟩, hs, hs'⟩ := hf.existsUnique_cycle_subtype
  refine' ⟨⟨s, hn, _⟩, _, _⟩
  · rw [hn.nontrivial_iff]
    subst f
    intro H
    refine' hf.ne_one _
    

Proof state:
case intro.mk.intro.refine'_1
α : Type u_1
inst✝¹ : Finite α
inst✝ : DecidableEq α
s : Cycle α
hn : Cycle.Nodup s
hf : IsCycle (Cycle.formPerm ↑{ val := s, property := hn } (_ : Cycle.Nodup ↑{ val := s, property := hn }))
hs' :
  ∀ (y : { s // Cycle.Nodup s }),
    (fun s_1 =>
          Cycle.formPerm ↑s_1 (_ : Cycle.Nodup ↑s_1) =
            Cycle.formPerm ↑{ val := s, property := hn } (_ : Cycle.Nodup ↑{ val := s, property := hn }))
        y →
      y = { val := s, property := hn }
H : Cycle.Subsingleton s
⊢ Cycle.formPerm ↑{ val := s, property := hn } (_ : Cycle.Nodup ↑{ val := s, property := hn }) = 1

Next tactic:
simpa using Cycle.formPerm_subsingleton _ H
theorem IsCycle.existsUnique_cycle_nontrivial_subtype {f : Perm α} (hf : IsCycle f) :
    ∃! s : { s : Cycle α // s.Nodup ∧ s.Nontrivial }, (s : Cycle α).formPerm s.prop.left = f := by
  obtain ⟨⟨s, hn⟩, hs, hs'⟩ := hf.existsUnique_cycle_subtype
  refine' ⟨⟨s, hn, _⟩, _, _⟩
  · rw [hn.nontrivial_iff]
    subst f
    intro H
    refine' hf.ne_one _
    simpa using Cycle.formPerm_subsingleton _ H
  · 

Proof state:
case intro.mk.intro.refine'_2
α : Type u_1
inst✝¹ : Finite α
inst✝ : DecidableEq α
f : Perm α
hf : IsCycle f
s : Cycle α
hn : Cycle.Nodup s
hs : Cycle.formPerm ↑{ val := s, property := hn } (_ : Cycle.Nodup ↑{ val := s, property := hn }) = f
hs' :
  ∀ (y : { s // Cycle.Nodup s }),
    (fun s => Cycle.formPerm ↑s (_ : Cycle.Nodup ↑s) = f) y → y = { val := s, property := hn }
⊢ (fun s => Cycle.formPerm ↑s (_ : Cycle.Nodup ↑s) = f)
    { val := s, property := (_ : Cycle.Nodup s ∧ Cycle.Nontrivial s) }

Next tactic:
simpa using hs
theorem IsCycle.existsUnique_cycle_nontrivial_subtype {f : Perm α} (hf : IsCycle f) :
    ∃! s : { s : Cycle α // s.Nodup ∧ s.Nontrivial }, (s : Cycle α).formPerm s.prop.left = f := by
  obtain ⟨⟨s, hn⟩, hs, hs'⟩ := hf.existsUnique_cycle_subtype
  refine' ⟨⟨s, hn, _⟩, _, _⟩
  · rw [hn.nontrivial_iff]
    subst f
    intro H
    refine' hf.ne_one _
    simpa using Cycle.formPerm_subsingleton _ H
  · simpa using hs
  · 

Proof state:
case intro.mk.intro.refine'_3
α : Type u_1
inst✝¹ : Finite α
inst✝ : DecidableEq α
f : Perm α
hf : IsCycle f
s : Cycle α
hn : Cycle.Nodup s
hs : Cycle.formPerm ↑{ val := s, property := hn } (_ : Cycle.Nodup ↑{ val := s, property := hn }) = f
hs' :
  ∀ (y : { s // Cycle.Nodup s }),
    (fun s => Cycle.formPerm ↑s (_ : Cycle.Nodup ↑s) = f) y → y = { val := s, property := hn }
⊢ ∀ (y : { s // Cycle.Nodup s ∧ Cycle.Nontrivial s }),
    (fun s => Cycle.formPerm ↑s (_ : Cycle.Nodup ↑s) = f) y →
      y = { val := s, property := (_ : Cycle.Nodup s ∧ Cycle.Nontrivial s) }

Next tactic:
rintro ⟨t, ht, ht'⟩ ht''
theorem IsCycle.existsUnique_cycle_nontrivial_subtype {f : Perm α} (hf : IsCycle f) :
    ∃! s : { s : Cycle α // s.Nodup ∧ s.Nontrivial }, (s : Cycle α).formPerm s.prop.left = f := by
  obtain ⟨⟨s, hn⟩, hs, hs'⟩ := hf.existsUnique_cycle_subtype
  refine' ⟨⟨s, hn, _⟩, _, _⟩
  · rw [hn.nontrivial_iff]
    subst f
    intro H
    refine' hf.ne_one _
    simpa using Cycle.formPerm_subsingleton _ H
  · simpa using hs
  · rintro ⟨t, ht, ht'⟩ ht''
    

Proof state:
case intro.mk.intro.refine'_3.mk.intro
α : Type u_1
inst✝¹ : Finite α
inst✝ : DecidableEq α
f : Perm α
hf : IsCycle f
s : Cycle α
hn : Cycle.Nodup s
hs : Cycle.formPerm ↑{ val := s, property := hn } (_ : Cycle.Nodup ↑{ val := s, property := hn }) = f
hs' :
  ∀ (y : { s // Cycle.Nodup s }),
    (fun s => Cycle.formPerm ↑s (_ : Cycle.Nodup ↑s) = f) y → y = { val := s, property := hn }
t : Cycle α
ht : Cycle.Nodup t
ht' : Cycle.Nontrivial t
ht'' :
  Cycle.formPerm ↑{ val := t, property := (_ : Cycle.Nodup t ∧ Cycle.Nontrivial t) }
      (_ : Cycle.Nodup ↑{ val := t, property := (_ : Cycle.Nodup t ∧ Cycle.Nontrivial t) }) =
    f
⊢ { val := t, property := (_ : Cycle.Nodup t ∧ Cycle.Nontrivial t) } =
    { val := s, property := (_ : Cycle.Nodup s ∧ Cycle.Nontrivial s) }

Next tactic:
simpa using hs' ⟨t, ht⟩ ht''
/-- Any cyclic `f : Perm α` is isomorphic to the nontrivial `Cycle α`
that corresponds to repeated application of `f`.
The forward direction is implemented by finding this `Cycle α` using `Fintype.choose`.
-/
def isoCycle' : { f : Perm α // IsCycle f } ≃ { s : Cycle α // s.Nodup ∧ s.Nontrivial } :=
  let f : { s : Cycle α // s.Nodup ∧ s.Nontrivial } → { f : Perm α // IsCycle f } :=
    fun s => ⟨(s : Cycle α).formPerm s.prop.left, (s : Cycle α).isCycle_formPerm _ s.prop.right⟩
  { toFun := Fintype.bijInv (show Function.Bijective f by
      

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
f : { s // Cycle.Nodup s ∧ Cycle.Nontrivial s } → { f // IsCycle f } :=
  fun s =>
    { val := Cycle.formPerm ↑s (_ : Cycle.Nodup ↑s),
      property := (_ : IsCycle (Cycle.formPerm ↑s (_ : Cycle.Nodup ↑s))) }
⊢ Function.Bijective f

Next tactic:
rw [Function.bijective_iff_existsUnique]
/-- Any cyclic `f : Perm α` is isomorphic to the nontrivial `Cycle α`
that corresponds to repeated application of `f`.
The forward direction is implemented by finding this `Cycle α` using `Fintype.choose`.
-/
def isoCycle' : { f : Perm α // IsCycle f } ≃ { s : Cycle α // s.Nodup ∧ s.Nontrivial } :=
  let f : { s : Cycle α // s.Nodup ∧ s.Nontrivial } → { f : Perm α // IsCycle f } :=
    fun s => ⟨(s : Cycle α).formPerm s.prop.left, (s : Cycle α).isCycle_formPerm _ s.prop.right⟩
  { toFun := Fintype.bijInv (show Function.Bijective f by
      rw [Function.bijective_iff_existsUnique]
      

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
f : { s // Cycle.Nodup s ∧ Cycle.Nontrivial s } → { f // IsCycle f } :=
  fun s =>
    { val := Cycle.formPerm ↑s (_ : Cycle.Nodup ↑s),
      property := (_ : IsCycle (Cycle.formPerm ↑s (_ : Cycle.Nodup ↑s))) }
⊢ ∀ (b : { f // IsCycle f }), ∃! a, f a = b

Next tactic:
rintro ⟨f, hf⟩
/-- Any cyclic `f : Perm α` is isomorphic to the nontrivial `Cycle α`
that corresponds to repeated application of `f`.
The forward direction is implemented by finding this `Cycle α` using `Fintype.choose`.
-/
def isoCycle' : { f : Perm α // IsCycle f } ≃ { s : Cycle α // s.Nodup ∧ s.Nontrivial } :=
  let f : { s : Cycle α // s.Nodup ∧ s.Nontrivial } → { f : Perm α // IsCycle f } :=
    fun s => ⟨(s : Cycle α).formPerm s.prop.left, (s : Cycle α).isCycle_formPerm _ s.prop.right⟩
  { toFun := Fintype.bijInv (show Function.Bijective f by
      rw [Function.bijective_iff_existsUnique]
      rintro ⟨f, hf⟩
      

Proof state:
case mk
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
f✝ : { s // Cycle.Nodup s ∧ Cycle.Nontrivial s } → { f // IsCycle f } :=
  fun s =>
    { val := Cycle.formPerm ↑s (_ : Cycle.Nodup ↑s),
      property := (_ : IsCycle (Cycle.formPerm ↑s (_ : Cycle.Nodup ↑s))) }
f : Perm α
hf : IsCycle f
⊢ ∃! a, f✝ a = { val := f, property := hf }

Next tactic:
simp only [Subtype.ext_iff]
/-- Any cyclic `f : Perm α` is isomorphic to the nontrivial `Cycle α`
that corresponds to repeated application of `f`.
The forward direction is implemented by finding this `Cycle α` using `Fintype.choose`.
-/
def isoCycle' : { f : Perm α // IsCycle f } ≃ { s : Cycle α // s.Nodup ∧ s.Nontrivial } :=
  let f : { s : Cycle α // s.Nodup ∧ s.Nontrivial } → { f : Perm α // IsCycle f } :=
    fun s => ⟨(s : Cycle α).formPerm s.prop.left, (s : Cycle α).isCycle_formPerm _ s.prop.right⟩
  { toFun := Fintype.bijInv (show Function.Bijective f by
      rw [Function.bijective_iff_existsUnique]
      rintro ⟨f, hf⟩
      simp only [Subtype.ext_iff]
      

Proof state:
case mk
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
f✝ : { s // Cycle.Nodup s ∧ Cycle.Nontrivial s } → { f // IsCycle f } :=
  fun s =>
    { val := Cycle.formPerm ↑s (_ : Cycle.Nodup ↑s),
      property := (_ : IsCycle (Cycle.formPerm ↑s (_ : Cycle.Nodup ↑s))) }
f : Perm α
hf : IsCycle f
⊢ ∃! a, Cycle.formPerm ↑a (_ : Cycle.Nodup ↑a) = f

Next tactic:
exact hf.existsUnique_cycle_nontrivial_subtype
example : bernsteinPolynomial ℤ 3 2 = 3 * X ^ 2 - 3 * X ^ 3 := by
  

Proof state:
R : Type u_1
inst✝ : CommRing R
⊢ bernsteinPolynomial ℤ 3 2 = 3 * X ^ 2 - 3 * X ^ 3

Next tactic:
norm_num [bernsteinPolynomial, choose]
example : bernsteinPolynomial ℤ 3 2 = 3 * X ^ 2 - 3 * X ^ 3 := by
  norm_num [bernsteinPolynomial, choose]
  

Proof state:
R : Type u_1
inst✝ : CommRing R
⊢ 3 * X ^ 2 * (1 - X) = 3 * X ^ 2 - 3 * X ^ 3

Next tactic:
ring
theorem eq_zero_of_lt {n ν : ℕ} (h : n < ν) : bernsteinPolynomial R n ν = 0 := by
  

Proof state:
R : Type u_1
inst✝ : CommRing R
n ν : ℕ
h : n < ν
⊢ bernsteinPolynomial R n ν = 0

Next tactic:
simp [bernsteinPolynomial, Nat.choose_eq_zero_of_lt h]
@[simp]
theorem map (f : R →+* S) (n ν : ℕ) :
    (bernsteinPolynomial R n ν).map f = bernsteinPolynomial S n ν := by 

Proof state:
R : Type u_1
inst✝¹ : CommRing R
S : Type u_2
inst✝ : CommRing S
f : R →+* S
n ν : ℕ
⊢ Polynomial.map f (bernsteinPolynomial R n ν) = bernsteinPolynomial S n ν

Next tactic:
simp [bernsteinPolynomial]
theorem flip (n ν : ℕ) (h : ν ≤ n) :
    (bernsteinPolynomial R n ν).comp (1 - X) = bernsteinPolynomial R n (n - ν) := by
  

Proof state:
R : Type u_1
inst✝ : CommRing R
n ν : ℕ
h : ν ≤ n
⊢ Polynomial.comp (bernsteinPolynomial R n ν) (1 - X) = bernsteinPolynomial R n (n - ν)

Next tactic:
simp [bernsteinPolynomial, h, tsub_tsub_assoc, mul_right_comm]
theorem flip' (n ν : ℕ) (h : ν ≤ n) :
    bernsteinPolynomial R n ν = (bernsteinPolynomial R n (n - ν)).comp (1 - X) := by
  

Proof state:
R : Type u_1
inst✝ : CommRing R
n ν : ℕ
h : ν ≤ n
⊢ bernsteinPolynomial R n ν = Polynomial.comp (bernsteinPolynomial R n (n - ν)) (1 - X)

Next tactic:
simp [← flip _ _ _ h, Polynomial.comp_assoc]
theorem eval_at_0 (n ν : ℕ) : (bernsteinPolynomial R n ν).eval 0 = if ν = 0 then 1 else 0 := by
  

Proof state:
R : Type u_1
inst✝ : CommRing R
n ν : ℕ
⊢ Polynomial.eval 0 (bernsteinPolynomial R n ν) = if ν = 0 then 1 else 0

Next tactic:
rw [bernsteinPolynomial]
theorem eval_at_0 (n ν : ℕ) : (bernsteinPolynomial R n ν).eval 0 = if ν = 0 then 1 else 0 := by
  rw [bernsteinPolynomial]
  

Proof state:
R : Type u_1
inst✝ : CommRing R
n ν : ℕ
⊢ Polynomial.eval 0 (↑(choose n ν) * X ^ ν * (1 - X) ^ (n - ν)) = if ν = 0 then 1 else 0

Next tactic:
split_ifs with h
theorem eval_at_0 (n ν : ℕ) : (bernsteinPolynomial R n ν).eval 0 = if ν = 0 then 1 else 0 := by
  rw [bernsteinPolynomial]
  split_ifs with h
  · 

Proof state:
case pos
R : Type u_1
inst✝ : CommRing R
n ν : ℕ
h : ν = 0
⊢ Polynomial.eval 0 (↑(choose n ν) * X ^ ν * (1 - X) ^ (n - ν)) = 1

Next tactic:
subst h
theorem eval_at_0 (n ν : ℕ) : (bernsteinPolynomial R n ν).eval 0 = if ν = 0 then 1 else 0 := by
  rw [bernsteinPolynomial]
  split_ifs with h
  · subst h; 

Proof state:
case pos
R : Type u_1
inst✝ : CommRing R
n : ℕ
⊢ Polynomial.eval 0 (↑(choose n 0) * X ^ 0 * (1 - X) ^ (n - 0)) = 1

Next tactic:
simp