364 |
366 |
365 val (diss, lthy) = @{fold_map 2} (fn b => fn rhs => fn lthy => |
367 val (diss, lthy) = @{fold_map 2} (fn b => fn rhs => fn lthy => |
366 lift_def ld_no_notes (b, NoSyn) dis_qty rhs (K all_tac) [] lthy |
368 lift_def ld_no_notes (b, NoSyn) dis_qty rhs (K all_tac) [] lthy |
367 |> apfst (mk_lift_const_of_lift_def dis_qty)) dis_names dis_rhs lthy |
369 |> apfst (mk_lift_const_of_lift_def dis_qty)) dis_names dis_rhs lthy |
368 |
370 |
|
371 fun eq_onp_to_top_tac ctxt = SELECT_GOAL (Local_Defs.unfold_tac ctxt |
|
372 (@{thm eq_onp_top_eq_eq[symmetric]} :: Lifting_Info.get_relator_eq_onp_rules ctxt)) |
|
373 |
|
374 val unfold_lift_sel_rsp = @{lemma "(\<And>x. P1 x \<Longrightarrow> P2 (f x)) \<Longrightarrow> (rel_fun (eq_onp P1) (eq_onp P2)) f f" |
|
375 by (simp add: eq_onp_same_args rel_fun_eq_onp_rel)} |
|
376 |
369 fun lift_sel_tac exhaust_rule dt_rules wits ctxt i = |
377 fun lift_sel_tac exhaust_rule dt_rules wits ctxt i = |
370 (Method.insert_tac wits THEN' case_tac exhaust_rule ctxt THEN_ALL_NEW ( |
378 (Method.insert_tac wits THEN' |
371 EVERY' [hyp_subst_tac ctxt, Raw_Simplifier.rewrite_goal_tac ctxt (map safe_mk_meta_eq dt_rules), |
379 eq_onp_to_top_tac ctxt THEN' (* normalize *) |
|
380 rtac unfold_lift_sel_rsp THEN' |
|
381 case_tac exhaust_rule ctxt THEN_ALL_NEW ( |
|
382 EVERY' [hyp_subst_tac ctxt, (* does not kill wits because = was rewritten to eq_onp top *) |
|
383 Raw_Simplifier.rewrite_goal_tac ctxt (map safe_mk_meta_eq dt_rules), |
372 REPEAT_DETERM o etac conjE, atac])) i |
384 REPEAT_DETERM o etac conjE, atac])) i |
373 val pred_simps = Transfer.lookup_pred_data lthy (Tname rty) |> the |> Transfer.pred_simps |
385 val pred_simps = Transfer.lookup_pred_data lthy (Tname rty) |> the |> Transfer.pred_simps |
374 val sel_tac = lift_sel_tac (#exhaust ctr_sugar) (#case_thms ctr_sugar @ pred_simps) |
386 val sel_tac = lift_sel_tac (#exhaust ctr_sugar) (#case_thms ctr_sugar @ pred_simps) |
375 val sel_names = map (fn (k, xs) => map (fn k' => Binding.qualified true |
387 val sel_names = map (fn (k, xs) => map (fn k' => Binding.qualified true |
376 ("sel" ^ string_of_int k ^ string_of_int k') uTname) (1 upto length xs)) (ks ~~ ctr_Tss); |
388 ("sel" ^ string_of_int k ^ string_of_int k') uTname) (1 upto length xs)) (ks ~~ ctr_Tss); |
377 val (selss, lthy) = @{fold_map 2} (@{fold_map 2} (fn b => fn ((_, qty_ret), wits, rhs) => fn lthy => |
389 val (selss, lthy) = @{fold_map 2} (@{fold_map 2} (fn b => fn ((_, qty_ret), wits, rhs) => fn lthy => |
378 lift_def_code_dt { code_dt = true, lift_config = ld_no_notes } |
390 lift_def_code_dt { code_dt = true, lift_config = ld_no_notes } |
379 (b, NoSyn) (qty_isom --> qty_ret) rhs (HEADGOAL o sel_tac wits) [] lthy |
391 (b, NoSyn) (qty_isom --> qty_ret) rhs (HEADGOAL o sel_tac wits) [] lthy |
380 |> apfst (mk_lift_const_of_lift_def (qty_isom --> qty_ret)))) sel_names sel_rhs lthy |
392 |> apfst (mk_lift_const_of_lift_def (qty_isom --> qty_ret)))) sel_names sel_rhs lthy |
381 |
393 |
382 fun lift_isom_tac ctxt = Local_Defs.unfold_tac ctxt [id_apply] THEN HEADGOAL atac; |
394 fun lift_isom_tac ctxt = HEADGOAL (eq_onp_to_top_tac ctxt |
|
395 THEN' (rtac @{thm id_transfer})); |
383 |
396 |
384 val (rep_isom_lift_def, lthy) = lift_def ld_no_notes (Binding.qualified true "Rep_isom" uTname, NoSyn) |
397 val (rep_isom_lift_def, lthy) = lift_def ld_no_notes (Binding.qualified true "Rep_isom" uTname, NoSyn) |
385 (qty_isom --> qty) (HOLogic.id_const rty) lift_isom_tac [] lthy |
398 (qty_isom --> qty) (HOLogic.id_const rty) lift_isom_tac [] lthy |
386 |> apfst (inst_of_lift_def lthy (qty_isom --> qty)); |
399 |> apfst (inst_of_lift_def lthy (qty_isom --> qty)); |
387 val (abs_isom, lthy) = lift_def ld_no_notes (Binding.qualified true "Abs_isom" uTname, NoSyn) |
400 val (abs_isom, lthy) = lift_def ld_no_notes (Binding.qualified true "Abs_isom" uTname, NoSyn) |
388 (qty --> qty_isom) (HOLogic.id_const rty) lift_isom_tac [] lthy |
401 (qty --> qty_isom) (HOLogic.id_const rty) lift_isom_tac [] lthy |
389 |> apfst (mk_lift_const_of_lift_def (qty --> qty_isom)); |
402 |> apfst (mk_lift_const_of_lift_def (qty --> qty_isom)); |
390 |
|
391 fun mk_type_definition newT oldT RepC AbsC A = |
403 fun mk_type_definition newT oldT RepC AbsC A = |
392 let |
404 let |
393 val typedefC = |
405 val typedefC = |
394 Const (@{const_name type_definition}, |
406 Const (@{const_name type_definition}, |
395 (newT --> oldT) --> (oldT --> newT) --> HOLogic.mk_setT oldT --> HOLogic.boolT); |
407 (newT --> oldT) --> (oldT --> newT) --> HOLogic.mk_setT oldT --> HOLogic.boolT); |
396 in typedefC $ RepC $ AbsC $ A end; |
408 in typedefC $ RepC $ AbsC $ A end; |
397 |
409 |
398 val rep_isom = lift_const_of_lift_def rep_isom_lift_def |
410 val rep_isom = lift_const_of_lift_def rep_isom_lift_def |
399 val typedef_goal = mk_type_definition qty_isom qty rep_isom abs_isom (HOLogic.mk_UNIV qty) |> |
411 val typedef_goal = mk_type_definition qty_isom qty rep_isom abs_isom (HOLogic.mk_UNIV qty) |> |
400 HOLogic.mk_Trueprop; |
412 HOLogic.mk_Trueprop; |
401 |
413 fun typ_isom_tac ctxt i = |
402 fun typ_isom_tac ctxt i = |
414 EVERY' [ SELECT_GOAL (Local_Defs.unfold_tac ctxt @{thms type_definition_def}), |
403 EVERY' [ SELECT_GOAL (Local_Defs.unfold_tac ctxt @{thms type_definition_def}), |
415 DETERM o Transfer.transfer_tac true ctxt, |
404 DETERM o Transfer.transfer_tac true ctxt, Raw_Simplifier.rewrite_goal_tac ctxt |
416 SELECT_GOAL (Local_Defs.unfold_tac ctxt @{thms eq_onp_top_eq_eq}) (* normalize *), |
405 (map safe_mk_meta_eq @{thms id_apply simp_thms Ball_def}), |
417 Raw_Simplifier.rewrite_goal_tac ctxt |
406 rtac TrueI] i; |
418 (map safe_mk_meta_eq @{thms id_apply simp_thms Ball_def}), |
|
419 rtac TrueI] i; |
407 |
420 |
408 val (_, transfer_lthy) = Proof_Context.note_thmss "" [((Binding.empty, []), |
421 val (_, transfer_lthy) = Proof_Context.note_thmss "" [((Binding.empty, []), |
409 [(@{thms right_total_UNIV_transfer},[Transfer.transfer_add]), |
422 [(@{thms right_total_UNIV_transfer},[Transfer.transfer_add]), |
410 (@{thms Domain_eq_top}, [Transfer.transfer_domain_add]) ])] lthy; |
423 (@{thms Domain_eq_top}, [Transfer.transfer_domain_add]) ])] lthy; |
411 |
424 |
412 val quot_thm_isom = Goal.prove_sorry transfer_lthy [] [] typedef_goal |
425 val quot_thm_isom = Goal.prove_sorry transfer_lthy [] [] typedef_goal |
413 (fn {context = ctxt, prems = _} => typ_isom_tac ctxt 1) |
426 (fn {context = ctxt, prems = _} => typ_isom_tac ctxt 1) |
414 |> Thm.close_derivation |
427 |> Thm.close_derivation |
415 |> singleton (Variable.export transfer_lthy lthy) |
428 |> singleton (Variable.export transfer_lthy lthy) |
416 |> (fn thm => @{thm UNIV_typedef_to_Quotient} OF [thm, @{thm reflexive}]) |
429 |> (fn thm => @{thm UNIV_typedef_to_Quotient} OF [thm, @{thm reflexive}]) |
417 |
|
418 val qty_isom_name = Tname qty_isom; |
430 val qty_isom_name = Tname qty_isom; |
419 |
431 |
420 val quot_isom_rep = |
432 val quot_isom_rep = |
421 let |
433 let |
422 val (quotients : Lifting_Term.quotients) = Symtab.insert (Lifting_Info.quotient_eq) (qty_isom_name, |
434 val (quotients : Lifting_Term.quotients) = Symtab.insert (Lifting_Info.quotient_eq) (qty_isom_name, |
423 {quot_thm = quot_thm_isom, pcr_info = NONE}) Symtab.empty |
435 {quot_thm = quot_thm_isom, pcr_info = NONE}) Symtab.empty |
424 val id_actions = { constr = K I, lift = K I, comp_lift = K I } |
436 val id_actions = { constr = K I, lift = K I, comp_lift = K I } |
520 val pred = quot_thm_rel quot_thm |> dest_comb |> snd; |
532 val pred = quot_thm_rel quot_thm |> dest_comb |> snd; |
521 val (pred, lthy) = yield_singleton (Variable.import_terms true) pred lthy; |
533 val (pred, lthy) = yield_singleton (Variable.import_terms true) pred lthy; |
522 val TFrees = Term.add_tfreesT qty [] |
534 val TFrees = Term.add_tfreesT qty [] |
523 |
535 |
524 fun non_empty_typedef_tac non_empty_pred ctxt i = |
536 fun non_empty_typedef_tac non_empty_pred ctxt i = |
525 (SELECT_GOAL (Local_Defs.unfold_tac ctxt [mem_Collect_eq]) THEN' rtac non_empty_pred) i |
537 (Method.insert_tac [non_empty_pred] THEN' |
526 |
538 SELECT_GOAL (Local_Defs.unfold_tac ctxt [mem_Collect_eq]) THEN' atac) i |
527 val uTname = unique_Tname (rty, qty) |
539 val uTname = unique_Tname (rty, qty) |
528 val Tdef_set = HOLogic.mk_Collect ("x", rty, pred $ Free("x", rty)); |
540 val Tdef_set = HOLogic.mk_Collect ("x", rty, pred $ Free("x", rty)); |
529 val ((_, tcode_dt), lthy) = conceal_naming_result (typedef (Binding.concealed uTname, TFrees, NoSyn) |
541 val ((_, tcode_dt), lthy) = conceal_naming_result (typedef (Binding.concealed uTname, TFrees, NoSyn) |
530 Tdef_set NONE (fn lthy => non_empty_typedef_tac non_empty_pred lthy 1)) lthy; |
542 Tdef_set NONE (fn lthy => HEADGOAL (non_empty_typedef_tac non_empty_pred lthy))) lthy; |
531 val type_definition_thm = tcode_dt |> snd |> #type_definition; |
543 val type_definition_thm = tcode_dt |> snd |> #type_definition; |
532 val qty_isom = tcode_dt |> fst |> #abs_type; |
544 val qty_isom = tcode_dt |> fst |> #abs_type; |
533 |
545 |
534 val config = { notes = false} |
546 val config = { notes = false} |
535 val (binding, lthy) = conceal_naming_result (Lifting_Setup.setup_by_typedef_thm |
547 val (binding, lthy) = conceal_naming_result (Lifting_Setup.setup_by_typedef_thm |
574 |
586 |
575 lift_definition command. It opens a proof of a corresponding respectfulness |
587 lift_definition command. It opens a proof of a corresponding respectfulness |
576 theorem in a user-friendly, readable form. Then add_lift_def_code_dt is called internally. |
588 theorem in a user-friendly, readable form. Then add_lift_def_code_dt is called internally. |
577 |
589 |
578 **) |
590 **) |
|
591 |
|
592 local |
|
593 val eq_onp_assms_tac_fixed_rules = map (Transfer.prep_transfer_domain_thm @{context}) |
|
594 [@{thm pcr_Domainp_total}, @{thm pcr_Domainp_par_left_total}, @{thm pcr_Domainp_par}, |
|
595 @{thm pcr_Domainp}] |
|
596 in |
|
597 fun mk_readable_rsp_thm_eq tm lthy = |
|
598 let |
|
599 val ctm = Thm.cterm_of lthy tm |
|
600 |
|
601 fun assms_rewr_conv tactic rule ct = |
|
602 let |
|
603 fun prove_extra_assms thm = |
|
604 let |
|
605 val assms = cprems_of thm |
|
606 fun finish thm = if Thm.no_prems thm then SOME (Goal.conclude thm) else NONE |
|
607 fun prove ctm = Option.mapPartial finish (SINGLE tactic (Goal.init ctm)) |
|
608 in |
|
609 map_interrupt prove assms |
|
610 end |
|
611 |
|
612 fun cconl_of thm = Drule.strip_imp_concl (Thm.cprop_of thm) |
|
613 fun lhs_of thm = fst (Thm.dest_equals (cconl_of thm)) |
|
614 fun rhs_of thm = snd (Thm.dest_equals (cconl_of thm)) |
|
615 val rule1 = Thm.incr_indexes (Thm.maxidx_of_cterm ct + 1) rule; |
|
616 val lhs = lhs_of rule1; |
|
617 val rule2 = Thm.rename_boundvars (Thm.term_of lhs) (Thm.term_of ct) rule1; |
|
618 val rule3 = |
|
619 Thm.instantiate (Thm.match (lhs, ct)) rule2 |
|
620 handle Pattern.MATCH => raise CTERM ("assms_rewr_conv", [lhs, ct]); |
|
621 val proved_assms = prove_extra_assms rule3 |
|
622 in |
|
623 case proved_assms of |
|
624 SOME proved_assms => |
|
625 let |
|
626 val rule3 = proved_assms MRSL rule3 |
|
627 val rule4 = |
|
628 if lhs_of rule3 aconvc ct then rule3 |
|
629 else |
|
630 let val ceq = Thm.dest_fun2 (Thm.cprop_of rule3) |
|
631 in rule3 COMP Thm.trivial (Thm.mk_binop ceq ct (rhs_of rule3)) end |
|
632 in Thm.transitive rule4 (Thm.beta_conversion true (rhs_of rule4)) end |
|
633 | NONE => Conv.no_conv ct |
|
634 end |
|
635 |
|
636 fun assms_rewrs_conv tactic rules = Conv.first_conv (map (assms_rewr_conv tactic) rules) |
|
637 |
|
638 fun simp_arrows_conv ctm = |
|
639 let |
|
640 val unfold_conv = Conv.rewrs_conv |
|
641 [@{thm rel_fun_eq_eq_onp[THEN eq_reflection]}, |
|
642 @{thm rel_fun_eq_onp_rel[THEN eq_reflection]}, |
|
643 @{thm rel_fun_eq[THEN eq_reflection]}, |
|
644 @{thm rel_fun_eq_rel[THEN eq_reflection]}, |
|
645 @{thm rel_fun_def[THEN eq_reflection]}] |
|
646 fun binop_conv2 cv1 cv2 = Conv.combination_conv (Conv.arg_conv cv1) cv2 |
|
647 val eq_onp_assms_tac_rules = @{thm left_unique_OO} :: |
|
648 eq_onp_assms_tac_fixed_rules @ (Transfer.get_transfer_raw lthy) |
|
649 val intro_top_rule = @{thm eq_onp_top_eq_eq[symmetric, THEN eq_reflection]} |
|
650 val kill_tops = Transfer.top_sweep_rewr_conv [@{thm eq_onp_top_eq_eq[THEN eq_reflection]}] |
|
651 val eq_onp_assms_tac = (CONVERSION kill_tops THEN' |
|
652 TRY o REPEAT_ALL_NEW (resolve_tac lthy eq_onp_assms_tac_rules) |
|
653 THEN_ALL_NEW (DETERM o Transfer.eq_tac lthy)) 1 |
|
654 val relator_eq_onp_conv = Conv.bottom_conv |
|
655 (K (Conv.try_conv (assms_rewrs_conv eq_onp_assms_tac |
|
656 (intro_top_rule :: Lifting_Info.get_relator_eq_onp_rules lthy)))) lthy |
|
657 then_conv kill_tops |
|
658 val relator_eq_conv = Conv.bottom_conv |
|
659 (K (Conv.try_conv (Conv.rewrs_conv (Transfer.get_relator_eq lthy)))) lthy |
|
660 in |
|
661 case (Thm.term_of ctm) of |
|
662 Const (@{const_name "rel_fun"}, _) $ _ $ _ => |
|
663 (binop_conv2 simp_arrows_conv simp_arrows_conv then_conv unfold_conv) ctm |
|
664 | _ => (relator_eq_onp_conv then_conv relator_eq_conv) ctm |
|
665 end |
|
666 |
|
667 val unfold_ret_val_invs = Conv.bottom_conv |
|
668 (K (Conv.try_conv (Conv.rewr_conv @{thm eq_onp_same_args[THEN eq_reflection]}))) lthy |
|
669 val unfold_inv_conv = |
|
670 Conv.top_sweep_conv (K (Conv.rewr_conv @{thm eq_onp_def[THEN eq_reflection]})) lthy |
|
671 val simp_conv = HOLogic.Trueprop_conv (Conv.fun2_conv simp_arrows_conv) |
|
672 val univq_conv = Conv.rewr_conv @{thm HOL.all_simps(6)[symmetric, THEN eq_reflection]} |
|
673 val univq_prenex_conv = Conv.top_conv (K (Conv.try_conv univq_conv)) lthy |
|
674 val beta_conv = Thm.beta_conversion true |
|
675 val eq_thm = |
|
676 (simp_conv then_conv univq_prenex_conv then_conv beta_conv then_conv unfold_ret_val_invs |
|
677 then_conv unfold_inv_conv) ctm |
|
678 in |
|
679 Object_Logic.rulify lthy (eq_thm RS Drule.equal_elim_rule2) |
|
680 end |
|
681 end |
|
682 |
|
683 fun rename_to_tnames ctxt term = |
|
684 let |
|
685 fun all_typs (Const (@{const_name Pure.all}, _) $ Abs (_, T, t)) = T :: all_typs t |
|
686 | all_typs _ = [] |
|
687 |
|
688 fun rename (Const (@{const_name Pure.all}, T1) $ Abs (_, T2, t)) (new_name :: names) = |
|
689 (Const (@{const_name Pure.all}, T1) $ Abs (new_name, T2, rename t names)) |
|
690 | rename t _ = t |
|
691 |
|
692 val (fixed_def_t, _) = yield_singleton (Variable.importT_terms) term ctxt |
|
693 val new_names = Old_Datatype_Prop.make_tnames (all_typs fixed_def_t) |
|
694 in |
|
695 rename term new_names |
|
696 end |
579 |
697 |
580 fun lift_def_cmd (params, raw_var, rhs_raw, par_xthms) lthy = |
698 fun lift_def_cmd (params, raw_var, rhs_raw, par_xthms) lthy = |
581 let |
699 let |
582 val config = evaluate_params params |
700 val config = evaluate_params params |
583 val ((binding, SOME qty, mx), lthy) = yield_singleton Proof_Context.read_vars raw_var lthy |
701 val ((binding, SOME qty, mx), lthy) = yield_singleton Proof_Context.read_vars raw_var lthy |
584 val var = (binding, mx) |
702 val var = (binding, mx) |
585 val rhs = (Syntax.check_term lthy o Syntax.parse_term lthy) rhs_raw |
703 val rhs = (Syntax.check_term lthy o Syntax.parse_term lthy) rhs_raw |
586 val par_thms = Attrib.eval_thms lthy par_xthms |
704 val par_thms = Attrib.eval_thms lthy par_xthms |
587 val (goal, after_qed) = prepare_lift_def (add_lift_def_code_dt config) var qty rhs par_thms lthy |
705 val (goal, after_qed) = prepare_lift_def (add_lift_def_code_dt config) var qty rhs par_thms lthy |
|
706 val (goal, after_qed) = |
|
707 case goal of |
|
708 NONE => (goal, K (after_qed Drule.dummy_thm)) |
|
709 | SOME prsp_tm => |
|
710 let |
|
711 val readable_rsp_thm_eq = mk_readable_rsp_thm_eq prsp_tm lthy |
|
712 val (readable_rsp_tm, _) = Logic.dest_implies (Thm.prop_of readable_rsp_thm_eq) |
|
713 val readable_rsp_tm_tnames = rename_to_tnames lthy readable_rsp_tm |
|
714 |
|
715 fun after_qed' [[thm]] lthy = |
|
716 let |
|
717 val internal_rsp_thm = Goal.prove lthy [] [] prsp_tm |
|
718 (fn {context = ctxt, ...} => |
|
719 rtac readable_rsp_thm_eq 1 THEN Proof_Context.fact_tac ctxt [thm] 1) |
|
720 in |
|
721 after_qed internal_rsp_thm lthy |
|
722 end |
|
723 in |
|
724 (SOME readable_rsp_tm_tnames, after_qed') |
|
725 end |
588 in |
726 in |
589 Proof.theorem NONE (snd oo after_qed) [map (rpair []) (the_list goal)] lthy |
727 Proof.theorem NONE (snd oo after_qed) [map (rpair []) (the_list goal)] lthy |
590 end |
728 end |
591 |
729 |
592 fun quot_thm_err ctxt (rty, qty) pretty_msg = |
730 fun quot_thm_err ctxt (rty, qty) pretty_msg = |