2 Author: David von Oheimb |
2 Author: David von Oheimb |
3 |
3 |
4 Syntax generator for domain command. |
4 Syntax generator for domain command. |
5 *) |
5 *) |
6 |
6 |
7 structure Domain_Syntax = struct |
7 signature DOMAIN_SYNTAX = |
|
8 sig |
|
9 val add_syntax: string -> ((string * typ list) * |
|
10 (binding * (bool * binding option * typ) list * mixfix) list) list |
|
11 -> theory -> theory |
|
12 end; |
|
13 |
|
14 |
|
15 structure Domain_Syntax : DOMAIN_SYNTAX = |
|
16 struct |
8 |
17 |
9 local |
18 local |
10 |
19 |
11 open Domain_Library; |
20 open Domain_Library; |
12 infixr 5 -->; infixr 6 ->>; |
21 infixr 5 -->; infixr 6 ->>; |
13 fun calc_syntax dtypeprod ((dname, typevars), |
22 fun calc_syntax dtypeprod ((dname, typevars), |
14 (cons': (string * mixfix * (bool * string option * typ) list) list)) = |
23 (cons': (binding * (bool * binding option * typ) list * mixfix) list)) : ((binding * typ * mixfix) list * ast Syntax.trrule list) = |
15 let |
24 let |
16 (* ----- constants concerning the isomorphism ------------------------------- *) |
25 (* ----- constants concerning the isomorphism ------------------------------- *) |
17 |
26 |
18 local |
27 local |
19 fun opt_lazy (lazy,_,t) = if lazy then mk_uT t else t |
28 fun opt_lazy (lazy,_,t) = if lazy then mk_uT t else t |
20 fun prod (_,_,args) = if args = [] then oneT |
29 fun prod (_,args,_) = case args of [] => oneT |
21 else foldr1 mk_sprodT (map opt_lazy args); |
30 | _ => foldr1 mk_sprodT (map opt_lazy args); |
22 fun freetvar s = let val tvar = mk_TFree s in |
31 fun freetvar s = let val tvar = mk_TFree s in |
23 if tvar mem typevars then freetvar ("t"^s) else tvar end; |
32 if tvar mem typevars then freetvar ("t"^s) else tvar end; |
24 fun when_type (_ ,_,args) = List.foldr (op ->>) (freetvar "t") (map third args); |
33 fun when_type (_,args,_) = List.foldr (op ->>) (freetvar "t") (map third args); |
25 in |
34 in |
26 val dtype = Type(dname,typevars); |
35 val dtype = Type(dname,typevars); |
27 val dtype2 = foldr1 mk_ssumT (map prod cons'); |
36 val dtype2 = foldr1 mk_ssumT (map prod cons'); |
28 val dnam = Long_Name.base_name dname; |
37 val dnam = Long_Name.base_name dname; |
29 val const_rep = (dnam^"_rep" , dtype ->> dtype2, NoSyn); |
38 fun dbind s = Binding.name (dnam ^ s); |
30 val const_abs = (dnam^"_abs" , dtype2 ->> dtype , NoSyn); |
39 val const_rep = (dbind "_rep" , dtype ->> dtype2, NoSyn); |
31 val const_when = (dnam^"_when", List.foldr (op ->>) (dtype ->> freetvar "t") (map when_type cons'), NoSyn); |
40 val const_abs = (dbind "_abs" , dtype2 ->> dtype , NoSyn); |
32 val const_copy = (dnam^"_copy", dtypeprod ->> dtype ->> dtype , NoSyn); |
41 val const_when = (dbind "_when", List.foldr (op ->>) (dtype ->> freetvar "t") (map when_type cons'), NoSyn); |
|
42 val const_copy = (dbind "_copy", dtypeprod ->> dtype ->> dtype , NoSyn); |
33 end; |
43 end; |
34 |
44 |
35 (* ----- constants concerning constructors, discriminators, and selectors --- *) |
45 (* ----- constants concerning constructors, discriminators, and selectors --- *) |
36 |
46 |
37 local |
47 local |
38 val escape = let |
48 val escape = let |
39 fun esc (c::cs) = if c mem ["'","_","(",")","/"] then "'"::c::esc cs |
49 fun esc (c::cs) = if c mem ["'","_","(",")","/"] then "'"::c::esc cs |
40 else c::esc cs |
50 else c::esc cs |
41 | esc [] = [] |
51 | esc [] = [] |
42 in implode o esc o Symbol.explode end; |
52 in implode o esc o Symbol.explode end; |
43 fun con (name,s,args) = (name, List.foldr (op ->>) dtype (map third args),s); |
53 fun dis_name_ con = Binding.name ("is_" ^ strip_esc (Binding.name_of con)); |
44 fun dis (con ,s,_ ) = (dis_name_ con, dtype->>trT, |
54 fun mat_name_ con = Binding.name ("match_" ^ strip_esc (Binding.name_of con)); |
45 Mixfix(escape ("is_" ^ con), [], Syntax.max_pri)); |
55 fun pat_name_ con = Binding.name (strip_esc (Binding.name_of con) ^ "_pat"); |
|
56 fun con (name,args,mx) = (name, List.foldr (op ->>) dtype (map third args), mx); |
|
57 fun dis (con,args,mx) = (dis_name_ con, dtype->>trT, |
|
58 Mixfix(escape ("is_" ^ Binding.name_of con), [], Syntax.max_pri)); |
46 (* strictly speaking, these constants have one argument, |
59 (* strictly speaking, these constants have one argument, |
47 but the mixfix (without arguments) is introduced only |
60 but the mixfix (without arguments) is introduced only |
48 to generate parse rules for non-alphanumeric names*) |
61 to generate parse rules for non-alphanumeric names*) |
49 fun freetvar s n = let val tvar = mk_TFree (s ^ string_of_int n) in |
62 fun freetvar s n = let val tvar = mk_TFree (s ^ string_of_int n) in |
50 if tvar mem typevars then freetvar ("t"^s) n else tvar end; |
63 if tvar mem typevars then freetvar ("t"^s) n else tvar end; |
51 fun mk_matT (a,bs,c) = a ->> foldr (op ->>) (mk_maybeT c) bs ->> mk_maybeT c; |
64 fun mk_matT (a,bs,c) = a ->> foldr (op ->>) (mk_maybeT c) bs ->> mk_maybeT c; |
52 fun mat (con,s,args) = (mat_name_ con, |
65 fun mat (con,args,mx) = (mat_name_ con, |
53 mk_matT(dtype, map third args, freetvar "t" 1), |
66 mk_matT(dtype, map third args, freetvar "t" 1), |
54 Mixfix(escape ("match_" ^ con), [], Syntax.max_pri)); |
67 Mixfix(escape ("match_" ^ Binding.name_of con), [], Syntax.max_pri)); |
55 fun sel1 (_,sel,typ) = Option.map (fn s => (s,dtype ->> typ,NoSyn)) sel; |
68 fun sel1 (_,sel,typ) = Option.map (fn s => (s,dtype ->> typ,NoSyn)) sel; |
56 fun sel (_ ,_,args) = List.mapPartial sel1 args; |
69 fun sel (con,args,mx) = List.mapPartial sel1 args; |
57 fun mk_patT (a,b) = a ->> mk_maybeT b; |
70 fun mk_patT (a,b) = a ->> mk_maybeT b; |
58 fun pat_arg_typ n arg = mk_patT (third arg, freetvar "t" n); |
71 fun pat_arg_typ n arg = mk_patT (third arg, freetvar "t" n); |
59 fun pat (con ,s,args) = (pat_name_ con, (mapn pat_arg_typ 1 args) ---> |
72 fun pat (con,args,mx) = (pat_name_ con, (mapn pat_arg_typ 1 args) ---> |
60 mk_patT (dtype, mk_ctupleT (map (freetvar "t") (1 upto length args))), |
73 mk_patT (dtype, mk_ctupleT (map (freetvar "t") (1 upto length args))), |
61 Mixfix(escape (con ^ "_pat"), [], Syntax.max_pri)); |
74 Mixfix(escape (Binding.name_of con ^ "_pat"), [], Syntax.max_pri)); |
62 |
75 |
63 in |
76 in |
64 val consts_con = map con cons'; |
77 val consts_con = map con cons'; |
65 val consts_dis = map dis cons'; |
78 val consts_dis = map dis cons'; |
66 val consts_mat = map mat cons'; |
79 val consts_mat = map mat cons'; |
68 val consts_sel = List.concat(map sel cons'); |
81 val consts_sel = List.concat(map sel cons'); |
69 end; |
82 end; |
70 |
83 |
71 (* ----- constants concerning induction ------------------------------------- *) |
84 (* ----- constants concerning induction ------------------------------------- *) |
72 |
85 |
73 val const_take = (dnam^"_take" , HOLogic.natT-->dtype->>dtype, NoSyn); |
86 val const_take = (dbind "_take" , HOLogic.natT-->dtype->>dtype, NoSyn); |
74 val const_finite = (dnam^"_finite", dtype-->HOLogic.boolT , NoSyn); |
87 val const_finite = (dbind "_finite", dtype-->HOLogic.boolT , NoSyn); |
75 |
88 |
76 (* ----- case translation --------------------------------------------------- *) |
89 (* ----- case translation --------------------------------------------------- *) |
77 |
90 |
78 local open Syntax in |
91 local open Syntax in |
79 local |
92 local |
80 fun c_ast con mx = Constant (Syntax.const_name mx con); |
93 fun c_ast con mx = Constant (Syntax.const_name mx (Binding.name_of con)); |
81 fun expvar n = Variable ("e"^(string_of_int n)); |
94 fun expvar n = Variable ("e"^(string_of_int n)); |
82 fun argvar n m _ = Variable ("a"^(string_of_int n)^"_"^ |
95 fun argvar n m _ = Variable ("a"^(string_of_int n)^"_"^ |
83 (string_of_int m)); |
96 (string_of_int m)); |
84 fun argvars n args = mapn (argvar n) 1 args; |
97 fun argvars n args = mapn (argvar n) 1 args; |
85 fun app s (l,r) = mk_appl (Constant s) [l,r]; |
98 fun app s (l,r) = mk_appl (Constant s) [l,r]; |
86 val cabs = app "_cabs"; |
99 val cabs = app "_cabs"; |
87 val capp = app "Rep_CFun"; |
100 val capp = app "Rep_CFun"; |
88 fun con1 n (con,mx,args) = Library.foldl capp (c_ast con mx, argvars n args); |
101 fun con1 n (con,args,mx) = Library.foldl capp (c_ast con mx, argvars n args); |
89 fun case1 n (con,mx,args) = app "_case1" (con1 n (con,mx,args), expvar n); |
102 fun case1 n (con,args,mx) = app "_case1" (con1 n (con,args,mx), expvar n); |
90 fun arg1 n (con,_,args) = List.foldr cabs (expvar n) (argvars n args); |
103 fun arg1 n (con,args,_) = List.foldr cabs (expvar n) (argvars n args); |
91 fun when1 n m = if n = m then arg1 n else K (Constant "UU"); |
104 fun when1 n m = if n = m then arg1 n else K (Constant "UU"); |
92 |
105 |
93 fun app_var x = mk_appl (Constant "_variable") [x, Variable "rhs"]; |
106 fun app_var x = mk_appl (Constant "_variable") [x, Variable "rhs"]; |
94 fun app_pat x = mk_appl (Constant "_pat") [x]; |
107 fun app_pat x = mk_appl (Constant "_pat") [x]; |
95 fun args_list [] = Constant "_noargs" |
108 fun args_list [] = Constant "_noargs" |
130 |
143 |
131 (* ----- putting all the syntax stuff together ------------------------------ *) |
144 (* ----- putting all the syntax stuff together ------------------------------ *) |
132 |
145 |
133 in (* local *) |
146 in (* local *) |
134 |
147 |
135 fun add_syntax (comp_dnam,eqs': ((string * typ list) * |
148 fun add_syntax |
136 (string * mixfix * (bool * string option * typ) list) list) list) thy'' = |
149 (comp_dnam : string) |
|
150 (eqs' : ((string * typ list) * |
|
151 (binding * (bool * binding option * typ) list * mixfix) list) list) |
|
152 (thy'' : theory) = |
137 let |
153 let |
138 val dtypes = map (Type o fst) eqs'; |
154 val dtypes = map (Type o fst) eqs'; |
139 val boolT = HOLogic.boolT; |
155 val boolT = HOLogic.boolT; |
140 val funprod = foldr1 HOLogic.mk_prodT (map (fn tp => tp ->> tp ) dtypes); |
156 val funprod = foldr1 HOLogic.mk_prodT (map (fn tp => tp ->> tp ) dtypes); |
141 val relprod = foldr1 HOLogic.mk_prodT (map (fn tp => tp --> tp --> boolT) dtypes); |
157 val relprod = foldr1 HOLogic.mk_prodT (map (fn tp => tp --> tp --> boolT) dtypes); |
142 val const_copy = (comp_dnam^"_copy" ,funprod ->> funprod, NoSyn); |
158 val const_copy = (Binding.name (comp_dnam^"_copy"), funprod ->> funprod, NoSyn); |
143 val const_bisim = (comp_dnam^"_bisim" ,relprod --> boolT , NoSyn); |
159 val const_bisim = (Binding.name (comp_dnam^"_bisim"), relprod --> boolT, NoSyn); |
144 val ctt = map (calc_syntax funprod) eqs'; |
160 val ctt : ((binding * typ * mixfix) list * ast Syntax.trrule list) list = map (calc_syntax funprod) eqs'; |
145 in thy'' |> ContConsts.add_consts_i (List.concat (map fst ctt) @ |
161 in thy'' |> ContConsts.add_consts_i (List.concat (map fst ctt) @ |
146 (if length eqs'>1 then [const_copy] else[])@ |
162 (if length eqs'>1 then [const_copy] else[])@ |
147 [const_bisim]) |
163 [const_bisim]) |
148 |> Sign.add_trrules_i (List.concat(map snd ctt)) |
164 |> Sign.add_trrules_i (List.concat(map snd ctt)) |
149 end; (* let *) |
165 end; (* let *) |