src/HOL/Tools/Lifting/lifting_def.ML
changeset 60225 eb4e322734bf
parent 60224 e759afe46a8c
child 60227 eacf75e4da95
equal deleted inserted replaced
60224:e759afe46a8c 60225:eb4e322734bf
    18   val transfer_rules_of_lift_def: lift_def -> thm list
    18   val transfer_rules_of_lift_def: lift_def -> thm list
    19   val morph_lift_def: morphism -> lift_def -> lift_def
    19   val morph_lift_def: morphism -> lift_def -> lift_def
    20   val inst_of_lift_def: Proof.context -> typ -> lift_def -> lift_def
    20   val inst_of_lift_def: Proof.context -> typ -> lift_def -> lift_def
    21   val mk_lift_const_of_lift_def: typ -> lift_def -> term
    21   val mk_lift_const_of_lift_def: typ -> lift_def -> term
    22 
    22 
       
    23   type config = { notes: bool }
       
    24   val default_config: config
       
    25 
    23   val generate_parametric_transfer_rule:
    26   val generate_parametric_transfer_rule:
    24     Proof.context -> thm -> thm -> thm
    27     Proof.context -> thm -> thm -> thm
    25 
    28 
    26   val add_lift_def:
    29   val add_lift_def: 
    27     binding * mixfix -> typ -> term -> thm -> thm list -> local_theory -> lift_def * local_theory
    30     config -> binding * mixfix -> typ -> term -> thm -> thm list -> local_theory -> 
       
    31       lift_def * local_theory
    28     
    32     
    29   val lift_def: 
    33   val lift_def: 
    30     binding * mixfix -> typ -> term -> (Proof.context -> tactic) -> thm list -> 
    34     config -> binding * mixfix -> typ -> term -> (Proof.context -> tactic) -> thm list -> 
    31     local_theory -> lift_def * local_theory
    35     local_theory -> lift_def * local_theory
    32 
    36 
    33   val lift_def_cmd:
    37   val lift_def_cmd:
    34     (binding * string option * mixfix) * string * (Facts.ref * Token.src list) list ->
    38     (binding * string option * mixfix) * string * (Facts.ref * Token.src list) list ->
    35     local_theory -> Proof.state
    39     local_theory -> Proof.state
    95 fun mk_lift_const_of_lift_def qty lift_def = Envir.subst_term_types (mk_inst_of_lift_def qty lift_def)
    99 fun mk_lift_const_of_lift_def qty lift_def = Envir.subst_term_types (mk_inst_of_lift_def qty lift_def)
    96   (lift_const_of_lift_def lift_def)
   100   (lift_const_of_lift_def lift_def)
    97 
   101 
    98 fun inst_of_lift_def ctxt qty lift_def =  mk_inst_of_lift_def qty lift_def
   102 fun inst_of_lift_def ctxt qty lift_def =  mk_inst_of_lift_def qty lift_def
    99   |> instT_morphism ctxt |> (fn phi => morph_lift_def phi lift_def)
   103   |> instT_morphism ctxt |> (fn phi => morph_lift_def phi lift_def)
       
   104 
       
   105 (* Config *)
       
   106 
       
   107 type config = { notes: bool };
       
   108 val default_config = { notes = true };
   100 
   109 
   101 (* Reflexivity prover *)
   110 (* Reflexivity prover *)
   102 
   111 
   103 fun mono_eq_prover ctxt prop =
   112 fun mono_eq_prover ctxt prop =
   104   let
   113   let
   516   rsp_thm - a respectfulness theorem in the internal tagged form (like '(R ===> R ===> R) f f'),
   525   rsp_thm - a respectfulness theorem in the internal tagged form (like '(R ===> R ===> R) f f'),
   517     i.e. "(Lifting_Term.equiv_relation (fastype_of rhs, qty)) $ rhs $ rhs"
   526     i.e. "(Lifting_Term.equiv_relation (fastype_of rhs, qty)) $ rhs $ rhs"
   518   par_thms - a parametricity theorem for rhs
   527   par_thms - a parametricity theorem for rhs
   519 *)
   528 *)
   520 
   529 
   521 fun add_lift_def var qty rhs rsp_thm par_thms lthy =
   530 fun add_lift_def config var qty rhs rsp_thm par_thms lthy =
   522   let
   531   let
   523     val rty = fastype_of rhs
   532     val rty = fastype_of rhs
   524     val quot_thm = Lifting_Term.prove_quot_thm lthy (rty, qty)
   533     val quot_thm = Lifting_Term.prove_quot_thm lthy (rty, qty)
   525     val absrep_trm =  quot_thm_abs quot_thm
   534     val absrep_trm =  quot_thm_abs quot_thm
   526     val rty_forced = (domain_type o fastype_of) absrep_trm
   535     val rty_forced = (domain_type o fastype_of) absrep_trm
   527     val forced_rhs = force_rty_type lthy rty_forced rhs
   536     val forced_rhs = force_rty_type lthy rty_forced rhs
   528     val lhs = Free (Binding.name_of (#1 var), qty)
   537     val lhs = Free (Binding.name_of (#1 var), qty)
   529     val prop = Logic.mk_equals (lhs, absrep_trm $ forced_rhs)
   538     val prop = Logic.mk_equals (lhs, absrep_trm $ forced_rhs)
   530     val (_, prop') = Local_Defs.cert_def lthy prop
   539     val (_, prop') = Local_Defs.cert_def lthy prop
   531     val (_, newrhs) = Local_Defs.abs_def prop'
   540     val (_, newrhs) = Local_Defs.abs_def prop'
   532 
   541     val var = (#notes config = false ? apfst Binding.concealed) var
   533     val ((lift_const, (_ , def_thm)), lthy') = 
   542     val def_name = if #notes config then Thm.def_binding (#1 var) else Binding.empty
   534       Local_Theory.define (var, ((Thm.def_binding (#1 var), []), newrhs)) lthy
   543     
   535 
   544     val ((lift_const, (_ , def_thm)), lthy) = 
   536     val transfer_rules = generate_transfer_rules lthy' quot_thm rsp_thm def_thm par_thms
   545       Local_Theory.define (var, ((def_name, []), newrhs)) lthy
   537 
   546 
   538     val abs_eq_thm = generate_abs_eq lthy' def_thm rsp_thm quot_thm
   547     val transfer_rules = generate_transfer_rules lthy quot_thm rsp_thm def_thm par_thms
   539     val opt_rep_eq_thm = generate_rep_eq lthy' def_thm rsp_thm (rty_forced, qty)
   548 
       
   549     val abs_eq_thm = generate_abs_eq lthy def_thm rsp_thm quot_thm
       
   550     val opt_rep_eq_thm = generate_rep_eq lthy def_thm rsp_thm (rty_forced, qty)
   540 
   551 
   541     fun qualify defname suffix = Binding.qualified true suffix defname
   552     fun qualify defname suffix = Binding.qualified true suffix defname
   542 
   553 
   543     val lhs_name = (#1 var)
   554     fun notes names =
   544     val rsp_thm_name = qualify lhs_name "rsp"
   555       let
   545     val abs_eq_thm_name = qualify lhs_name "abs_eq"
   556         val lhs_name = (#1 var)
   546     val rep_eq_thm_name = qualify lhs_name "rep_eq"
   557         val rsp_thmN = qualify lhs_name "rsp"
   547     val transfer_rule_name = qualify lhs_name "transfer"
   558         val abs_eq_thmN = qualify lhs_name "abs_eq"
   548     val transfer_attr = Attrib.internal (K Transfer.transfer_add)
   559         val rep_eq_thmN = qualify lhs_name "rep_eq"
       
   560         val transfer_ruleN = qualify lhs_name "transfer"
       
   561         val notes = 
       
   562           [(rsp_thmN, [], [rsp_thm]), 
       
   563           (transfer_ruleN, @{attributes [transfer_rule]}, transfer_rules),
       
   564           (abs_eq_thmN, [], [abs_eq_thm])] 
       
   565           @ (case opt_rep_eq_thm of SOME rep_eq_thm => [(rep_eq_thmN, [], [rep_eq_thm])] | NONE => [])
       
   566       in
       
   567         if names then map (fn (name, attrs, thms) => ((name, []), [(thms, attrs)])) notes
       
   568         else map_filter (fn (_, attrs, thms) => if null attrs then NONE 
       
   569           else SOME ((Binding.empty, []), [(thms, attrs)])) notes
       
   570       end
   549     val lift_def = mk_lift_def rty_forced qty newrhs lift_const def_thm rsp_thm abs_eq_thm 
   571     val lift_def = mk_lift_def rty_forced qty newrhs lift_const def_thm rsp_thm abs_eq_thm 
   550       opt_rep_eq_thm transfer_rules 
   572           opt_rep_eq_thm transfer_rules
   551   in
   573   in
   552     lthy'
   574     lthy
   553       |> (snd oo Local_Theory.note) ((rsp_thm_name, []), [rsp_thm])
   575       |> Local_Theory.notes (notes (#notes config)) |> snd
   554       |> (snd oo Local_Theory.note) ((transfer_rule_name, [transfer_attr]), transfer_rules)
       
   555       |> (snd oo Local_Theory.note) ((abs_eq_thm_name, []), [abs_eq_thm])
       
   556       |> (case opt_rep_eq_thm of 
       
   557             SOME rep_eq_thm => (snd oo Local_Theory.note) ((rep_eq_thm_name, []), [rep_eq_thm])
       
   558             | NONE => I)
       
   559       |> register_code_eq abs_eq_thm opt_rep_eq_thm (rty_forced, qty)
   576       |> register_code_eq abs_eq_thm opt_rep_eq_thm (rty_forced, qty)
   560       |> ` (fn lthy => morph_lift_def (Local_Theory.target_morphism lthy) lift_def)
   577       |> ` (fn lthy => morph_lift_def (Local_Theory.target_morphism lthy) lift_def)
   561       ||> Local_Theory.restore
   578       ||> Local_Theory.restore
   562   end
   579   end
   563 
   580 
   678     val table = Lifting_Info.get_quotients ctxt
   695     val table = Lifting_Info.get_quotients ctxt
   679   in
   696   in
   680     Symtab.fold (fn (_, data) => fn l => collect data l) table []
   697     Symtab.fold (fn (_, data) => fn l => collect data l) table []
   681   end
   698   end
   682 
   699 
   683 fun prepare_lift_def var qty rhs par_thms lthy =
   700 fun prepare_lift_def config var qty rhs par_thms lthy =
   684   let
   701   let
   685     val rsp_rel = Lifting_Term.equiv_relation lthy (fastype_of rhs, qty)
   702     val rsp_rel = Lifting_Term.equiv_relation lthy (fastype_of rhs, qty)
   686     val rty_forced = (domain_type o fastype_of) rsp_rel;
   703     val rty_forced = (domain_type o fastype_of) rsp_rel;
   687     val forced_rhs = force_rty_type lthy rty_forced rhs;
   704     val forced_rhs = force_rty_type lthy rty_forced rhs;
   688     val cr_to_pcr_conv = HOLogic.Trueprop_conv (Conv.fun2_conv 
   705     val cr_to_pcr_conv = HOLogic.Trueprop_conv (Conv.fun2_conv 
   695       |>> snd
   712       |>> snd
   696     val to_rsp = rsp_prsp_eq RS Drule.equal_elim_rule2
   713     val to_rsp = rsp_prsp_eq RS Drule.equal_elim_rule2
   697     val opt_proven_rsp_thm = try_prove_reflexivity lthy prsp_tm
   714     val opt_proven_rsp_thm = try_prove_reflexivity lthy prsp_tm
   698     
   715     
   699     fun after_qed internal_rsp_thm lthy = 
   716     fun after_qed internal_rsp_thm lthy = 
   700       add_lift_def var qty rhs (internal_rsp_thm RS to_rsp) par_thms lthy
   717       add_lift_def config var qty rhs (internal_rsp_thm RS to_rsp) par_thms lthy
   701   in
   718   in
   702     case opt_proven_rsp_thm of
   719     case opt_proven_rsp_thm of
   703       SOME thm => (NONE, K (after_qed thm))
   720       SOME thm => (NONE, K (after_qed thm))
   704       | NONE =>  
   721       | NONE =>  
   705         let
   722         let
   718         in
   735         in
   719           (SOME readable_rsp_tm_tnames, after_qed')
   736           (SOME readable_rsp_tm_tnames, after_qed')
   720         end 
   737         end 
   721   end
   738   end
   722 
   739 
   723 fun lift_def var qty rhs tac par_thms lthy =
   740 fun lift_def config var qty rhs tac par_thms lthy =
   724   let
   741   let
   725     val (goal, after_qed) = prepare_lift_def var qty rhs par_thms lthy
   742     val (goal, after_qed) = prepare_lift_def config var qty rhs par_thms lthy
   726   in
   743   in
   727     case goal of
   744     case goal of
   728       SOME goal => 
   745       SOME goal => 
   729         let 
   746         let 
   730           val rsp_thm = Goal.prove_sorry lthy [] [] goal (fn {context = ctxt, ...} => tac ctxt)
   747           val rsp_thm = Goal.prove_sorry lthy [] [] goal (fn {context = ctxt, ...} => tac ctxt)
   746   let
   763   let
   747     val ((binding, SOME qty, mx), lthy) = yield_singleton Proof_Context.read_vars raw_var lthy 
   764     val ((binding, SOME qty, mx), lthy) = yield_singleton Proof_Context.read_vars raw_var lthy 
   748     val var = (binding, mx)
   765     val var = (binding, mx)
   749     val rhs = (Syntax.check_term lthy o Syntax.parse_term lthy) rhs_raw
   766     val rhs = (Syntax.check_term lthy o Syntax.parse_term lthy) rhs_raw
   750     val par_thms = Attrib.eval_thms lthy par_xthms
   767     val par_thms = Attrib.eval_thms lthy par_xthms
   751     val (goal, after_qed) = prepare_lift_def var qty rhs par_thms lthy
   768     val (goal, after_qed) = prepare_lift_def default_config var qty rhs par_thms lthy
   752   in
   769   in
   753     Proof.theorem NONE (snd oo after_qed) [map (rpair []) (the_list goal)] lthy
   770     Proof.theorem NONE (snd oo after_qed) [map (rpair []) (the_list goal)] lthy
   754   end
   771   end
   755 
   772 
   756 fun quot_thm_err ctxt (rty, qty) pretty_msg =
   773 fun quot_thm_err ctxt (rty, qty) pretty_msg =