65 map (fn (bn_fun, _, _) => Binding.name_of bn_fun) bn_funs |
65 map (fn (bn_fun, _, _) => Binding.name_of bn_fun) bn_funs |
66 *} |
66 *} |
67 |
67 |
68 |
68 |
69 ML {* |
69 ML {* |
|
70 (* exports back the results *) |
70 fun add_primrec_wrapper funs eqs lthy = |
71 fun add_primrec_wrapper funs eqs lthy = |
71 if null funs then (([], []), lthy) |
72 if null funs then ([], [], lthy) |
72 else |
73 else |
73 let |
74 let |
74 val eqs' = map (fn (_, eq) => (Attrib.empty_binding, eq)) eqs |
75 val eqs' = map (fn (_, eq) => (Attrib.empty_binding, eq)) eqs |
75 val funs' = map (fn (bn, ty, mx) => (bn, SOME ty, mx)) funs |
76 val funs' = map (fn (bn, ty, mx) => (bn, SOME ty, mx)) funs |
76 val ((funs'', eqs''), lthy') = Primrec.add_primrec funs' eqs' lthy |
77 val ((funs'', eqs''), lthy') = Primrec.add_primrec funs' eqs' lthy |
77 val phi = ProofContext.export_morphism lthy' lthy |
78 val phi = ProofContext.export_morphism lthy' lthy |
78 in |
79 in |
79 ((map (Morphism.term phi) funs'', map (Morphism.thm phi) eqs''), lthy') |
80 (map (Morphism.term phi) funs'', map (Morphism.thm phi) eqs'', lthy') |
80 end |
81 end |
81 *} |
82 *} |
82 |
83 |
83 ML {* |
84 ML {* |
84 fun add_datatype_wrapper dt_names dts = |
85 fun add_datatype_wrapper dt_names dts = |
250 val bn_fun_env = bn_fun_strs ~~ bn_fun_strs' |
250 val bn_fun_env = bn_fun_strs ~~ bn_fun_strs' |
251 val bn_fun_full_env = map (pairself (Long_Name.qualify thy_name)) |
251 val bn_fun_full_env = map (pairself (Long_Name.qualify thy_name)) |
252 (bn_fun_strs ~~ bn_fun_strs') |
252 (bn_fun_strs ~~ bn_fun_strs') |
253 |
253 |
254 val (raw_dt_names, raw_dts) = rawify_dts dt_names dts dts_env |
254 val (raw_dt_names, raw_dts) = rawify_dts dt_names dts dts_env |
255 |
|
256 val (raw_bn_funs, raw_bn_eqs) = rawify_bn_funs dts_env cnstrs_env bn_fun_env bn_funs bn_eqs |
255 val (raw_bn_funs, raw_bn_eqs) = rawify_bn_funs dts_env cnstrs_env bn_fun_env bn_funs bn_eqs |
257 |
|
258 val raw_bclauses = rawify_bclauses dts_env cnstrs_env bn_fun_full_env binds |
256 val raw_bclauses = rawify_bclauses dts_env cnstrs_env bn_fun_full_env binds |
259 val raw_bns = prep_bn lthy dt_full_names' raw_dts (map snd raw_bn_eqs) |
257 val raw_bns = prep_bn lthy dt_full_names' raw_dts (map snd raw_bn_eqs) |
260 |
258 |
261 val (raw_dt_names, lthy1) = add_datatype_wrapper raw_dt_names raw_dts lthy |
259 val (raw_dt_names, lthy1) = add_datatype_wrapper raw_dt_names raw_dts lthy |
262 val ((raw_bn_funs, raw_bn_eqs), lthy2) = add_primrec_wrapper raw_bn_funs raw_bn_eqs lthy1 |
260 val (raw_bn_funs, raw_bn_eqs, lthy2) = add_primrec_wrapper raw_bn_funs raw_bn_eqs lthy1 |
263 |
261 |
264 val morphism_2_0 = ProofContext.export_morphism lthy2 lthy |
262 val morphism_2_0 = ProofContext.export_morphism lthy2 lthy |
265 fun export_fun f (t, n , l) = (f t, n, map (map (apsnd (Option.map f))) l); |
263 fun export_fun f (t, n , l) = (f t, n, map (map (apsnd (Option.map f))) l); |
266 val bn_funs_decls = map (export_fun (Morphism.term morphism_2_0)) raw_bns; |
264 val bn_funs_decls = map (export_fun (Morphism.term morphism_2_0)) raw_bns; |
267 in |
265 in |
368 fun get_STEPS ctxt = Config.get ctxt STEPS |
366 fun get_STEPS ctxt = Config.get ctxt STEPS |
369 *} |
367 *} |
370 |
368 |
371 setup STEPS_setup |
369 setup STEPS_setup |
372 |
370 |
373 |
|
374 ML {* |
371 ML {* |
375 fun nominal_datatype2 dts bn_funs bn_eqs bclauses lthy = |
372 fun nominal_datatype2 dts bn_funs bn_eqs bclauses lthy = |
376 let |
373 let |
377 (* definition of the raw datatype and raw bn-functions *) |
374 (* definition of the raw datatypes and raw bn-functions *) |
378 val (raw_dt_names, raw_bn_eqs, raw_bclauses, raw_bns, lthy1) = |
375 val (raw_dt_names, raw_bn_eqs, raw_bclauses, raw_bns, lthy1) = |
379 if get_STEPS lthy > 1 then raw_nominal_decls dts bn_funs bn_eqs bclauses lthy |
376 if get_STEPS lthy > 1 then raw_nominal_decls dts bn_funs bn_eqs bclauses lthy |
380 else raise TEST lthy |
377 else raise TEST lthy |
381 |
378 |
382 val dtinfo = Datatype.the_info (ProofContext.theory_of lthy1) (hd raw_dt_names); |
379 val dtinfo = Datatype.the_info (ProofContext.theory_of lthy1) (hd raw_dt_names) |
383 val {descr, sorts, ...} = dtinfo; |
380 val {descr, sorts, ...} = dtinfo |
384 val raw_tys = map (fn (i, _) => nth_dtyp descr sorts i) descr; |
381 val all_tys = map (fn (i, _) => nth_dtyp descr sorts i) descr |
385 val all_typs = map (fn i => Datatype_Aux.typ_of_dtyp descr sorts (Datatype_Aux.DtRec i)) (map fst descr) |
382 val all_full_tnames = map (fn (_, (n, _, _)) => n) descr |
386 val all_full_tnames = map (fn (_, (n, _, _)) => n) descr; |
383 val dtinfos = map (Datatype.the_info (ProofContext.theory_of lthy1)) all_full_tnames |
387 |
|
388 val dtinfos = map (Datatype.the_info (ProofContext.theory_of lthy1)) all_full_tnames; |
|
389 |
384 |
390 val inject_thms = flat (map #inject dtinfos); |
385 val inject_thms = flat (map #inject dtinfos); |
391 val distinct_thms = flat (map #distinct dtinfos); |
386 val distinct_thms = flat (map #distinct dtinfos); |
392 val rel_dtinfos = List.take (dtinfos, (length dts)); |
387 val rel_dtinfos = List.take (dtinfos, (length dts)); |
393 val rel_distinct = map #distinct rel_dtinfos; (* thm list list *) |
388 val rel_distinct = map #distinct rel_dtinfos; (* thm list list *) |
394 val induct_thm = #induct dtinfo; |
389 val induct_thm = #induct dtinfo; |
395 val exhaust_thms = map #exhaust dtinfos; |
390 val exhaust_thms = map #exhaust dtinfos; |
396 |
391 |
397 (* definitions of raw permutations *) |
392 (* definitions of raw permutations *) |
398 val ((raw_perm_def, raw_perm_simps, perms), lthy2) = |
393 val ((perms, raw_perm_defs, raw_perm_simps), lthy2) = |
399 if get_STEPS lthy > 2 |
394 if get_STEPS lthy1 > 2 |
400 then Local_Theory.theory_result (define_raw_perms descr sorts induct_thm (length dts)) lthy1 |
395 then Local_Theory.theory_result (define_raw_perms descr sorts induct_thm (length dts)) lthy1 |
401 else raise TEST lthy1 |
396 else raise TEST lthy1 |
402 |
397 |
403 val (_, lthy2a) = Local_Theory.note ((Binding.empty, |
398 val (_, lthy2a) = Local_Theory.note ((Binding.empty, |
404 [Attrib.internal (fn _ => Nominal_ThmDecls.eqvt_add)]), raw_perm_def) lthy2; |
399 [Attrib.internal (fn _ => Nominal_ThmDecls.eqvt_add)]), raw_perm_defs) lthy2; |
|
400 |
405 val thy = Local_Theory.exit_global lthy2a; |
401 val thy = Local_Theory.exit_global lthy2a; |
406 val thy_name = Context.theory_name thy |
402 val thy_name = Context.theory_name thy |
407 |
403 |
408 (* definition of raw fv_functions *) |
404 (* definition of raw fv_functions *) |
409 val lthy3 = Theory_Target.init NONE thy; |
405 val lthy3 = Theory_Target.init NONE thy; |
410 val raw_bn_funs = map (fn (f, _, _) => f) raw_bns; |
406 val raw_bn_funs = map (fn (f, _, _) => f) raw_bns; |
411 |
407 |
412 val ((fv, fvbn), fv_def, lthy3a) = |
408 val ((fv, fvbn), fv_def, lthy3a) = |
413 if get_STEPS lthy > 3 |
409 if get_STEPS lthy2 > 3 |
414 then define_raw_fv descr sorts raw_bns raw_bclauses lthy3 |
410 then define_raw_fv descr sorts raw_bns raw_bclauses lthy3 |
415 else raise TEST lthy3 |
411 else raise TEST lthy3 |
416 |
412 |
417 |
413 |
418 (* definition of raw alphas *) |
414 (* definition of raw alphas *) |
437 val alpha_eq_iff_simp = map remove_loop alpha_eq_iff; |
433 val alpha_eq_iff_simp = map remove_loop alpha_eq_iff; |
438 val _ = map tracing (map PolyML.makestring alpha_eq_iff_simp); |
434 val _ = map tracing (map PolyML.makestring alpha_eq_iff_simp); |
439 |
435 |
440 (* proving equivariance lemmas *) |
436 (* proving equivariance lemmas *) |
441 val _ = warning "Proving equivariance"; |
437 val _ = warning "Proving equivariance"; |
442 val (bv_eqvt, lthy5) = prove_eqvt raw_tys induct_thm (raw_bn_eqs @ raw_perm_def) (map fst bns) lthy4 |
438 val (bv_eqvt, lthy5) = prove_eqvt all_tys induct_thm (raw_bn_eqs @ raw_perm_defs) (map fst bns) lthy4 |
443 val (fv_eqvt, lthy6) = prove_eqvt raw_tys induct_thm (fv_def @ raw_perm_def) (fv @ fvbn) lthy5 |
439 val (fv_eqvt, lthy6) = prove_eqvt all_tys induct_thm (fv_def @ raw_perm_defs) (fv @ fvbn) lthy5 |
444 val (alpha_eqvt, lthy6a) = Nominal_Eqvt.equivariance alpha_ts alpha_induct alpha_intros lthy6; |
440 val (alpha_eqvt, lthy6a) = Nominal_Eqvt.equivariance alpha_ts alpha_induct alpha_intros lthy6; |
445 |
441 |
446 (* proving alpha equivalence *) |
442 (* proving alpha equivalence *) |
447 val _ = warning "Proving equivalence"; |
443 val _ = warning "Proving equivalence"; |
448 val fv_alpha_all = combine_fv_alpha_bns (fv, fvbn) (alpha_ts_nobn, alpha_ts_bn) bn_nos; |
444 val fv_alpha_all = combine_fv_alpha_bns (fv, fvbn) (alpha_ts_nobn, alpha_ts_bn) bn_nos; |
452 else build_equivps alpha_ts reflps alpha_induct |
448 else build_equivps alpha_ts reflps alpha_induct |
453 inject_thms alpha_eq_iff_simp distinct_thms alpha_cases alpha_eqvt lthy6a; |
449 inject_thms alpha_eq_iff_simp distinct_thms alpha_cases alpha_eqvt lthy6a; |
454 val qty_binds = map (fn (_, b, _, _) => b) dts; |
450 val qty_binds = map (fn (_, b, _, _) => b) dts; |
455 val qty_names = map Name.of_binding qty_binds; |
451 val qty_names = map Name.of_binding qty_binds; |
456 val qty_full_names = map (Long_Name.qualify thy_name) qty_names |
452 val qty_full_names = map (Long_Name.qualify thy_name) qty_names |
457 val (qtys, lthy7) = define_quotient_types qty_binds all_typs alpha_ts_nobn alpha_equivp lthy6a; |
453 val (qtys, lthy7) = define_quotient_types qty_binds all_tys alpha_ts_nobn alpha_equivp lthy6a; |
458 val const_names = map Name.of_binding (flat (map (fn (_, _, _, t) => map (fn (b, _, _) => b) t) dts)); |
454 val const_names = map Name.of_binding (flat (map (fn (_, _, _, t) => map (fn (b, _, _) => b) t) dts)); |
459 val raw_consts = |
455 val raw_consts = |
460 flat (map (fn (i, (_, _, l)) => |
456 flat (map (fn (i, (_, _, l)) => |
461 map (fn (cname, dts) => |
457 map (fn (cname, dts) => |
462 Const (cname, map (Datatype_Aux.typ_of_dtyp descr sorts) dts ---> |
458 Const (cname, map (Datatype_Aux.typ_of_dtyp descr sorts) dts ---> |
513 val (_, lthy14) = Local_Theory.note ((suffix_bind "induct", |
509 val (_, lthy14) = Local_Theory.note ((suffix_bind "induct", |
514 [Attrib.internal (K (Rule_Cases.case_names constr_names))]), |
510 [Attrib.internal (K (Rule_Cases.case_names constr_names))]), |
515 [Rule_Cases.name constr_names q_induct]) lthy13; |
511 [Rule_Cases.name constr_names q_induct]) lthy13; |
516 val q_inducts = Project_Rule.projects lthy13 (1 upto (length fv)) q_induct |
512 val q_inducts = Project_Rule.projects lthy13 (1 upto (length fv)) q_induct |
517 val (_, lthy14a) = Local_Theory.note ((suffix_bind "inducts", []), q_inducts) lthy14; |
513 val (_, lthy14a) = Local_Theory.note ((suffix_bind "inducts", []), q_inducts) lthy14; |
518 val q_perm = map (lift_thm qtys lthy14) raw_perm_def; |
514 val q_perm = map (lift_thm qtys lthy14) raw_perm_defs; |
519 val lthy15 = note_simp_suffix "perm" q_perm lthy14a; |
515 val lthy15 = note_simp_suffix "perm" q_perm lthy14a; |
520 val q_fv = map (lift_thm qtys lthy15) fv_def; |
516 val q_fv = map (lift_thm qtys lthy15) fv_def; |
521 val lthy16 = note_simp_suffix "fv" q_fv lthy15; |
517 val lthy16 = note_simp_suffix "fv" q_fv lthy15; |
522 val q_bn = map (lift_thm qtys lthy16) raw_bn_eqs; |
518 val q_bn = map (lift_thm qtys lthy16) raw_bn_eqs; |
523 val lthy17 = note_simp_suffix "bn" q_bn lthy16; |
519 val lthy17 = note_simp_suffix "bn" q_bn lthy16; |