12 |
12 |
13 structure NumeralSyntax: NUMERAL_SYNTAX = |
13 structure NumeralSyntax: NUMERAL_SYNTAX = |
14 struct |
14 struct |
15 |
15 |
16 |
16 |
17 (* bit strings *) (*we try to handle superfluous leading digits nicely*) |
17 (* parse translation *) |
18 |
18 |
19 fun prefix_len _ [] = 0 |
19 local |
20 | prefix_len pred (x :: xs) = |
20 |
21 if pred x then 1 + prefix_len pred xs else 0; |
21 fun mk_bin num = |
|
22 let |
|
23 val {leading_zeros = z, value, ...} = Syntax.read_xnum num; |
|
24 fun bit b bs = Syntax.const "\\<^const>Numeral.Bit" $ bs $ HOLogic.mk_bit b; |
|
25 fun mk 0 = (* FIXME funpow z (bit 0) *) (Syntax.const "\\<^const>Numeral.Pls") |
|
26 | mk ~1 = (* FIXME funpow z (bit 1) *) (Syntax.const "\\<^const>Numeral.Min") |
|
27 | mk i = let val (q, r) = IntInf.divMod (i, 2) in bit r (mk q) end; |
|
28 in mk value end; |
|
29 |
|
30 in |
|
31 |
|
32 fun numeral_tr (*"_Numeral"*) [t as Const (num, _)] = |
|
33 Syntax.const "Numeral.number_of" $ mk_bin num |
|
34 | numeral_tr (*"_Numeral"*) ts = raise TERM ("numeral_tr", ts); |
|
35 |
|
36 end; |
|
37 |
|
38 |
|
39 (* print translation *) |
|
40 |
|
41 local |
|
42 |
|
43 fun dest_bit (Const ("Numeral.bit.B0", _)) = 0 |
|
44 | dest_bit (Const ("Numeral.bit.B1", _)) = 1 |
|
45 | dest_bit (Const ("bit.B0", _)) = 0 |
|
46 | dest_bit (Const ("bit.B1", _)) = 1 |
|
47 | dest_bit _ = raise Match; |
|
48 |
|
49 fun dest_bin (Const ("\\<^const>Numeral.Pls", _)) = [] |
|
50 | dest_bin (Const ("\\<^const>Numeral.Min", _)) = [~1] |
|
51 | dest_bin (Const ("\\<^const>Numeral.Bit", _) $ bs $ b) = dest_bit b :: dest_bin bs |
|
52 | dest_bin _ = raise Match; |
|
53 |
|
54 fun leading _ [] = 0 |
|
55 | leading (i: int) (j :: js) = if i = j then 1 + leading i js else 0; |
|
56 |
|
57 fun int_of [] = 0 |
|
58 | int_of (b :: bs) = IntInf.fromInt b + 2 * int_of bs; |
22 |
59 |
23 fun dest_bin_str tm = |
60 fun dest_bin_str tm = |
24 let |
61 let |
25 val rev_digs = HOLogic.bin_of tm handle TERM _ => raise Match |
62 val rev_digs = dest_bin tm; |
26 val (sign, zs) = |
63 val (sign, z) = |
27 (case rev rev_digs of |
64 (case rev rev_digs of |
28 ~1 :: bs => ("-", prefix_len (equal 1) bs) |
65 ~1 :: bs => ("-", leading 1 bs) |
29 | bs => ("", prefix_len (equal 0) bs)); |
66 | bs => ("", leading 0 bs)); |
30 val i = HOLogic.int_of rev_digs; |
67 val i = int_of rev_digs; |
31 val num = IntInf.toString (IntInf.abs i); |
68 val num = IntInf.toString (IntInf.abs i); |
32 in |
69 in |
33 if i = IntInf.fromInt 0 orelse i = IntInf.fromInt 1 then raise Match |
70 if (i = 0 orelse i = 1) andalso z = 0 then raise Match |
34 else sign ^ implode (replicate zs "0") ^ num |
71 else sign ^ implode (replicate z "0") ^ num |
35 end; |
72 end; |
36 |
73 |
37 |
74 in |
38 (* translation of integer numeral tokens to and from bitstrings *) |
|
39 |
|
40 fun numeral_tr (*"_Numeral"*) [t as Const (str, _)] = |
|
41 (Syntax.const "Numeral.number_of" $ (HOLogic.mk_binum (Syntax.read_xnum str))) |
|
42 | numeral_tr (*"_Numeral"*) ts = raise TERM ("numeral_tr", ts); |
|
43 |
75 |
44 fun numeral_tr' show_sorts (*"number_of"*) (Type ("fun", [_, T])) (t :: ts) = |
76 fun numeral_tr' show_sorts (*"number_of"*) (Type ("fun", [_, T])) (t :: ts) = |
45 let val t' = Syntax.const "_Numeral" $ Syntax.free (dest_bin_str t) in |
77 let val t' = Syntax.const "_Numeral" $ Syntax.free (dest_bin_str t) in |
46 if not (! show_types) andalso can Term.dest_Type T then t' |
78 if not (! show_types) andalso can Term.dest_Type T then t' |
47 else Syntax.const Syntax.constrainC $ t' $ Syntax.term_of_typ show_sorts T |
79 else Syntax.const Syntax.constrainC $ t' $ Syntax.term_of_typ show_sorts T |