src/HOL/Integ/Bin.thy
author paulson
Fri, 18 Sep 1998 16:05:08 +0200
changeset 5510 ad120f7c52ad
parent 5491 22f8331cdf47
child 5512 4327eec06849
permissions -rw-r--r--
improved (but still flawed) treatment of binary arithmetic
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
2988
d38f330e58b3 Renamed sign constructors to eliminate clash with the Plus infix of Sum.thy
paulson
parents: 1632
diff changeset
     9
   The sign PlusSign stands for an infinite string of leading F's.
d38f330e58b3 Renamed sign constructors to eliminate clash with the Plus infix of Sum.thy
paulson
parents: 1632
diff changeset
    10
   The sign MinusSign 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
2988
d38f330e58b3 Renamed sign constructors to eliminate clash with the Plus infix of Sum.thy
paulson
parents: 1632
diff changeset
    13
PlusSign and leading T's with sign MinusSign.  See twos-compl.ML/int_of_binary
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
2988
d38f330e58b3 Renamed sign constructors to eliminate clash with the Plus infix of Sum.thy
paulson
parents: 1632
diff changeset
    31
    bin = PlusSign
d38f330e58b3 Renamed sign constructors to eliminate clash with the Plus infix of Sum.thy
paulson
parents: 1632
diff changeset
    32
        | MinusSign
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    33
        | Bcons bin bool
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
5491
22f8331cdf47 revised treatment of integers
paulson
parents: 5184
diff changeset
    36
  integ_of     :: bin=>int
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    37
  norm_Bcons       :: [bin,bool]=>bin
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
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    42
  h_bin :: [bin,bool,bin]=>bin
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    43
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    44
(*norm_Bcons adds a bit, suppressing leading 0s and 1s*)
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    45
5184
9b8547a9496a Adapted to new datatype package.
berghofe
parents: 4709
diff changeset
    46
primrec
2988
d38f330e58b3 Renamed sign constructors to eliminate clash with the Plus infix of Sum.thy
paulson
parents: 1632
diff changeset
    47
  norm_Plus  "norm_Bcons PlusSign  b = (if b then (Bcons PlusSign b) else PlusSign)"
d38f330e58b3 Renamed sign constructors to eliminate clash with the Plus infix of Sum.thy
paulson
parents: 1632
diff changeset
    48
  norm_Minus "norm_Bcons MinusSign b = (if b then MinusSign else (Bcons MinusSign b))"
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    49
  norm_Bcons "norm_Bcons (Bcons w' x') b = Bcons (Bcons w' x') b"
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    50
 
5184
9b8547a9496a Adapted to new datatype package.
berghofe
parents: 4709
diff changeset
    51
primrec
5491
22f8331cdf47 revised treatment of integers
paulson
parents: 5184
diff changeset
    52
  integ_of_Plus  "integ_of PlusSign = $# 0"
22f8331cdf47 revised treatment of integers
paulson
parents: 5184
diff changeset
    53
  integ_of_Minus "integ_of MinusSign = - ($# 1)"
22f8331cdf47 revised treatment of integers
paulson
parents: 5184
diff changeset
    54
  integ_of_Bcons "integ_of(Bcons w x) = (if x then $# 1 else $# 0) +
22f8331cdf47 revised treatment of integers
paulson
parents: 5184
diff changeset
    55
	                               (integ_of w) + (integ_of w)" 
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    56
5184
9b8547a9496a Adapted to new datatype package.
berghofe
parents: 4709
diff changeset
    57
primrec
2988
d38f330e58b3 Renamed sign constructors to eliminate clash with the Plus infix of Sum.thy
paulson
parents: 1632
diff changeset
    58
  succ_Plus  "bin_succ PlusSign = Bcons PlusSign True" 
d38f330e58b3 Renamed sign constructors to eliminate clash with the Plus infix of Sum.thy
paulson
parents: 1632
diff changeset
    59
  succ_Minus "bin_succ MinusSign = PlusSign"
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    60
  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
    61
5184
9b8547a9496a Adapted to new datatype package.
berghofe
parents: 4709
diff changeset
    62
primrec
2988
d38f330e58b3 Renamed sign constructors to eliminate clash with the Plus infix of Sum.thy
paulson
parents: 1632
diff changeset
    63
  pred_Plus  "bin_pred(PlusSign) = MinusSign"
d38f330e58b3 Renamed sign constructors to eliminate clash with the Plus infix of Sum.thy
paulson
parents: 1632
diff changeset
    64
  pred_Minus "bin_pred(MinusSign) = Bcons MinusSign False"
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    65
  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
    66
 
5184
9b8547a9496a Adapted to new datatype package.
berghofe
parents: 4709
diff changeset
    67
primrec
2988
d38f330e58b3 Renamed sign constructors to eliminate clash with the Plus infix of Sum.thy
paulson
parents: 1632
diff changeset
    68
  min_Plus  "bin_minus PlusSign = PlusSign"
d38f330e58b3 Renamed sign constructors to eliminate clash with the Plus infix of Sum.thy
paulson
parents: 1632
diff changeset
    69
  min_Minus "bin_minus MinusSign = Bcons PlusSign True"
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    70
  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
    71
5184
9b8547a9496a Adapted to new datatype package.
berghofe
parents: 4709
diff changeset
    72
primrec
2988
d38f330e58b3 Renamed sign constructors to eliminate clash with the Plus infix of Sum.thy
paulson
parents: 1632
diff changeset
    73
  add_Plus  "bin_add PlusSign w = w"
d38f330e58b3 Renamed sign constructors to eliminate clash with the Plus infix of Sum.thy
paulson
parents: 1632
diff changeset
    74
  add_Minus "bin_add MinusSign w = bin_pred w"
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    75
  add_Bcons "bin_add (Bcons v x) w = h_bin v x w"
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
2988
d38f330e58b3 Renamed sign constructors to eliminate clash with the Plus infix of Sum.thy
paulson
parents: 1632
diff changeset
    78
  mult_Plus "bin_mult PlusSign w = PlusSign"
d38f330e58b3 Renamed sign constructors to eliminate clash with the Plus infix of Sum.thy
paulson
parents: 1632
diff changeset
    79
  mult_Minus "bin_mult MinusSign w = bin_minus w"
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    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))"
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
2988
d38f330e58b3 Renamed sign constructors to eliminate clash with the Plus infix of Sum.thy
paulson
parents: 1632
diff changeset
    83
  h_Plus  "h_bin v x PlusSign =  Bcons v x"
d38f330e58b3 Renamed sign constructors to eliminate clash with the Plus infix of Sum.thy
paulson
parents: 1632
diff changeset
    84
  h_Minus "h_bin v x MinusSign = bin_pred (Bcons v x)"
5491
22f8331cdf47 revised treatment of integers
paulson
parents: 5184
diff changeset
    85
  h_BCons "h_bin v x (Bcons w y) = norm_Bcons
22f8331cdf47 revised treatment of integers
paulson
parents: 5184
diff changeset
    86
	            (bin_add v (if (x & y) then bin_succ w else w)) (x~=y)" 
22f8331cdf47 revised treatment of integers
paulson
parents: 5184
diff changeset
    87
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    88
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    89
end
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    90
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    91
ML
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    92
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    93
(** Concrete syntax for integers **)
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    94
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    95
local
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    96
  open Syntax;
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    97
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    98
  (* Bits *)
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
    99
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   100
  fun mk_bit 0 = const "False"
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   101
    | mk_bit 1 = const "True"
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   102
    | mk_bit _ = sys_error "mk_bit";
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   103
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   104
  fun dest_bit (Const ("False", _)) = 0
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   105
    | dest_bit (Const ("True", _)) = 1
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   106
    | dest_bit _ = raise Match;
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   107
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   108
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   109
  (* Bit strings *)   (*we try to handle superfluous leading digits nicely*)
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   110
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   111
  fun prefix_len _ [] = 0
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   112
    | prefix_len pred (x :: xs) =
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   113
        if pred x then 1 + prefix_len pred xs else 0;
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   114
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   115
  fun mk_bin str =
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   116
    let
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   117
      val (sign, digs) =
4709
d24168720303 Symbol.explode;
wenzelm
parents: 3795
diff changeset
   118
        (case Symbol.explode str of
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   119
          "#" :: "~" :: cs => (~1, cs)
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   120
        | "#" :: cs => (1, cs)
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   121
        | _ => raise ERROR);
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   122
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   123
      val zs = prefix_len (equal "0") digs;
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   124
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   125
      fun bin_of 0 = replicate zs 0
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   126
        | bin_of ~1 = replicate zs 1 @ [~1]
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   127
        | bin_of n = (n mod 2) :: bin_of (n div 2);
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   128
2988
d38f330e58b3 Renamed sign constructors to eliminate clash with the Plus infix of Sum.thy
paulson
parents: 1632
diff changeset
   129
      fun term_of [] = const "PlusSign"
d38f330e58b3 Renamed sign constructors to eliminate clash with the Plus infix of Sum.thy
paulson
parents: 1632
diff changeset
   130
        | term_of [~1] = const "MinusSign"
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   131
        | term_of (b :: bs) = const "Bcons" $ term_of bs $ mk_bit b;
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   132
    in
4709
d24168720303 Symbol.explode;
wenzelm
parents: 3795
diff changeset
   133
      term_of (bin_of (sign * (#1 (read_int digs))))
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   134
    end;
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   135
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   136
  fun dest_bin tm =
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   137
    let
2988
d38f330e58b3 Renamed sign constructors to eliminate clash with the Plus infix of Sum.thy
paulson
parents: 1632
diff changeset
   138
      fun bin_of (Const ("PlusSign", _)) = []
d38f330e58b3 Renamed sign constructors to eliminate clash with the Plus infix of Sum.thy
paulson
parents: 1632
diff changeset
   139
        | bin_of (Const ("MinusSign", _)) = [~1]
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   140
        | bin_of (Const ("Bcons", _) $ bs $ b) = dest_bit b :: bin_of bs
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   141
        | bin_of _ = raise Match;
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   142
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   143
      fun int_of [] = 0
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   144
        | int_of (b :: bs) = b + 2 * int_of bs;
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   145
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   146
      val rev_digs = bin_of tm;
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   147
      val (sign, zs) =
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   148
        (case rev rev_digs of
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   149
          ~1 :: bs => ("~", prefix_len (equal 1) bs)
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   150
        | bs => ("", prefix_len (equal 0) bs));
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   151
      val num = string_of_int (abs (int_of rev_digs));
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   152
    in
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   153
      "#" ^ sign ^ implode (replicate zs "0") ^ num
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   154
    end;
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   155
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   156
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   157
  (* translation of integer constant tokens to and from binary *)
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   158
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   159
  fun int_tr (*"_Int"*) [t as Free (str, _)] =
5491
22f8331cdf47 revised treatment of integers
paulson
parents: 5184
diff changeset
   160
        (const "integ_of" $
3795
e687069e7257 eliminated raise_term;
wenzelm
parents: 2988
diff changeset
   161
          (mk_bin str handle ERROR => raise TERM ("int_tr", [t])))
e687069e7257 eliminated raise_term;
wenzelm
parents: 2988
diff changeset
   162
    | int_tr (*"_Int"*) ts = raise TERM ("int_tr", ts);
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   163
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   164
  fun int_tr' (*"integ_of"*) [t] = const "_Int" $ free (dest_bin t)
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   165
    | int_tr' (*"integ_of"*) _ = raise Match;
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   166
in
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   167
  val parse_translation = [("_Int", int_tr)];
5491
22f8331cdf47 revised treatment of integers
paulson
parents: 5184
diff changeset
   168
  val print_translation = [("integ_of", int_tr')]; 
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   169
end;