l3lab/ntp-mathlib huggingface dataset:
/-- Witness that the limit cone in `AlgebraCat R` is a limit cone.
(Internal use only; use the limits API.)
-/
def limitConeIsLimit (F : J ⥤ AlgebraCatMax.{v, w} R) : IsLimit (limitCone.{v, w} F) := by
  refine'
    IsLimit.ofFaithful (forget (AlgebraCat R)) (Types.limitConeIsLimit.{v, w} _)
      -- Porting note: in mathlib3 the function term
      -- `fun v => ⟨fun j => ((forget (AlgebraCat R)).mapCone s).π.app j v`
      -- was provided by unification, and the last argument `(fun s => _)` was `(fun s => rfl)`.
      (fun s => ⟨⟨⟨⟨fun v => ⟨fun j => ((forget (AlgebraCat R)).mapCone s).π.app j v, _⟩,
         _⟩, _⟩, _, _⟩, _⟩)
      (fun s => _)
  · intro j j' f
    exact FunLike.congr_fun (Cone.w s f) v
  · -- Porting note: we could add a custom `ext` lemma here.
    apply Subtype.ext
    ext j
    simp only [Functor.comp_obj, Functor.mapCone_pt, Functor.mapCone_π_app,
      forget_map_eq_coe]
    -- This used to be as below but we need `erw` after leanprover/lean4#2644
    -- simp [forget_map_eq_coe, AlgHom.map_one, Functor.mapCone_π_app]
    erw [map_one]
    rfl
  · intro x y
    apply Subtype.ext
    ext j
    simp only [Functor.comp_obj, Functor.mapCone_pt, Functor.mapCone_π_app,
      forget_map_eq_coe]
    -- This used to be as below, but we need `erw` after leanprover/lean4#2644
    -- simp [forget_map_eq_coe, AlgHom.map_mul, Functor.mapCone_π_app]
    erw [map_mul]
    rfl
  · simp only [Functor.comp_obj, Functor.mapCone_pt, Functor.mapCone_π_app,
      forget_map_eq_coe]
    -- The below `simp` was enough before leanprover/lean4#2644
    -- simp [forget_map_eq_coe, AlgHom.map_zero, Functor.mapCone_π_app]
    apply Subtype.ext
    dsimp
    funext u
    

Proof state:
case refine'_4.a.h
R : Type u
inst✝¹ : CommRing R
J : Type v
inst✝ : SmallCategory J
F : J ⥤ AlgebraCatMax R
s : Cone F
u : J
⊢ (s.π.app u) 0 = ↑0 u

Next tactic:
erw [map_zero]
/-- Witness that the limit cone in `AlgebraCat R` is a limit cone.
(Internal use only; use the limits API.)
-/
def limitConeIsLimit (F : J ⥤ AlgebraCatMax.{v, w} R) : IsLimit (limitCone.{v, w} F) := by
  refine'
    IsLimit.ofFaithful (forget (AlgebraCat R)) (Types.limitConeIsLimit.{v, w} _)
      -- Porting note: in mathlib3 the function term
      -- `fun v => ⟨fun j => ((forget (AlgebraCat R)).mapCone s).π.app j v`
      -- was provided by unification, and the last argument `(fun s => _)` was `(fun s => rfl)`.
      (fun s => ⟨⟨⟨⟨fun v => ⟨fun j => ((forget (AlgebraCat R)).mapCone s).π.app j v, _⟩,
         _⟩, _⟩, _, _⟩, _⟩)
      (fun s => _)
  · intro j j' f
    exact FunLike.congr_fun (Cone.w s f) v
  · -- Porting note: we could add a custom `ext` lemma here.
    apply Subtype.ext
    ext j
    simp only [Functor.comp_obj, Functor.mapCone_pt, Functor.mapCone_π_app,
      forget_map_eq_coe]
    -- This used to be as below but we need `erw` after leanprover/lean4#2644
    -- simp [forget_map_eq_coe, AlgHom.map_one, Functor.mapCone_π_app]
    erw [map_one]
    rfl
  · intro x y
    apply Subtype.ext
    ext j
    simp only [Functor.comp_obj, Functor.mapCone_pt, Functor.mapCone_π_app,
      forget_map_eq_coe]
    -- This used to be as below, but we need `erw` after leanprover/lean4#2644
    -- simp [forget_map_eq_coe, AlgHom.map_mul, Functor.mapCone_π_app]
    erw [map_mul]
    rfl
  · simp only [Functor.comp_obj, Functor.mapCone_pt, Functor.mapCone_π_app,
      forget_map_eq_coe]
    -- The below `simp` was enough before leanprover/lean4#2644
    -- simp [forget_map_eq_coe, AlgHom.map_zero, Functor.mapCone_π_app]
    apply Subtype.ext
    dsimp
    funext u
    erw [map_zero]
    

Proof state:
case refine'_4.a.h
R : Type u
inst✝¹ : CommRing R
J : Type v
inst✝ : SmallCategory J
F : J ⥤ AlgebraCatMax R
s : Cone F
u : J
⊢ 0 = ↑0 u

Next tactic:
rfl
/-- Witness that the limit cone in `AlgebraCat R` is a limit cone.
(Internal use only; use the limits API.)
-/
def limitConeIsLimit (F : J ⥤ AlgebraCatMax.{v, w} R) : IsLimit (limitCone.{v, w} F) := by
  refine'
    IsLimit.ofFaithful (forget (AlgebraCat R)) (Types.limitConeIsLimit.{v, w} _)
      -- Porting note: in mathlib3 the function term
      -- `fun v => ⟨fun j => ((forget (AlgebraCat R)).mapCone s).π.app j v`
      -- was provided by unification, and the last argument `(fun s => _)` was `(fun s => rfl)`.
      (fun s => ⟨⟨⟨⟨fun v => ⟨fun j => ((forget (AlgebraCat R)).mapCone s).π.app j v, _⟩,
         _⟩, _⟩, _, _⟩, _⟩)
      (fun s => _)
  · intro j j' f
    exact FunLike.congr_fun (Cone.w s f) v
  · -- Porting note: we could add a custom `ext` lemma here.
    apply Subtype.ext
    ext j
    simp only [Functor.comp_obj, Functor.mapCone_pt, Functor.mapCone_π_app,
      forget_map_eq_coe]
    -- This used to be as below but we need `erw` after leanprover/lean4#2644
    -- simp [forget_map_eq_coe, AlgHom.map_one, Functor.mapCone_π_app]
    erw [map_one]
    rfl
  · intro x y
    apply Subtype.ext
    ext j
    simp only [Functor.comp_obj, Functor.mapCone_pt, Functor.mapCone_π_app,
      forget_map_eq_coe]
    -- This used to be as below, but we need `erw` after leanprover/lean4#2644
    -- simp [forget_map_eq_coe, AlgHom.map_mul, Functor.mapCone_π_app]
    erw [map_mul]
    rfl
  · simp only [Functor.comp_obj, Functor.mapCone_pt, Functor.mapCone_π_app,
      forget_map_eq_coe]
    -- The below `simp` was enough before leanprover/lean4#2644
    -- simp [forget_map_eq_coe, AlgHom.map_zero, Functor.mapCone_π_app]
    apply Subtype.ext
    dsimp
    funext u
    erw [map_zero]
    rfl
  · intro x y
    simp only [Functor.comp_obj, Functor.mapCone_pt, Functor.mapCone_π_app,
      forget_map_eq_coe]
    -- The below `simp` was enough before leanprover/lean4#2644
    -- simp [forget_map_eq_coe, AlgHom.map_add, Functor.mapCone_π_app]
    

Proof state:
case refine'_5
R : Type u
inst✝¹ : CommRing R
J : Type v
inst✝ : SmallCategory J
F : J ⥤ AlgebraCatMax R
s : Cone F
x y : ↑s.pt
⊢ { val := fun j => (s.π.app j) (x + y),
      property := (_ : (fun x => x ∈ Functor.sections (F ⋙ forget (AlgebraCatMax R))) fun j => (s.π.app j) (x + y)) } =
    { val := fun j => (s.π.app j) x,
        property := (_ : (fun x => x ∈ Functor.sections (F ⋙ forget (AlgebraCatMax R))) fun j => (s.π.app j) x) } +
      { val := fun j => (s.π.app j) y,
        property := (_ : (fun x => x ∈ Functor.sections (F ⋙ forget (AlgebraCatMax R))) fun j => (s.π.app j) y) }

Next tactic:
apply Subtype.ext
/-- Witness that the limit cone in `AlgebraCat R` is a limit cone.
(Internal use only; use the limits API.)
-/
def limitConeIsLimit (F : J ⥤ AlgebraCatMax.{v, w} R) : IsLimit (limitCone.{v, w} F) := by
  refine'
    IsLimit.ofFaithful (forget (AlgebraCat R)) (Types.limitConeIsLimit.{v, w} _)
      -- Porting note: in mathlib3 the function term
      -- `fun v => ⟨fun j => ((forget (AlgebraCat R)).mapCone s).π.app j v`
      -- was provided by unification, and the last argument `(fun s => _)` was `(fun s => rfl)`.
      (fun s => ⟨⟨⟨⟨fun v => ⟨fun j => ((forget (AlgebraCat R)).mapCone s).π.app j v, _⟩,
         _⟩, _⟩, _, _⟩, _⟩)
      (fun s => _)
  · intro j j' f
    exact FunLike.congr_fun (Cone.w s f) v
  · -- Porting note: we could add a custom `ext` lemma here.
    apply Subtype.ext
    ext j
    simp only [Functor.comp_obj, Functor.mapCone_pt, Functor.mapCone_π_app,
      forget_map_eq_coe]
    -- This used to be as below but we need `erw` after leanprover/lean4#2644
    -- simp [forget_map_eq_coe, AlgHom.map_one, Functor.mapCone_π_app]
    erw [map_one]
    rfl
  · intro x y
    apply Subtype.ext
    ext j
    simp only [Functor.comp_obj, Functor.mapCone_pt, Functor.mapCone_π_app,
      forget_map_eq_coe]
    -- This used to be as below, but we need `erw` after leanprover/lean4#2644
    -- simp [forget_map_eq_coe, AlgHom.map_mul, Functor.mapCone_π_app]
    erw [map_mul]
    rfl
  · simp only [Functor.comp_obj, Functor.mapCone_pt, Functor.mapCone_π_app,
      forget_map_eq_coe]
    -- The below `simp` was enough before leanprover/lean4#2644
    -- simp [forget_map_eq_coe, AlgHom.map_zero, Functor.mapCone_π_app]
    apply Subtype.ext
    dsimp
    funext u
    erw [map_zero]
    rfl
  · intro x y
    simp only [Functor.comp_obj, Functor.mapCone_pt, Functor.mapCone_π_app,
      forget_map_eq_coe]
    -- The below `simp` was enough before leanprover/lean4#2644
    -- simp [forget_map_eq_coe, AlgHom.map_add, Functor.mapCone_π_app]
    apply Subtype.ext
    

Proof state:
case refine'_5.a
R : Type u
inst✝¹ : CommRing R
J : Type v
inst✝ : SmallCategory J
F : J ⥤ AlgebraCatMax R
s : Cone F
x y : ↑s.pt
⊢ ↑{ val := fun j => (s.π.app j) (x + y),
        property :=
          (_ : (fun x => x ∈ Functor.sections (F ⋙ forget (AlgebraCatMax R))) fun j => (s.π.app j) (x + y)) } =
    ↑({ val := fun j => (s.π.app j) x,
          property := (_ : (fun x => x ∈ Functor.sections (F ⋙ forget (AlgebraCatMax R))) fun j => (s.π.app j) x) } +
        { val := fun j => (s.π.app j) y,
          property := (_ : (fun x => x ∈ Functor.sections (F ⋙ forget (AlgebraCatMax R))) fun j => (s.π.app j) y) })

Next tactic:
dsimp
/-- Witness that the limit cone in `AlgebraCat R` is a limit cone.
(Internal use only; use the limits API.)
-/
def limitConeIsLimit (F : J ⥤ AlgebraCatMax.{v, w} R) : IsLimit (limitCone.{v, w} F) := by
  refine'
    IsLimit.ofFaithful (forget (AlgebraCat R)) (Types.limitConeIsLimit.{v, w} _)
      -- Porting note: in mathlib3 the function term
      -- `fun v => ⟨fun j => ((forget (AlgebraCat R)).mapCone s).π.app j v`
      -- was provided by unification, and the last argument `(fun s => _)` was `(fun s => rfl)`.
      (fun s => ⟨⟨⟨⟨fun v => ⟨fun j => ((forget (AlgebraCat R)).mapCone s).π.app j v, _⟩,
         _⟩, _⟩, _, _⟩, _⟩)
      (fun s => _)
  · intro j j' f
    exact FunLike.congr_fun (Cone.w s f) v
  · -- Porting note: we could add a custom `ext` lemma here.
    apply Subtype.ext
    ext j
    simp only [Functor.comp_obj, Functor.mapCone_pt, Functor.mapCone_π_app,
      forget_map_eq_coe]
    -- This used to be as below but we need `erw` after leanprover/lean4#2644
    -- simp [forget_map_eq_coe, AlgHom.map_one, Functor.mapCone_π_app]
    erw [map_one]
    rfl
  · intro x y
    apply Subtype.ext
    ext j
    simp only [Functor.comp_obj, Functor.mapCone_pt, Functor.mapCone_π_app,
      forget_map_eq_coe]
    -- This used to be as below, but we need `erw` after leanprover/lean4#2644
    -- simp [forget_map_eq_coe, AlgHom.map_mul, Functor.mapCone_π_app]
    erw [map_mul]
    rfl
  · simp only [Functor.comp_obj, Functor.mapCone_pt, Functor.mapCone_π_app,
      forget_map_eq_coe]
    -- The below `simp` was enough before leanprover/lean4#2644
    -- simp [forget_map_eq_coe, AlgHom.map_zero, Functor.mapCone_π_app]
    apply Subtype.ext
    dsimp
    funext u
    erw [map_zero]
    rfl
  · intro x y
    simp only [Functor.comp_obj, Functor.mapCone_pt, Functor.mapCone_π_app,
      forget_map_eq_coe]
    -- The below `simp` was enough before leanprover/lean4#2644
    -- simp [forget_map_eq_coe, AlgHom.map_add, Functor.mapCone_π_app]
    apply Subtype.ext
    dsimp
    

Proof state:
case refine'_5.a
R : Type u
inst✝¹ : CommRing R
J : Type v
inst✝ : SmallCategory J
F : J ⥤ AlgebraCatMax R
s : Cone F
x y : ↑s.pt
⊢ (fun j => (s.π.app j) (x + y)) =
    ↑({ val := fun j => (s.π.app j) x,
          property := (_ : ∀ {j j' : J} (f : j ⟶ j'), (s.π.app j ≫ F.map f) x = (s.π.app j') x) } +
        { val := fun j => (s.π.app j) y,
          property := (_ : ∀ {j j' : J} (f : j ⟶ j'), (s.π.app j ≫ F.map f) y = (s.π.app j') y) })

Next tactic:
funext u
/-- Witness that the limit cone in `AlgebraCat R` is a limit cone.
(Internal use only; use the limits API.)
-/
def limitConeIsLimit (F : J ⥤ AlgebraCatMax.{v, w} R) : IsLimit (limitCone.{v, w} F) := by
  refine'
    IsLimit.ofFaithful (forget (AlgebraCat R)) (Types.limitConeIsLimit.{v, w} _)
      -- Porting note: in mathlib3 the function term
      -- `fun v => ⟨fun j => ((forget (AlgebraCat R)).mapCone s).π.app j v`
      -- was provided by unification, and the last argument `(fun s => _)` was `(fun s => rfl)`.
      (fun s => ⟨⟨⟨⟨fun v => ⟨fun j => ((forget (AlgebraCat R)).mapCone s).π.app j v, _⟩,
         _⟩, _⟩, _, _⟩, _⟩)
      (fun s => _)
  · intro j j' f
    exact FunLike.congr_fun (Cone.w s f) v
  · -- Porting note: we could add a custom `ext` lemma here.
    apply Subtype.ext
    ext j
    simp only [Functor.comp_obj, Functor.mapCone_pt, Functor.mapCone_π_app,
      forget_map_eq_coe]
    -- This used to be as below but we need `erw` after leanprover/lean4#2644
    -- simp [forget_map_eq_coe, AlgHom.map_one, Functor.mapCone_π_app]
    erw [map_one]
    rfl
  · intro x y
    apply Subtype.ext
    ext j
    simp only [Functor.comp_obj, Functor.mapCone_pt, Functor.mapCone_π_app,
      forget_map_eq_coe]
    -- This used to be as below, but we need `erw` after leanprover/lean4#2644
    -- simp [forget_map_eq_coe, AlgHom.map_mul, Functor.mapCone_π_app]
    erw [map_mul]
    rfl
  · simp only [Functor.comp_obj, Functor.mapCone_pt, Functor.mapCone_π_app,
      forget_map_eq_coe]
    -- The below `simp` was enough before leanprover/lean4#2644
    -- simp [forget_map_eq_coe, AlgHom.map_zero, Functor.mapCone_π_app]
    apply Subtype.ext
    dsimp
    funext u
    erw [map_zero]
    rfl
  · intro x y
    simp only [Functor.comp_obj, Functor.mapCone_pt, Functor.mapCone_π_app,
      forget_map_eq_coe]
    -- The below `simp` was enough before leanprover/lean4#2644
    -- simp [forget_map_eq_coe, AlgHom.map_add, Functor.mapCone_π_app]
    apply Subtype.ext
    dsimp
    funext u
    

Proof state:
case refine'_5.a.h
R : Type u
inst✝¹ : CommRing R
J : Type v
inst✝ : SmallCategory J
F : J ⥤ AlgebraCatMax R
s : Cone F
x y : ↑s.pt
u : J
⊢ (s.π.app u) (x + y) =
    ↑({ val := fun j => (s.π.app j) x,
            property := (_ : ∀ {j j' : J} (f : j ⟶ j'), (s.π.app j ≫ F.map f) x = (s.π.app j') x) } +
          { val := fun j => (s.π.app j) y,
            property := (_ : ∀ {j j' : J} (f : j ⟶ j'), (s.π.app j ≫ F.map f) y = (s.π.app j') y) })
      u

Next tactic:
erw [map_add]
/-- Witness that the limit cone in `AlgebraCat R` is a limit cone.
(Internal use only; use the limits API.)
-/
def limitConeIsLimit (F : J ⥤ AlgebraCatMax.{v, w} R) : IsLimit (limitCone.{v, w} F) := by
  refine'
    IsLimit.ofFaithful (forget (AlgebraCat R)) (Types.limitConeIsLimit.{v, w} _)
      -- Porting note: in mathlib3 the function term
      -- `fun v => ⟨fun j => ((forget (AlgebraCat R)).mapCone s).π.app j v`
      -- was provided by unification, and the last argument `(fun s => _)` was `(fun s => rfl)`.
      (fun s => ⟨⟨⟨⟨fun v => ⟨fun j => ((forget (AlgebraCat R)).mapCone s).π.app j v, _⟩,
         _⟩, _⟩, _, _⟩, _⟩)
      (fun s => _)
  · intro j j' f
    exact FunLike.congr_fun (Cone.w s f) v
  · -- Porting note: we could add a custom `ext` lemma here.
    apply Subtype.ext
    ext j
    simp only [Functor.comp_obj, Functor.mapCone_pt, Functor.mapCone_π_app,
      forget_map_eq_coe]
    -- This used to be as below but we need `erw` after leanprover/lean4#2644
    -- simp [forget_map_eq_coe, AlgHom.map_one, Functor.mapCone_π_app]
    erw [map_one]
    rfl
  · intro x y
    apply Subtype.ext
    ext j
    simp only [Functor.comp_obj, Functor.mapCone_pt, Functor.mapCone_π_app,
      forget_map_eq_coe]
    -- This used to be as below, but we need `erw` after leanprover/lean4#2644
    -- simp [forget_map_eq_coe, AlgHom.map_mul, Functor.mapCone_π_app]
    erw [map_mul]
    rfl
  · simp only [Functor.comp_obj, Functor.mapCone_pt, Functor.mapCone_π_app,
      forget_map_eq_coe]
    -- The below `simp` was enough before leanprover/lean4#2644
    -- simp [forget_map_eq_coe, AlgHom.map_zero, Functor.mapCone_π_app]
    apply Subtype.ext
    dsimp
    funext u
    erw [map_zero]
    rfl
  · intro x y
    simp only [Functor.comp_obj, Functor.mapCone_pt, Functor.mapCone_π_app,
      forget_map_eq_coe]
    -- The below `simp` was enough before leanprover/lean4#2644
    -- simp [forget_map_eq_coe, AlgHom.map_add, Functor.mapCone_π_app]
    apply Subtype.ext
    dsimp
    funext u
    erw [map_add]
    

Proof state:
case refine'_5.a.h
R : Type u
inst✝¹ : CommRing R
J : Type v
inst✝ : SmallCategory J
F : J ⥤ AlgebraCatMax R
s : Cone F
x y : ↑s.pt
u : J
⊢ (s.π.app u) x + (s.π.app u) y =
    ↑({ val := fun j => (s.π.app j) x,
            property := (_ : ∀ {j j' : J} (f : j ⟶ j'), (s.π.app j ≫ F.map f) x = (s.π.app j') x) } +
          { val := fun j => (s.π.app j) y,
            property := (_ : ∀ {j j' : J} (f : j ⟶ j'), (s.π.app j ≫ F.map f) y = (s.π.app j') y) })
      u

Next tactic:
rfl
theorem rotate_mod (l : List α) (n : ℕ) : l.rotate (n % l.length) = l.rotate n := by 

Proof state:
α : Type u
l : List α
n : ℕ
⊢ rotate l (n % length l) = rotate l n

Next tactic:
simp [rotate]
@[simp]
theorem rotate_nil (n : ℕ) : ([] : List α).rotate n = [] := by 

Proof state:
α : Type u
n : ℕ
⊢ rotate [] n = []

Next tactic:
simp [rotate]
@[simp]
theorem rotate_zero (l : List α) : l.rotate 0 = l := by 

Proof state:
α : Type u
l : List α
⊢ rotate l 0 = l

Next tactic:
simp [rotate]
theorem rotate'_nil (n : ℕ) : ([] : List α).rotate' n = [] := by 

Proof state:
α : Type u
n : ℕ
⊢ rotate' [] n = []

Next tactic:
cases n
theorem rotate'_nil (n : ℕ) : ([] : List α).rotate' n = [] := by cases n <;> 

Proof state:
case zero
α : Type u
⊢ rotate' [] zero = []

Next tactic:
rfl
theorem rotate'_nil (n : ℕ) : ([] : List α).rotate' n = [] := by cases n <;> 

Proof state:
case succ
α : Type u
n✝ : ℕ
⊢ rotate' [] (succ n✝) = []

Next tactic:
rfl
@[simp]
theorem rotate'_zero (l : List α) : l.rotate' 0 = l := by 

Proof state:
α : Type u
l : List α
⊢ rotate' l 0 = l

Next tactic:
cases l
@[simp]
theorem rotate'_zero (l : List α) : l.rotate' 0 = l := by cases l <;> 

Proof state:
case nil
α : Type u
⊢ rotate' [] 0 = []

Next tactic:
rfl
@[simp]
theorem rotate'_zero (l : List α) : l.rotate' 0 = l := by cases l <;> 

Proof state:
case cons
α : Type u
head✝ : α
tail✝ : List α
⊢ rotate' (head✝ :: tail✝) 0 = head✝ :: tail✝

Next tactic:
rfl
theorem rotate'_cons_succ (l : List α) (a : α) (n : ℕ) :
    (a :: l : List α).rotate' n.succ = (l ++ [a]).rotate' n := by 

Proof state:
α : Type u
l : List α
a : α
n : ℕ
⊢ rotate' (a :: l) (succ n) = rotate' (l ++ [a]) n

Next tactic:
simp [rotate']
@[simp]
theorem length_rotate' : ∀ (l : List α) (n : ℕ), (l.rotate' n).length = l.length
  | [], _ => by 

Proof state:
α : Type u
x✝ : ℕ
⊢ length (rotate' [] x✝) = length []

Next tactic:
simp
@[simp]
theorem length_rotate' : ∀ (l : List α) (n : ℕ), (l.rotate' n).length = l.length
  | [], _ => by simp
  | a :: l, 0 => rfl
  | a :: l, n + 1 => by 

Proof state:
α : Type u
a : α
l : List α
n : ℕ
⊢ length (rotate' (a :: l) (n + 1)) = length (a :: l)

Next tactic:
rw [List.rotate', length_rotate' (l ++ [a]) n]
@[simp]
theorem length_rotate' : ∀ (l : List α) (n : ℕ), (l.rotate' n).length = l.length
  | [], _ => by simp
  | a :: l, 0 => rfl
  | a :: l, n + 1 => by rw [List.rotate', length_rotate' (l ++ [a]) n]; 

Proof state:
α : Type u
a : α
l : List α
n : ℕ
⊢ length (l ++ [a]) = length (a :: l)

Next tactic:
simp
theorem rotate'_eq_drop_append_take :
    ∀ {l : List α} {n : ℕ}, n ≤ l.length → l.rotate' n = l.drop n ++ l.take n
  | [], n, h => by 

Proof state:
α : Type u
n : ℕ
h : n ≤ length []
⊢ rotate' [] n = drop n [] ++ take n []

Next tactic:
simp [drop_append_of_le_length h]
theorem rotate'_eq_drop_append_take :
    ∀ {l : List α} {n : ℕ}, n ≤ l.length → l.rotate' n = l.drop n ++ l.take n
  | [], n, h => by simp [drop_append_of_le_length h]
  | l, 0, h => by 

Proof state:
α : Type u
l : List α
h : 0 ≤ length l
⊢ rotate' l 0 = drop 0 l ++ take 0 l

Next tactic:
simp [take_append_of_le_length h]
theorem rotate'_eq_drop_append_take :
    ∀ {l : List α} {n : ℕ}, n ≤ l.length → l.rotate' n = l.drop n ++ l.take n
  | [], n, h => by simp [drop_append_of_le_length h]
  | l, 0, h => by simp [take_append_of_le_length h]
  | a :: l, n + 1, h => by
    

Proof state:
α : Type u
a : α
l : List α
n : ℕ
h : n + 1 ≤ length (a :: l)
⊢ rotate' (a :: l) (n + 1) = drop (n + 1) (a :: l) ++ take (n + 1) (a :: l)

Next tactic:
have hnl : n ≤ l.length := le_of_succ_le_succ h
theorem rotate'_eq_drop_append_take :
    ∀ {l : List α} {n : ℕ}, n ≤ l.length → l.rotate' n = l.drop n ++ l.take n
  | [], n, h => by simp [drop_append_of_le_length h]
  | l, 0, h => by simp [take_append_of_le_length h]
  | a :: l, n + 1, h => by
    have hnl : n ≤ l.length := le_of_succ_le_succ h
    

Proof state:
α : Type u
a : α
l : List α
n : ℕ
h : n + 1 ≤ length (a :: l)
hnl : n ≤ length l
⊢ rotate' (a :: l) (n + 1) = drop (n + 1) (a :: l) ++ take (n + 1) (a :: l)

Next tactic:
have hnl' : n ≤ (l ++ [a]).length := by
      rw [length_append, length_cons, List.length]; exact le_of_succ_le h
theorem rotate'_eq_drop_append_take :
    ∀ {l : List α} {n : ℕ}, n ≤ l.length → l.rotate' n = l.drop n ++ l.take n
  | [], n, h => by simp [drop_append_of_le_length h]
  | l, 0, h => by simp [take_append_of_le_length h]
  | a :: l, n + 1, h => by
    have hnl : n ≤ l.length := le_of_succ_le_succ h
    have hnl' : n ≤ (l ++ [a]).length := by
      

Proof state:
α : Type u
a : α
l : List α
n : ℕ
h : n + 1 ≤ length (a :: l)
hnl : n ≤ length l
⊢ n ≤ length (l ++ [a])

Next tactic:
rw [length_append, length_cons, List.length]
theorem rotate'_eq_drop_append_take :
    ∀ {l : List α} {n : ℕ}, n ≤ l.length → l.rotate' n = l.drop n ++ l.take n
  | [], n, h => by simp [drop_append_of_le_length h]
  | l, 0, h => by simp [take_append_of_le_length h]
  | a :: l, n + 1, h => by
    have hnl : n ≤ l.length := le_of_succ_le_succ h
    have hnl' : n ≤ (l ++ [a]).length := by
      rw [length_append, length_cons, List.length]; 

Proof state:
α : Type u
a : α
l : List α
n : ℕ
h : n + 1 ≤ length (a :: l)
hnl : n ≤ length l
⊢ n ≤ length l + succ 0

Next tactic:
exact le_of_succ_le h
theorem rotate'_eq_drop_append_take :
    ∀ {l : List α} {n : ℕ}, n ≤ l.length → l.rotate' n = l.drop n ++ l.take n
  | [], n, h => by simp [drop_append_of_le_length h]
  | l, 0, h => by simp [take_append_of_le_length h]
  | a :: l, n + 1, h => by
    have hnl : n ≤ l.length := le_of_succ_le_succ h
    have hnl' : n ≤ (l ++ [a]).length := by
      rw [length_append, length_cons, List.length]; exact le_of_succ_le h
    

Proof state:
α : Type u
a : α
l : List α
n : ℕ
h : n + 1 ≤ length (a :: l)
hnl : n ≤ length l
hnl' : n ≤ length (l ++ [a])
⊢ rotate' (a :: l) (n + 1) = drop (n + 1) (a :: l) ++ take (n + 1) (a :: l)

Next tactic:
rw [rotate'_cons_succ, rotate'_eq_drop_append_take hnl', drop, take,
        drop_append_of_le_length hnl, take_append_of_le_length hnl]
theorem rotate'_eq_drop_append_take :
    ∀ {l : List α} {n : ℕ}, n ≤ l.length → l.rotate' n = l.drop n ++ l.take n
  | [], n, h => by simp [drop_append_of_le_length h]
  | l, 0, h => by simp [take_append_of_le_length h]
  | a :: l, n + 1, h => by
    have hnl : n ≤ l.length := le_of_succ_le_succ h
    have hnl' : n ≤ (l ++ [a]).length := by
      rw [length_append, length_cons, List.length]; exact le_of_succ_le h
    rw [rotate'_cons_succ, rotate'_eq_drop_append_take hnl', drop, take,
        drop_append_of_le_length hnl, take_append_of_le_length hnl]; 

Proof state:
α : Type u
a : α
l : List α
n : ℕ
h : n + 1 ≤ length (a :: l)
hnl : n ≤ length l
hnl' : n ≤ length (l ++ [a])
⊢ drop n l ++ [a] ++ take n l = drop n l ++ a :: take n l

Next tactic:
simp
theorem rotate'_rotate' : ∀ (l : List α) (n m : ℕ), (l.rotate' n).rotate' m = l.rotate' (n + m)
  | a :: l, 0, m => by 

Proof state:
α : Type u
a : α
l : List α
m : ℕ
⊢ rotate' (rotate' (a :: l) 0) m = rotate' (a :: l) (0 + m)

Next tactic:
simp
theorem rotate'_rotate' : ∀ (l : List α) (n m : ℕ), (l.rotate' n).rotate' m = l.rotate' (n + m)
  | a :: l, 0, m => by simp
  | [], n, m => by 

Proof state:
α : Type u
n m : ℕ
⊢ rotate' (rotate' [] n) m = rotate' [] (n + m)

Next tactic:
simp
theorem rotate'_rotate' : ∀ (l : List α) (n m : ℕ), (l.rotate' n).rotate' m = l.rotate' (n + m)
  | a :: l, 0, m => by simp
  | [], n, m => by simp
  | a :: l, n + 1, m => by
    

Proof state:
α : Type u
a : α
l : List α
n m : ℕ
⊢ rotate' (rotate' (a :: l) (n + 1)) m = rotate' (a :: l) (n + 1 + m)

Next tactic:
rw [rotate'_cons_succ, rotate'_rotate' _ n, add_right_comm, ← rotate'_cons_succ]
@[simp]
theorem rotate'_length (l : List α) : rotate' l l.length = l := by
  

Proof state:
α : Type u
l : List α
⊢ rotate' l (length l) = l

Next tactic:
rw [rotate'_eq_drop_append_take le_rfl]