--- a/src/HOL/Numeral.thy Sun Jul 16 20:50:48 2000 +0200
+++ b/src/HOL/Numeral.thy Sun Jul 16 20:51:19 2000 +0200
@@ -2,16 +2,20 @@
ID: $Id$
Author: Larry Paulson and Markus Wenzel
-Generic numerals represented as twos-complement bitstrings.
+Generic numerals represented as twos-complement bit strings, and
+selector function as ones-complement unit strings.
*)
theory Numeral = Datatype
files "Tools/numeral_syntax.ML":
+
+(* numerals *)
+
datatype
bin = Pls
| Min
- | Bit bin bool (infixl "BIT" 90)
+ | Bit bin bool (infixl "BIT" 90)
axclass
number < "term" (*for numeric types: nat, int, real, ...*)
@@ -20,9 +24,77 @@
number_of :: "bin => 'a::number"
syntax
- "_Numeral" :: "xnum => 'a" ("_")
+ "_Numeral" :: "xnum => 'a" ("_")
setup NumeralSyntax.setup
+(* selector functions *)
+
+(*Note that type constraints on selector functons are not handled
+ properly here*)
+
+syntax
+ "_selector" :: 'a
+ "_op_selector" :: "xnum => 'a" ("op _" [0] 1000)
+
+translations
+ "(_Numeral i) x" => "_selector i x"
+
+parse_translation {*
+ let
+ val fstC = Syntax.const "fst";
+ val sndC = Syntax.const "snd";
+ fun ap_snd t = sndC $ t;
+ fun comp_snd t = Syntax.const "op o" $ t $ sndC;
+
+ fun selector_tr [Free (x, _), t] =
+ let val i = Syntax.read_xnum x in
+ if i = 0 orelse i = ~1 then t
+ else if i > 0 then fstC $ funpow (i - 1) ap_snd t
+ else funpow (~i - 1) ap_snd t
+ end
+ | selector_tr ts = raise TERM ("selector_tr", ts);
+
+ fun op_selector_tr [Free (x, _)] =
+ let val i = Syntax.read_xnum x in
+ if i = 0 orelse i = ~1 then Abs ("x", dummyT, Bound 0)
+ else if i > 0 then funpow (i - 1) comp_snd fstC
+ else funpow (~i - 2) comp_snd sndC
+ end
+ | op_selector_tr ts = raise TERM ("op_selector_tr", ts);
+ in [("_selector", selector_tr), ("_op_selector", op_selector_tr)] end
+*}
+
+print_translation {*
+ let
+ fun mk_xnum i =
+ Syntax.free ("#" ^ (if i < 0 then "-" else "") ^ (string_of_int (abs i)));
+
+
+ fun snds_tr' (i, Const ("snd", _) $ t) = snds_tr' (i + 1, t)
+ | snds_tr' x = x;
+
+ fun fst_tr' t = let val (i, t') = snds_tr' (0, t) in (i + 1, t') end;
+ fun snd_tr' t = let val (i, t') = snds_tr' (0, t) in (~ (i + 2), t') end;
+
+ fun selector_tr' f (t :: ts) =
+ let val (i, u) = f t in
+ if ~2 <= i andalso i <= 1 then raise Match
+ else Term.list_comb (mk_xnum i $ u, ts) end
+ | selector_tr' _ [] = raise Match;
+
+
+ fun o_snd_tr' i (Const ("op o", _) $ t $ Const ("snd", _)) = o_snd_tr' (i + 1) t
+ | o_snd_tr' i (Const ("fst", _)) = i + 1
+ | o_snd_tr' i (Const ("snd", _)) = ~ (i + 2)
+ | o_snd_tr' _ _ = raise Match;
+
+ fun comp_tr' (t :: u :: ts) =
+ Term.list_comb (Syntax.const "_op_selector" $
+ mk_xnum (o_snd_tr' 0 (Syntax.const "op o" $ t $ u)), ts)
+ | comp_tr' _ = raise Match;
+ in [("fst", selector_tr' fst_tr'), ("snd", selector_tr' snd_tr'), ("op o", comp_tr')] end
+*}
+
end