src/ZF/ex/twos_compl.ML
changeset 912 ed9e0c70a5da
parent 0 a5a9c433f639
child 1461 6bcb44e4d6e5
equal deleted inserted replaced
911:55754d6d399c 912:ed9e0c70a5da
     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 =
    92 bfact 5;
   103 bfact 5;
    93 int_of_binary it;
   104 int_of_binary it;
    94 bfact 69;
   105 bfact 69;
    95 int_of_binary it;
   106 int_of_binary it;
    96 
   107 
    97 (*leading zeros!*)
   108 (*leading zeros??*)
    98 bin_add(binary_of_int 1234, binary_of_int ~1234);
   109 bin_add(binary_of_int 1234, binary_of_int ~1234);
    99 bin_mult(binary_of_int 1234, Plus);
   110 bin_mult(binary_of_int 1234, Plus);
   100 
   111 
   101 (*leading ones!*)
   112 (*leading ones??*)
       
   113 bin_add(binary_of_int 1, binary_of_int ~2);
   102 bin_add(binary_of_int 1234, binary_of_int ~1235);
   114 bin_add(binary_of_int 1234, binary_of_int ~1235);
   103 *)
   115 *)