l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem toList_eq_self {xs : List α} : toList xs = xs := by
  

Proof state:
α β γ : Type u
t : Type u → Type u
inst✝¹ : Traversable t
inst✝ : LawfulTraversable t
xs : List α
⊢ toList xs = xs

Next tactic:
simp only [toList_spec, foldMap, traverse]
@[simp]
theorem toList_eq_self {xs : List α} : toList xs = xs := by
  simp only [toList_spec, foldMap, traverse]
  

Proof state:
α β γ : Type u
t : Type u → Type u
inst✝¹ : Traversable t
inst✝ : LawfulTraversable t
xs : List α
⊢ FreeMonoid.toList (List.traverse (Const.mk' ∘ FreeMonoid.of) xs) = xs

Next tactic:
induction xs
@[simp]
theorem toList_eq_self {xs : List α} : toList xs = xs := by
  simp only [toList_spec, foldMap, traverse]
  induction xs
  

Proof state:
case nil
α β γ : Type u
t : Type u → Type u
inst✝¹ : Traversable t
inst✝ : LawfulTraversable t
⊢ FreeMonoid.toList (List.traverse (Const.mk' ∘ FreeMonoid.of) []) = []
case cons
α β γ : Type u
t : Type u → Type u
inst✝¹ : Traversable t
inst✝ : LawfulTraversable t
head✝ : α
tail✝ : List α
tail_ih✝ : FreeMonoid.toList (List.traverse (Const.mk' ∘ FreeMonoid.of) tail✝) = tail✝
⊢ FreeMonoid.toList (List.traverse (Const.mk' ∘ FreeMonoid.of) (head✝ :: tail✝)) = head✝ :: tail✝

Next tactic:
case nil => rfl
@[simp]
theorem toList_eq_self {xs : List α} : toList xs = xs := by
  simp only [toList_spec, foldMap, traverse]
  induction xs
  

Proof state:
α β γ : Type u
t : Type u → Type u
inst✝¹ : Traversable t
inst✝ : LawfulTraversable t
⊢ FreeMonoid.toList (List.traverse (Const.mk' ∘ FreeMonoid.of) []) = []

Next tactic:
case nil => rfl
@[simp]
theorem toList_eq_self {xs : List α} : toList xs = xs := by
  simp only [toList_spec, foldMap, traverse]
  induction xs
  case nil => 

Proof state:
α β γ : Type u
t : Type u → Type u
inst✝¹ : Traversable t
inst✝ : LawfulTraversable t
⊢ FreeMonoid.toList (List.traverse (Const.mk' ∘ FreeMonoid.of) []) = []

Next tactic:
rfl
@[simp]
theorem toList_eq_self {xs : List α} : toList xs = xs := by
  simp only [toList_spec, foldMap, traverse]
  induction xs
  case nil => rfl
  

Proof state:
case cons
α β γ : Type u
t : Type u → Type u
inst✝¹ : Traversable t
inst✝ : LawfulTraversable t
head✝ : α
tail✝ : List α
tail_ih✝ : FreeMonoid.toList (List.traverse (Const.mk' ∘ FreeMonoid.of) tail✝) = tail✝
⊢ FreeMonoid.toList (List.traverse (Const.mk' ∘ FreeMonoid.of) (head✝ :: tail✝)) = head✝ :: tail✝

Next tactic:
case cons _ _ ih => conv_rhs => rw [← ih]; rfl
@[simp]
theorem toList_eq_self {xs : List α} : toList xs = xs := by
  simp only [toList_spec, foldMap, traverse]
  induction xs
  case nil => rfl
  

Proof state:
α β γ : Type u
t : Type u → Type u
inst✝¹ : Traversable t
inst✝ : LawfulTraversable t
head✝ : α
tail✝ : List α
ih : FreeMonoid.toList (List.traverse (Const.mk' ∘ FreeMonoid.of) tail✝) = tail✝
⊢ FreeMonoid.toList (List.traverse (Const.mk' ∘ FreeMonoid.of) (head✝ :: tail✝)) = head✝ :: tail✝

Next tactic:
case cons _ _ ih => conv_rhs => rw [← ih]; rfl
@[simp]
theorem toList_eq_self {xs : List α} : toList xs = xs := by
  simp only [toList_spec, foldMap, traverse]
  induction xs
  case nil => rfl
  case cons _ _ ih => 

Proof state:
α β γ : Type u
t : Type u → Type u
inst✝¹ : Traversable t
inst✝ : LawfulTraversable t
head✝ : α
tail✝ : List α
ih : FreeMonoid.toList (List.traverse (Const.mk' ∘ FreeMonoid.of) tail✝) = tail✝
⊢ FreeMonoid.toList (List.traverse (Const.mk' ∘ FreeMonoid.of) (head✝ :: tail✝)) = head✝ :: tail✝

Next tactic:
conv_rhs => rw [← ih]; rfl
@[simp]
theorem toList_eq_self {xs : List α} : toList xs = xs := by
  simp only [toList_spec, foldMap, traverse]
  induction xs
  case nil => rfl
  case cons _ _ ih => conv_rhs => 

Proof state:
α β γ : Type u
t : Type u → Type u
inst✝¹ : Traversable t
inst✝ : LawfulTraversable t
head✝ : α
tail✝ : List α
ih : FreeMonoid.toList (List.traverse (Const.mk' ∘ FreeMonoid.of) tail✝) = tail✝
| head✝ :: tail✝

Next tactic:
rw [← ih]; rfl
@[simp]
theorem toList_eq_self {xs : List α} : toList xs = xs := by
  simp only [toList_spec, foldMap, traverse]
  induction xs
  case nil => rfl
  case cons _ _ ih => conv_rhs => 

Proof state:
α β γ : Type u
t : Type u → Type u
inst✝¹ : Traversable t
inst✝ : LawfulTraversable t
head✝ : α
tail✝ : List α
ih : FreeMonoid.toList (List.traverse (Const.mk' ∘ FreeMonoid.of) tail✝) = tail✝
| head✝ :: tail✝

Next tactic:
rw [← ih]
@[simp]
theorem toList_eq_self {xs : List α} : toList xs = xs := by
  simp only [toList_spec, foldMap, traverse]
  induction xs
  case nil => rfl
  case cons _ _ ih => conv_rhs => rw [← ih]; 

Proof state:
α β γ : Type u
t : Type u → Type u
inst✝¹ : Traversable t
inst✝ : LawfulTraversable t
head✝ : α
tail✝ : List α
ih : FreeMonoid.toList (List.traverse (Const.mk' ∘ FreeMonoid.of) tail✝) = tail✝
| head✝ :: FreeMonoid.toList (List.traverse (Const.mk' ∘ FreeMonoid.of) tail✝)

Next tactic:
rfl
theorem length_toList {xs : t α} : length xs = List.length (toList xs) := by
  

Proof state:
α β γ : Type u
t : Type u → Type u
inst✝¹ : Traversable t
inst✝ : LawfulTraversable t
xs : t α
⊢ length xs = List.length (toList xs)

Next tactic:
unfold length
theorem length_toList {xs : t α} : length xs = List.length (toList xs) := by
  unfold length
  

Proof state:
α β γ : Type u
t : Type u → Type u
inst✝¹ : Traversable t
inst✝ : LawfulTraversable t
xs : t α
⊢ (foldl (fun l x => { down := l.down + 1 }) { down := 0 } xs).down = List.length (toList xs)

Next tactic:
rw [foldl_toList]
theorem length_toList {xs : t α} : length xs = List.length (toList xs) := by
  unfold length
  rw [foldl_toList]
  

Proof state:
α β γ : Type u
t : Type u → Type u
inst✝¹ : Traversable t
inst✝ : LawfulTraversable t
xs : t α
⊢ (List.foldl (fun l x => { down := l.down + 1 }) { down := 0 } (toList xs)).down = List.length (toList xs)

Next tactic:
generalize toList xs = ys
theorem length_toList {xs : t α} : length xs = List.length (toList xs) := by
  unfold length
  rw [foldl_toList]
  generalize toList xs = ys
  

Proof state:
α β γ : Type u
t : Type u → Type u
inst✝¹ : Traversable t
inst✝ : LawfulTraversable t
xs : t α
ys : List α
⊢ (List.foldl (fun l x => { down := l.down + 1 }) { down := 0 } ys).down = List.length ys

Next tactic:
rw [← Nat.add_zero ys.length]
theorem length_toList {xs : t α} : length xs = List.length (toList xs) := by
  unfold length
  rw [foldl_toList]
  generalize toList xs = ys
  rw [← Nat.add_zero ys.length]
  

Proof state:
α β γ : Type u
t : Type u → Type u
inst✝¹ : Traversable t
inst✝ : LawfulTraversable t
xs : t α
ys : List α
⊢ (List.foldl (fun l x => { down := l.down + 1 }) { down := 0 } ys).down = List.length ys + 0

Next tactic:
generalize 0 = n
theorem length_toList {xs : t α} : length xs = List.length (toList xs) := by
  unfold length
  rw [foldl_toList]
  generalize toList xs = ys
  rw [← Nat.add_zero ys.length]
  generalize 0 = n
  

Proof state:
α β γ : Type u
t : Type u → Type u
inst✝¹ : Traversable t
inst✝ : LawfulTraversable t
xs : t α
ys : List α
n : ℕ
⊢ (List.foldl (fun l x => { down := l.down + 1 }) { down := n } ys).down = List.length ys + n

Next tactic:
induction' ys with _ _ ih generalizing n
theorem length_toList {xs : t α} : length xs = List.length (toList xs) := by
  unfold length
  rw [foldl_toList]
  generalize toList xs = ys
  rw [← Nat.add_zero ys.length]
  generalize 0 = n
  induction' ys with _ _ ih generalizing n
  · 

Proof state:
case nil
α β γ : Type u
t : Type u → Type u
inst✝¹ : Traversable t
inst✝ : LawfulTraversable t
xs : t α
n : ℕ
⊢ (List.foldl (fun l x => { down := l.down + 1 }) { down := n } []).down = List.length [] + n

Next tactic:
simp
theorem length_toList {xs : t α} : length xs = List.length (toList xs) := by
  unfold length
  rw [foldl_toList]
  generalize toList xs = ys
  rw [← Nat.add_zero ys.length]
  generalize 0 = n
  induction' ys with _ _ ih generalizing n
  · simp
  · 

Proof state:
case cons
α β γ : Type u
t : Type u → Type u
inst✝¹ : Traversable t
inst✝ : LawfulTraversable t
xs : t α
head✝ : α
tail✝ : List α
ih : ∀ (n : ℕ), (List.foldl (fun l x => { down := l.down + 1 }) { down := n } tail✝).down = List.length tail✝ + n
n : ℕ
⊢ (List.foldl (fun l x => { down := l.down + 1 }) { down := n } (head✝ :: tail✝)).down =
    List.length (head✝ :: tail✝) + n

Next tactic:
simp_arith [ih]
theorem foldlm_toList {f : α → β → m α} {x : α} {xs : t β} :
    foldlm f x xs = List.foldlM f x (toList xs) :=
  calc
    foldlm f x xs = unop (foldlM.ofFreeMonoid f (FreeMonoid.ofList <| toList xs)) x :=
    by 

Proof state:
α β γ : Type u
t : Type u → Type u
inst✝³ : Traversable t
inst✝² : LawfulTraversable t
m : Type u → Type u
inst✝¹ : Monad m
inst✝ : LawfulMonad m
f : α → β → m α
x : α
xs : t β
⊢ foldlm f x xs = unop ((foldlM.ofFreeMonoid f) (FreeMonoid.ofList (toList xs))) x

Next tactic:
simp only [foldlm, toList_spec, foldMap_hom_free (foldlM.ofFreeMonoid f),
        foldlm.ofFreeMonoid_comp_of, foldlM.get, FreeMonoid.ofList_toList]
theorem foldlm_toList {f : α → β → m α} {x : α} {xs : t β} :
    foldlm f x xs = List.foldlM f x (toList xs) :=
  calc
    foldlm f x xs = unop (foldlM.ofFreeMonoid f (FreeMonoid.ofList <| toList xs)) x :=
    by simp only [foldlm, toList_spec, foldMap_hom_free (foldlM.ofFreeMonoid f),
        foldlm.ofFreeMonoid_comp_of, foldlM.get, FreeMonoid.ofList_toList]
    _ = List.foldlM f x (toList xs) := by 

Proof state:
α β γ : Type u
t : Type u → Type u
inst✝³ : Traversable t
inst✝² : LawfulTraversable t
m : Type u → Type u
inst✝¹ : Monad m
inst✝ : LawfulMonad m
f : α → β → m α
x : α
xs : t β
⊢ unop ((foldlM.ofFreeMonoid f) (FreeMonoid.ofList (toList xs))) x = List.foldlM f x (toList xs)

Next tactic:
simp [foldlM.ofFreeMonoid, unop_op, flip]
theorem foldrm_toList (f : α → β → m β) (x : β) (xs : t α) :
    foldrm f x xs = List.foldrM f x (toList xs) := by
  

Proof state:
α β γ : Type u
t : Type u → Type u
inst✝³ : Traversable t
inst✝² : LawfulTraversable t
m : Type u → Type u
inst✝¹ : Monad m
inst✝ : LawfulMonad m
f : α → β → m β
x : β
xs : t α
⊢ foldrm f x xs = List.foldrM f x (toList xs)

Next tactic:
change _ = foldrM.ofFreeMonoid f (FreeMonoid.ofList <| toList xs) x
theorem foldrm_toList (f : α → β → m β) (x : β) (xs : t α) :
    foldrm f x xs = List.foldrM f x (toList xs) := by
  change _ = foldrM.ofFreeMonoid f (FreeMonoid.ofList <| toList xs) x
  

Proof state:
α β γ : Type u
t : Type u → Type u
inst✝³ : Traversable t
inst✝² : LawfulTraversable t
m : Type u → Type u
inst✝¹ : Monad m
inst✝ : LawfulMonad m
f : α → β → m β
x : β
xs : t α
⊢ foldrm f x xs = (foldrM.ofFreeMonoid f) (FreeMonoid.ofList (toList xs)) x

Next tactic:
simp only [foldrm, toList_spec, foldMap_hom_free (foldrM.ofFreeMonoid f),
    foldrm.ofFreeMonoid_comp_of, foldrM.get, FreeMonoid.ofList_toList]
@[simp]
theorem foldlm_map (g : β → γ) (f : α → γ → m α) (a : α) (l : t β) :
    foldlm f a (g <$> l) = foldlm (fun x y => f x (g y)) a l := by
  

Proof state:
α β γ : Type u
t : Type u → Type u
inst✝³ : Traversable t
inst✝² : LawfulTraversable t
m : Type u → Type u
inst✝¹ : Monad m
inst✝ : LawfulMonad m
g : β → γ
f : α → γ → m α
a : α
l : t β
⊢ foldlm f a (g <$> l) = foldlm (fun x y => f x (g y)) a l

Next tactic:
simp only [foldlm, foldMap_map, (· ∘ ·), flip]
@[simp]
theorem foldrm_map (g : β → γ) (f : γ → α → m α) (a : α) (l : t β) :
    foldrm f a (g <$> l) = foldrm (f ∘ g) a l := by 

Proof state:
α β γ : Type u
t : Type u → Type u
inst✝³ : Traversable t
inst✝² : LawfulTraversable t
m : Type u → Type u
inst✝¹ : Monad m
inst✝ : LawfulMonad m
g : β → γ
f : γ → α → m α
a : α
l : t β
⊢ foldrm f a (g <$> l) = foldrm (f ∘ g) a l

Next tactic:
simp only [foldrm, foldMap_map, (· ∘ ·), flip]
/-- The ring isomorphism between multivariable polynomials in a single variable and
polynomials over the ground ring.
-/
@[simps]
def pUnitAlgEquiv : MvPolynomial PUnit R ≃ₐ[R] R[X] where
  toFun := eval₂ Polynomial.C fun _ => Polynomial.X
  invFun := Polynomial.eval₂ MvPolynomial.C (X PUnit.unit)
  left_inv := by
    

Proof state:
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
s : σ →₀ ℕ
inst✝ : CommSemiring R
⊢ LeftInverse (Polynomial.eval₂ C (X PUnit.unit)) (eval₂ Polynomial.C fun x => Polynomial.X)

Next tactic:
let f : R[X] →+* MvPolynomial PUnit R := Polynomial.eval₂RingHom MvPolynomial.C (X PUnit.unit)
/-- The ring isomorphism between multivariable polynomials in a single variable and
polynomials over the ground ring.
-/
@[simps]
def pUnitAlgEquiv : MvPolynomial PUnit R ≃ₐ[R] R[X] where
  toFun := eval₂ Polynomial.C fun _ => Polynomial.X
  invFun := Polynomial.eval₂ MvPolynomial.C (X PUnit.unit)
  left_inv := by
    let f : R[X] →+* MvPolynomial PUnit R := Polynomial.eval₂RingHom MvPolynomial.C (X PUnit.unit)
    

Proof state:
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
s : σ →₀ ℕ
inst✝ : CommSemiring R
f : R[X] →+* MvPolynomial PUnit.{?u.1943 + 1} R := eval₂RingHom C (X PUnit.unit)
⊢ LeftInverse (Polynomial.eval₂ C (X PUnit.unit)) (eval₂ Polynomial.C fun x => Polynomial.X)

Next tactic:
let g : MvPolynomial PUnit R →+* R[X] := eval₂Hom Polynomial.C fun _ => Polynomial.X
/-- The ring isomorphism between multivariable polynomials in a single variable and
polynomials over the ground ring.
-/
@[simps]
def pUnitAlgEquiv : MvPolynomial PUnit R ≃ₐ[R] R[X] where
  toFun := eval₂ Polynomial.C fun _ => Polynomial.X
  invFun := Polynomial.eval₂ MvPolynomial.C (X PUnit.unit)
  left_inv := by
    let f : R[X] →+* MvPolynomial PUnit R := Polynomial.eval₂RingHom MvPolynomial.C (X PUnit.unit)
    let g : MvPolynomial PUnit R →+* R[X] := eval₂Hom Polynomial.C fun _ => Polynomial.X
    

Proof state:
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
s : σ →₀ ℕ
inst✝ : CommSemiring R
f : R[X] →+* MvPolynomial PUnit.{?u.1943 + 1} R := eval₂RingHom C (X PUnit.unit)
g : MvPolynomial PUnit.{?u.2335 + 1} R →+* R[X] := eval₂Hom Polynomial.C fun x => Polynomial.X
⊢ LeftInverse (Polynomial.eval₂ C (X PUnit.unit)) (eval₂ Polynomial.C fun x => Polynomial.X)

Next tactic:
show ∀ p, f.comp g p = p
/-- The ring isomorphism between multivariable polynomials in a single variable and
polynomials over the ground ring.
-/
@[simps]
def pUnitAlgEquiv : MvPolynomial PUnit R ≃ₐ[R] R[X] where
  toFun := eval₂ Polynomial.C fun _ => Polynomial.X
  invFun := Polynomial.eval₂ MvPolynomial.C (X PUnit.unit)
  left_inv := by
    let f : R[X] →+* MvPolynomial PUnit R := Polynomial.eval₂RingHom MvPolynomial.C (X PUnit.unit)
    let g : MvPolynomial PUnit R →+* R[X] := eval₂Hom Polynomial.C fun _ => Polynomial.X
    show ∀ p, f.comp g p = p
    

Proof state:
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
s : σ →₀ ℕ
inst✝ : CommSemiring R
f : R[X] →+* MvPolynomial PUnit.{?u.2335 + 1} R := eval₂RingHom C (X PUnit.unit)
g : MvPolynomial PUnit.{?u.2335 + 1} R →+* R[X] := eval₂Hom Polynomial.C fun x => Polynomial.X
⊢ ∀ (p : MvPolynomial PUnit.{?u.2335 + 1} R), (RingHom.comp f g) p = p

Next tactic:
apply is_id
/-- The ring isomorphism between multivariable polynomials in a single variable and
polynomials over the ground ring.
-/
@[simps]
def pUnitAlgEquiv : MvPolynomial PUnit R ≃ₐ[R] R[X] where
  toFun := eval₂ Polynomial.C fun _ => Polynomial.X
  invFun := Polynomial.eval₂ MvPolynomial.C (X PUnit.unit)
  left_inv := by
    let f : R[X] →+* MvPolynomial PUnit R := Polynomial.eval₂RingHom MvPolynomial.C (X PUnit.unit)
    let g : MvPolynomial PUnit R →+* R[X] := eval₂Hom Polynomial.C fun _ => Polynomial.X
    show ∀ p, f.comp g p = p
    apply is_id
    · 

Proof state:
case hC
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
s : σ →₀ ℕ
inst✝ : CommSemiring R
f : R[X] →+* MvPolynomial PUnit.{?u.2335 + 1} R := eval₂RingHom C (X PUnit.unit)
g : MvPolynomial PUnit.{?u.2335 + 1} R →+* R[X] := eval₂Hom Polynomial.C fun x => Polynomial.X
⊢ RingHom.comp (RingHom.comp f g) C = C

Next tactic:
ext a
/-- The ring isomorphism between multivariable polynomials in a single variable and
polynomials over the ground ring.
-/
@[simps]
def pUnitAlgEquiv : MvPolynomial PUnit R ≃ₐ[R] R[X] where
  toFun := eval₂ Polynomial.C fun _ => Polynomial.X
  invFun := Polynomial.eval₂ MvPolynomial.C (X PUnit.unit)
  left_inv := by
    let f : R[X] →+* MvPolynomial PUnit R := Polynomial.eval₂RingHom MvPolynomial.C (X PUnit.unit)
    let g : MvPolynomial PUnit R →+* R[X] := eval₂Hom Polynomial.C fun _ => Polynomial.X
    show ∀ p, f.comp g p = p
    apply is_id
    · ext a
      

Proof state:
case hC.a.a
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a✝ a' a₁ a₂ : R
e : ℕ
s : σ →₀ ℕ
inst✝ : CommSemiring R
f : R[X] →+* MvPolynomial PUnit.{?u.2335 + 1} R := eval₂RingHom C (X PUnit.unit)
g : MvPolynomial PUnit.{?u.2335 + 1} R →+* R[X] := eval₂Hom Polynomial.C fun x => Polynomial.X
a : R
m✝ : PUnit.{?u.2335 + 1} →₀ ℕ
⊢ coeff m✝ ((RingHom.comp (RingHom.comp f g) C) a) = coeff m✝ (C a)

Next tactic:
dsimp
/-- The ring isomorphism between multivariable polynomials in a single variable and
polynomials over the ground ring.
-/
@[simps]
def pUnitAlgEquiv : MvPolynomial PUnit R ≃ₐ[R] R[X] where
  toFun := eval₂ Polynomial.C fun _ => Polynomial.X
  invFun := Polynomial.eval₂ MvPolynomial.C (X PUnit.unit)
  left_inv := by
    let f : R[X] →+* MvPolynomial PUnit R := Polynomial.eval₂RingHom MvPolynomial.C (X PUnit.unit)
    let g : MvPolynomial PUnit R →+* R[X] := eval₂Hom Polynomial.C fun _ => Polynomial.X
    show ∀ p, f.comp g p = p
    apply is_id
    · ext a
      dsimp
      

Proof state:
case hC.a.a
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a✝ a' a₁ a₂ : R
e : ℕ
s : σ →₀ ℕ
inst✝ : CommSemiring R
f : R[X] →+* MvPolynomial PUnit.{?u.2335 + 1} R := eval₂RingHom C (X PUnit.unit)
g : MvPolynomial PUnit.{?u.2335 + 1} R →+* R[X] := eval₂Hom Polynomial.C fun x => Polynomial.X
a : R
m✝ : PUnit.{?u.2335 + 1} →₀ ℕ
⊢ coeff m✝ (Polynomial.eval₂ C (X PUnit.unit) (eval₂ Polynomial.C (fun x => Polynomial.X) (C a))) = coeff m✝ (C a)

Next tactic:
rw [eval₂_C, Polynomial.eval₂_C]
/-- The ring isomorphism between multivariable polynomials in a single variable and
polynomials over the ground ring.
-/
@[simps]
def pUnitAlgEquiv : MvPolynomial PUnit R ≃ₐ[R] R[X] where
  toFun := eval₂ Polynomial.C fun _ => Polynomial.X
  invFun := Polynomial.eval₂ MvPolynomial.C (X PUnit.unit)
  left_inv := by
    let f : R[X] →+* MvPolynomial PUnit R := Polynomial.eval₂RingHom MvPolynomial.C (X PUnit.unit)
    let g : MvPolynomial PUnit R →+* R[X] := eval₂Hom Polynomial.C fun _ => Polynomial.X
    show ∀ p, f.comp g p = p
    apply is_id
    · ext a
      dsimp
      rw [eval₂_C, Polynomial.eval₂_C]
    · 

Proof state:
case hX
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
s : σ →₀ ℕ
inst✝ : CommSemiring R
f : R[X] →+* MvPolynomial PUnit.{?u.2335 + 1} R := eval₂RingHom C (X PUnit.unit)
g : MvPolynomial PUnit.{?u.2335 + 1} R →+* R[X] := eval₂Hom Polynomial.C fun x => Polynomial.X
⊢ ∀ (n : PUnit.{?u.2335 + 1}), (RingHom.comp f g) (X n) = X n

Next tactic:
rintro ⟨⟩
/-- The ring isomorphism between multivariable polynomials in a single variable and
polynomials over the ground ring.
-/
@[simps]
def pUnitAlgEquiv : MvPolynomial PUnit R ≃ₐ[R] R[X] where
  toFun := eval₂ Polynomial.C fun _ => Polynomial.X
  invFun := Polynomial.eval₂ MvPolynomial.C (X PUnit.unit)
  left_inv := by
    let f : R[X] →+* MvPolynomial PUnit R := Polynomial.eval₂RingHom MvPolynomial.C (X PUnit.unit)
    let g : MvPolynomial PUnit R →+* R[X] := eval₂Hom Polynomial.C fun _ => Polynomial.X
    show ∀ p, f.comp g p = p
    apply is_id
    · ext a
      dsimp
      rw [eval₂_C, Polynomial.eval₂_C]
    · rintro ⟨⟩
      

Proof state:
case hX.unit
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
s : σ →₀ ℕ
inst✝ : CommSemiring R
f : R[X] →+* MvPolynomial PUnit.{?u.2335 + 1} R := eval₂RingHom C (X PUnit.unit)
g : MvPolynomial PUnit.{?u.2335 + 1} R →+* R[X] := eval₂Hom Polynomial.C fun x => Polynomial.X
⊢ (RingHom.comp f g) (X PUnit.unit) = X PUnit.unit

Next tactic:
dsimp
/-- The ring isomorphism between multivariable polynomials in a single variable and
polynomials over the ground ring.
-/
@[simps]
def pUnitAlgEquiv : MvPolynomial PUnit R ≃ₐ[R] R[X] where
  toFun := eval₂ Polynomial.C fun _ => Polynomial.X
  invFun := Polynomial.eval₂ MvPolynomial.C (X PUnit.unit)
  left_inv := by
    let f : R[X] →+* MvPolynomial PUnit R := Polynomial.eval₂RingHom MvPolynomial.C (X PUnit.unit)
    let g : MvPolynomial PUnit R →+* R[X] := eval₂Hom Polynomial.C fun _ => Polynomial.X
    show ∀ p, f.comp g p = p
    apply is_id
    · ext a
      dsimp
      rw [eval₂_C, Polynomial.eval₂_C]
    · rintro ⟨⟩
      dsimp
      

Proof state:
case hX.unit
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
s : σ →₀ ℕ
inst✝ : CommSemiring R
f : R[X] →+* MvPolynomial PUnit.{?u.2335 + 1} R := eval₂RingHom C (X PUnit.unit)
g : MvPolynomial PUnit.{?u.2335 + 1} R →+* R[X] := eval₂Hom Polynomial.C fun x => Polynomial.X
⊢ Polynomial.eval₂ C (X PUnit.unit) (eval₂ Polynomial.C (fun x => Polynomial.X) (X PUnit.unit)) = X PUnit.unit

Next tactic:
rw [eval₂_X, Polynomial.eval₂_X]
/-- The ring isomorphism between multivariable polynomials in a single variable and
polynomials over the ground ring.
-/
@[simps]
def pUnitAlgEquiv : MvPolynomial PUnit R ≃ₐ[R] R[X] where
  toFun := eval₂ Polynomial.C fun _ => Polynomial.X
  invFun := Polynomial.eval₂ MvPolynomial.C (X PUnit.unit)
  left_inv := by
    let f : R[X] →+* MvPolynomial PUnit R := Polynomial.eval₂RingHom MvPolynomial.C (X PUnit.unit)
    let g : MvPolynomial PUnit R →+* R[X] := eval₂Hom Polynomial.C fun _ => Polynomial.X
    show ∀ p, f.comp g p = p
    apply is_id
    · ext a
      dsimp
      rw [eval₂_C, Polynomial.eval₂_C]
    · rintro ⟨⟩
      dsimp
      rw [eval₂_X, Polynomial.eval₂_X]
  right_inv p :=
    Polynomial.induction_on p (fun a => by 

Proof state:
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a✝ a' a₁ a₂ : R
e : ℕ
s : σ →₀ ℕ
inst✝ : CommSemiring R
p : R[X]
a : R
⊢ eval₂ Polynomial.C (fun x => Polynomial.X) (Polynomial.eval₂ C (X PUnit.unit) (Polynomial.C a)) = Polynomial.C a

Next tactic:
rw [Polynomial.eval₂_C, MvPolynomial.eval₂_C]
/-- The ring isomorphism between multivariable polynomials in a single variable and
polynomials over the ground ring.
-/
@[simps]
def pUnitAlgEquiv : MvPolynomial PUnit R ≃ₐ[R] R[X] where
  toFun := eval₂ Polynomial.C fun _ => Polynomial.X
  invFun := Polynomial.eval₂ MvPolynomial.C (X PUnit.unit)
  left_inv := by
    let f : R[X] →+* MvPolynomial PUnit R := Polynomial.eval₂RingHom MvPolynomial.C (X PUnit.unit)
    let g : MvPolynomial PUnit R →+* R[X] := eval₂Hom Polynomial.C fun _ => Polynomial.X
    show ∀ p, f.comp g p = p
    apply is_id
    · ext a
      dsimp
      rw [eval₂_C, Polynomial.eval₂_C]
    · rintro ⟨⟩
      dsimp
      rw [eval₂_X, Polynomial.eval₂_X]
  right_inv p :=
    Polynomial.induction_on p (fun a => by rw [Polynomial.eval₂_C, MvPolynomial.eval₂_C])
    (fun p q hp hq => by 

Proof state:
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
s : σ →₀ ℕ
inst✝ : CommSemiring R
p✝ p q : R[X]
hp : eval₂ Polynomial.C (fun x => Polynomial.X) (Polynomial.eval₂ C (X PUnit.unit) p) = p
hq : eval₂ Polynomial.C (fun x => Polynomial.X) (Polynomial.eval₂ C (X PUnit.unit) q) = q
⊢ eval₂ Polynomial.C (fun x => Polynomial.X) (Polynomial.eval₂ C (X PUnit.unit) (p + q)) = p + q

Next tactic:
rw [Polynomial.eval₂_add, MvPolynomial.eval₂_add, hp, hq]