~ubuntu-branches/ubuntu/lucid/agda-stdlib/lucid

« back to all changes in this revision

Viewing changes to src/Data/Nat/Coprimality.agda

  • Committer: Bazaar Package Importer
  • Author(s): Iain Lane
  • Date: 2010-01-08 23:35:09 UTC
  • Revision ID: james.westby@ubuntu.com-20100108233509-l6ejt9xji64xysfb
Import upstream version 0.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
------------------------------------------------------------------------
 
2
-- Coprimality
 
3
------------------------------------------------------------------------
 
4
 
 
5
module Data.Nat.Coprimality where
 
6
 
 
7
open import Data.Nat
 
8
import Data.Nat.Properties as NatProp
 
9
open import Data.Nat.Divisibility as Div
 
10
open import Data.Nat.GCD
 
11
open import Data.Nat.GCD.Lemmas
 
12
open import Data.Product as Prod
 
13
open import Data.Function
 
14
open import Relation.Binary.PropositionalEquality as PropEq
 
15
  using (_≡_; _≢_; refl)
 
16
open import Relation.Nullary
 
17
open import Relation.Binary
 
18
open import Algebra
 
19
private
 
20
  module P  = Poset Div.poset
 
21
  module CS = CommutativeSemiring NatProp.commutativeSemiring
 
22
 
 
23
-- Coprime m n is inhabited iff m and n are coprime (relatively
 
24
-- prime), i.e. if their only common divisor is 1.
 
25
 
 
26
Coprime : (m n : ℕ) → Set
 
27
Coprime m n = ∀ {i} → i ∣ m × i ∣ n → i ≡ 1
 
28
 
 
29
-- Coprime numbers have 1 as their gcd.
 
30
 
 
31
coprime-gcd : ∀ {m n} → Coprime m n → GCD m n 1
 
32
coprime-gcd {m} {n} c = GCD.is (1∣ m , 1∣ n) greatest
 
33
  where
 
34
  greatest : ∀ {d} → d ∣ m × d ∣ n → d ∣ 1
 
35
  greatest      cd with c cd
 
36
  greatest .{1} cd | refl = 1∣ 1
 
37
 
 
38
-- If two numbers have 1 as their gcd, then they are coprime.
 
39
 
 
40
gcd-coprime : ∀ {m n} → GCD m n 1 → Coprime m n
 
41
gcd-coprime g cd with GCD.greatest g cd
 
42
gcd-coprime g cd | divides q eq =
 
43
  NatProp.i*j≡1⇒j≡1 q _ (PropEq.sym eq)
 
44
 
 
45
-- Coprime is decidable.
 
46
 
 
47
private
 
48
  0≢1 : 0 ≢ 1
 
49
  0≢1 ()
 
50
 
 
51
  2+≢1 : ∀ {n} → suc (suc n) ≢ 1
 
52
  2+≢1 ()
 
53
 
 
54
coprime? : Decidable Coprime
 
55
coprime? i j with gcd i j
 
56
... | (0           , g) = no  (0≢1  ∘ GCD.unique g ∘ coprime-gcd)
 
57
... | (1           , g) = yes (λ {i} → gcd-coprime g {i})
 
58
... | (suc (suc d) , g) = no  (2+≢1 ∘ GCD.unique g ∘ coprime-gcd)
 
59
 
 
60
-- The coprimality relation is symmetric.
 
61
 
 
62
sym : ∀ {m n} → Coprime m n → Coprime n m
 
63
sym c = c ∘ swap
 
64
 
 
65
-- Everything is coprime to 1.
 
66
 
 
67
1-coprimeTo : ∀ m → Coprime 1 m
 
68
1-coprimeTo m = 1∣1 ∘ proj₁
 
69
 
 
70
-- Nothing except for 1 is coprime to 0.
 
71
 
 
72
0-coprimeTo-1 : ∀ {m} → Coprime 0 m → m ≡ 1
 
73
0-coprimeTo-1 {m} c = c (m ∣0 , P.refl)
 
74
 
 
75
-- If m and n are coprime, then n + m and n are also coprime.
 
76
 
 
77
coprime-+ : ∀ {m n} → Coprime m n → Coprime (n + m) n
 
78
coprime-+ c (d₁ , d₂) = c (∣-∸ d₁ d₂ , d₂)
 
79
 
 
80
-- If the "gcd" in Bézout's identity is non-zero, then the "other"
 
81
-- divisors are coprime.
 
82
 
 
83
Bézout-coprime : ∀ {i j d} →
 
84
                 Bézout.Identity (suc d) (i * suc d) (j * suc d) →
 
85
                 Coprime i j
 
86
Bézout-coprime (Bézout.+- x y eq) (divides q₁ refl , divides q₂ refl) =
 
87
  lem₁₀ y q₂ x q₁ eq
 
88
Bézout-coprime (Bézout.-+ x y eq) (divides q₁ refl , divides q₂ refl) =
 
89
  lem₁₀ x q₁ y q₂ eq
 
90
 
 
91
-- Coprime numbers satisfy Bézout's identity.
 
92
 
 
93
coprime-Bézout : ∀ {i j} → Coprime i j → Bézout.Identity 1 i j
 
94
coprime-Bézout = Bézout.identity ∘ coprime-gcd
 
95
 
 
96
-- If i divides jk and is coprime to j, then it divides k.
 
97
 
 
98
coprime-divisor : ∀ {k i j} → Coprime i j → i ∣ j * k → i ∣ k
 
99
coprime-divisor {k} c (divides q eq′) with coprime-Bézout c
 
100
... | Bézout.+- x y eq = divides (x * k ∸ y * q) (lem₈ x y eq eq′)
 
101
... | Bézout.-+ x y eq = divides (y * q ∸ x * k) (lem₉ x y eq eq′)
 
102
 
 
103
-- If d is a common divisor of mk and nk, and m and n are coprime,
 
104
-- then d divides k.
 
105
 
 
106
coprime-factors : ∀ {d m n k} →
 
107
                  Coprime m n → d ∣ m * k × d ∣ n * k → d ∣ k
 
108
coprime-factors c (divides q₁ eq₁ , divides q₂ eq₂) with coprime-Bézout c
 
109
... | Bézout.+- x y eq = divides (x * q₁ ∸ y * q₂) (lem₁₁ x y eq eq₁ eq₂)
 
110
... | Bézout.-+ x y eq = divides (y * q₂ ∸ x * q₁) (lem₁₁ y x eq eq₂ eq₁)
 
111
 
 
112
-- A variant of GCD.
 
113
 
 
114
data GCD′ : ℕ → ℕ → ℕ → Set where
 
115
  gcd-* : ∀ {d} q₁ q₂ (c : Coprime q₁ q₂) →
 
116
          GCD′ (q₁ * d) (q₂ * d) d
 
117
 
 
118
-- The two definitions are equivalent.
 
119
 
 
120
gcd-gcd′ : ∀ {d m n} → GCD m n d → GCD′ m n d
 
121
gcd-gcd′         g with GCD.commonDivisor g
 
122
gcd-gcd′ {zero}  g | (divides q₁ refl , divides q₂ refl)
 
123
                     with q₁ * 0 | CS.*-comm 0 q₁
 
124
                        | q₂ * 0 | CS.*-comm 0 q₂
 
125
...                  | .0 | refl | .0 | refl = gcd-* 1 1 (1-coprimeTo 1)
 
126
gcd-gcd′ {suc d} g | (divides q₁ refl , divides q₂ refl) =
 
127
  gcd-* q₁ q₂ (Bézout-coprime (Bézout.identity g))
 
128
 
 
129
gcd′-gcd : ∀ {m n d} → GCD′ m n d → GCD m n d
 
130
gcd′-gcd (gcd-* q₁ q₂ c) = GCD.is (∣-* q₁ , ∣-* q₂) (coprime-factors c)
 
131
 
 
132
-- Calculates (the alternative representation of) the gcd of the
 
133
-- arguments.
 
134
 
 
135
gcd′ : ∀ m n → ∃ λ d → GCD′ m n d
 
136
gcd′ m n = Prod.map id gcd-gcd′ (gcd m n)