wenzelm@23152
|
1 |
(* Title: HOLCF/Tools/cont_consts.ML
|
wenzelm@23152
|
2 |
ID: $Id$
|
wenzelm@23152
|
3 |
Author: Tobias Mayr, David von Oheimb, and Markus Wenzel
|
wenzelm@23152
|
4 |
|
wenzelm@23152
|
5 |
HOLCF version of consts: handle continuous function types in mixfix
|
wenzelm@23152
|
6 |
syntax.
|
wenzelm@23152
|
7 |
*)
|
wenzelm@23152
|
8 |
|
wenzelm@23152
|
9 |
signature CONT_CONSTS =
|
wenzelm@23152
|
10 |
sig
|
wenzelm@23152
|
11 |
val add_consts: (bstring * string * mixfix) list -> theory -> theory
|
wenzelm@23152
|
12 |
val add_consts_i: (bstring * typ * mixfix) list -> theory -> theory
|
wenzelm@23152
|
13 |
end;
|
wenzelm@23152
|
14 |
|
wenzelm@23152
|
15 |
structure ContConsts: CONT_CONSTS =
|
wenzelm@23152
|
16 |
struct
|
wenzelm@23152
|
17 |
|
wenzelm@23152
|
18 |
|
wenzelm@23152
|
19 |
(* misc utils *)
|
wenzelm@23152
|
20 |
|
wenzelm@23152
|
21 |
open HOLCFLogic;
|
wenzelm@23152
|
22 |
|
wenzelm@23152
|
23 |
fun first (x,_,_) = x;
|
wenzelm@23152
|
24 |
fun second (_,x,_) = x;
|
wenzelm@23152
|
25 |
fun third (_,_,x) = x;
|
wenzelm@23152
|
26 |
fun upd_first f (x,y,z) = (f x, y, z);
|
wenzelm@23152
|
27 |
fun upd_second f (x,y,z) = ( x, f y, z);
|
wenzelm@23152
|
28 |
fun upd_third f (x,y,z) = ( x, y, f z);
|
wenzelm@23152
|
29 |
|
wenzelm@23152
|
30 |
fun change_arrow 0 T = T
|
wenzelm@23152
|
31 |
| change_arrow n (Type(_,[S,T])) = Type ("fun",[S,change_arrow (n-1) T])
|
wenzelm@23152
|
32 |
| change_arrow _ _ = sys_error "cont_consts: change_arrow";
|
wenzelm@23152
|
33 |
|
wenzelm@23152
|
34 |
fun trans_rules name2 name1 n mx = let
|
wenzelm@23152
|
35 |
fun argnames _ 0 = []
|
wenzelm@23152
|
36 |
| argnames c n = chr c::argnames (c+1) (n-1);
|
wenzelm@23152
|
37 |
val vnames = argnames (ord "A") n;
|
wenzelm@23152
|
38 |
val extra_parse_rule = Syntax.ParseRule (Constant name2, Constant name1);
|
wenzelm@23152
|
39 |
in [Syntax.ParsePrintRule (Syntax.mk_appl (Constant name2) (map Variable vnames),
|
wenzelm@23152
|
40 |
Library.foldl (fn (t,arg) => (Syntax.mk_appl (Constant "Rep_CFun")
|
wenzelm@23152
|
41 |
[t,Variable arg]))
|
wenzelm@23152
|
42 |
(Constant name1,vnames))]
|
wenzelm@23152
|
43 |
@(case mx of InfixName _ => [extra_parse_rule]
|
wenzelm@23152
|
44 |
| InfixlName _ => [extra_parse_rule]
|
wenzelm@23152
|
45 |
| InfixrName _ => [extra_parse_rule] | _ => []) end;
|
wenzelm@23152
|
46 |
|
wenzelm@23152
|
47 |
|
wenzelm@23152
|
48 |
(* transforming infix/mixfix declarations of constants with type ...->...
|
wenzelm@23152
|
49 |
a declaration of such a constant is transformed to a normal declaration with
|
wenzelm@23152
|
50 |
an internal name, the same type, and nofix. Additionally, a purely syntactic
|
wenzelm@23152
|
51 |
declaration with the original name, type ...=>..., and the original mixfix
|
wenzelm@23152
|
52 |
is generated and connected to the other declaration via some translation.
|
wenzelm@23152
|
53 |
*)
|
wenzelm@23152
|
54 |
fun fix_mixfix (syn , T, mx as Infix p ) =
|
wenzelm@23152
|
55 |
(Syntax.const_name syn mx, T, InfixName (syn, p))
|
wenzelm@23152
|
56 |
| fix_mixfix (syn , T, mx as Infixl p ) =
|
wenzelm@23152
|
57 |
(Syntax.const_name syn mx, T, InfixlName (syn, p))
|
wenzelm@23152
|
58 |
| fix_mixfix (syn , T, mx as Infixr p ) =
|
wenzelm@23152
|
59 |
(Syntax.const_name syn mx, T, InfixrName (syn, p))
|
wenzelm@23152
|
60 |
| fix_mixfix decl = decl;
|
wenzelm@23152
|
61 |
fun transform decl = let
|
wenzelm@23152
|
62 |
val (c, T, mx) = fix_mixfix decl;
|
wenzelm@23152
|
63 |
val c2 = "_cont_" ^ c;
|
wenzelm@23152
|
64 |
val n = Syntax.mixfix_args mx
|
wenzelm@23152
|
65 |
in ((c , T,NoSyn),
|
wenzelm@23152
|
66 |
(c2,change_arrow n T,mx ),
|
wenzelm@23152
|
67 |
trans_rules c2 c n mx) end;
|
wenzelm@23152
|
68 |
|
wenzelm@23152
|
69 |
fun cfun_arity (Type(n,[_,T])) = if n = cfun_arrow then 1+cfun_arity T else 0
|
wenzelm@23152
|
70 |
| cfun_arity _ = 0;
|
wenzelm@23152
|
71 |
|
wenzelm@23152
|
72 |
fun is_contconst (_,_,NoSyn ) = false
|
wenzelm@23152
|
73 |
| is_contconst (_,_,Binder _) = false
|
wenzelm@23152
|
74 |
| is_contconst (c,T,mx ) = cfun_arity T >= Syntax.mixfix_args mx
|
wenzelm@23152
|
75 |
handle ERROR msg => cat_error msg ("in mixfix annotation for " ^
|
wenzelm@23152
|
76 |
quote (Syntax.const_name c mx));
|
wenzelm@23152
|
77 |
|
wenzelm@23152
|
78 |
|
wenzelm@23152
|
79 |
(* add_consts(_i) *)
|
wenzelm@23152
|
80 |
|
wenzelm@23152
|
81 |
fun gen_add_consts prep_typ raw_decls thy =
|
wenzelm@23152
|
82 |
let
|
wenzelm@23152
|
83 |
val decls = map (upd_second (prep_typ thy)) raw_decls;
|
wenzelm@23152
|
84 |
val (contconst_decls, normal_decls) = List.partition is_contconst decls;
|
wenzelm@23152
|
85 |
val transformed_decls = map transform contconst_decls;
|
wenzelm@23152
|
86 |
in
|
wenzelm@23152
|
87 |
thy
|
wenzelm@23152
|
88 |
|> Sign.add_consts_i normal_decls
|
wenzelm@23152
|
89 |
|> Sign.add_consts_i (map first transformed_decls)
|
wenzelm@23152
|
90 |
|> Sign.add_syntax_i (map second transformed_decls)
|
wenzelm@23152
|
91 |
|> Sign.add_trrules_i (List.concat (map third transformed_decls))
|
wenzelm@23152
|
92 |
end;
|
wenzelm@23152
|
93 |
|
wenzelm@24707
|
94 |
val add_consts = gen_add_consts Syntax.read_typ_global;
|
wenzelm@23152
|
95 |
val add_consts_i = gen_add_consts Sign.certify_typ;
|
wenzelm@23152
|
96 |
|
wenzelm@23152
|
97 |
|
wenzelm@23152
|
98 |
(* outer syntax *)
|
wenzelm@23152
|
99 |
|
wenzelm@23152
|
100 |
local structure P = OuterParse and K = OuterKeyword in
|
wenzelm@23152
|
101 |
|
wenzelm@24867
|
102 |
val _ =
|
wenzelm@23152
|
103 |
OuterSyntax.command "consts" "declare constants (HOLCF)" K.thy_decl
|
wenzelm@23152
|
104 |
(Scan.repeat1 P.const >> (Toplevel.theory o add_consts));
|
wenzelm@23152
|
105 |
|
wenzelm@23152
|
106 |
end;
|
wenzelm@23152
|
107 |
|
wenzelm@23152
|
108 |
end;
|