l3lab/ntp-mathlib huggingface dataset:
theorem liftAux_spec (f : X → L) (a b : lib R X) (h : FreeLieAlgebra.Rel R X a b) :
    liftAux R f a = liftAux R f b := by
  induction h
  case lie_self a' => simp only [liftAux_map_mul, NonUnitalAlgHom.map_zero, lie_self]
  case leibniz_lie a' b' c' =>
    simp only [liftAux_map_mul, liftAux_map_add, sub_add_cancel, lie_lie]
  case smul t a' b' _ h₂ => simp only [liftAux_map_smul, h₂]
  case add_right a' b' c' _ h₂ => 

Proof state:
R : Type u
X : Type v
inst✝² : CommRing R
L : Type w
inst✝¹ : LieRing L
inst✝ : LieAlgebra R L
f : X → L
a b a' b' c' : lib R X
a✝ : Rel R X a' b'
h₂ : (liftAux R f) a' = (liftAux R f) b'
⊢ (liftAux R f) (a' + c') = (liftAux R f) (b' + c')

Next tactic:
simp only [liftAux_map_add, h₂]
theorem liftAux_spec (f : X → L) (a b : lib R X) (h : FreeLieAlgebra.Rel R X a b) :
    liftAux R f a = liftAux R f b := by
  induction h
  case lie_self a' => simp only [liftAux_map_mul, NonUnitalAlgHom.map_zero, lie_self]
  case leibniz_lie a' b' c' =>
    simp only [liftAux_map_mul, liftAux_map_add, sub_add_cancel, lie_lie]
  case smul t a' b' _ h₂ => simp only [liftAux_map_smul, h₂]
  case add_right a' b' c' _ h₂ => simp only [liftAux_map_add, h₂]
  

Proof state:
case mul_left
R : Type u
X : Type v
inst✝² : CommRing R
L : Type w
inst✝¹ : LieRing L
inst✝ : LieAlgebra R L
f : X → L
a b a✝¹ b✝ c✝ : lib R X
a✝ : Rel R X b✝ c✝
a_ih✝ : (liftAux R f) b✝ = (liftAux R f) c✝
⊢ (liftAux R f) (a✝¹ * b✝) = (liftAux R f) (a✝¹ * c✝)
case mul_right
R : Type u
X : Type v
inst✝² : CommRing R
L : Type w
inst✝¹ : LieRing L
inst✝ : LieAlgebra R L
f : X → L
a b a✝¹ b✝ c✝ : lib R X
a✝ : Rel R X a✝¹ b✝
a_ih✝ : (liftAux R f) a✝¹ = (liftAux R f) b✝
⊢ (liftAux R f) (a✝¹ * c✝) = (liftAux R f) (b✝ * c✝)

Next tactic:
case mul_left a' b' c' _ h₂ => simp only [liftAux_map_mul, h₂]
theorem liftAux_spec (f : X → L) (a b : lib R X) (h : FreeLieAlgebra.Rel R X a b) :
    liftAux R f a = liftAux R f b := by
  induction h
  case lie_self a' => simp only [liftAux_map_mul, NonUnitalAlgHom.map_zero, lie_self]
  case leibniz_lie a' b' c' =>
    simp only [liftAux_map_mul, liftAux_map_add, sub_add_cancel, lie_lie]
  case smul t a' b' _ h₂ => simp only [liftAux_map_smul, h₂]
  case add_right a' b' c' _ h₂ => simp only [liftAux_map_add, h₂]
  

Proof state:
R : Type u
X : Type v
inst✝² : CommRing R
L : Type w
inst✝¹ : LieRing L
inst✝ : LieAlgebra R L
f : X → L
a b a' b' c' : lib R X
a✝ : Rel R X b' c'
h₂ : (liftAux R f) b' = (liftAux R f) c'
⊢ (liftAux R f) (a' * b') = (liftAux R f) (a' * c')

Next tactic:
case mul_left a' b' c' _ h₂ => simp only [liftAux_map_mul, h₂]
theorem liftAux_spec (f : X → L) (a b : lib R X) (h : FreeLieAlgebra.Rel R X a b) :
    liftAux R f a = liftAux R f b := by
  induction h
  case lie_self a' => simp only [liftAux_map_mul, NonUnitalAlgHom.map_zero, lie_self]
  case leibniz_lie a' b' c' =>
    simp only [liftAux_map_mul, liftAux_map_add, sub_add_cancel, lie_lie]
  case smul t a' b' _ h₂ => simp only [liftAux_map_smul, h₂]
  case add_right a' b' c' _ h₂ => simp only [liftAux_map_add, h₂]
  case mul_left a' b' c' _ h₂ => 

Proof state:
R : Type u
X : Type v
inst✝² : CommRing R
L : Type w
inst✝¹ : LieRing L
inst✝ : LieAlgebra R L
f : X → L
a b a' b' c' : lib R X
a✝ : Rel R X b' c'
h₂ : (liftAux R f) b' = (liftAux R f) c'
⊢ (liftAux R f) (a' * b') = (liftAux R f) (a' * c')

Next tactic:
simp only [liftAux_map_mul, h₂]
theorem liftAux_spec (f : X → L) (a b : lib R X) (h : FreeLieAlgebra.Rel R X a b) :
    liftAux R f a = liftAux R f b := by
  induction h
  case lie_self a' => simp only [liftAux_map_mul, NonUnitalAlgHom.map_zero, lie_self]
  case leibniz_lie a' b' c' =>
    simp only [liftAux_map_mul, liftAux_map_add, sub_add_cancel, lie_lie]
  case smul t a' b' _ h₂ => simp only [liftAux_map_smul, h₂]
  case add_right a' b' c' _ h₂ => simp only [liftAux_map_add, h₂]
  case mul_left a' b' c' _ h₂ => simp only [liftAux_map_mul, h₂]
  

Proof state:
case mul_right
R : Type u
X : Type v
inst✝² : CommRing R
L : Type w
inst✝¹ : LieRing L
inst✝ : LieAlgebra R L
f : X → L
a b a✝¹ b✝ c✝ : lib R X
a✝ : Rel R X a✝¹ b✝
a_ih✝ : (liftAux R f) a✝¹ = (liftAux R f) b✝
⊢ (liftAux R f) (a✝¹ * c✝) = (liftAux R f) (b✝ * c✝)

Next tactic:
case mul_right a' b' c' _ h₂ => simp only [liftAux_map_mul, h₂]
theorem liftAux_spec (f : X → L) (a b : lib R X) (h : FreeLieAlgebra.Rel R X a b) :
    liftAux R f a = liftAux R f b := by
  induction h
  case lie_self a' => simp only [liftAux_map_mul, NonUnitalAlgHom.map_zero, lie_self]
  case leibniz_lie a' b' c' =>
    simp only [liftAux_map_mul, liftAux_map_add, sub_add_cancel, lie_lie]
  case smul t a' b' _ h₂ => simp only [liftAux_map_smul, h₂]
  case add_right a' b' c' _ h₂ => simp only [liftAux_map_add, h₂]
  case mul_left a' b' c' _ h₂ => simp only [liftAux_map_mul, h₂]
  

Proof state:
R : Type u
X : Type v
inst✝² : CommRing R
L : Type w
inst✝¹ : LieRing L
inst✝ : LieAlgebra R L
f : X → L
a b a' b' c' : lib R X
a✝ : Rel R X a' b'
h₂ : (liftAux R f) a' = (liftAux R f) b'
⊢ (liftAux R f) (a' * c') = (liftAux R f) (b' * c')

Next tactic:
case mul_right a' b' c' _ h₂ => simp only [liftAux_map_mul, h₂]
theorem liftAux_spec (f : X → L) (a b : lib R X) (h : FreeLieAlgebra.Rel R X a b) :
    liftAux R f a = liftAux R f b := by
  induction h
  case lie_self a' => simp only [liftAux_map_mul, NonUnitalAlgHom.map_zero, lie_self]
  case leibniz_lie a' b' c' =>
    simp only [liftAux_map_mul, liftAux_map_add, sub_add_cancel, lie_lie]
  case smul t a' b' _ h₂ => simp only [liftAux_map_smul, h₂]
  case add_right a' b' c' _ h₂ => simp only [liftAux_map_add, h₂]
  case mul_left a' b' c' _ h₂ => simp only [liftAux_map_mul, h₂]
  case mul_right a' b' c' _ h₂ => 

Proof state:
R : Type u
X : Type v
inst✝² : CommRing R
L : Type w
inst✝¹ : LieRing L
inst✝ : LieAlgebra R L
f : X → L
a b a' b' c' : lib R X
a✝ : Rel R X a' b'
h₂ : (liftAux R f) a' = (liftAux R f) b'
⊢ (liftAux R f) (a' * c') = (liftAux R f) (b' * c')

Next tactic:
simp only [liftAux_map_mul, h₂]
/-- The functor `X ↦ FreeLieAlgebra R X` from the category of types to the category of Lie
algebras over `R` is adjoint to the forgetful functor in the other direction. -/
def lift : (X → L) ≃ (FreeLieAlgebra R X →ₗ⁅R⁆ L) where
  toFun f :=
    { toFun := fun c => Quot.liftOn c (liftAux R f) (liftAux_spec R f)
      map_add' := by 

Proof state:
R : Type u
X : Type v
inst✝² : CommRing R
L : Type w
inst✝¹ : LieRing L
inst✝ : LieAlgebra R L
f : X → L
⊢ ∀ (x y : FreeLieAlgebra R X),
    (fun c => Quot.liftOn c ⇑(liftAux R f) (_ : ∀ (a b : lib R X), Rel R X a b → (liftAux R f) a = (liftAux R f) b))
        (x + y) =
      (fun c => Quot.liftOn c ⇑(liftAux R f) (_ : ∀ (a b : lib R X), Rel R X a b → (liftAux R f) a = (liftAux R f) b))
          x +
        (fun c => Quot.liftOn c ⇑(liftAux R f) (_ : ∀ (a b : lib R X), Rel R X a b → (liftAux R f) a = (liftAux R f) b))
          y

Next tactic:
rintro ⟨a⟩ ⟨b⟩
/-- The functor `X ↦ FreeLieAlgebra R X` from the category of types to the category of Lie
algebras over `R` is adjoint to the forgetful functor in the other direction. -/
def lift : (X → L) ≃ (FreeLieAlgebra R X →ₗ⁅R⁆ L) where
  toFun f :=
    { toFun := fun c => Quot.liftOn c (liftAux R f) (liftAux_spec R f)
      map_add' := by rintro ⟨a⟩ ⟨b⟩; 

Proof state:
case mk.mk
R : Type u
X : Type v
inst✝² : CommRing R
L : Type w
inst✝¹ : LieRing L
inst✝ : LieAlgebra R L
f : X → L
x✝ : FreeLieAlgebra R X
a : lib R X
y✝ : FreeLieAlgebra R X
b : lib R X
⊢ (fun c => Quot.liftOn c ⇑(liftAux R f) (_ : ∀ (a b : lib R X), Rel R X a b → (liftAux R f) a = (liftAux R f) b))
      (Quot.mk (Rel R X) a + Quot.mk (Rel R X) b) =
    (fun c => Quot.liftOn c ⇑(liftAux R f) (_ : ∀ (a b : lib R X), Rel R X a b → (liftAux R f) a = (liftAux R f) b))
        (Quot.mk (Rel R X) a) +
      (fun c => Quot.liftOn c ⇑(liftAux R f) (_ : ∀ (a b : lib R X), Rel R X a b → (liftAux R f) a = (liftAux R f) b))
        (Quot.mk (Rel R X) b)

Next tactic:
rw [← liftAux_map_add]
/-- The functor `X ↦ FreeLieAlgebra R X` from the category of types to the category of Lie
algebras over `R` is adjoint to the forgetful functor in the other direction. -/
def lift : (X → L) ≃ (FreeLieAlgebra R X →ₗ⁅R⁆ L) where
  toFun f :=
    { toFun := fun c => Quot.liftOn c (liftAux R f) (liftAux_spec R f)
      map_add' := by rintro ⟨a⟩ ⟨b⟩; rw [← liftAux_map_add]; 

Proof state:
case mk.mk
R : Type u
X : Type v
inst✝² : CommRing R
L : Type w
inst✝¹ : LieRing L
inst✝ : LieAlgebra R L
f : X → L
x✝ : FreeLieAlgebra R X
a : lib R X
y✝ : FreeLieAlgebra R X
b : lib R X
⊢ (fun c => Quot.liftOn c ⇑(liftAux R f) (_ : ∀ (a b : lib R X), Rel R X a b → (liftAux R f) a = (liftAux R f) b))
      (Quot.mk (Rel R X) a + Quot.mk (Rel R X) b) =
    (liftAux R f) (a + b)

Next tactic:
rfl
/-- The functor `X ↦ FreeLieAlgebra R X` from the category of types to the category of Lie
algebras over `R` is adjoint to the forgetful functor in the other direction. -/
def lift : (X → L) ≃ (FreeLieAlgebra R X →ₗ⁅R⁆ L) where
  toFun f :=
    { toFun := fun c => Quot.liftOn c (liftAux R f) (liftAux_spec R f)
      map_add' := by rintro ⟨a⟩ ⟨b⟩; rw [← liftAux_map_add]; rfl
      map_smul' := by 

Proof state:
R : Type u
X : Type v
inst✝² : CommRing R
L : Type w
inst✝¹ : LieRing L
inst✝ : LieAlgebra R L
f : X → L
⊢ ∀ (r : R) (x : FreeLieAlgebra R X),
    AddHom.toFun
        {
          toFun := fun c =>
            Quot.liftOn c ⇑(liftAux R f) (_ : ∀ (a b : lib R X), Rel R X a b → (liftAux R f) a = (liftAux R f) b),
          map_add' :=
            (_ :
              ∀ (x y : FreeLieAlgebra R X),
                (fun c =>
                      Quot.liftOn c ⇑(liftAux R f)
                        (_ : ∀ (a b : lib R X), Rel R X a b → (liftAux R f) a = (liftAux R f) b))
                    (x + y) =
                  (fun c =>
                        Quot.liftOn c ⇑(liftAux R f)
                          (_ : ∀ (a b : lib R X), Rel R X a b → (liftAux R f) a = (liftAux R f) b))
                      x +
                    (fun c =>
                        Quot.liftOn c ⇑(liftAux R f)
                          (_ : ∀ (a b : lib R X), Rel R X a b → (liftAux R f) a = (liftAux R f) b))
                      y) }
        (r • x) =
      (RingHom.id R) r •
        AddHom.toFun
          {
            toFun := fun c =>
              Quot.liftOn c ⇑(liftAux R f) (_ : ∀ (a b : lib R X), Rel R X a b → (liftAux R f) a = (liftAux R f) b),
            map_add' :=
              (_ :
                ∀ (x y : FreeLieAlgebra R X),
                  (fun c =>
                        Quot.liftOn c ⇑(liftAux R f)
                          (_ : ∀ (a b : lib R X), Rel R X a b → (liftAux R f) a = (liftAux R f) b))
                      (x + y) =
                    (fun c =>
                          Quot.liftOn c ⇑(liftAux R f)
                            (_ : ∀ (a b : lib R X), Rel R X a b → (liftAux R f) a = (liftAux R f) b))
                        x +
                      (fun c =>
                          Quot.liftOn c ⇑(liftAux R f)
                            (_ : ∀ (a b : lib R X), Rel R X a b → (liftAux R f) a = (liftAux R f) b))
                        y) }
          x

Next tactic:
rintro t ⟨a⟩
/-- The functor `X ↦ FreeLieAlgebra R X` from the category of types to the category of Lie
algebras over `R` is adjoint to the forgetful functor in the other direction. -/
def lift : (X → L) ≃ (FreeLieAlgebra R X →ₗ⁅R⁆ L) where
  toFun f :=
    { toFun := fun c => Quot.liftOn c (liftAux R f) (liftAux_spec R f)
      map_add' := by rintro ⟨a⟩ ⟨b⟩; rw [← liftAux_map_add]; rfl
      map_smul' := by rintro t ⟨a⟩; 

Proof state:
case mk
R : Type u
X : Type v
inst✝² : CommRing R
L : Type w
inst✝¹ : LieRing L
inst✝ : LieAlgebra R L
f : X → L
t : R
x✝ : FreeLieAlgebra R X
a : lib R X
⊢ AddHom.toFun
      {
        toFun := fun c =>
          Quot.liftOn c ⇑(liftAux R f) (_ : ∀ (a b : lib R X), Rel R X a b → (liftAux R f) a = (liftAux R f) b),
        map_add' :=
          (_ :
            ∀ (x y : FreeLieAlgebra R X),
              (fun c =>
                    Quot.liftOn c ⇑(liftAux R f)
                      (_ : ∀ (a b : lib R X), Rel R X a b → (liftAux R f) a = (liftAux R f) b))
                  (x + y) =
                (fun c =>
                      Quot.liftOn c ⇑(liftAux R f)
                        (_ : ∀ (a b : lib R X), Rel R X a b → (liftAux R f) a = (liftAux R f) b))
                    x +
                  (fun c =>
                      Quot.liftOn c ⇑(liftAux R f)
                        (_ : ∀ (a b : lib R X), Rel R X a b → (liftAux R f) a = (liftAux R f) b))
                    y) }
      (t • Quot.mk (Rel R X) a) =
    (RingHom.id R) t •
      AddHom.toFun
        {
          toFun := fun c =>
            Quot.liftOn c ⇑(liftAux R f) (_ : ∀ (a b : lib R X), Rel R X a b → (liftAux R f) a = (liftAux R f) b),
          map_add' :=
            (_ :
              ∀ (x y : FreeLieAlgebra R X),
                (fun c =>
                      Quot.liftOn c ⇑(liftAux R f)
                        (_ : ∀ (a b : lib R X), Rel R X a b → (liftAux R f) a = (liftAux R f) b))
                    (x + y) =
                  (fun c =>
                        Quot.liftOn c ⇑(liftAux R f)
                          (_ : ∀ (a b : lib R X), Rel R X a b → (liftAux R f) a = (liftAux R f) b))
                      x +
                    (fun c =>
                        Quot.liftOn c ⇑(liftAux R f)
                          (_ : ∀ (a b : lib R X), Rel R X a b → (liftAux R f) a = (liftAux R f) b))
                      y) }
        (Quot.mk (Rel R X) a)

Next tactic:
rw [← liftAux_map_smul]
/-- The functor `X ↦ FreeLieAlgebra R X` from the category of types to the category of Lie
algebras over `R` is adjoint to the forgetful functor in the other direction. -/
def lift : (X → L) ≃ (FreeLieAlgebra R X →ₗ⁅R⁆ L) where
  toFun f :=
    { toFun := fun c => Quot.liftOn c (liftAux R f) (liftAux_spec R f)
      map_add' := by rintro ⟨a⟩ ⟨b⟩; rw [← liftAux_map_add]; rfl
      map_smul' := by rintro t ⟨a⟩; rw [← liftAux_map_smul]; 

Proof state:
case mk
R : Type u
X : Type v
inst✝² : CommRing R
L : Type w
inst✝¹ : LieRing L
inst✝ : LieAlgebra R L
f : X → L
t : R
x✝ : FreeLieAlgebra R X
a : lib R X
⊢ AddHom.toFun
      {
        toFun := fun c =>
          Quot.liftOn c ⇑(liftAux R f) (_ : ∀ (a b : lib R X), Rel R X a b → (liftAux R f) a = (liftAux R f) b),
        map_add' :=
          (_ :
            ∀ (x y : FreeLieAlgebra R X),
              (fun c =>
                    Quot.liftOn c ⇑(liftAux R f)
                      (_ : ∀ (a b : lib R X), Rel R X a b → (liftAux R f) a = (liftAux R f) b))
                  (x + y) =
                (fun c =>
                      Quot.liftOn c ⇑(liftAux R f)
                        (_ : ∀ (a b : lib R X), Rel R X a b → (liftAux R f) a = (liftAux R f) b))
                    x +
                  (fun c =>
                      Quot.liftOn c ⇑(liftAux R f)
                        (_ : ∀ (a b : lib R X), Rel R X a b → (liftAux R f) a = (liftAux R f) b))
                    y) }
      (t • Quot.mk (Rel R X) a) =
    (liftAux R f) ((RingHom.id R) t • a)

Next tactic:
rfl
@[simp]
theorem lift_of_apply (f : X → L) (x) : lift R f (of R x) = f x := by
  

Proof state:
R : Type u
X : Type v
inst✝² : CommRing R
L : Type w
inst✝¹ : LieRing L
inst✝ : LieAlgebra R L
f : X → L
x : X
⊢ ((lift R) f) (of R x) = f x

Next tactic:
rw [← @Function.comp_apply _ _ _ (lift R f) (of R) x, of_comp_lift]
@[simp]
theorem lift_comp_of (F : FreeLieAlgebra R X →ₗ⁅R⁆ L) : lift R (F ∘ of R) = F := by
  

Proof state:
R : Type u
X : Type v
inst✝² : CommRing R
L : Type w
inst✝¹ : LieRing L
inst✝ : LieAlgebra R L
F : FreeLieAlgebra R X →ₗ⁅R⁆ L
⊢ (lift R) (⇑F ∘ of R) = F

Next tactic:
rw [← lift_symm_apply]
@[simp]
theorem lift_comp_of (F : FreeLieAlgebra R X →ₗ⁅R⁆ L) : lift R (F ∘ of R) = F := by
  rw [← lift_symm_apply]; 

Proof state:
R : Type u
X : Type v
inst✝² : CommRing R
L : Type w
inst✝¹ : LieRing L
inst✝ : LieAlgebra R L
F : FreeLieAlgebra R X →ₗ⁅R⁆ L
⊢ (lift R) ((lift R).symm F) = F

Next tactic:
exact (lift R).apply_symm_apply F
@[ext]
theorem hom_ext {F₁ F₂ : FreeLieAlgebra R X →ₗ⁅R⁆ L} (h : ∀ x, F₁ (of R x) = F₂ (of R x)) :
    F₁ = F₂ :=
  have h' : (lift R).symm F₁ = (lift R).symm F₂ := by 

Proof state:
R : Type u
X : Type v
inst✝² : CommRing R
L : Type w
inst✝¹ : LieRing L
inst✝ : LieAlgebra R L
F₁ F₂ : FreeLieAlgebra R X →ₗ⁅R⁆ L
h : ∀ (x : X), F₁ (of R x) = F₂ (of R x)
⊢ (lift R).symm F₁ = (lift R).symm F₂

Next tactic:
ext
@[ext]
theorem hom_ext {F₁ F₂ : FreeLieAlgebra R X →ₗ⁅R⁆ L} (h : ∀ x, F₁ (of R x) = F₂ (of R x)) :
    F₁ = F₂ :=
  have h' : (lift R).symm F₁ = (lift R).symm F₂ := by ext; 

Proof state:
case h
R : Type u
X : Type v
inst✝² : CommRing R
L : Type w
inst✝¹ : LieRing L
inst✝ : LieAlgebra R L
F₁ F₂ : FreeLieAlgebra R X →ₗ⁅R⁆ L
h : ∀ (x : X), F₁ (of R x) = F₂ (of R x)
x✝ : X
⊢ (lift R).symm F₁ x✝ = (lift R).symm F₂ x✝

Next tactic:
simp [h]
/-- The universal enveloping algebra of the free Lie algebra is just the free unital associative
algebra. -/
@[simps!]
def universalEnvelopingEquivFreeAlgebra :
    UniversalEnvelopingAlgebra R (FreeLieAlgebra R X) ≃ₐ[R] FreeAlgebra R X :=
  AlgEquiv.ofAlgHom (UniversalEnvelopingAlgebra.lift R <| FreeLieAlgebra.lift R <| FreeAlgebra.ι R)
    (FreeAlgebra.lift R <| UniversalEnvelopingAlgebra.ι R ∘ FreeLieAlgebra.of R) (by 

Proof state:
R : Type u
X : Type v
inst✝² : CommRing R
L : Type w
inst✝¹ : LieRing L
inst✝ : LieAlgebra R L
⊢ AlgHom.comp ((UniversalEnvelopingAlgebra.lift R) ((lift R) (FreeAlgebra.ι R)))
      ((FreeAlgebra.lift R) (⇑(UniversalEnvelopingAlgebra.ι R) ∘ of R)) =
    AlgHom.id R (FreeAlgebra R X)

Next tactic:
ext
/-- The universal enveloping algebra of the free Lie algebra is just the free unital associative
algebra. -/
@[simps!]
def universalEnvelopingEquivFreeAlgebra :
    UniversalEnvelopingAlgebra R (FreeLieAlgebra R X) ≃ₐ[R] FreeAlgebra R X :=
  AlgEquiv.ofAlgHom (UniversalEnvelopingAlgebra.lift R <| FreeLieAlgebra.lift R <| FreeAlgebra.ι R)
    (FreeAlgebra.lift R <| UniversalEnvelopingAlgebra.ι R ∘ FreeLieAlgebra.of R) (by ext; 

Proof state:
case w.h
R : Type u
X : Type v
inst✝² : CommRing R
L : Type w
inst✝¹ : LieRing L
inst✝ : LieAlgebra R L
x✝ : X
⊢ (⇑(AlgHom.comp ((UniversalEnvelopingAlgebra.lift R) ((lift R) (FreeAlgebra.ι R)))
            ((FreeAlgebra.lift R) (⇑(UniversalEnvelopingAlgebra.ι R) ∘ of R))) ∘
        FreeAlgebra.ι R)
      x✝ =
    (⇑(AlgHom.id R (FreeAlgebra R X)) ∘ FreeAlgebra.ι R) x✝

Next tactic:
simp
/-- The universal enveloping algebra of the free Lie algebra is just the free unital associative
algebra. -/
@[simps!]
def universalEnvelopingEquivFreeAlgebra :
    UniversalEnvelopingAlgebra R (FreeLieAlgebra R X) ≃ₐ[R] FreeAlgebra R X :=
  AlgEquiv.ofAlgHom (UniversalEnvelopingAlgebra.lift R <| FreeLieAlgebra.lift R <| FreeAlgebra.ι R)
    (FreeAlgebra.lift R <| UniversalEnvelopingAlgebra.ι R ∘ FreeLieAlgebra.of R) (by ext; simp)
    (by 

Proof state:
R : Type u
X : Type v
inst✝² : CommRing R
L : Type w
inst✝¹ : LieRing L
inst✝ : LieAlgebra R L
⊢ AlgHom.comp ((FreeAlgebra.lift R) (⇑(UniversalEnvelopingAlgebra.ι R) ∘ of R))
      ((UniversalEnvelopingAlgebra.lift R) ((lift R) (FreeAlgebra.ι R))) =
    AlgHom.id R (UniversalEnvelopingAlgebra R (FreeLieAlgebra R X))

Next tactic:
ext
/-- The universal enveloping algebra of the free Lie algebra is just the free unital associative
algebra. -/
@[simps!]
def universalEnvelopingEquivFreeAlgebra :
    UniversalEnvelopingAlgebra R (FreeLieAlgebra R X) ≃ₐ[R] FreeAlgebra R X :=
  AlgEquiv.ofAlgHom (UniversalEnvelopingAlgebra.lift R <| FreeLieAlgebra.lift R <| FreeAlgebra.ι R)
    (FreeAlgebra.lift R <| UniversalEnvelopingAlgebra.ι R ∘ FreeLieAlgebra.of R) (by ext; simp)
    (by ext; 

Proof state:
case h.h
R : Type u
X : Type v
inst✝² : CommRing R
L : Type w
inst✝¹ : LieRing L
inst✝ : LieAlgebra R L
x✝ : X
⊢ (LieHom.comp
        (AlgHom.toLieHom
          (AlgHom.comp ((FreeAlgebra.lift R) (⇑(UniversalEnvelopingAlgebra.ι R) ∘ of R))
            ((UniversalEnvelopingAlgebra.lift R) ((lift R) (FreeAlgebra.ι R)))))
        (UniversalEnvelopingAlgebra.ι R))
      (of R x✝) =
    (LieHom.comp (AlgHom.toLieHom (AlgHom.id R (UniversalEnvelopingAlgebra R (FreeLieAlgebra R X))))
        (UniversalEnvelopingAlgebra.ι R))
      (of R x✝)

Next tactic:
simp
/-- Prepend an element to a sequence -/
def cons (a : α) (s : Seq α) : Seq α :=
  ⟨some a::s.1, by
    

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
s : Seq α
⊢ IsSeq (some a :: ↑s)

Next tactic:
rintro (n | _) h
/-- Prepend an element to a sequence -/
def cons (a : α) (s : Seq α) : Seq α :=
  ⟨some a::s.1, by
    rintro (n | _) h
    · 

Proof state:
case zero
α : Type u
β : Type v
γ : Type w
a : α
s : Seq α
h : (some a :: ↑s) Nat.zero = none
⊢ (some a :: ↑s) (Nat.zero + 1) = none

Next tactic:
contradiction
/-- Prepend an element to a sequence -/
def cons (a : α) (s : Seq α) : Seq α :=
  ⟨some a::s.1, by
    rintro (n | _) h
    · contradiction
    · 

Proof state:
case succ
α : Type u
β : Type v
γ : Type w
a : α
s : Seq α
n✝ : ℕ
h : (some a :: ↑s) (Nat.succ n✝) = none
⊢ (some a :: ↑s) (Nat.succ n✝ + 1) = none

Next tactic:
exact s.2 h
theorem cons_injective2 : Function.Injective2 (cons : α → Seq α → Seq α) := fun x y s t h =>
  ⟨by 

Proof state:
α : Type u
β : Type v
γ : Type w
x y : α
s t : Seq α
h : cons x s = cons y t
⊢ x = y

Next tactic:
rw [← Option.some_inj, ← get?_cons_zero, h, get?_cons_zero]
theorem cons_injective2 : Function.Injective2 (cons : α → Seq α → Seq α) := fun x y s t h =>
  ⟨by rw [← Option.some_inj, ← get?_cons_zero, h, get?_cons_zero],
    Seq.ext fun n => by 

Proof state:
α : Type u
β : Type v
γ : Type w
x y : α
s t : Seq α
h : cons x s = cons y t
n : ℕ
⊢ get? s n = get? t n

Next tactic:
simp_rw [← get?_cons_succ x s n, h, get?_cons_succ]
/-- It is decidable whether a sequence terminates at a given position. -/
instance terminatedAtDecidable (s : Seq α) (n : ℕ) : Decidable (s.TerminatedAt n) :=
  decidable_of_iff' (s.get? n).isNone <| by 

Proof state:
α : Type u
β : Type v
γ : Type w
s : Seq α
n : ℕ
⊢ TerminatedAt s n ↔ Option.isNone (get? s n) = true

Next tactic:
unfold TerminatedAt
/-- It is decidable whether a sequence terminates at a given position. -/
instance terminatedAtDecidable (s : Seq α) (n : ℕ) : Decidable (s.TerminatedAt n) :=
  decidable_of_iff' (s.get? n).isNone <| by unfold TerminatedAt; 

Proof state:
α : Type u
β : Type v
γ : Type w
s : Seq α
n : ℕ
⊢ get? s n = none ↔ Option.isNone (get? s n) = true

Next tactic:
cases s.get? n
/-- It is decidable whether a sequence terminates at a given position. -/
instance terminatedAtDecidable (s : Seq α) (n : ℕ) : Decidable (s.TerminatedAt n) :=
  decidable_of_iff' (s.get? n).isNone <| by unfold TerminatedAt; cases s.get? n <;> 

Proof state:
case none
α : Type u
β : Type v
γ : Type w
s : Seq α
n : ℕ
⊢ none = none ↔ Option.isNone none = true

Next tactic:
simp
/-- It is decidable whether a sequence terminates at a given position. -/
instance terminatedAtDecidable (s : Seq α) (n : ℕ) : Decidable (s.TerminatedAt n) :=
  decidable_of_iff' (s.get? n).isNone <| by unfold TerminatedAt; cases s.get? n <;> 

Proof state:
case some
α : Type u
β : Type v
γ : Type w
s : Seq α
n : ℕ
val✝ : α
⊢ some val✝ = none ↔ Option.isNone (some val✝) = true

Next tactic:
simp
theorem not_terminates_iff {s : Seq α} : ¬s.Terminates ↔ ∀ n, (s.get? n).isSome := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
s : Seq α
⊢ ¬Terminates s ↔ ∀ (n : ℕ), Option.isSome (get? s n) = true

Next tactic:
simp only [Terminates, TerminatedAt, ← Ne.def, Option.ne_none_iff_isSome, not_exists, iff_self]
/-- Get the tail of a sequence (or `nil` if the sequence is `nil`) -/
def tail (s : Seq α) : Seq α :=
  ⟨s.1.tail, fun n' => by
    

Proof state:
α : Type u
β : Type v
γ : Type w
s : Seq α
n✝ : ℕ
n' : Stream'.tail (↑s) n✝ = none
⊢ Stream'.tail (↑s) (n✝ + 1) = none

Next tactic:
cases' s with f al
/-- Get the tail of a sequence (or `nil` if the sequence is `nil`) -/
def tail (s : Seq α) : Seq α :=
  ⟨s.1.tail, fun n' => by
    cases' s with f al
    

Proof state:
case mk
α : Type u
β : Type v
γ : Type w
n✝ : ℕ
f : Stream' (Option α)
al : IsSeq f
n' : Stream'.tail (↑{ val := f, property := al }) n✝ = none
⊢ Stream'.tail (↑{ val := f, property := al }) (n✝ + 1) = none

Next tactic:
exact al n'