src/HOL/Tools/Lifting/lifting_def_code_dt.ML
changeset 66017 57acac0fd29b
parent 63352 4eaf35781b23
child 67713 041898537c19
equal deleted inserted replaced
66016:39d9a59d8d94 66017:57acac0fd29b
   144 
   144 
   145 val all_code_dt_of = all_code_dt_of_generic o Context.Proof;
   145 val all_code_dt_of = all_code_dt_of_generic o Context.Proof;
   146 val all_code_dt_of_global = all_code_dt_of_generic o Context.Theory;
   146 val all_code_dt_of_global = all_code_dt_of_generic o Context.Theory;
   147 
   147 
   148 fun update_code_dt code_dt =
   148 fun update_code_dt code_dt =
   149   Local_Theory.declaration {syntax = false, pervasive = true}
   149   Local_Theory.open_target #> snd
   150     (fn phi => Data.map (Item_Net.update (morph_code_dt phi code_dt)));
   150   #> Local_Theory.declaration {syntax = false, pervasive = true}
       
   151     (fn phi => Data.map (Item_Net.update (morph_code_dt phi code_dt)))
       
   152   #> Local_Theory.close_target
   151 
   153 
   152 fun mk_match_of_code_dt qty code_dt = Vartab.empty |> Type.raw_match (qty_of_code_dt code_dt, qty)
   154 fun mk_match_of_code_dt qty code_dt = Vartab.empty |> Type.raw_match (qty_of_code_dt code_dt, qty)
   153   |> Vartab.dest |> map (fn (x, (S, T)) => (TVar (x, S), T));
   155   |> Vartab.dest |> map (fn (x, (S, T)) => (TVar (x, S), T));
   154 
   156 
   155 fun mk_witness_of_code_dt qty code_dt =
   157 fun mk_witness_of_code_dt qty code_dt =
   209       let
   211       let
   210         val (wit, wit_thm) = (mk_witness quot_thm
   212         val (wit, wit_thm) = (mk_witness quot_thm
   211           handle THM _ => error ("code_dt: " ^ quote (Tname qty) ^ " was not defined as a subtype."))
   213           handle THM _ => error ("code_dt: " ^ quote (Tname qty) ^ " was not defined as a subtype."))
   212         val code_dt = mk_code_dt rty qty wit wit_thm NONE
   214         val code_dt = mk_code_dt rty qty wit wit_thm NONE
   213       in
   215       in
   214         (quot_thm, (update_code_dt code_dt lthy |> Local_Theory.reset, rel_eq_onps))
   216         (quot_thm, (update_code_dt code_dt lthy, rel_eq_onps))
   215       end
   217       end
   216     else
   218     else
   217       (quot_thm, (lthy, rel_eq_onps))
   219       (quot_thm, (lthy, rel_eq_onps))
   218   end;
   220   end;
   219 
   221 
   325       (@{thm eq_onp_top_eq_eq[symmetric]} :: Lifting_Info.get_relator_eq_onp_rules ctxt))
   327       (@{thm eq_onp_top_eq_eq[symmetric]} :: Lifting_Info.get_relator_eq_onp_rules ctxt))
   326     fun lift_isom_tac ctxt = HEADGOAL (eq_onp_to_top_tac ctxt
   328     fun lift_isom_tac ctxt = HEADGOAL (eq_onp_to_top_tac ctxt
   327       THEN' (rtac ctxt @{thm id_transfer}));
   329       THEN' (rtac ctxt @{thm id_transfer}));
   328 
   330 
   329     val (rep_isom_lift_def, lthy) =
   331     val (rep_isom_lift_def, lthy) =
   330       lift_def ld_no_notes (Binding.qualify_name true uTname "Rep_isom", NoSyn)
   332       lthy
   331       (qty_isom --> qty) (HOLogic.id_const rty) lift_isom_tac [] lthy
   333       |> Local_Theory.open_target |> snd
   332       |> apfst (inst_of_lift_def lthy (qty_isom --> qty));
   334       |> lift_def ld_no_notes (Binding.qualify_name true uTname "Rep_isom", NoSyn)
       
   335         (qty_isom --> qty) (HOLogic.id_const rty) lift_isom_tac []
       
   336       |>> inst_of_lift_def lthy (qty_isom --> qty);
   333     val (abs_isom, lthy) =
   337     val (abs_isom, lthy) =
   334       lift_def ld_no_notes (Binding.qualify_name true uTname "Abs_isom", NoSyn)
   338       lthy
   335       (qty --> qty_isom) (HOLogic.id_const rty) lift_isom_tac [] lthy
   339       |> lift_def ld_no_notes (Binding.qualify_name true uTname "Abs_isom", NoSyn)
   336       |> apfst (mk_lift_const_of_lift_def (qty --> qty_isom));
   340         (qty --> qty_isom) (HOLogic.id_const rty) lift_isom_tac []
       
   341       |>> mk_lift_const_of_lift_def (qty --> qty_isom);
   337     val rep_isom = lift_const_of_lift_def rep_isom_lift_def
   342     val rep_isom = lift_const_of_lift_def rep_isom_lift_def
   338 
   343 
   339     val pointer = Lifting_Setup.pointer_of_bundle_binding lthy qty_isom_bundle
   344     val pointer = Lifting_Setup.pointer_of_bundle_binding lthy qty_isom_bundle
   340     fun code_dt phi context = code_dt_of lthy (rty, qty) |> the |>
   345     fun code_dt phi context = code_dt_of lthy (rty, qty) |> the |>
   341       update_rep_isom rep_isom (transfer_rules_of_lift_def rep_isom_lift_def |> hd)
   346       update_rep_isom rep_isom (transfer_rules_of_lift_def rep_isom_lift_def |> hd)
   342        (bundle_name_of_bundle_binding qty_isom_bundle phi context) pointer;
   347        (bundle_name_of_bundle_binding qty_isom_bundle phi context) pointer;
   343     val lthy = lthy  
   348     val lthy = lthy  
   344       |> Local_Theory.declaration {syntax = false, pervasive = true}
   349       |> Local_Theory.declaration {syntax = false, pervasive = true}
   345         (fn phi => fn context => Data.map (Item_Net.update (morph_code_dt phi (code_dt phi context))) context)
   350         (fn phi => fn context => Data.map (Item_Net.update (morph_code_dt phi (code_dt phi context))) context)
   346       |> Local_Theory.reset
   351       |> Local_Theory.close_target
   347 
   352 
   348     (* in order to make the qty qty_isom isomorphism executable we have to define discriminators 
   353     (* in order to make the qty qty_isom isomorphism executable we have to define discriminators 
   349       and selectors for qty_isom *)
   354       and selectors for qty_isom *)
   350     val (rty_name, typs) = dest_Type rty
   355     val (rty_name, typs) = dest_Type rty
   351     val (_, qty_typs) = dest_Type qty
   356     val (_, qty_typs) = dest_Type qty
   402     val dis_qty = qty_isom --> HOLogic.boolT;
   407     val dis_qty = qty_isom --> HOLogic.boolT;
   403     val dis_names = map (fn k => Binding.qualify_name true uTname ("dis" ^ string_of_int k)) ks;
   408     val dis_names = map (fn k => Binding.qualify_name true uTname ("dis" ^ string_of_int k)) ks;
   404 
   409 
   405     val (diss, lthy) = @{fold_map 2} (fn b => fn rhs => fn lthy =>
   410     val (diss, lthy) = @{fold_map 2} (fn b => fn rhs => fn lthy =>
   406       lift_def ld_no_notes (b, NoSyn) dis_qty rhs (K all_tac) [] lthy
   411       lift_def ld_no_notes (b, NoSyn) dis_qty rhs (K all_tac) [] lthy
   407       |> apfst (mk_lift_const_of_lift_def dis_qty)) dis_names dis_rhs lthy
   412       |>> mk_lift_const_of_lift_def dis_qty) dis_names dis_rhs lthy
   408 
   413 
   409     val unfold_lift_sel_rsp = @{lemma "(\<And>x. P1 x \<Longrightarrow> P2 (f x)) \<Longrightarrow> (rel_fun (eq_onp P1) (eq_onp P2)) f f"
   414     val unfold_lift_sel_rsp = @{lemma "(\<And>x. P1 x \<Longrightarrow> P2 (f x)) \<Longrightarrow> (rel_fun (eq_onp P1) (eq_onp P2)) f f"
   410       by (simp add: eq_onp_same_args rel_fun_eq_onp_rel)}
   415       by (simp add: eq_onp_same_args rel_fun_eq_onp_rel)}
   411 
   416 
   412     fun lift_sel_tac exhaust_rule dt_rules wits ctxt i =
   417     fun lift_sel_tac exhaust_rule dt_rules wits ctxt i =
   424         map (fn k' => Binding.qualify_name true uTname ("sel" ^ string_of_int k ^ string_of_int k'))
   429         map (fn k' => Binding.qualify_name true uTname ("sel" ^ string_of_int k ^ string_of_int k'))
   425           (1 upto length xs)) (ks ~~ ctr_Tss);
   430           (1 upto length xs)) (ks ~~ ctr_Tss);
   426     val (selss, lthy) = @{fold_map 2} (@{fold_map 2} (fn b => fn (qty_ret, wits, rhs) => fn lthy =>
   431     val (selss, lthy) = @{fold_map 2} (@{fold_map 2} (fn b => fn (qty_ret, wits, rhs) => fn lthy =>
   427         lift_def_code_dt { code_dt = true, lift_config = ld_no_notes }
   432         lift_def_code_dt { code_dt = true, lift_config = ld_no_notes }
   428         (b, NoSyn) (qty_isom --> qty_ret) rhs (HEADGOAL o sel_tac wits) [] lthy
   433         (b, NoSyn) (qty_isom --> qty_ret) rhs (HEADGOAL o sel_tac wits) [] lthy
   429       |> apfst (mk_lift_const_of_lift_def (qty_isom --> qty_ret)))) sel_names sel_rhs lthy
   434       |>> mk_lift_const_of_lift_def (qty_isom --> qty_ret))) sel_names sel_rhs lthy
   430 
   435 
   431     (* now we can execute the qty qty_isom isomorphism *)
   436     (* now we can execute the qty qty_isom isomorphism *)
   432     fun mk_type_definition newT oldT RepC AbsC A =
   437     fun mk_type_definition newT oldT RepC AbsC A =
   433       let
   438       let
   434         val typedefC =
   439         val typedefC =
   559   in
   564   in
   560     if is_none (code_dt_of lthy (rty, qty)) then
   565     if is_none (code_dt_of lthy (rty, qty)) then
   561       let
   566       let
   562         val non_empty_pred = quot_thm RS @{thm type_definition_Quotient_not_empty}
   567         val non_empty_pred = quot_thm RS @{thm type_definition_Quotient_not_empty}
   563         val pred = quot_thm_rel quot_thm |> dest_comb |> snd;
   568         val pred = quot_thm_rel quot_thm |> dest_comb |> snd;
   564         val (pred, lthy) = yield_singleton (Variable.import_terms true) pred lthy;
   569         val (pred, lthy) =
       
   570           lthy
       
   571           |> Local_Theory.open_target |> snd
       
   572           |> yield_singleton (Variable.import_terms true) pred;
   565         val TFrees = Term.add_tfreesT qty []
   573         val TFrees = Term.add_tfreesT qty []
   566 
   574 
   567         fun non_empty_typedef_tac non_empty_pred ctxt i =
   575         fun non_empty_typedef_tac non_empty_pred ctxt i =
   568           (Method.insert_tac ctxt [non_empty_pred] THEN' 
   576           (Method.insert_tac ctxt [non_empty_pred] THEN' 
   569             SELECT_GOAL (Local_Defs.unfold0_tac ctxt [mem_Collect_eq]) THEN' assume_tac ctxt) i
   577             SELECT_GOAL (Local_Defs.unfold0_tac ctxt [mem_Collect_eq]) THEN' assume_tac ctxt) i
   572         val ((_, tcode_dt), lthy) = conceal_naming_result (typedef (Binding.concealed uTname, TFrees, NoSyn)
   580         val ((_, tcode_dt), lthy) = conceal_naming_result (typedef (Binding.concealed uTname, TFrees, NoSyn)
   573           Tdef_set NONE (fn lthy => HEADGOAL (non_empty_typedef_tac non_empty_pred lthy))) lthy;
   581           Tdef_set NONE (fn lthy => HEADGOAL (non_empty_typedef_tac non_empty_pred lthy))) lthy;
   574         val type_definition_thm = tcode_dt |> snd |> #type_definition;
   582         val type_definition_thm = tcode_dt |> snd |> #type_definition;
   575         val qty_isom = tcode_dt |> fst |> #abs_type;
   583         val qty_isom = tcode_dt |> fst |> #abs_type;
   576 
   584 
   577         val config = { notes = false}
   585         val (binding, lthy) =
   578         val (binding, lthy) = conceal_naming_result (Lifting_Setup.setup_by_typedef_thm
   586           lthy
   579           config type_definition_thm) lthy
   587           |> conceal_naming_result (Lifting_Setup.setup_by_typedef_thm
   580         val lthy = Local_Theory.reset lthy
   588               { notes = false } type_definition_thm)
       
   589           ||> Local_Theory.close_target
   581         val (wit, wit_thm) = mk_witness quot_thm;
   590         val (wit, wit_thm) = mk_witness quot_thm;
   582         val code_dt = mk_code_dt rty qty wit wit_thm NONE;
   591         val code_dt = mk_code_dt rty qty wit wit_thm NONE;
   583         val lthy = lthy
   592         val lthy = lthy
   584           |> update_code_dt code_dt
   593           |> update_code_dt code_dt
   585           |> Local_Theory.reset
       
   586           |> mk_rep_isom binding (rty, qty, qty_isom) |> snd
   594           |> mk_rep_isom binding (rty, qty, qty_isom) |> snd
   587       in
   595       in
   588         (quot_thm, (lthy, rel_eq_onps))
   596         (quot_thm, (lthy, rel_eq_onps))
   589       end
   597       end
   590     else
   598     else