287 |
287 |
288 |
288 |
289 ML {* |
289 ML {* |
290 fun nominal_datatype2 dts bn_funs bn_eqs binds lthy = |
290 fun nominal_datatype2 dts bn_funs bn_eqs binds lthy = |
291 let |
291 let |
|
292 val _ = tracing "Raw declarations"; |
292 val thy = ProofContext.theory_of lthy |
293 val thy = ProofContext.theory_of lthy |
293 val thy_name = Context.theory_name thy |
294 val thy_name = Context.theory_name thy |
294 val ((((raw_dt_names, (raw_bn_funs_loc, raw_bn_eqs_loc)), raw_binds), raw_bns), lthy2) = |
295 val ((((raw_dt_names, (raw_bn_funs_loc, raw_bn_eqs_loc)), raw_binds), raw_bns), lthy2) = |
295 raw_nominal_decls dts bn_funs bn_eqs binds lthy |
296 raw_nominal_decls dts bn_funs bn_eqs binds lthy |
296 val morphism_2_1 = ProofContext.export_morphism lthy2 lthy |
297 val morphism_2_1 = ProofContext.export_morphism lthy2 lthy |
309 val inject = flat (map #inject dtinfos); |
310 val inject = flat (map #inject dtinfos); |
310 val distincts = flat (map #distinct dtinfos); |
311 val distincts = flat (map #distinct dtinfos); |
311 val rel_distinct = map #distinct rel_dtinfos; |
312 val rel_distinct = map #distinct rel_dtinfos; |
312 val induct = #induct dtinfo; |
313 val induct = #induct dtinfo; |
313 val inducts = #inducts dtinfo; |
314 val inducts = #inducts dtinfo; |
|
315 val _ = tracing "Defining permutations, fv and alpha"; |
314 val ((raw_perm_def, raw_perm_simps, perms), lthy3) = |
316 val ((raw_perm_def, raw_perm_simps, perms), lthy3) = |
315 Local_Theory.theory_result (define_raw_perms dtinfo (length dts)) lthy2; |
317 Local_Theory.theory_result (define_raw_perms dtinfo (length dts)) lthy2; |
316 val raw_binds_flat = map (map flat) raw_binds; |
318 val raw_binds_flat = map (map flat) raw_binds; |
317 val (((fv_ts_loc, fv_def_loc), alpha), lthy4) = define_fv_alpha dtinfo raw_binds_flat bn_funs_decls lthy3; |
319 val (((fv_ts_loc, fv_def_loc), alpha), lthy4) = define_fv_alpha dtinfo raw_binds_flat bn_funs_decls lthy3; |
318 val alpha_ts_loc = #preds alpha |
320 val alpha_ts_loc = #preds alpha |
334 val alpha_intros = #intrs alpha; |
336 val alpha_intros = #intrs alpha; |
335 val alpha_cases_loc = #elims alpha |
337 val alpha_cases_loc = #elims alpha |
336 val alpha_cases = ProofContext.export lthy4 lthy3 alpha_cases_loc |
338 val alpha_cases = ProofContext.export lthy4 lthy3 alpha_cases_loc |
337 val alpha_inj_loc = build_alpha_inj alpha_intros (inject @ distincts) alpha_cases_loc lthy4 |
339 val alpha_inj_loc = build_alpha_inj alpha_intros (inject @ distincts) alpha_cases_loc lthy4 |
338 val alpha_inj = ProofContext.export lthy4 lthy3 alpha_inj_loc |
340 val alpha_inj = ProofContext.export lthy4 lthy3 alpha_inj_loc |
|
341 val _ = tracing "Proving equivariance"; |
339 val (bv_eqvts, lthy5) = fold_map (build_bv_eqvt (raw_bn_eqs @ raw_perm_def) inducts) bns lthy4; |
342 val (bv_eqvts, lthy5) = fold_map (build_bv_eqvt (raw_bn_eqs @ raw_perm_def) inducts) bns lthy4; |
340 val _ = tracing "3"; |
|
341 val fv_eqvt_tac = |
343 val fv_eqvt_tac = |
342 if !cheat_fv_eqvt then (fn _ => fn _ => Skip_Proof.cheat_tac thy) |
344 if !cheat_fv_eqvt then (fn _ => fn _ => Skip_Proof.cheat_tac thy) |
343 else build_eqvts_tac induct ((flat (map snd bv_eqvts)) @ fv_def_loc @ raw_perm_def) lthy5 |
345 else build_eqvts_tac induct ((flat (map snd bv_eqvts)) @ fv_def_loc @ raw_perm_def) lthy5 |
344 val _ = tracing "4"; |
|
345 val (fv_eqvts, lthy6) = build_eqvts Binding.empty fv_ts_loc_nobn fv_eqvt_tac lthy5; |
346 val (fv_eqvts, lthy6) = build_eqvts Binding.empty fv_ts_loc_nobn fv_eqvt_tac lthy5; |
346 val _ = tracing "4a"; |
|
347 val (fv_bn_eqvts, lthy6a) = |
347 val (fv_bn_eqvts, lthy6a) = |
348 if fv_ts_loc_bn = [] then ([], lthy6) else |
348 if fv_ts_loc_bn = [] then ([], lthy6) else |
349 fold_map (build_bv_eqvt ((flat (map snd bv_eqvts)) @ fv_def_loc @ raw_perm_def) inducts) |
349 fold_map (build_bv_eqvt ((flat (map snd bv_eqvts)) @ fv_def_loc @ raw_perm_def) inducts) |
350 (fv_ts_loc_bn ~~ (map snd bns)) lthy6; |
350 (fv_ts_loc_bn ~~ (map snd bns)) lthy6; |
351 val _ = tracing "4b"; |
|
352 val lthy6 = lthy6a; |
351 val lthy6 = lthy6a; |
353 val raw_fv_bv_eqvt_loc = flat (map snd bv_eqvts) @ (snd fv_eqvts) |
352 val raw_fv_bv_eqvt_loc = flat (map snd bv_eqvts) @ (snd fv_eqvts) |
354 val raw_fv_bv_eqvt = ProofContext.export lthy6 lthy3 raw_fv_bv_eqvt_loc; |
353 val raw_fv_bv_eqvt = ProofContext.export lthy6 lthy3 raw_fv_bv_eqvt_loc; |
355 val _ = tracing "5"; |
|
356 fun alpha_eqvt_tac' _ = |
354 fun alpha_eqvt_tac' _ = |
357 if !cheat_alpha_eqvt then Skip_Proof.cheat_tac thy |
355 if !cheat_alpha_eqvt then Skip_Proof.cheat_tac thy |
358 else alpha_eqvt_tac alpha_induct_loc (raw_perm_def @ alpha_inj_loc @ raw_fv_bv_eqvt_loc) lthy6 1 |
356 else alpha_eqvt_tac alpha_induct_loc (raw_perm_def @ alpha_inj_loc @ raw_fv_bv_eqvt_loc) lthy6 1 |
359 val alpha_eqvt_loc = build_alpha_eqvts alpha_ts_loc alpha_eqvt_tac' lthy6; |
357 val alpha_eqvt_loc = build_alpha_eqvts alpha_ts_loc alpha_eqvt_tac' lthy6; |
360 val alpha_eqvt = ProofContext.export lthy6 lthy2 alpha_eqvt_loc; |
358 val alpha_eqvt = ProofContext.export lthy6 lthy2 alpha_eqvt_loc; |
361 val _ = map tracing (map PolyML.makestring alpha_eqvt) |
359 val _ = tracing "Proving equivalence"; |
362 val alpha_equivp_loc = |
360 val alpha_equivp_loc = |
363 if !cheat_equivp then map (equivp_hack lthy6) alpha_ts_loc_nobn |
361 if !cheat_equivp then map (equivp_hack lthy6) alpha_ts_loc_nobn |
364 else build_equivps alpha_ts_loc induct alpha_induct_loc |
362 else build_equivps alpha_ts_loc induct alpha_induct_loc |
365 inject alpha_inj_loc distincts alpha_cases_loc alpha_eqvt_loc lthy6; |
363 inject alpha_inj_loc distincts alpha_cases_loc alpha_eqvt_loc lthy6; |
366 val alpha_equivp = ProofContext.export lthy6 lthy2 alpha_equivp_loc; |
364 val alpha_equivp = ProofContext.export lthy6 lthy2 alpha_equivp_loc; |
380 val (consts_loc, const_defs) = split_list consts_defs; |
378 val (consts_loc, const_defs) = split_list consts_defs; |
381 val morphism_8_7 = ProofContext.export_morphism lthy8 lthy7; |
379 val morphism_8_7 = ProofContext.export_morphism lthy8 lthy7; |
382 val consts = map (Morphism.term morphism_8_7) consts_loc; |
380 val consts = map (Morphism.term morphism_8_7) consts_loc; |
383 (* Could be done nicer *) |
381 (* Could be done nicer *) |
384 val q_tys = distinct (op =) (map (snd o strip_type o fastype_of) consts); |
382 val q_tys = distinct (op =) (map (snd o strip_type o fastype_of) consts); |
|
383 val _ = tracing "Proving respects"; |
385 val (bns_rsp_pre, lthy9) = fold_map ( |
384 val (bns_rsp_pre, lthy9) = fold_map ( |
386 fn (bn_t, i) => prove_const_rsp Binding.empty [bn_t] |
385 fn (bn_t, i) => prove_const_rsp Binding.empty [bn_t] |
387 (fn _ => fvbv_rsp_tac (nth alpha_inducts i) raw_bn_eqs 1)) bns lthy8; |
386 (fn _ => fvbv_rsp_tac (nth alpha_inducts i) raw_bn_eqs 1)) bns lthy8; |
388 val bns_rsp = flat (map snd bns_rsp_pre); |
387 val bns_rsp = flat (map snd bns_rsp_pre); |
389 fun fv_rsp_tac _ = if !cheat_fv_rsp then Skip_Proof.cheat_tac thy |
388 fun fv_rsp_tac _ = if !cheat_fv_rsp then Skip_Proof.cheat_tac thy |
398 val qfv_names = map (unsuffix "_raw" o Long_Name.base_name o fst o dest_Const) fv_ts |
397 val qfv_names = map (unsuffix "_raw" o Long_Name.base_name o fst o dest_Const) fv_ts |
399 val (qfv_defs, lthy12a) = fold_map Quotient_Def.quotient_lift_const (qfv_names ~~ fv_ts) lthy12; |
398 val (qfv_defs, lthy12a) = fold_map Quotient_Def.quotient_lift_const (qfv_names ~~ fv_ts) lthy12; |
400 val qbn_names = map (fn (b, _ , _) => Name.of_binding b) bn_funs |
399 val qbn_names = map (fn (b, _ , _) => Name.of_binding b) bn_funs |
401 val (qbn_defs, lthy12b) = fold_map Quotient_Def.quotient_lift_const (qbn_names ~~ raw_bn_funs) lthy12a; |
400 val (qbn_defs, lthy12b) = fold_map Quotient_Def.quotient_lift_const (qbn_names ~~ raw_bn_funs) lthy12a; |
402 val qalpha_bn_names = map (unsuffix "_raw" o Long_Name.base_name o fst o dest_Const) alpha_ts_bn |
401 val qalpha_bn_names = map (unsuffix "_raw" o Long_Name.base_name o fst o dest_Const) alpha_ts_bn |
|
402 val _ = tracing "Lifting permutations"; |
403 val (qbn_defs, lthy12c) = fold_map Quotient_Def.quotient_lift_const (qalpha_bn_names ~~ alpha_ts_bn) lthy12b; |
403 val (qbn_defs, lthy12c) = fold_map Quotient_Def.quotient_lift_const (qalpha_bn_names ~~ alpha_ts_bn) lthy12b; |
404 val thy = Local_Theory.exit_global lthy12c; |
404 val thy = Local_Theory.exit_global lthy12c; |
405 val perm_names = map (fn x => "permute_" ^ x) qty_names |
405 val perm_names = map (fn x => "permute_" ^ x) qty_names |
406 val thy' = define_lifted_perms qty_full_names (perm_names ~~ perms) raw_perm_simps thy; |
406 val thy' = define_lifted_perms qty_full_names (perm_names ~~ perms) raw_perm_simps thy; |
407 val lthy13 = Theory_Target.init NONE thy'; |
407 val lthy13 = Theory_Target.init NONE thy'; |
408 val q_name = space_implode "_" qty_names; |
408 val q_name = space_implode "_" qty_names; |
|
409 val _ = tracing "Lifting induction"; |
409 val q_induct = lift_thm lthy13 induct; |
410 val q_induct = lift_thm lthy13 induct; |
410 val (_, lthy14) = Local_Theory.note ((Binding.name (q_name ^ "_induct"), []), [q_induct]) lthy13; |
411 val (_, lthy14) = Local_Theory.note ((Binding.name (q_name ^ "_induct"), []), [q_induct]) lthy13; |
411 val q_inducts = Project_Rule.projects lthy13 (1 upto (length alpha_inducts)) q_induct |
412 val q_inducts = Project_Rule.projects lthy13 (1 upto (length alpha_inducts)) q_induct |
412 val (_, lthy14a) = Local_Theory.note ((Binding.name (q_name ^ "_inducts"), []), q_inducts) lthy14; |
413 val (_, lthy14a) = Local_Theory.note ((Binding.name (q_name ^ "_inducts"), []), q_inducts) lthy14; |
413 val q_perm = map (lift_thm lthy14) raw_perm_def; |
414 val q_perm = map (lift_thm lthy14) raw_perm_def; |
414 val (_, lthy15) = Local_Theory.note ((Binding.name (q_name ^ "_perm"), []), q_perm) lthy14a; |
415 val (_, lthy15) = Local_Theory.note ((Binding.name (q_name ^ "_perm"), []), q_perm) lthy14a; |
415 val q_fv = map (lift_thm lthy15) fv_def; |
416 val q_fv = map (lift_thm lthy15) fv_def; |
416 val (_, lthy16) = Local_Theory.note ((Binding.name (q_name ^ "_fv"), []), q_fv) lthy15; |
417 val (_, lthy16) = Local_Theory.note ((Binding.name (q_name ^ "_fv"), []), q_fv) lthy15; |
417 val q_bn = map (lift_thm lthy16) raw_bn_eqs; |
418 val q_bn = map (lift_thm lthy16) raw_bn_eqs; |
418 val (_, lthy17) = Local_Theory.note ((Binding.name (q_name ^ "_bn"), []), q_bn) lthy16; |
419 val (_, lthy17) = Local_Theory.note ((Binding.name (q_name ^ "_bn"), []), q_bn) lthy16; |
|
420 val _ = tracing "Lifting pseudo-injectivity"; |
419 val inj_unfolded1 = map (Local_Defs.unfold lthy17 @{thms alpha_gen2}) alpha_inj |
421 val inj_unfolded1 = map (Local_Defs.unfold lthy17 @{thms alpha_gen2}) alpha_inj |
420 val inj_unfolded2 = map (Local_Defs.unfold lthy17 @{thms alpha_gen}) inj_unfolded1 |
422 val inj_unfolded2 = map (Local_Defs.unfold lthy17 @{thms alpha_gen}) inj_unfolded1 |
421 val q_inj_pre1 = map (lift_thm lthy17) inj_unfolded2; |
423 val q_inj_pre1 = map (lift_thm lthy17) inj_unfolded2; |
422 val q_inj_pre2 = map (Local_Defs.fold lthy17 @{thms alpha_gen2}) q_inj_pre1 |
424 val q_inj_pre2 = map (Local_Defs.fold lthy17 @{thms alpha_gen2}) q_inj_pre1 |
423 val q_inj = map (Local_Defs.fold lthy17 @{thms alpha_gen}) q_inj_pre2 |
425 val q_inj = map (Local_Defs.fold lthy17 @{thms alpha_gen}) q_inj_pre2 |
427 val q_dis = map (lift_thm lthy18) rel_dists; |
429 val q_dis = map (lift_thm lthy18) rel_dists; |
428 val (_, lthy19) = Local_Theory.note ((Binding.name (q_name ^ "_distinct"), []), q_dis) lthy18; |
430 val (_, lthy19) = Local_Theory.note ((Binding.name (q_name ^ "_distinct"), []), q_dis) lthy18; |
429 val q_eqvt = map (lift_thm lthy19) raw_fv_bv_eqvt; |
431 val q_eqvt = map (lift_thm lthy19) raw_fv_bv_eqvt; |
430 val (_, lthy20) = Local_Theory.note ((Binding.empty, |
432 val (_, lthy20) = Local_Theory.note ((Binding.empty, |
431 [Attrib.internal (fn _ => Nominal_ThmDecls.eqvt_add)]), q_eqvt) lthy19; |
433 [Attrib.internal (fn _ => Nominal_ThmDecls.eqvt_add)]), q_eqvt) lthy19; |
|
434 val _ = tracing "Finite Support"; |
432 val supports = map (prove_supports lthy20 q_perm) consts |
435 val supports = map (prove_supports lthy20 q_perm) consts |
433 val _ = map tracing (map PolyML.makestring supports); |
|
434 val fin_supp = HOLogic.conj_elims (prove_fs lthy20 q_induct supports q_tys) handle _ => [] |
436 val fin_supp = HOLogic.conj_elims (prove_fs lthy20 q_induct supports q_tys) handle _ => [] |
435 val thy3 = Local_Theory.exit_global lthy20; |
437 val thy3 = Local_Theory.exit_global lthy20; |
436 val lthy21 = Theory_Target.instantiation (qty_full_names, [], @{sort fs}) thy3; |
438 val lthy21 = Theory_Target.instantiation (qty_full_names, [], @{sort fs}) thy3; |
437 fun tac _ = Class.intro_classes_tac [] THEN (ALLGOALS (resolve_tac fin_supp)) |
439 fun tac _ = Class.intro_classes_tac [] THEN (ALLGOALS (resolve_tac fin_supp)) |
438 val lthy22 = Class.prove_instantiation_instance tac lthy21 handle _ => lthy20 |
440 val lthy22 = Class.prove_instantiation_instance tac lthy21 handle _ => lthy20 |