348 28) show that the lifted type is in fs typeclass (* by q_induct, supports *) |
348 28) show that the lifted type is in fs typeclass (* by q_induct, supports *) |
349 Equivp.thy/supp_eq |
349 Equivp.thy/supp_eq |
350 29) prove supp = fv |
350 29) prove supp = fv |
351 *} |
351 *} |
352 |
352 |
|
353 ML {* |
|
354 (* for testing porposes - to exit the procedure early *) |
|
355 exception TEST of Proof.context |
|
356 |
|
357 val STEPS = 3 |
|
358 *} |
353 |
359 |
354 ML {* |
360 ML {* |
355 fun nominal_datatype2 dts bn_funs bn_eqs bclauses lthy = |
361 fun nominal_datatype2 dts bn_funs bn_eqs bclauses lthy = |
356 let |
362 let |
357 (* definition of the raw datatype and raw bn-functions *) |
363 (* definition of the raw datatype and raw bn-functions *) |
358 val ((((raw_dt_names, (raw_bn_funs_loc, raw_bn_eqs_loc)), raw_bclauses), raw_bns), lthy1) = |
364 val ((((raw_dt_names, (raw_bn_funs_loc, raw_bn_eqs_loc)), raw_bclauses), raw_bns), lthy1) = |
359 raw_nominal_decls dts bn_funs bn_eqs bclauses lthy |
365 if STEPS > 1 then raw_nominal_decls dts bn_funs bn_eqs bclauses lthy |
|
366 else raise TEST lthy |
360 |
367 |
361 val dtinfo = Datatype.the_info (ProofContext.theory_of lthy1) (hd raw_dt_names); |
368 val dtinfo = Datatype.the_info (ProofContext.theory_of lthy1) (hd raw_dt_names); |
362 val {descr, sorts, ...} = dtinfo; |
369 val {descr, sorts, ...} = dtinfo; |
363 val raw_tys = map (fn (i, _) => nth_dtyp descr sorts i) descr; |
370 val raw_tys = map (fn (i, _) => nth_dtyp descr sorts i) descr; |
364 val all_typs = map (fn i => Datatype_Aux.typ_of_dtyp descr sorts (Datatype_Aux.DtRec i)) (map fst descr) |
371 val all_typs = map (fn i => Datatype_Aux.typ_of_dtyp descr sorts (Datatype_Aux.DtRec i)) (map fst descr) |
365 |
|
366 val all_full_tnames = map (fn (_, (n, _, _)) => n) descr; |
372 val all_full_tnames = map (fn (_, (n, _, _)) => n) descr; |
|
373 |
367 val dtinfos = map (Datatype.the_info (ProofContext.theory_of lthy1)) all_full_tnames; |
374 val dtinfos = map (Datatype.the_info (ProofContext.theory_of lthy1)) all_full_tnames; |
368 val inject = flat (map #inject dtinfos); |
375 |
369 val distincts = flat (map #distinct dtinfos); |
376 (* what is the difference between raw_dt_names and all_full_tnames ? *) |
370 val rel_dtinfos = List.take (dtinfos, (length dts)); |
377 (* what is the purpose of dtinfo and dtinfos ? *) |
371 val rel_distinct = map #distinct rel_dtinfos; |
378 val _ = tracing ("raw_dt_names " ^ commas raw_dt_names) |
372 val induct = #induct dtinfo; |
379 val _ = tracing ("all_full_tnames " ^ commas all_full_tnames) |
373 val exhausts = map #exhaust dtinfos; |
380 |
|
381 val inject_thms = flat (map #inject dtinfos); |
|
382 val distinct_thms = flat (map #distinct dtinfos); |
|
383 val rel_dtinfos = List.take (dtinfos, (length dts)); |
|
384 val rel_distinct = map #distinct rel_dtinfos; (* thm list list *) |
|
385 val induct_thms = #induct dtinfo; |
|
386 val exhaust_thms = map #exhaust dtinfos; |
374 |
387 |
375 (* definitions of raw permutations *) |
388 (* definitions of raw permutations *) |
376 val ((raw_perm_def, raw_perm_simps, perms), lthy2) = |
389 val ((raw_perm_def, raw_perm_simps, perms), lthy2) = |
377 Local_Theory.theory_result (define_raw_perms dtinfo (length dts)) lthy1; |
390 if STEPS > 2 then Local_Theory.theory_result (define_raw_perms descr sorts (length dts)) lthy1 |
|
391 else raise TEST lthy1 |
378 |
392 |
379 val morphism_2_0 = ProofContext.export_morphism lthy2 lthy |
393 val morphism_2_0 = ProofContext.export_morphism lthy2 lthy |
380 fun export_fun f (t, l) = (f t, map (map (apsnd (Option.map f))) l); |
394 fun export_fun f (t, l) = (f t, map (map (apsnd (Option.map f))) l); |
381 val raw_bns_exp = map (apsnd (map (export_fun (Morphism.term morphism_2_0)))) raw_bns; |
395 val raw_bns_exp = map (apsnd (map (export_fun (Morphism.term morphism_2_0)))) raw_bns; |
382 val bn_funs_decls = flat (map (fn (ith, l) => map (fn (bn, data) => (bn, ith, data)) l) raw_bns_exp); |
396 val bn_funs_decls = flat (map (fn (ith, l) => map (fn (bn, data) => (bn, ith, data)) l) raw_bns_exp); |
386 |
400 |
387 val lthy3 = Theory_Target.init NONE thy; |
401 val lthy3 = Theory_Target.init NONE thy; |
388 val raw_bn_funs = map (fn (f, _, _) => f) bn_funs_decls; |
402 val raw_bn_funs = map (fn (f, _, _) => f) bn_funs_decls; |
389 |
403 |
390 (* definition of raw fv_functions *) |
404 (* definition of raw fv_functions *) |
391 val ((fv, fvbn), fv_def, lthy3a) = define_raw_fv dtinfo bn_funs_decls raw_bclauses lthy3; |
405 val _ = tracing ("raw_bclauses\n" ^ @{make_string} raw_bclauses) |
392 |
406 val _ = tracing ("raw_bclauses\n" ^ @{make_string} bn_funs_decls) |
|
407 val ((fv, fvbn), fv_def, lthy3a) = |
|
408 if STEPS > 3 then define_raw_fv dtinfo bn_funs_decls raw_bclauses lthy3 |
|
409 else raise TEST lthy3 |
|
410 |
|
411 |
393 (* definition of raw alphas *) |
412 (* definition of raw alphas *) |
394 val (((alpha_ts, alpha_intros), (alpha_cases, alpha_induct)), lthy4) = |
413 val (((alpha_ts, alpha_intros), (alpha_cases, alpha_induct)), lthy4) = |
395 define_raw_alpha dtinfo bn_funs_decls raw_bclauses fv lthy3a; |
414 if STEPS > 4 then define_raw_alpha dtinfo bn_funs_decls raw_bclauses fv lthy3a |
|
415 else raise TEST lthy3a |
|
416 |
396 val (alpha_ts_nobn, alpha_ts_bn) = chop (length fv) alpha_ts |
417 val (alpha_ts_nobn, alpha_ts_bn) = chop (length fv) alpha_ts |
397 |
418 |
398 val dts_names = map (fn (i, (s, _, _)) => (s, i)) (#descr dtinfo); |
419 val dts_names = map (fn (i, (s, _, _)) => (s, i)) (#descr dtinfo); |
399 val bn_tys = map (domain_type o fastype_of) raw_bn_funs; |
420 val bn_tys = map (domain_type o fastype_of) raw_bn_funs; |
400 val bn_nos = map (dtyp_no_of_typ dts_names) bn_tys; |
421 val bn_nos = map (dtyp_no_of_typ dts_names) bn_tys; |
403 (rel_distinct ~~ alpha_ts_nobn)); |
424 (rel_distinct ~~ alpha_ts_nobn)); |
404 val rel_dists_bn = flat (map (distinct_rel lthy4 alpha_cases) |
425 val rel_dists_bn = flat (map (distinct_rel lthy4 alpha_cases) |
405 ((map (fn i => nth rel_distinct i) bn_nos) ~~ alpha_ts_bn)) |
426 ((map (fn i => nth rel_distinct i) bn_nos) ~~ alpha_ts_bn)) |
406 |
427 |
407 (* definition of raw_alpha_eq_iff lemmas *) |
428 (* definition of raw_alpha_eq_iff lemmas *) |
408 val alpha_eq_iff = build_rel_inj alpha_intros (inject @ distincts) alpha_cases lthy4 |
429 val alpha_eq_iff = build_rel_inj alpha_intros (inject_thms @ distinct_thms) alpha_cases lthy4 |
409 val alpha_eq_iff_simp = map remove_loop alpha_eq_iff; |
430 val alpha_eq_iff_simp = map remove_loop alpha_eq_iff; |
410 val _ = map tracing (map PolyML.makestring alpha_eq_iff_simp); |
431 val _ = map tracing (map PolyML.makestring alpha_eq_iff_simp); |
411 |
432 |
412 (* proving equivariance lemmas *) |
433 (* proving equivariance lemmas *) |
413 val _ = warning "Proving equivariance"; |
434 val _ = warning "Proving equivariance"; |
414 val (bv_eqvt, lthy5) = prove_eqvt raw_tys induct (raw_bn_eqs @ raw_perm_def) (map fst bns) lthy4 |
435 val (bv_eqvt, lthy5) = prove_eqvt raw_tys induct_thms (raw_bn_eqs @ raw_perm_def) (map fst bns) lthy4 |
415 val (fv_eqvt, lthy6) = prove_eqvt raw_tys induct (fv_def @ raw_perm_def) (fv @ fvbn) lthy5 |
436 val (fv_eqvt, lthy6) = prove_eqvt raw_tys induct_thms (fv_def @ raw_perm_def) (fv @ fvbn) lthy5 |
416 fun alpha_eqvt_tac' _ = |
437 fun alpha_eqvt_tac' _ = |
417 if !cheat_alpha_eqvt then Skip_Proof.cheat_tac thy |
438 if !cheat_alpha_eqvt then Skip_Proof.cheat_tac thy |
418 else alpha_eqvt_tac alpha_induct (raw_perm_def @ alpha_eq_iff_simp) lthy6 1 |
439 else alpha_eqvt_tac alpha_induct (raw_perm_def @ alpha_eq_iff_simp) lthy6 1 |
419 val alpha_eqvt = build_alpha_eqvts alpha_ts alpha_eqvt_tac' lthy6; |
440 val alpha_eqvt = build_alpha_eqvts alpha_ts alpha_eqvt_tac' lthy6; |
420 |
441 |
421 (* provind alpha equivalence *) |
442 (* proving alpha equivalence *) |
422 val _ = warning "Proving equivalence"; |
443 val _ = warning "Proving equivalence"; |
423 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; |
424 val reflps = build_alpha_refl fv_alpha_all alpha_ts induct alpha_eq_iff_simp lthy6; |
445 val reflps = build_alpha_refl fv_alpha_all alpha_ts induct_thms alpha_eq_iff_simp lthy6; |
425 val alpha_equivp = |
446 val alpha_equivp = |
426 if !cheat_equivp then map (equivp_hack lthy6) alpha_ts |
447 if !cheat_equivp then map (equivp_hack lthy6) alpha_ts |
427 else build_equivps alpha_ts reflps alpha_induct |
448 else build_equivps alpha_ts reflps alpha_induct |
428 inject alpha_eq_iff_simp distincts alpha_cases alpha_eqvt lthy6; |
449 inject_thms alpha_eq_iff_simp distinct_thms alpha_cases alpha_eqvt lthy6; |
429 val qty_binds = map (fn (_, b, _, _) => b) dts; |
450 val qty_binds = map (fn (_, b, _, _) => b) dts; |
430 val qty_names = map Name.of_binding qty_binds; |
451 val qty_names = map Name.of_binding qty_binds; |
431 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 |
432 val (qtys, lthy7) = define_quotient_types qty_binds all_typs alpha_ts_nobn alpha_equivp lthy6; |
453 val (qtys, lthy7) = define_quotient_types qty_binds all_typs alpha_ts_nobn alpha_equivp lthy6; |
433 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)); |
453 val fv_rsp = flat (map snd fv_rsp_pre); |
474 val fv_rsp = flat (map snd fv_rsp_pre); |
454 val (perms_rsp, lthy11) = prove_const_rsp qtys Binding.empty perms |
475 val (perms_rsp, lthy11) = prove_const_rsp qtys Binding.empty perms |
455 (fn _ => asm_simp_tac (HOL_ss addsimps alpha_eqvt) 1) lthy10; |
476 (fn _ => asm_simp_tac (HOL_ss addsimps alpha_eqvt) 1) lthy10; |
456 fun alpha_bn_rsp_tac _ = if !cheat_alpha_bn_rsp then Skip_Proof.cheat_tac thy |
477 fun alpha_bn_rsp_tac _ = if !cheat_alpha_bn_rsp then Skip_Proof.cheat_tac thy |
457 else |
478 else |
458 let val alpha_bn_rsp_pre = prove_alpha_bn_rsp alpha_ts alpha_induct (alpha_eq_iff_simp @ rel_dists @ rel_dists_bn) alpha_equivp exhausts alpha_ts_bn lthy11 in asm_simp_tac (HOL_ss addsimps alpha_bn_rsp_pre) 1 end; |
479 let val alpha_bn_rsp_pre = prove_alpha_bn_rsp alpha_ts alpha_induct (alpha_eq_iff_simp @ rel_dists @ rel_dists_bn) alpha_equivp exhaust_thms alpha_ts_bn lthy11 in asm_simp_tac (HOL_ss addsimps alpha_bn_rsp_pre) 1 end; |
459 val (alpha_bn_rsps, lthy11a) = fold_map (fn cnst => prove_const_rsp qtys Binding.empty [cnst] |
480 val (alpha_bn_rsps, lthy11a) = fold_map (fn cnst => prove_const_rsp qtys Binding.empty [cnst] |
460 alpha_bn_rsp_tac) alpha_ts_bn lthy11 |
481 alpha_bn_rsp_tac) alpha_ts_bn lthy11 |
461 fun const_rsp_tac _ = |
482 fun const_rsp_tac _ = |
462 let val alpha_alphabn = prove_alpha_alphabn alpha_ts alpha_induct alpha_eq_iff_simp alpha_ts_bn lthy11a |
483 let val alpha_alphabn = prove_alpha_alphabn alpha_ts alpha_induct alpha_eq_iff_simp alpha_ts_bn lthy11a |
463 in constr_rsp_tac alpha_eq_iff_simp (fv_rsp @ bns_rsp @ reflps @ alpha_alphabn) 1 end |
484 in constr_rsp_tac alpha_eq_iff_simp (fv_rsp @ bns_rsp @ reflps @ alpha_alphabn) 1 end |
478 val lthy13 = Theory_Target.init NONE thy'; |
499 val lthy13 = Theory_Target.init NONE thy'; |
479 val q_name = space_implode "_" qty_names; |
500 val q_name = space_implode "_" qty_names; |
480 fun suffix_bind s = Binding.qualify true q_name (Binding.name s); |
501 fun suffix_bind s = Binding.qualify true q_name (Binding.name s); |
481 val _ = warning "Lifting induction"; |
502 val _ = warning "Lifting induction"; |
482 val constr_names = map (Long_Name.base_name o fst o dest_Const) consts; |
503 val constr_names = map (Long_Name.base_name o fst o dest_Const) consts; |
483 val q_induct = Rule_Cases.name constr_names (lift_thm qtys lthy13 induct); |
504 val q_induct = Rule_Cases.name constr_names (lift_thm qtys lthy13 induct_thms); |
484 fun note_suffix s th ctxt = |
505 fun note_suffix s th ctxt = |
485 snd (Local_Theory.note ((suffix_bind s, []), th) ctxt); |
506 snd (Local_Theory.note ((suffix_bind s, []), th) ctxt); |
486 fun note_simp_suffix s th ctxt = |
507 fun note_simp_suffix s th ctxt = |
487 snd (Local_Theory.note ((suffix_bind s, [Attrib.internal (K Simplifier.simp_add)]), th) ctxt); |
508 snd (Local_Theory.note ((suffix_bind s, [Attrib.internal (K Simplifier.simp_add)]), th) ctxt); |
488 val (_, lthy14) = Local_Theory.note ((suffix_bind "induct", |
509 val (_, lthy14) = Local_Theory.note ((suffix_bind "induct", |