src/HOL/Tools/Lifting/lifting_setup.ML
changeset 51956 a4d81cdebf8b
parent 51374 84d01fd733cf
child 51994 82cc2aeb7d13
equal deleted inserted replaced
51955:04d9381bebff 51956:a4d81cdebf8b
   218   in
   218   in
   219     lthy
   219     lthy
   220       |> Local_Theory.declaration {syntax = false, pervasive = true}
   220       |> Local_Theory.declaration {syntax = false, pervasive = true}
   221         (fn phi => Lifting_Info.update_quotients qty_full_name (quot_info phi))
   221         (fn phi => Lifting_Info.update_quotients qty_full_name (quot_info phi))
   222   end
   222   end
       
   223 
       
   224 local
       
   225   fun importT_inst_exclude exclude ts ctxt =
       
   226     let
       
   227       val tvars = rev (subtract op= exclude (fold Term.add_tvars ts []));
       
   228       val (tfrees, ctxt') = Variable.invent_types (map #2 tvars) ctxt;
       
   229     in (tvars ~~ map TFree tfrees, ctxt') end
       
   230   
       
   231   fun import_inst_exclude exclude ts ctxt =
       
   232     let
       
   233       val excludeT = fold (Term.add_tvarsT o snd) exclude []
       
   234       val (instT, ctxt') = importT_inst_exclude excludeT ts ctxt;
       
   235       val vars = map (apsnd (Term_Subst.instantiateT instT)) 
       
   236         (rev (subtract op= exclude (fold Term.add_vars ts [])));
       
   237       val (xs, ctxt'') = Variable.variant_fixes (map (#1 o #1) vars) ctxt';
       
   238       val inst = vars ~~ map Free (xs ~~ map #2 vars);
       
   239     in ((instT, inst), ctxt'') end
       
   240   
       
   241   fun import_terms_exclude exclude ts ctxt =
       
   242     let val (inst, ctxt') = import_inst_exclude exclude ts ctxt
       
   243     in (map (Term_Subst.instantiate inst) ts, ctxt') end
       
   244 in
       
   245   fun reduce_goal not_fix goal tac ctxt =
       
   246     let
       
   247       val thy = Proof_Context.theory_of ctxt
       
   248       val orig_ctxt = ctxt
       
   249       val (fixed_goal, ctxt) = yield_singleton (import_terms_exclude not_fix) goal ctxt
       
   250       val init_goal = Goal.init (cterm_of thy fixed_goal)
       
   251     in
       
   252       (singleton (Variable.export ctxt orig_ctxt) o Goal.conclude) (the (SINGLE tac init_goal))
       
   253     end
       
   254 end
   223 
   255 
   224 local 
   256 local 
   225   val OO_rules = [@{thm bi_total_OO}, @{thm bi_unique_OO}, @{thm right_total_OO}, @{thm right_unique_OO}]
   257   val OO_rules = [@{thm bi_total_OO}, @{thm bi_unique_OO}, @{thm right_total_OO}, @{thm right_unique_OO}]
   226 in
   258 in
   227   fun parametrize_class_constraint ctxt pcr_def constraint =
   259   fun parametrize_class_constraint ctxt pcr_def constraint =
   317       in
   349       in
   318         (warning error_msg; id_transfer_rule)
   350         (warning error_msg; id_transfer_rule)
   319       end
   351       end
   320 end
   352 end
   321 
   353 
   322 fun parametrize_quantifier lthy quant_transfer_rule =
   354 local
   323   Lifting_Term.parametrize_transfer_rule lthy quant_transfer_rule
   355   fun rewrite_first_Domainp_arg rewr_thm thm = Conv.fconv_rule (Conv.concl_conv ~1 (HOLogic.Trueprop_conv 
       
   356       (Conv.arg1_conv (Conv.arg_conv (Conv.rewr_conv rewr_thm))))) thm
       
   357   
       
   358   fun fold_Domainp_pcrel pcrel_def thm =
       
   359     let
       
   360       val ct = thm |> cprop_of |> Drule.strip_imp_concl |> Thm.dest_arg |> Thm.dest_arg1 |> Thm.dest_arg
       
   361       val pcrel_def = Thm.incr_indexes (#maxidx (Thm.rep_cterm ct) + 1) pcrel_def
       
   362       val thm = Thm.instantiate (Thm.match (ct, Thm.rhs_of pcrel_def)) thm
       
   363         handle Pattern.MATCH => raise CTERM ("fold_Domainp_pcrel", [ct, Thm.rhs_of pcrel_def]);
       
   364     in
       
   365       rewrite_first_Domainp_arg (Thm.symmetric pcrel_def) thm
       
   366     end
       
   367 
       
   368   fun reduce_Domainp ctxt rules thm =
       
   369     let
       
   370       val goal = thm |> prems_of |> hd
       
   371       val var = goal |> HOLogic.dest_Trueprop |> dest_comb |> snd |> dest_Var 
       
   372       val reduced_assm = reduce_goal [var] goal (TRY (REPEAT_ALL_NEW (resolve_tac rules) 1)) ctxt
       
   373     in
       
   374       reduced_assm RS thm
       
   375     end
       
   376 in
       
   377   fun parametrize_domain dom_thm (pcrel_info : Lifting_Info.pcrel_info) ctxt =
       
   378     let
       
   379       fun reduce_first_assm ctxt rules thm =
       
   380         let
       
   381           val goal = thm |> prems_of |> hd
       
   382           val reduced_assm = reduce_goal [] goal (TRY (REPEAT_ALL_NEW (resolve_tac rules) 1)) ctxt
       
   383         in
       
   384           reduced_assm RS thm
       
   385         end
       
   386 
       
   387       val pcr_cr_met_eq = #pcr_cr_eq pcrel_info RS @{thm eq_reflection}
       
   388       val pcr_Domainp_eq = rewrite_first_Domainp_arg (Thm.symmetric pcr_cr_met_eq) dom_thm
       
   389       val pcrel_def = #pcrel_def pcrel_info
       
   390       val pcr_Domainp_par_left_total = 
       
   391         (dom_thm RS @{thm pcr_Domainp_par_left_total})
       
   392           |> fold_Domainp_pcrel pcrel_def
       
   393           |> reduce_first_assm ctxt (Lifting_Info.get_reflexivity_rules ctxt)
       
   394       val pcr_Domainp_par = 
       
   395         (dom_thm RS @{thm pcr_Domainp_par})      
       
   396           |> fold_Domainp_pcrel pcrel_def
       
   397           |> reduce_Domainp ctxt (Transfer.get_relator_domain ctxt)
       
   398       val pcr_Domainp = 
       
   399         (dom_thm RS @{thm pcr_Domainp})
       
   400           |> fold_Domainp_pcrel pcrel_def
       
   401       val thms =
       
   402         [("domain",                 pcr_Domainp),
       
   403          ("domain_par",             pcr_Domainp_par),
       
   404          ("domain_par_left_total",  pcr_Domainp_par_left_total),
       
   405          ("domain_eq",              pcr_Domainp_eq)]
       
   406     in
       
   407       thms
       
   408     end
       
   409 
       
   410   fun parametrize_total_domain bi_total pcrel_def ctxt =
       
   411     let
       
   412       val thm =
       
   413         (bi_total RS @{thm pcr_Domainp_total})
       
   414           |> fold_Domainp_pcrel pcrel_def 
       
   415           |> reduce_Domainp ctxt (Transfer.get_relator_domain ctxt)
       
   416     in
       
   417       [("domain", thm)]
       
   418     end
       
   419 
       
   420 end
   324 
   421 
   325 fun get_pcrel_info ctxt qty_full_name =  
   422 fun get_pcrel_info ctxt qty_full_name =  
   326   #pcrel_info (the (Lifting_Info.lookup_quotients ctxt qty_full_name))
   423   #pcrel_info (the (Lifting_Info.lookup_quotients ctxt qty_full_name))
       
   424 
       
   425 fun get_Domainp_thm quot_thm =
       
   426    the (get_first (try(curry op RS quot_thm)) [@{thm invariant_to_Domainp}, @{thm Quotient_to_Domainp}])
   327 
   427 
   328 (*
   428 (*
   329   Sets up the Lifting package by a quotient theorem.
   429   Sets up the Lifting package by a quotient theorem.
   330 
   430 
   331   gen_code - flag if an abstract type given by quot_thm should be registred 
   431   gen_code - flag if an abstract type given by quot_thm should be registred 
   339   let
   439   let
   340     (**)
   440     (**)
   341     val quot_thm = Morphism.thm (Local_Theory.target_morphism lthy) quot_thm
   441     val quot_thm = Morphism.thm (Local_Theory.target_morphism lthy) quot_thm
   342     (**)
   442     (**)
   343     val transfer_attr = Attrib.internal (K Transfer.transfer_add)
   443     val transfer_attr = Attrib.internal (K Transfer.transfer_add)
       
   444     val transfer_domain_attr = Attrib.internal (K Transfer.transfer_domain_add)
   344     val (rty, qty) = quot_thm_rty_qty quot_thm
   445     val (rty, qty) = quot_thm_rty_qty quot_thm
   345     val induct_attr = Attrib.internal (K (Induct.induct_type (fst (dest_Type qty))))
   446     val induct_attr = Attrib.internal (K (Induct.induct_type (fst (dest_Type qty))))
   346     val qty_full_name = (fst o dest_Type) qty
   447     val qty_full_name = (fst o dest_Type) qty
   347     val qty_name = (Binding.name o Long_Name.base_name) qty_full_name
   448     val qty_name = (Binding.name o Long_Name.base_name) qty_full_name
   348     fun qualify suffix = Binding.qualified true suffix qty_name
   449     fun qualify suffix = Binding.qualified true suffix qty_name
   363             [("abs_induct",     @{thm Quotient_abs_induct},       [induct_attr])]
   464             [("abs_induct",     @{thm Quotient_abs_induct},       [induct_attr])]
   364         in
   465         in
   365           fold (fn (name, thm, attr) => (snd oo Local_Theory.note) ((qualify name, attr), 
   466           fold (fn (name, thm, attr) => (snd oo Local_Theory.note) ((qualify name, attr), 
   366             [quot_thm RS thm])) thms lthy
   467             [quot_thm RS thm])) thms lthy
   367         end
   468         end
       
   469     val dom_thm = get_Domainp_thm quot_thm
   368 
   470 
   369     fun setup_transfer_rules_nonpar lthy =
   471     fun setup_transfer_rules_nonpar lthy =
   370       let
   472       let
   371         val lthy =
   473         val lthy =
   372           case opt_reflp_thm of
   474           case opt_reflp_thm of
   378               in
   480               in
   379                 fold (fn (name, thm) => (snd oo Local_Theory.note) ((qualify name, [transfer_attr]), 
   481                 fold (fn (name, thm) => (snd oo Local_Theory.note) ((qualify name, [transfer_attr]), 
   380                     [[quot_thm, reflp_thm] MRSL thm])) thms lthy
   482                     [[quot_thm, reflp_thm] MRSL thm])) thms lthy
   381               end
   483               end
   382             | NONE =>
   484             | NONE =>
   383               let
   485               lthy
   384                 val thms = 
   486               |> (snd oo Local_Theory.note) ((qualify "domain", [transfer_domain_attr]), [dom_thm])
   385                   [("All_transfer",   @{thm Quotient_All_transfer}   ),
   487 
   386                    ("Ex_transfer",    @{thm Quotient_Ex_transfer}    ),
       
   387                    ("forall_transfer",@{thm Quotient_forall_transfer})]
       
   388               in
       
   389                 fold (fn (name, thm) => (snd oo Local_Theory.note) ((qualify name, [transfer_attr]), 
       
   390                   [quot_thm RS thm])) thms lthy
       
   391               end
       
   392         val thms = 
   488         val thms = 
   393           [("rel_eq_transfer", @{thm Quotient_rel_eq_transfer}),
   489           [("rel_eq_transfer", @{thm Quotient_rel_eq_transfer}),
   394            ("right_unique",    @{thm Quotient_right_unique}   ), 
   490            ("right_unique",    @{thm Quotient_right_unique}   ), 
   395            ("right_total",     @{thm Quotient_right_total}    )]
   491            ("right_total",     @{thm Quotient_right_total}    )]
   396       in
   492       in
   410           error error_msg
   506           error error_msg
   411         end
   507         end
   412 
   508 
   413     fun setup_transfer_rules_par lthy =
   509     fun setup_transfer_rules_par lthy =
   414       let
   510       let
   415         val pcrel_def = #pcrel_def (the (get_pcrel_info lthy qty_full_name))
   511         val pcrel_info = (the (get_pcrel_info lthy qty_full_name))
       
   512         val pcrel_def = #pcrel_def pcrel_info
   416         val lthy =
   513         val lthy =
   417           case opt_reflp_thm of
   514           case opt_reflp_thm of
   418             SOME reflp_thm =>
   515             SOME reflp_thm =>
   419               let
   516               let
       
   517                 val bi_total = ([quot_thm, reflp_thm] MRSL @{thm Quotient_bi_total})
       
   518                 val domain_thms = parametrize_total_domain bi_total pcrel_def lthy
   420                 val id_abs_transfer = generate_parametric_id lthy rty
   519                 val id_abs_transfer = generate_parametric_id lthy rty
   421                   (Lifting_Term.parametrize_transfer_rule lthy
   520                   (Lifting_Term.parametrize_transfer_rule lthy
   422                     ([quot_thm, reflp_thm] MRSL @{thm Quotient_id_abs_transfer}))
   521                     ([quot_thm, reflp_thm] MRSL @{thm Quotient_id_abs_transfer}))
   423                 val bi_total = parametrize_class_constraint lthy pcrel_def 
   522                 val bi_total = parametrize_class_constraint lthy pcrel_def bi_total
   424                     ([quot_thm, reflp_thm] MRSL @{thm Quotient_bi_total})
       
   425                 val thms = 
   523                 val thms = 
   426                   [("id_abs_transfer",id_abs_transfer),
   524                   [("id_abs_transfer",id_abs_transfer),
   427                    ("bi_total",       bi_total       )]
   525                    ("bi_total",       bi_total       )]
   428               in
   526               in
   429                 fold (fn (name, thm) => (snd oo Local_Theory.note) ((qualify name, [transfer_attr]), 
   527                 lthy
   430                     [thm])) thms lthy
   528                 |> fold (fn (name, thm) => (snd oo Local_Theory.note) ((qualify name, [transfer_attr]), 
       
   529                      [thm])) thms
       
   530                 |> fold (fn (name, thm) => (snd oo Local_Theory.note) ((qualify name, [transfer_domain_attr]), 
       
   531                      [thm])) domain_thms
   431               end
   532               end
   432             | NONE =>
   533             | NONE =>
   433               let
   534               let
   434                 val thms = 
   535                 val thms = parametrize_domain dom_thm pcrel_info lthy
   435                   [("All_transfer",   @{thm Quotient_All_transfer}   ),
       
   436                    ("Ex_transfer",    @{thm Quotient_Ex_transfer}    ),
       
   437                    ("forall_transfer",@{thm Quotient_forall_transfer})]
       
   438               in
   536               in
   439                 fold (fn (name, thm) => (snd oo Local_Theory.note) ((qualify name, [transfer_attr]), 
   537                 fold (fn (name, thm) => (snd oo Local_Theory.note) ((qualify name, [transfer_domain_attr]), 
   440                   [parametrize_quantifier lthy (quot_thm RS thm)])) thms lthy
   538                   [thm])) thms lthy
   441               end
   539               end
       
   540 
   442         val rel_eq_transfer = generate_parametric_rel_eq lthy 
   541         val rel_eq_transfer = generate_parametric_rel_eq lthy 
   443           (Lifting_Term.parametrize_transfer_rule lthy (quot_thm RS @{thm Quotient_rel_eq_transfer}))
   542           (Lifting_Term.parametrize_transfer_rule lthy (quot_thm RS @{thm Quotient_rel_eq_transfer}))
   444             opt_par_thm
   543             opt_par_thm
   445         val right_unique = parametrize_class_constraint lthy pcrel_def 
   544         val right_unique = parametrize_class_constraint lthy pcrel_def 
   446             (quot_thm RS @{thm Quotient_right_unique})
   545             (quot_thm RS @{thm Quotient_right_unique})
   473 *)
   572 *)
   474 
   573 
   475 fun setup_by_typedef_thm gen_code typedef_thm lthy =
   574 fun setup_by_typedef_thm gen_code typedef_thm lthy =
   476   let
   575   let
   477     val transfer_attr = Attrib.internal (K Transfer.transfer_add)
   576     val transfer_attr = Attrib.internal (K Transfer.transfer_add)
       
   577     val transfer_domain_attr = Attrib.internal (K Transfer.transfer_domain_add)
   478     val (_ $ rep_fun $ _ $ typedef_set) = (HOLogic.dest_Trueprop o prop_of) typedef_thm
   578     val (_ $ rep_fun $ _ $ typedef_set) = (HOLogic.dest_Trueprop o prop_of) typedef_thm
   479     val (T_def, lthy) = define_crel rep_fun lthy
   579     val (T_def, lthy) = define_crel rep_fun lthy
   480     (**)
   580     (**)
   481     val T_def = Morphism.thm (Local_Theory.target_morphism lthy) T_def
   581     val T_def = Morphism.thm (Local_Theory.target_morphism lthy) T_def
   482     (**)    
   582     (**)    
   495     val opt_reflp_thm = 
   595     val opt_reflp_thm = 
   496       case typedef_set of
   596       case typedef_set of
   497         Const ("Orderings.top_class.top", _) => 
   597         Const ("Orderings.top_class.top", _) => 
   498           SOME ((typedef_thm RS @{thm UNIV_typedef_to_equivp}) RS @{thm equivp_reflp2})
   598           SOME ((typedef_thm RS @{thm UNIV_typedef_to_equivp}) RS @{thm equivp_reflp2})
   499         | _ =>  NONE
   599         | _ =>  NONE
       
   600     val dom_thm = get_Domainp_thm quot_thm
   500 
   601 
   501     fun setup_transfer_rules_nonpar lthy =
   602     fun setup_transfer_rules_nonpar lthy =
   502       let
   603       let
   503         val lthy =
   604         val lthy =
   504           case opt_reflp_thm of
   605           case opt_reflp_thm of
   510               in
   611               in
   511                 fold (fn (name, thm) => (snd oo Local_Theory.note) ((qualify name, [transfer_attr]), 
   612                 fold (fn (name, thm) => (snd oo Local_Theory.note) ((qualify name, [transfer_attr]), 
   512                     [[quot_thm, reflp_thm] MRSL thm])) thms lthy
   613                     [[quot_thm, reflp_thm] MRSL thm])) thms lthy
   513               end
   614               end
   514             | NONE =>
   615             | NONE =>
   515               let
   616               lthy
   516                 val thms = 
   617               |> (snd oo Local_Theory.note) ((qualify "domain", [transfer_domain_attr]), [dom_thm])
   517                   [("All_transfer",   @{thm typedef_All_transfer}   ),
       
   518                    ("Ex_transfer",    @{thm typedef_Ex_transfer}    )]
       
   519               in
       
   520                 lthy
       
   521                 |> (snd oo Local_Theory.note) ((qualify "forall_transfer", [transfer_attr]), 
       
   522                   [simplify ([typedef_thm, T_def] MRSL @{thm typedef_forall_transfer})])
       
   523                 |> fold (fn (name, thm) => (snd oo Local_Theory.note) ((qualify name, [transfer_attr]), 
       
   524                   [[typedef_thm, T_def] MRSL thm])) thms
       
   525               end
       
   526         val thms = 
   618         val thms = 
   527           [("rep_transfer", @{thm typedef_rep_transfer}),
   619           [("rep_transfer", @{thm typedef_rep_transfer}),
   528            ("bi_unique",    @{thm typedef_bi_unique}   ),
   620            ("bi_unique",    @{thm typedef_bi_unique}   ),
   529            ("right_unique", @{thm typedef_right_unique}), 
   621            ("right_unique", @{thm typedef_right_unique}), 
   530            ("right_total",  @{thm typedef_right_total} )]
   622            ("right_total",  @{thm typedef_right_total} )]
   533           [[typedef_thm, T_def] MRSL thm])) thms lthy
   625           [[typedef_thm, T_def] MRSL thm])) thms lthy
   534       end
   626       end
   535 
   627 
   536     fun setup_transfer_rules_par lthy =
   628     fun setup_transfer_rules_par lthy =
   537       let
   629       let
   538         val pcrel_def = #pcrel_def (the (get_pcrel_info lthy qty_full_name))
   630         val pcrel_info = (the (get_pcrel_info lthy qty_full_name))
       
   631         val pcrel_def = #pcrel_def pcrel_info
       
   632 
   539         val lthy =
   633         val lthy =
   540           case opt_reflp_thm of
   634           case opt_reflp_thm of
   541             SOME reflp_thm =>
   635             SOME reflp_thm =>
   542               let
   636               let
       
   637                 val bi_total = ([quot_thm, reflp_thm] MRSL @{thm Quotient_bi_total})
       
   638                 val domain_thms = parametrize_total_domain bi_total pcrel_def lthy
       
   639                 val bi_total = parametrize_class_constraint lthy pcrel_def bi_total
   543                 val id_abs_transfer = generate_parametric_id lthy rty
   640                 val id_abs_transfer = generate_parametric_id lthy rty
   544                   (Lifting_Term.parametrize_transfer_rule lthy
   641                   (Lifting_Term.parametrize_transfer_rule lthy
   545                     ([quot_thm, reflp_thm] MRSL @{thm Quotient_id_abs_transfer}))
   642                     ([quot_thm, reflp_thm] MRSL @{thm Quotient_id_abs_transfer}))
   546                 val bi_total = parametrize_class_constraint lthy pcrel_def 
       
   547                     ([quot_thm, reflp_thm] MRSL @{thm Quotient_bi_total})
       
   548                 val thms = 
   643                 val thms = 
   549                   [("id_abs_transfer",id_abs_transfer),
   644                   [("bi_total",       bi_total       ),
   550                    ("bi_total",       bi_total       )]
   645                    ("id_abs_transfer",id_abs_transfer)]              
   551               in
   646               in
   552                 fold (fn (name, thm) => (snd oo Local_Theory.note) ((qualify name, [transfer_attr]), 
   647                 lthy
   553                     [thm])) thms lthy
   648                 |> fold (fn (name, thm) => (snd oo Local_Theory.note) ((qualify name, [transfer_attr]), 
       
   649                      [thm])) thms
       
   650                 |> fold (fn (name, thm) => (snd oo Local_Theory.note) ((qualify name, [transfer_domain_attr]), 
       
   651                      [thm])) domain_thms
   554               end
   652               end
   555             | NONE =>
   653             | NONE =>
   556               let
   654               let
   557                 val thms = 
   655                 val thms = parametrize_domain dom_thm pcrel_info lthy
   558                   ("forall_transfer", simplify ([typedef_thm, T_def] MRSL @{thm typedef_forall_transfer})) 
       
   559                   ::
       
   560                   (map_snd (fn thm => [typedef_thm, T_def] MRSL thm)                
       
   561                   [("All_transfer", @{thm typedef_All_transfer}),
       
   562                    ("Ex_transfer",  @{thm typedef_Ex_transfer} )])
       
   563               in
   656               in
   564                 fold (fn (name, thm) => (snd oo Local_Theory.note) ((qualify name, [transfer_attr]), 
   657                 fold (fn (name, thm) => (snd oo Local_Theory.note) ((qualify name, [transfer_domain_attr]), 
   565                   [parametrize_quantifier lthy thm])) thms lthy
   658                   [thm])) thms lthy
   566               end
   659               end
       
   660               
   567         val thms = 
   661         val thms = 
   568           ("rep_transfer", generate_parametric_id lthy rty 
   662           ("rep_transfer", generate_parametric_id lthy rty 
   569             (Lifting_Term.parametrize_transfer_rule lthy ([typedef_thm, T_def] MRSL @{thm typedef_rep_transfer})))
   663             (Lifting_Term.parametrize_transfer_rule lthy ([typedef_thm, T_def] MRSL @{thm typedef_rep_transfer})))
   570           ::
   664           ::
   571           (map_snd (fn thm => parametrize_class_constraint lthy pcrel_def ([typedef_thm, T_def] MRSL thm))
   665           (map_snd (fn thm => parametrize_class_constraint lthy pcrel_def ([typedef_thm, T_def] MRSL thm))