~ubuntu-branches/ubuntu/raring/agda-stdlib/raring-proposed

« back to all changes in this revision

Viewing changes to src/Data/Nat/Properties.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
Tags: upstream-0.3
Import upstream version 0.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
------------------------------------------------------------------------
 
2
-- A bunch of properties about natural number operations
 
3
------------------------------------------------------------------------
 
4
 
 
5
-- See README.Nat for some examples showing how this module can be
 
6
-- used.
 
7
 
 
8
module Data.Nat.Properties where
 
9
 
 
10
open import Data.Nat as Nat
 
11
open ≤-Reasoning
 
12
  renaming (begin_ to start_; _∎ to _□; _≡⟨_⟩_ to _≡⟨_⟩'_)
 
13
open import Relation.Binary
 
14
open DecTotalOrder Nat.decTotalOrder using () renaming (refl to ≤-refl)
 
15
open import Data.Function
 
16
open import Algebra
 
17
open import Algebra.Structures
 
18
open import Relation.Nullary
 
19
open import Relation.Binary.PropositionalEquality as PropEq
 
20
  using (_≡_; _≢_; refl; sym; cong; cong₂)
 
21
open PropEq.≡-Reasoning
 
22
import Algebra.FunctionProperties as P; open P _≡_
 
23
open import Data.Product
 
24
 
 
25
------------------------------------------------------------------------
 
26
-- (ℕ, +, *, 0, 1) is a commutative semiring
 
27
 
 
28
private
 
29
 
 
30
  +-assoc : Associative _+_
 
31
  +-assoc zero    _ _ = refl
 
32
  +-assoc (suc m) n o = cong suc $ +-assoc m n o
 
33
 
 
34
  +-identity : Identity 0 _+_
 
35
  +-identity = (λ _ → refl) , n+0≡n
 
36
    where
 
37
    n+0≡n : RightIdentity 0 _+_
 
38
    n+0≡n zero    = refl
 
39
    n+0≡n (suc n) = cong suc $ n+0≡n n
 
40
 
 
41
  m+1+n≡1+m+n : ∀ m n → m + suc n ≡ suc (m + n)
 
42
  m+1+n≡1+m+n zero    n = refl
 
43
  m+1+n≡1+m+n (suc m) n = cong suc (m+1+n≡1+m+n m n)
 
44
 
 
45
  +-comm : Commutative _+_
 
46
  +-comm zero    n = sym $ proj₂ +-identity n
 
47
  +-comm (suc m) n =
 
48
    begin
 
49
      suc m + n
 
50
    ≡⟨ refl ⟩
 
51
      suc (m + n)
 
52
    ≡⟨ cong suc (+-comm m n) ⟩
 
53
      suc (n + m)
 
54
    ≡⟨ sym (m+1+n≡1+m+n n m) ⟩
 
55
      n + suc m
 
56
    ∎
 
57
 
 
58
  m*1+n≡m+mn : ∀ m n → m * suc n ≡ m + m * n
 
59
  m*1+n≡m+mn zero    n = refl
 
60
  m*1+n≡m+mn (suc m) n =
 
61
    begin
 
62
      suc m * suc n
 
63
    ≡⟨ refl ⟩
 
64
      suc n + m * suc n
 
65
    ≡⟨ cong (λ x → suc n + x) (m*1+n≡m+mn m n) ⟩
 
66
      suc n + (m + m * n)
 
67
    ≡⟨ refl ⟩
 
68
      suc (n + (m + m * n))
 
69
    ≡⟨ cong suc (sym $ +-assoc n m (m * n)) ⟩
 
70
      suc (n + m + m * n)
 
71
    ≡⟨ cong (λ x → suc (x + m * n)) (+-comm n m) ⟩
 
72
      suc (m + n + m * n)
 
73
    ≡⟨ cong suc (+-assoc m n (m * n)) ⟩
 
74
      suc (m + (n + m * n))
 
75
    ≡⟨ refl ⟩
 
76
      suc m + suc m * n
 
77
    ∎
 
78
 
 
79
  *-zero : Zero 0 _*_
 
80
  *-zero = (λ _ → refl) , n*0≡0
 
81
    where
 
82
    n*0≡0 : RightZero 0 _*_
 
83
    n*0≡0 zero    = refl
 
84
    n*0≡0 (suc n) = n*0≡0 n
 
85
 
 
86
  *-comm : Commutative _*_
 
87
  *-comm zero    n = sym $ proj₂ *-zero n
 
88
  *-comm (suc m) n =
 
89
    begin
 
90
      suc m * n
 
91
    ≡⟨ refl ⟩
 
92
      n + m * n
 
93
    ≡⟨ cong (λ x → n + x) (*-comm m n) ⟩
 
94
      n + n * m
 
95
    ≡⟨ sym (m*1+n≡m+mn n m) ⟩
 
96
      n * suc m
 
97
    ∎
 
98
 
 
99
  distrib-*-+ : _*_ DistributesOver _+_
 
100
  distrib-*-+ = distˡ , distʳ
 
101
    where
 
102
    distˡ : _*_ DistributesOverˡ _+_
 
103
    distˡ zero    n o = refl
 
104
    distˡ (suc m) n o =
 
105
                                 begin
 
106
      suc m * (n + o)
 
107
                                 ≡⟨ refl ⟩
 
108
      (n + o) + m * (n + o)
 
109
                                 ≡⟨ cong (λ x → (n + o) + x) (distˡ m n o) ⟩
 
110
      (n + o) + (m * n + m * o)
 
111
                                 ≡⟨ sym $ +-assoc (n + o) (m * n) (m * o) ⟩
 
112
      ((n + o) + m * n) + m * o
 
113
                                 ≡⟨ cong (λ x → x + (m * o)) $ +-assoc n o (m * n) ⟩
 
114
      (n + (o + m * n)) + m * o
 
115
                                 ≡⟨ cong (λ x → (n + x) + m * o) $ +-comm o (m * n) ⟩
 
116
      (n + (m * n + o)) + m * o
 
117
                                 ≡⟨ cong (λ x → x + (m * o)) $ sym $ +-assoc n (m * n) o ⟩
 
118
      ((n + m * n) + o) + m * o
 
119
                                 ≡⟨ +-assoc (n + m * n) o (m * o) ⟩
 
120
      (n + m * n) + (o + m * o)
 
121
                                 ≡⟨ refl ⟩
 
122
      suc m * n + suc m * o
 
123
                                 ∎
 
124
 
 
125
    distʳ : _*_ DistributesOverʳ _+_
 
126
    distʳ m n o =
 
127
                      begin
 
128
       (n + o) * m
 
129
                      ≡⟨ *-comm (n + o) m ⟩
 
130
       m * (n + o)
 
131
                      ≡⟨ distˡ m n o ⟩
 
132
       m * n + m * o
 
133
                      ≡⟨ cong₂ _+_ (*-comm m n) (*-comm m o) ⟩
 
134
       n * m + o * m
 
135
                      ∎
 
136
 
 
137
  *-assoc : Associative _*_
 
138
  *-assoc zero    n o = refl
 
139
  *-assoc (suc m) n o =
 
140
                         begin
 
141
    (suc m * n) * o
 
142
                         ≡⟨ refl ⟩
 
143
    (n + m * n) * o
 
144
                         ≡⟨ proj₂ distrib-*-+ o n (m * n) ⟩
 
145
    n * o + (m * n) * o
 
146
                         ≡⟨ cong (λ x → n * o + x) $ *-assoc m n o ⟩
 
147
    n * o + m * (n * o)
 
148
                         ≡⟨ refl ⟩
 
149
    suc m * (n * o)
 
150
                         ∎
 
151
 
 
152
  *-identity : Identity 1 _*_
 
153
  *-identity = proj₂ +-identity , n*1≡n
 
154
    where
 
155
    n*1≡n : RightIdentity 1 _*_
 
156
    n*1≡n n =
 
157
      begin
 
158
        n * 1
 
159
      ≡⟨ *-comm n 1 ⟩
 
160
        1 * n
 
161
      ≡⟨ refl ⟩
 
162
        n + 0
 
163
      ≡⟨ proj₂ +-identity n ⟩
 
164
        n
 
165
      ∎
 
166
 
 
167
isCommutativeSemiring : IsCommutativeSemiring _≡_ _+_ _*_ 0 1
 
168
isCommutativeSemiring = record
 
169
  { isSemiring = record
 
170
    { isSemiringWithoutAnnihilatingZero = record
 
171
      { +-isCommutativeMonoid = record
 
172
        { isMonoid = record
 
173
          { isSemigroup = record
 
174
            { isEquivalence = PropEq.isEquivalence
 
175
            ; assoc         = +-assoc
 
176
            ; ∙-cong        = cong₂ _+_
 
177
            }
 
178
          ; identity = +-identity
 
179
          }
 
180
        ; comm = +-comm
 
181
        }
 
182
      ; *-isMonoid = record
 
183
        { isSemigroup = record
 
184
          { isEquivalence = PropEq.isEquivalence
 
185
          ; assoc         = *-assoc
 
186
          ; ∙-cong        = cong₂ _*_
 
187
          }
 
188
        ; identity = *-identity
 
189
        }
 
190
      ; distrib = distrib-*-+
 
191
      }
 
192
    ; zero = *-zero
 
193
    }
 
194
  ; *-comm = *-comm
 
195
  }
 
196
 
 
197
commutativeSemiring : CommutativeSemiring
 
198
commutativeSemiring = record
 
199
  { _+_                   = _+_
 
200
  ; _*_                   = _*_
 
201
  ; 0#                    = 0
 
202
  ; 1#                    = 1
 
203
  ; isCommutativeSemiring = isCommutativeSemiring
 
204
  }
 
205
 
 
206
import Algebra.RingSolver.Simple as Solver
 
207
import Algebra.RingSolver.AlmostCommutativeRing as ACR
 
208
module SemiringSolver =
 
209
  Solver (ACR.fromCommutativeSemiring commutativeSemiring)
 
210
 
 
211
------------------------------------------------------------------------
 
212
-- (ℕ, ⊔, ⊓, 0) is a commutative semiring without one
 
213
 
 
214
private
 
215
 
 
216
  ⊔-assoc : Associative _⊔_
 
217
  ⊔-assoc zero    _       _       = refl
 
218
  ⊔-assoc (suc m) zero    o       = refl
 
219
  ⊔-assoc (suc m) (suc n) zero    = refl
 
220
  ⊔-assoc (suc m) (suc n) (suc o) = cong suc $ ⊔-assoc m n o
 
221
 
 
222
  ⊔-identity : Identity 0 _⊔_
 
223
  ⊔-identity = (λ _ → refl) , n⊔0≡n
 
224
    where
 
225
    n⊔0≡n : RightIdentity 0 _⊔_
 
226
    n⊔0≡n zero    = refl
 
227
    n⊔0≡n (suc n) = refl
 
228
 
 
229
  ⊔-comm : Commutative _⊔_
 
230
  ⊔-comm zero    n       = sym $ proj₂ ⊔-identity n
 
231
  ⊔-comm (suc m) zero    = refl
 
232
  ⊔-comm (suc m) (suc n) =
 
233
    begin
 
234
      suc m ⊔ suc n
 
235
    ≡⟨ refl ⟩
 
236
      suc (m ⊔ n)
 
237
    ≡⟨ cong suc (⊔-comm m n) ⟩
 
238
      suc (n ⊔ m)
 
239
    ≡⟨ refl ⟩
 
240
      suc n ⊔ suc m
 
241
    ∎
 
242
 
 
243
  ⊓-assoc : Associative _⊓_
 
244
  ⊓-assoc zero    _       _       = refl
 
245
  ⊓-assoc (suc m) zero    o       = refl
 
246
  ⊓-assoc (suc m) (suc n) zero    = refl
 
247
  ⊓-assoc (suc m) (suc n) (suc o) = cong suc $ ⊓-assoc m n o
 
248
 
 
249
  ⊓-zero : Zero 0 _⊓_
 
250
  ⊓-zero = (λ _ → refl) , n⊓0≡0
 
251
    where
 
252
    n⊓0≡0 : RightZero 0 _⊓_
 
253
    n⊓0≡0 zero    = refl
 
254
    n⊓0≡0 (suc n) = refl
 
255
 
 
256
  ⊓-comm : Commutative _⊓_
 
257
  ⊓-comm zero    n       = sym $ proj₂ ⊓-zero n
 
258
  ⊓-comm (suc m) zero    = refl
 
259
  ⊓-comm (suc m) (suc n) =
 
260
    begin
 
261
      suc m ⊓ suc n
 
262
    ≡⟨ refl ⟩
 
263
      suc (m ⊓ n)
 
264
    ≡⟨ cong suc (⊓-comm m n) ⟩
 
265
      suc (n ⊓ m)
 
266
    ≡⟨ refl ⟩
 
267
      suc n ⊓ suc m
 
268
    ∎
 
269
 
 
270
  distrib-⊓-⊔ : _⊓_ DistributesOver _⊔_
 
271
  distrib-⊓-⊔ = (distribˡ-⊓-⊔ , distribʳ-⊓-⊔)
 
272
    where
 
273
    distribʳ-⊓-⊔ : _⊓_ DistributesOverʳ _⊔_
 
274
    distribʳ-⊓-⊔ (suc m) (suc n) (suc o) = cong suc $ distribʳ-⊓-⊔ m n o
 
275
    distribʳ-⊓-⊔ (suc m) (suc n) zero    = cong suc $ refl
 
276
    distribʳ-⊓-⊔ (suc m) zero    o       = refl
 
277
    distribʳ-⊓-⊔ zero    n       o       = begin
 
278
      (n ⊔ o) ⊓ 0    ≡⟨ ⊓-comm (n ⊔ o) 0 ⟩
 
279
      0 ⊓ (n ⊔ o)    ≡⟨ refl ⟩
 
280
      0 ⊓ n ⊔ 0 ⊓ o  ≡⟨ ⊓-comm 0 n ⟨ cong₂ _⊔_ ⟩ ⊓-comm 0 o ⟩
 
281
      n ⊓ 0 ⊔ o ⊓ 0  ∎
 
282
 
 
283
    distribˡ-⊓-⊔ : _⊓_ DistributesOverˡ _⊔_
 
284
    distribˡ-⊓-⊔ m n o = begin
 
285
      m ⊓ (n ⊔ o)    ≡⟨ ⊓-comm m _ ⟩
 
286
      (n ⊔ o) ⊓ m    ≡⟨ distribʳ-⊓-⊔ m n o ⟩
 
287
      n ⊓ m ⊔ o ⊓ m  ≡⟨ ⊓-comm n m ⟨ cong₂ _⊔_ ⟩ ⊓-comm o m ⟩
 
288
      m ⊓ n ⊔ m ⊓ o  ∎
 
289
 
 
290
⊔-⊓-0-isCommutativeSemiringWithoutOne
 
291
  : IsCommutativeSemiringWithoutOne _≡_ _⊔_ _⊓_ 0
 
292
⊔-⊓-0-isCommutativeSemiringWithoutOne = record
 
293
  { isSemiringWithoutOne = record
 
294
      { +-isCommutativeMonoid = record
 
295
          { isMonoid = record
 
296
              { isSemigroup = record
 
297
                  { isEquivalence = PropEq.isEquivalence
 
298
                  ; assoc         = ⊔-assoc
 
299
                  ; ∙-cong        = cong₂ _⊔_
 
300
                  }
 
301
              ; identity = ⊔-identity
 
302
              }
 
303
          ; comm = ⊔-comm
 
304
          }
 
305
      ; *-isSemigroup = record
 
306
          { isEquivalence = PropEq.isEquivalence
 
307
          ; assoc         = ⊓-assoc
 
308
          ; ∙-cong        = cong₂ _⊓_
 
309
          }
 
310
      ; distrib = distrib-⊓-⊔
 
311
      ; zero    = ⊓-zero
 
312
      }
 
313
  ; *-comm = ⊓-comm
 
314
  }
 
315
 
 
316
⊔-⊓-0-commutativeSemiringWithoutOne : CommutativeSemiringWithoutOne
 
317
⊔-⊓-0-commutativeSemiringWithoutOne = record
 
318
  { _+_                             = _⊔_
 
319
  ; _*_                             = _⊓_
 
320
  ; 0#                              = 0
 
321
  ; isCommutativeSemiringWithoutOne =
 
322
      ⊔-⊓-0-isCommutativeSemiringWithoutOne
 
323
  }
 
324
 
 
325
------------------------------------------------------------------------
 
326
-- (ℕ, ⊓, ⊔) is a lattice
 
327
 
 
328
private
 
329
 
 
330
  absorptive-⊓-⊔ : Absorptive _⊓_ _⊔_
 
331
  absorptive-⊓-⊔ = abs-⊓-⊔ , abs-⊔-⊓
 
332
    where
 
333
    abs-⊔-⊓ : _⊔_ Absorbs _⊓_
 
334
    abs-⊔-⊓ zero    n       = refl
 
335
    abs-⊔-⊓ (suc m) zero    = refl
 
336
    abs-⊔-⊓ (suc m) (suc n) = cong suc $ abs-⊔-⊓ m n
 
337
 
 
338
    abs-⊓-⊔ : _⊓_ Absorbs _⊔_
 
339
    abs-⊓-⊔ zero    n       = refl
 
340
    abs-⊓-⊔ (suc m) (suc n) = cong suc $ abs-⊓-⊔ m n
 
341
    abs-⊓-⊔ (suc m) zero    = cong suc $
 
342
                   begin
 
343
      m ⊓ m
 
344
                   ≡⟨ cong (_⊓_ m) $ sym $ proj₂ ⊔-identity m ⟩
 
345
      m ⊓ (m ⊔ 0)
 
346
                   ≡⟨ abs-⊓-⊔ m zero ⟩
 
347
      m
 
348
                   ∎
 
349
 
 
350
isDistributiveLattice : IsDistributiveLattice _≡_ _⊓_ _⊔_
 
351
isDistributiveLattice = record
 
352
  { isLattice = record
 
353
      { isEquivalence = PropEq.isEquivalence
 
354
      ; ∨-comm        = ⊓-comm
 
355
      ; ∨-assoc       = ⊓-assoc
 
356
      ; ∨-cong        = cong₂ _⊓_
 
357
      ; ∧-comm        = ⊔-comm
 
358
      ; ∧-assoc       = ⊔-assoc
 
359
      ; ∧-cong        = cong₂ _⊔_
 
360
      ; absorptive    = absorptive-⊓-⊔
 
361
      }
 
362
  ; ∨-∧-distribʳ = proj₂ distrib-⊓-⊔
 
363
  }
 
364
 
 
365
distributiveLattice : DistributiveLattice
 
366
distributiveLattice = record
 
367
  { _∨_                   = _⊓_
 
368
  ; _∧_                   = _⊔_
 
369
  ; isDistributiveLattice = isDistributiveLattice
 
370
  }
 
371
 
 
372
------------------------------------------------------------------------
 
373
-- Converting between ≤ and ≤′
 
374
 
 
375
≤-step : ∀ {m n} → m ≤ n → m ≤ 1 + n
 
376
≤-step z≤n       = z≤n
 
377
≤-step (s≤s m≤n) = s≤s (≤-step m≤n)
 
378
 
 
379
≤′⇒≤ : _≤′_ ⇒ _≤_
 
380
≤′⇒≤ ≤′-refl        = ≤-refl
 
381
≤′⇒≤ (≤′-step m≤′n) = ≤-step (≤′⇒≤ m≤′n)
 
382
 
 
383
z≤′n : ∀ {n} → zero ≤′ n
 
384
z≤′n {zero}  = ≤′-refl
 
385
z≤′n {suc n} = ≤′-step z≤′n
 
386
 
 
387
s≤′s : ∀ {m n} → m ≤′ n → suc m ≤′ suc n
 
388
s≤′s ≤′-refl        = ≤′-refl
 
389
s≤′s (≤′-step m≤′n) = ≤′-step (s≤′s m≤′n)
 
390
 
 
391
≤⇒≤′ : _≤_ ⇒ _≤′_
 
392
≤⇒≤′ z≤n       = z≤′n
 
393
≤⇒≤′ (s≤s m≤n) = s≤′s (≤⇒≤′ m≤n)
 
394
 
 
395
------------------------------------------------------------------------
 
396
-- Various order-related properties
 
397
 
 
398
≤-steps : ∀ {m n} k → m ≤ n → m ≤ k + n
 
399
≤-steps zero    m≤n = m≤n
 
400
≤-steps (suc k) m≤n = ≤-step (≤-steps k m≤n)
 
401
 
 
402
m≤m+n : ∀ m n → m ≤ m + n
 
403
m≤m+n zero    n = z≤n
 
404
m≤m+n (suc m) n = s≤s (m≤m+n m n)
 
405
 
 
406
m≤′m+n : ∀ m n → m ≤′ m + n
 
407
m≤′m+n m n = ≤⇒≤′ (m≤m+n m n)
 
408
 
 
409
n≤′m+n : ∀ m n → n ≤′ m + n
 
410
n≤′m+n zero    n = ≤′-refl
 
411
n≤′m+n (suc m) n = ≤′-step (n≤′m+n m n)
 
412
 
 
413
n≤m+n : ∀ m n → n ≤ m + n
 
414
n≤m+n m n = ≤′⇒≤ (n≤′m+n m n)
 
415
 
 
416
n≤1+n : ∀ n → n ≤ 1 + n
 
417
n≤1+n _ = ≤-step ≤-refl
 
418
 
 
419
1+n≰n : ∀ {n} → ¬ 1 + n ≤ n
 
420
1+n≰n (s≤s le) = 1+n≰n le
 
421
 
 
422
≤pred⇒≤ : ∀ m n → m ≤ pred n → m ≤ n
 
423
≤pred⇒≤ m zero    le = le
 
424
≤pred⇒≤ m (suc n) le = ≤-step le
 
425
 
 
426
≤⇒pred≤ : ∀ m n → m ≤ n → pred m ≤ n
 
427
≤⇒pred≤ zero    n le = le
 
428
≤⇒pred≤ (suc m) n le = start
 
429
  m     ≤⟨ n≤1+n m ⟩
 
430
  suc m ≤⟨ le ⟩
 
431
  n     □
 
432
 
 
433
¬i+1+j≤i : ∀ i {j} → ¬ i + suc j ≤ i
 
434
¬i+1+j≤i zero    ()
 
435
¬i+1+j≤i (suc i) le = ¬i+1+j≤i i (≤-pred le)
 
436
 
 
437
n∸m≤n : ∀ m n → n ∸ m ≤ n
 
438
n∸m≤n zero    n       = ≤-refl
 
439
n∸m≤n (suc m) zero    = ≤-refl
 
440
n∸m≤n (suc m) (suc n) = start
 
441
  n ∸ m  ≤⟨ n∸m≤n m n ⟩
 
442
  n      ≤⟨ n≤1+n n ⟩
 
443
  suc n  □
 
444
 
 
445
n≤m+n∸m : ∀ m n → n ≤ m + (n ∸ m)
 
446
n≤m+n∸m m       zero    = z≤n
 
447
n≤m+n∸m zero    (suc n) = ≤-refl
 
448
n≤m+n∸m (suc m) (suc n) = s≤s (n≤m+n∸m m n)
 
449
 
 
450
m⊓n≤m : ∀ m n → m ⊓ n ≤ m
 
451
m⊓n≤m zero    _       = z≤n
 
452
m⊓n≤m (suc m) zero    = z≤n
 
453
m⊓n≤m (suc m) (suc n) = s≤s $ m⊓n≤m m n
 
454
 
 
455
m≤m⊔n : ∀ m n → m ≤ m ⊔ n
 
456
m≤m⊔n zero    _       = z≤n
 
457
m≤m⊔n (suc m) zero    = ≤-refl
 
458
m≤m⊔n (suc m) (suc n) = s≤s $ m≤m⊔n m n
 
459
 
 
460
⌈n/2⌉≤′n : ∀ n → ⌈ n /2⌉ ≤′ n
 
461
⌈n/2⌉≤′n zero          = ≤′-refl
 
462
⌈n/2⌉≤′n (suc zero)    = ≤′-refl
 
463
⌈n/2⌉≤′n (suc (suc n)) = s≤′s (≤′-step (⌈n/2⌉≤′n n))
 
464
 
 
465
⌊n/2⌋≤′n : ∀ n → ⌊ n /2⌋ ≤′ n
 
466
⌊n/2⌋≤′n zero    = ≤′-refl
 
467
⌊n/2⌋≤′n (suc n) = ≤′-step (⌈n/2⌉≤′n n)
 
468
 
 
469
<-trans : Transitive _<_
 
470
<-trans {i} {j} {k} i<j j<k = start
 
471
  1 + i  ≤⟨ i<j ⟩
 
472
  j      ≤⟨ n≤1+n j ⟩
 
473
  1 + j  ≤⟨ j<k ⟩
 
474
  k      □
 
475
 
 
476
------------------------------------------------------------------------
 
477
-- (ℕ, _≡_, _<_) is a strict total order
 
478
 
 
479
m≢1+m+n : ∀ m {n} → m ≢ suc (m + n)
 
480
m≢1+m+n zero    ()
 
481
m≢1+m+n (suc m) eq = m≢1+m+n m (cong pred eq)
 
482
 
 
483
strictTotalOrder : StrictTotalOrder _ _ _
 
484
strictTotalOrder = record
 
485
  { Carrier            = ℕ
 
486
  ; _≈_                = _≡_
 
487
  ; _<_                = _<_
 
488
  ; isStrictTotalOrder = record
 
489
    { isEquivalence = PropEq.isEquivalence
 
490
    ; trans         = <-trans
 
491
    ; compare       = cmp
 
492
    ; <-resp-≈      = PropEq.resp₂ _<_
 
493
    }
 
494
  }
 
495
  where
 
496
  2+m+n≰m : ∀ {m n} → ¬ 2 + (m + n) ≤ m
 
497
  2+m+n≰m (s≤s le) = 2+m+n≰m le
 
498
 
 
499
  cmp : Trichotomous _≡_ _<_
 
500
  cmp m n with compare m n
 
501
  cmp .m .(suc (m + k)) | less    m k = tri< (m≤m+n (suc m) k) (m≢1+m+n _) 2+m+n≰m
 
502
  cmp .n             .n | equal   n   = tri≈ 1+n≰n refl 1+n≰n
 
503
  cmp .(suc (n + k)) .n | greater n k = tri> 2+m+n≰m (m≢1+m+n _ ∘ sym) (m≤m+n (suc n) k)
 
504
 
 
505
------------------------------------------------------------------------
 
506
-- Miscellaneous other properties
 
507
 
 
508
0∸n≡0 : LeftZero zero _∸_
 
509
0∸n≡0 zero    = refl
 
510
0∸n≡0 (suc _) = refl
 
511
 
 
512
∸-+-assoc : ∀ m n o → (m ∸ n) ∸ o ≡ m ∸ (n + o)
 
513
∸-+-assoc m       n       zero    = cong (_∸_ m) (sym $ proj₂ +-identity n)
 
514
∸-+-assoc zero    zero    (suc o) = refl
 
515
∸-+-assoc zero    (suc n) (suc o) = refl
 
516
∸-+-assoc (suc m) zero    (suc o) = refl
 
517
∸-+-assoc (suc m) (suc n) (suc o) = ∸-+-assoc m n (suc o)
 
518
 
 
519
m+n∸n≡m : ∀ m n → (m + n) ∸ n ≡ m
 
520
m+n∸n≡m m       zero    = proj₂ +-identity m
 
521
m+n∸n≡m zero    (suc n) = m+n∸n≡m zero n
 
522
m+n∸n≡m (suc m) (suc n) = begin
 
523
  m + suc n ∸ n
 
524
                 ≡⟨ cong (λ x → x ∸ n) (m+1+n≡1+m+n m n) ⟩
 
525
  suc m + n ∸ n
 
526
                 ≡⟨ m+n∸n≡m (suc m) n ⟩
 
527
  suc m
 
528
                 ∎
 
529
 
 
530
m⊓n+n∸m≡n : ∀ m n → (m ⊓ n) + (n ∸ m) ≡ n
 
531
m⊓n+n∸m≡n zero    n       = refl
 
532
m⊓n+n∸m≡n (suc m) zero    = refl
 
533
m⊓n+n∸m≡n (suc m) (suc n) = cong suc $ m⊓n+n∸m≡n m n
 
534
 
 
535
[m∸n]⊓[n∸m]≡0 : ∀ m n → (m ∸ n) ⊓ (n ∸ m) ≡ 0
 
536
[m∸n]⊓[n∸m]≡0 zero zero       = refl
 
537
[m∸n]⊓[n∸m]≡0 zero (suc n)    = refl
 
538
[m∸n]⊓[n∸m]≡0 (suc m) zero    = refl
 
539
[m∸n]⊓[n∸m]≡0 (suc m) (suc n) = [m∸n]⊓[n∸m]≡0 m n
 
540
 
 
541
-- TODO: Can this proof be simplified? An automatic solver which can
 
542
-- handle ∸ would be nice...
 
543
 
 
544
i∸k∸j+j∸k≡i+j∸k : ∀ i j k → i ∸ (k ∸ j) + (j ∸ k) ≡ i + j ∸ k
 
545
i∸k∸j+j∸k≡i+j∸k zero j k = begin
 
546
  0 ∸ (k ∸ j) + (j ∸ k)
 
547
                         ≡⟨ cong (λ x → x + (j ∸ k)) (0∸n≡0 (k ∸ j)) ⟩
 
548
  0 + (j ∸ k)
 
549
                         ≡⟨ refl ⟩
 
550
  j ∸ k
 
551
                         ∎
 
552
i∸k∸j+j∸k≡i+j∸k (suc i) j zero = begin
 
553
  suc i ∸ (0 ∸ j) + j
 
554
                       ≡⟨ cong (λ x → suc i ∸ x + j) (0∸n≡0 j) ⟩
 
555
  suc i ∸ 0 + j
 
556
                       ≡⟨ refl ⟩
 
557
  suc (i + j)
 
558
                       ∎
 
559
i∸k∸j+j∸k≡i+j∸k (suc i) zero (suc k) = begin
 
560
  i ∸ k + 0
 
561
             ≡⟨ proj₂ +-identity _ ⟩
 
562
  i ∸ k
 
563
             ≡⟨ cong (λ x → x ∸ k) (sym (proj₂ +-identity _)) ⟩
 
564
  i + 0 ∸ k
 
565
             ∎
 
566
i∸k∸j+j∸k≡i+j∸k (suc i) (suc j) (suc k) = begin
 
567
  suc i ∸ (k ∸ j) + (j ∸ k)
 
568
                             ≡⟨ i∸k∸j+j∸k≡i+j∸k (suc i) j k ⟩
 
569
  suc i + j ∸ k
 
570
                             ≡⟨ cong (λ x → x ∸ k)
 
571
                                     (sym (m+1+n≡1+m+n i j)) ⟩
 
572
  i + suc j ∸ k
 
573
                             ∎
 
574
 
 
575
m+n∸m≡n : ∀ {m n} → m ≤ n → m + (n ∸ m) ≡ n
 
576
m+n∸m≡n z≤n       = refl
 
577
m+n∸m≡n (s≤s m≤n) = cong suc $ m+n∸m≡n m≤n
 
578
 
 
579
i+j≡0⇒i≡0 : ∀ i {j} → i + j ≡ 0 → i ≡ 0
 
580
i+j≡0⇒i≡0 zero    eq = refl
 
581
i+j≡0⇒i≡0 (suc i) ()
 
582
 
 
583
i+j≡0⇒j≡0 : ∀ i {j} → i + j ≡ 0 → j ≡ 0
 
584
i+j≡0⇒j≡0 i {j} i+j≡0 = i+j≡0⇒i≡0 j $ begin
 
585
  j + i
 
586
    ≡⟨ +-comm j i ⟩
 
587
  i + j
 
588
    ≡⟨ i+j≡0 ⟩
 
589
  0
 
590
    ∎
 
591
 
 
592
i*j≡1⇒i≡1 : ∀ i j → i * j ≡ 1 → i ≡ 1
 
593
i*j≡1⇒i≡1 (suc zero)    j             _  = refl
 
594
i*j≡1⇒i≡1 zero          j             ()
 
595
i*j≡1⇒i≡1 (suc (suc i)) (suc (suc j)) ()
 
596
i*j≡1⇒i≡1 (suc (suc i)) (suc zero)    ()
 
597
i*j≡1⇒i≡1 (suc (suc i)) zero          eq with begin
 
598
  0      ≡⟨ *-comm 0 i ⟩
 
599
  i * 0  ≡⟨ eq ⟩
 
600
  1      ∎
 
601
... | ()
 
602
 
 
603
i*j≡1⇒j≡1 : ∀ i j → i * j ≡ 1 → j ≡ 1
 
604
i*j≡1⇒j≡1 i j eq = i*j≡1⇒i≡1 j i (begin
 
605
  j * i  ≡⟨ *-comm j i ⟩
 
606
  i * j  ≡⟨ eq ⟩
 
607
  1      ∎)
 
608
 
 
609
cancel-+-left : ∀ i {j k} → i + j ≡ i + k → j ≡ k
 
610
cancel-+-left zero    eq = eq
 
611
cancel-+-left (suc i) eq = cancel-+-left i (cong pred eq)
 
612
 
 
613
cancel-*-right : ∀ i j {k} → i * suc k ≡ j * suc k → i ≡ j
 
614
cancel-*-right zero    zero        eq = refl
 
615
cancel-*-right zero    (suc j)     ()
 
616
cancel-*-right (suc i) zero        ()
 
617
cancel-*-right (suc i) (suc j) {k} eq =
 
618
  cong suc (cancel-*-right i j (cancel-+-left (suc k) eq))
 
619
 
 
620
im≡jm+n⇒[i∸j]m≡n
 
621
  : ∀ i j m n →
 
622
    i * m ≡ j * m + n → (i ∸ j) * m ≡ n
 
623
im≡jm+n⇒[i∸j]m≡n i       zero    m n eq = eq
 
624
im≡jm+n⇒[i∸j]m≡n zero    (suc j) m n eq =
 
625
  sym $ i+j≡0⇒j≡0 (m + j * m) $ sym eq
 
626
im≡jm+n⇒[i∸j]m≡n (suc i) (suc j) m n eq =
 
627
  im≡jm+n⇒[i∸j]m≡n i j m n (cancel-+-left m eq')
 
628
  where
 
629
  eq' = begin
 
630
    m + i * m
 
631
      ≡⟨ eq ⟩
 
632
    m + j * m + n
 
633
      ≡⟨ +-assoc m (j * m) n ⟩
 
634
    m + (j * m + n)
 
635
      ∎
 
636
 
 
637
i+1+j≢i : ∀ i {j} → i + suc j ≢ i
 
638
i+1+j≢i i eq = ¬i+1+j≤i i (reflexive eq)
 
639
  where open DecTotalOrder decTotalOrder
 
640
 
 
641
⌊n/2⌋-mono : ⌊_/2⌋ Preserves _≤_ ⟶ _≤_
 
642
⌊n/2⌋-mono z≤n             = z≤n
 
643
⌊n/2⌋-mono (s≤s z≤n)       = z≤n
 
644
⌊n/2⌋-mono (s≤s (s≤s m≤n)) = s≤s (⌊n/2⌋-mono m≤n)
 
645
 
 
646
⌈n/2⌉-mono : ⌈_/2⌉ Preserves _≤_ ⟶ _≤_
 
647
⌈n/2⌉-mono m≤n = ⌊n/2⌋-mono (s≤s m≤n)
 
648
 
 
649
pred-mono : pred Preserves _≤_ ⟶ _≤_
 
650
pred-mono z≤n      = z≤n
 
651
pred-mono (s≤s le) = le
 
652
 
 
653
_+-mono_ : _+_ Preserves₂ _≤_ ⟶ _≤_ ⟶ _≤_
 
654
_+-mono_ {zero} {m₂} {n₁} {n₂} z≤n n₁≤n₂ = start
 
655
  n₁      ≤⟨ n₁≤n₂ ⟩
 
656
  n₂      ≤⟨ n≤m+n m₂ n₂ ⟩
 
657
  m₂ + n₂ □
 
658
s≤s m₁≤m₂ +-mono n₁≤n₂ = s≤s (m₁≤m₂ +-mono n₁≤n₂)
 
659
 
 
660
_*-mono_ : _*_ Preserves₂ _≤_ ⟶ _≤_ ⟶ _≤_
 
661
z≤n       *-mono n₁≤n₂ = z≤n
 
662
s≤s m₁≤m₂ *-mono n₁≤n₂ = n₁≤n₂ +-mono (m₁≤m₂ *-mono n₁≤n₂)