303 fun get_STEPS ctxt = Config.get ctxt STEPS |
297 fun get_STEPS ctxt = Config.get ctxt STEPS |
304 *} |
298 *} |
305 |
299 |
306 setup STEPS_setup |
300 setup STEPS_setup |
307 |
301 |
308 ML {* dtyp_no_of_typ *} |
302 ML {* |
|
303 fun mk_conjl props = |
|
304 fold (fn a => fn b => |
|
305 if a = @{term True} then b else |
|
306 if b = @{term True} then a else |
|
307 HOLogic.mk_conj (a, b)) (rev props) @{term True}; |
|
308 *} |
|
309 |
|
310 ML {* |
|
311 val split_conj_tac = REPEAT o etac conjE THEN' TRY o REPEAT_ALL_NEW (CHANGED o rtac conjI) |
|
312 *} |
|
313 |
|
314 (* Given function for buildng a goal for an input, prepares a |
|
315 one common goals for all the inputs and proves it by induction |
|
316 together *) |
|
317 ML {* |
|
318 fun prove_by_induct tys build_goal ind utac inputs ctxt = |
|
319 let |
|
320 val names = Datatype_Prop.make_tnames tys; |
|
321 val (names', ctxt') = Variable.variant_fixes names ctxt; |
|
322 val frees = map Free (names' ~~ tys); |
|
323 val (gls_lists, ctxt'') = fold_map (build_goal (tys ~~ frees)) inputs ctxt'; |
|
324 val gls = flat gls_lists; |
|
325 fun trm_gls_map t = filter (exists_subterm (fn s => s = t)) gls; |
|
326 val trm_gl_lists = map trm_gls_map frees; |
|
327 val trm_gl_insts = map2 (fn n => fn l => [NONE, if l = [] then NONE else SOME n]) names' trm_gl_lists |
|
328 val trm_gls = map mk_conjl trm_gl_lists; |
|
329 val gl = HOLogic.mk_Trueprop (foldr1 HOLogic.mk_conj trm_gls); |
|
330 fun tac {context,...} = ( |
|
331 InductTacs.induct_rules_tac context [(flat trm_gl_insts)] [ind] |
|
332 THEN_ALL_NEW split_conj_tac THEN_ALL_NEW utac) 1 |
|
333 val th_loc = Goal.prove ctxt'' [] [] gl tac |
|
334 val ths_loc = HOLogic.conj_elims th_loc |
|
335 val ths = Variable.export ctxt'' ctxt ths_loc |
|
336 in |
|
337 filter (fn x => not (prop_of x = prop_of @{thm TrueI})) ths |
|
338 end |
|
339 *} |
|
340 |
|
341 ML {* |
|
342 fun build_eqvt_gl pi frees fnctn ctxt = |
|
343 let |
|
344 val typ = domain_type (fastype_of fnctn); |
|
345 val arg = the (AList.lookup (op=) frees typ); |
|
346 in |
|
347 ([HOLogic.mk_eq (mk_perm pi (fnctn $ arg), fnctn $ (mk_perm pi arg))], ctxt) |
|
348 end |
|
349 *} |
|
350 |
|
351 ML {* |
|
352 fun prove_eqvt tys ind simps funs ctxt = |
|
353 let |
|
354 val ([p], ctxt') = Variable.variant_fixes ["p"] ctxt; |
|
355 val p = Free (p, @{typ perm}) |
|
356 val simp_set = @{thms atom_eqvt permute_list.simps} @ simps @ all_eqvts ctxt' |
|
357 val tac = asm_full_simp_tac (HOL_ss addsimps simp_set) |
|
358 val ths_loc = prove_by_induct tys (build_eqvt_gl p) ind tac funs ctxt' |
|
359 val ths = Variable.export ctxt' ctxt ths_loc |
|
360 val add_eqvt = Attrib.internal (fn _ => Nominal_ThmDecls.eqvt_add) |
|
361 in |
|
362 (ths, snd (Local_Theory.note ((Binding.empty, [add_eqvt]), ths) ctxt)) |
|
363 end |
|
364 *} |
309 |
365 |
310 ML {* |
366 ML {* |
311 fun nominal_datatype2 dts bn_funs bn_eqs bclauses lthy = |
367 fun nominal_datatype2 dts bn_funs bn_eqs bclauses lthy = |
312 let |
368 let |
313 (* definition of the raw datatypes *) |
369 (* definition of the raw datatypes *) |
352 if get_STEPS lthy2 > 3 |
408 if get_STEPS lthy2 > 3 |
353 then define_raw_fvs descr sorts raw_bn_info raw_bclauses lthy3 |
409 then define_raw_fvs descr sorts raw_bn_info raw_bclauses lthy3 |
354 else raise TEST lthy3 |
410 else raise TEST lthy3 |
355 |
411 |
356 (* definition of raw alphas *) |
412 (* definition of raw alphas *) |
357 val (alpha_ts, alpha_bn_ts, alpha_intros, alpha_cases, alpha_induct, lthy4) = |
413 val (alpha_trms, alpha_bn_trms, alpha_intros, alpha_cases, alpha_induct, lthy4) = |
358 if get_STEPS lthy > 4 |
414 if get_STEPS lthy > 4 |
359 then define_raw_alpha descr sorts raw_bn_info raw_bclauses raw_fvs lthy3a |
415 then define_raw_alpha descr sorts raw_bn_info raw_bclauses raw_fvs lthy3a |
360 else raise TEST lthy3a |
416 else raise TEST lthy3a |
361 |
417 |
362 (* HERE *) |
418 (* definition of alpha-distinct lemmas *) |
|
419 val (alpha_distincts, alpha_bn_distincts) = |
|
420 mk_alpha_distincts lthy4 alpha_cases raw_constrs_distinct alpha_trms alpha_bn_trms raw_bn_info |
|
421 |
363 (* definition of raw_alpha_eq_iff lemmas *) |
422 (* definition of raw_alpha_eq_iff lemmas *) |
364 val rel_dists = flat (map (distinct_rel lthy4 alpha_cases) (rel_distinct ~~ alpha_ts)); |
|
365 val rel_dists_bn = flat (map (distinct_rel lthy4 alpha_cases) |
|
366 ((map (fn i => nth rel_distinct i) bn_nos) ~~ alpha_bn_ts)) |
|
367 |
|
368 val alpha_eq_iff = |
423 val alpha_eq_iff = |
369 if get_STEPS lthy > 5 |
424 if get_STEPS lthy > 5 |
370 then build_rel_inj alpha_intros (inject_thms @ distinct_thms) alpha_cases lthy4 |
425 then mk_alpha_eq_iff lthy4 alpha_intros distinct_thms inject_thms alpha_cases |
371 else raise TEST lthy4 |
426 else raise TEST lthy4 |
372 |
427 |
373 val alpha_eq_iff_simp = map remove_loop alpha_eq_iff; |
|
374 |
|
375 (* proving equivariance lemmas for bns, fvs and alpha *) |
428 (* proving equivariance lemmas for bns, fvs and alpha *) |
376 val _ = warning "Proving equivariance"; |
429 val _ = warning "Proving equivariance"; |
377 val (bv_eqvt, lthy5) = |
430 val (bv_eqvt, lthy5) = |
378 if get_STEPS lthy > 6 |
431 if get_STEPS lthy > 6 |
379 then prove_eqvt all_tys induct_thm (raw_bn_eqs @ raw_perm_defs) raw_bn_funs lthy4 |
432 then prove_eqvt all_tys induct_thm (raw_bn_eqs @ raw_perm_defs) raw_bn_funs lthy4 |
384 then prove_eqvt all_tys induct_thm (raw_fv_defs @ raw_perm_defs) (raw_fvs @ raw_fv_bns) lthy5 |
437 then prove_eqvt all_tys induct_thm (raw_fv_defs @ raw_perm_defs) (raw_fvs @ raw_fv_bns) lthy5 |
385 else raise TEST lthy5 |
438 else raise TEST lthy5 |
386 |
439 |
387 val (alpha_eqvt, lthy6a) = |
440 val (alpha_eqvt, lthy6a) = |
388 if get_STEPS lthy > 8 |
441 if get_STEPS lthy > 8 |
389 then Nominal_Eqvt.equivariance alpha_ts alpha_induct alpha_intros lthy6 |
442 then Nominal_Eqvt.equivariance alpha_trms alpha_induct alpha_intros lthy6 |
390 else raise TEST lthy6 |
443 else raise TEST lthy6 |
391 |
444 |
392 |
445 |
393 (* proving alpha equivalence *) |
446 (* proving alpha equivalence *) |
394 val _ = warning "Proving equivalence"; |
447 val _ = warning "Proving equivalence"; |
395 val fv_alpha_all = combine_fv_alpha_bns (raw_fvs, raw_fv_bns) (alpha_ts, alpha_bn_ts) bn_nos; |
448 val fv_alpha_all = combine_fv_alpha_bns (raw_fvs, raw_fv_bns) (alpha_trms, alpha_bn_trms) bn_nos; |
396 val reflps = build_alpha_refl fv_alpha_all alpha_ts induct_thm alpha_eq_iff_simp lthy6a; |
449 val reflps = build_alpha_refl fv_alpha_all alpha_trms induct_thm alpha_eq_iff lthy6a; |
397 val alpha_equivp = |
450 val alpha_equivp = |
398 if !cheat_equivp then map (equivp_hack lthy6a) alpha_ts |
451 if !cheat_equivp then map (equivp_hack lthy6a) alpha_trms |
399 else build_equivps alpha_ts reflps alpha_induct |
452 else build_equivps alpha_trms reflps alpha_induct |
400 inject_thms alpha_eq_iff_simp distinct_thms alpha_cases alpha_eqvt lthy6a; |
453 inject_thms alpha_eq_iff distinct_thms alpha_cases alpha_eqvt lthy6a; |
401 val qty_binds = map (fn (_, b, _, _) => b) dts; |
454 val qty_binds = map (fn (_, b, _, _) => b) dts; |
402 val qty_names = map Name.of_binding qty_binds; |
455 val qty_names = map Name.of_binding qty_binds; |
403 val qty_full_names = map (Long_Name.qualify thy_name) qty_names |
456 val qty_full_names = map (Long_Name.qualify thy_name) qty_names |
404 val (qtys, lthy7) = define_quotient_types qty_binds all_tys alpha_ts alpha_equivp lthy6a; |
457 val (qtys, lthy7) = define_quotient_types qty_binds all_tys alpha_trms alpha_equivp lthy6a; |
405 val const_names = map Name.of_binding (flat (map (fn (_, _, _, t) => map (fn (b, _, _) => b) t) dts)); |
458 val const_names = map Name.of_binding (flat (map (fn (_, _, _, t) => map (fn (b, _, _) => b) t) dts)); |
406 val raw_consts = |
459 val raw_consts = |
407 flat (map (fn (i, (_, _, l)) => |
460 flat (map (fn (i, (_, _, l)) => |
408 map (fn (cname, dts) => |
461 map (fn (cname, dts) => |
409 Const (cname, map (Datatype_Aux.typ_of_dtyp descr sorts) dts ---> |
462 Const (cname, map (Datatype_Aux.typ_of_dtyp descr sorts) dts ---> |
410 Datatype_Aux.typ_of_dtyp descr sorts (Datatype_Aux.DtRec i))) l) descr); |
463 Datatype_Aux.typ_of_dtyp descr sorts (Datatype_Aux.DtRec i))) l) descr); |
411 val (consts, const_defs, lthy8) = quotient_lift_consts_export qtys (const_names ~~ raw_consts) lthy7; |
464 val (consts, const_defs, lthy8) = quotient_lift_consts_export qtys (const_names ~~ raw_consts) lthy7; |
412 val _ = warning "Proving respects"; |
465 val _ = warning "Proving respects"; |
413 val bns_rsp_pre' = build_fvbv_rsps alpha_ts alpha_induct raw_bn_eqs (map fst bns) lthy8; |
466 val bns_rsp_pre' = build_fvbv_rsps alpha_trms alpha_induct raw_bn_eqs (map fst bns) lthy8; |
414 val (bns_rsp_pre, lthy9) = fold_map ( |
467 val (bns_rsp_pre, lthy9) = fold_map ( |
415 fn (bn_t, _) => prove_const_rsp qtys Binding.empty [bn_t] (fn _ => |
468 fn (bn_t, _) => prove_const_rsp qtys Binding.empty [bn_t] (fn _ => |
416 resolve_tac bns_rsp_pre' 1)) bns lthy8; |
469 resolve_tac bns_rsp_pre' 1)) bns lthy8; |
417 val bns_rsp = flat (map snd bns_rsp_pre); |
470 val bns_rsp = flat (map snd bns_rsp_pre); |
418 |
471 |
419 fun fv_rsp_tac _ = if !cheat_fv_rsp then Skip_Proof.cheat_tac thy |
472 fun fv_rsp_tac _ = if !cheat_fv_rsp then Skip_Proof.cheat_tac thy |
420 else fvbv_rsp_tac alpha_induct raw_fv_defs lthy8 1; |
473 else fvbv_rsp_tac alpha_induct raw_fv_defs lthy8 1; |
421 val fv_rsps = prove_fv_rsp fv_alpha_all alpha_ts fv_rsp_tac lthy9; |
474 val fv_rsps = prove_fv_rsp fv_alpha_all alpha_trms fv_rsp_tac lthy9; |
422 val (fv_rsp_pre, lthy10) = fold_map |
475 val (fv_rsp_pre, lthy10) = fold_map |
423 (fn fv => fn ctxt => prove_const_rsp qtys Binding.empty [fv] |
476 (fn fv => fn ctxt => prove_const_rsp qtys Binding.empty [fv] |
424 (fn _ => asm_simp_tac (HOL_ss addsimps fv_rsps) 1) ctxt) (raw_fvs @ raw_fv_bns) lthy9; |
477 (fn _ => asm_simp_tac (HOL_ss addsimps fv_rsps) 1) ctxt) (raw_fvs @ raw_fv_bns) lthy9; |
425 val fv_rsp = flat (map snd fv_rsp_pre); |
478 val fv_rsp = flat (map snd fv_rsp_pre); |
426 val (perms_rsp, lthy11) = prove_const_rsp qtys Binding.empty raw_perm_funs |
479 val (perms_rsp, lthy11) = prove_const_rsp qtys Binding.empty raw_perm_funs |
427 (fn _ => asm_simp_tac (HOL_ss addsimps alpha_eqvt) 1) lthy10; |
480 (fn _ => asm_simp_tac (HOL_ss addsimps alpha_eqvt) 1) lthy10; |
428 fun alpha_bn_rsp_tac _ = if !cheat_alpha_bn_rsp then Skip_Proof.cheat_tac thy |
481 fun alpha_bn_rsp_tac _ = if !cheat_alpha_bn_rsp then Skip_Proof.cheat_tac thy |
429 else |
482 else |
430 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_bn_ts lthy11 in asm_simp_tac (HOL_ss addsimps alpha_bn_rsp_pre) 1 end; |
483 let val alpha_bn_rsp_pre = prove_alpha_bn_rsp alpha_trms alpha_induct (alpha_eq_iff @ alpha_distincts @ alpha_bn_distincts) alpha_equivp exhaust_thms alpha_bn_trms lthy11 in asm_simp_tac (HOL_ss addsimps alpha_bn_rsp_pre) 1 end; |
431 val (alpha_bn_rsps, lthy11a) = fold_map (fn cnst => prove_const_rsp qtys Binding.empty [cnst] |
484 val (alpha_bn_rsps, lthy11a) = fold_map (fn cnst => prove_const_rsp qtys Binding.empty [cnst] |
432 alpha_bn_rsp_tac) alpha_bn_ts lthy11 |
485 alpha_bn_rsp_tac) alpha_bn_trms lthy11 |
433 fun const_rsp_tac _ = |
486 fun const_rsp_tac _ = |
434 let val alpha_alphabn = prove_alpha_alphabn alpha_ts alpha_induct alpha_eq_iff_simp alpha_bn_ts lthy11a |
487 let val alpha_alphabn = prove_alpha_alphabn alpha_trms alpha_induct alpha_eq_iff alpha_bn_trms lthy11a |
435 in constr_rsp_tac alpha_eq_iff_simp (fv_rsp @ bns_rsp @ reflps @ alpha_alphabn) 1 end |
488 in constr_rsp_tac alpha_eq_iff (fv_rsp @ bns_rsp @ reflps @ alpha_alphabn) 1 end |
436 val (const_rsps, lthy12) = fold_map (fn cnst => prove_const_rsp qtys Binding.empty [cnst] |
489 val (const_rsps, lthy12) = fold_map (fn cnst => prove_const_rsp qtys Binding.empty [cnst] |
437 const_rsp_tac) raw_consts lthy11a |
490 const_rsp_tac) raw_consts lthy11a |
438 val qfv_names = map (unsuffix "_raw" o Long_Name.base_name o fst o dest_Const) (raw_fvs @ raw_fv_bns) |
491 val qfv_names = map (unsuffix "_raw" o Long_Name.base_name o fst o dest_Const) (raw_fvs @ raw_fv_bns) |
439 val (qfv_ts, qfv_defs, lthy12a) = quotient_lift_consts_export qtys (qfv_names ~~ (raw_fvs @ raw_fv_bns)) lthy12; |
492 val (qfv_ts, qfv_defs, lthy12a) = quotient_lift_consts_export qtys (qfv_names ~~ (raw_fvs @ raw_fv_bns)) lthy12; |
440 val (qfv_ts_nobn, qfv_ts_bn) = chop (length raw_perm_funs) qfv_ts; |
493 val (qfv_ts_nobn, qfv_ts_bn) = chop (length raw_perm_funs) qfv_ts; |
441 val qbn_names = map (fn (b, _ , _) => Name.of_binding b) bn_funs |
494 val qbn_names = map (fn (b, _ , _) => Name.of_binding b) bn_funs |
442 val (qbn_ts, qbn_defs, lthy12b) = quotient_lift_consts_export qtys (qbn_names ~~ raw_bn_funs) lthy12a; |
495 val (qbn_ts, qbn_defs, lthy12b) = quotient_lift_consts_export qtys (qbn_names ~~ raw_bn_funs) lthy12a; |
443 val qalpha_bn_names = map (unsuffix "_raw" o Long_Name.base_name o fst o dest_Const) alpha_bn_ts |
496 val qalpha_bn_names = map (unsuffix "_raw" o Long_Name.base_name o fst o dest_Const) alpha_bn_trms |
444 val (qalpha_bn_ts, qalphabn_defs, lthy12c) = |
497 val (qalpha_bn_trms, qalphabn_defs, lthy12c) = |
445 quotient_lift_consts_export qtys (qalpha_bn_names ~~ alpha_bn_ts) lthy12b; |
498 quotient_lift_consts_export qtys (qalpha_bn_names ~~ alpha_bn_trms) lthy12b; |
446 val _ = warning "Lifting permutations"; |
499 val _ = warning "Lifting permutations"; |
447 val thy = Local_Theory.exit_global lthy12c; |
500 val thy = Local_Theory.exit_global lthy12c; |
448 val perm_names = map (fn x => "permute_" ^ x) qty_names |
501 val perm_names = map (fn x => "permute_" ^ x) qty_names |
449 val thy' = define_lifted_perms qtys qty_full_names (perm_names ~~ raw_perm_funs) raw_perm_simps thy; |
502 val thy' = define_lifted_perms qtys qty_full_names (perm_names ~~ raw_perm_funs) raw_perm_simps thy; |
450 val lthy13 = Theory_Target.init NONE thy'; |
503 val lthy13 = Theory_Target.init NONE thy'; |
468 val lthy16 = note_simp_suffix "fv" q_fv lthy15; |
521 val lthy16 = note_simp_suffix "fv" q_fv lthy15; |
469 val q_bn = map (lift_thm qtys lthy16) raw_bn_eqs; |
522 val q_bn = map (lift_thm qtys lthy16) raw_bn_eqs; |
470 val lthy17 = note_simp_suffix "bn" q_bn lthy16; |
523 val lthy17 = note_simp_suffix "bn" q_bn lthy16; |
471 val _ = warning "Lifting eq-iff"; |
524 val _ = warning "Lifting eq-iff"; |
472 (*val _ = map tracing (map PolyML.makestring alpha_eq_iff);*) |
525 (*val _ = map tracing (map PolyML.makestring alpha_eq_iff);*) |
473 val eq_iff_unfolded0 = map (Local_Defs.unfold lthy17 @{thms alphas}) alpha_eq_iff_simp |
526 val eq_iff_unfolded0 = map (Local_Defs.unfold lthy17 @{thms alphas}) alpha_eq_iff |
474 val eq_iff_unfolded1 = map (Local_Defs.unfold lthy17 @{thms Pair_eqvt}) eq_iff_unfolded0 |
527 val eq_iff_unfolded1 = map (Local_Defs.unfold lthy17 @{thms Pair_eqvt}) eq_iff_unfolded0 |
475 val q_eq_iff_pre0 = map (lift_thm qtys lthy17) eq_iff_unfolded1; |
528 val q_eq_iff_pre0 = map (lift_thm qtys lthy17) eq_iff_unfolded1; |
476 val q_eq_iff_pre1 = map (Local_Defs.fold lthy17 @{thms Pair_eqvt}) q_eq_iff_pre0 |
529 val q_eq_iff_pre1 = map (Local_Defs.fold lthy17 @{thms Pair_eqvt}) q_eq_iff_pre0 |
477 val q_eq_iff_pre2 = map (Local_Defs.fold lthy17 @{thms alphas}) q_eq_iff_pre1 |
530 val q_eq_iff_pre2 = map (Local_Defs.fold lthy17 @{thms alphas}) q_eq_iff_pre1 |
478 val q_eq_iff = map (Local_Defs.unfold lthy17 (Quotient_Info.id_simps_get lthy17)) q_eq_iff_pre2 |
531 val q_eq_iff = map (Local_Defs.unfold lthy17 (Quotient_Info.id_simps_get lthy17)) q_eq_iff_pre2 |
479 val (_, lthy18) = Local_Theory.note ((suffix_bind "eq_iff", []), q_eq_iff) lthy17; |
532 val (_, lthy18) = Local_Theory.note ((suffix_bind "eq_iff", []), q_eq_iff) lthy17; |
480 val q_dis = map (lift_thm qtys lthy18) rel_dists; |
533 val q_dis = map (lift_thm qtys lthy18) alpha_distincts; |
481 val lthy19 = note_simp_suffix "distinct" q_dis lthy18; |
534 val lthy19 = note_simp_suffix "distinct" q_dis lthy18; |
482 val q_eqvt = map (lift_thm qtys lthy19) (bv_eqvt @ fv_eqvt); |
535 val q_eqvt = map (lift_thm qtys lthy19) (bv_eqvt @ fv_eqvt); |
483 val (_, lthy20) = Local_Theory.note ((Binding.empty, |
536 val (_, lthy20) = Local_Theory.note ((Binding.empty, |
484 [Attrib.internal (fn _ => Nominal_ThmDecls.eqvt_add)]), q_eqvt) lthy19; |
537 [Attrib.internal (fn _ => Nominal_ThmDecls.eqvt_add)]), q_eqvt) lthy19; |
485 val _ = warning "Supports"; |
538 val _ = warning "Supports"; |