l3lab/ntp-mathlib huggingface dataset:
/-- Given relation isomorphisms `r₁ ≃r s₁` and `r₂ ≃r s₂`, construct a relation isomorphism for the
lexicographic orders on the sum.
-/
def sumLexCongr {α₁ α₂ β₁ β₂ r₁ r₂ s₁ s₂} (e₁ : @RelIso α₁ β₁ r₁ s₁) (e₂ : @RelIso α₂ β₂ r₂ s₂) :
    Sum.Lex r₁ r₂ ≃r Sum.Lex s₁ s₂ :=
  ⟨Equiv.sumCongr e₁.toEquiv e₂.toEquiv, @fun a b => by
    cases' e₁ with f hf; cases' e₂ with g hg; cases a <;> 

Proof state:
case mk.mk.inr
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
r : α → α → Prop
s : β → β → Prop
t : γ → γ → Prop
u : δ → δ → Prop
α₁ : Type ?u.77965
α₂ : Type ?u.77973
β₁ : Type ?u.77966
β₂ : Type ?u.77974
r₁ : α₁ → α₁ → Prop
r₂ : α₂ → α₂ → Prop
s₁ : β₁ → β₁ → Prop
s₂ : β₂ → β₂ → Prop
b : α₁ ⊕ α₂
f : α₁ ≃ β₁
hf : ∀ {a b : α₁}, s₁ (f a) (f b) ↔ r₁ a b
g : α₂ ≃ β₂
hg : ∀ {a b : α₂}, s₂ (g a) (g b) ↔ r₂ a b
val✝ : α₂
⊢ Sum.Lex s₁ s₂
      ((Equiv.sumCongr { toEquiv := f, map_rel_iff' := hf }.toEquiv { toEquiv := g, map_rel_iff' := hg }.toEquiv)
        (Sum.inr val✝))
      ((Equiv.sumCongr { toEquiv := f, map_rel_iff' := hf }.toEquiv { toEquiv := g, map_rel_iff' := hg }.toEquiv) b) ↔
    Sum.Lex r₁ r₂ (Sum.inr val✝) b

Next tactic:
cases b
/-- Given relation isomorphisms `r₁ ≃r s₁` and `r₂ ≃r s₂`, construct a relation isomorphism for the
lexicographic orders on the sum.
-/
def sumLexCongr {α₁ α₂ β₁ β₂ r₁ r₂ s₁ s₂} (e₁ : @RelIso α₁ β₁ r₁ s₁) (e₂ : @RelIso α₂ β₂ r₂ s₂) :
    Sum.Lex r₁ r₂ ≃r Sum.Lex s₁ s₂ :=
  ⟨Equiv.sumCongr e₁.toEquiv e₂.toEquiv, @fun a b => by
    cases' e₁ with f hf; cases' e₂ with g hg; cases a <;> cases b <;> 

Proof state:
case mk.mk.inl.inl
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
r : α → α → Prop
s : β → β → Prop
t : γ → γ → Prop
u : δ → δ → Prop
α₁ : Type ?u.77965
α₂ : Type ?u.77973
β₁ : Type ?u.77966
β₂ : Type ?u.77974
r₁ : α₁ → α₁ → Prop
r₂ : α₂ → α₂ → Prop
s₁ : β₁ → β₁ → Prop
s₂ : β₂ → β₂ → Prop
f : α₁ ≃ β₁
hf : ∀ {a b : α₁}, s₁ (f a) (f b) ↔ r₁ a b
g : α₂ ≃ β₂
hg : ∀ {a b : α₂}, s₂ (g a) (g b) ↔ r₂ a b
val✝¹ val✝ : α₁
⊢ Sum.Lex s₁ s₂
      ((Equiv.sumCongr { toEquiv := f, map_rel_iff' := hf }.toEquiv { toEquiv := g, map_rel_iff' := hg }.toEquiv)
        (Sum.inl val✝¹))
      ((Equiv.sumCongr { toEquiv := f, map_rel_iff' := hf }.toEquiv { toEquiv := g, map_rel_iff' := hg }.toEquiv)
        (Sum.inl val✝)) ↔
    Sum.Lex r₁ r₂ (Sum.inl val✝¹) (Sum.inl val✝)

Next tactic:
simp [hf, hg]
/-- Given relation isomorphisms `r₁ ≃r s₁` and `r₂ ≃r s₂`, construct a relation isomorphism for the
lexicographic orders on the sum.
-/
def sumLexCongr {α₁ α₂ β₁ β₂ r₁ r₂ s₁ s₂} (e₁ : @RelIso α₁ β₁ r₁ s₁) (e₂ : @RelIso α₂ β₂ r₂ s₂) :
    Sum.Lex r₁ r₂ ≃r Sum.Lex s₁ s₂ :=
  ⟨Equiv.sumCongr e₁.toEquiv e₂.toEquiv, @fun a b => by
    cases' e₁ with f hf; cases' e₂ with g hg; cases a <;> cases b <;> 

Proof state:
case mk.mk.inl.inr
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
r : α → α → Prop
s : β → β → Prop
t : γ → γ → Prop
u : δ → δ → Prop
α₁ : Type ?u.77965
α₂ : Type ?u.77973
β₁ : Type ?u.77966
β₂ : Type ?u.77974
r₁ : α₁ → α₁ → Prop
r₂ : α₂ → α₂ → Prop
s₁ : β₁ → β₁ → Prop
s₂ : β₂ → β₂ → Prop
f : α₁ ≃ β₁
hf : ∀ {a b : α₁}, s₁ (f a) (f b) ↔ r₁ a b
g : α₂ ≃ β₂
hg : ∀ {a b : α₂}, s₂ (g a) (g b) ↔ r₂ a b
val✝¹ : α₁
val✝ : α₂
⊢ Sum.Lex s₁ s₂
      ((Equiv.sumCongr { toEquiv := f, map_rel_iff' := hf }.toEquiv { toEquiv := g, map_rel_iff' := hg }.toEquiv)
        (Sum.inl val✝¹))
      ((Equiv.sumCongr { toEquiv := f, map_rel_iff' := hf }.toEquiv { toEquiv := g, map_rel_iff' := hg }.toEquiv)
        (Sum.inr val✝)) ↔
    Sum.Lex r₁ r₂ (Sum.inl val✝¹) (Sum.inr val✝)

Next tactic:
simp [hf, hg]
/-- Given relation isomorphisms `r₁ ≃r s₁` and `r₂ ≃r s₂`, construct a relation isomorphism for the
lexicographic orders on the sum.
-/
def sumLexCongr {α₁ α₂ β₁ β₂ r₁ r₂ s₁ s₂} (e₁ : @RelIso α₁ β₁ r₁ s₁) (e₂ : @RelIso α₂ β₂ r₂ s₂) :
    Sum.Lex r₁ r₂ ≃r Sum.Lex s₁ s₂ :=
  ⟨Equiv.sumCongr e₁.toEquiv e₂.toEquiv, @fun a b => by
    cases' e₁ with f hf; cases' e₂ with g hg; cases a <;> cases b <;> 

Proof state:
case mk.mk.inr.inl
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
r : α → α → Prop
s : β → β → Prop
t : γ → γ → Prop
u : δ → δ → Prop
α₁ : Type ?u.77965
α₂ : Type ?u.77973
β₁ : Type ?u.77966
β₂ : Type ?u.77974
r₁ : α₁ → α₁ → Prop
r₂ : α₂ → α₂ → Prop
s₁ : β₁ → β₁ → Prop
s₂ : β₂ → β₂ → Prop
f : α₁ ≃ β₁
hf : ∀ {a b : α₁}, s₁ (f a) (f b) ↔ r₁ a b
g : α₂ ≃ β₂
hg : ∀ {a b : α₂}, s₂ (g a) (g b) ↔ r₂ a b
val✝¹ : α₂
val✝ : α₁
⊢ Sum.Lex s₁ s₂
      ((Equiv.sumCongr { toEquiv := f, map_rel_iff' := hf }.toEquiv { toEquiv := g, map_rel_iff' := hg }.toEquiv)
        (Sum.inr val✝¹))
      ((Equiv.sumCongr { toEquiv := f, map_rel_iff' := hf }.toEquiv { toEquiv := g, map_rel_iff' := hg }.toEquiv)
        (Sum.inl val✝)) ↔
    Sum.Lex r₁ r₂ (Sum.inr val✝¹) (Sum.inl val✝)

Next tactic:
simp [hf, hg]
/-- Given relation isomorphisms `r₁ ≃r s₁` and `r₂ ≃r s₂`, construct a relation isomorphism for the
lexicographic orders on the sum.
-/
def sumLexCongr {α₁ α₂ β₁ β₂ r₁ r₂ s₁ s₂} (e₁ : @RelIso α₁ β₁ r₁ s₁) (e₂ : @RelIso α₂ β₂ r₂ s₂) :
    Sum.Lex r₁ r₂ ≃r Sum.Lex s₁ s₂ :=
  ⟨Equiv.sumCongr e₁.toEquiv e₂.toEquiv, @fun a b => by
    cases' e₁ with f hf; cases' e₂ with g hg; cases a <;> cases b <;> 

Proof state:
case mk.mk.inr.inr
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
r : α → α → Prop
s : β → β → Prop
t : γ → γ → Prop
u : δ → δ → Prop
α₁ : Type ?u.77965
α₂ : Type ?u.77973
β₁ : Type ?u.77966
β₂ : Type ?u.77974
r₁ : α₁ → α₁ → Prop
r₂ : α₂ → α₂ → Prop
s₁ : β₁ → β₁ → Prop
s₂ : β₂ → β₂ → Prop
f : α₁ ≃ β₁
hf : ∀ {a b : α₁}, s₁ (f a) (f b) ↔ r₁ a b
g : α₂ ≃ β₂
hg : ∀ {a b : α₂}, s₂ (g a) (g b) ↔ r₂ a b
val✝¹ val✝ : α₂
⊢ Sum.Lex s₁ s₂
      ((Equiv.sumCongr { toEquiv := f, map_rel_iff' := hf }.toEquiv { toEquiv := g, map_rel_iff' := hg }.toEquiv)
        (Sum.inr val✝¹))
      ((Equiv.sumCongr { toEquiv := f, map_rel_iff' := hf }.toEquiv { toEquiv := g, map_rel_iff' := hg }.toEquiv)
        (Sum.inr val✝)) ↔
    Sum.Lex r₁ r₂ (Sum.inr val✝¹) (Sum.inr val✝)

Next tactic:
simp [hf, hg]
/-- Given relation isomorphisms `r₁ ≃r s₁` and `r₂ ≃r s₂`, construct a relation isomorphism for the
lexicographic orders on the product.
-/
def prodLexCongr {α₁ α₂ β₁ β₂ r₁ r₂ s₁ s₂} (e₁ : @RelIso α₁ β₁ r₁ s₁) (e₂ : @RelIso α₂ β₂ r₂ s₂) :
    Prod.Lex r₁ r₂ ≃r Prod.Lex s₁ s₂ :=
  ⟨Equiv.prodCongr e₁.toEquiv e₂.toEquiv, by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
r : α → α → Prop
s : β → β → Prop
t : γ → γ → Prop
u : δ → δ → Prop
α₁ : Type ?u.79872
α₂ : Type ?u.79880
β₁ : Type ?u.79873
β₂ : Type ?u.79881
r₁ : α₁ → α₁ → Prop
r₂ : α₂ → α₂ → Prop
s₁ : β₁ → β₁ → Prop
s₂ : β₂ → β₂ → Prop
e₁ : r₁ ≃r s₁
e₂ : r₂ ≃r s₂
⊢ ∀ {a b : α₁ × α₂},
    Prod.Lex s₁ s₂ ((Equiv.prodCongr e₁.toEquiv e₂.toEquiv) a) ((Equiv.prodCongr e₁.toEquiv e₂.toEquiv) b) ↔
      Prod.Lex r₁ r₂ a b

Next tactic:
simp [Prod.lex_def, e₁.map_rel_iff, e₂.map_rel_iff,
    e₁.injective.eq_iff]
@[simp, norm_cast]
theorem coe_eq_zero {x : Icc (0 : α) 1} : (x : α) = 0 ↔ x = 0 := by
  

Proof state:
α : Type u_1
inst✝ : OrderedSemiring α
x : ↑(Icc 0 1)
⊢ ↑x = 0 ↔ x = 0

Next tactic:
symm
@[simp, norm_cast]
theorem coe_eq_zero {x : Icc (0 : α) 1} : (x : α) = 0 ↔ x = 0 := by
  symm
  

Proof state:
α : Type u_1
inst✝ : OrderedSemiring α
x : ↑(Icc 0 1)
⊢ x = 0 ↔ ↑x = 0

Next tactic:
exact Subtype.ext_iff
@[simp, norm_cast]
theorem coe_eq_one {x : Icc (0 : α) 1} : (x : α) = 1 ↔ x = 1 := by
  

Proof state:
α : Type u_1
inst✝ : OrderedSemiring α
x : ↑(Icc 0 1)
⊢ ↑x = 1 ↔ x = 1

Next tactic:
symm
@[simp, norm_cast]
theorem coe_eq_one {x : Icc (0 : α) 1} : (x : α) = 1 ↔ x = 1 := by
  symm
  

Proof state:
α : Type u_1
inst✝ : OrderedSemiring α
x : ↑(Icc 0 1)
⊢ x = 1 ↔ ↑x = 1

Next tactic:
exact Subtype.ext_iff
theorem one_sub_mem {t : β} (ht : t ∈ Icc (0 : β) 1) : 1 - t ∈ Icc (0 : β) 1 := by
  

Proof state:
α : Type u_1
inst✝¹ : OrderedSemiring α
β : Type u_2
inst✝ : OrderedRing β
t : β
ht : t ∈ Icc 0 1
⊢ 1 - t ∈ Icc 0 1

Next tactic:
rw [mem_Icc] at *
theorem one_sub_mem {t : β} (ht : t ∈ Icc (0 : β) 1) : 1 - t ∈ Icc (0 : β) 1 := by
  rw [mem_Icc] at *
  

Proof state:
α : Type u_1
inst✝¹ : OrderedSemiring α
β : Type u_2
inst✝ : OrderedRing β
t : β
ht : 0 ≤ t ∧ t ≤ 1
⊢ 0 ≤ 1 - t ∧ 1 - t ≤ 1

Next tactic:
exact ⟨sub_nonneg.2 ht.2, (sub_le_self_iff _).2 ht.1⟩
theorem one_sub_nonneg (x : Icc (0 : β) 1) : 0 ≤ 1 - (x : β) := by 

Proof state:
α : Type u_1
inst✝¹ : OrderedSemiring α
β : Type u_2
inst✝ : OrderedRing β
x : ↑(Icc 0 1)
⊢ 0 ≤ 1 - ↑x

Next tactic:
simpa using x.2.2
theorem one_sub_le_one (x : Icc (0 : β) 1) : 1 - (x : β) ≤ 1 := by 

Proof state:
α : Type u_1
inst✝¹ : OrderedSemiring α
β : Type u_2
inst✝ : OrderedRing β
x : ↑(Icc 0 1)
⊢ 1 - ↑x ≤ 1

Next tactic:
simpa using x.2.1
@[simp, norm_cast]
theorem coe_eq_zero [Nontrivial α] {x : Ico (0 : α) 1} : (x : α) = 0 ↔ x = 0 := by
  

Proof state:
α : Type u_1
inst✝¹ : OrderedSemiring α
inst✝ : Nontrivial α
x : ↑(Ico 0 1)
⊢ ↑x = 0 ↔ x = 0

Next tactic:
symm
@[simp, norm_cast]
theorem coe_eq_zero [Nontrivial α] {x : Ico (0 : α) 1} : (x : α) = 0 ↔ x = 0 := by
  symm
  

Proof state:
α : Type u_1
inst✝¹ : OrderedSemiring α
inst✝ : Nontrivial α
x : ↑(Ico 0 1)
⊢ x = 0 ↔ ↑x = 0

Next tactic:
exact Subtype.ext_iff
@[simp, norm_cast]
theorem coe_eq_one [Nontrivial α] {x : Ioc (0 : α) 1} : (x : α) = 1 ↔ x = 1 := by
  

Proof state:
α : Type u_1
inst✝¹ : StrictOrderedSemiring α
inst✝ : Nontrivial α
x : ↑(Ioc 0 1)
⊢ ↑x = 1 ↔ x = 1

Next tactic:
symm
@[simp, norm_cast]
theorem coe_eq_one [Nontrivial α] {x : Ioc (0 : α) 1} : (x : α) = 1 ↔ x = 1 := by
  symm
  

Proof state:
α : Type u_1
inst✝¹ : StrictOrderedSemiring α
inst✝ : Nontrivial α
x : ↑(Ioc 0 1)
⊢ x = 1 ↔ ↑x = 1

Next tactic:
exact Subtype.ext_iff
theorem one_sub_mem {t : β} (ht : t ∈ Ioo (0 : β) 1) : 1 - t ∈ Ioo (0 : β) 1 := by
  

Proof state:
α : Type u_1
inst✝¹ : StrictOrderedSemiring α
β : Type u_2
inst✝ : OrderedRing β
t : β
ht : t ∈ Ioo 0 1
⊢ 1 - t ∈ Ioo 0 1

Next tactic:
rw [mem_Ioo] at *
theorem one_sub_mem {t : β} (ht : t ∈ Ioo (0 : β) 1) : 1 - t ∈ Ioo (0 : β) 1 := by
  rw [mem_Ioo] at *
  

Proof state:
α : Type u_1
inst✝¹ : StrictOrderedSemiring α
β : Type u_2
inst✝ : OrderedRing β
t : β
ht : 0 < t ∧ t < 1
⊢ 0 < 1 - t ∧ 1 - t < 1

Next tactic:
refine' ⟨sub_pos.2 ht.2, _⟩
theorem one_sub_mem {t : β} (ht : t ∈ Ioo (0 : β) 1) : 1 - t ∈ Ioo (0 : β) 1 := by
  rw [mem_Ioo] at *
  refine' ⟨sub_pos.2 ht.2, _⟩
  

Proof state:
α : Type u_1
inst✝¹ : StrictOrderedSemiring α
β : Type u_2
inst✝ : OrderedRing β
t : β
ht : 0 < t ∧ t < 1
⊢ 1 - t < 1

Next tactic:
exact lt_of_le_of_ne ((sub_le_self_iff 1).2 ht.1.le) (mt sub_eq_self.mp ht.1.ne')
theorem one_minus_pos (x : Ioo (0 : β) 1) : 0 < 1 - (x : β) := by 

Proof state:
α : Type u_1
inst✝¹ : StrictOrderedSemiring α
β : Type u_2
inst✝ : OrderedRing β
x : ↑(Ioo 0 1)
⊢ 0 < 1 - ↑x

Next tactic:
simpa using x.2.2
theorem one_minus_lt_one (x : Ioo (0 : β) 1) : 1 - (x : β) < 1 := by 

Proof state:
α : Type u_1
inst✝¹ : StrictOrderedSemiring α
β : Type u_2
inst✝ : OrderedRing β
x : ↑(Ioo 0 1)
⊢ 1 - ↑x < 1

Next tactic:
simpa using x.2.1
/-- A basis provides an algebra isomorphism with the free algebra, replacing each basis vector
with its index. -/
noncomputable def equivFreeAlgebra (b : Basis κ R M) :
    TensorAlgebra R M ≃ₐ[R] FreeAlgebra R κ :=
  AlgEquiv.ofAlgHom
    (TensorAlgebra.lift _ (Finsupp.total _ _ _ (FreeAlgebra.ι _) ∘ₗ b.repr.toLinearMap))
    (FreeAlgebra.lift _ (ι R ∘ b))
    (by 

Proof state:
κ : Type uκ
R : Type uR
M : Type uM
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
b : Basis κ R M
⊢ AlgHom.comp ((lift R) (Finsupp.total κ (FreeAlgebra R κ) R (FreeAlgebra.ι R) ∘ₗ ↑b.repr))
      ((FreeAlgebra.lift R) (⇑(ι R) ∘ ⇑b)) =
    AlgHom.id R (FreeAlgebra R κ)

Next tactic:
ext
/-- A basis provides an algebra isomorphism with the free algebra, replacing each basis vector
with its index. -/
noncomputable def equivFreeAlgebra (b : Basis κ R M) :
    TensorAlgebra R M ≃ₐ[R] FreeAlgebra R κ :=
  AlgEquiv.ofAlgHom
    (TensorAlgebra.lift _ (Finsupp.total _ _ _ (FreeAlgebra.ι _) ∘ₗ b.repr.toLinearMap))
    (FreeAlgebra.lift _ (ι R ∘ b))
    (by ext; 

Proof state:
case w.h
κ : Type uκ
R : Type uR
M : Type uM
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
b : Basis κ R M
x✝ : κ
⊢ (⇑(AlgHom.comp ((lift R) (Finsupp.total κ (FreeAlgebra R κ) R (FreeAlgebra.ι R) ∘ₗ ↑b.repr))
            ((FreeAlgebra.lift R) (⇑(ι R) ∘ ⇑b))) ∘
        FreeAlgebra.ι R)
      x✝ =
    (⇑(AlgHom.id R (FreeAlgebra R κ)) ∘ FreeAlgebra.ι R) x✝

Next tactic:
simp
/-- A basis provides an algebra isomorphism with the free algebra, replacing each basis vector
with its index. -/
noncomputable def equivFreeAlgebra (b : Basis κ R M) :
    TensorAlgebra R M ≃ₐ[R] FreeAlgebra R κ :=
  AlgEquiv.ofAlgHom
    (TensorAlgebra.lift _ (Finsupp.total _ _ _ (FreeAlgebra.ι _) ∘ₗ b.repr.toLinearMap))
    (FreeAlgebra.lift _ (ι R ∘ b))
    (by ext; simp)
    (hom_ext <| b.ext <| fun i => by 

Proof state:
κ : Type uκ
R : Type uR
M : Type uM
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
b : Basis κ R M
i : κ
⊢ (AlgHom.toLinearMap
          (AlgHom.comp ((FreeAlgebra.lift R) (⇑(ι R) ∘ ⇑b))
            ((lift R) (Finsupp.total κ (FreeAlgebra R κ) R (FreeAlgebra.ι R) ∘ₗ ↑b.repr))) ∘ₗ
        ι R)
      (b i) =
    (AlgHom.toLinearMap (AlgHom.id R (TensorAlgebra R M)) ∘ₗ ι R) (b i)

Next tactic:
simp
@[simp]
lemma equivFreeAlgebra_ι_apply (b : Basis κ R M) (i : κ) :
    equivFreeAlgebra b (ι R (b i)) = FreeAlgebra.ι R i :=
  (TensorAlgebra.lift_ι_apply _ _).trans <| by 

Proof state:
κ : Type uκ
R : Type uR
M : Type uM
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
b : Basis κ R M
i : κ
⊢ (LinearMap.comp (Finsupp.total κ (FreeAlgebra R κ) R (FreeAlgebra.ι R)) ↑b.repr) (b i) = FreeAlgebra.ι R i

Next tactic:
simp
open Cardinal in
lemma rank_eq [Nontrivial R] [Module.Free R M] :
    Module.rank R (TensorAlgebra R M) = Cardinal.lift.{uR} (sum fun n ↦ Module.rank R M ^ n) := by
  

Proof state:
κ : Type uκ
R : Type uR
M : Type uM
inst✝⁴ : CommRing R
inst✝³ : AddCommGroup M
inst✝² : Module R M
inst✝¹ : Nontrivial R
inst✝ : Module.Free R M
⊢ Module.rank R (TensorAlgebra R M) = Cardinal.lift.{uR, uM} (sum fun n => Module.rank R M ^ n)

Next tactic:
let ⟨⟨κ, b⟩⟩ := Module.Free.exists_basis (R := R) (M := M)
open Cardinal in
lemma rank_eq [Nontrivial R] [Module.Free R M] :
    Module.rank R (TensorAlgebra R M) = Cardinal.lift.{uR} (sum fun n ↦ Module.rank R M ^ n) := by
  let ⟨⟨κ, b⟩⟩ := Module.Free.exists_basis (R := R) (M := M)
  

Proof state:
κ✝ : Type uκ
R : Type uR
M : Type uM
inst✝⁴ : CommRing R
inst✝³ : AddCommGroup M
inst✝² : Module R M
inst✝¹ : Nontrivial R
inst✝ : Module.Free R M
κ : Type uM
b : Basis κ R M
⊢ Module.rank R (TensorAlgebra R M) = Cardinal.lift.{uR, uM} (sum fun n => Module.rank R M ^ n)

Next tactic:
rw [(equivFreeAlgebra b).toLinearEquiv.rank_eq, FreeAlgebra.rank_eq, mk_list_eq_sum_pow,
    Basis.mk_eq_rank'' b]
private theorem mul_aux_left (x1 x2 y : ℕ × K) (H : R K p x1 x2) :
    mk K p (x1.1 + y.1, (frobenius K p)^[y.1] x1.2 * (frobenius K p)^[x1.1] y.2) =
      mk K p (x2.1 + y.1, (frobenius K p)^[y.1] x2.2 * (frobenius K p)^[x2.1] y.2) :=
  match x1, x2, H with
  | _, _, R.intro n x =>
    Quot.sound <| by
      

Proof state:
K : Type u
inst✝² : CommRing K
p : ℕ
inst✝¹ : Fact (Nat.Prime p)
inst✝ : CharP K p
x1 x2 y : ℕ × K
H : R K p x1 x2
n : ℕ
x : K
⊢ R K p ((n, x).1 + y.1, (⇑(frobenius K p))^[y.1] (n, x).2 * (⇑(frobenius K p))^[(n, x).1] y.2)
    ((n + 1, (frobenius K p) x).1 + y.1,
      (⇑(frobenius K p))^[y.1] (n + 1, (frobenius K p) x).2 * (⇑(frobenius K p))^[(n + 1, (frobenius K p) x).1] y.2)

Next tactic:
rw [← iterate_succ_apply, iterate_succ_apply', iterate_succ_apply', ← frobenius_mul,
        Nat.succ_add]
private theorem mul_aux_left (x1 x2 y : ℕ × K) (H : R K p x1 x2) :
    mk K p (x1.1 + y.1, (frobenius K p)^[y.1] x1.2 * (frobenius K p)^[x1.1] y.2) =
      mk K p (x2.1 + y.1, (frobenius K p)^[y.1] x2.2 * (frobenius K p)^[x2.1] y.2) :=
  match x1, x2, H with
  | _, _, R.intro n x =>
    Quot.sound <| by
      rw [← iterate_succ_apply, iterate_succ_apply', iterate_succ_apply', ← frobenius_mul,
        Nat.succ_add]
      

Proof state:
K : Type u
inst✝² : CommRing K
p : ℕ
inst✝¹ : Fact (Nat.Prime p)
inst✝ : CharP K p
x1 x2 y : ℕ × K
H : R K p x1 x2
n : ℕ
x : K
⊢ R K p ((n, x).1 + y.1, (⇑(frobenius K p))^[y.1] (n, x).2 * (⇑(frobenius K p))^[(n, x).1] y.2)
    (Nat.succ (n + y.1), (frobenius K p) ((⇑(frobenius K p))^[y.1] x * (⇑(frobenius K p))^[n] y.2))

Next tactic:
apply R.intro
private theorem mul_aux_right (x y1 y2 : ℕ × K) (H : R K p y1 y2) :
    mk K p (x.1 + y1.1, (frobenius K p)^[y1.1] x.2 * (frobenius K p)^[x.1] y1.2) =
      mk K p (x.1 + y2.1, (frobenius K p)^[y2.1] x.2 * (frobenius K p)^[x.1] y2.2) :=
  match y1, y2, H with
  | _, _, R.intro n y =>
    Quot.sound <| by
      

Proof state:
K : Type u
inst✝² : CommRing K
p : ℕ
inst✝¹ : Fact (Nat.Prime p)
inst✝ : CharP K p
x y1 y2 : ℕ × K
H : R K p y1 y2
n : ℕ
y : K
⊢ R K p (x.1 + (n, y).1, (⇑(frobenius K p))^[(n, y).1] x.2 * (⇑(frobenius K p))^[x.1] (n, y).2)
    (x.1 + (n + 1, (frobenius K p) y).1,
      (⇑(frobenius K p))^[(n + 1, (frobenius K p) y).1] x.2 * (⇑(frobenius K p))^[x.1] (n + 1, (frobenius K p) y).2)

Next tactic:
rw [← iterate_succ_apply, iterate_succ_apply', iterate_succ_apply', ← frobenius_mul]
private theorem mul_aux_right (x y1 y2 : ℕ × K) (H : R K p y1 y2) :
    mk K p (x.1 + y1.1, (frobenius K p)^[y1.1] x.2 * (frobenius K p)^[x.1] y1.2) =
      mk K p (x.1 + y2.1, (frobenius K p)^[y2.1] x.2 * (frobenius K p)^[x.1] y2.2) :=
  match y1, y2, H with
  | _, _, R.intro n y =>
    Quot.sound <| by
      rw [← iterate_succ_apply, iterate_succ_apply', iterate_succ_apply', ← frobenius_mul]
      

Proof state:
K : Type u
inst✝² : CommRing K
p : ℕ
inst✝¹ : Fact (Nat.Prime p)
inst✝ : CharP K p
x y1 y2 : ℕ × K
H : R K p y1 y2
n : ℕ
y : K
⊢ R K p (x.1 + (n, y).1, (⇑(frobenius K p))^[(n, y).1] x.2 * (⇑(frobenius K p))^[x.1] (n, y).2)
    (x.1 + (n + 1, (frobenius K p) y).1, (frobenius K p) ((⇑(frobenius K p))^[n] x.2 * (⇑(frobenius K p))^[x.1] y))

Next tactic:
apply R.intro
instance : CommMonoid (PerfectClosure K p) :=
  { (inferInstance : Mul (PerfectClosure K p)) with
    mul_assoc := fun e f g =>
      Quot.inductionOn e fun ⟨m, x⟩ =>
        Quot.inductionOn f fun ⟨n, y⟩ =>
          Quot.inductionOn g fun ⟨s, z⟩ => by
            

Proof state:
K : Type u
inst✝² : CommRing K
p : ℕ
inst✝¹ : Fact (Nat.Prime p)
inst✝ : CharP K p
src✝ : Mul (PerfectClosure K p) := inferInstance
e f g : PerfectClosure K p
x✝² : ℕ × K
m : ℕ
x : K
x✝¹ : ℕ × K
n : ℕ
y : K
x✝ : ℕ × K
s : ℕ
z : K
⊢ Quot.mk (R K p) (m, x) * Quot.mk (R K p) (n, y) * Quot.mk (R K p) (s, z) =
    Quot.mk (R K p) (m, x) * (Quot.mk (R K p) (n, y) * Quot.mk (R K p) (s, z))

Next tactic:
simp only [quot_mk_eq_mk, mk_mul_mk]
instance : CommMonoid (PerfectClosure K p) :=
  { (inferInstance : Mul (PerfectClosure K p)) with
    mul_assoc := fun e f g =>
      Quot.inductionOn e fun ⟨m, x⟩ =>
        Quot.inductionOn f fun ⟨n, y⟩ =>
          Quot.inductionOn g fun ⟨s, z⟩ => by
            simp only [quot_mk_eq_mk, mk_mul_mk] -- Porting note: added this line
            

Proof state:
K : Type u
inst✝² : CommRing K
p : ℕ
inst✝¹ : Fact (Nat.Prime p)
inst✝ : CharP K p
src✝ : Mul (PerfectClosure K p) := inferInstance
e f g : PerfectClosure K p
x✝² : ℕ × K
m : ℕ
x : K
x✝¹ : ℕ × K
n : ℕ
y : K
x✝ : ℕ × K
s : ℕ
z : K
⊢ mk K p
      (m + n + s,
        (⇑(frobenius K p))^[s] ((⇑(frobenius K p))^[n] x * (⇑(frobenius K p))^[m] y) * (⇑(frobenius K p))^[m + n] z) =
    mk K p
      (m + (n + s),
        (⇑(frobenius K p))^[n + s] x * (⇑(frobenius K p))^[m] ((⇑(frobenius K p))^[s] y * (⇑(frobenius K p))^[n] z))

Next tactic:
apply congr_arg (Quot.mk _)
instance : CommMonoid (PerfectClosure K p) :=
  { (inferInstance : Mul (PerfectClosure K p)) with
    mul_assoc := fun e f g =>
      Quot.inductionOn e fun ⟨m, x⟩ =>
        Quot.inductionOn f fun ⟨n, y⟩ =>
          Quot.inductionOn g fun ⟨s, z⟩ => by
            simp only [quot_mk_eq_mk, mk_mul_mk] -- Porting note: added this line
            apply congr_arg (Quot.mk _)
            

Proof state:
K : Type u
inst✝² : CommRing K
p : ℕ
inst✝¹ : Fact (Nat.Prime p)
inst✝ : CharP K p
src✝ : Mul (PerfectClosure K p) := inferInstance
e f g : PerfectClosure K p
x✝² : ℕ × K
m : ℕ
x : K
x✝¹ : ℕ × K
n : ℕ
y : K
x✝ : ℕ × K
s : ℕ
z : K
⊢ (m + n + s,
      (⇑(frobenius K p))^[s] ((⇑(frobenius K p))^[n] x * (⇑(frobenius K p))^[m] y) * (⇑(frobenius K p))^[m + n] z) =
    (m + (n + s),
      (⇑(frobenius K p))^[n + s] x * (⇑(frobenius K p))^[m] ((⇑(frobenius K p))^[s] y * (⇑(frobenius K p))^[n] z))

Next tactic:
simp only [add_assoc, mul_assoc, iterate_map_mul, ← iterate_add_apply,
              add_comm, add_left_comm]
instance : CommMonoid (PerfectClosure K p) :=
  { (inferInstance : Mul (PerfectClosure K p)) with
    mul_assoc := fun e f g =>
      Quot.inductionOn e fun ⟨m, x⟩ =>
        Quot.inductionOn f fun ⟨n, y⟩ =>
          Quot.inductionOn g fun ⟨s, z⟩ => by
            simp only [quot_mk_eq_mk, mk_mul_mk] -- Porting note: added this line
            apply congr_arg (Quot.mk _)
            simp only [add_assoc, mul_assoc, iterate_map_mul, ← iterate_add_apply,
              add_comm, add_left_comm]
    one := mk K p (0, 1)
    one_mul := fun e =>
      Quot.inductionOn e fun ⟨n, x⟩ =>
        congr_arg (Quot.mk _) <| by
          

Proof state:
K : Type u
inst✝² : CommRing K
p : ℕ
inst✝¹ : Fact (Nat.Prime p)
inst✝ : CharP K p
src✝ : Mul (PerfectClosure K p) := inferInstance
e : PerfectClosure K p
x✝ : ℕ × K
n : ℕ
x : K
⊢ ((0, 1).1 + (n, x).1, (⇑(frobenius K p))^[(n, x).1] (0, 1).2 * (⇑(frobenius K p))^[(0, 1).1] (n, x).2) = (n, x)

Next tactic:
simp only [RingHom.iterate_map_one, iterate_zero_apply, one_mul, zero_add]
instance : CommMonoid (PerfectClosure K p) :=
  { (inferInstance : Mul (PerfectClosure K p)) with
    mul_assoc := fun e f g =>
      Quot.inductionOn e fun ⟨m, x⟩ =>
        Quot.inductionOn f fun ⟨n, y⟩ =>
          Quot.inductionOn g fun ⟨s, z⟩ => by
            simp only [quot_mk_eq_mk, mk_mul_mk] -- Porting note: added this line
            apply congr_arg (Quot.mk _)
            simp only [add_assoc, mul_assoc, iterate_map_mul, ← iterate_add_apply,
              add_comm, add_left_comm]
    one := mk K p (0, 1)
    one_mul := fun e =>
      Quot.inductionOn e fun ⟨n, x⟩ =>
        congr_arg (Quot.mk _) <| by
          simp only [RingHom.iterate_map_one, iterate_zero_apply, one_mul, zero_add]
    mul_one := fun e =>
      Quot.inductionOn e fun ⟨n, x⟩ =>
        congr_arg (Quot.mk _) <| by
          

Proof state:
K : Type u
inst✝² : CommRing K
p : ℕ
inst✝¹ : Fact (Nat.Prime p)
inst✝ : CharP K p
src✝ : Mul (PerfectClosure K p) := inferInstance
e : PerfectClosure K p
x✝ : ℕ × K
n : ℕ
x : K
⊢ ((n, x).1 + (0, 1).1, (⇑(frobenius K p))^[(0, 1).1] (n, x).2 * (⇑(frobenius K p))^[(n, x).1] (0, 1).2) = (n, x)

Next tactic:
simp only [RingHom.iterate_map_one, iterate_zero_apply, mul_one, add_zero]