@@ -14,24 +14,18 @@ universe u
14
14
section prio
15
15
set_option default_priority 100 -- see Note [default priority]
16
16
set_option old_structure_cmd true
17
+ /-- A Euclidean domain is an integral domain with quotient and remainder functions-/
17
18
@[protect_proj without mul_left_not_lt r_well_founded]
18
19
class euclidean_domain (α : Type u) extends comm_ring α, nontrivial α :=
19
20
(quotient : α → α → α)
20
21
(quotient_zero : ∀ a, quotient a 0 = 0 )
21
22
(remainder : α → α → α)
22
23
-- This could be changed to the same order as int.mod_add_div.
23
- -- We normally write qb+r rather than r + qb though.
24
+ -- We normally write ` qb+r` rather than ` r + qb` though.
24
25
(quotient_mul_add_remainder_eq : ∀ a b, b * quotient a b + remainder a b = a)
25
26
(r : α → α → Prop )
26
27
(r_well_founded : well_founded r)
27
28
(remainder_lt : ∀ a {b}, b ≠ 0 → r (remainder a b) b)
28
- /- `val_le_mul_left` is often not a required in definitions of a euclidean
29
- domain since given the other properties we can show there is a
30
- (noncomputable) euclidean domain α with the property `val_le_mul_left`.
31
- So potentially this definition could be split into two different ones
32
- (euclidean_domain_weak and euclidean_domain_strong) with a noncomputable
33
- function from weak to strong. I've currently divided the lemmas into
34
- strong and weak depending on whether they require `val_le_mul_left` or not. -/
35
29
(mul_left_not_lt : ∀ a {b}, b ≠ 0 → ¬r (a * b) a)
36
30
end prio
37
31
@@ -104,15 +98,15 @@ mod_eq_zero.2 (one_dvd _)
104
98
@[simp] lemma zero_mod (b : α) : 0 % b = 0 :=
105
99
mod_eq_zero.2 (dvd_zero _)
106
100
107
- @[simp] lemma div_zero (a : α) : a / 0 = 0 :=
101
+ @[simp, priority 900 ] lemma div_zero (a : α) : a / 0 = 0 :=
108
102
euclidean_domain.quotient_zero a
109
103
110
- @[simp] lemma zero_div {a : α} : 0 / a = 0 :=
104
+ @[simp, priority 900 ] lemma zero_div {a : α} : 0 / a = 0 :=
111
105
classical.by_cases
112
106
(λ a0 : a = 0 , a0.symm ▸ div_zero 0 )
113
107
(λ a0, by simpa only [zero_mul] using mul_div_cancel 0 a0)
114
108
115
- @[simp] lemma div_self {a : α} (a0 : a ≠ 0 ) : a / a = 1 :=
109
+ @[simp, priority 900 ] lemma div_self {a : α} (a0 : a ≠ 0 ) : a / a = 1 :=
116
110
by simpa only [one_mul] using mul_div_cancel 1 a0
117
111
118
112
lemma eq_div_of_mul_eq_left {a b c : α} (hb : b ≠ 0 ) (h : a * b = c) : a = c / b :=
148
142
section gcd
149
143
variable [decidable_eq α]
150
144
145
+ /-- The greatest common denominator of two elements of a Euclidean domain.
146
+ It is defined using the Euclidean algorithm. -/
151
147
def gcd : α → α → α
152
148
| a := λ b, if a0 : a = 0 then b else
153
149
have h:_ := mod_lt b a0,
@@ -195,6 +191,16 @@ gcd_eq_left.2 (one_dvd _)
195
191
@[simp] theorem gcd_self (a : α) : gcd a a = a :=
196
192
gcd_eq_left.2 (dvd_refl _)
197
193
194
+ /--
195
+ An implementation of the extended GCD algorithm.
196
+ At each step we are computing a triple `(r, s, t)`, where `r` is the next value of the GCD
197
+ algorithm, to compute the greatest common divisor of the input (say `x` and `y`), and `s` and `t`
198
+ are the coefficients in front of `x` and `y` to obtain `r` (i.e. `r = s * x + t * y`).
199
+ The function `xgcd_aux` takes in two triples, and from these recursively computes the next triple:
200
+ ```
201
+ xgcd_aux (r, s, t) (r', s', t') = xgcd_aux (r' % r, s' - (r' / r) * s, t' - (r' / r) * t) (r, s, t)
202
+ ```
203
+ -/
198
204
def xgcd_aux : α → α → α → α → α → α → α × α × α
199
205
| r := λ s t r' s' t',
200
206
if hr : r = 0 then (r', s', t')
@@ -261,6 +267,7 @@ end gcd
261
267
section lcm
262
268
variables [decidable_eq α]
263
269
270
+ /-- The least common multiple of two elements of a Euclidean domain. -/
264
271
def lcm (x y : α) : α :=
265
272
x * y / gcd x y
266
273
0 commit comments