@@ -11,18 +11,15 @@ module Data.Rational.Base where
11
11
open import Function using (id)
12
12
open import Data.Integer as ℤ using (ℤ; ∣_∣; +_; -[1+_])
13
13
open import Data.Nat.GCD
14
- open import Data.Nat.Divisibility as ℕDiv using (_∣_ ; divides ; ∣-antisym )
15
- open import Data.Nat.Coprimality as C using (Coprime; coprime?; Bézout-coprime)
14
+ open import Data.Nat.Divisibility as ℕDiv using (divides; 0∣⇒≡0 )
15
+ open import Data.Nat.Coprimality as C using (Coprime; Bézout-coprime)
16
16
open import Data.Nat as ℕ using (ℕ; zero; suc)
17
- import Data.Nat.Properties as ℕ
18
17
open import Data.Product
19
- open import Data.Unit using (tt)
20
18
open import Level using (0ℓ)
21
- open import Relation.Nullary.Decidable
22
- using (True; False; toWitness)
19
+ open import Relation.Nullary.Decidable using (False)
23
20
open import Relation.Nullary.Negation using (contradiction)
24
- open import Relation.Binary using (Rel; Decidable; _⇒_ )
25
- open import Relation.Binary.PropositionalEquality as P
21
+ open import Relation.Binary using (Rel)
22
+ open import Relation.Binary.PropositionalEquality
26
23
using (_≡_; refl; subst; cong; cong₂; module ≡-Reasoning )
27
24
28
25
open ≡-Reasoning
@@ -38,13 +35,17 @@ record ℚ : Set where
38
35
denominator-1 : ℕ
39
36
.isCoprime : Coprime ∣ numerator ∣ (suc denominator-1)
40
37
38
+ denominatorℕ : ℕ
39
+ denominatorℕ = suc denominator-1
40
+
41
41
denominator : ℤ
42
- denominator = + suc denominator-1
42
+ denominator = + denominatorℕ
43
43
44
44
open ℚ public using ()
45
45
renaming
46
- ( numerator to ↥_
47
- ; denominator to ↧_
46
+ ( numerator to ↥_
47
+ ; denominator to ↧_
48
+ ; denominatorℕ to ↧ₙ_
48
49
)
49
50
50
51
------------------------------------------------------------------------
@@ -53,114 +54,97 @@ open ℚ public using ()
53
54
infix 4 _≃_
54
55
55
56
_≃_ : Rel ℚ 0ℓ
56
- p ≃ q = (↥ p ℤ.* ↧ q) ≡ (↥ q) ℤ.* ( ↧ p)
57
+ p ≃ q = (↥ p ℤ.* ↧ q) ≡ (↥ q ℤ.* ↧ p)
57
58
58
59
------------------------------------------------------------------------
59
60
-- Ordering of rationals
60
61
61
62
infix 4 _≤_
62
63
63
- data _≤_ : ℚ → ℚ → Set where
64
+ data _≤_ : Rel ℚ 0ℓ where
64
65
*≤* : ∀ {p q} → (↥ p ℤ.* ↧ q) ℤ.≤ (↥ q ℤ.* ↧ p) → p ≤ q
65
66
66
67
------------------------------------------------------------------------
67
- -- Two useful lemmas to help with constructing on rationals
68
- --
69
- -- normalize takes two natural numbers, say 6 and 21 and their gcd 3, and
70
- -- returns them normalized as 2 and 7 and a proof that they are coprime
68
+ -- Negation
69
+
70
+ pattern +0 = + 0
71
+ pattern +[1+_] n = + suc n
72
+
73
+ -_ : ℚ → ℚ
74
+ - mkℚ -[1+ n ] d prf = mkℚ +[1+ n ] d prf
75
+ - mkℚ +0 d prf = mkℚ +0 d prf
76
+ - mkℚ +[1+ n ] d prf = mkℚ -[1+ n ] d prf
77
+
78
+ ------------------------------------------------------------------------
79
+ -- Constructing rationals
71
80
72
81
infix 4 _≢0
73
82
_≢0 : ℕ → Set
74
83
n ≢0 = False (n ℕ.≟ 0 )
75
84
76
- -- introducing a notation for that nasty pattern
77
- pattern ⟨_&_∧_&_⟩ p eqp q eqq = GCD.is (divides p eqp , divides q eqq) _
78
-
79
- normalize : ∀ m n g .{m≢0 : m ≢0} .{n≢0 : n ≢0} .{g≢0 : g ≢0} → GCD m n g →
80
- Σ[ p ∈ ℕ ] Σ[ q ∈ ℕ ] Coprime (suc p) (suc q) × m ℕ.* suc q ≡ n ℕ.* suc p
81
- normalize 0 n g {m≢0 = ()} _
82
- normalize m 0 g {n≢0 = ()} _
83
- normalize m n 0 {g≢0 = ()} _
84
- normalize (suc _) n g ⟨ 0 & () ∧ q & n≡qg' ⟩
85
- normalize m (suc _) g ⟨ p & m≡pg' ∧ 0 & () ⟩
86
- normalize(suc _) (suc _) (suc g) G@(⟨ suc p & refl ∧ suc q & refl ⟩)
87
- = p , q , Bézout-coprime (Bézout.identity G) , (begin
88
- (suc p ℕ.* suc g) ℕ.* suc q ≡⟨ ℕ.*-assoc (suc p) (suc g) (suc q) ⟩
89
- suc p ℕ.* (suc g ℕ.* suc q) ≡⟨ cong (suc p ℕ.*_) (ℕ.*-comm (suc g) (suc q)) ⟩
90
- suc p ℕ.* (suc q ℕ.* suc g) ≡⟨ ℕ.*-comm (suc p) _ ⟩
91
- (suc q ℕ.* suc g) ℕ.* suc p ∎)
92
-
93
- -- a version of gcd that returns a proof that the result is non-zero given
94
- -- that one of the inputs is non-zero
95
-
96
- gcd≢0 : (m n : ℕ) {m≢0 : m ≢0} → Σ[ d ∈ ℕ ] GCD m n d × d ≢0
97
- gcd≢0 m n {m≢0} with gcd m n
98
- ... | (suc d , G) = (suc d , G , tt)
99
- ... | (0 , GCD.is (0|m , _) _) with ℕDiv.0∣⇒≡0 0|m
100
- ... | refl = contradiction m≢0 id
85
+ -- A constructor for ℚ that takes two natural numbers, say 6 and 21,
86
+ -- and returns them in a normalized form, e.g. say 2 and 7
101
87
102
- pattern +0 = + 0
103
- pattern +[1+_] n = + suc n
88
+ normalize : ∀ m n .{m≢0 : m ≢0} .{n≢0 : n ≢0} → ℚ
89
+ normalize (suc m) (suc n) with gcd (suc m) (suc n)
90
+ ... | zero , GCD.is (1+m∣0 , _) _ = contradiction (0∣⇒≡0 1+m∣0) λ ()
91
+ ... | suc g , G@(GCD.is (divides (suc p) refl , divides (suc q) refl) _)
92
+ = mkℚ (+ suc p) q (Bézout-coprime (Bézout.identity G))
104
93
105
- norm-mkℚ : (n : ℤ) (d : ℕ) → .{d≢0 : d ≢0} → ℚ
106
- norm-mkℚ +0 d {d≢0} = mkℚ +0 0 (C.sym (C.1-coprimeTo 0 ))
107
- norm-mkℚ -[1+ n ] d {d≢0} =
108
- let (q , gcd , q≢0) = gcd≢0 (suc n) d
109
- (n′ , d′ , prf , eq) = normalize (suc n) d q {_} {d≢0} {q≢0} gcd
110
- in mkℚ -[1+ n′ ] d′ prf
111
- norm-mkℚ +[1+ n ] d {d≢0} =
112
- let (q , gcd , q≢0) = gcd≢0 (suc n) d
113
- (n′ , d′ , prf , eq) = normalize (suc n) d q {_} {d≢0} {q≢0} gcd
114
- in mkℚ (+ suc n′) d′ prf
94
+ -- A constructor for ℚ that (unlike mkℚ) automatically normalises it's
95
+ -- arguments. See the constants section below for how to use this operator.
115
96
116
- ------------------------------------------------------------------------------
117
- -- Operations on rationals
97
+ infixl 7 _/_
118
98
119
- infix 8 -_ 1/_
120
- infixl 7 _*_ _/_ _÷_
121
- infixl 6 _-_ _+_
122
-
123
- -- unary negation
99
+ _/_ : (n : ℤ) (d : ℕ) → .{d≢0 : d ≢0} → ℚ
100
+ _/_ +0 d {d≢0} = mkℚ +0 0 (C.sym (C.1-coprimeTo 0 ))
101
+ _/_ +[1+ n ] d {d≢0} = normalize (suc n) d {_} {d≢0}
102
+ _/_ -[1+ n ] d {d≢0} = - normalize (suc n) d {_} {d≢0}
124
103
125
- -_ : ℚ → ℚ
126
- - mkℚ -[1+ n ] d prf = mkℚ +[1+ n ] d prf
127
- - mkℚ +0 d prf = mkℚ +0 d prf
128
- - mkℚ +[1+ n ] d prf = mkℚ -[1+ n ] d prf
104
+ ------------------------------------------------------------------------------
105
+ -- Some constants
129
106
130
- -- reciprocal: requires a proof that the numerator is not zero
107
+ 0ℚ : ℚ
108
+ 0ℚ = + 0 / 1
131
109
132
- 1/_ : (p : ℚ) → .{n≢0 : ∣ ↥ p ∣ ≢0} → ℚ
133
- (1/ mkℚ +0 d prf) {()}
134
- 1/ mkℚ +[1+ n ] d prf = mkℚ +[1+ d ] n (C.sym prf)
135
- 1/ mkℚ -[1+ n ] d prf = mkℚ -[1+ d ] n (C.sym prf)
110
+ 1ℚ : ℚ
111
+ 1ℚ = + 1 / 1
136
112
137
- -- multiplication
113
+ ½ : ℚ
114
+ ½ = + 1 / 2
138
115
139
- _*_ : ℚ → ℚ → ℚ
140
- mkℚ n₁ d₁ prf₁ * mkℚ n₂ d₂ prf₂ = norm-mkℚ (n₁ ℤ.* n₂) (suc d₁ ℕ.* suc d₂)
116
+ -½ : ℚ
117
+ -½ = - ½
141
118
142
- -- division
119
+ ------------------------------------------------------------------------------
120
+ -- Operations on rationals
143
121
144
- _÷_ : (numerator : ℤ) (denominator : ℕ)
145
- .{coprime : True (coprime? ∣ numerator ∣ denominator)}
146
- {≢0 : denominator ≢0} →
147
- ℚ
148
- (n ÷ zero) {≢0 = ()}
149
- (n ÷ suc d) {c} = mkℚ n d (toWitness c)
122
+ infix 8 -_ 1/_
123
+ infixl 7 _*_ _÷_
124
+ infixl 6 _-_ _+_
150
125
151
126
-- addition
152
127
153
128
_+_ : ℚ → ℚ → ℚ
154
- mkℚ n₁ d₁ prf₁ + mkℚ n₂ d₂ prf₂ = norm-mkℚ
155
- (n₁ ℤ.* (+[1+ d₂ ]) ℤ.+ n₂ ℤ.* (+[1+ d₂ ]))
156
- (suc d₁ ℕ.* suc d₂)
129
+ p + q = (↥ p ℤ.* ↧ q ℤ.+ ↥ q ℤ.* ↧ p) / (↧ₙ p ℕ.* ↧ₙ q)
130
+
131
+ -- multiplication
132
+
133
+ _*_ : ℚ → ℚ → ℚ
134
+ p * q = (↥ p ℤ.* ↥ q) / (↧ₙ p ℕ.* ↧ₙ q)
157
135
158
136
-- subtraction
159
137
160
138
_-_ : ℚ → ℚ → ℚ
161
139
p - q = p + (- q)
162
140
163
- -- division
141
+ -- reciprocal: requires a proof that the numerator is not zero
142
+
143
+ 1/_ : (p : ℚ) → .{n≢0 : ∣ ↥ p ∣ ≢0} → ℚ
144
+ 1/ mkℚ +[1+ n ] d prf = mkℚ +[1+ d ] n (C.sym prf)
145
+ 1/ mkℚ -[1+ n ] d prf = mkℚ -[1+ d ] n (C.sym prf)
146
+
147
+ -- division: requires a proof that the denominator is not zero
164
148
165
- _/ _ : (p q : ℚ) → {n≢0 : ∣ ↥ q ∣ ≢0} → ℚ
166
- (p / q) {n≢0} = p * (1/_ q {n≢0})
149
+ _÷ _ : (p q : ℚ) → . {n≢0 : ∣ ↥ q ∣ ≢0} → ℚ
150
+ (p ÷ q) {n≢0} = p * (1/_ q {n≢0})
0 commit comments