src/HOL/Tools/Lifting/lifting_setup.ML
changeset 47937 70375fa2679d
parent 47936 756f30eac792
child 47943 c09326cedb41
equal deleted inserted replaced
47936:756f30eac792 47937:70375fa2679d
    34       Local_Theory.define ((cr_rel_name, NoSyn), ((Thm.def_binding cr_rel_name, []), fixed_def_term)) lthy'
    34       Local_Theory.define ((cr_rel_name, NoSyn), ((Thm.def_binding cr_rel_name, []), fixed_def_term)) lthy'
    35   in
    35   in
    36     (def_thm, lthy'')
    36     (def_thm, lthy'')
    37   end
    37   end
    38 
    38 
    39 fun define_abs_type gen_abs_code quot_thm lthy =
    39 fun define_code_constr gen_code quot_thm lthy =
    40   if gen_abs_code andalso Lifting_Def.can_generate_code_cert quot_thm then
    40   let
       
    41     val abs = Lifting_Term.quot_thm_abs quot_thm
       
    42     val abs_background = Morphism.term (Local_Theory.target_morphism lthy) abs
       
    43   in
       
    44     if gen_code andalso is_Const abs_background then
       
    45       let
       
    46         val (const_name, typ) = dest_Const abs_background
       
    47         val fake_term = Logic.mk_type typ
       
    48         val (fixed_fake_term, lthy') = yield_singleton(Variable.importT_terms) fake_term lthy
       
    49         val fixed_type = Logic.dest_type fixed_fake_term
       
    50       in  
       
    51          Local_Theory.background_theory(Code.add_datatype [(const_name, fixed_type)]) lthy'
       
    52       end
       
    53     else
       
    54       lthy
       
    55   end
       
    56 
       
    57 fun define_abs_type gen_code quot_thm lthy =
       
    58   if gen_code andalso Lifting_Def.can_generate_code_cert quot_thm then
    41     let
    59     let
    42       val abs_type_thm = quot_thm RS @{thm Quotient_abs_rep}
    60       val abs_type_thm = quot_thm RS @{thm Quotient_abs_rep}
    43       val add_abstype_attribute = 
    61       val add_abstype_attribute = 
    44           Thm.declaration_attribute (fn thm => Context.mapping (Code.add_abstype thm) I)
    62           Thm.declaration_attribute (fn thm => Context.mapping (Code.add_abstype thm) I)
    45         val add_abstype_attrib = Attrib.internal (K add_abstype_attribute);
    63         val add_abstype_attrib = Attrib.internal (K add_abstype_attribute);
    74   in
    92   in
    75     if null errs then () else error (cat_lines (["Sanity check of the quotient theorem failed:",""] 
    93     if null errs then () else error (cat_lines (["Sanity check of the quotient theorem failed:",""] 
    76                                                 @ (map Pretty.string_of errs)))
    94                                                 @ (map Pretty.string_of errs)))
    77   end
    95   end
    78 
    96 
    79 fun setup_lifting_infr gen_abs_code quot_thm lthy =
    97 fun setup_lifting_infr gen_code quot_thm maybe_reflp_thm lthy =
    80   let
    98   let
    81     val _ = quot_thm_sanity_check lthy quot_thm
    99     val _ = quot_thm_sanity_check lthy quot_thm
    82     val (_, qtyp) = Lifting_Term.quot_thm_rty_qty quot_thm
   100     val (_, qtyp) = Lifting_Term.quot_thm_rty_qty quot_thm
    83     val qty_full_name = (fst o dest_Type) qtyp
   101     val qty_full_name = (fst o dest_Type) qtyp
    84     val quotients = { quot_thm = quot_thm }
   102     val quotients = { quot_thm = quot_thm }
    85     fun quot_info phi = Lifting_Info.transform_quotients phi quotients
   103     fun quot_info phi = Lifting_Info.transform_quotients phi quotients
    86   in
   104     val lthy' = case maybe_reflp_thm of
    87     lthy
   105       SOME reflp_thm => lthy
       
   106         |> (snd oo Local_Theory.note) ((Binding.empty, [Lifting_Info.add_reflp_preserve_rule_attrib]),
       
   107               [reflp_thm])
       
   108         |> define_code_constr gen_code quot_thm
       
   109       | NONE => lthy
       
   110         |> define_abs_type gen_code quot_thm
       
   111   in
       
   112     lthy'
    88       |> Local_Theory.declaration {syntax = false, pervasive = true}
   113       |> Local_Theory.declaration {syntax = false, pervasive = true}
    89         (fn phi => Lifting_Info.update_quotients qty_full_name (quot_info phi))
   114         (fn phi => Lifting_Info.update_quotients qty_full_name (quot_info phi))
    90       |> define_abs_type gen_abs_code quot_thm
       
    91   end
   115   end
    92 
   116 
    93 (*
   117 (*
    94   Sets up the Lifting package by a quotient theorem.
   118   Sets up the Lifting package by a quotient theorem.
    95 
   119 
    96   gen_abs_code - flag if an abstract type given by quot_thm should be registred 
   120   gen_code - flag if an abstract type given by quot_thm should be registred 
    97     as an abstract type in the code generator
   121     as an abstract type in the code generator
    98   quot_thm - a quotient theorem (Quotient R Abs Rep T)
   122   quot_thm - a quotient theorem (Quotient R Abs Rep T)
    99   maybe_reflp_thm - a theorem saying that a relation from quot_thm is reflexive
   123   maybe_reflp_thm - a theorem saying that a relation from quot_thm is reflexive
   100     (in the form "reflp R")
   124     (in the form "reflp R")
   101 *)
   125 *)
   102 
   126 
   103 fun setup_by_quotient gen_abs_code quot_thm maybe_reflp_thm lthy =
   127 fun setup_by_quotient gen_code quot_thm maybe_reflp_thm lthy =
   104   let
   128   let
   105     val transfer_attr = Attrib.internal (K Transfer.transfer_add)
   129     val transfer_attr = Attrib.internal (K Transfer.transfer_add)
   106     val (_, qty) = Lifting_Term.quot_thm_rty_qty quot_thm
   130     val (_, qty) = Lifting_Term.quot_thm_rty_qty quot_thm
   107     val induct_attr = Attrib.internal (K (Induct.induct_type (fst (dest_Type qty))))
   131     val induct_attr = Attrib.internal (K (Induct.induct_type (fst (dest_Type qty))))
   108     val qty_name = (Binding.name o Long_Name.base_name o fst o dest_Type) qty
   132     val qty_name = (Binding.name o Long_Name.base_name o fst o dest_Type) qty
   115           [[quot_thm, reflp_thm] MRSL @{thm Quotient_id_abs_transfer}])
   139           [[quot_thm, reflp_thm] MRSL @{thm Quotient_id_abs_transfer}])
   116         |> (snd oo Local_Theory.note) ((qualify "abs_induct", [induct_attr]),
   140         |> (snd oo Local_Theory.note) ((qualify "abs_induct", [induct_attr]),
   117           [[quot_thm, reflp_thm] MRSL @{thm Quotient_total_abs_induct}])
   141           [[quot_thm, reflp_thm] MRSL @{thm Quotient_total_abs_induct}])
   118         |> (snd oo Local_Theory.note) ((qualify "abs_eq_iff", []),
   142         |> (snd oo Local_Theory.note) ((qualify "abs_eq_iff", []),
   119           [[quot_thm, reflp_thm] MRSL @{thm Quotient_total_abs_eq_iff}])
   143           [[quot_thm, reflp_thm] MRSL @{thm Quotient_total_abs_eq_iff}])
   120         |> (snd oo Local_Theory.note) ((Binding.empty, [Lifting_Info.add_reflp_preserve_rule_attrib]),
       
   121           [reflp_thm])
       
   122       | NONE => lthy
   144       | NONE => lthy
   123         |> (snd oo Local_Theory.note) ((qualify "All_transfer", [transfer_attr]), 
   145         |> (snd oo Local_Theory.note) ((qualify "All_transfer", [transfer_attr]), 
   124           [quot_thm RS @{thm Quotient_All_transfer}])
   146           [quot_thm RS @{thm Quotient_All_transfer}])
   125         |> (snd oo Local_Theory.note) ((qualify "Ex_transfer", [transfer_attr]), 
   147         |> (snd oo Local_Theory.note) ((qualify "Ex_transfer", [transfer_attr]), 
   126           [quot_thm RS @{thm Quotient_Ex_transfer}])
   148           [quot_thm RS @{thm Quotient_Ex_transfer}])
   134         [quot_thm RS @{thm Quotient_right_unique}])
   156         [quot_thm RS @{thm Quotient_right_unique}])
   135       |> (snd oo Local_Theory.note) ((qualify "right_total", [transfer_attr]), 
   157       |> (snd oo Local_Theory.note) ((qualify "right_total", [transfer_attr]), 
   136         [quot_thm RS @{thm Quotient_right_total}])
   158         [quot_thm RS @{thm Quotient_right_total}])
   137       |> (snd oo Local_Theory.note) ((qualify "rel_eq_transfer", [transfer_attr]), 
   159       |> (snd oo Local_Theory.note) ((qualify "rel_eq_transfer", [transfer_attr]), 
   138         [quot_thm RS @{thm Quotient_rel_eq_transfer}])
   160         [quot_thm RS @{thm Quotient_rel_eq_transfer}])
   139       |> setup_lifting_infr gen_abs_code quot_thm
   161       |> setup_lifting_infr gen_code quot_thm maybe_reflp_thm
   140   end
   162   end
   141 
   163 
   142 (*
   164 (*
   143   Sets up the Lifting package by a typedef theorem.
   165   Sets up the Lifting package by a typedef theorem.
   144 
   166 
   145   gen_abs_code - flag if an abstract type given by typedef_thm should be registred 
   167   gen_code - flag if an abstract type given by typedef_thm should be registred 
   146     as an abstract type in the code generator
   168     as an abstract type in the code generator
   147   typedef_thm - a typedef theorem (type_definition Rep Abs S)
   169   typedef_thm - a typedef theorem (type_definition Rep Abs S)
   148 *)
   170 *)
   149 
   171 
   150 fun setup_by_typedef_thm gen_abs_code typedef_thm lthy =
   172 fun setup_by_typedef_thm gen_code typedef_thm lthy =
   151   let
   173   let
   152     val transfer_attr = Attrib.internal (K Transfer.transfer_add)
   174     val transfer_attr = Attrib.internal (K Transfer.transfer_add)
   153     val (_ $ rep_fun $ _ $ typedef_set) = (HOLogic.dest_Trueprop o prop_of) typedef_thm
   175     val (_ $ rep_fun $ _ $ typedef_set) = (HOLogic.dest_Trueprop o prop_of) typedef_thm
   154     val (T_def, lthy') = define_cr_rel rep_fun lthy
   176     val (T_def, lthy') = define_cr_rel rep_fun lthy
   155 
   177 
   164     val (_, qty) = Lifting_Term.quot_thm_rty_qty quot_thm
   186     val (_, qty) = Lifting_Term.quot_thm_rty_qty quot_thm
   165     val qty_name = (Binding.name o Long_Name.base_name o fst o dest_Type) qty
   187     val qty_name = (Binding.name o Long_Name.base_name o fst o dest_Type) qty
   166     fun qualify suffix = Binding.qualified true suffix qty_name
   188     fun qualify suffix = Binding.qualified true suffix qty_name
   167     val simplify = Raw_Simplifier.rewrite_rule [mk_meta_eq @{thm mem_Collect_eq}]
   189     val simplify = Raw_Simplifier.rewrite_rule [mk_meta_eq @{thm mem_Collect_eq}]
   168 
   190 
   169     val lthy'' = case typedef_set of
   191     val (maybe_reflp_thm, lthy'') = case typedef_set of
   170       Const ("Orderings.top_class.top", _) => 
   192       Const ("Orderings.top_class.top", _) => 
   171         let
   193         let
   172           val equivp_thm = typedef_thm RS @{thm UNIV_typedef_to_equivp}
   194           val equivp_thm = typedef_thm RS @{thm UNIV_typedef_to_equivp}
   173           val reflp_thm = equivp_thm RS @{thm equivp_reflp2}
   195           val reflp_thm = equivp_thm RS @{thm equivp_reflp2}
   174         in
   196         in
   175           lthy'
   197           lthy'
   176             |> (snd oo Local_Theory.note) ((qualify "bi_total", [transfer_attr]), 
   198             |> (snd oo Local_Theory.note) ((qualify "bi_total", [transfer_attr]), 
   177               [[quot_thm, reflp_thm] MRSL @{thm Quotient_bi_total}])
   199               [[quot_thm, reflp_thm] MRSL @{thm Quotient_bi_total}])
   178             |> (snd oo Local_Theory.note) ((qualify "id_abs_transfer", [transfer_attr]), 
   200             |> (snd oo Local_Theory.note) ((qualify "id_abs_transfer", [transfer_attr]), 
   179               [[quot_thm, reflp_thm] MRSL @{thm Quotient_id_abs_transfer}])
   201               [[quot_thm, reflp_thm] MRSL @{thm Quotient_id_abs_transfer}])
   180             |> (snd oo Local_Theory.note) ((Binding.empty, [Lifting_Info.add_reflp_preserve_rule_attrib]),
   202             |> pair (SOME reflp_thm)
   181               [reflp_thm])
       
   182         end
   203         end
   183       | _ => lthy'
   204       | _ => lthy'
   184         |> (snd oo Local_Theory.note) ((qualify "All_transfer", [transfer_attr]), 
   205         |> (snd oo Local_Theory.note) ((qualify "All_transfer", [transfer_attr]), 
   185           [[typedef_thm, T_def] MRSL @{thm typedef_All_transfer}])
   206           [[typedef_thm, T_def] MRSL @{thm typedef_All_transfer}])
   186         |> (snd oo Local_Theory.note) ((qualify "Ex_transfer", [transfer_attr]), 
   207         |> (snd oo Local_Theory.note) ((qualify "Ex_transfer", [transfer_attr]), 
   187           [[typedef_thm, T_def] MRSL @{thm typedef_Ex_transfer}])
   208           [[typedef_thm, T_def] MRSL @{thm typedef_Ex_transfer}])
   188         |> (snd oo Local_Theory.note) ((qualify "forall_transfer", [transfer_attr]), 
   209         |> (snd oo Local_Theory.note) ((qualify "forall_transfer", [transfer_attr]), 
   189           [simplify ([typedef_thm, T_def] MRSL @{thm typedef_forall_transfer})])
   210           [simplify ([typedef_thm, T_def] MRSL @{thm typedef_forall_transfer})])
       
   211         |> pair NONE
   190   in
   212   in
   191     lthy''
   213     lthy''
   192       |> (snd oo Local_Theory.note) ((qualify "bi_unique", [transfer_attr]), 
   214       |> (snd oo Local_Theory.note) ((qualify "bi_unique", [transfer_attr]), 
   193         [[typedef_thm, T_def] MRSL @{thm typedef_bi_unique}])
   215         [[typedef_thm, T_def] MRSL @{thm typedef_bi_unique}])
   194       |> (snd oo Local_Theory.note) ((qualify "rep_transfer", [transfer_attr]), 
   216       |> (snd oo Local_Theory.note) ((qualify "rep_transfer", [transfer_attr]), 
   195         [[typedef_thm, T_def] MRSL @{thm typedef_rep_transfer}])
   217         [[typedef_thm, T_def] MRSL @{thm typedef_rep_transfer}])
   196       |> (snd oo Local_Theory.note) ((qualify "right_unique", [transfer_attr]), 
   218       |> (snd oo Local_Theory.note) ((qualify "right_unique", [transfer_attr]), 
   197         [[quot_thm] MRSL @{thm Quotient_right_unique}])
   219         [[quot_thm] MRSL @{thm Quotient_right_unique}])
   198       |> (snd oo Local_Theory.note) ((qualify "right_total", [transfer_attr]), 
   220       |> (snd oo Local_Theory.note) ((qualify "right_total", [transfer_attr]), 
   199         [[quot_thm] MRSL @{thm Quotient_right_total}])
   221         [[quot_thm] MRSL @{thm Quotient_right_total}])
   200       |> setup_lifting_infr gen_abs_code quot_thm
   222       |> setup_lifting_infr gen_code quot_thm maybe_reflp_thm
   201   end
   223   end
   202 
   224 
   203 fun setup_lifting_cmd gen_abs_code xthm opt_reflp_xthm lthy =
   225 fun setup_lifting_cmd gen_code xthm opt_reflp_xthm lthy =
   204   let 
   226   let 
   205     val input_thm = singleton (Attrib.eval_thms lthy) xthm
   227     val input_thm = singleton (Attrib.eval_thms lthy) xthm
   206     val input_term = (HOLogic.dest_Trueprop o prop_of) input_thm
   228     val input_term = (HOLogic.dest_Trueprop o prop_of) input_thm
   207       handle TERM _ => error "Unsupported type of a theorem. Only Quotient or type_definition are supported."
   229       handle TERM _ => error "Unsupported type of a theorem. Only Quotient or type_definition are supported."
   208 
   230 
   221         SOME reflp_xthm => 
   243         SOME reflp_xthm => 
   222           let
   244           let
   223             val reflp_thm = singleton (Attrib.eval_thms lthy) reflp_xthm
   245             val reflp_thm = singleton (Attrib.eval_thms lthy) reflp_xthm
   224             val _ = sanity_check_reflp_thm reflp_thm
   246             val _ = sanity_check_reflp_thm reflp_thm
   225           in
   247           in
   226             setup_by_quotient gen_abs_code input_thm (SOME reflp_thm) lthy
   248             setup_by_quotient gen_code input_thm (SOME reflp_thm) lthy
   227           end
   249           end
   228         | NONE => setup_by_quotient gen_abs_code input_thm NONE lthy
   250         | NONE => setup_by_quotient gen_code input_thm NONE lthy
   229 
   251 
   230     fun setup_typedef () = 
   252     fun setup_typedef () = 
   231       case opt_reflp_xthm of
   253       case opt_reflp_xthm of
   232         SOME _ => error "The reflexivity theorem cannot be specified if the type_definition theorem is used."
   254         SOME _ => error "The reflexivity theorem cannot be specified if the type_definition theorem is used."
   233         | NONE => setup_by_typedef_thm gen_abs_code input_thm lthy
   255         | NONE => setup_by_typedef_thm gen_code input_thm lthy
   234   in
   256   in
   235     case input_term of
   257     case input_term of
   236       (Const (@{const_name Quotient}, _) $ _ $ _ $ _ $ _) => setup_quotient ()
   258       (Const (@{const_name Quotient}, _) $ _ $ _ $ _ $ _) => setup_quotient ()
   237       | (Const (@{const_name type_definition}, _) $ _ $ _ $ _) => setup_typedef ()
   259       | (Const (@{const_name type_definition}, _) $ _ $ _ $ _) => setup_typedef ()
   238       | _ => error "Unsupported type of a theorem. Only Quotient or type_definition are supported."
   260       | _ => error "Unsupported type of a theorem. Only Quotient or type_definition are supported."
   239   end
   261   end
   240 
   262 
   241 val opt_gen_abs_code =
   263 val opt_gen_code =
   242   Scan.optional (@{keyword "("} |-- Parse.!!! ((Parse.reserved "no_abs_code" >> K false) --| @{keyword ")"})) true
   264   Scan.optional (@{keyword "("} |-- Parse.!!! ((Parse.reserved "no_code" >> K false) --| @{keyword ")"})) true
   243 
   265 
   244 val _ = 
   266 val _ = 
   245   Outer_Syntax.local_theory @{command_spec "setup_lifting"}
   267   Outer_Syntax.local_theory @{command_spec "setup_lifting"}
   246     "Setup lifting infrastructure" 
   268     "Setup lifting infrastructure" 
   247       (opt_gen_abs_code -- Parse_Spec.xthm -- Scan.option Parse_Spec.xthm >> 
   269       (opt_gen_code -- Parse_Spec.xthm -- Scan.option Parse_Spec.xthm >> 
   248         (fn ((gen_abs_code, xthm), opt_reflp_xthm) => setup_lifting_cmd gen_abs_code xthm opt_reflp_xthm))
   270         (fn ((gen_code, xthm), opt_reflp_xthm) => setup_lifting_cmd gen_code xthm opt_reflp_xthm))
   249 end;
   271 end;