2 (** Big numbers as little-endian lists of digits.
4 This is borrowed from a PVS tutorial.
5 (see for instance http://fm.csl.sri.com/SSFT11/ITPSummerFormal2011.pdf)
7 In addition, we show that the representation is valid (all digits in
8 0..base-1) and canonical (no most significant 0 digits).
16 val constant base: int
17 ensures { result > 1 }
22 function value (n: num) : int =
25 | Cons d r -> d + base * value r
28 predicate valid (n: num) =
31 | Cons d Nil -> 0 < d < base
32 | Cons d r -> 0 <= d < base && valid r
35 let rec lemma nonneg (n: num) : unit
37 ensures { value n >= 0 }
39 = match n with Nil -> () | Cons _ r -> nonneg r end
41 let rec lemma msd (n: num)
43 ensures { value n = 0 <-> n = Nil }
45 = match n with Nil -> () | Cons _ r -> msd r end
47 let rec add_digit (n: num) (d: digit) : num
49 requires { 0 <= d < base }
50 ensures { valid result }
51 ensures { value result = value n + d }
55 if d = 0 then Nil else Cons d Nil
57 if d + d0 < base then Cons (d + d0) r
58 else Cons (d + d0 - base) (add_digit r 1)
61 let rec add_cin (n1 n2: num) (cin: int) : num
62 requires { valid n1 && valid n2 && 0 <= cin <= 1 }
63 ensures { valid result }
64 ensures { value result = value n1 + value n2 + cin }
71 | Cons d1 r1, Cons d2 r2 ->
72 let d = cin + d1 + d2 in
73 if d < base then Cons d (add_cin r1 r2 0)
74 else Cons (d - base) (add_cin r1 r2 1)
77 let add (n1 n2: num) : num
78 requires { valid n1 && valid n2 }
79 ensures { valid result }
80 ensures { value result = value n1 + value n2 }