-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Expand file tree
/
Copy pathOpposite.lean
More file actions
299 lines (218 loc) · 10.7 KB
/
Opposite.lean
File metadata and controls
299 lines (218 loc) · 10.7 KB
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
/-
Copyright (c) 2018 Kenny Lau. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Kenny Lau
-/
module
public import Mathlib.Algebra.Group.Commute.Defs
public import Mathlib.Algebra.Group.InjSurj
public import Mathlib.Algebra.Group.Torsion
public import Mathlib.Algebra.Opposites
public import Mathlib.Tactic.Conv
/-!
# Group structures on the multiplicative and additive opposites
-/
@[expose] public section
assert_not_exists MonoidWithZero DenselyOrdered Units
variable {α : Type*}
namespace MulOpposite
/-!
### Additive structures on `αᵐᵒᵖ`
-/
instance instAddSemigroup [AddSemigroup α] : AddSemigroup αᵐᵒᵖ :=
unop_injective.addSemigroup _ fun _ _ => rfl
instance instAddLeftCancelSemigroup [AddLeftCancelSemigroup α] : AddLeftCancelSemigroup αᵐᵒᵖ :=
unop_injective.addLeftCancelSemigroup _ fun _ _ => rfl
instance instAddRightCancelSemigroup [AddRightCancelSemigroup α] : AddRightCancelSemigroup αᵐᵒᵖ :=
unop_injective.addRightCancelSemigroup _ fun _ _ => rfl
instance instAddCommMagma [AddCommMagma α] : AddCommMagma αᵐᵒᵖ :=
unop_injective.addCommMagma _ fun _ _ => rfl
instance instAddCommSemigroup [AddCommSemigroup α] : AddCommSemigroup αᵐᵒᵖ :=
unop_injective.addCommSemigroup _ fun _ _ => rfl
instance instAddZeroClass [AddZeroClass α] : AddZeroClass αᵐᵒᵖ :=
unop_injective.addZeroClass _ (by exact rfl) fun _ _ => rfl
instance instAddMonoid [AddMonoid α] : AddMonoid αᵐᵒᵖ :=
unop_injective.addMonoid _ (by exact rfl) (fun _ _ => rfl) fun _ _ => rfl
instance instAddCommMonoid [AddCommMonoid α] : AddCommMonoid αᵐᵒᵖ :=
unop_injective.addCommMonoid _ rfl (fun _ _ => rfl) fun _ _ => rfl
instance instSubNegMonoid [SubNegMonoid α] : SubNegMonoid αᵐᵒᵖ :=
unop_injective.subNegMonoid _ (by exact rfl) (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl)
(fun _ _ => rfl) fun _ _ => rfl
instance instAddGroup [AddGroup α] : AddGroup αᵐᵒᵖ :=
unop_injective.addGroup _ (by exact rfl) (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl)
(fun _ _ => rfl) fun _ _ => rfl
instance instAddCommGroup [AddCommGroup α] : AddCommGroup αᵐᵒᵖ :=
unop_injective.addCommGroup _ rfl (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl)
(fun _ _ => rfl) fun _ _ => rfl
/-!
### Multiplicative structures on `αᵐᵒᵖ`
We also generate additive structures on `αᵃᵒᵖ` using `to_additive`
-/
@[to_additive]
instance instIsRightCancelMul [Mul α] [IsLeftCancelMul α] : IsRightCancelMul αᵐᵒᵖ where
mul_right_cancel _ _ _ h := unop_injective <| mul_left_cancel <| op_injective h
@[to_additive]
instance instIsLeftCancelMul [Mul α] [IsRightCancelMul α] : IsLeftCancelMul αᵐᵒᵖ where
mul_left_cancel _ _ _ h := unop_injective <| mul_right_cancel <| op_injective h
@[to_additive] instance instIsCancelMul [Mul α] [IsCancelMul α] : IsCancelMul αᵐᵒᵖ where
@[to_additive]
instance instSemigroup [Semigroup α] : Semigroup αᵐᵒᵖ where
mul_assoc x y z := unop_injective <| Eq.symm <| mul_assoc (unop z) (unop y) (unop x)
@[to_additive]
instance instLeftCancelSemigroup [RightCancelSemigroup α] : LeftCancelSemigroup αᵐᵒᵖ where
mul_left_cancel _ _ _ := mul_left_cancel
@[to_additive]
instance instRightCancelSemigroup [LeftCancelSemigroup α] : RightCancelSemigroup αᵐᵒᵖ where
mul_right_cancel _ _ _ := mul_right_cancel
@[to_additive]
instance instCommSemigroup [CommSemigroup α] : CommSemigroup αᵐᵒᵖ where
mul_comm x y := unop_injective <| mul_comm (unop y) (unop x)
@[to_additive] instance instMulOne [MulOne α] : MulOne αᵐᵒᵖ where
@[to_additive]
instance instMulOneClass [MulOneClass α] : MulOneClass αᵐᵒᵖ where
one_mul _ := unop_injective <| mul_one _
mul_one _ := unop_injective <| one_mul _
@[to_additive]
instance instMonoid [Monoid α] : Monoid αᵐᵒᵖ where
toSemigroup := instSemigroup
__ := instMulOneClass
npow n a := op <| a.unop ^ n
npow_zero _ := unop_injective <| pow_zero _
npow_succ _ _ := unop_injective <| pow_succ' _ _
@[to_additive]
instance instLeftCancelMonoid [RightCancelMonoid α] : LeftCancelMonoid αᵐᵒᵖ where
toMonoid := instMonoid
__ := instLeftCancelSemigroup
@[to_additive]
instance instRightCancelMonoid [LeftCancelMonoid α] : RightCancelMonoid αᵐᵒᵖ where
toMonoid := instMonoid
__ := instRightCancelSemigroup
@[to_additive]
instance instCancelMonoid [CancelMonoid α] : CancelMonoid αᵐᵒᵖ where
toLeftCancelMonoid := instLeftCancelMonoid
__ := instRightCancelMonoid
@[to_additive]
instance instCommMonoid [CommMonoid α] : CommMonoid αᵐᵒᵖ where
toMonoid := instMonoid
__ := instCommSemigroup
@[to_additive]
instance instCancelCommMonoid [CancelCommMonoid α] : CancelCommMonoid αᵐᵒᵖ where
toCommMonoid := instCommMonoid
__ := instLeftCancelMonoid
@[to_additive AddOpposite.instSubNegMonoid]
instance instDivInvMonoid [DivInvMonoid α] : DivInvMonoid αᵐᵒᵖ where
toMonoid := instMonoid
toInv := instInv
zpow n a := op <| a.unop ^ n
zpow_zero' _ := unop_injective <| zpow_zero _
zpow_succ' _ _ := unop_injective <| by
simp_rw [HPow.hPow, Pow.pow]
rw [unop_op, zpow_natCast, pow_succ', unop_mul, unop_op, zpow_natCast]
zpow_neg' _ _ := unop_injective <| DivInvMonoid.zpow_neg' _ _
@[to_additive]
instance instDivisionMonoid [DivisionMonoid α] : DivisionMonoid αᵐᵒᵖ where
toDivInvMonoid := instDivInvMonoid
__ := instInvolutiveInv
mul_inv_rev _ _ := unop_injective <| mul_inv_rev _ _
inv_eq_of_mul _ _ h := unop_injective <| inv_eq_of_mul_eq_one_left <| congr_arg unop h
@[to_additive AddOpposite.instSubtractionCommMonoid]
instance instDivisionCommMonoid [DivisionCommMonoid α] : DivisionCommMonoid αᵐᵒᵖ where
toDivisionMonoid := instDivisionMonoid
__ := instCommSemigroup
@[to_additive]
instance instGroup [Group α] : Group αᵐᵒᵖ where
toDivInvMonoid := instDivInvMonoid
inv_mul_cancel _ := unop_injective <| mul_inv_cancel _
@[to_additive]
instance instCommGroup [CommGroup α] : CommGroup αᵐᵒᵖ where
toGroup := instGroup
__ := instCommSemigroup
section Monoid
variable [Monoid α]
@[to_additive (attr := simp)] lemma op_pow (x : α) (n : ℕ) : op (x ^ n) = op x ^ n := rfl
@[to_additive (attr := simp)] lemma unop_pow (x : αᵐᵒᵖ) (n : ℕ) : unop (x ^ n) = unop x ^ n := rfl
end Monoid
section DivInvMonoid
variable [DivInvMonoid α]
@[to_additive (attr := simp)] lemma op_zpow (x : α) (z : ℤ) : op (x ^ z) = op x ^ z := rfl
@[to_additive (attr := simp)] lemma unop_zpow (x : αᵐᵒᵖ) (z : ℤ) : unop (x ^ z) = unop x ^ z := rfl
end DivInvMonoid
@[to_additive (attr := simp)]
theorem unop_div [DivInvMonoid α] (x y : αᵐᵒᵖ) : unop (x / y) = (unop y)⁻¹ * unop x :=
rfl
@[to_additive (attr := simp)]
theorem op_div [DivInvMonoid α] (x y : α) : op (x / y) = (op y)⁻¹ * op x := by simp [div_eq_mul_inv]
@[to_additive (attr := simp)]
theorem semiconjBy_op [Mul α] {a x y : α} : SemiconjBy (op a) (op y) (op x) ↔ SemiconjBy a x y := by
simp only [SemiconjBy, ← op_mul, op_inj, eq_comm]
@[to_additive (attr := simp, nolint simpComm)]
theorem semiconjBy_unop [Mul α] {a x y : αᵐᵒᵖ} :
SemiconjBy (unop a) (unop y) (unop x) ↔ SemiconjBy a x y := by
conv_rhs => rw [← op_unop a, ← op_unop x, ← op_unop y, semiconjBy_op]
attribute [nolint simpComm] AddOpposite.addSemiconjBy_unop
@[to_additive]
theorem _root_.SemiconjBy.op [Mul α] {a x y : α} (h : SemiconjBy a x y) :
SemiconjBy (op a) (op y) (op x) :=
semiconjBy_op.2 h
@[to_additive]
theorem _root_.SemiconjBy.unop [Mul α] {a x y : αᵐᵒᵖ} (h : SemiconjBy a x y) :
SemiconjBy (unop a) (unop y) (unop x) :=
semiconjBy_unop.2 h
@[to_additive]
theorem _root_.Commute.op [Mul α] {x y : α} (h : Commute x y) : Commute (op x) (op y) :=
SemiconjBy.op h
@[to_additive]
nonrec theorem _root_.Commute.unop [Mul α] {x y : αᵐᵒᵖ} (h : Commute x y) :
Commute (unop x) (unop y) :=
h.unop
@[to_additive (attr := simp)]
theorem commute_op [Mul α] {x y : α} : Commute (op x) (op y) ↔ Commute x y :=
semiconjBy_op
@[to_additive (attr := simp, nolint simpComm)]
theorem commute_unop [Mul α] {x y : αᵐᵒᵖ} : Commute (unop x) (unop y) ↔ Commute x y :=
semiconjBy_unop
attribute [nolint simpComm] AddOpposite.addCommute_unop
@[to_additive] protected theorem isDedekindFiniteMonoid_iff [MulOne α] :
IsDedekindFiniteMonoid αᵐᵒᵖ ↔ IsDedekindFiniteMonoid α := by
simp_rw [isDedekindFiniteMonoid_iff, ← opEquiv.forall_congr_right]
simpa [← op_one, ← op_mul] using forall_comm
@[to_additive] instance [MulOne α] [IsDedekindFiniteMonoid α] : IsDedekindFiniteMonoid αᵐᵒᵖ :=
MulOpposite.isDedekindFiniteMonoid_iff.mpr ‹_›
end MulOpposite
/-!
### Multiplicative structures on `αᵃᵒᵖ`
-/
namespace AddOpposite
instance instSemigroup [Semigroup α] : Semigroup αᵃᵒᵖ := unop_injective.semigroup _ fun _ _ ↦ rfl
instance instLeftCancelSemigroup [LeftCancelSemigroup α] : LeftCancelSemigroup αᵃᵒᵖ :=
unop_injective.leftCancelSemigroup _ fun _ _ => rfl
instance instRightCancelSemigroup [RightCancelSemigroup α] : RightCancelSemigroup αᵃᵒᵖ :=
unop_injective.rightCancelSemigroup _ fun _ _ => rfl
instance instCommSemigroup [CommSemigroup α] : CommSemigroup αᵃᵒᵖ :=
unop_injective.commSemigroup _ fun _ _ => rfl
instance instMulOneClass [MulOneClass α] : MulOneClass αᵃᵒᵖ :=
unop_injective.mulOneClass _ (by exact rfl) fun _ _ => rfl
instance pow {β} [Pow α β] : Pow αᵃᵒᵖ β where pow a b := op (unop a ^ b)
@[simp]
theorem op_pow {β} [Pow α β] (a : α) (b : β) : op (a ^ b) = op a ^ b :=
rfl
@[simp]
theorem unop_pow {β} [Pow α β] (a : αᵃᵒᵖ) (b : β) : unop (a ^ b) = unop a ^ b :=
rfl
instance instMonoid [Monoid α] : Monoid αᵃᵒᵖ :=
unop_injective.monoid _ (by exact rfl) (fun _ _ => rfl) fun _ _ => rfl
instance instCommMonoid [CommMonoid α] : CommMonoid αᵃᵒᵖ :=
unop_injective.commMonoid _ (by exact rfl) (fun _ _ => rfl) fun _ _ => rfl
instance instDivInvMonoid [DivInvMonoid α] : DivInvMonoid αᵃᵒᵖ :=
unop_injective.divInvMonoid _ (by exact rfl) (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl)
(fun _ _ => rfl) fun _ _ => rfl
instance instGroup [Group α] : Group αᵃᵒᵖ :=
unop_injective.group _ (by exact rfl) (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl)
(fun _ _ => rfl) fun _ _ => rfl
instance instCommGroup [CommGroup α] : CommGroup αᵃᵒᵖ :=
unop_injective.commGroup _ (by exact rfl) (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl)
(fun _ _ => rfl) fun _ _ => rfl
@[to_additive]
instance instMulTorsionFree [Monoid α] [IsMulTorsionFree α] : IsMulTorsionFree αᵐᵒᵖ :=
⟨fun _ h ↦ op_injective.comp <| (pow_left_injective h).comp <| unop_injective⟩
end AddOpposite