1 (* Title: ZF/ex/twos-compl.ML |
1 (* Title: ZF/ex/twos-compl.ML |
2 ID: $Id$ |
2 ID: $Id$ |
3 Author: Lawrence C Paulson, Cambridge University Computer Laboratory |
3 Author: Lawrence C Paulson, Cambridge University Computer Laboratory |
4 Copyright 1993 University of Cambridge |
4 Copyright 1993 University of Cambridge |
5 |
5 |
6 ML code for Arithmetic on binary integers; the model for theory BinFn |
6 ML code for Arithmetic on binary integers; the model for theory Bin |
7 |
7 |
8 The sign Plus stands for an infinite string of leading 0's. |
8 The sign Plus stands for an infinite string of leading 0s. |
9 The sign Minus stands for an infinite string of leading 1's. |
9 The sign Minus stands for an infinite string of leading 1s. |
10 |
10 |
11 A number can have multiple representations, namely leading 0's with sign |
11 See int_of_binary for the numerical interpretation. A number can have |
12 Plus and leading 1's with sign Minus. See int_of_binary for the numerical |
12 multiple representations, namely leading 0s with sign Plus and leading 1s with |
13 interpretation. |
13 sign Minus. A number is in NORMAL FORM if it has no such extra bits. |
14 |
14 |
15 The representation expects that (m mod 2) is 0 or 1, even if m is negative; |
15 The representation expects that (m mod 2) is 0 or 1, even if m is negative; |
16 For instance, ~5 div 2 = ~3 and ~5 mod 2 = 1; thus ~5 = (~3)*2 + 1 |
16 For instance, ~5 div 2 = ~3 and ~5 mod 2 = 1; thus ~5 = (~3)*2 + 1 |
17 |
17 |
18 Still needs division! |
18 Still needs division! |
19 |
19 |
20 print_depth 40; |
20 print_depth 40; |
21 System.Control.Print.printDepth := 350; |
21 System.Control.Print.printDepth := 350; |
22 *) |
22 *) |
23 |
23 |
24 infix 5 $$ |
24 infix 5 $$ $$$ |
25 |
25 |
26 (*Recursive datatype of binary integers*) |
26 (*Recursive datatype of binary integers*) |
27 datatype bin = Plus | Minus | op $$ of bin * int; |
27 datatype bin = Plus | Minus | op $$ of bin * int; |
28 |
28 |
29 (** Conversions between bin and int **) |
29 (** Conversions between bin and int **) |
36 | binary_of_int ~1 = Minus |
36 | binary_of_int ~1 = Minus |
37 | binary_of_int n = binary_of_int (n div 2) $$ (n mod 2); |
37 | binary_of_int n = binary_of_int (n div 2) $$ (n mod 2); |
38 |
38 |
39 (*** Addition ***) |
39 (*** Addition ***) |
40 |
40 |
41 (*Adding one to a number*) |
41 (*Attach a bit while preserving the normal form. Cases left as default |
|
42 are Plus$$$1 and Minus$$$0. *) |
|
43 fun Plus $$$ 0 = Plus |
|
44 | Minus $$$ 1 = Minus |
|
45 | v $$$ x = v$$x; |
|
46 |
|
47 (*Successor of an integer, assumed to be in normal form. |
|
48 If w$$1 is normal then w is not Minus, so bin_succ(w) $$ 0 is normal. |
|
49 But Minus$$0 is normal while Minus$$1 is not.*) |
42 fun bin_succ Plus = Plus$$1 |
50 fun bin_succ Plus = Plus$$1 |
43 | bin_succ Minus = Plus |
51 | bin_succ Minus = Plus |
44 | bin_succ (w$$1) = bin_succ(w) $$ 0 |
52 | bin_succ (w$$1) = bin_succ(w) $$ 0 |
45 | bin_succ (w$$0) = w$$1; |
53 | bin_succ (w$$0) = w $$$ 1; |
46 |
54 |
47 (*Subtracing one from a number*) |
55 (*Predecessor of an integer, assumed to be in normal form. |
|
56 If w$$0 is normal then w is not Plus, so bin_pred(w) $$ 1 is normal. |
|
57 But Plus$$1 is normal while Plus$$0 is not.*) |
48 fun bin_pred Plus = Minus |
58 fun bin_pred Plus = Minus |
49 | bin_pred Minus = Minus$$0 |
59 | bin_pred Minus = Minus$$0 |
50 | bin_pred (w$$1) = w$$0 |
60 | bin_pred (w$$1) = w $$$ 0 |
51 | bin_pred (w$$0) = bin_pred(w) $$ 1; |
61 | bin_pred (w$$0) = bin_pred(w) $$ 1; |
52 |
62 |
53 (*sum of two binary integers*) |
63 (*Sum of two binary integers in normal form. |
|
64 Ensure last $$ preserves normal form! *) |
54 fun bin_add (Plus, w) = w |
65 fun bin_add (Plus, w) = w |
55 | bin_add (Minus, w) = bin_pred w |
66 | bin_add (Minus, w) = bin_pred w |
56 | bin_add (v$$x, Plus) = v$$x |
67 | bin_add (v$$x, Plus) = v$$x |
57 | bin_add (v$$x, Minus) = bin_pred (v$$x) |
68 | bin_add (v$$x, Minus) = bin_pred (v$$x) |
58 | bin_add (v$$x, w$$y) = bin_add(v, if x+y=2 then bin_succ w else w) $$ |
69 | bin_add (v$$x, w$$y) = |
59 ((x+y) mod 2); |
70 bin_add(v, if x+y=2 then bin_succ w else w) $$$ ((x+y) mod 2); |
60 |
71 |
61 (*** Subtraction ***) |
72 (*** Subtraction ***) |
62 |
73 |
63 (*Unary minus*) |
74 (*Unary minus*) |
64 fun bin_minus Plus = Plus |
75 fun bin_minus Plus = Plus |
66 | bin_minus (w$$1) = bin_pred (bin_minus(w) $$ 0) |
77 | bin_minus (w$$1) = bin_pred (bin_minus(w) $$ 0) |
67 | bin_minus (w$$0) = bin_minus(w) $$ 0; |
78 | bin_minus (w$$0) = bin_minus(w) $$ 0; |
68 |
79 |
69 (*** Multiplication ***) |
80 (*** Multiplication ***) |
70 |
81 |
71 (*product of two bins*) |
82 (*product of two bins; a factor of 0 might cause leading 0s in result*) |
72 fun bin_mult (Plus, _) = Plus |
83 fun bin_mult (Plus, _) = Plus |
73 | bin_mult (Minus, v) = bin_minus v |
84 | bin_mult (Minus, v) = bin_minus v |
74 | bin_mult (w$$1, v) = bin_add(bin_mult(w,v) $$ 0, v) |
85 | bin_mult (w$$1, v) = bin_add(bin_mult(w,v) $$$ 0, v) |
75 | bin_mult (w$$0, v) = bin_mult(w,v) $$ 0; |
86 | bin_mult (w$$0, v) = bin_mult(w,v) $$$ 0; |
76 |
87 |
77 (*** Testing ***) |
88 (*** Testing ***) |
78 |
89 |
79 (*tests addition*) |
90 (*tests addition*) |
80 fun checksum m n = |
91 fun checksum m n = |