mathematics_in_lean

My solutions for this book

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
  42. 42
  43. 43
  44. 44
  45. 45
  46. 46
  47. 47
  48. 48
  49. 49
  50. 50
  51. 51
  52. 52
  53. 53
  54. 54
  55. 55
  56. 56
  57. 57
  58. 58
  59. 59
  60. 60
  61. 61
  62. 62
  63. 63
  64. 64
  65. 65
  66. 66
  67. 67
  68. 68
  69. 69
  70. 70
  71. 71
  72. 72
  73. 73
  74. 74
  75. 75
  76. 76
  77. 77
  78. 78
  79. 79
  80. 80
  81. 81
  82. 82
  83. 83
  84. 84
  85. 85
  86. 86
  87. 87
  88. 88
  89. 89
  90. 90
  91. 91
  92. 92
  93. 93
  94. 94
  95. 95
  96. 96
  97. 97
  98. 98
  99. 99
  100. 100
  101. 101
  102. 102
  103. 103
  104. 104
  105. 105
  106. 106
  107. 107
  108. 108
  109. 109
  110. 110
  111. 111
  112. 112
  113. 113
  114. 114
  115. 115
  116. 116
  117. 117
  118. 118
  119. 119
  120. 120
  121. 121
  122. 122
  123. 123
  124. 124
  125. 125
  126. 126
import Mathlib.Tactic
import Mathlib.GroupTheory.QuotientGroup



@[ext]
structure Submonoid₁ (M : Type) [Monoid M] where
  /-- The carrier of a submonoid. -/
  carrier : Set M
  /-- The product of two elements of a submonoid belongs to the submonoid. -/
  mul_mem {a b} : a  carrier  b  carrier  a * b  carrier
  /-- The unit element belongs to the submonoid. -/
  one_mem : 1  carrier

/-- Submonoids in `M` can be seen as sets in `M`. -/
instance [Monoid M] : SetLike (Submonoid₁ M) M where
  coe := Submonoid₁.carrier
  coe_injective' := Submonoid₁.ext



example [Monoid M] (N : Submonoid₁ M) : 1  N := N.one_mem

example [Monoid M] (N : Submonoid₁ M) (α : Type) (f : M  α) := f '' N


example [Monoid M] (N : Submonoid₁ M) (x : N) : (x : M)  N := x.property


instance SubMonoid₁Monoid [Monoid M] (N : Submonoid₁ M) : Monoid N where
  mul := fun x y  x*y, N.mul_mem x.property y.property
  mul_assoc := fun x y z  SetCoe.ext (mul_assoc (x : M) y z)
  one := 1, N.one_mem
  one_mul := fun x  SetCoe.ext (one_mul (x : M))
  mul_one := fun x  SetCoe.ext (mul_one (x : M))


example [Monoid M] (N : Submonoid₁ M) : Monoid N where
  mul := fun x, hx y, hy  x*y, N.mul_mem hx hy
  mul_assoc := fun x, _ y, _ z, _  SetCoe.ext (mul_assoc x y z)
  one := 1, N.one_mem
  one_mul := fun x, _  SetCoe.ext (one_mul x)
  mul_one := fun x, _  SetCoe.ext (mul_one x)


class SubmonoidClass₁ (S : Type) (M : Type) [Monoid M] [SetLike S M] : Prop where
  mul_mem :  (s : S) {a b : M}, a  s  b  s  a * b  s
  one_mem :  s : S, 1  s

instance [Monoid M] : SubmonoidClass₁ (Submonoid₁ M) M where
  mul_mem := Submonoid₁.mul_mem
  one_mem := Submonoid₁.one_mem

@[ext]
structure Subgroup₁ (G : Type) [Group G] extends Submonoid₁ G where
  /-- The inverse of an element of a subgroup belongs to the subgroup. -/
  inv_mem {a} : a  carrier  a⁻¹  carrier


/-- Subgroups in `M` can be seen as sets in `M`. -/
instance [Group G] : SetLike (Subgroup₁ G) G where
  coe := fun H  H.toSubmonoid₁.carrier
  coe_injective' := Subgroup₁.ext

instance [Group G] (H : Subgroup₁ G) : Group H :=
{ SubMonoid₁Monoid H.toSubmonoid₁ with
  inv := fun x  x⁻¹, H.inv_mem x.property
  mul_left_inv := fun x  SetCoe.ext (mul_left_inv (x : G)) }

class SubgroupClass₁ (S : Type*) (G : Type) [Group G] [SetLike S G]
    extends SubmonoidClass₁ S G  : Prop where
  inv_mem :  (s : S) {a : G}, a  s  a⁻¹  s

instance [Group G] : SubmonoidClass₁ (Subgroup₁ G) G where
  mul_mem := fun H  H.toSubmonoid₁.mul_mem
  one_mem := fun H  H.toSubmonoid₁.one_mem

instance [Group G] : SubgroupClass₁ (Subgroup₁ G) G :=
{ (inferInstance : SubmonoidClass₁ (Subgroup₁ G) G) with
  inv_mem := Subgroup₁.inv_mem }


instance [Monoid M] : Inf (Submonoid₁ M) :=
  fun S₁ S₂ 
    { carrier := S₁  S₂
      one_mem := S₁.one_mem, S₂.one_mem
      mul_mem := fun hx, hx' hy, hy'  S₁.mul_mem hx hy, S₂.mul_mem hx' hy' }


example [Monoid M] (N P : Submonoid₁ M) : Submonoid₁ M := N  P


def Submonoid.Setoid [CommMonoid M] (N : Submonoid M) : Setoid M  where
  r := fun x y   w  N,  z  N, x*w = y*z
  iseqv := {
    refl := fun x  1, N.one_mem, 1, N.one_mem, rfl
    symm := fun w, hw, z, hz, h  z, hz, w, hw, h.symm
    trans := by
      rintro a b c w, hw, z, hz, h w', hw', z', hz', h'
      refine w*w', N.mul_mem hw hw', z*z', N.mul_mem hz hz', ?_
      rw [ mul_assoc, h, mul_comm b, mul_assoc, h',  mul_assoc, mul_comm z, mul_assoc]
  }

instance [CommMonoid M] : HasQuotient M (Submonoid M) where
  quotient' := fun N  Quotient N.Setoid

def QuotientMonoid.mk [CommMonoid M] (N : Submonoid M) : M  M  N := Quotient.mk N.Setoid

instance [CommMonoid M] (N : Submonoid M) : Monoid (M  N) where
  mul := Quotient.map₂' (· * ·) (by
    rintro a₁ b₁ w, hw, z, hz, ha a₂ b₂ w', hw', z', hz', hb
    refine w*w', N.mul_mem hw hw', z*z', N.mul_mem hz hz', ?_
    rw [mul_comm w,  mul_assoc, mul_assoc a₁, hb, mul_comm,  mul_assoc, mul_comm w, ha,
        mul_assoc, mul_comm z, mul_assoc b₂, mul_comm z', mul_assoc]
        )
  mul_assoc := by
    rintro a b c
    apply Quotient.sound
    dsimp only
    rw [mul_assoc]
    apply @Setoid.refl M N.Setoid
  one := QuotientMonoid.mk N 1
  one_mul := by
    rintro a ; apply Quotient.sound ; dsimp only ; rw [one_mul] ; apply @Setoid.refl M N.Setoid
  mul_one := by
    rintro a ; apply Quotient.sound ; dsimp only ; rw [mul_one] ; apply @Setoid.refl M N.Setoid