src/HOL/Tools/BNF/bnf_comp.ML
changeset 55803 74d3fe9031d8
parent 55707 50cf04dd2584
child 55851 3d40cf74726c
equal deleted inserted replaced
55802:f7ceebe2f1b5 55803:74d3fe9031d8
    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]]]);