159 val bn_fun_env = bn_fun_strs ~~ bn_fun_strs' |
157 val bn_fun_env = bn_fun_strs ~~ bn_fun_strs' |
160 |
158 |
161 val bn_funs' = map (fn (bn, ty, mx) => |
159 val bn_funs' = map (fn (bn, ty, mx) => |
162 (raw_bind bn, SOME (replace_typ dt_env ty), mx)) bn_funs |
160 (raw_bind bn, SOME (replace_typ dt_env ty), mx)) bn_funs |
163 |
161 |
164 val bn_eqs' = map (fn trm => |
162 val bn_eqs' = map (fn (_, trm) => |
165 (Attrib.empty_binding, replace_term (ctrs_env @ bn_fun_env) dt_env trm)) bn_eqs |
163 (Attrib.empty_binding, replace_term (ctrs_env @ bn_fun_env) dt_env trm)) bn_eqs |
166 in |
164 in |
167 if null bn_eqs |
165 if null bn_eqs |
168 then (([], []), lthy) |
166 then (([], []), lthy) |
169 else Primrec.add_primrec bn_funs' bn_eqs' lthy |
167 else Primrec.add_primrec bn_funs' bn_eqs' lthy |
170 end |
168 end |
171 *} |
169 *} |
172 |
170 |
173 ML {* |
171 ML {* |
174 fun nominal_datatype2 dts bn_funs bn_eqs lthy = |
172 fun nominal_datatype2 dts bn_funs bn_eqs binds lthy = |
175 let |
173 let |
176 val dts_names = map (fn (_, s, _, _) => Binding.name_of s) dts |
174 val dts_names = map (fn (_, s, _, _) => Binding.name_of s) dts |
177 in |
175 in |
178 lthy |
176 lthy |
179 |> raw_dts_decl dts_names dts |
177 |> raw_dts_decl dts_names dts |
180 ||>> raw_bn_fun_decl dts_names dts bn_funs bn_eqs |
178 ||>> raw_bn_fun_decl dts_names dts bn_funs bn_eqs |
181 end |
179 end |
182 *} |
180 *} |
183 |
181 |
184 ML {* |
182 |
185 fun get_constrs2 lthy dts = |
183 ML {* |
|
184 (* parsing the datatypes and declaring *) |
|
185 (* constructors in the local theory *) |
|
186 fun prepare_dts dt_strs lthy = |
186 let |
187 let |
187 val thy = ProofContext.theory_of lthy |
188 val thy = ProofContext.theory_of lthy |
188 |
189 |
189 (* makes a full named type out of a binding with tvars applied to it *) |
190 fun mk_type full_tname tvrs = |
190 fun mk_type thy bind tvrs = |
191 Type (full_tname, map (fn a => TVar ((a, 0), [])) tvrs) |
191 Type (Sign.full_name thy bind, map (fn s => TVar ((s, 0), [])) tvrs) |
192 |
192 |
193 fun prep_cnstr lthy full_tname tvs (cname, anno_tys, mx, _) = |
193 val dts' = map (fn (tvrs, tname, _, constrs) => (mk_type thy tname tvrs, constrs)) dts |
194 let |
194 in |
195 val tys = map (Syntax.read_typ lthy o snd) anno_tys |
195 flat (map (fn (ty, constrs) => map (fn (bn, tys, mx) => (bn, tys ---> ty, mx)) constrs) dts') |
196 val ty = mk_type full_tname tvs |
196 end |
197 in |
197 *} |
198 ((cname, tys ---> ty, mx), (cname, tys, mx)) |
198 |
199 end |
199 ML {* |
200 |
200 fun find_all _ [] _ = [] |
201 fun prep_dt lthy (tvs, tname, mx, cnstrs) = |
201 | find_all eq ((y, z)::xs) x = |
202 let |
202 if eq (x, y) |
203 val full_tname = Sign.full_name thy tname |
203 then z::find_all eq xs x |
204 val (cnstrs', cnstrs'') = |
204 else find_all eq xs x |
205 split_list (map (prep_cnstr lthy full_tname tvs) cnstrs) |
205 *} |
206 in |
206 |
207 (cnstrs', (tvs, tname, mx, cnstrs'')) |
207 ML {* |
208 end |
|
209 |
|
210 val (cnstrs, dts) = |
|
211 split_list (map (prep_dt lthy) dt_strs) |
|
212 in |
|
213 lthy |
|
214 |> Local_Theory.theory (Sign.add_consts_i (flat cnstrs)) |
|
215 |> pair dts |
|
216 end |
|
217 *} |
|
218 |
|
219 ML {* |
|
220 (* parsing the function specification and *) |
|
221 (* declaring the functions in the local theory *) |
|
222 fun prepare_bn_funs bn_fun_strs bn_eq_strs lthy = |
|
223 let |
|
224 fun prep_bn_fun ((bn, T), mx) = (bn, T, mx) |
|
225 |
|
226 val ((bn_funs, bn_eqs), _) = |
|
227 Specification.read_spec bn_fun_strs bn_eq_strs lthy |
|
228 |
|
229 val bn_funs' = map prep_bn_fun bn_funs |
|
230 in |
|
231 lthy |
|
232 |> Local_Theory.theory (Sign.add_consts_i bn_funs') |
|
233 |> pair (bn_funs', bn_eqs) |
|
234 end |
|
235 *} |
|
236 |
|
237 ML {* |
|
238 fun forth (_, _, _, x) = x |
|
239 |
|
240 fun find_all eq [] _ = [] |
|
241 | find_all eq ((key, value)::xs) key' = |
|
242 let |
|
243 val values = find_all eq xs key' |
|
244 in if eq (key', key) then value :: values else values end; |
|
245 |
208 fun mk_env xs = |
246 fun mk_env xs = |
209 let |
247 let |
210 fun mapp (_: int) [] = [] |
248 fun mapp (_: int) [] = [] |
211 | mapp i ((a, _) :: xs) = |
249 | mapp i ((a, _) :: xs) = |
212 case a of |
250 case a of |
219 SOME x => x |
257 SOME x => x |
220 | NONE => error ("cannot find " ^ x ^ " in the binding specification.") |
258 | NONE => error ("cannot find " ^ x ^ " in the binding specification.") |
221 *} |
259 *} |
222 |
260 |
223 ML {* |
261 ML {* |
224 fun nominal_datatype2_cmd (dt_strs, bn_fun_strs, bn_eq_strs) lthy = |
262 fun prepare_binds dt_strs lthy = |
225 let |
263 let |
226 fun prep_typ (tvs, tname, mx, _) = (tname, length tvs, mx); |
264 fun prep_bn env str = |
227 |
265 (case Syntax.read_term lthy str of |
228 (* adding the types for parsing datatypes *) |
|
229 val lthy_tmp1 = lthy |
|
230 |> Local_Theory.theory (Sign.add_types (map prep_typ dt_strs)) |
|
231 |
|
232 (* parsing the datatypes *) |
|
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) |
|
237 |
|
238 fun prep_dt lthy (tvs, tname, mx, cnstrs) = |
|
239 (tvs, tname, mx, map (prep_cnstr lthy) cnstrs) |
|
240 in |
|
241 map (prep_dt lthy_tmp1) dt_strs |
|
242 end |
|
243 |
|
244 (* adding constructors for parsing functions *) |
|
245 val lthy_tmp2 = lthy_tmp1 |
|
246 |> Local_Theory.theory (Sign.add_consts_i (get_constrs2 lthy dts_prep)) |
|
247 |
|
248 (* parsing the function specification *) |
|
249 val (bn_fun_prep, bn_eq_prep) = |
|
250 let |
|
251 val ((bn_fun_aux, bn_eq_aux), _) = Specification.read_spec bn_fun_strs bn_eq_strs lthy_tmp2 |
|
252 |
|
253 fun prep_bn_fun ((bn, T), mx) = (bn, T, mx) |
|
254 fun prep_bn_eq (attr, t) = t |
|
255 in |
|
256 (map prep_bn_fun bn_fun_aux, map prep_bn_eq bn_eq_aux) |
|
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) |
266 Free (x, _) => (env_lookup env x, NONE) |
269 | Const (a, T) $ Free (x, _) => (env_lookup env x, SOME (Const (a, T))) |
267 | Const (a, T) $ Free (x, _) => (env_lookup env x, SOME (Const (a, T))) |
270 | _ => error (str ^ " not allowed as binding specification.")) |
268 | x => error (str ^ " not allowed as binding specification.")) |
271 |
269 |
272 fun prep_typ env (opt_name, _) = |
270 fun prep_typ env (opt_name, _) = |
273 (case opt_name of |
271 (case opt_name of |
274 NONE => [] |
272 NONE => [] |
275 | SOME x => find_all (op=) env x) |
273 | SOME x => find_all (op=) env x) |
276 |
274 |
277 fun prep_binds (_, anno_tys, _, bind_strs) = |
275 fun prep_binds (_, anno_tys, _, bind_strs) = |
278 let |
276 let |
279 val env = mk_env anno_tys |
277 val env = mk_env anno_tys |
280 val binds = map (fn (x, y) => (x, prep_bn env y)) bind_strs |
278 val binds = map (fn (x, y) => (x, prep_bn env y)) bind_strs |
281 in |
279 in |
282 map (prep_typ binds) anno_tys |
280 map (prep_typ binds) anno_tys |
283 end |
281 end |
284 in |
282 in |
285 map ((map prep_binds) o #4) dt_strs |
283 map ((map prep_binds) o forth) dt_strs |
286 end |
284 end |
287 |
285 *} |
288 val _ = tracing (PolyML.makestring binds) |
286 |
289 in |
287 ML {* |
290 nominal_datatype2 dts_prep bn_fun_prep bn_eq_prep lthy |> snd |
288 fun nominal_datatype2_cmd (dt_strs, bn_fun_strs, bn_eq_strs) lthy = |
291 end |
289 let |
292 *} |
290 val t = start_timing () |
|
291 |
|
292 fun prep_typ (tvs, tname, mx, _) = (tname, length tvs, mx) |
|
293 |
|
294 val ((dts, (bn_fun, bn_eq)), binds) = |
|
295 lthy |
|
296 |> Local_Theory.theory (Sign.add_types (map prep_typ dt_strs)) |
|
297 |> prepare_dts dt_strs |
|
298 ||>> prepare_bn_funs bn_fun_strs bn_eq_strs |
|
299 ||> prepare_binds dt_strs |
|
300 |
|
301 val _ = tracing (PolyML.makestring binds) |
|
302 val _ = tracing (#message (end_timing t)) |
|
303 in |
|
304 nominal_datatype2 dts bn_fun bn_eq binds lthy |> snd |
|
305 end |
|
306 *} |
|
307 |
293 |
308 |
294 (* Command Keyword *) |
309 (* Command Keyword *) |
295 |
|
296 |
310 |
297 ML {* |
311 ML {* |
298 let |
312 let |
299 val kind = OuterKeyword.thy_decl |
313 val kind = OuterKeyword.thy_decl |
300 in |
314 in |