29 ^^^^^^^^^ |
29 ^^^^^^^^^ |
30 the equations of the binding functions |
30 the equations of the binding functions |
31 (Trueprop equations) |
31 (Trueprop equations) |
32 *} |
32 *} |
33 |
33 |
|
34 ML {* |
|
35 |
|
36 *} |
|
37 |
34 text {*****************************************************} |
38 text {*****************************************************} |
35 ML {* |
39 ML {* |
36 (* nominal datatype parser *) |
40 (* nominal datatype parser *) |
37 local |
41 local |
38 structure P = OuterParse |
42 structure P = OuterParse |
39 |
43 |
40 fun tuple ((x, y, z), u) = (x, y, z, u) |
44 fun tuple ((x, y, z), u) = (x, y, z, u) |
|
45 fun tswap (((x, y), z), u) = (x, y, u, z) |
41 in |
46 in |
42 |
47 |
43 val _ = OuterKeyword.keyword "bind" |
48 val _ = OuterKeyword.keyword "bind" |
44 val anno_typ = Scan.option (P.name --| P.$$$ "::") -- P.typ |
49 val anno_typ = Scan.option (P.name --| P.$$$ "::") -- P.typ |
45 |
50 |
46 (* binding specification *) |
51 (* binding specification *) |
47 (* maybe use and_list *) |
52 (* maybe use and_list *) |
48 val bind_parser = |
53 val bind_parser = |
49 P.enum "," ((P.$$$ "bind" |-- P.term) -- (P.$$$ "in" |-- P.name)) |
54 P.enum "," ((P.$$$ "bind" |-- P.term) -- (P.$$$ "in" |-- P.name) >> swap) |
50 |
55 |
51 val constr_parser = |
56 val constr_parser = |
52 P.binding -- Scan.repeat anno_typ |
57 P.binding -- Scan.repeat anno_typ |
53 |
58 |
54 (* datatype parser *) |
59 (* datatype parser *) |
55 val dt_parser = |
60 val dt_parser = |
56 (P.type_args -- P.binding -- P.opt_infix >> P.triple1) -- |
61 (P.type_args -- P.binding -- P.opt_mixfix >> P.triple1) -- |
57 (P.$$$ "=" |-- P.enum1 "|" (constr_parser -- bind_parser -- P.opt_mixfix >> P.triple_swap)) >> tuple |
62 (P.$$$ "=" |-- P.enum1 "|" (constr_parser -- bind_parser -- P.opt_mixfix >> tswap)) >> tuple |
58 |
63 |
59 (* function equation parser *) |
64 (* function equation parser *) |
60 val fun_parser = |
65 val fun_parser = |
61 Scan.optional (P.$$$ "binder" |-- P.fixes -- SpecParse.where_alt_specs) ([],[]) |
66 Scan.optional (P.$$$ "binder" |-- P.fixes -- SpecParse.where_alt_specs) ([],[]) |
62 |
67 |
173 ||>> raw_bn_fun_decl dts_names dts bn_funs bn_eqs |
180 ||>> raw_bn_fun_decl dts_names dts bn_funs bn_eqs |
174 end |
181 end |
175 *} |
182 *} |
176 |
183 |
177 ML {* |
184 ML {* |
178 fun get_constrs2 thy dts = |
185 fun get_constrs2 lthy dts = |
179 let |
186 let |
|
187 val thy = ProofContext.theory_of lthy |
|
188 |
180 (* makes a full named type out of a binding with tvars applied to it *) |
189 (* makes a full named type out of a binding with tvars applied to it *) |
181 fun mk_type thy bind tvrs = |
190 fun mk_type thy bind tvrs = |
182 Type (Sign.full_name thy bind, map (fn s => TVar ((s, 0), [])) tvrs) |
191 Type (Sign.full_name thy bind, map (fn s => TVar ((s, 0), [])) tvrs) |
183 |
192 |
184 val dts' = map (fn (tvrs, tname, _, constrs) => (mk_type thy tname tvrs, constrs)) dts |
193 val dts' = map (fn (tvrs, tname, _, constrs) => (mk_type thy tname tvrs, constrs)) dts |
185 in |
194 in |
186 flat (map (fn (ty, constrs) => map (fn (bn, tys, mx) => (bn, tys ---> ty, mx)) constrs) dts') |
195 flat (map (fn (ty, constrs) => map (fn (bn, tys, mx) => (bn, tys ---> ty, mx)) constrs) dts') |
187 end |
196 end |
188 *} |
197 *} |
189 |
198 |
|
199 ML {* |
|
200 fun find_all _ [] _ = [] |
|
201 | find_all eq ((y, z)::xs) x = |
|
202 if eq (x, y) |
|
203 then z::find_all eq xs x |
|
204 else find_all eq xs x |
|
205 *} |
|
206 |
|
207 ML {* |
|
208 fun mk_env xs = |
|
209 let |
|
210 fun mapp (_: int) [] = [] |
|
211 | mapp i ((a, _) :: xs) = |
|
212 case a of |
|
213 NONE => mapp (i + 1) xs |
|
214 | SOME x => (x, i) :: mapp (i + 1) xs |
|
215 in mapp 0 xs end |
|
216 |
|
217 fun env_lookup xs x = |
|
218 case AList.lookup (op =) xs x of |
|
219 SOME x => x |
|
220 | NONE => error ("cannot find " ^ x ^ " in the binding specification.") |
|
221 *} |
|
222 |
190 ML {* |
223 ML {* |
191 fun nominal_datatype2_cmd (dt_strs, bn_fun_strs, bn_eq_strs) lthy = |
224 fun nominal_datatype2_cmd (dt_strs, bn_fun_strs, bn_eq_strs) lthy = |
192 let |
225 let |
193 val thy = ProofContext.theory_of lthy |
|
194 |
|
195 fun prep_typ (tvs, tname, mx, _) = (tname, length tvs, mx); |
226 fun prep_typ (tvs, tname, mx, _) = (tname, length tvs, mx); |
196 |
227 |
197 (* adding the types for parsing datatypes *) |
228 (* adding the types for parsing datatypes *) |
198 val lthy_tmp = lthy |
229 val lthy_tmp1 = lthy |
199 |> Local_Theory.theory (Sign.add_types (map prep_typ dt_strs)) |
230 |> Local_Theory.theory (Sign.add_types (map prep_typ dt_strs)) |
200 |
231 |
201 fun prep_cnstr lthy (((cname, atys), mx), binders) = |
232 (* parsing the datatypes *) |
202 (cname, map (Syntax.read_typ lthy o snd) atys, mx) |
233 val dts_prep = |
|
234 let |
|
235 fun prep_cnstr lthy (cname, anno_tys, mx, _) = |
|
236 (cname, map (Syntax.read_typ lthy o snd) anno_tys, mx) |
203 |
237 |
204 fun prep_dt lthy (tvs, tname, mx, cnstrs) = |
238 fun prep_dt lthy (tvs, tname, mx, cnstrs) = |
205 (tvs, tname, mx, map (prep_cnstr lthy) cnstrs) |
239 (tvs, tname, mx, map (prep_cnstr lthy) cnstrs) |
206 |
240 in |
207 (* parsing the datatypes *) |
241 map (prep_dt lthy_tmp1) dt_strs |
208 val dts_prep = map (prep_dt lthy_tmp) dt_strs |
242 end |
209 |
243 |
210 (* adding constructors for parsing functions *) |
244 (* adding constructors for parsing functions *) |
211 val lthy_tmp2 = lthy_tmp |
245 val lthy_tmp2 = lthy_tmp1 |
212 |> Local_Theory.theory (Sign.add_consts_i (get_constrs2 thy dts_prep)) |
246 |> Local_Theory.theory (Sign.add_consts_i (get_constrs2 lthy dts_prep)) |
213 |
247 |
214 val (bn_fun_aux, bn_eq_aux) = fst (Specification.read_spec bn_fun_strs bn_eq_strs lthy_tmp2) |
248 (* parsing the function specification *) |
215 |
249 val (bn_fun_prep, bn_eq_prep) = |
216 fun prep_bn_fun ((bn, T), mx) = (bn, SOME T, mx) |
250 let |
217 |
251 val ((bn_fun_aux, bn_eq_aux), _) = Specification.read_spec bn_fun_strs bn_eq_strs lthy_tmp2 |
218 fun prep_bn_eq (attr, t) = t |
252 |
219 |
253 fun prep_bn_fun ((bn, T), mx) = (bn, T, mx) |
220 val bn_fun_prep = map prep_bn_fun bn_fun_aux |
254 fun prep_bn_eq (attr, t) = t |
221 val bn_eq_prep = map prep_bn_eq bn_eq_aux |
255 in |
222 in |
256 (map prep_bn_fun bn_fun_aux, map prep_bn_eq bn_eq_aux) |
223 nominal_datatype2 dts_prep bn_fun_prep bn_eq_prep lthy |> snd |
257 end |
|
258 |
|
259 (* adding functions for parsing binders *) |
|
260 val lthy_tmp3 = lthy_tmp2 |
|
261 |> Local_Theory.theory (Sign.add_consts_i bn_fun_prep) |
|
262 |
|
263 (* parsing the binding structure *) |
|
264 val binds = |
|
265 let |
|
266 fun prep_bn env str = |
|
267 (case Syntax.read_term lthy_tmp3 str of |
|
268 Free (x, _) => (env_lookup env x, NONE) |
|
269 | Const (a, T) $ Free (x, _) => (env_lookup env x, SOME (Const (a, T))) |
|
270 | _ => error (str ^ " not allowed as binding specification.")) |
|
271 |
|
272 fun prep_typ env (opt_name, _) = |
|
273 (case opt_name of |
|
274 NONE => [] |
|
275 | SOME x => find_all (op=) env x) |
|
276 |
|
277 fun prep_binds (_, anno_tys, _, bind_strs) = |
|
278 let |
|
279 val env = mk_env anno_tys |
|
280 val binds = map (fn (x, y) => (x, prep_bn env y)) bind_strs |
|
281 in |
|
282 map (prep_typ binds) anno_tys |
|
283 end |
|
284 in |
|
285 map ((map prep_binds) o #4) dt_strs |
|
286 end |
|
287 |
|
288 val _ = tracing (PolyML.makestring binds) |
|
289 in |
|
290 nominal_datatype2 dts_prep bn_fun_prep bn_eq_prep lthy |> snd |
224 end |
291 end |
225 *} |
292 *} |
226 |
293 |
227 (* Command Keyword *) |
294 (* Command Keyword *) |
|
295 |
|
296 |
228 ML {* |
297 ML {* |
229 let |
298 let |
230 val kind = OuterKeyword.thy_decl |
299 val kind = OuterKeyword.thy_decl |
231 in |
300 in |
232 OuterSyntax.local_theory "nominal_datatype" "test" kind |
301 OuterSyntax.local_theory "nominal_datatype" "test" kind |