l3lab/ntp-mathlib huggingface dataset:
/-- If `t : Cocone F` is a colimit cocone, then `t.op : Cone F.op` is a limit cone.
-/
def IsColimit.op {t : Cocone F} (P : IsColimit t) : IsLimit t.op where
  lift s := (P.desc s.unop).op
  fac s j := congrArg Quiver.Hom.op (P.fac s.unop (unop j))
  uniq s m w := by
    dsimp
    rw [← P.uniq s.unop m.unop]
    · rfl
    · dsimp
      intro j
      rw [← w]
      

Proof state:
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u
inst✝ : Category.{v, u} C
F : J ⥤ C
t : Cocone F
P : IsColimit t
s : Cone F.op
m : s.pt ⟶ (Cocone.op t).pt
w : ∀ (j : Jᵒᵖ), m ≫ (Cocone.op t).π.app j = s.π.app j
j : J
⊢ t.ι.app j ≫ m.unop = (m ≫ (Cocone.op t).π.app (Opposite.op j)).unop

Next tactic:
rfl
/-- If `t : Cone F.op` is a limit cone, then `t.unop : Cocone F` is a colimit cocone.
-/
def IsLimit.unop {t : Cone F.op} (P : IsLimit t) : IsColimit t.unop where
  desc s := (P.lift s.op).unop
  fac s j := congrArg Quiver.Hom.unop (P.fac s.op (Opposite.op j))
  -- Porting note: thinks `op j` is `IsLimit.op j`
  uniq s m w := by
    

Proof state:
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u
inst✝ : Category.{v, u} C
F : J ⥤ C
t : Cone F.op
P : IsLimit t
s : Cocone F
m : (Cone.unop t).pt ⟶ s.pt
w : ∀ (j : J), (Cone.unop t).ι.app j ≫ m = s.ι.app j
⊢ m = (fun s => (lift P (Cocone.op s)).unop) s

Next tactic:
dsimp
/-- If `t : Cone F.op` is a limit cone, then `t.unop : Cocone F` is a colimit cocone.
-/
def IsLimit.unop {t : Cone F.op} (P : IsLimit t) : IsColimit t.unop where
  desc s := (P.lift s.op).unop
  fac s j := congrArg Quiver.Hom.unop (P.fac s.op (Opposite.op j))
  -- Porting note: thinks `op j` is `IsLimit.op j`
  uniq s m w := by
    dsimp
    

Proof state:
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u
inst✝ : Category.{v, u} C
F : J ⥤ C
t : Cone F.op
P : IsLimit t
s : Cocone F
m : (Cone.unop t).pt ⟶ s.pt
w : ∀ (j : J), (Cone.unop t).ι.app j ≫ m = s.ι.app j
⊢ m = (lift P (Cocone.op s)).unop

Next tactic:
rw [← P.uniq s.op m.op]
/-- If `t : Cone F.op` is a limit cone, then `t.unop : Cocone F` is a colimit cocone.
-/
def IsLimit.unop {t : Cone F.op} (P : IsLimit t) : IsColimit t.unop where
  desc s := (P.lift s.op).unop
  fac s j := congrArg Quiver.Hom.unop (P.fac s.op (Opposite.op j))
  -- Porting note: thinks `op j` is `IsLimit.op j`
  uniq s m w := by
    dsimp
    rw [← P.uniq s.op m.op]
    · 

Proof state:
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u
inst✝ : Category.{v, u} C
F : J ⥤ C
t : Cone F.op
P : IsLimit t
s : Cocone F
m : (Cone.unop t).pt ⟶ s.pt
w : ∀ (j : J), (Cone.unop t).ι.app j ≫ m = s.ι.app j
⊢ m = m.op.unop

Next tactic:
rfl
/-- If `t : Cone F.op` is a limit cone, then `t.unop : Cocone F` is a colimit cocone.
-/
def IsLimit.unop {t : Cone F.op} (P : IsLimit t) : IsColimit t.unop where
  desc s := (P.lift s.op).unop
  fac s j := congrArg Quiver.Hom.unop (P.fac s.op (Opposite.op j))
  -- Porting note: thinks `op j` is `IsLimit.op j`
  uniq s m w := by
    dsimp
    rw [← P.uniq s.op m.op]
    · rfl
    · 

Proof state:
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u
inst✝ : Category.{v, u} C
F : J ⥤ C
t : Cone F.op
P : IsLimit t
s : Cocone F
m : (Cone.unop t).pt ⟶ s.pt
w : ∀ (j : J), (Cone.unop t).ι.app j ≫ m = s.ι.app j
⊢ ∀ (j : Jᵒᵖ), m.op ≫ t.π.app j = (Cocone.op s).π.app j

Next tactic:
dsimp
/-- If `t : Cone F.op` is a limit cone, then `t.unop : Cocone F` is a colimit cocone.
-/
def IsLimit.unop {t : Cone F.op} (P : IsLimit t) : IsColimit t.unop where
  desc s := (P.lift s.op).unop
  fac s j := congrArg Quiver.Hom.unop (P.fac s.op (Opposite.op j))
  -- Porting note: thinks `op j` is `IsLimit.op j`
  uniq s m w := by
    dsimp
    rw [← P.uniq s.op m.op]
    · rfl
    · dsimp
      

Proof state:
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u
inst✝ : Category.{v, u} C
F : J ⥤ C
t : Cone F.op
P : IsLimit t
s : Cocone F
m : (Cone.unop t).pt ⟶ s.pt
w : ∀ (j : J), (Cone.unop t).ι.app j ≫ m = s.ι.app j
⊢ ∀ (j : Jᵒᵖ), m.op ≫ t.π.app j = (s.ι.app j.unop).op

Next tactic:
intro j
/-- If `t : Cone F.op` is a limit cone, then `t.unop : Cocone F` is a colimit cocone.
-/
def IsLimit.unop {t : Cone F.op} (P : IsLimit t) : IsColimit t.unop where
  desc s := (P.lift s.op).unop
  fac s j := congrArg Quiver.Hom.unop (P.fac s.op (Opposite.op j))
  -- Porting note: thinks `op j` is `IsLimit.op j`
  uniq s m w := by
    dsimp
    rw [← P.uniq s.op m.op]
    · rfl
    · dsimp
      intro j
      

Proof state:
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u
inst✝ : Category.{v, u} C
F : J ⥤ C
t : Cone F.op
P : IsLimit t
s : Cocone F
m : (Cone.unop t).pt ⟶ s.pt
w : ∀ (j : J), (Cone.unop t).ι.app j ≫ m = s.ι.app j
j : Jᵒᵖ
⊢ m.op ≫ t.π.app j = (s.ι.app j.unop).op

Next tactic:
rw [← w]
/-- If `t : Cone F.op` is a limit cone, then `t.unop : Cocone F` is a colimit cocone.
-/
def IsLimit.unop {t : Cone F.op} (P : IsLimit t) : IsColimit t.unop where
  desc s := (P.lift s.op).unop
  fac s j := congrArg Quiver.Hom.unop (P.fac s.op (Opposite.op j))
  -- Porting note: thinks `op j` is `IsLimit.op j`
  uniq s m w := by
    dsimp
    rw [← P.uniq s.op m.op]
    · rfl
    · dsimp
      intro j
      rw [← w]
      

Proof state:
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u
inst✝ : Category.{v, u} C
F : J ⥤ C
t : Cone F.op
P : IsLimit t
s : Cocone F
m : (Cone.unop t).pt ⟶ s.pt
w : ∀ (j : J), (Cone.unop t).ι.app j ≫ m = s.ι.app j
j : Jᵒᵖ
⊢ m.op ≫ t.π.app j = ((Cone.unop t).ι.app j.unop ≫ m).op

Next tactic:
rfl
/-- If `t : Cocone F.op` is a colimit cocone, then `t.unop : Cone F.` is a limit cone.
-/
def IsColimit.unop {t : Cocone F.op} (P : IsColimit t) : IsLimit t.unop where
  lift s := (P.desc s.op).unop
  fac s j := congrArg Quiver.Hom.unop (P.fac s.op (Opposite.op j))
  -- Porting note: thinks `op j` is `IsLimit.op j`
  uniq s m w := by
    

Proof state:
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u
inst✝ : Category.{v, u} C
F : J ⥤ C
t : Cocone F.op
P : IsColimit t
s : Cone F
m : s.pt ⟶ (Cocone.unop t).pt
w : ∀ (j : J), m ≫ (Cocone.unop t).π.app j = s.π.app j
⊢ m = (fun s => (desc P (Cone.op s)).unop) s

Next tactic:
dsimp
/-- If `t : Cocone F.op` is a colimit cocone, then `t.unop : Cone F.` is a limit cone.
-/
def IsColimit.unop {t : Cocone F.op} (P : IsColimit t) : IsLimit t.unop where
  lift s := (P.desc s.op).unop
  fac s j := congrArg Quiver.Hom.unop (P.fac s.op (Opposite.op j))
  -- Porting note: thinks `op j` is `IsLimit.op j`
  uniq s m w := by
    dsimp
    

Proof state:
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u
inst✝ : Category.{v, u} C
F : J ⥤ C
t : Cocone F.op
P : IsColimit t
s : Cone F
m : s.pt ⟶ (Cocone.unop t).pt
w : ∀ (j : J), m ≫ (Cocone.unop t).π.app j = s.π.app j
⊢ m = (desc P (Cone.op s)).unop

Next tactic:
rw [← P.uniq s.op m.op]
/-- If `t : Cocone F.op` is a colimit cocone, then `t.unop : Cone F.` is a limit cone.
-/
def IsColimit.unop {t : Cocone F.op} (P : IsColimit t) : IsLimit t.unop where
  lift s := (P.desc s.op).unop
  fac s j := congrArg Quiver.Hom.unop (P.fac s.op (Opposite.op j))
  -- Porting note: thinks `op j` is `IsLimit.op j`
  uniq s m w := by
    dsimp
    rw [← P.uniq s.op m.op]
    · 

Proof state:
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u
inst✝ : Category.{v, u} C
F : J ⥤ C
t : Cocone F.op
P : IsColimit t
s : Cone F
m : s.pt ⟶ (Cocone.unop t).pt
w : ∀ (j : J), m ≫ (Cocone.unop t).π.app j = s.π.app j
⊢ m = m.op.unop

Next tactic:
rfl
/-- If `t : Cocone F.op` is a colimit cocone, then `t.unop : Cone F.` is a limit cone.
-/
def IsColimit.unop {t : Cocone F.op} (P : IsColimit t) : IsLimit t.unop where
  lift s := (P.desc s.op).unop
  fac s j := congrArg Quiver.Hom.unop (P.fac s.op (Opposite.op j))
  -- Porting note: thinks `op j` is `IsLimit.op j`
  uniq s m w := by
    dsimp
    rw [← P.uniq s.op m.op]
    · rfl
    · 

Proof state:
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u
inst✝ : Category.{v, u} C
F : J ⥤ C
t : Cocone F.op
P : IsColimit t
s : Cone F
m : s.pt ⟶ (Cocone.unop t).pt
w : ∀ (j : J), m ≫ (Cocone.unop t).π.app j = s.π.app j
⊢ ∀ (j : Jᵒᵖ), t.ι.app j ≫ m.op = (Cone.op s).ι.app j

Next tactic:
dsimp
/-- If `t : Cocone F.op` is a colimit cocone, then `t.unop : Cone F.` is a limit cone.
-/
def IsColimit.unop {t : Cocone F.op} (P : IsColimit t) : IsLimit t.unop where
  lift s := (P.desc s.op).unop
  fac s j := congrArg Quiver.Hom.unop (P.fac s.op (Opposite.op j))
  -- Porting note: thinks `op j` is `IsLimit.op j`
  uniq s m w := by
    dsimp
    rw [← P.uniq s.op m.op]
    · rfl
    · dsimp
      

Proof state:
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u
inst✝ : Category.{v, u} C
F : J ⥤ C
t : Cocone F.op
P : IsColimit t
s : Cone F
m : s.pt ⟶ (Cocone.unop t).pt
w : ∀ (j : J), m ≫ (Cocone.unop t).π.app j = s.π.app j
⊢ ∀ (j : Jᵒᵖ), t.ι.app j ≫ m.op = (s.π.app j.unop).op

Next tactic:
intro j
/-- If `t : Cocone F.op` is a colimit cocone, then `t.unop : Cone F.` is a limit cone.
-/
def IsColimit.unop {t : Cocone F.op} (P : IsColimit t) : IsLimit t.unop where
  lift s := (P.desc s.op).unop
  fac s j := congrArg Quiver.Hom.unop (P.fac s.op (Opposite.op j))
  -- Porting note: thinks `op j` is `IsLimit.op j`
  uniq s m w := by
    dsimp
    rw [← P.uniq s.op m.op]
    · rfl
    · dsimp
      intro j
      

Proof state:
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u
inst✝ : Category.{v, u} C
F : J ⥤ C
t : Cocone F.op
P : IsColimit t
s : Cone F
m : s.pt ⟶ (Cocone.unop t).pt
w : ∀ (j : J), m ≫ (Cocone.unop t).π.app j = s.π.app j
j : Jᵒᵖ
⊢ t.ι.app j ≫ m.op = (s.π.app j.unop).op

Next tactic:
rw [← w]
/-- If `t : Cocone F.op` is a colimit cocone, then `t.unop : Cone F.` is a limit cone.
-/
def IsColimit.unop {t : Cocone F.op} (P : IsColimit t) : IsLimit t.unop where
  lift s := (P.desc s.op).unop
  fac s j := congrArg Quiver.Hom.unop (P.fac s.op (Opposite.op j))
  -- Porting note: thinks `op j` is `IsLimit.op j`
  uniq s m w := by
    dsimp
    rw [← P.uniq s.op m.op]
    · rfl
    · dsimp
      intro j
      rw [← w]
      

Proof state:
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u
inst✝ : Category.{v, u} C
F : J ⥤ C
t : Cocone F.op
P : IsColimit t
s : Cone F
m : s.pt ⟶ (Cocone.unop t).pt
w : ∀ (j : J), m ≫ (Cocone.unop t).π.app j = s.π.app j
j : Jᵒᵖ
⊢ t.ι.app j ≫ m.op = (m ≫ (Cocone.unop t).π.app j.unop).op

Next tactic:
rfl
theorem measurable_of_re_im (hre : Measurable fun x => IsROrC.re (f x))
    (him : Measurable fun x => IsROrC.im (f x)) : Measurable f := by
  

Proof state:
α : Type u_1
𝕜 : Type u_2
inst✝¹ : IsROrC 𝕜
inst✝ : MeasurableSpace α
f : α → 𝕜
μ : MeasureTheory.Measure α
hre : Measurable fun x => IsROrC.re (f x)
him : Measurable fun x => IsROrC.im (f x)
⊢ Measurable f

Next tactic:
convert Measurable.add (M := 𝕜) (IsROrC.measurable_ofReal.comp hre)
      ((IsROrC.measurable_ofReal.comp him).mul_const IsROrC.I)
theorem measurable_of_re_im (hre : Measurable fun x => IsROrC.re (f x))
    (him : Measurable fun x => IsROrC.im (f x)) : Measurable f := by
  convert Measurable.add (M := 𝕜) (IsROrC.measurable_ofReal.comp hre)
      ((IsROrC.measurable_ofReal.comp him).mul_const IsROrC.I)
  

Proof state:
case h.e'_5.h
α : Type u_1
𝕜 : Type u_2
inst✝¹ : IsROrC 𝕜
inst✝ : MeasurableSpace α
f : α → 𝕜
μ : MeasureTheory.Measure α
hre : Measurable fun x => IsROrC.re (f x)
him : Measurable fun x => IsROrC.im (f x)
x✝ : α
⊢ f x✝ = (IsROrC.ofReal ∘ fun x => IsROrC.re (f x)) x✝ + (IsROrC.ofReal ∘ fun x => IsROrC.im (f x)) x✝ * IsROrC.I

Next tactic:
exact (IsROrC.re_add_im _).symm
theorem aemeasurable_of_re_im (hre : AEMeasurable (fun x => IsROrC.re (f x)) μ)
    (him : AEMeasurable (fun x => IsROrC.im (f x)) μ) : AEMeasurable f μ := by
  

Proof state:
α : Type u_1
𝕜 : Type u_2
inst✝¹ : IsROrC 𝕜
inst✝ : MeasurableSpace α
f : α → 𝕜
μ : MeasureTheory.Measure α
hre : AEMeasurable fun x => IsROrC.re (f x)
him : AEMeasurable fun x => IsROrC.im (f x)
⊢ AEMeasurable f

Next tactic:
convert AEMeasurable.add (M := 𝕜) (IsROrC.measurable_ofReal.comp_aemeasurable hre)
      ((IsROrC.measurable_ofReal.comp_aemeasurable him).mul_const IsROrC.I)
theorem aemeasurable_of_re_im (hre : AEMeasurable (fun x => IsROrC.re (f x)) μ)
    (him : AEMeasurable (fun x => IsROrC.im (f x)) μ) : AEMeasurable f μ := by
  convert AEMeasurable.add (M := 𝕜) (IsROrC.measurable_ofReal.comp_aemeasurable hre)
      ((IsROrC.measurable_ofReal.comp_aemeasurable him).mul_const IsROrC.I)
  

Proof state:
case h.e'_5.h
α : Type u_1
𝕜 : Type u_2
inst✝¹ : IsROrC 𝕜
inst✝ : MeasurableSpace α
f : α → 𝕜
μ : MeasureTheory.Measure α
hre : AEMeasurable fun x => IsROrC.re (f x)
him : AEMeasurable fun x => IsROrC.im (f x)
x✝ : α
⊢ f x✝ = (IsROrC.ofReal ∘ fun x => IsROrC.re (f x)) x✝ + (IsROrC.ofReal ∘ fun x => IsROrC.im (f x)) x✝ * IsROrC.I

Next tactic:
exact (IsROrC.re_add_im _).symm
@[simp]
theorem toPrefunctor_symm_comp (f : SingleObj α ⥤q SingleObj β) (g : SingleObj β ⥤q SingleObj γ) :
    toPrefunctor.symm (f ⋙q g) = toPrefunctor.symm g ∘ toPrefunctor.symm f := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f : SingleObj α ⥤q SingleObj β
g : SingleObj β ⥤q SingleObj γ
⊢ toPrefunctor.symm (f ⋙q g) = toPrefunctor.symm g ∘ toPrefunctor.symm f

Next tactic:
simp only [Equiv.symm_apply_eq, toPrefunctor_comp, Equiv.apply_symm_apply]
theorem listToPath_pathToList {x : SingleObj α} (p : Path (star α) x) :
    listToPath (pathToList p) = p.cast rfl ext := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
x : SingleObj α
p : Path (star α) x
⊢ listToPath (pathToList p) = Path.cast (_ : star α = star α) (_ : x = star α) p

Next tactic:
induction' p with y z p a ih
theorem listToPath_pathToList {x : SingleObj α} (p : Path (star α) x) :
    listToPath (pathToList p) = p.cast rfl ext := by
  induction' p with y z p a ih
  · 

Proof state:
case nil
α : Type u_1
β : Type u_2
γ : Type u_3
x : SingleObj α
⊢ listToPath (pathToList Path.nil) = Path.cast (_ : star α = star α) (_ : star α = star α) Path.nil

Next tactic:
rfl
theorem listToPath_pathToList {x : SingleObj α} (p : Path (star α) x) :
    listToPath (pathToList p) = p.cast rfl ext := by
  induction' p with y z p a ih
  · rfl
  · 

Proof state:
case cons
α : Type u_1
β : Type u_2
γ : Type u_3
x y z : SingleObj α
p : Path (star α) y
a : y ⟶ z
ih : listToPath (pathToList p) = Path.cast (_ : star α = star α) (_ : y = star α) p
⊢ listToPath (pathToList (Path.cons p a)) = Path.cast (_ : star α = star α) (_ : z = star α) (Path.cons p a)

Next tactic:
dsimp at *
theorem listToPath_pathToList {x : SingleObj α} (p : Path (star α) x) :
    listToPath (pathToList p) = p.cast rfl ext := by
  induction' p with y z p a ih
  · rfl
  · dsimp at *; 

Proof state:
case cons
α : Type u_1
β : Type u_2
γ : Type u_3
x y z : SingleObj α
p : Path (star α) y
a : y ⟶ z
ih : listToPath (pathToList p) = p
⊢ Path.cons (listToPath (pathToList p)) a = Path.cons p a

Next tactic:
rw [ih]
theorem pathToList_listToPath (l : List α) : pathToList (listToPath l) = l := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
l : List α
⊢ pathToList (listToPath l) = l

Next tactic:
induction' l with a l ih
theorem pathToList_listToPath (l : List α) : pathToList (listToPath l) = l := by
  induction' l with a l ih
  · 

Proof state:
case nil
α : Type u_1
β : Type u_2
γ : Type u_3
⊢ pathToList (listToPath []) = []

Next tactic:
rfl
theorem pathToList_listToPath (l : List α) : pathToList (listToPath l) = l := by
  induction' l with a l ih
  · rfl
  · 

Proof state:
case cons
α : Type u_1
β : Type u_2
γ : Type u_3
a : α
l : List α
ih : pathToList (listToPath l) = l
⊢ pathToList (listToPath (a :: l)) = a :: l

Next tactic:
change a :: pathToList (listToPath l) = a :: l
theorem pathToList_listToPath (l : List α) : pathToList (listToPath l) = l := by
  induction' l with a l ih
  · rfl
  · change a :: pathToList (listToPath l) = a :: l; 

Proof state:
case cons
α : Type u_1
β : Type u_2
γ : Type u_3
a : α
l : List α
ih : pathToList (listToPath l) = l
⊢ a :: pathToList (listToPath l) = a :: l

Next tactic:
rw [ih]
theorem cycleType_eq' {σ : Perm α} (s : Finset (Perm α)) (h1 : ∀ f : Perm α, f ∈ s → f.IsCycle)
    (h2 : (s : Set (Perm α)).Pairwise Disjoint)
    (h0 : s.noncommProd id (h2.imp fun _ _ => Disjoint.commute) = σ) :
    σ.cycleType = s.1.map (Finset.card ∘ support) := by
  

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ : Perm α
s : Finset (Perm α)
h1 : ∀ f ∈ s, IsCycle f
h2 : Set.Pairwise (↑s) Disjoint
h0 : Finset.noncommProd s id (_ : Set.Pairwise ↑s fun a b => Commute (id a) (id b)) = σ
⊢ cycleType σ = map (Finset.card ∘ support) s.val

Next tactic:
rw [cycleType_def]
theorem cycleType_eq' {σ : Perm α} (s : Finset (Perm α)) (h1 : ∀ f : Perm α, f ∈ s → f.IsCycle)
    (h2 : (s : Set (Perm α)).Pairwise Disjoint)
    (h0 : s.noncommProd id (h2.imp fun _ _ => Disjoint.commute) = σ) :
    σ.cycleType = s.1.map (Finset.card ∘ support) := by
  rw [cycleType_def]
  

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ : Perm α
s : Finset (Perm α)
h1 : ∀ f ∈ s, IsCycle f
h2 : Set.Pairwise (↑s) Disjoint
h0 : Finset.noncommProd s id (_ : Set.Pairwise ↑s fun a b => Commute (id a) (id b)) = σ
⊢ map (Finset.card ∘ support) (cycleFactorsFinset σ).val = map (Finset.card ∘ support) s.val

Next tactic:
congr
theorem cycleType_eq' {σ : Perm α} (s : Finset (Perm α)) (h1 : ∀ f : Perm α, f ∈ s → f.IsCycle)
    (h2 : (s : Set (Perm α)).Pairwise Disjoint)
    (h0 : s.noncommProd id (h2.imp fun _ _ => Disjoint.commute) = σ) :
    σ.cycleType = s.1.map (Finset.card ∘ support) := by
  rw [cycleType_def]
  congr
  

Proof state:
case e_s.e_self
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ : Perm α
s : Finset (Perm α)
h1 : ∀ f ∈ s, IsCycle f
h2 : Set.Pairwise (↑s) Disjoint
h0 : Finset.noncommProd s id (_ : Set.Pairwise ↑s fun a b => Commute (id a) (id b)) = σ
⊢ cycleFactorsFinset σ = s

Next tactic:
rw [cycleFactorsFinset_eq_finset]
theorem cycleType_eq' {σ : Perm α} (s : Finset (Perm α)) (h1 : ∀ f : Perm α, f ∈ s → f.IsCycle)
    (h2 : (s : Set (Perm α)).Pairwise Disjoint)
    (h0 : s.noncommProd id (h2.imp fun _ _ => Disjoint.commute) = σ) :
    σ.cycleType = s.1.map (Finset.card ∘ support) := by
  rw [cycleType_def]
  congr
  rw [cycleFactorsFinset_eq_finset]
  

Proof state:
case e_s.e_self
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ : Perm α
s : Finset (Perm α)
h1 : ∀ f ∈ s, IsCycle f
h2 : Set.Pairwise (↑s) Disjoint
h0 : Finset.noncommProd s id (_ : Set.Pairwise ↑s fun a b => Commute (id a) (id b)) = σ
⊢ (∀ f ∈ s, IsCycle f) ∧
    ∃ (h : Set.Pairwise (↑s) Disjoint),
      Finset.noncommProd s id (_ : Set.Pairwise ↑s fun a b => Commute (id a) (id b)) = σ

Next tactic:
exact ⟨h1, h2, h0⟩
theorem cycleType_eq {σ : Perm α} (l : List (Perm α)) (h0 : l.prod = σ)
    (h1 : ∀ σ : Perm α, σ ∈ l → σ.IsCycle) (h2 : l.Pairwise Disjoint) :
    σ.cycleType = l.map (Finset.card ∘ support) := by
  

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ : Perm α
l : List (Perm α)
h0 : List.prod l = σ
h1 : ∀ σ ∈ l, IsCycle σ
h2 : List.Pairwise Disjoint l
⊢ cycleType σ = ↑(List.map (Finset.card ∘ support) l)

Next tactic:
have hl : l.Nodup := nodup_of_pairwise_disjoint_cycles h1 h2
theorem cycleType_eq {σ : Perm α} (l : List (Perm α)) (h0 : l.prod = σ)
    (h1 : ∀ σ : Perm α, σ ∈ l → σ.IsCycle) (h2 : l.Pairwise Disjoint) :
    σ.cycleType = l.map (Finset.card ∘ support) := by
  have hl : l.Nodup := nodup_of_pairwise_disjoint_cycles h1 h2
  

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ : Perm α
l : List (Perm α)
h0 : List.prod l = σ
h1 : ∀ σ ∈ l, IsCycle σ
h2 : List.Pairwise Disjoint l
hl : List.Nodup l
⊢ cycleType σ = ↑(List.map (Finset.card ∘ support) l)

Next tactic:
rw [cycleType_eq' l.toFinset]
theorem cycleType_eq {σ : Perm α} (l : List (Perm α)) (h0 : l.prod = σ)
    (h1 : ∀ σ : Perm α, σ ∈ l → σ.IsCycle) (h2 : l.Pairwise Disjoint) :
    σ.cycleType = l.map (Finset.card ∘ support) := by
  have hl : l.Nodup := nodup_of_pairwise_disjoint_cycles h1 h2
  rw [cycleType_eq' l.toFinset]
  · 

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ : Perm α
l : List (Perm α)
h0 : List.prod l = σ
h1 : ∀ σ ∈ l, IsCycle σ
h2 : List.Pairwise Disjoint l
hl : List.Nodup l
⊢ map (Finset.card ∘ support) (List.toFinset l).val = ↑(List.map (Finset.card ∘ support) l)

Next tactic:
simp [List.dedup_eq_self.mpr hl, (· ∘ ·)]
theorem cycleType_eq {σ : Perm α} (l : List (Perm α)) (h0 : l.prod = σ)
    (h1 : ∀ σ : Perm α, σ ∈ l → σ.IsCycle) (h2 : l.Pairwise Disjoint) :
    σ.cycleType = l.map (Finset.card ∘ support) := by
  have hl : l.Nodup := nodup_of_pairwise_disjoint_cycles h1 h2
  rw [cycleType_eq' l.toFinset]
  · simp [List.dedup_eq_self.mpr hl, (· ∘ ·)]
  · 

Proof state:
case h1
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ : Perm α
l : List (Perm α)
h0 : List.prod l = σ
h1 : ∀ σ ∈ l, IsCycle σ
h2 : List.Pairwise Disjoint l
hl : List.Nodup l
⊢ ∀ f ∈ List.toFinset l, IsCycle f

Next tactic:
simpa using h1
theorem cycleType_eq {σ : Perm α} (l : List (Perm α)) (h0 : l.prod = σ)
    (h1 : ∀ σ : Perm α, σ ∈ l → σ.IsCycle) (h2 : l.Pairwise Disjoint) :
    σ.cycleType = l.map (Finset.card ∘ support) := by
  have hl : l.Nodup := nodup_of_pairwise_disjoint_cycles h1 h2
  rw [cycleType_eq' l.toFinset]
  · simp [List.dedup_eq_self.mpr hl, (· ∘ ·)]
  · simpa using h1
  · 

Proof state:
case h2
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ : Perm α
l : List (Perm α)
h0 : List.prod l = σ
h1 : ∀ σ ∈ l, IsCycle σ
h2 : List.Pairwise Disjoint l
hl : List.Nodup l
⊢ Set.Pairwise (↑(List.toFinset l)) Disjoint

Next tactic:
simpa [hl] using h2
theorem cycleType_eq {σ : Perm α} (l : List (Perm α)) (h0 : l.prod = σ)
    (h1 : ∀ σ : Perm α, σ ∈ l → σ.IsCycle) (h2 : l.Pairwise Disjoint) :
    σ.cycleType = l.map (Finset.card ∘ support) := by
  have hl : l.Nodup := nodup_of_pairwise_disjoint_cycles h1 h2
  rw [cycleType_eq' l.toFinset]
  · simp [List.dedup_eq_self.mpr hl, (· ∘ ·)]
  · simpa using h1
  · simpa [hl] using h2
  · 

Proof state:
case h0
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ : Perm α
l : List (Perm α)
h0 : List.prod l = σ
h1 : ∀ σ ∈ l, IsCycle σ
h2 : List.Pairwise Disjoint l
hl : List.Nodup l
⊢ Finset.noncommProd (List.toFinset l) id (_ : Set.Pairwise ↑(List.toFinset l) fun a b => Commute (id a) (id b)) = σ

Next tactic:
simp [hl, h0]
@[simp] -- porting note: new attr
theorem cycleType_eq_zero {σ : Perm α} : σ.cycleType = 0 ↔ σ = 1 := by
  

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ : Perm α
⊢ cycleType σ = 0 ↔ σ = 1

Next tactic:
simp [cycleType_def, cycleFactorsFinset_eq_empty_iff]
theorem card_cycleType_eq_zero {σ : Perm α} : Multiset.card σ.cycleType = 0 ↔ σ = 1 := by
  

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

Next tactic:
rw [card_eq_zero, cycleType_eq_zero]
theorem two_le_of_mem_cycleType {σ : Perm α} {n : ℕ} (h : n ∈ σ.cycleType) : 2 ≤ n := by
  

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

Next tactic:
simp only [cycleType_def, ← Finset.mem_def, Function.comp_apply, Multiset.mem_map,
    mem_cycleFactorsFinset_iff] at h
theorem two_le_of_mem_cycleType {σ : Perm α} {n : ℕ} (h : n ∈ σ.cycleType) : 2 ≤ n := by
  simp only [cycleType_def, ← Finset.mem_def, Function.comp_apply, Multiset.mem_map,
    mem_cycleFactorsFinset_iff] at h
  

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ : Perm α
n : ℕ
h : ∃ a, (IsCycle a ∧ ∀ a_1 ∈ support a, a a_1 = σ a_1) ∧ Finset.card (support a) = n
⊢ 2 ≤ n

Next tactic:
obtain ⟨_, ⟨hc, -⟩, rfl⟩ := h