idris-0.9.0: lib/prelude/nat.idr
module prelude.nat
import builtins
import prelude.cast
%access public
data Nat = O | S Nat
instance Cast Nat Int where
cast O = 0
cast (S k) = 1 + cast k
plus : Nat -> Nat -> Nat
plus O y = y
plus (S k) y = S (plus k y)
eqRespS : m = n -> S m = S n
eqRespS refl = refl
eqRespS' : S m = S n -> m = n
eqRespS' refl = refl
sub : Nat -> Nat -> Nat
sub O y = O
sub (S k) (S y) = sub k y
sub x O = x
mult : Nat -> Nat -> Nat
mult O y = O
mult (S k) y = plus y (mult k y)
instance Eq Nat where
O == O = True
(S x) == (S y) = x == y
O == (S y) = False
(S x) == O = False
instance Ord Nat where
compare O O = EQ
compare O (S k) = LT
compare (S k) O = GT
compare (S x) (S y) = compare x y
instance Num Nat where
(+) = plus
(-) = sub
(*) = mult
fromInteger 0 = O
fromInteger n = if (n > 0) then (S (fromInteger (n-1))) else O
plusnO : (m : Nat) -> m + O = m
plusnO O = refl
plusnO (S k) = eqRespS (plusnO k)
plusn_Sm : (n, m : Nat) -> (plus n (S m)) = S (plus n m)
plusn_Sm O m = refl
plusn_Sm (S j) m = eqRespS (plusn_Sm _ _)
plus_commutes : (n : Nat) -> (m : Nat) -> n + m = m + n
plus_commutes O m = sym (plusnO m)
plus_commutes (S k) m = let ih = plus_commutes k m in ?plus_commutes_Sk
plus_commutes_Sk = proof {
intros;
refine sym;
rewrite sym ih;
rewrite plusn_Sm m k;
trivial;
}
plus_assoc : (n, m, p : Nat) -> n + (m + p) = (n + m) + p
plus_assoc O m p = refl
plus_assoc (S k) m p = let ih = plus_assoc k m p in eqRespS ih
data Cmp : Nat -> Nat -> Set where
cmpLT : (y : Nat) -> Cmp x (x + S y)
cmpEQ : Cmp x x
cmpGT : (x : Nat) -> Cmp (y + S x) y
cmp : (n, m : Nat) -> Cmp n m
cmp O O = cmpEQ
cmp (S n) O = cmpGT _
cmp O (S n) = cmpLT _
cmp (S x) (S y) with (cmp x y)
cmp (S x) (S x) | cmpEQ = cmpEQ
cmp (S (y + S x)) (S y) | cmpGT _ = cmpGT _
cmp (S x) (S (x + S y)) | cmpLT _ = cmpLT _
multnO : (n : Nat) -> (n * O) = O
multnO O = refl
multnO (S k) = multnO k
multn_Sm : (n, m : Nat) -> n * S m = n + n * m
multn_Sm O m = refl
multn_Sm (S k) m = let ih = multn_Sm k m in ?multnSmSk
mult_commutes : (n, m : Nat) -> n * m = m * n
mult_commutes O m = ?mult_commO
mult_commutes (S k) m = let ih = mult_commutes k m in ?mult_commSk
mult_commSk = proof {
intros;
rewrite sym ih;
rewrite multn_Sm m k;
trivial;
}
mult_commO = proof {
intro;
rewrite multnO m;
trivial;
}
multnSmSk = proof {
intros;
rewrite plus_commutes (mult k m) m;
rewrite sym (plus_assoc k (mult k m) m);
rewrite ih;
rewrite plus_commutes m (mult k (S m));
trivial;
}