forked from coq-community/math-classes
-
Notifications
You must be signed in to change notification settings - Fork 0
/
dec_fields.v
265 lines (233 loc) · 8 KB
/
dec_fields.v
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
Require Import
Coq.setoid_ring.Field Coq.setoid_ring.Ring
MathClasses.interfaces.abstract_algebra MathClasses.interfaces.vectorspace
MathClasses.theory.fields MathClasses.theory.strong_setoids.
Require Export
MathClasses.theory.rings.
Section contents.
Context `{DecField F} `{∀ x y: F, Decision (x = y)}.
Add Ring F : (stdlib_ring_theory F).
Global Instance: ZeroProduct F.
Proof with auto.
intros x y E.
destruct (decide (x = 0)) as [? | Ex]...
right.
rewrite <-(mult_1_r y), <-(dec_recip_inverse x) by assumption.
rewrite associativity, (commutativity y), E. ring.
Qed.
Global Instance: IntegralDomain F.
Proof. split; try apply _. Qed.
Lemma dec_recip_1: / 1 = 1.
Proof.
rewrite <-(rings.mult_1_l (/1)).
apply dec_recip_inverse.
solve_propholds.
Qed.
Lemma dec_recip_distr (x y: F): / (x * y) = / x * / y.
Proof.
destruct (decide (x = 0)) as [Ex|Ex].
rewrite Ex, left_absorb, dec_recip_0. ring.
destruct (decide (y = 0)) as [Ey|Ey].
rewrite Ey, right_absorb, dec_recip_0. ring.
assert (x * y ≠ 0) as Exy by now apply mult_ne_0.
apply (left_cancellation_ne_0 (.*.) (x * y)); trivial.
transitivity (x / x * (y / y)).
rewrite !dec_recip_inverse by assumption. ring.
ring.
Qed.
Lemma dec_recip_zero x : / x = 0 ↔ x = 0.
Proof.
split; intros E.
apply stable. intros Ex.
destruct (is_ne_0 1).
rewrite <-(dec_recip_inverse x), E by assumption. ring.
rewrite E. now apply dec_recip_0.
Qed.
Lemma dec_recip_ne_0_iff x : / x ≠ 0 ↔ x ≠ 0.
Proof. now split; intros E1 E2; destruct E1; apply dec_recip_zero. Qed.
Instance dec_recip_ne_0 x : PropHolds (x ≠ 0) → PropHolds (/x ≠ 0).
Proof. intro. now apply dec_recip_ne_0_iff. Qed.
Lemma equal_by_one_quotient (x y : F) : x / y = 1 → x = y.
Proof.
intro Exy.
destruct (decide (y = 0)) as [Ey|Ey].
exfalso. apply (is_ne_0 1).
rewrite <- Exy, Ey, dec_recip_0. ring.
apply (right_cancellation_ne_0 (.*.) (/y)).
now apply dec_recip_ne_0.
now rewrite dec_recip_inverse.
Qed.
Global Instance dec_recip_inj: Injective (/).
Proof.
repeat (split; try apply _).
intros x y E.
destruct (decide (y = 0)) as [Ey|Ey].
rewrite Ey in *. rewrite dec_recip_0 in E.
now apply dec_recip_zero.
apply (right_cancellation_ne_0 (.*.) (/y)).
now apply dec_recip_ne_0.
rewrite dec_recip_inverse by assumption.
rewrite <-E, dec_recip_inverse.
easy.
apply dec_recip_ne_0_iff. rewrite E.
now apply dec_recip_ne_0.
Qed.
Global Instance dec_recip_involutive: Involutive (/).
Proof.
intros x. destruct (decide (x = 0)) as [Ex|Ex].
now rewrite Ex, !dec_recip_0.
apply (right_cancellation_ne_0 (.*.) (/x)).
now apply dec_recip_ne_0.
rewrite dec_recip_inverse by assumption.
rewrite commutativity, dec_recip_inverse.
reflexivity.
now apply dec_recip_ne_0.
Qed.
Lemma equal_dec_quotients (a b c d : F) : b ≠ 0 → d ≠ 0 → (a * d = c * b ↔ a / b = c / d).
Proof with trivial; try ring.
split; intro E.
apply (right_cancellation_ne_0 (.*.) b)...
apply (right_cancellation_ne_0 (.*.) d)...
transitivity (a * d * (b * /b))...
transitivity (c * b * (d * /d))...
rewrite E, dec_recip_inverse, dec_recip_inverse...
transitivity (a * d * 1)...
rewrite <-(dec_recip_inverse b)...
transitivity (a * / b * d * b)...
rewrite E.
transitivity (c * (d * / d) * b)...
rewrite dec_recip_inverse...
Qed.
Lemma dec_quotients (a c b d : F) : b ≠ 0 → d ≠ 0 → a / b + c / d = (a * d + c * b) / (b * d).
Proof with auto.
intros A B.
assert (a / b = (a * d) / (b * d)) as E1.
apply ->equal_dec_quotients...
ring.
intros G. destruct (zero_product b d)...
assert (c / d = (b * c) / (b * d)) as E2.
apply ->equal_dec_quotients...
ring.
intros G. destruct (zero_product b d)...
rewrite E1, E2. ring.
Qed.
Lemma dec_recip_swap_l x y: x / y = / (/ x * y).
Proof. rewrite dec_recip_distr, involutive. ring. Qed.
Lemma dec_recip_swap_r x y: / x * y = / (x / y).
Proof. rewrite dec_recip_distr, involutive. ring. Qed.
Lemma dec_recip_negate x : -(/ x) = / (-x).
Proof.
destruct (decide (x = 0)) as [Ex|Ex].
now rewrite Ex, negate_0, dec_recip_0, negate_0.
apply (left_cancellation_ne_0 (.*.) (-x)).
now apply flip_negate_ne_0.
rewrite dec_recip_inverse.
ring_simplify.
now apply dec_recip_inverse.
now apply flip_negate_ne_0.
Qed.
Instance: @VectorSpace F F Ae Aplus Amult Azero Aone Anegate Adec_recip
Ae Aplus Azero Anegate Amult.
Proof.
repeat split; repeat (try apply _).
- apply dec_recip_0.
- now apply dec_recip_inverse.
Qed.
End contents.
(* Due to bug #2528 *)
Hint Extern 7 (PropHolds (/ _ ≠ 0)) => eapply @dec_recip_ne_0 : typeclass_instances.
(* Given a decidable field we can easily construct a constructive field. *)
Section is_field.
Context `{DecField F} `{Apart F} `{!TrivialApart F} `{∀ x y: F, Decision (x = y)}.
Global Program Instance recip_dec_field: Recip F := λ x, /`x.
Instance: StrongSetoid F := dec_strong_setoid.
Global Instance: Field F.
Proof.
split; try apply _.
now apply (dec_strong_binary_morphism (+)).
now apply (dec_strong_binary_morphism (.*.)).
split; try apply _.
intros ? ? E. unfold recip, recip_dec_field.
now apply sm_proper.
intros [x Px]. rapply (dec_recip_inverse x).
now apply trivial_apart.
Qed.
Lemma dec_recip_correct (x : F) Px : / x = // x↾Px.
Proof with auto.
apply (left_cancellation_ne_0 (.*.) x).
now apply trivial_apart.
now rewrite dec_recip_inverse, reciperse_alt by now apply trivial_apart.
Qed.
End is_field.
Definition stdlib_field_theory F `{DecField F} :
Field_theory.field_theory 0 1 (+) (.*.) (λ x y, x - y) (-) (λ x y, x / y) (/) (=).
Proof with auto.
intros.
constructor.
apply (theory.rings.stdlib_ring_theory _).
apply (is_ne_0 1).
reflexivity.
intros.
rewrite commutativity. now apply dec_recip_inverse.
Qed.
Section from_stdlib_field_theory.
Context `(ftheory : @field_theory F Fzero Fone Fplus Fmult Fminus Fnegate Fdiv Frecip Fe)
(rinv_0 : Fe (Frecip Fzero) Fzero)
`{!@Setoid F Fe}
`{!Proper (Fe ==> Fe ==> Fe) Fplus}
`{!Proper (Fe ==> Fe ==> Fe) Fmult}
`{!Proper (Fe ==> Fe) Fnegate}
`{!Proper (Fe ==> Fe) Frecip}.
Add Field F2 : ftheory.
Definition from_stdlib_field_theory: @DecField F Fe Fplus Fmult Fzero Fone Fnegate Frecip.
Proof with auto.
destruct ftheory.
repeat (constructor; try assumption); repeat intro
; unfold equiv, mon_unit, sg_op, zero_is_mon_unit, plus_is_sg_op,
one_is_mon_unit, mult_is_sg_op, plus, mult, recip, negate; try field...
unfold recip, mult.
simpl.
assert (Fe (Fmult x (Frecip x)) (Fmult (Frecip x) x)) as E by ring.
rewrite E...
Qed.
End from_stdlib_field_theory.
Section morphisms.
Context `{DecField F} `{∀ x y: F, Decision (x = y)}.
Global Instance dec_field_to_domain_inj `{IntegralDomain R}
`{!SemiRing_Morphism (f : F → R)} : Injective f.
Proof.
apply injective_preserves_0.
intros x Efx.
apply stable. intros Ex.
destruct (is_ne_0 (1:R)).
rewrite <-(rings.preserves_1 (f:=f)).
rewrite <-(dec_recip_inverse x) by assumption.
rewrite rings.preserves_mult, Efx.
now apply left_absorb.
Qed.
Lemma preserves_dec_recip `{DecField F2} `{∀ x y: F2, Decision (x = y)}
`{!SemiRing_Morphism (f : F → F2)} x : f (/ x) = / f x.
Proof.
case (decide (x = 0)) as [E | E].
now rewrite E, dec_recip_0, preserves_0, dec_recip_0.
intros.
apply (left_cancellation_ne_0 (.*.) (f x)).
now apply injective_ne_0.
rewrite <-preserves_mult, 2!dec_recip_inverse.
now apply preserves_1.
now apply injective_ne_0.
easy.
Qed.
Lemma dec_recip_to_recip `{Field F2} `{!StrongSemiRing_Morphism (f : F → F2)} x Pfx :
f (/ x) = // (f x)↾Pfx.
Proof.
assert (x ≠ 0).
intros Ex.
destruct (apart_ne (f x) 0 Pfx).
now rewrite Ex, preserves_0.
apply (left_cancellation_ne_0 (.*.) (f x)).
now apply injective_ne_0.
rewrite <-preserves_mult, dec_recip_inverse, reciperse_alt by assumption.
now apply preserves_1.
Qed.
End morphisms.