author | wenzelm |
Tue, 28 Jun 2022 15:17:47 +0200 | |
changeset 75629 | 11e233ba53c8 |
parent 69593 | 3dda49e08b9d |
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:
32960
diff
changeset
|
9 |
val make_binary: int -> int list |
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
wenzelm
parents:
32960
diff
changeset
|
10 |
val dest_binary: int list -> int |
9570 | 11 |
end; |
12 |
||
35123 | 13 |
structure Numeral_Syntax: NUMERAL_SYNTAX = |
9570 | 14 |
struct |
15 |
||
35112
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
wenzelm
parents:
32960
diff
changeset
|
16 |
(* bits *) |
9570 | 17 |
|
69593 | 18 |
fun mk_bit 0 = Syntax.const \<^const_syntax>\<open>zero\<close> |
19 |
| mk_bit 1 = Syntax.const \<^const_syntax>\<open>succ\<close> $ Syntax.const \<^const_syntax>\<open>zero\<close> |
|
40314
b5ec88d9ac03
replaced ancient sys_error by raise Fail, assuming that the latter is not handled specifically by the environment;
wenzelm
parents:
35123
diff
changeset
|
20 |
| mk_bit _ = raise Fail "mk_bit"; |
9570 | 21 |
|
69593 | 22 |
fun dest_bit (Const (\<^const_syntax>\<open>zero\<close>, _)) = 0 |
23 |
| dest_bit (Const (\<^const_syntax>\<open>one\<close>, _)) = 1 |
|
24 |
| dest_bit (Const (\<^const_syntax>\<open>succ\<close>, _) $ Const (\<^const_syntax>\<open>zero\<close>, _)) = 1 |
|
9570 | 25 |
| dest_bit _ = raise Match; |
26 |
||
27 |
||
35112
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
wenzelm
parents:
32960
diff
changeset
|
28 |
(* bit strings *) |
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
wenzelm
parents:
32960
diff
changeset
|
29 |
|
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
wenzelm
parents:
32960
diff
changeset
|
30 |
fun make_binary 0 = [] |
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
wenzelm
parents:
32960
diff
changeset
|
31 |
| make_binary ~1 = [~1] |
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
wenzelm
parents:
32960
diff
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:
32960
diff
changeset
|
34 |
fun dest_binary [] = 0 |
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
wenzelm
parents:
32960
diff
changeset
|
35 |
| dest_binary (b :: bs) = b + 2 * dest_binary bs; |
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
wenzelm
parents:
32960
diff
changeset
|
36 |
|
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
wenzelm
parents:
32960
diff
changeset
|
37 |
|
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
wenzelm
parents:
32960
diff
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:
23146
diff
changeset
|
43 |
fun mk_bin i = |
35112
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
wenzelm
parents:
32960
diff
changeset
|
44 |
let |
69593 | 45 |
fun term_of [] = Syntax.const \<^const_syntax>\<open>Pls\<close> |
46 |
| term_of [~1] = Syntax.const \<^const_syntax>\<open>Min\<close> |
|
47 |
| term_of (b :: bs) = Syntax.const \<^const_syntax>\<open>Bit\<close> $ term_of bs $ mk_bit b; |
|
35112
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
wenzelm
parents:
32960
diff
changeset
|
48 |
in term_of (make_binary i) end; |
9570 | 49 |
|
69593 | 50 |
fun bin_of (Const (\<^const_syntax>\<open>Pls\<close>, _)) = [] |
51 |
| bin_of (Const (\<^const_syntax>\<open>Min\<close>, _)) = [~1] |
|
52 |
| bin_of (Const (\<^const_syntax>\<open>Bit\<close>, _) $ 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:
32960
diff
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:
10917
diff
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:
10917
diff
changeset
|
57 |
them altogether.*) |
9570 | 58 |
fun show_int t = |
59 |
let |
|
60 |
val rev_digs = bin_of t; |
|
58421 | 61 |
val (c, zs) = |
35112
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
wenzelm
parents:
32960
diff
changeset
|
62 |
(case rev rev_digs of |
69593 | 63 |
~1 :: bs => (\<^syntax_const>\<open>_Neg_Int\<close>, prefix_len (equal 1) bs) |
64 |
| bs => (\<^syntax_const>\<open>_Int\<close>, prefix_len (equal 0) bs)); |
|
35112
ff6f60e6ab85
numeral syntax: clarify parse trees vs. actual terms;
wenzelm
parents:
32960
diff
changeset
|
65 |
val num = string_of_int (abs (dest_binary rev_digs)); |
58421 | 66 |
in (c, implode (replicate zs "0") ^ num) end; |
9570 | 67 |
|
68 |
||
69 |
(* translation of integer constant tokens to and from binary *) |
|
70 |
||
58421 | 71 |
fun int_tr [Free (s, _)] = |
69593 | 72 |
Syntax.const \<^const_syntax>\<open>integ_of\<close> $ mk_bin (#value (Lexicon.read_num s)) |
42246 | 73 |
| int_tr ts = raise TERM ("int_tr", ts); |
9570 | 74 |
|
58421 | 75 |
fun neg_int_tr [Free (s, _)] = |
69593 | 76 |
Syntax.const \<^const_syntax>\<open>integ_of\<close> $ mk_bin (~ (#value (Lexicon.read_num s))) |
58421 | 77 |
| neg_int_tr ts = raise TERM ("neg_int_tr", ts); |
9570 | 78 |
|
58421 | 79 |
fun integ_of_tr' [t] = |
80 |
let val (c, s) = show_int t |
|
81 |
in Syntax.const c $ Syntax.free s end |
|
82 |
| integ_of_tr' _ = raise Match; |
|
83 |
||
84 |
val _ = Theory.setup |
|
85 |
(Sign.parse_translation |
|
69593 | 86 |
[(\<^syntax_const>\<open>_Int\<close>, K int_tr), |
87 |
(\<^syntax_const>\<open>_Neg_Int\<close>, K neg_int_tr)] #> |
|
58421 | 88 |
Sign.print_translation |
69593 | 89 |
[(\<^const_syntax>\<open>integ_of\<close>, K integ_of_tr')]); |
9570 | 90 |
|
91 |
end; |