src/HOL/Integ/Bin.thy
author wenzelm
Wed, 17 Mar 1999 16:53:46 +0100
changeset 6394 3d9fd50fcc43
parent 5582 a356fb49e69e
child 6396 fee481d8ea7a
permissions -rw-r--r--
Theory.sign_of;
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
5562
02261e6880d1 Renaming of Integ/Integ.* to Integ/Int.*, and renaming of related constants
paulson
parents: 5546
diff changeset
    25
Bin = Int + 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
5546
a48cbe410618 renamed some axioms
paulson
parents: 5540
diff changeset
    42
  adding            :: [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
5540
0f16c3b66ab4 much renaming and reorganization
paulson
parents: 5512
diff changeset
    46
  NCons_Pls "NCons Pls b = (if b then (Pls BIT b) else Pls)"
0f16c3b66ab4 much renaming and reorganization
paulson
parents: 5512
diff changeset
    47
  NCons_Min "NCons Min b = (if b then Min else (Min BIT b))"
0f16c3b66ab4 much renaming and reorganization
paulson
parents: 5512
diff changeset
    48
  NCons_BIT "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
5582
a356fb49e69e many renamings and changes. Simproc for cancelling common terms in relations
paulson
parents: 5562
diff changeset
    51
  integ_of_Pls  "integ_of Pls = int 0"
a356fb49e69e many renamings and changes. Simproc for cancelling common terms in relations
paulson
parents: 5562
diff changeset
    52
  integ_of_Min  "integ_of Min = - (int 1)"
a356fb49e69e many renamings and changes. Simproc for cancelling common terms in relations
paulson
parents: 5562
diff changeset
    53
  integ_of_BIT  "integ_of(w BIT x) = (if x then int 1 else int 0) +
5512
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
5546
a48cbe410618 renamed some axioms
paulson
parents: 5540
diff changeset
    57
  bin_succ_Pls  "bin_succ Pls = Pls BIT True" 
a48cbe410618 renamed some axioms
paulson
parents: 5540
diff changeset
    58
  bin_succ_Min  "bin_succ Min = Pls"
a48cbe410618 renamed some axioms
paulson
parents: 5540
diff changeset
    59
  bin_succ_BIT  "bin_succ(w BIT x) =
a48cbe410618 renamed some axioms
paulson
parents: 5540
diff changeset
    60
  	            (if x then bin_succ w BIT False
a48cbe410618 renamed some axioms
paulson
parents: 5540
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
5546
a48cbe410618 renamed some axioms
paulson
parents: 5540
diff changeset
    64
  bin_pred_Pls  "bin_pred Pls = Min"
a48cbe410618 renamed some axioms
paulson
parents: 5540
diff changeset
    65
  bin_pred_Min  "bin_pred Min = Min BIT False"
a48cbe410618 renamed some axioms
paulson
parents: 5540
diff changeset
    66
  bin_pred_BIT  "bin_pred(w BIT x) =
a48cbe410618 renamed some axioms
paulson
parents: 5540
diff changeset
    67
	            (if x then NCons w False
a48cbe410618 renamed some axioms
paulson
parents: 5540
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
5546
a48cbe410618 renamed some axioms
paulson
parents: 5540
diff changeset
    71
  bin_minus_Pls  "bin_minus Pls = Pls"
a48cbe410618 renamed some axioms
paulson
parents: 5540
diff changeset
    72
  bin_minus_Min  "bin_minus Min = Pls BIT True"
a48cbe410618 renamed some axioms
paulson
parents: 5540
diff changeset
    73
  bin_minus_BIT  "bin_minus(w BIT x) =
a48cbe410618 renamed some axioms
paulson
parents: 5540
diff changeset
    74
	             (if x then bin_pred (NCons (bin_minus w) False)
a48cbe410618 renamed some axioms
paulson
parents: 5540
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
5546
a48cbe410618 renamed some axioms
paulson
parents: 5540
diff changeset
    78
  bin_add_Pls  "bin_add Pls w = w"
a48cbe410618 renamed some axioms
paulson
parents: 5540
diff changeset
    79
  bin_add_Min  "bin_add Min w = bin_pred w"
a48cbe410618 renamed some axioms
paulson
parents: 5540
diff changeset
    80
  bin_add_BIT  "bin_add (v BIT x) w = adding 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
5546
a48cbe410618 renamed some axioms
paulson
parents: 5540
diff changeset
    83
  "adding v x Pls = v BIT x"
a48cbe410618 renamed some axioms
paulson
parents: 5540
diff changeset
    84
  "adding v x Min = bin_pred (v BIT x)"
a48cbe410618 renamed some axioms
paulson
parents: 5540
diff changeset
    85
  "adding v x (w BIT y) =
a48cbe410618 renamed some axioms
paulson
parents: 5540
diff changeset
    86
 	     NCons (bin_add v (if (x & y) then bin_succ w else w))
5512
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
5546
a48cbe410618 renamed some axioms
paulson
parents: 5540
diff changeset
    90
  bin_mult_Pls  "bin_mult Pls w = Pls"
a48cbe410618 renamed some axioms
paulson
parents: 5540
diff changeset
    91
  bin_mult_Min  "bin_mult Min w = bin_minus w"
a48cbe410618 renamed some axioms
paulson
parents: 5540
diff changeset
    92
  bin_mult_BIT  "bin_mult (v BIT x) w =
a48cbe410618 renamed some axioms
paulson
parents: 5540
diff changeset
    93
	            (if x then (bin_add (NCons (bin_mult v w) False) w)
a48cbe410618 renamed some axioms
paulson
parents: 5540
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
5540
0f16c3b66ab4 much renaming and reorganization
paulson
parents: 5512
diff changeset
   144
      (*We consider both "spellings", since Min might be declared elsewhere*)
0f16c3b66ab4 much renaming and reorganization
paulson
parents: 5512
diff changeset
   145
      fun bin_of (Const ("Pls", _))     = []
0f16c3b66ab4 much renaming and reorganization
paulson
parents: 5512
diff changeset
   146
        | bin_of (Const ("bin.Pls", _)) = []
0f16c3b66ab4 much renaming and reorganization
paulson
parents: 5512
diff changeset
   147
        | bin_of (Const ("Min", _))     = [~1]
0f16c3b66ab4 much renaming and reorganization
paulson
parents: 5512
diff changeset
   148
        | bin_of (Const ("bin.Min", _)) = [~1]
0f16c3b66ab4 much renaming and reorganization
paulson
parents: 5512
diff changeset
   149
        | bin_of (Const ("op BIT", _) $ bs $ b)     = dest_bit b :: bin_of bs
0f16c3b66ab4 much renaming and reorganization
paulson
parents: 5512
diff changeset
   150
        | bin_of (Const ("bin.op BIT", _) $ bs $ b) = dest_bit b :: bin_of bs
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   151
        | bin_of _ = raise Match;
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_of [] = 0
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   154
        | int_of (b :: bs) = b + 2 * int_of bs;
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   155
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   156
      val rev_digs = bin_of tm;
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   157
      val (sign, zs) =
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   158
        (case rev rev_digs of
5512
4327eec06849 much renaming and tidying
paulson
parents: 5510
diff changeset
   159
          ~1 :: bs => ("-", prefix_len (equal 1) bs)
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   160
        | bs => ("", prefix_len (equal 0) bs));
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   161
      val num = string_of_int (abs (int_of rev_digs));
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   162
    in
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   163
      "#" ^ sign ^ implode (replicate zs "0") ^ num
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   164
    end;
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   165
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   166
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   167
  (* translation of integer constant tokens to and from binary *)
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   168
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   169
  fun int_tr (*"_Int"*) [t as Free (str, _)] =
5491
22f8331cdf47 revised treatment of integers
paulson
parents: 5184
diff changeset
   170
        (const "integ_of" $
3795
e687069e7257 eliminated raise_term;
wenzelm
parents: 2988
diff changeset
   171
          (mk_bin str handle ERROR => raise TERM ("int_tr", [t])))
e687069e7257 eliminated raise_term;
wenzelm
parents: 2988
diff changeset
   172
    | int_tr (*"_Int"*) ts = raise TERM ("int_tr", ts);
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   173
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   174
  fun int_tr' (*"integ_of"*) [t] = const "_Int" $ free (dest_bin t)
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   175
    | int_tr' (*"integ_of"*) _ = raise Match;
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   176
in
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   177
  val parse_translation = [("_Int", int_tr)];
5491
22f8331cdf47 revised treatment of integers
paulson
parents: 5184
diff changeset
   178
  val print_translation = [("integ_of", int_tr')]; 
1632
39e146ac224c Binary integers and their numeric syntax
paulson
parents:
diff changeset
   179
end;