25 (BNF_Def.bnf * (typ list * typ list)) * ((comp_cache * unfold_set) * Proof.context) |
25 (BNF_Def.bnf * (typ list * typ list)) * ((comp_cache * unfold_set) * Proof.context) |
26 val default_comp_sort: (string * sort) list list -> (string * sort) list |
26 val default_comp_sort: (string * sort) list list -> (string * sort) list |
27 val normalize_bnfs: (int -> binding -> binding) -> ''a list list -> ''a list -> |
27 val normalize_bnfs: (int -> binding -> binding) -> ''a list list -> ''a list -> |
28 (''a list list -> ''a list) -> BNF_Def.bnf list -> unfold_set -> Proof.context -> |
28 (''a list list -> ''a list) -> BNF_Def.bnf list -> unfold_set -> Proof.context -> |
29 (int list list * ''a list) * (BNF_Def.bnf list * (unfold_set * Proof.context)) |
29 (int list list * ''a list) * (BNF_Def.bnf list * (unfold_set * Proof.context)) |
|
30 |
|
31 type absT_info = |
|
32 {absT: typ, |
|
33 repT: typ, |
|
34 abs: term, |
|
35 rep: term, |
|
36 abs_inject: thm, |
|
37 abs_inverse: thm, |
|
38 type_definition: thm} |
|
39 |
|
40 val morph_absT_info: morphism -> absT_info -> absT_info |
|
41 val mk_absT: theory -> typ -> typ -> typ -> typ |
|
42 val mk_repT: typ -> typ -> typ -> typ |
|
43 val mk_abs: typ -> term -> term |
|
44 val mk_rep: typ -> term -> term |
30 val seal_bnf: (binding -> binding) -> unfold_set -> binding -> typ list -> BNF_Def.bnf -> |
45 val seal_bnf: (binding -> binding) -> unfold_set -> binding -> typ list -> BNF_Def.bnf -> |
31 Proof.context -> (BNF_Def.bnf * typ list) * local_theory |
46 Proof.context -> (BNF_Def.bnf * (typ list * absT_info)) * local_theory |
32 end; |
47 end; |
33 |
48 |
34 structure BNF_Comp : BNF_COMP = |
49 structure BNF_Comp : BNF_COMP = |
35 struct |
50 struct |
36 |
51 |
570 (clean_compose_bnf const_policy (qualify 0) b outer inners' (unfold_set', lthy')) |
585 (clean_compose_bnf const_policy (qualify 0) b outer inners' (unfold_set', lthy')) |
571 end; |
586 end; |
572 |
587 |
573 (* Hide the type of the bound (optimization) and unfold the definitions (nicer to the user) *) |
588 (* Hide the type of the bound (optimization) and unfold the definitions (nicer to the user) *) |
574 |
589 |
|
590 type absT_info = |
|
591 {absT: typ, |
|
592 repT: typ, |
|
593 abs: term, |
|
594 rep: term, |
|
595 abs_inject: thm, |
|
596 abs_inverse: thm, |
|
597 type_definition: thm}; |
|
598 |
|
599 fun morph_absT_info phi |
|
600 {absT, repT, abs, rep, abs_inject, abs_inverse, type_definition} = |
|
601 {absT = Morphism.typ phi absT, |
|
602 repT = Morphism.typ phi repT, |
|
603 abs = Morphism.term phi abs, |
|
604 rep = Morphism.term phi rep, |
|
605 abs_inject = Morphism.thm phi abs_inject, |
|
606 abs_inverse = Morphism.thm phi abs_inverse, |
|
607 type_definition = Morphism.thm phi type_definition}; |
|
608 |
|
609 fun mk_absT thy repT absT repU = |
|
610 let val rho = Vartab.fold (cons o apsnd snd) (Sign.typ_match thy (repT, repU) Vartab.empty) []; |
|
611 in Term.typ_subst_TVars rho absT end; |
|
612 |
|
613 fun mk_repT (t as Type (C, Ts)) repT (u as Type (C', Us)) = |
|
614 if C = C' andalso length Ts = length Us then Term.typ_subst_atomic (Ts ~~ Us) repT |
|
615 else raise Term.TYPE ("mk_repT", [t, repT, u], []) |
|
616 | mk_repT t repT u = raise Term.TYPE ("mk_repT", [t, repT, u], []); |
|
617 |
|
618 fun mk_abs_or_rep getT (Type (_, Us)) abs = |
|
619 let val Ts = snd (dest_Type (getT (fastype_of abs))) |
|
620 in Term.subst_atomic_types (Ts ~~ Us) abs end; |
|
621 |
|
622 val mk_abs = mk_abs_or_rep range_type; |
|
623 val mk_rep = mk_abs_or_rep domain_type; |
|
624 |
575 fun seal_bnf qualify (unfold_set : unfold_set) b Ds bnf lthy = |
625 fun seal_bnf qualify (unfold_set : unfold_set) b Ds bnf lthy = |
576 let |
626 let |
577 val live = live_of_bnf bnf; |
627 val live = live_of_bnf bnf; |
578 val nwits = nwits_of_bnf bnf; |
628 val nwits = nwits_of_bnf bnf; |
579 |
629 |
580 val (As, lthy1) = apfst (map TFree) |
630 val (As, lthy1) = apfst (map TFree) |
581 (Variable.invent_types (replicate live HOLogic.typeS) (fold Variable.declare_typ Ds lthy)); |
631 (Variable.invent_types (replicate live HOLogic.typeS) (fold Variable.declare_typ Ds lthy)); |
582 val (Bs, _) = apfst (map TFree) |
632 val (Bs, _) = apfst (map TFree) |
583 (Variable.invent_types (replicate live HOLogic.typeS) lthy1); |
633 (Variable.invent_types (replicate live HOLogic.typeS) lthy1); |
|
634 |
|
635 val (((fs, fs'), (Rs, Rs')), _(*names_lthy*)) = lthy |
|
636 |> mk_Frees' "f" (map2 (curry op -->) As Bs) |
|
637 ||>> mk_Frees' "R" (map2 mk_pred2T As Bs) |
584 |
638 |
585 val map_unfolds = #map_unfolds unfold_set; |
639 val map_unfolds = #map_unfolds unfold_set; |
586 val set_unfoldss = #set_unfoldss unfold_set; |
640 val set_unfoldss = #set_unfoldss unfold_set; |
587 val rel_unfolds = #rel_unfolds unfold_set; |
641 val rel_unfolds = #rel_unfolds unfold_set; |
588 |
642 |
594 fold expand_term_const (map (single o Logic.dest_equals o Thm.prop_of) rel_unfolds); |
648 fold expand_term_const (map (single o Logic.dest_equals o Thm.prop_of) rel_unfolds); |
595 fun unfold_maps ctxt = fold (unfold_thms ctxt o single) map_unfolds; |
649 fun unfold_maps ctxt = fold (unfold_thms ctxt o single) map_unfolds; |
596 fun unfold_sets ctxt = fold (unfold_thms ctxt) set_unfoldss; |
650 fun unfold_sets ctxt = fold (unfold_thms ctxt) set_unfoldss; |
597 fun unfold_rels ctxt = unfold_thms ctxt rel_unfolds; |
651 fun unfold_rels ctxt = unfold_thms ctxt rel_unfolds; |
598 fun unfold_all ctxt = unfold_sets ctxt o unfold_maps ctxt o unfold_rels ctxt; |
652 fun unfold_all ctxt = unfold_sets ctxt o unfold_maps ctxt o unfold_rels ctxt; |
599 val bnf_map = expand_maps (mk_map_of_bnf Ds As Bs bnf); |
653 |
600 val bnf_sets = map (expand_maps o expand_sets) |
654 val repTA = mk_T_of_bnf Ds As bnf; |
|
655 val repTB = mk_T_of_bnf Ds Bs bnf; |
|
656 val T_bind = qualify b; |
|
657 val TA_params = Term.add_tfreesT repTA []; |
|
658 val TB_params = Term.add_tfreesT repTB []; |
|
659 val ((T_name, (T_glob_info, T_loc_info)), lthy) = |
|
660 typedef (T_bind, TA_params, NoSyn) |
|
661 (HOLogic.mk_UNIV repTA) NONE (EVERY' [rtac exI, rtac UNIV_I] 1) lthy; |
|
662 val TA = Type (T_name, map TFree TA_params); |
|
663 val TB = Type (T_name, map TFree TB_params); |
|
664 val RepA = Const (#Rep_name T_glob_info, TA --> repTA); |
|
665 val RepB = Const (#Rep_name T_glob_info, TB --> repTB); |
|
666 val AbsA = Const (#Abs_name T_glob_info, repTA --> TA); |
|
667 val AbsB = Const (#Abs_name T_glob_info, repTB --> TB); |
|
668 val typedef_thm = #type_definition T_loc_info; |
|
669 val Abs_inject' = #Abs_inject T_loc_info OF @{thms UNIV_I UNIV_I}; |
|
670 val Abs_inverse' = #Abs_inverse T_loc_info OF @{thms UNIV_I}; |
|
671 |
|
672 val absT_info = {absT = TA, repT = repTA, abs = AbsA, rep = RepA, abs_inject = Abs_inject', |
|
673 abs_inverse = Abs_inverse', type_definition = typedef_thm}; |
|
674 |
|
675 val bnf_map = fold_rev Term.absfree fs' (HOLogic.mk_comp (HOLogic.mk_comp (AbsB, |
|
676 Term.list_comb (expand_maps (mk_map_of_bnf Ds As Bs bnf), fs)), RepA)); |
|
677 val bnf_sets = map ((fn t => HOLogic.mk_comp (t, RepA)) o expand_maps o expand_sets) |
601 (mk_sets_of_bnf (replicate live Ds) (replicate live As) bnf); |
678 (mk_sets_of_bnf (replicate live Ds) (replicate live As) bnf); |
602 val bnf_bd = mk_bd_of_bnf Ds As bnf; |
679 val bnf_bd = mk_bd_of_bnf Ds As bnf; |
603 val bnf_rel = expand_rels (mk_rel_of_bnf Ds As Bs bnf); |
680 val bnf_rel = fold_rev Term.absfree Rs' (mk_vimage2p RepA RepB $ |
604 val T = mk_T_of_bnf Ds As bnf; |
681 (Term.list_comb (expand_rels (mk_rel_of_bnf Ds As Bs bnf), Rs))); |
605 |
682 |
606 (*bd may depend only on dead type variables*) |
683 (*bd may depend only on dead type variables*) |
607 val bd_repT = fst (dest_relT (fastype_of bnf_bd)); |
684 val bd_repT = fst (dest_relT (fastype_of bnf_bd)); |
608 val bdT_bind = qualify (Binding.suffix_name ("_" ^ bdTN) b); |
685 val bdT_bind = qualify (Binding.suffix_name ("_" ^ bdTN) b); |
609 val params = Term.add_tfreesT bd_repT []; |
686 val params = Term.add_tfreesT bd_repT []; |
624 val bd_card_order = |
701 val bd_card_order = |
625 @{thm card_order_dir_image} OF [Abs_bdT_bij, bd_card_order_of_bnf bnf]; |
702 @{thm card_order_dir_image} OF [Abs_bdT_bij, bd_card_order_of_bnf bnf]; |
626 val bd_cinfinite = |
703 val bd_cinfinite = |
627 (@{thm Cinfinite_cong} OF [bd_ordIso, bd_Cinfinite_of_bnf bnf]) RS conjunct1; |
704 (@{thm Cinfinite_cong} OF [bd_ordIso, bd_Cinfinite_of_bnf bnf]) RS conjunct1; |
628 |
705 |
629 val set_bds = |
706 fun map_id0_tac ctxt = |
630 map (fn thm => @{thm ordLeq_ordIso_trans} OF [thm, bd_ordIso]) (set_bd_of_bnf bnf); |
707 rtac (@{thm type_copy_map_id0} OF [typedef_thm, unfold_maps ctxt (map_id0_of_bnf bnf)]) 1; |
631 |
708 fun map_comp0_tac ctxt = |
632 fun mk_tac thm ctxt = |
709 rtac (@{thm type_copy_map_comp0} OF [typedef_thm, unfold_maps ctxt (map_comp0_of_bnf bnf)]) 1; |
633 (rtac (unfold_all ctxt thm) THEN' |
710 fun map_cong0_tac ctxt = |
634 SOLVE o REPEAT_DETERM o (atac ORELSE' Goal.assume_rule_tac ctxt)) 1; |
711 EVERY' (rtac @{thm type_copy_map_cong0} :: rtac (unfold_all ctxt (map_cong0_of_bnf bnf)) :: |
635 |
712 map (fn i => EVERY' [select_prem_tac live (dtac meta_spec) i, etac meta_mp, |
636 val tacs = zip_axioms (mk_tac (map_id0_of_bnf bnf)) (mk_tac (map_comp0_of_bnf bnf)) |
713 etac (o_apply RS equalityD2 RS set_mp)]) (1 upto live)) 1; |
637 (mk_tac (map_cong0_of_bnf bnf)) (map mk_tac (set_map0_of_bnf bnf)) |
714 fun set_map0_tac thm ctxt = |
638 (K (rtac bd_card_order 1)) (K (rtac bd_cinfinite 1)) (map mk_tac set_bds) |
715 rtac (@{thm type_copy_set_map0} OF [typedef_thm, unfold_all ctxt thm]) 1; |
639 (mk_tac (le_rel_OO_of_bnf bnf)) |
716 val set_bd_tacs = map (fn thm => fn ctxt => rtac (@{thm ordLeq_ordIso_trans} OF |
640 (mk_tac (rel_OO_Grp_of_bnf bnf)); |
717 [unfold_sets ctxt thm, bd_ordIso] RS @{thm type_copy_set_bd}) 1) |
641 |
718 (set_bd_of_bnf bnf); |
642 val bnf_wits = map snd (mk_wits_of_bnf (replicate nwits Ds) (replicate nwits As) bnf); |
719 fun le_rel_OO_tac ctxt = |
643 |
720 rtac (unfold_rels ctxt (le_rel_OO_of_bnf bnf) RS @{thm vimage2p_relcompp_mono}) 1; |
644 fun wit_tac ctxt = |
721 fun rel_OO_Grp_tac ctxt = |
|
722 (rtac (unfold_all ctxt (rel_OO_Grp_of_bnf bnf) RS @{thm vimage2p_cong} RS trans) THEN' |
|
723 SELECT_GOAL (unfold_thms_tac ctxt [o_apply, typedef_thm RS @{thm type_copy_vimage2p_Grp_Rep}, |
|
724 typedef_thm RS @{thm vimage2p_relcompp_converse}]) THEN' rtac refl) 1; |
|
725 |
|
726 val tacs = zip_axioms map_id0_tac map_comp0_tac map_cong0_tac |
|
727 (map set_map0_tac (set_map0_of_bnf bnf)) (K (rtac bd_card_order 1)) (K (rtac bd_cinfinite 1)) |
|
728 set_bd_tacs le_rel_OO_tac rel_OO_Grp_tac; |
|
729 |
|
730 val bnf_wits = map (fn (I, t) => |
|
731 fold Term.absdummy (map (nth As) I) |
|
732 (AbsA $ Term.list_comb (t, map Bound (0 upto length I - 1)))) |
|
733 (mk_wits_of_bnf (replicate nwits Ds) (replicate nwits As) bnf); |
|
734 |
|
735 fun wit_tac ctxt = ALLGOALS (dtac (typedef_thm RS @{thm type_copy_wit})) THEN |
645 mk_simple_wit_tac (map (unfold_all ctxt) (wit_thms_of_bnf bnf)); |
736 mk_simple_wit_tac (map (unfold_all ctxt) (wit_thms_of_bnf bnf)); |
646 |
737 |
647 val (bnf', lthy') = |
738 val (bnf', lthy') = |
648 bnf_def Hardly_Inline (user_policy Dont_Note) qualify tacs wit_tac (SOME all_deads) |
739 bnf_def Hardly_Inline (user_policy Dont_Note) qualify tacs wit_tac (SOME all_deads) |
649 Binding.empty Binding.empty [] |
740 Binding.empty Binding.empty [] |
650 ((((((b, T), bnf_map), bnf_sets), bnf_bd'), bnf_wits), SOME bnf_rel) lthy; |
741 ((((((b, TA), bnf_map), bnf_sets), bnf_bd'), bnf_wits), SOME bnf_rel) lthy; |
651 in |
742 in |
652 ((bnf', all_deads), lthy') |
743 ((bnf', (all_deads, absT_info)), lthy') |
653 end; |
744 end; |
654 |
745 |
655 fun key_of_types Ts = Type ("", Ts); |
746 fun key_of_types Ts = Type ("", Ts); |
656 val key_of_typess = key_of_types o map key_of_types; |
747 val key_of_typess = key_of_types o map key_of_types; |
657 fun key_of_comp oDs Dss Ass T = key_of_types (map key_of_typess [[oDs], Dss, Ass, [[T]]]); |
748 fun key_of_comp oDs Dss Ass T = key_of_types (map key_of_typess [[oDs], Dss, Ass, [[T]]]); |