-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
-
22
-
23
-
24
-
25
-
26
-
27
-
28
-
29
-
30
-
31
-
32
-
33
-
34
-
35
-
36
-
37
-
38
-
39
-
40
-
41
-
42
-
43
-
44
-
45
-
46
-
47
-
48
-
49
-
50
-
51
-
52
-
53
-
54
-
55
-
56
-
57
-
58
-
59
-
60
-
61
-
62
-
63
-
64
-
65
-
66
-
67
-
68
-
69
-
70
-
71
-
72
-
73
-
74
-
75
-
76
-
77
-
78
-
79
-
80
-
81
-
82
-
83
-
84
-
85
-
86
-
87
-
88
-
89
-
90
-
91
-
92
-
93
-
94
-
95
-
96
-
97
-
98
-
99
-
100
-
101
-
102
-
103
-
104
-
105
-
106
-
107
-
108
-
109
-
110
-
111
-
112
-
113
-
114
-
115
-
116
-
117
-
118
-
119
-
120
-
121
-
122
-
123
-
124
-
125
-
126
-
127
-
128
-
129
-
130
-
131
-
132
-
133
-
134
-
135
-
136
-
137
-
138
-
139
-
140
-
141
-
142
-
143
-
144
-
145
-
146
-
147
-
148
-
149
-
150
-
151
-
152
-
153
-
154
-
155
-
156
-
157
-
158
-
159
-
160
-
161
-
162
-
163
-
164
-
165
-
166
-
167
-
168
-
169
-
170
-
171
-
172
-
173
-
174
-
175
-
176
-
177
-
178
-
179
-
180
-
181
-
182
-
183
-
184
-
185
-
186
-
187
-
188
-
189
-
190
-
191
-
192
-
193
-
194
-
195
-
196
-
197
-
198
-
199
-
200
-
201
-
202
-
203
-
204
-
205
-
206
-
207
-
208
-
209
-
210
-
211
-
212
-
213
-
214
-
215
-
216
-
217
-
218
-
219
-
220
-
221
-
222
-
223
-
224
-
225
-
226
-
227
-
228
-
229
-
230
-
231
-
232
-
233
-
234
-
235
-
236
-
237
-
238
-
239
-
240
-
241
-
242
-
243
-
244
-
245
-
246
-
247
-
248
-
249
-
250
-
251
-
252
-
253
-
254
-
255
-
256
-
257
-
258
-
259
-
260
-
261
-
262
-
263
-
264
-
265
-
266
-
267
-
268
-
269
-
270
-
271
-
272
-
273
-
274
-
275
-
276
-
277
-
278
-
279
-
280
-
281
-
282
-
283
-
284
-
285
-
286
-
287
-
288
-
289
-
290
-
291
-
292
-
293
-
294
-
295
-
296
-
297
-
298
-
299
-
300
-
301
-
302
-
303
-
304
-
305
-
306
-
307
-
308
-
309
import Mathlib.Tactic.LibrarySearch
import Mathlib.Algebra.BigOperators.Ring
import Mathlib.Data.Real.Basic
class One₁ (α : Type) where
/-- The element one -/
one : α
#check One₁.one -- One₁.one {α : Type} [self : One₁ α] : α
@[class] structure One₂ (α : Type) where
/-- The element one -/
one : α
#check One₂.one
example (α : Type) [One₁ α] : α := One₁.one
example (α : Type) [One₁ α] := (One₁.one : α)
@[inherit_doc]
notation "𝟙" => One₁.one
example {α : Type} [One₁ α] : α := 𝟙
example {α : Type} [One₁ α] : (𝟙 : α) = 𝟙 := rfl
class Dia₁ (α : Type) where
dia : α → α → α
infixl:70 " ⋄ " => Dia₁.dia
class Semigroup₁ (α : Type) where
toDia₁ : Dia₁ α
/-- Diamond is associative -/
dia_assoc : ∀ a b c : α, a ⋄ b ⋄ c = a ⋄ (b ⋄ c)
attribute [instance] Semigroup₁.toDia₁
example {α : Type} [Semigroup₁ α] (a b : α) : α := a ⋄ b
class Semigroup₂ (α : Type) extends Dia₁ α where
/-- Diamond is associative -/
dia_assoc : ∀ a b c : α, a ⋄ b ⋄ c = a ⋄ (b ⋄ c)
example {α : Type} [Semigroup₂ α] (a b : α) : α := a ⋄ b
class DiaOneClass₁ (α : Type) extends One₁ α, Dia₁ α where
/-- One is a left neutral element for diamond. -/
one_dia : ∀ a : α, 𝟙 ⋄ a = a
/-- One is a right neutral element for diamond -/
dia_one : ∀ a : α, a ⋄ 𝟙 = a
set_option trace.Meta.synthInstance true in
example {α : Type} [DiaOneClass₁ α] (a b : α) : Prop := a ⋄ b = 𝟙
class Monoid₁ (α : Type) extends Semigroup₁ α, DiaOneClass₁ α
class Monoid₂ (α : Type) where
toSemigroup₁ : Semigroup₁ α
toDiaOneClass₁ : DiaOneClass₁ α
example {α : Type} [Monoid₁ α] :
(Monoid₁.toSemigroup₁.toDia₁.dia : α → α → α) = Monoid₁.toDiaOneClass₁.toDia₁.dia := rfl
/- Monoid₂.mk {α : Type} (toSemigroup₁ : Semigroup₁ α) (toDiaOneClass₁ : DiaOneClass₁ α) : Monoid₂ α -/
#check Monoid₂.mk
/- Monoid₁.mk {α : Type} [toSemigroup₁ : Semigroup₁ α] [toOne₁ : One₁ α] (one_dia : ∀ (a : α), 𝟙 ⋄ a = a) (dia_one : ∀ (a : α), a ⋄ 𝟙 = a) : Monoid₁ α -/
#check Monoid₁.mk
#check Monoid₁.toSemigroup₁
#check Monoid₁.toDiaOneClass₁
class Inv₁ (α : Type) where
/-- The inversion function -/
inv : α → α
@[inherit_doc]
postfix:max "⁻¹" => Inv₁.inv
class Group₁ (G : Type) extends Monoid₁ G, Inv G where
inv_dia : ∀ a : G, a⁻¹ ⋄ a = 𝟙
lemma left_inv_eq_right_inv₁ {M : Type} [Monoid₁ M] {a b c : M} (hba : b ⋄ a = 𝟙) (hac : a ⋄ c = 𝟙) : b = c := by
rw [← DiaOneClass₁.one_dia c, ← hba, Semigroup₁.dia_assoc, hac, DiaOneClass₁.dia_one b]
export DiaOneClass₁ (one_dia dia_one)
export Semigroup₁ (dia_assoc)
export Group₁ (inv_dia)
example {M : Type} [Monoid₁ M] {a b c : M} (hba : b ⋄ a = 𝟙) (hac : a ⋄ c = 𝟙) : b = c := by
rw [← one_dia c, ← hba, dia_assoc, hac, dia_one b]
lemma inv_eq_of_dia [Group₁ G] {a b : G} (h : a ⋄ b = 𝟙) : a⁻¹ = b :=
sorry
lemma dia_inv [Group₁ G] (a : G) : a ⋄ a⁻¹ = 𝟙 :=
sorry
class AddSemigroup₃ (α : Type) extends Add α where
/-- Addition is associative -/
add_assoc₃ : ∀ a b c : α, a + b + c = a + (b + c)
@[to_additive AddSemigroup₃]
class Semigroup₃ (α : Type) extends Mul α where
/-- Multiplication is associative -/
mul_assoc₃ : ∀ a b c : α, a * b * c = a * (b * c)
class AddMonoid₃ (α : Type) extends AddSemigroup₃ α, AddZeroClass α
@[to_additive AddMonoid₃]
class Monoid₃ (α : Type) extends Semigroup₃ α, MulOneClass α
attribute [to_additive existing] Monoid₃.toMulOneClass
export Semigroup₃ (mul_assoc₃)
export AddSemigroup₃ (add_assoc₃)
whatsnew in
@[to_additive]
lemma left_inv_eq_right_inv' {M : Type} [Monoid₃ M] {a b c : M} (hba : b * a = 1) (hac : a * c = 1) : b = c := by
rw [← one_mul c, ← hba, mul_assoc₃, hac, mul_one b]
#check left_neg_eq_right_neg'
class AddCommSemigroup₃ (α : Type) extends AddSemigroup₃ α where
add_comm : ∀ a b : α, a + b = b + a
@[to_additive AddCommSemigroup₃]
class CommSemigroup₃ (α : Type) extends Semigroup₃ α where
mul_comm : ∀ a b : α, a * b = b * a
class AddCommMonoid₃ (α : Type) extends AddMonoid₃ α, AddCommSemigroup₃ α
@[to_additive AddCommMonoid₃]
class CommMonoid₃ (α : Type) extends Monoid₃ α, CommSemigroup₃ α
class AddGroup₃ (G : Type) extends AddMonoid₃ G, Neg G where
neg_add : ∀ a : G, -a + a = 0
@[to_additive AddGroup₃]
class Group₃ (G : Type) extends Monoid₃ G, Inv G where
inv_mul : ∀ a : G, a⁻¹ * a = 1
attribute [simp] Group₃.inv_mul AddGroup₃.neg_add
@[to_additive]
lemma inv_eq_of_mul [Group₃ G] {a b : G} (h : a * b = 1) : a⁻¹ = b :=
sorry
@[to_additive (attr := simp)]
lemma Group₃.mul_inv {G : Type} [Group₃ G] {a : G} : a * a⁻¹ = 1 := by
sorry
@[to_additive]
lemma mul_left_cancel₃ {G : Type} [Group₃ G] {a b c : G} (h : a * b = a * c) : b = c := by
sorry
@[to_additive]
lemma mul_right_cancel₃ {G : Type} [Group₃ G] {a b c : G} (h : b*a = c*a) : b = c := by
sorry
class AddCommGroup₃ (G : Type) extends AddGroup₃ G, AddCommMonoid₃ G
@[to_additive AddCommGroup₃]
class CommGroup₃ (G : Type) extends Group₃ G, CommMonoid₃ G
class Ring₃ (R : Type) extends AddGroup₃ R, Monoid₃ R, MulZeroClass R where
/-- Multiplication is left distributive over addition -/
left_distrib : ∀ a b c : R, a * (b + c) = a * b + a * c
/-- Multiplication is right distributive over addition -/
right_distrib : ∀ a b c : R, (a + b) * c = a * c + b * c
instance {R : Type} [Ring₃ R] : AddCommGroup₃ R :=
{ Ring₃.toAddGroup₃ with
add_comm := by
sorry }
instance : Ring₃ ℤ where
add := (· + ·)
add_assoc₃ := add_assoc
zero := 0
zero_add := by simp
add_zero := by simp
neg := (- ·)
neg_add := by simp
mul := (· * ·)
mul_assoc₃ := mul_assoc
one := 1
one_mul := by simp
mul_one := by simp
zero_mul := by simp
mul_zero := by simp
left_distrib := Int.mul_add
right_distrib := Int.add_mul
class LE₁ (α : Type) where
/-- The Less-or-Equal relation. -/
le : α → α → Prop
@[inherit_doc] infix:50 " ≤₁ " => LE₁.le
class Preorder₁ (α : Type)
class PartialOrder₁ (α : Type)
class OrderedCommMonoid₁ (α : Type)
instance : OrderedCommMonoid₁ ℕ where
class SMul₃ (α : Type) (β : Type) where
/-- Scalar multiplication -/
smul : α → β → β
infixr:73 " • " => SMul₃.smul
class Module₁ (R : Type) [Ring₃ R] (M : Type) [AddCommGroup₃ M] extends SMul₃ R M where
zero_smul : ∀ m : M, (0 : R) • m = 0
one_smul : ∀ m : M, (1 : R) • m = m
mul_smul : ∀ (a b : R) (m : M), (a * b) • m = a • b • m
add_smul : ∀ (a b : R) (m : M), (a + b) • m = a • m + b • m
smul_add : ∀ (a : R) (m n : M), a • (m + n) = a • m + a • n
instance selfModule (R : Type) [Ring₃ R] : Module₁ R R where
smul := fun r s ↦ r*s
zero_smul := zero_mul
one_smul := one_mul
mul_smul := mul_assoc₃
add_smul := Ring₃.right_distrib
smul_add := Ring₃.left_distrib
def nsmul₁ [Zero M] [Add M] : ℕ → M → M
| 0, _ => 0
| n + 1, a => a + nsmul₁ n a
def zsmul₁ {M : Type _} [Zero M] [Add M] [Neg M] : ℤ → M → M
| Int.ofNat n, a => nsmul₁ n a
| Int.negSucc n, a => -nsmul₁ n.succ a
instance abGrpModule (A : Type) [AddCommGroup₃ A] : Module₁ ℤ A where
smul := zsmul₁
zero_smul := sorry
one_smul := sorry
mul_smul := sorry
add_smul := sorry
smul_add := sorry
#synth Module₁ ℤ ℤ -- abGrpModule ℤ
class AddMonoid₄ (M : Type) extends AddSemigroup₃ M, AddZeroClass M where
/-- Multiplication by a natural number. -/
nsmul : ℕ → M → M := nsmul₁
/-- Multiplication by `(0 : ℕ)` gives `0`. -/
nsmul_zero : ∀ x, nsmul 0 x = 0 := by intros; rfl
/-- Multiplication by `(n + 1 : ℕ)` behaves as expected. -/
nsmul_succ : ∀ (n : ℕ) (x), nsmul (n + 1) x = x + nsmul n x := by intros; rfl
instance mySMul {M : Type} [AddMonoid₄ M] : SMul ℕ M := ⟨AddMonoid₄.nsmul⟩
instance (M N : Type) [AddMonoid₄ M] [AddMonoid₄ N] : AddMonoid₄ (M × N) where
add := fun p q ↦ (p.1 + q.1, p.2 + q.2)
add_assoc₃ := fun a b c ↦ by ext <;> apply add_assoc₃
zero := (0, 0)
zero_add := fun a ↦ by ext <;> apply zero_add
add_zero := fun a ↦ by ext <;> apply add_zero
instance : AddMonoid₄ ℤ where
add := (· + ·)
add_assoc₃ := Int.add_assoc
zero := 0
zero_add := Int.zero_add
add_zero := Int.add_zero
nsmul := fun n m ↦ (n : ℤ) * m
nsmul_zero := Int.zero_mul
nsmul_succ := fun n m ↦ show (n + 1 : ℤ) * m = m + n * m
by rw [Int.add_mul, Int.add_comm, Int.one_mul]
example (n : ℕ) (m : ℤ) : SMul.smul (self := mySMul) n m = n * m := rfl