src/HOL/Integ/Bin.thy
author paulson
Mon, 21 Sep 1998 10:43:09 +0200
changeset 5512 4327eec06849
parent 5510 ad120f7c52ad
child 5540 0f16c3b66ab4
permissions -rw-r--r--
much renaming and tidying
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
5512
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
     9
   The sign Pls stands for an infinite string of leading F's.
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    10
   The sign Min stands for an infinite string of leading T's.
1632
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
5512
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    13
Pls and leading T's with sign Min.  See ZF/ex/twos-compl.ML/int_of_binary
2988
d38f330e58b3 Renamed sign constructors to eliminate clash with the Plus infix of Sum.thy
paulson
parents: 1632
diff changeset
    14
for the numerical interpretation.
1632
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
2988
d38f330e58b3 Renamed sign constructors to eliminate clash with the Plus infix of Sum.thy
paulson
parents: 1632
diff changeset
    19
Division is not defined yet!  To do it efficiently requires computing the
d38f330e58b3 Renamed sign constructors to eliminate clash with the Plus infix of Sum.thy
paulson
parents: 1632
diff changeset
    20
quotient and remainder using ML and checking the answer using multiplication
d38f330e58b3 Renamed sign constructors to eliminate clash with the Plus infix of Sum.thy
paulson
parents: 1632
diff changeset
    21
by proof.  Then uniqueness of the quotient and remainder yields theorems
d38f330e58b3 Renamed sign constructors to eliminate clash with the Plus infix of Sum.thy
paulson
parents: 1632
diff changeset
    22
quoting the previously computed values.  (Or code an oracle...)
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    23
*)
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    24
5184
9b8547a9496a Adapted to new datatype package.
berghofe
parents: 4709
diff changeset
    25
Bin = Integ + Datatype +
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    26
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    27
syntax
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    28
  "_Int"           :: xnum => int        ("_")
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    29
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    30
datatype
5512
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    31
    bin = Pls
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    32
        | Min
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    33
        | BIT bin bool	(infixl 90)
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    34
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    35
consts
5512
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    36
  integ_of         :: bin=>int
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    37
  NCons            :: [bin,bool]=>bin
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    38
  bin_succ         :: bin=>bin
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    39
  bin_pred         :: bin=>bin
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    40
  bin_minus        :: bin=>bin
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    41
  bin_add,bin_mult :: [bin,bin]=>bin
5512
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    42
  h_bin            :: [bin,bool,bin]=>bin
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    43
5512
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    44
(*NCons inserts a bit, suppressing leading 0s and 1s*)
5184
9b8547a9496a Adapted to new datatype package.
berghofe
parents: 4709
diff changeset
    45
primrec
5512
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    46
  norm_Pls "NCons Pls b = (if b then (Pls BIT b) else Pls)"
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    47
  norm_Min "NCons Min b = (if b then Min else (Min BIT b))"
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    48
  NCons    "NCons (w' BIT x') b = (w' BIT x') BIT b"
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    49
 
5184
9b8547a9496a Adapted to new datatype package.
berghofe
parents: 4709
diff changeset
    50
primrec
5512
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    51
  integ_of_Pls  "integ_of Pls = $# 0"
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    52
  integ_of_Min  "integ_of Min = - ($# 1)"
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    53
  integ_of_BIT  "integ_of(w BIT x) = (if x then $# 1 else $# 0) +
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    54
	                             (integ_of w) + (integ_of w)" 
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    55
5184
9b8547a9496a Adapted to new datatype package.
berghofe
parents: 4709
diff changeset
    56
primrec
5512
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    57
  succ_Pls  "bin_succ Pls = Pls BIT True" 
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    58
  succ_Min  "bin_succ Min = Pls"
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    59
  succ_BIT  "bin_succ(w BIT x) =
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    60
  	        (if x then bin_succ w BIT False
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    61
	              else NCons w True)"
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    62
5184
9b8547a9496a Adapted to new datatype package.
berghofe
parents: 4709
diff changeset
    63
primrec
5512
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    64
  pred_Pls  "bin_pred Pls = Min"
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    65
  pred_Min  "bin_pred Min = Min BIT False"
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    66
  pred_BIT  "bin_pred(w BIT x) =
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    67
	        (if x then NCons w False
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    68
		      else (bin_pred w) BIT True)"
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    69
 
5184
9b8547a9496a Adapted to new datatype package.
berghofe
parents: 4709
diff changeset
    70
primrec
5512
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    71
  minus_Pls  "bin_minus Pls = Pls"
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    72
  minus_Min  "bin_minus Min = Pls BIT True"
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    73
  minus_BIT  "bin_minus(w BIT x) =
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    74
	         (if x then bin_pred (NCons (bin_minus w) False)
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    75
		       else bin_minus w BIT False)"
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    76
5184
9b8547a9496a Adapted to new datatype package.
berghofe
parents: 4709
diff changeset
    77
primrec
5512
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    78
  add_Pls  "bin_add Pls w = w"
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    79
  add_Min  "bin_add Min w = bin_pred w"
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    80
  add_BIT  "bin_add (v BIT x) w = h_bin v x w"
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    81
5184
9b8547a9496a Adapted to new datatype package.
berghofe
parents: 4709
diff changeset
    82
primrec
5512
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    83
  "h_bin v x Pls = v BIT x"
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    84
  "h_bin v x Min = bin_pred (v BIT x)"
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    85
  "h_bin v x (w BIT y) =
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    86
	     NCons (bin_add v (if (x & y) then bin_succ w else w))
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    87
	           (x~=y)" 
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    88
5184
9b8547a9496a Adapted to new datatype package.
berghofe
parents: 4709
diff changeset
    89
primrec
5512
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    90
  mult_Pls  "bin_mult Pls w = Pls"
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    91
  mult_Min  "bin_mult Min w = bin_minus w"
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    92
  mult_BIT "bin_mult (v BIT x) w =
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    93
	        (if x then (bin_add (NCons (bin_mult v w) False) w)
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
    94
	              else (NCons (bin_mult v w) False))"
5491
22f8331cdf47 revised treatment of integers
paulson
parents: 5184
diff changeset
    95
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    96
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    97
end
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    98
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    99
ML
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   100
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   101
(** Concrete syntax for integers **)
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   102
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   103
local
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   104
  open Syntax;
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   105
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   106
  (* Bits *)
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   107
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   108
  fun mk_bit 0 = const "False"
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   109
    | mk_bit 1 = const "True"
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   110
    | mk_bit _ = sys_error "mk_bit";
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   111
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   112
  fun dest_bit (Const ("False", _)) = 0
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   113
    | dest_bit (Const ("True", _)) = 1
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   114
    | dest_bit _ = raise Match;
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   115
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   116
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   117
  (* Bit strings *)   (*we try to handle superfluous leading digits nicely*)
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 prefix_len _ [] = 0
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   120
    | prefix_len pred (x :: xs) =
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   121
        if pred x then 1 + prefix_len pred xs else 0;
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 mk_bin str =
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   124
    let
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   125
      val (sign, digs) =
4709
d24168720303 Symbol.explode;
wenzelm
parents: 3795
diff changeset
   126
        (case Symbol.explode str of
5512
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
   127
          "#" :: "-" :: cs => (~1, cs)
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   128
        | "#" :: cs => (1, cs)
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   129
        | _ => raise ERROR);
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   130
5512
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
   131
      fun bin_of 0  = []
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
   132
        | bin_of ~1 = [~1]
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
   133
        | bin_of n  = (n mod 2) :: bin_of (n div 2);
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   134
5512
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
   135
      fun term_of []   = const "Bin.bin.Pls"
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
   136
        | term_of [~1] = const "Bin.bin.Min"
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
   137
        | term_of (b :: bs) = const "Bin.bin.op BIT" $ term_of bs $ mk_bit b;
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   138
    in
4709
d24168720303 Symbol.explode;
wenzelm
parents: 3795
diff changeset
   139
      term_of (bin_of (sign * (#1 (read_int digs))))
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   140
    end;
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   141
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   142
  fun dest_bin tm =
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   143
    let
5512
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
   144
      fun bin_of (Const ("Pls", _)) = []
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
   145
        | bin_of (Const ("Min", _)) = [~1]
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
   146
        | bin_of (Const ("op BIT", _) $ bs $ b) = dest_bit b :: bin_of bs
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   147
        | bin_of _ = raise Match;
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   148
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   149
      fun int_of [] = 0
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   150
        | int_of (b :: bs) = b + 2 * int_of bs;
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   151
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   152
      val rev_digs = bin_of tm;
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   153
      val (sign, zs) =
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   154
        (case rev rev_digs of
5512
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
   155
          ~1 :: bs => ("-", prefix_len (equal 1) bs)
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   156
        | bs => ("", prefix_len (equal 0) bs));
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   157
      val num = string_of_int (abs (int_of rev_digs));
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   158
    in
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   159
      "#" ^ sign ^ implode (replicate zs "0") ^ num
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   160
    end;
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   161
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   162
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   163
  (* translation of integer constant tokens to and from binary *)
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   164
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   165
  fun int_tr (*"_Int"*) [t as Free (str, _)] =
5491
22f8331cdf47 revised treatment of integers
paulson
parents: 5184
diff changeset
   166
        (const "integ_of" $
3795
e687069e7257 eliminated raise_term;
wenzelm
parents: 2988
diff changeset
   167
          (mk_bin str handle ERROR => raise TERM ("int_tr", [t])))
e687069e7257 eliminated raise_term;
wenzelm
parents: 2988
diff changeset
   168
    | int_tr (*"_Int"*) ts = raise TERM ("int_tr", ts);
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   169
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   170
  fun int_tr' (*"integ_of"*) [t] = const "_Int" $ free (dest_bin t)
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   171
    | int_tr' (*"integ_of"*) _ = raise Match;
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   172
in
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   173
  val parse_translation = [("_Int", int_tr)];
5491
22f8331cdf47 revised treatment of integers
paulson
parents: 5184
diff changeset
   174
  val print_translation = [("integ_of", int_tr')]; 
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   175
end;