4 Copyright 1994 University of Cambridge |
4 Copyright 1994 University of Cambridge |
5 Copyright 1996 University of Twente |
5 Copyright 1996 University of Twente |
6 |
6 |
7 Arithmetic on binary integers. |
7 Arithmetic on binary integers. |
8 |
8 |
9 The sign PlusSign stands for an infinite string of leading F's. |
9 The sign Pls stands for an infinite string of leading F's. |
10 The sign MinusSign stands for an infinite string of leading T's. |
10 The sign Min stands for an infinite string of leading T's. |
11 |
11 |
12 A number can have multiple representations, namely leading F's with sign |
12 A number can have multiple representations, namely leading F's with sign |
13 PlusSign and leading T's with sign MinusSign. See twos-compl.ML/int_of_binary |
13 Pls and leading T's with sign Min. See ZF/ex/twos-compl.ML/int_of_binary |
14 for the numerical interpretation. |
14 for the numerical interpretation. |
15 |
15 |
16 The representation expects that (m mod 2) is 0 or 1, even if m is negative; |
16 The representation expects that (m mod 2) is 0 or 1, even if m is negative; |
17 For instance, ~5 div 2 = ~3 and ~5 mod 2 = 1; thus ~5 = (~3)*2 + 1 |
17 For instance, ~5 div 2 = ~3 and ~5 mod 2 = 1; thus ~5 = (~3)*2 + 1 |
18 |
18 |
26 |
26 |
27 syntax |
27 syntax |
28 "_Int" :: xnum => int ("_") |
28 "_Int" :: xnum => int ("_") |
29 |
29 |
30 datatype |
30 datatype |
31 bin = PlusSign |
31 bin = Pls |
32 | MinusSign |
32 | Min |
33 | Bcons bin bool |
33 | BIT bin bool (infixl 90) |
34 |
34 |
35 consts |
35 consts |
36 integ_of :: bin=>int |
36 integ_of :: bin=>int |
37 norm_Bcons :: [bin,bool]=>bin |
37 NCons :: [bin,bool]=>bin |
38 bin_succ :: bin=>bin |
38 bin_succ :: bin=>bin |
39 bin_pred :: bin=>bin |
39 bin_pred :: bin=>bin |
40 bin_minus :: bin=>bin |
40 bin_minus :: bin=>bin |
41 bin_add,bin_mult :: [bin,bin]=>bin |
41 bin_add,bin_mult :: [bin,bin]=>bin |
42 h_bin :: [bin,bool,bin]=>bin |
42 h_bin :: [bin,bool,bin]=>bin |
43 |
43 |
44 (*norm_Bcons adds a bit, suppressing leading 0s and 1s*) |
44 (*NCons inserts a bit, suppressing leading 0s and 1s*) |
|
45 primrec |
|
46 norm_Pls "NCons Pls b = (if b then (Pls BIT b) else Pls)" |
|
47 norm_Min "NCons Min b = (if b then Min else (Min BIT b))" |
|
48 NCons "NCons (w' BIT x') b = (w' BIT x') BIT b" |
|
49 |
|
50 primrec |
|
51 integ_of_Pls "integ_of Pls = $# 0" |
|
52 integ_of_Min "integ_of Min = - ($# 1)" |
|
53 integ_of_BIT "integ_of(w BIT x) = (if x then $# 1 else $# 0) + |
|
54 (integ_of w) + (integ_of w)" |
45 |
55 |
46 primrec |
56 primrec |
47 norm_Plus "norm_Bcons PlusSign b = (if b then (Bcons PlusSign b) else PlusSign)" |
57 succ_Pls "bin_succ Pls = Pls BIT True" |
48 norm_Minus "norm_Bcons MinusSign b = (if b then MinusSign else (Bcons MinusSign b))" |
58 succ_Min "bin_succ Min = Pls" |
49 norm_Bcons "norm_Bcons (Bcons w' x') b = Bcons (Bcons w' x') b" |
59 succ_BIT "bin_succ(w BIT x) = |
|
60 (if x then bin_succ w BIT False |
|
61 else NCons w True)" |
|
62 |
|
63 primrec |
|
64 pred_Pls "bin_pred Pls = Min" |
|
65 pred_Min "bin_pred Min = Min BIT False" |
|
66 pred_BIT "bin_pred(w BIT x) = |
|
67 (if x then NCons w False |
|
68 else (bin_pred w) BIT True)" |
50 |
69 |
51 primrec |
70 primrec |
52 integ_of_Plus "integ_of PlusSign = $# 0" |
71 minus_Pls "bin_minus Pls = Pls" |
53 integ_of_Minus "integ_of MinusSign = - ($# 1)" |
72 minus_Min "bin_minus Min = Pls BIT True" |
54 integ_of_Bcons "integ_of(Bcons w x) = (if x then $# 1 else $# 0) + |
73 minus_BIT "bin_minus(w BIT x) = |
55 (integ_of w) + (integ_of w)" |
74 (if x then bin_pred (NCons (bin_minus w) False) |
|
75 else bin_minus w BIT False)" |
56 |
76 |
57 primrec |
77 primrec |
58 succ_Plus "bin_succ PlusSign = Bcons PlusSign True" |
78 add_Pls "bin_add Pls w = w" |
59 succ_Minus "bin_succ MinusSign = PlusSign" |
79 add_Min "bin_add Min w = bin_pred w" |
60 succ_Bcons "bin_succ(Bcons w x) = (if x then (Bcons (bin_succ w) False) else (norm_Bcons w True))" |
80 add_BIT "bin_add (v BIT x) w = h_bin v x w" |
61 |
81 |
62 primrec |
82 primrec |
63 pred_Plus "bin_pred(PlusSign) = MinusSign" |
83 "h_bin v x Pls = v BIT x" |
64 pred_Minus "bin_pred(MinusSign) = Bcons MinusSign False" |
84 "h_bin v x Min = bin_pred (v BIT x)" |
65 pred_Bcons "bin_pred(Bcons w x) = (if x then (norm_Bcons w False) else (Bcons (bin_pred w) True))" |
85 "h_bin v x (w BIT y) = |
66 |
86 NCons (bin_add v (if (x & y) then bin_succ w else w)) |
67 primrec |
87 (x~=y)" |
68 min_Plus "bin_minus PlusSign = PlusSign" |
|
69 min_Minus "bin_minus MinusSign = Bcons PlusSign True" |
|
70 min_Bcons "bin_minus(Bcons w x) = (if x then (bin_pred (Bcons (bin_minus w) False)) else (Bcons (bin_minus w) False))" |
|
71 |
88 |
72 primrec |
89 primrec |
73 add_Plus "bin_add PlusSign w = w" |
90 mult_Pls "bin_mult Pls w = Pls" |
74 add_Minus "bin_add MinusSign w = bin_pred w" |
91 mult_Min "bin_mult Min w = bin_minus w" |
75 add_Bcons "bin_add (Bcons v x) w = h_bin v x w" |
92 mult_BIT "bin_mult (v BIT x) w = |
76 |
93 (if x then (bin_add (NCons (bin_mult v w) False) w) |
77 primrec |
94 else (NCons (bin_mult v w) False))" |
78 mult_Plus "bin_mult PlusSign w = PlusSign" |
|
79 mult_Minus "bin_mult MinusSign w = bin_minus w" |
|
80 mult_Bcons "bin_mult (Bcons v x) w = (if x then (bin_add (norm_Bcons (bin_mult v w) False) w) else (norm_Bcons (bin_mult v w) False))" |
|
81 |
|
82 primrec |
|
83 h_Plus "h_bin v x PlusSign = Bcons v x" |
|
84 h_Minus "h_bin v x MinusSign = bin_pred (Bcons v x)" |
|
85 h_BCons "h_bin v x (Bcons w y) = norm_Bcons |
|
86 (bin_add v (if (x & y) then bin_succ w else w)) (x~=y)" |
|
87 |
95 |
88 |
96 |
89 end |
97 end |
90 |
98 |
91 ML |
99 ML |
114 |
122 |
115 fun mk_bin str = |
123 fun mk_bin str = |
116 let |
124 let |
117 val (sign, digs) = |
125 val (sign, digs) = |
118 (case Symbol.explode str of |
126 (case Symbol.explode str of |
119 "#" :: "~" :: cs => (~1, cs) |
127 "#" :: "-" :: cs => (~1, cs) |
120 | "#" :: cs => (1, cs) |
128 | "#" :: cs => (1, cs) |
121 | _ => raise ERROR); |
129 | _ => raise ERROR); |
122 |
130 |
123 val zs = prefix_len (equal "0") digs; |
131 fun bin_of 0 = [] |
|
132 | bin_of ~1 = [~1] |
|
133 | bin_of n = (n mod 2) :: bin_of (n div 2); |
124 |
134 |
125 fun bin_of 0 = replicate zs 0 |
135 fun term_of [] = const "Bin.bin.Pls" |
126 | bin_of ~1 = replicate zs 1 @ [~1] |
136 | term_of [~1] = const "Bin.bin.Min" |
127 | bin_of n = (n mod 2) :: bin_of (n div 2); |
137 | term_of (b :: bs) = const "Bin.bin.op BIT" $ term_of bs $ mk_bit b; |
128 |
|
129 fun term_of [] = const "PlusSign" |
|
130 | term_of [~1] = const "MinusSign" |
|
131 | term_of (b :: bs) = const "Bcons" $ term_of bs $ mk_bit b; |
|
132 in |
138 in |
133 term_of (bin_of (sign * (#1 (read_int digs)))) |
139 term_of (bin_of (sign * (#1 (read_int digs)))) |
134 end; |
140 end; |
135 |
141 |
136 fun dest_bin tm = |
142 fun dest_bin tm = |
137 let |
143 let |
138 fun bin_of (Const ("PlusSign", _)) = [] |
144 fun bin_of (Const ("Pls", _)) = [] |
139 | bin_of (Const ("MinusSign", _)) = [~1] |
145 | bin_of (Const ("Min", _)) = [~1] |
140 | bin_of (Const ("Bcons", _) $ bs $ b) = dest_bit b :: bin_of bs |
146 | bin_of (Const ("op BIT", _) $ bs $ b) = dest_bit b :: bin_of bs |
141 | bin_of _ = raise Match; |
147 | bin_of _ = raise Match; |
142 |
148 |
143 fun int_of [] = 0 |
149 fun int_of [] = 0 |
144 | int_of (b :: bs) = b + 2 * int_of bs; |
150 | int_of (b :: bs) = b + 2 * int_of bs; |
145 |
151 |
146 val rev_digs = bin_of tm; |
152 val rev_digs = bin_of tm; |
147 val (sign, zs) = |
153 val (sign, zs) = |
148 (case rev rev_digs of |
154 (case rev rev_digs of |
149 ~1 :: bs => ("~", prefix_len (equal 1) bs) |
155 ~1 :: bs => ("-", prefix_len (equal 1) bs) |
150 | bs => ("", prefix_len (equal 0) bs)); |
156 | bs => ("", prefix_len (equal 0) bs)); |
151 val num = string_of_int (abs (int_of rev_digs)); |
157 val num = string_of_int (abs (int_of rev_digs)); |
152 in |
158 in |
153 "#" ^ sign ^ implode (replicate zs "0") ^ num |
159 "#" ^ sign ^ implode (replicate zs "0") ^ num |
154 end; |
160 end; |