src/HOL/Integ/Bin.thy
author oheimb
Wed, 27 Nov 1996 13:13:21 +0100
changeset 2250 891eb76b8045
parent 1632 39e146ac224c
child 2988 d38f330e58b3
permissions -rw-r--r--
added if_cancel later to simpset
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
     1
(*  Title:	HOL/Integ/Bin.thy
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
     2
    Authors:	Lawrence C Paulson, Cambridge University Computer Laboratory
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
     3
		David Spelt, University of Twente 
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
     4
    Copyright	1994  University of Cambridge
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
     5
    Copyright   1996 University of Twente
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
     6
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
     7
Arithmetic on binary integers.
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
     8
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
     9
   The sign Plus stands for an infinite string of leading F's.
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    10
   The sign Minus stands for an infinite string of leading T's.
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    11
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    12
A number can have multiple representations, namely leading F's with sign
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    13
Plus and leading T's with sign Minus.  See twos-compl.ML/int_of_binary for
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    14
the numerical interpretation.
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    15
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    16
The representation expects that (m mod 2) is 0 or 1, even if m is negative;
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    17
For instance, ~5 div 2 = ~3 and ~5 mod 2 = 1; thus ~5 = (~3)*2 + 1
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    18
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    19
Division is not defined yet!
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    20
*)
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    21
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    22
Bin = Integ + 
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    23
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    24
syntax
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    25
  "_Int"           :: xnum => int        ("_")
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    26
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    27
datatype
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    28
   bin = Plus
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    29
        | Minus
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    30
        | Bcons bin bool
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    31
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    32
consts
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    33
  integ_of_bin     :: bin=>int
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    34
  norm_Bcons       :: [bin,bool]=>bin
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    35
  bin_succ         :: bin=>bin
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    36
  bin_pred         :: bin=>bin
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    37
  bin_minus        :: bin=>bin
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    38
  bin_add,bin_mult :: [bin,bin]=>bin
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    39
  h_bin :: [bin,bool,bin]=>bin
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    40
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    41
(*norm_Bcons adds a bit, suppressing leading 0s and 1s*)
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    42
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    43
primrec norm_Bcons bin
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    44
  norm_Plus  "norm_Bcons Plus  b = (if b then (Bcons Plus b) else Plus)"
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    45
  norm_Minus "norm_Bcons Minus b = (if b then Minus else (Bcons Minus b))"
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    46
  norm_Bcons "norm_Bcons (Bcons w' x') b = Bcons (Bcons w' x') b"
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    47
 
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    48
primrec integ_of_bin bin
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    49
  iob_Plus  "integ_of_bin Plus = $#0"
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    50
  iob_Minus "integ_of_bin Minus = $~($#1)"
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    51
  iob_Bcons "integ_of_bin(Bcons w x) = (if x then $#1 else $#0) + (integ_of_bin w) + (integ_of_bin w)" 
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    52
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    53
primrec bin_succ bin
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    54
  succ_Plus  "bin_succ Plus = Bcons Plus True" 
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    55
  succ_Minus "bin_succ Minus = Plus"
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    56
  succ_Bcons "bin_succ(Bcons w x) = (if x then (Bcons (bin_succ w) False) else (norm_Bcons w True))"
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    57
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    58
primrec bin_pred bin
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    59
  pred_Plus  "bin_pred(Plus) = Minus"
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    60
  pred_Minus "bin_pred(Minus) = Bcons Minus False"
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    61
  pred_Bcons "bin_pred(Bcons w x) = (if x then (norm_Bcons w False) else (Bcons (bin_pred w) True))"
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    62
 
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    63
primrec bin_minus bin
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    64
  min_Plus  "bin_minus Plus = Plus"
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    65
  min_Minus "bin_minus Minus = Bcons Plus True"
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    66
  min_Bcons "bin_minus(Bcons w x) = (if x then (bin_pred (Bcons (bin_minus w) False)) else (Bcons (bin_minus w) False))"
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    67
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    68
primrec bin_add bin
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    69
  add_Plus  "bin_add Plus w = w"
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    70
  add_Minus "bin_add Minus w = bin_pred w"
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    71
  add_Bcons "bin_add (Bcons v x) w = h_bin v x w"
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    72
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    73
primrec bin_mult bin
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    74
  mult_Plus "bin_mult Plus w = Plus"
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    75
  mult_Minus "bin_mult Minus w = bin_minus w"
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    76
  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))"
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    77
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    78
primrec h_bin bin
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    79
  h_Plus  "h_bin v x Plus =  Bcons v x"
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    80
  h_Minus "h_bin v x Minus = bin_pred (Bcons v x)"
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    81
  h_BCons "h_bin v x (Bcons w y) = norm_Bcons (bin_add v (if (x & y) then bin_succ w else w)) (x~=y)" 
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    82
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    83
end
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    84
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    85
ML
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    86
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    87
(** Concrete syntax for integers **)
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    88
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    89
local
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    90
  open Syntax;
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    91
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    92
  (* Bits *)
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    93
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    94
  fun mk_bit 0 = const "False"
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    95
    | mk_bit 1 = const "True"
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    96
    | mk_bit _ = sys_error "mk_bit";
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    97
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    98
  fun dest_bit (Const ("False", _)) = 0
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    99
    | dest_bit (Const ("True", _)) = 1
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   100
    | dest_bit _ = raise Match;
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   101
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   102
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   103
  (* Bit strings *)   (*we try to handle superfluous leading digits nicely*)
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   104
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   105
  fun prefix_len _ [] = 0
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   106
    | prefix_len pred (x :: xs) =
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   107
        if pred x then 1 + prefix_len pred xs else 0;
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   108
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   109
  fun mk_bin str =
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   110
    let
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   111
      val (sign, digs) =
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   112
        (case explode str of
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   113
          "#" :: "~" :: cs => (~1, cs)
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   114
        | "#" :: cs => (1, cs)
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   115
        | _ => raise ERROR);
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   116
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   117
      val zs = prefix_len (equal "0") digs;
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   118
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   119
      fun bin_of 0 = replicate zs 0
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   120
        | bin_of ~1 = replicate zs 1 @ [~1]
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   121
        | bin_of n = (n mod 2) :: bin_of (n div 2);
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   122
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   123
      fun term_of [] = const "Plus"
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   124
        | term_of [~1] = const "Minus"
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   125
        | term_of (b :: bs) = const "Bcons" $ term_of bs $ mk_bit b;
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   126
    in
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   127
      term_of (bin_of (sign * (#1 (scan_int digs))))
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   128
    end;
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   129
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   130
  fun dest_bin tm =
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   131
    let
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   132
      fun bin_of (Const ("Plus", _)) = []
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   133
        | bin_of (Const ("Minus", _)) = [~1]
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   134
        | bin_of (Const ("Bcons", _) $ bs $ b) = dest_bit b :: bin_of bs
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   135
        | bin_of _ = raise Match;
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   136
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   137
      fun int_of [] = 0
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   138
        | int_of (b :: bs) = b + 2 * int_of bs;
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   139
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   140
      val rev_digs = bin_of tm;
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   141
      val (sign, zs) =
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   142
        (case rev rev_digs of
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   143
          ~1 :: bs => ("~", prefix_len (equal 1) bs)
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   144
        | bs => ("", prefix_len (equal 0) bs));
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   145
      val num = string_of_int (abs (int_of rev_digs));
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   146
    in
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   147
      "#" ^ sign ^ implode (replicate zs "0") ^ num
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   148
    end;
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   149
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   150
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   151
  (* translation of integer constant tokens to and from binary *)
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   152
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   153
  fun int_tr (*"_Int"*) [t as Free (str, _)] =
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   154
        (const "integ_of_bin" $
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   155
          (mk_bin str handle ERROR => raise_term "int_tr" [t]))
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   156
    | int_tr (*"_Int"*) ts = raise_term "int_tr" ts;
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   157
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   158
  fun int_tr' (*"integ_of"*) [t] = const "_Int" $ free (dest_bin t)
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   159
    | int_tr' (*"integ_of"*) _ = raise Match;
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   160
in
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   161
  val parse_translation = [("_Int", int_tr)];
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   162
  val print_translation = [("integ_of_bin", int_tr')]; 
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   163
end;