| author | wenzelm | 
| Wed, 14 Dec 2011 12:02:02 +0100 | |
| changeset 45860 | 93eda35a8377 | 
| parent 42290 | b1f544c84040 | 
| child 52143 | 36ffe23b25f8 | 
| permissions | -rw-r--r-- | 
| 9570 | 1 | (* Title: ZF/Tools/numeral_syntax.ML | 
| 2 | Author: Lawrence C Paulson, Cambridge University Computer Laboratory | |
| 3 | ||
| 42246 | 4 | Concrete syntax for generic numerals. | 
| 9570 | 5 | *) | 
| 6 | ||
| 7 | signature NUMERAL_SYNTAX = | |
| 8 | sig | |
| 35112 
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
 wenzelm parents: 
32960diff
changeset | 9 | val make_binary: int -> int list | 
| 
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
 wenzelm parents: 
32960diff
changeset | 10 | val dest_binary: int list -> int | 
| 
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
 wenzelm parents: 
32960diff
changeset | 11 | val setup: theory -> theory | 
| 9570 | 12 | end; | 
| 13 | ||
| 35123 | 14 | structure Numeral_Syntax: NUMERAL_SYNTAX = | 
| 9570 | 15 | struct | 
| 16 | ||
| 35112 
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
 wenzelm parents: 
32960diff
changeset | 17 | (* bits *) | 
| 9570 | 18 | |
| 41310 | 19 | fun mk_bit 0 = Syntax.const @{const_syntax zero}
 | 
| 20 |   | mk_bit 1 = Syntax.const @{const_syntax succ} $ Syntax.const @{const_syntax zero}
 | |
| 40314 
b5ec88d9ac03
replaced ancient sys_error by raise Fail, assuming that the latter is not handled specifically by the environment;
 wenzelm parents: 
35123diff
changeset | 21 | | mk_bit _ = raise Fail "mk_bit"; | 
| 9570 | 22 | |
| 41310 | 23 | fun dest_bit (Const (@{const_syntax zero}, _)) = 0
 | 
| 24 |   | dest_bit (Const (@{const_syntax succ}, _) $ Const (@{const_syntax zero}, _)) = 1
 | |
| 9570 | 25 | | dest_bit _ = raise Match; | 
| 26 | ||
| 27 | ||
| 35112 
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
 wenzelm parents: 
32960diff
changeset | 28 | (* bit strings *) | 
| 
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
 wenzelm parents: 
32960diff
changeset | 29 | |
| 
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
 wenzelm parents: 
32960diff
changeset | 30 | fun make_binary 0 = [] | 
| 
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
 wenzelm parents: 
32960diff
changeset | 31 | | make_binary ~1 = [~1] | 
| 
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
 wenzelm parents: 
32960diff
changeset | 32 | | make_binary n = (n mod 2) :: make_binary (n div 2); | 
| 9570 | 33 | |
| 35112 
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
 wenzelm parents: 
32960diff
changeset | 34 | fun dest_binary [] = 0 | 
| 
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
 wenzelm parents: 
32960diff
changeset | 35 | | dest_binary (b :: bs) = b + 2 * dest_binary bs; | 
| 
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
 wenzelm parents: 
32960diff
changeset | 36 | |
| 
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
 wenzelm parents: 
32960diff
changeset | 37 | |
| 
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
 wenzelm parents: 
32960diff
changeset | 38 | (*try to handle superfluous leading digits nicely*) | 
| 9570 | 39 | fun prefix_len _ [] = 0 | 
| 40 | | prefix_len pred (x :: xs) = | |
| 41 | if pred x then 1 + prefix_len pred xs else 0; | |
| 42 | ||
| 24630 
351a308ab58d
simplified type int (eliminated IntInf.int, integer);
 wenzelm parents: 
23146diff
changeset | 43 | fun mk_bin i = | 
| 35112 
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
 wenzelm parents: 
32960diff
changeset | 44 | let | 
| 
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
 wenzelm parents: 
32960diff
changeset | 45 |     fun term_of [] = Syntax.const @{const_syntax Pls}
 | 
| 
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
 wenzelm parents: 
32960diff
changeset | 46 |       | term_of [~1] = Syntax.const @{const_syntax Min}
 | 
| 
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
 wenzelm parents: 
32960diff
changeset | 47 |       | term_of (b :: bs) = Syntax.const @{const_syntax Bit} $ term_of bs $ mk_bit b;
 | 
| 
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
 wenzelm parents: 
32960diff
changeset | 48 | in term_of (make_binary i) end; | 
| 9570 | 49 | |
| 35112 
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
 wenzelm parents: 
32960diff
changeset | 50 | fun bin_of (Const (@{const_syntax Pls}, _)) = []
 | 
| 
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
 wenzelm parents: 
32960diff
changeset | 51 |   | bin_of (Const (@{const_syntax Min}, _)) = [~1]
 | 
| 
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
 wenzelm parents: 
32960diff
changeset | 52 |   | bin_of (Const (@{const_syntax Bit}, _) $ bs $ b) = dest_bit b :: bin_of bs
 | 
| 9570 | 53 | | bin_of _ = raise Match; | 
| 54 | ||
| 35112 
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
 wenzelm parents: 
32960diff
changeset | 55 | (*Leading 0s and (for negative numbers) -1s cause complications, though they | 
| 15965 
f422f8283491
Use of IntInf.int instead of int in most numeric simprocs; avoids
 paulson parents: 
10917diff
changeset | 56 | should never arise in normal use. The formalization used in HOL prevents | 
| 
f422f8283491
Use of IntInf.int instead of int in most numeric simprocs; avoids
 paulson parents: 
10917diff
changeset | 57 | them altogether.*) | 
| 9570 | 58 | fun show_int t = | 
| 59 | let | |
| 60 | val rev_digs = bin_of t; | |
| 61 | val (sign, zs) = | |
| 35112 
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
 wenzelm parents: 
32960diff
changeset | 62 | (case rev rev_digs of | 
| 
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
 wenzelm parents: 
32960diff
changeset | 63 |          ~1 :: bs => ("-", prefix_len (equal 1) bs)
 | 
| 
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
 wenzelm parents: 
32960diff
changeset | 64 |       | bs => ("",  prefix_len (equal 0) bs));
 | 
| 
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
 wenzelm parents: 
32960diff
changeset | 65 | val num = string_of_int (abs (dest_binary rev_digs)); | 
| 9570 | 66 | in | 
| 67 | "#" ^ sign ^ implode (replicate zs "0") ^ num | |
| 68 | end; | |
| 69 | ||
| 70 | ||
| 71 | (* translation of integer constant tokens to and from binary *) | |
| 72 | ||
| 42246 | 73 | fun int_tr [t as Free (str, _)] = | 
| 42290 
b1f544c84040
discontinued special treatment of structure Lexicon;
 wenzelm parents: 
42246diff
changeset | 74 |       Syntax.const @{const_syntax integ_of} $ mk_bin (#value (Lexicon.read_xnum str))
 | 
| 42246 | 75 |   | int_tr ts = raise TERM ("int_tr", ts);
 | 
| 9570 | 76 | |
| 42246 | 77 | fun int_tr' [t] = Syntax.const @{syntax_const "_Int"} $ Syntax.free (show_int t)
 | 
| 78 | | int_tr' _ = raise Match; | |
| 9570 | 79 | |
| 80 | ||
| 81 | val setup = | |
| 42246 | 82 |  Sign.add_trfuns ([], [(@{syntax_const "_Int"}, int_tr)], [(@{const_syntax integ_of}, int_tr')], []);
 | 
| 9570 | 83 | |
| 84 | end; |