src/ZF/ex/twos-compl.ML
changeset 0 a5a9c433f639
equal deleted inserted replaced
-1:000000000000 0:a5a9c433f639
       
     1 (*  Title: 	ZF/ex/twos-compl.ML
       
     2     ID:         $Id$
       
     3     Author: 	Lawrence C Paulson, Cambridge University Computer Laboratory
       
     4     Copyright   1993  University of Cambridge
       
     5 
       
     6 ML code for Arithmetic on binary integers; the model for theory BinFn
       
     7 
       
     8    The sign Plus stands for an infinite string of leading 0's.
       
     9    The sign Minus stands for an infinite string of leading 1's.
       
    10 
       
    11 A number can have multiple representations, namely leading 0's with sign
       
    12 Plus and leading 1's with sign Minus.  See int_of_binary for the numerical
       
    13 interpretation.
       
    14 
       
    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
       
    17 
       
    18 Still needs division!
       
    19 
       
    20 print_depth 40;
       
    21 System.Control.Print.printDepth := 350; 
       
    22 *)
       
    23 
       
    24 infix 5 $$ 
       
    25 
       
    26 (*Recursive datatype of binary integers*)
       
    27 datatype bin = Plus | Minus | op $$ of bin * int;
       
    28 
       
    29 (** Conversions between bin and int **)
       
    30 
       
    31 fun int_of_binary Plus = 0
       
    32   | int_of_binary Minus = ~1
       
    33   | int_of_binary (w$$b) = 2 * int_of_binary w + b;
       
    34 
       
    35 fun binary_of_int 0 = Plus
       
    36   | binary_of_int ~1 = Minus
       
    37   | binary_of_int n = binary_of_int (n div 2) $$ (n mod 2);
       
    38 
       
    39 (*** Addition ***)
       
    40 
       
    41 (*Adding one to a number*)
       
    42 fun bin_succ Plus = Plus$$1
       
    43   | bin_succ Minus = Plus
       
    44   | bin_succ (w$$1) = bin_succ(w) $$ 0
       
    45   | bin_succ (w$$0) = w$$1;
       
    46 
       
    47 (*Subtracing one from a number*)
       
    48 fun bin_pred Plus = Minus
       
    49   | bin_pred Minus = Minus$$0
       
    50   | bin_pred (w$$1) = w$$0
       
    51   | bin_pred (w$$0) = bin_pred(w) $$ 1;
       
    52 
       
    53 (*sum of two binary integers*)
       
    54 fun bin_add (Plus, w) = w
       
    55   | bin_add (Minus, w) = bin_pred w
       
    56   | bin_add (v$$x, Plus) = v$$x
       
    57   | 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) $$ 
       
    59                            ((x+y) mod 2);
       
    60 
       
    61 (*** Subtraction ***)
       
    62 
       
    63 (*Unary minus*)
       
    64 fun bin_minus Plus = Plus
       
    65   | bin_minus Minus = Plus$$1
       
    66   | bin_minus (w$$1) = bin_pred (bin_minus(w) $$ 0)
       
    67   | bin_minus (w$$0) = bin_minus(w) $$ 0;
       
    68 
       
    69 (*** Multiplication ***)
       
    70 
       
    71 (*product of two bins*)
       
    72 fun bin_mult (Plus, _) = Plus
       
    73   | bin_mult (Minus, v) = bin_minus v
       
    74   | bin_mult (w$$1, v) = bin_add(bin_mult(w,v) $$ 0,  v)
       
    75   | bin_mult (w$$0, v) = bin_mult(w,v) $$ 0;
       
    76 
       
    77 (*** Testing ***)
       
    78 
       
    79 (*tests addition*)
       
    80 fun checksum m n =
       
    81     let val wm = binary_of_int m
       
    82         and wn = binary_of_int n
       
    83         val wsum = bin_add(wm,wn)
       
    84     in  if m+n = int_of_binary wsum then (wm, wn, wsum, m+n)
       
    85         else raise Match
       
    86     end;
       
    87 
       
    88 fun bfact n = if n=0 then  Plus$$1  
       
    89               else  bin_mult(binary_of_int n, bfact(n-1));
       
    90 
       
    91 (*Examples...
       
    92 bfact 5;
       
    93 int_of_binary it;
       
    94 bfact 69;
       
    95 int_of_binary it;
       
    96 
       
    97 (*leading zeros!*)
       
    98 bin_add(binary_of_int 1234, binary_of_int ~1234);
       
    99 bin_mult(binary_of_int 1234, Plus);
       
   100 
       
   101 (*leading ones!*)
       
   102 bin_add(binary_of_int 1234, binary_of_int ~1235);
       
   103 *)