src/HOL/Integ/Bin.thy
changeset 5512 4327eec06849
parent 5510 ad120f7c52ad
child 5540 0f16c3b66ab4
equal deleted inserted replaced
5511:7f52fb755581 5512:4327eec06849
     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;