118 fun get_bn_fun_strs bn_funs = |
118 fun get_bn_fun_strs bn_funs = |
119 map (fn (bn_fun, _, _) => Binding.name_of bn_fun) bn_funs |
119 map (fn (bn_fun, _, _) => Binding.name_of bn_fun) bn_funs |
120 *} |
120 *} |
121 |
121 |
122 ML {* |
122 ML {* |
123 fun nominal_dt_decl dt_names dts bn_funs bn_eqs lthy = |
123 fun raw_dts_decl dt_names dts lthy = |
124 let |
124 let |
125 val conf = Datatype.default_config |
125 val conf = Datatype.default_config |
126 |
126 |
127 val dt_names' = map add_raw dt_names |
127 val dt_names' = map add_raw dt_names |
128 val dts' = raw_dts dt_names dts |
128 val dts' = raw_dts dt_names dts |
129 val constr_strs = get_constr_strs dts |
129 in |
|
130 Local_Theory.theory_result (Datatype.add_datatype conf dt_names' dts') lthy |
|
131 end |
|
132 *} |
|
133 |
|
134 ML {* |
|
135 fun raw_bn_fun_decl dt_names cnstr_names bn_funs bn_eqs lthy = |
|
136 let |
130 val bn_fun_strs = get_bn_fun_strs bn_funs |
137 val bn_fun_strs = get_bn_fun_strs bn_funs |
131 |
138 |
132 val bn_funs' = map (fn (bn, opt_ty, mx) => |
139 val bn_funs' = map (fn (bn, opt_ty, mx) => |
133 (raw_bind bn, Option.map (raw_typ dt_names) opt_ty, mx)) bn_funs |
140 (raw_bind bn, Option.map (raw_typ dt_names) opt_ty, mx)) bn_funs |
134 val bn_eqs' = map (fn trm => |
141 val bn_eqs' = map (fn trm => |
135 (Attrib.empty_binding, raw_term (constr_strs @ bn_fun_strs) dt_names trm)) bn_eqs |
142 (Attrib.empty_binding, raw_term (cnstr_names @ bn_fun_strs) dt_names trm)) bn_eqs |
|
143 in |
|
144 (*Primrec.add_primrec bn_funs' bn_eqs' lthy*) |
|
145 ((), lthy) |
|
146 end |
|
147 *} |
|
148 |
|
149 ML {* |
|
150 fun nominal_datatype2 dts bn_funs bn_eqs lthy = |
|
151 let |
|
152 val dts_names = map (fn (_, s, _, _) => Binding.name_of s) dts |
|
153 val ctrs_names = get_constr_strs dts |
136 in |
154 in |
137 lthy |
155 lthy |
138 |> (Local_Theory.theory_result (Datatype.add_datatype conf dt_names' dts')) |
156 |> raw_dts_decl dts_names dts |
139 ||>> Primrec.add_primrec bn_funs' bn_eqs' |
157 ||>> raw_bn_fun_decl dts_names ctrs_names bn_funs bn_eqs |
140 end |
158 end |
141 *} |
159 *} |
142 |
160 |
143 local_setup {* |
161 ML {* |
144 let |
162 fun nominal_datatype2_cmd (dt_strs, (bn_fun_strs, bn_eq_strs)) lthy = |
145 val T0 = Type ("Test.foo", []) |
163 let |
146 val T1 = T0 --> @{typ "nat"} |
164 val lthy_tmp = lthy |
147 in |
165 |> (Local_Theory.theory |
148 nominal_dt_decl |
166 (Sign.add_types (map (fn ((tvs, tname, mx), _) => |
149 ["foo"] |
167 (tname, length tvs, mx)) dt_strs))) |
150 [([], @{binding "foo"}, NoSyn, |
168 |
151 [(@{binding "myzero"}, [], NoSyn),(@{binding "mysuc"}, [Type ("Test.foo", [])], NoSyn)])] |
169 fun prep_cnstr lthy (((cname, atys), mx), binders) = |
152 [(@{binding "Bar"}, SOME T1, NoSyn)] |
170 (cname, map (Syntax.read_typ lthy o snd) atys, mx) |
153 [HOLogic.mk_Trueprop (HOLogic.mk_eq |
|
154 (Free ("Bar", T1) $ Const ("Test.foo_raw.myzero", T0), @{term "0::nat"})), |
|
155 HOLogic.mk_Trueprop (HOLogic.mk_eq |
|
156 (Free ("Bar", T1) $ (Const ("Test.foo_raw.mysuc", T0 --> T0) $ Free ("n", T0)), @{term "0::nat"}))] |
|
157 #> snd |
|
158 end |
|
159 *} |
|
160 |
|
161 typ foo_raw |
|
162 thm foo_raw.induct |
|
163 term myzero_raw |
|
164 term mysuc_raw |
|
165 thm Bar_raw.simps |
|
166 |
|
167 (* printing stuff *) |
|
168 |
|
169 ML {* |
|
170 fun print_str_option NONE = "NONE" |
|
171 | print_str_option (SOME s) = (s:bstring) |
|
172 |
|
173 fun print_anno_typ lthy (NONE, ty) = Syntax.string_of_typ lthy ty |
|
174 | print_anno_typ lthy (SOME x, ty) = x ^ ":" ^ Syntax.string_of_typ lthy ty |
|
175 |
|
176 fun print_bind (s1, s2) = "bind " ^ s1 ^ " in " ^ s2 |
|
177 |
|
178 fun print_constr lthy (((name, anno_tys), bds), syn) = |
|
179 (Binding.name_of name ^ " of " ^ (commas (map (print_anno_typ lthy) anno_tys)) ^ " " |
|
180 ^ (commas (map print_bind bds)) ^ " " |
|
181 ^ (Pretty.str_of (Syntax.pretty_mixfix syn))) |
|
182 |
|
183 fun print_single_dt lthy (((s2, s3), syn), constrs) = |
|
184 ["constructor declaration"] |
|
185 @ ["type arguments: "] @ s2 |
|
186 @ ["datatype name: ", Binding.name_of s3] |
|
187 @ ["typ mixfix: ", Pretty.string_of (Syntax.pretty_mixfix syn)] |
|
188 @ ["constructors: "] @ (map (print_constr lthy) constrs) |
|
189 |> separate "\n" |
|
190 |> implode |
|
191 |
|
192 fun print_single_fun_eq lthy (at, s) = |
|
193 ["function equations: ", (Syntax.string_of_term lthy s)] |
|
194 |> separate "\n" |
|
195 |> implode |
|
196 |
|
197 fun print_single_fun_fix lthy (b, _, _) = |
|
198 ["functions: ", Binding.name_of b] |
|
199 |> separate "\n" |
|
200 |> implode |
|
201 |
|
202 fun dt_name (((s2, s3), syn), constrs) = Binding.name_of s3 |
|
203 |
|
204 fun print_dts (dts, (funs, feqs)) lthy = |
|
205 let |
|
206 val _ = warning (implode (separate "\n" (map (print_single_dt lthy) dts))); |
|
207 val _ = warning (implode (separate "\n" (map (print_single_fun_fix lthy) funs))); |
|
208 val _ = warning (implode (separate "\n" (map (print_single_fun_eq lthy) feqs))); |
|
209 in |
|
210 () |
|
211 end |
|
212 *} |
|
213 |
|
214 ML {* |
|
215 fun transp_ty_arg (anno, ty) = ty |
|
216 |
|
217 fun transp_constr (((constr_name, ty_args), bind), mx) = |
|
218 (constr_name, map transp_ty_arg ty_args, mx) |
|
219 |
|
220 fun transp_dt (((ty_args, ty_name), mx), constrs) = |
|
221 (ty_args, ty_name, mx, map transp_constr constrs) |
|
222 *} |
|
223 |
|
224 ML {* |
|
225 fun dt_defn dts thy = |
|
226 let |
|
227 val names = map (fn (_, s, _, _) => Binding.name_of s) dts |
|
228 val thy' = Datatype.datatype_cmd names dts thy |
|
229 in |
|
230 thy' |
|
231 end |
|
232 *} |
|
233 |
|
234 ML {* |
|
235 fun fn_defn [] [] lthy = lthy |
|
236 | fn_defn funs feqs lthy = |
|
237 Function_Fun.add_fun Function_Common.default_config funs feqs false lthy |
|
238 |
|
239 fun fn_defn_cmd [] [] lthy = lthy |
|
240 | fn_defn_cmd funs feqs lthy = |
|
241 Function_Fun.add_fun_cmd Function_Common.default_config funs feqs false lthy |
|
242 *} |
|
243 |
|
244 ML {* |
|
245 fun parse_fun lthy (b, NONE, m) = (b, NONE, m) |
|
246 | parse_fun lthy (b, SOME ty, m) = (b, SOME (Syntax.read_typ lthy ty), m) |
|
247 |
|
248 fun parse_feq lthy (b, t) = (b, Syntax.read_prop lthy t); |
|
249 |
|
250 fun parse_anno_ty lthy (anno, ty) = (anno, Syntax.read_typ lthy ty); |
|
251 |
|
252 fun parse_constr lthy (((constr_name, ty_args), bind), mx) = |
|
253 (((constr_name, map (parse_anno_ty lthy) ty_args), bind), mx); |
|
254 |
171 |
255 fun parse_dt lthy (((ty_args, ty_name), mx), constrs) = |
172 fun prep_dt lthy ((tvs, tname, mx), cnstrs) = |
256 (((ty_args, ty_name), mx), map (parse_constr lthy) constrs); |
173 (tvs, tname, mx, map (prep_cnstr lthy) cnstrs) |
257 *} |
174 |
258 |
175 fun prep_bn_fun lthy (bn, ty_str, mx) = |
259 ML {* |
176 (bn, Option.map (Syntax.read_typ lthy) ty_str, mx) |
260 fun nominal_datatype2_cmd (dt_strs, (fun_strs, feq_strs)) thy = |
177 |
261 let |
178 fun prep_bn_eq lthy (attr, trm_str) = Syntax.read_term lthy trm_str |
262 val thy' = dt_defn (map transp_dt dt_strs) thy |
179 |
263 val lthy = Theory_Target.init NONE thy' |
180 val dts_prep = map (prep_dt lthy_tmp) dt_strs |
264 val lthy' = fn_defn_cmd fun_strs feq_strs lthy |
181 val bn_fun_prep = map (prep_bn_fun lthy_tmp) bn_fun_strs |
265 val funs = map (parse_fun lthy') fun_strs |
182 val bn_eq_prep = map (prep_bn_eq lthy_tmp) bn_eq_strs |
266 val feqs = map (parse_feq lthy') feq_strs |
183 in |
267 val dts = map (parse_dt lthy') dt_strs |
184 nominal_datatype2 dts_prep bn_fun_prep [] lthy |> snd |
268 val _ = print_dts (dts, (funs, feqs)) lthy' |
|
269 in |
|
270 Local_Theory.exit_global lthy' |
|
271 end |
185 end |
272 *} |
186 *} |
273 |
187 |
274 (* Command Keyword *) |
188 (* Command Keyword *) |
275 ML {* |
189 ML {* |
276 let |
190 let |
277 val kind = OuterKeyword.thy_decl |
191 val kind = OuterKeyword.thy_decl |
278 in |
192 in |
279 OuterSyntax.command "nominal_datatype" "test" kind |
193 OuterSyntax.local_theory "nominal_datatype" "test" kind |
280 (parser >> (Toplevel.theory o nominal_datatype2_cmd)) |
194 (main_parser >> nominal_datatype2_cmd) |
281 end |
195 end |
282 *} |
196 *} |
283 |
197 |
284 text {* example 1 *} |
198 text {* example 1 *} |
285 nominal_datatype lam = |
199 nominal_datatype lam = |