-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Expand file tree
/
Copy pathBasic.lean
More file actions
244 lines (185 loc) · 8.73 KB
/
Copy pathBasic.lean
File metadata and controls
244 lines (185 loc) · 8.73 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
/-
Copyright (c) 2020 Eric Wieser. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Simon Hudon, Patrick Massot, Eric Wieser
-/
module
public import Mathlib.Algebra.Group.Defs
public import Mathlib.Algebra.Notation.Pi.Basic
public import Mathlib.Basic.Unique
public import Mathlib.Data.Sum.Basic
public import Mathlib.Tactic.Spread
/-!
# Instances and theorems on pi types
This file provides instances for the typeclass defined in `Algebra.Group.Defs`. More sophisticated
instances are defined in `Algebra.Group.Pi.Lemmas` files elsewhere.
## Porting note
This file relied on the `pi_instance` tactic, which was not available at the time of porting. The
comment `--pi_instance` is inserted before all fields which were previously derived by
`pi_instance`. See this Zulip discussion:
[https://leanprover.zulipchat.com/#narrow/stream/287929-mathlib4/topic/not.20porting.20pi_instance]
-/
@[expose] public section
-- We enforce to only import `Algebra.Group.Defs` and basic logic
assert_not_exists Set.range MonoidHom MonoidWithZero DenselyOrdered
universe u v₁ v₂ v₃
variable {I : Type u}
-- The indexing type
variable {α β γ : Type*}
-- The families of types already equipped with instances
variable {f : I → Type v₁} {g : I → Type v₂} {h : I → Type v₃}
variable (x y : ∀ i, f i) (i : I)
namespace Pi
@[to_additive]
instance isMulCommutative [∀ i, Mul (f i)] [∀ i, IsMulCommutative (f i)] :
IsMulCommutative (∀ i, f i) where
is_comm.comm _ _ := by ext; apply mul_comm'
@[to_additive]
instance commMagma [∀ i, CommMagma (f i)] : CommMagma (∀ i, f i) where
mul_comm _ _ := by ext; apply mul_comm
@[to_additive]
instance semigroup [∀ i, Semigroup (f i)] : Semigroup (∀ i, f i) where
mul_assoc := by intros; ext; exact mul_assoc _ _ _
@[to_additive]
instance commSemigroup [∀ i, CommSemigroup (f i)] : CommSemigroup (∀ i, f i) where
@[to_additive]
instance mulOneClass [∀ i, MulOneClass (f i)] : MulOneClass (∀ i, f i) where
one_mul := by intros; ext; exact one_mul _
mul_one := by intros; ext; exact mul_one _
@[to_additive]
instance invOneClass [∀ i, InvOneClass (f i)] : InvOneClass (∀ i, f i) where
inv_one := by ext; exact inv_one
@[to_additive]
instance monoid [∀ i, Monoid (f i)] : Monoid (∀ i, f i) where
__ := semigroup
__ := mulOneClass
npow := fun n x i => x i ^ n
npow_zero := by intros; ext; exact Monoid.npow_zero _
npow_succ := by intros; ext; exact Monoid.npow_succ _ _
@[to_additive]
instance commMonoid [∀ i, CommMonoid (f i)] : CommMonoid (∀ i, f i) where
@[to_additive Pi.subNegMonoid]
instance divInvMonoid [∀ i, DivInvMonoid (f i)] : DivInvMonoid (∀ i, f i) where
zpow := fun z x i => x i ^ z
div_eq_mul_inv := by intros; ext; exact div_eq_mul_inv _ _
zpow_zero' := by intros; ext; exact DivInvMonoid.zpow_zero' _
zpow_succ' := by intros; ext; exact DivInvMonoid.zpow_succ' _ _
zpow_neg' := by intros; ext; exact DivInvMonoid.zpow_neg' _ _
@[to_additive]
instance divInvOneMonoid [∀ i, DivInvOneMonoid (f i)] : DivInvOneMonoid (∀ i, f i) where
inv_one := by ext; exact inv_one
@[to_additive]
instance involutiveInv [∀ i, InvolutiveInv (f i)] : InvolutiveInv (∀ i, f i) where
inv_inv := by intros; ext; exact inv_inv _
@[to_additive]
instance divisionMonoid [∀ i, DivisionMonoid (f i)] : DivisionMonoid (∀ i, f i) where
__ := divInvMonoid
__ := involutiveInv
mul_inv_rev := by intros; ext; exact mul_inv_rev _ _
inv_eq_of_mul := by intro _ _ h; ext; exact DivisionMonoid.inv_eq_of_mul _ _ (congrFun h _)
@[to_additive instSubtractionCommMonoid]
instance divisionCommMonoid [∀ i, DivisionCommMonoid (f i)] : DivisionCommMonoid (∀ i, f i) :=
{ divisionMonoid, commSemigroup with }
@[to_additive]
instance group [∀ i, Group (f i)] : Group (∀ i, f i) where
inv_mul_cancel := by intros; ext; exact inv_mul_cancel _
@[to_additive]
instance commGroup [∀ i, CommGroup (f i)] : CommGroup (∀ i, f i) := { group, commMonoid with }
@[to_additive] instance instIsLeftCancelMul [∀ i, Mul (f i)] [∀ i, IsLeftCancelMul (f i)] :
IsLeftCancelMul (∀ i, f i) where
mul_left_cancel _ _ _ h := funext fun _ ↦ mul_left_cancel (congr_fun h _)
@[to_additive] instance instIsRightCancelMul [∀ i, Mul (f i)] [∀ i, IsRightCancelMul (f i)] :
IsRightCancelMul (∀ i, f i) where
mul_right_cancel _ _ _ h := funext fun _ ↦ mul_right_cancel (congr_fun h _)
@[to_additive] instance instIsCancelMul [∀ i, Mul (f i)] [∀ i, IsCancelMul (f i)] :
IsCancelMul (∀ i, f i) where
@[to_additive]
instance leftCancelSemigroup [∀ i, LeftCancelSemigroup (f i)] : LeftCancelSemigroup (∀ i, f i) :=
{ semigroup with mul_left_cancel := fun _ _ _ => mul_left_cancel }
@[to_additive]
instance rightCancelSemigroup [∀ i, RightCancelSemigroup (f i)] : RightCancelSemigroup (∀ i, f i) :=
{ semigroup with mul_right_cancel := fun _ _ _ => mul_right_cancel }
@[to_additive]
instance leftCancelMonoid [∀ i, LeftCancelMonoid (f i)] : LeftCancelMonoid (∀ i, f i) :=
{ leftCancelSemigroup, monoid with }
@[to_additive]
instance rightCancelMonoid [∀ i, RightCancelMonoid (f i)] : RightCancelMonoid (∀ i, f i) :=
{ rightCancelSemigroup, monoid with }
@[to_additive]
instance cancelMonoid [∀ i, CancelMonoid (f i)] : CancelMonoid (∀ i, f i) :=
{ leftCancelMonoid, rightCancelMonoid with }
@[to_additive]
instance cancelCommMonoid [∀ i, CancelCommMonoid (f i)] : CancelCommMonoid (∀ i, f i) :=
{ leftCancelMonoid, commMonoid with }
end Pi
namespace Function
section Extend
@[to_additive]
theorem extend_one [One γ] (f : α → β) : Function.extend f (1 : α → γ) (1 : β → γ) = 1 :=
funext fun _ => by apply ite_self
@[to_additive]
theorem extend_mul [Mul γ] (f : α → β) (g₁ g₂ : α → γ) (e₁ e₂ : β → γ) :
Function.extend f (g₁ * g₂) (e₁ * e₂) = Function.extend f g₁ e₁ * Function.extend f g₂ e₂ := by
classical
funext x
simp [Function.extend_def, apply_dite₂]
@[to_additive]
theorem extend_inv [Inv γ] (f : α → β) (g : α → γ) (e : β → γ) :
Function.extend f g⁻¹ e⁻¹ = (Function.extend f g e)⁻¹ := by
classical
funext x
simp [Function.extend_def, apply_dite Inv.inv]
@[to_additive]
theorem extend_div [Div γ] (f : α → β) (g₁ g₂ : α → γ) (e₁ e₂ : β → γ) :
Function.extend f (g₁ / g₂) (e₁ / e₂) = Function.extend f g₁ e₁ / Function.extend f g₂ e₂ := by
classical
funext x
simp [Function.extend_def, apply_dite₂]
end Extend
lemma comp_eq_const_iff (b : β) (f : α → β) {g : β → γ} (hg : Injective g) :
g ∘ f = Function.const _ (g b) ↔ f = Function.const _ b :=
hg.comp_left.eq_iff' rfl
@[to_additive]
lemma comp_eq_one_iff [One β] [One γ] (f : α → β) {g : β → γ} (hg : Injective g) (hg0 : g 1 = 1) :
g ∘ f = 1 ↔ f = 1 := by
simpa [hg0, const_one] using comp_eq_const_iff 1 f hg
@[to_additive]
lemma comp_ne_one_iff [One β] [One γ] (f : α → β) {g : β → γ} (hg : Injective g) (hg0 : g 1 = 1) :
g ∘ f ≠ 1 ↔ f ≠ 1 :=
(comp_eq_one_iff f hg hg0).ne
end Function
/-- If the one function is surjective, the codomain is trivial. -/
@[to_additive (attr := instance_reducible)
/-- If the zero function is surjective, the codomain is trivial. -/]
def uniqueOfSurjectiveOne (α : Type*) {β : Type*} [One β] (h : Function.Surjective (1 : α → β)) :
Unique β :=
h.uniqueOfSurjectiveConst α (1 : β)
@[to_additive]
theorem Subsingleton.pi_mulSingle_eq {α : Type*} [DecidableEq I] [Subsingleton I] [One α]
(i : I) (x : α) : Pi.mulSingle i x = fun _ => x :=
funext fun j => by rw [Subsingleton.elim j i, Pi.mulSingle_eq_same]
namespace Sum
variable (a a' : α → γ) (b b' : β → γ)
@[to_additive (attr := simp)]
theorem elim_one_one [One γ] : Sum.elim (1 : α → γ) (1 : β → γ) = 1 :=
Sum.elim_const_const 1
@[to_additive (attr := simp)]
theorem elim_mulSingle_one [DecidableEq α] [DecidableEq β] [One γ] (i : α) (c : γ) :
Sum.elim (Pi.mulSingle i c) (1 : β → γ) = Pi.mulSingle (Sum.inl i) c := by
simp only [Pi.mulSingle, Sum.elim_update_left, elim_one_one]
@[to_additive (attr := simp)]
theorem elim_one_mulSingle [DecidableEq α] [DecidableEq β] [One γ] (i : β) (c : γ) :
Sum.elim (1 : α → γ) (Pi.mulSingle i c) = Pi.mulSingle (Sum.inr i) c := by
simp only [Pi.mulSingle, Sum.elim_update_right, elim_one_one]
@[to_additive]
theorem elim_inv_inv [Inv γ] : Sum.elim a⁻¹ b⁻¹ = (Sum.elim a b)⁻¹ :=
(Sum.comp_elim Inv.inv a b).symm
@[to_additive]
theorem elim_mul_mul [Mul γ] : Sum.elim (a * a') (b * b') = Sum.elim a b * Sum.elim a' b' := by
ext x
cases x <;> rfl
@[to_additive]
theorem elim_div_div [Div γ] : Sum.elim (a / a') (b / b') = Sum.elim a b / Sum.elim a' b' := by
ext x
cases x <;> rfl
end Sum