@@ -1,127 +1,497 @@
1−module prelude.nat
1+module MoreNat
3import builtins
3import builtins
4import prelude.cast
6import prelude.cast
6%access public
8%access public
8−data Nat = O | S Nat
10+data Nat
10−instance Cast Nat Int where
14+--------------------------------------------------------------------------------
11− cast O = 0
15+-- Syntactic tests
12− cast (S k) = 1 + cast k
16+--------------------------------------------------------------------------------
14−plus : Nat -> Nat -> Nat
18+isZero : Nat -> Bool
15−plus O y = y
19+isZero O = True
16−plus (S k) y = S (plus k y)
20+isZero (S n) = False
18−eqRespS : m = n -> S m = S n
22+isSucc : Nat -> Bool
19−eqRespS refl = refl
23+isSucc O = False
21−eqRespS' : S m = S n -> m = n
26+--------------------------------------------------------------------------------
22−eqRespS' refl = refl
27+-- Basic arithmetic functions
28+--------------------------------------------------------------------------------
24−sub : Nat -> Nat -> Nat
30+plus : Nat -> Nat -> Nat
25−sub O y = O
31+plus O right = right
26−sub (S k) (S y) = sub k y
32+plus (S left) right = S (plus left right)
29mult : Nat -> Nat -> Nat
34mult : Nat -> Nat -> Nat
30−mult O y = O
35+mult O right = O
31−mult (S k) y = plus y (mult k y)
36+mult (S left) right = plus right $ mult left right
38+minus : Nat -> Nat -> Nat
41+minus (S left) (S right) = minus left right
43+power : Nat -> Nat -> Nat
45+power base (S exp) = mult base $ power base exp
47+--------------------------------------------------------------------------------
48+-- Type class instances
49+--------------------------------------------------------------------------------
33−instance Eq Nat where
51+instance Eq Nat where
34− O == O = True
52+ Z == Z = True
35− (S x) == (S y) = x == y
53+ (S l) == (S r) = l == r
36− O == (S y) = False
54+ _ == _ = False
37− (S x) == O = False
55+
56+instance Cast Nat Int where
58+ cast (S k) = 1 + cast k
39instance Ord Nat where
60instance Ord Nat where
40− compare O O = EQ
61+ compare O O = EQ
41− compare O (S k) = LT
62+ compare O (S k) = LT
42− compare (S k) O = GT
63+ compare (S k) O = GT
43− compare (S x) (S y) = compare x y
64+ compare (S x) (S y) = compare x y
45instance Num Nat where
66instance Num Nat where
46− (+) = plus
67+ (+) = plus
47− (-) = sub
68+ (-) = minus
48− (*) = mult
69+ (*) = mult
74+ (S (fromInteger (n-1)))
78+--------------------------------------------------------------------------------
79+-- Division and modulus
80+--------------------------------------------------------------------------------
82+--------------------------------------------------------------------------------
84+--------------------------------------------------------------------------------
90+--------------------------------------------------------------------------------
91+-- Fibonacci and factorial
92+--------------------------------------------------------------------------------
97+fib (S (S n)) = plus (fib (S n)) (fib n)
99+--------------------------------------------------------------------------------
101+--------------------------------------------------------------------------------
103+--------------------------------------------------------------------------------
105+--------------------------------------------------------------------------------
107+data LTE : Nat -> Nat -> Set where
108+ lteZero : LTE O right
109+ lteSucc : LTE left right -> LTE (S left) (S right)
111+GTE : Nat -> Nat -> Set
112+GTE left right = LTE right left
114+LT : Nat -> Nat -> Set
115+LT left right = LTE (S left) right
117+GT : Nat -> Nat -> Set
118+GT left right = LT right left
120+lte : Nat -> Nat -> Bool
123+lte (S left) (S right) = lte left right
125+gte : Nat -> Nat -> Bool
126+gte left right = lte right left
128+lt : Nat -> Nat -> Bool
129+lt left right = lte (S left) right
131+gt : Nat -> Nat -> Bool
132+gt left right = lt right left
134+minimum : Nat -> Nat -> Nat
136+ if lte left right then
141+maximum : Nat -> Nat -> Nat
143+ if lte left right then
148+--------------------------------------------------------------------------------
150+--------------------------------------------------------------------------------
153+succMonotonic : (left : Nat) -> (right : Nat) -> (p : left = right) ->
155+succMonotonic left right refl = refl
157+succInjective : (left : Nat) -> (right : Nat) -> (p : S left = S right) ->
159+succInjective left right refl = refl
162+plusZeroLeftNeutral : (right : Nat) -> plus O right = right
163+plusZeroLeftNeutral right = refl
165+plusZeroRightNeutral : (left : Nat) -> plus left O = left
166+plusZeroRightNeutral O = refl
167+plusZeroRightNeutral (S n) =
168+ let inductiveHypothesis = plusZeroRightNeutral n in
169+ ?plusZeroRightNeutralStepCase
171+plusSuccRightSucc : (left : Nat) -> (right : Nat) ->
172+ S (plus left right) = plus left (S right)
173+plusSuccRightSucc O right = refl
174+plusSuccRightSucc (S left) right =
175+ let inductiveHypothesis = plusSuccRightSucc left right in
176+ ?plusSuccRightSuccStepCase
178+plusCommutative : (left : Nat) -> (right : Nat) ->
179+ plus left right = plus right left
180+plusCommutative O right = ?plusCommutativeBaseCase
181+plusCommutative (S left) right =
182+ let inductiveHypothesis = plusCommutative left right in
183+ ?plusCommutativeStepCase
185+plusAssociative : (left : Nat) -> (centre : Nat) -> (right : Nat) ->
186+ plus left (plus centre right) = plus (plus left centre) right
187+plusAssociative O centre right = refl
188+plusAssociative (S left) centre right =
189+ let inductiveHypothesis = plusAssociative left centre right in
190+ ?plusAssociativeStepCase
192+plusMonotonicRight : (left : Nat) -> (right : Nat) -> (c : Nat) ->
193+ (p : left = right) -> plus left c = plus right c
194+plusMonotonicRight left right c refl = refl
196+plusMonotonicLeft : (left : Nat) -> (right : Nat) -> (c : Nat) ->
197+ (p : left = right) -> plus c left = plus c right
198+plusMonotonicLeft left right c refl = refl
200+plusOneSucc : (right : Nat) -> plus (S O) right = S right
204+multZeroLeftZero : (right : Nat) -> mult O right = O
205+multZeroLeftZero right = refl
207+multZeroRightZero : (left : Nat) -> mult left O = O
208+multZeroRightZero O = refl
209+multZeroRightZero (S left) =
210+ let inductiveHypothesis = multZeroRightZero left in
211+ ?multZeroRightZeroStepCase
213+multRightSuccPlus : (left : Nat) -> (right : Nat) ->
214+ mult left (S right) = plus left (mult left right)
215+multRightSuccPlus O right = refl
216+multRightSuccPlus (S left) right =
217+ let inductiveHypothesis = multRightSuccPlus left right in
218+ ?multRightSuccPlusStepCase
220+multLeftSuccPlus : (left : Nat) -> (right : Nat) ->
221+ mult (S left) right = plus right (mult left right)
222+multLeftSuccPlus left right = refl
224+multCommutative : (left : Nat) -> (right : Nat) ->
225+ mult left right = mult right left
226+multCommutative O right = ?multCommutativeBaseCase
227+multCommutative (S left) right =
228+ let inductiveHypothesis = multCommutative left right in
229+ ?multCommutativeStepCase
231+multDistributesOverPlusRight : (left : Nat) -> (centre : Nat) -> (right : Nat) ->
232+ mult left (plus centre right) = plus (mult left centre) (mult left right)
233+multDistributesOverPlusRight O centre right = refl
234+multDistributesOverPlusRight (S left) centre right =
235+ let inductiveHypothesis = multDistributesOverPlusRight left centre right in
236+ ?multDistributesOverPlusRightStepCase
238+multDistributesOverPlusLeft : (left : Nat) -> (centre : Nat) -> (right : Nat) ->
239+ mult (plus left centre) right = plus (mult left right) (mult centre right)
240+multDistributesOverPlusLeft O centre right = refl
241+multDistributesOverPlusLeft (S left) centre right =
242+ let inductiveHypothesis = multDistributesOverPlusLeft left centre right in
243+ ?multDistributesOverPlusLeftStepCase
245+multAssociative : (left : Nat) -> (centre : Nat) -> (right : Nat) ->
246+ mult left (mult centre right) = mult (mult left centre) right
247+multAssociative O centre right = refl
248+multAssociative (S left) centre right =
249+ let inductiveHypothesis = multAssociative left centre right in
250+ ?multAssociativeStepCase
252+multOneLeftNeutral : (right : Nat) -> mult (S O) right = right
253+multOneLeftNeutral O = refl
254+multOneLeftNeutral (S right) =
255+ let inductiveHypothesis = multOneLeftNeutral right in
256+ ?multOneLeftNeutralStepCase
258+multOneRightNeutral : (left : Nat) -> mult left (S O) = left
259+multOneRightNeutral O = refl
260+multOneRightNeutral (S left) =
261+ let inductiveHypothesis = multOneRightNeutral left in
262+ ?multOneRightNeutralStepCase
265+minusSuccSucc : (left : Nat) -> (right : Nat) ->
266+ minus (S left) (S right) = minus left right
267+minusSuccSucc left right = refl
269+minusZeroLeft : (right : Nat) -> minus O right = O
270+minusZeroLeft right = refl
272+minusZeroRight : (left : Nat) -> minus left O = left
273+minusZeroRight O = refl
274+minusZeroRight (S left) = refl
276+minusZeroN : (n : Nat) -> O = minus n n
278+minusZeroN (S n) = minusZeroN n
280+minusOneSuccN : (n : Nat) -> S O = minus (S n) n
281+minusOneSuccN O = refl
282+minusOneSuccN (S n) = minusOneSuccN n
285+powerSuccPowerLeft : (base : Nat) -> (exp : Nat) -> power base (S exp) =
286+ mult base (power base exp)
287+powerSuccPowerLeft base exp = refl
289+multPowerPowerPlus : (base : Nat) -> (exp : Nat) -> (exp' : Nat) ->
290+ mult (power base exp) (power base exp') = power base (plus exp exp')
291+multPowerPowerPlus base O exp' = ?multPowerPowerPlusBaseCase
292+multPowerPowerPlus base (S exp) exp' =
293+ let inductiveHypothesis = multPowerPowerPlus base exp exp' in
294+ ?multPowerPowerPlusStepCase
296+powerZeroOne : (base : Nat) -> power base O = S O
297+powerZeroOne base = refl
299+powerOneNeutral : (base : Nat) -> power base (S O) = base
300+powerOneNeutral O = refl
301+powerOneNeutral (S base) =
302+ let inductiveHypothesis = powerOneNeutral base in
303+ ?powerOneNeutralStepCase
305+powerOneSuccOne : (exp : Nat) -> power (S O) exp = S O
306+powerOneSuccOne O = refl
307+powerOneSuccOne (S exp) =
308+ let inductiveHypothesis = powerOneSuccOne exp in
309+ ?powerOneSuccOneStepCase
311+powerSuccSuccMult : (base : Nat) -> power base (S (S O)) = mult base base
312+powerSuccSuccMult O = refl
313+powerSuccSuccMult (S base) =
314+ let inductiveHypothesis = powerSuccSuccMult base in
315+ ?powerSuccSuccMultStepCase
317+powerPowerMultPower : (base : Nat) -> (exp : Nat) -> (exp' : Nat) ->
318+ power (power base exp) exp' = power base (mult exp exp')
319+powerPowerMultPower base exp O = ?powerPowerMultPowerBaseCase
320+powerPowerMultPower base exp (S exp') =
321+ let inductiveHypothesis = powerPowerMultPower base exp exp' in
322+ ?powerPowerMultPowerStepCase
325+predSucc : (n : Nat) -> pred (S n) = n
328+minusSuccPred : (left : Nat) -> (right : Nat) ->
329+ minus left (S right) = pred (minus left right)
330+minusSuccPred O right = refl
331+minusSuccPred (S left) O =
332+ let inductiveHypothesis = minusSuccPred left O in
333+ ?minusSuccPredStepCase
334+minusSuccPred (S left) (S right) =
335+ let inductiveHypothesis = minusSuccPred left right in
336+ ?minusSuccPredStepCase'
338+--------------------------------------------------------------------------------
340+--------------------------------------------------------------------------------
342+powerPowerMultPowerStepCase = proof {
344+ rewrite sym inductiveHypothesis;
345+ rewrite sym (multRightSuccPlus exp exp');
346+ rewrite (multPowerPowerPlus base exp (mult exp exp'));
350+powerPowerMultPowerBaseCase = proof {
352+ rewrite sym (multZeroRightZero exp);
356+powerSuccSuccMultStepCase = proof {
358+ rewrite (multOneRightNeutral base);
359+ rewrite sym (multOneRightNeutral base);
363+powerOneSuccOneStepCase = proof {
365+ rewrite inductiveHypothesis;
366+ rewrite sym (plusZeroRightNeutral (power (S O) exp));
370+powerOneNeutralStepCase = proof {
372+ rewrite inductiveHypothesis;
376+multAssociativeStepCase = proof {
378+ rewrite sym (multDistributesOverPlusLeft centre (mult left centre) right);
379+ rewrite inductiveHypothesis;
383+minusSuccPredStepCase' = proof {
385+ rewrite sym inductiveHypothesis;
389+minusSuccPredStepCase = proof {
391+ rewrite (minusZeroRight left);
395+multPowerPowerPlusStepCase = proof {
397+ rewrite inductiveHypothesis;
398+ rewrite (multAssociative base (power base exp) (power base exp'));
50− fromInteger 0 = O
402+multPowerPowerPlusBaseCase = proof {
51− fromInteger n = if (n > 0) then (S (fromInteger (n-1))) else O
403+ intros;
404+ rewrite (plusZeroRightNeutral (power base exp'));
53−plusnO : (m : Nat) -> m + O = m
408+multOneRightNeutralStepCase = proof {
54−plusnO O = refl
409+ intros;
55−plusnO (S k) = eqRespS (plusnO k)
410+ rewrite inductiveHypothesis;
57−plusn_Sm : (n, m : Nat) -> (plus n (S m)) = S (plus n m)
414+multOneLeftNeutralStepCase = proof {
58−plusn_Sm O m = refl
415+ intros;
59−plusn_Sm (S j) m = eqRespS (plusn_Sm _ _)
416+ rewrite (plusZeroRightNeutral right);
61−plus_commutes : (n : Nat) -> (m : Nat) -> n + m = m + n
420+multDistributesOverPlusLeftStepCase = proof {
62−plus_commutes O m = sym (plusnO m)
421+ intros;
63−plus_commutes (S k) m = let ih = plus_commutes k m in ?plus_commutes_Sk
422+ rewrite sym inductiveHypothesis;
423+ rewrite sym (plusAssociative right (mult left right) (mult centre right));
65−plus_commutes_Sk = proof {
427+multDistributesOverPlusRightStepCase = proof {
67− refine sym;
429+ rewrite sym inductiveHypothesis;
68− rewrite sym ih;
430+ rewrite sym (plusAssociative (plus centre (mult left centre)) right (mult left right));
69− rewrite plusn_Sm m k;
431+ rewrite (plusAssociative centre (mult left centre) right);
432+ rewrite sym (plusCommutative (mult left centre) right);
433+ rewrite sym (plusAssociative centre right (mult left centre));
434+ rewrite sym (plusAssociative (plus centre right) (mult left centre) (mult left right));
73−plus_assoc : (n, m, p : Nat) -> n + (m + p) = (n + m) + p
438+multCommutativeStepCase = proof {
74−plus_assoc O m p = refl
439+ intros;
75−plus_assoc (S k) m p = let ih = plus_assoc k m p in eqRespS ih
440+ rewrite sym (multRightSuccPlus right left);
441+ rewrite inductiveHypothesis;
77−multnO : (n : Nat) -> (n * O) = O
445+multCommutativeBaseCase = proof {
78−multnO O = refl
446+ intros;
79−multnO (S k) = multnO k
447+ rewrite (multZeroRightZero right);
451+multRightSuccPlusStepCase = proof {
453+ rewrite inductiveHypothesis;
454+ rewrite sym inductiveHypothesis;
455+ rewrite sym (plusAssociative right left (mult left right));
456+ rewrite sym (plusCommutative right left);
457+ rewrite (plusAssociative left right (mult left right));
461+multZeroRightZeroStepCase = proof {
463+ rewrite inductiveHypothesis;
81−multn_Sm : (n, m : Nat) -> n * S m = n + n * m
467+plusAssociativeStepCase = proof {
82−multn_Sm O m = refl
468+ intros;
83−multn_Sm (S k) m = let ih = multn_Sm k m in ?multnSmSk
469+ rewrite inductiveHypothesis;
85−mult_commutes : (n, m : Nat) -> n * m = m * n
473+plusCommutativeStepCase = proof {
86−mult_commutes O m = ?mult_commO
474+ intros;
87−mult_commutes (S k) m = let ih = mult_commutes k m in ?mult_commSk
475+ rewrite (plusSuccRightSucc right left);
476+ rewrite inductiveHypothesis;
89−mult_commSk = proof {
480+plusSuccRightSuccStepCase = proof {
91− rewrite sym ih;
482+ rewrite inductiveHypothesis;
92− rewrite multn_Sm m k;
96−mult_commO = proof {
486+plusCommutativeBaseCase = proof {
98− rewrite multnO m;
488+ rewrite sym (plusZeroRightNeutral right);
102−multnSmSk = proof {
492+plusZeroRightNeutralStepCase = proof {
104− rewrite plus_commutes (mult k m) m;
494+ rewrite inductiveHypothesis;
105− rewrite sym (plus_assoc k (mult k m) m);
107− rewrite plus_commutes m (mult k (S m));
111−data Cmp : Nat -> Nat -> Set where
112− cmpLT : (y : Nat) -> Cmp x (x + S y)
114− cmpGT : (x : Nat) -> Cmp (y + S x) y
116−cmp : (n, m : Nat) -> Cmp n m
118−cmp (S n) O = cmpGT _
119−cmp O (S n) = cmpLT _
120−cmp (S x) (S y) with (cmp x y)
121− cmp (S x) (S x) | cmpEQ = cmpEQ
122− cmp (S (y + S x)) (S y) | cmpGT _ = cmpGT _
123− cmp (S x) (S (x + S y)) | cmpLT _ = cmpLT _
125− data LE : Nat -> Nat -> Set where
127− leS : LE x y -> LE (S x) (S y)