src/HOL/Tools/Lifting/lifting_def_code_dt.ML
changeset 60231 0daab758e087
parent 60230 4857d553c52c
child 60232 29ac1c6a1fbb
equal deleted inserted replaced
60230:4857d553c52c 60231:0daab758e087
    44     local_theory -> Proof.state
    44     local_theory -> Proof.state
    45 end
    45 end
    46 
    46 
    47 structure Lifting_Def_Code_Dt: LIFTING_DEF_CODE_DT =
    47 structure Lifting_Def_Code_Dt: LIFTING_DEF_CODE_DT =
    48 struct
    48 struct
    49 
    49                                                                        
    50 open Ctr_Sugar_Util BNF_Util BNF_FP_Util BNF_FP_Def_Sugar Lifting_Def Lifting_Util
    50 open Ctr_Sugar_Util BNF_Util BNF_FP_Util BNF_FP_Def_Sugar Lifting_Def Lifting_Util
       
    51 
       
    52 infix 0 MRSL
    51 
    53 
    52 (** data structures **)
    54 (** data structures **)
    53 
    55 
    54 (* all type variables in qty are in rty *)
    56 (* all type variables in qty are in rty *)
    55 datatype rep_isom_data = REP_ISOM of { isom: term, transfer: thm, bundle_name: string, pointer: string }
    57 datatype rep_isom_data = REP_ISOM of { isom: term, transfer: thm, bundle_name: string, pointer: string }
   270             val qty_isom = qty_isom_of_rep_isom rep_isom
   272             val qty_isom = qty_isom_of_rep_isom rep_isom
   271             val f'_var = (Binding.suffix_name "_aux" (fst var), NoSyn);
   273             val f'_var = (Binding.suffix_name "_aux" (fst var), NoSyn);
   272             val f'_qty = strip_type qty |> fst |> rpair qty_isom |> op --->
   274             val f'_qty = strip_type qty |> fst |> rpair qty_isom |> op --->
   273             val f'_rsp_rel = Lifting_Term.equiv_relation lthy (rty, f'_qty);
   275             val f'_rsp_rel = Lifting_Term.equiv_relation lthy (rty, f'_qty);
   274             val rsp = rsp_thm_of_lift_def lift_def
   276             val rsp = rsp_thm_of_lift_def lift_def
   275             val rel_eq_onps_conv = HOLogic.Trueprop_conv (ret_rel_conv (R_conv rel_eq_onps))
   277             val rel_eq_onps_conv = HOLogic.Trueprop_conv (Conv.fun2_conv (ret_rel_conv (R_conv rel_eq_onps)))
   276             val rsp_norm = Conv.fconv_rule rel_eq_onps_conv rsp
   278             val rsp_norm = Conv.fconv_rule rel_eq_onps_conv rsp
   277             val f'_rsp_goal = HOLogic.mk_Trueprop (f'_rsp_rel $ rhs $ rhs);
   279             val f'_rsp_goal = HOLogic.mk_Trueprop (f'_rsp_rel $ rhs $ rhs);
   278             val f'_rsp = Goal.prove_sorry lthy [] [] f'_rsp_goal
   280             val f'_rsp = Goal.prove_sorry lthy [] [] f'_rsp_goal
   279               (K (HEADGOAL (CONVERSION (rel_eq_onps_conv) THEN' rtac rsp_norm)))
   281               (K (HEADGOAL (CONVERSION (rel_eq_onps_conv) THEN' rtac rsp_norm)))
   280               |> Thm.close_derivation
   282               |> Thm.close_derivation
   364 
   366 
   365     val (diss, lthy) = @{fold_map 2} (fn b => fn rhs => fn lthy =>
   367     val (diss, lthy) = @{fold_map 2} (fn b => fn rhs => fn lthy =>
   366       lift_def ld_no_notes (b, NoSyn) dis_qty rhs (K all_tac) [] lthy
   368       lift_def ld_no_notes (b, NoSyn) dis_qty rhs (K all_tac) [] lthy
   367       |> apfst (mk_lift_const_of_lift_def dis_qty)) dis_names dis_rhs lthy
   369       |> apfst (mk_lift_const_of_lift_def dis_qty)) dis_names dis_rhs lthy
   368 
   370 
       
   371     fun eq_onp_to_top_tac ctxt = SELECT_GOAL (Local_Defs.unfold_tac ctxt 
       
   372       (@{thm eq_onp_top_eq_eq[symmetric]} :: Lifting_Info.get_relator_eq_onp_rules ctxt))
       
   373 
       
   374     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"
       
   375       by (simp add: eq_onp_same_args rel_fun_eq_onp_rel)}
       
   376 
   369     fun lift_sel_tac exhaust_rule dt_rules wits ctxt i =
   377     fun lift_sel_tac exhaust_rule dt_rules wits ctxt i =
   370       (Method.insert_tac wits THEN' case_tac exhaust_rule ctxt THEN_ALL_NEW (
   378         (Method.insert_tac wits THEN' 
   371       EVERY' [hyp_subst_tac ctxt, Raw_Simplifier.rewrite_goal_tac ctxt (map safe_mk_meta_eq dt_rules),
   379          eq_onp_to_top_tac ctxt THEN' (* normalize *)
       
   380          rtac unfold_lift_sel_rsp THEN'
       
   381          case_tac exhaust_rule ctxt THEN_ALL_NEW (
       
   382         EVERY' [hyp_subst_tac ctxt, (* does not kill wits because = was rewritten to eq_onp top *)
       
   383         Raw_Simplifier.rewrite_goal_tac ctxt (map safe_mk_meta_eq dt_rules), 
   372         REPEAT_DETERM o etac conjE, atac])) i
   384         REPEAT_DETERM o etac conjE, atac])) i
   373     val pred_simps = Transfer.lookup_pred_data lthy (Tname rty) |> the |> Transfer.pred_simps
   385     val pred_simps = Transfer.lookup_pred_data lthy (Tname rty) |> the |> Transfer.pred_simps
   374     val sel_tac = lift_sel_tac (#exhaust ctr_sugar) (#case_thms ctr_sugar @ pred_simps)
   386     val sel_tac = lift_sel_tac (#exhaust ctr_sugar) (#case_thms ctr_sugar @ pred_simps)
   375     val sel_names = map (fn (k, xs) => map (fn k' => Binding.qualified true
   387     val sel_names = map (fn (k, xs) => map (fn k' => Binding.qualified true
   376       ("sel" ^ string_of_int k ^ string_of_int k') uTname) (1 upto length xs)) (ks ~~ ctr_Tss);
   388       ("sel" ^ string_of_int k ^ string_of_int k') uTname) (1 upto length xs)) (ks ~~ ctr_Tss);
   377     val (selss, lthy) = @{fold_map 2} (@{fold_map 2} (fn b => fn ((_, qty_ret), wits, rhs) => fn lthy =>
   389     val (selss, lthy) = @{fold_map 2} (@{fold_map 2} (fn b => fn ((_, qty_ret), wits, rhs) => fn lthy =>
   378       lift_def_code_dt { code_dt = true, lift_config = ld_no_notes }
   390         lift_def_code_dt { code_dt = true, lift_config = ld_no_notes }
   379         (b, NoSyn) (qty_isom --> qty_ret) rhs (HEADGOAL o sel_tac wits) [] lthy
   391         (b, NoSyn) (qty_isom --> qty_ret) rhs (HEADGOAL o sel_tac wits) [] lthy
   380       |> apfst (mk_lift_const_of_lift_def (qty_isom --> qty_ret)))) sel_names sel_rhs lthy
   392       |> apfst (mk_lift_const_of_lift_def (qty_isom --> qty_ret)))) sel_names sel_rhs lthy
   381 
   393 
   382     fun lift_isom_tac ctxt = Local_Defs.unfold_tac ctxt [id_apply] THEN HEADGOAL atac;
   394     fun lift_isom_tac ctxt = HEADGOAL (eq_onp_to_top_tac ctxt
       
   395       THEN' (rtac @{thm id_transfer}));
   383 
   396 
   384     val (rep_isom_lift_def, lthy) = lift_def ld_no_notes (Binding.qualified true "Rep_isom" uTname, NoSyn)
   397     val (rep_isom_lift_def, lthy) = lift_def ld_no_notes (Binding.qualified true "Rep_isom" uTname, NoSyn)
   385       (qty_isom --> qty) (HOLogic.id_const rty) lift_isom_tac [] lthy
   398       (qty_isom --> qty) (HOLogic.id_const rty) lift_isom_tac [] lthy
   386       |> apfst (inst_of_lift_def lthy (qty_isom --> qty));
   399       |> apfst (inst_of_lift_def lthy (qty_isom --> qty));
   387     val (abs_isom, lthy) = lift_def ld_no_notes (Binding.qualified true "Abs_isom" uTname, NoSyn)
   400     val (abs_isom, lthy) = lift_def ld_no_notes (Binding.qualified true "Abs_isom" uTname, NoSyn)
   388       (qty --> qty_isom) (HOLogic.id_const rty) lift_isom_tac [] lthy
   401       (qty --> qty_isom) (HOLogic.id_const rty) lift_isom_tac [] lthy
   389       |> apfst (mk_lift_const_of_lift_def (qty --> qty_isom));
   402       |> apfst (mk_lift_const_of_lift_def (qty --> qty_isom));
   390 
       
   391     fun mk_type_definition newT oldT RepC AbsC A =
   403     fun mk_type_definition newT oldT RepC AbsC A =
   392       let
   404       let
   393         val typedefC =
   405         val typedefC =
   394           Const (@{const_name type_definition},
   406           Const (@{const_name type_definition},
   395             (newT --> oldT) --> (oldT --> newT) --> HOLogic.mk_setT oldT --> HOLogic.boolT);
   407             (newT --> oldT) --> (oldT --> newT) --> HOLogic.mk_setT oldT --> HOLogic.boolT);
   396       in typedefC $ RepC $ AbsC $ A end;
   408       in typedefC $ RepC $ AbsC $ A end;
   397 
   409 
   398     val rep_isom = lift_const_of_lift_def rep_isom_lift_def
   410     val rep_isom = lift_const_of_lift_def rep_isom_lift_def
   399     val typedef_goal = mk_type_definition qty_isom qty rep_isom abs_isom (HOLogic.mk_UNIV qty) |>
   411     val typedef_goal = mk_type_definition qty_isom qty rep_isom abs_isom (HOLogic.mk_UNIV qty) |>
   400       HOLogic.mk_Trueprop;
   412       HOLogic.mk_Trueprop;
   401 
   413     fun typ_isom_tac ctxt i =
   402       fun typ_isom_tac ctxt i =
   414       EVERY' [ SELECT_GOAL (Local_Defs.unfold_tac ctxt @{thms type_definition_def}),
   403         EVERY' [ SELECT_GOAL (Local_Defs.unfold_tac ctxt @{thms type_definition_def}),
   415         DETERM o Transfer.transfer_tac true ctxt,
   404           DETERM o Transfer.transfer_tac true ctxt, Raw_Simplifier.rewrite_goal_tac ctxt
   416           SELECT_GOAL (Local_Defs.unfold_tac ctxt @{thms eq_onp_top_eq_eq}) (* normalize *), 
   405             (map safe_mk_meta_eq @{thms id_apply simp_thms Ball_def}),
   417           Raw_Simplifier.rewrite_goal_tac ctxt 
   406            rtac TrueI] i;
   418           (map safe_mk_meta_eq @{thms id_apply simp_thms Ball_def}),
       
   419          rtac TrueI] i;
   407 
   420 
   408     val (_, transfer_lthy) = Proof_Context.note_thmss "" [((Binding.empty, []),
   421     val (_, transfer_lthy) = Proof_Context.note_thmss "" [((Binding.empty, []),
   409       [(@{thms right_total_UNIV_transfer},[Transfer.transfer_add]),
   422       [(@{thms right_total_UNIV_transfer},[Transfer.transfer_add]),
   410        (@{thms Domain_eq_top}, [Transfer.transfer_domain_add]) ])] lthy;
   423        (@{thms Domain_eq_top}, [Transfer.transfer_domain_add]) ])] lthy;
   411 
   424 
   412     val quot_thm_isom = Goal.prove_sorry transfer_lthy [] [] typedef_goal
   425     val quot_thm_isom = Goal.prove_sorry transfer_lthy [] [] typedef_goal
   413       (fn {context = ctxt, prems = _} => typ_isom_tac ctxt 1)
   426       (fn {context = ctxt, prems = _} => typ_isom_tac ctxt 1)
   414       |> Thm.close_derivation
   427       |> Thm.close_derivation
   415       |> singleton (Variable.export transfer_lthy lthy)
   428       |> singleton (Variable.export transfer_lthy lthy)
   416       |> (fn thm => @{thm UNIV_typedef_to_Quotient} OF [thm, @{thm reflexive}])
   429       |> (fn thm => @{thm UNIV_typedef_to_Quotient} OF [thm, @{thm reflexive}])
   417 
       
   418     val qty_isom_name = Tname qty_isom;
   430     val qty_isom_name = Tname qty_isom;
   419 
   431     
   420     val quot_isom_rep =
   432     val quot_isom_rep =
   421       let
   433       let
   422         val (quotients : Lifting_Term.quotients) = Symtab.insert (Lifting_Info.quotient_eq) (qty_isom_name,
   434         val (quotients : Lifting_Term.quotients) = Symtab.insert (Lifting_Info.quotient_eq) (qty_isom_name,
   423           {quot_thm = quot_thm_isom, pcr_info = NONE}) Symtab.empty
   435           {quot_thm = quot_thm_isom, pcr_info = NONE}) Symtab.empty
   424         val id_actions = { constr = K I, lift = K I, comp_lift = K I }
   436         val id_actions = { constr = K I, lift = K I, comp_lift = K I }
   483 
   495 
   484     val rep_isom_code = Goal.prove_sorry lthy [] [] rep_isom_code_goal
   496     val rep_isom_code = Goal.prove_sorry lthy [] [] rep_isom_code_goal
   485       (fn {context = ctxt, prems = _} => rep_isom_code_tac ctr_sugar ctxt 1)
   497       (fn {context = ctxt, prems = _} => rep_isom_code_tac ctr_sugar ctxt 1)
   486       |> Thm.close_derivation
   498       |> Thm.close_derivation
   487       |> singleton(Variable.export lthy x_lthy)
   499       |> singleton(Variable.export lthy x_lthy)
   488 
       
   489     val lthy = x_lthy
   500     val lthy = x_lthy
   490     val pointer = Lifting_Setup.pointer_of_bundle_binding lthy qty_isom_bundle
   501     val pointer = Lifting_Setup.pointer_of_bundle_binding lthy qty_isom_bundle
   491     fun code_dt phi context = code_dt_of lthy (rty, qty) |> the |>
   502     fun code_dt phi context = code_dt_of lthy (rty, qty) |> the |>
   492       update_rep_isom rep_isom (transfer_rules_of_lift_def rep_isom_lift_def |> hd)
   503       update_rep_isom rep_isom (transfer_rules_of_lift_def rep_isom_lift_def |> hd)
   493        (bundle_name_of_bundle_binding qty_isom_bundle phi context) pointer;
   504        (bundle_name_of_bundle_binding qty_isom_bundle phi context) pointer;
   508     val rty_name = Tname rty;
   519     val rty_name = Tname rty;
   509     val pred_data = Transfer.lookup_pred_data lthy rty_name
   520     val pred_data = Transfer.lookup_pred_data lthy rty_name
   510     val pred_data = if is_some pred_data then the pred_data
   521     val pred_data = if is_some pred_data then the pred_data
   511       else error ("code_dt: " ^ quote rty_name ^ " is not a datatype.")
   522       else error ("code_dt: " ^ quote rty_name ^ " is not a datatype.")
   512     val rel_eq_onp = safe_mk_meta_eq (Transfer.rel_eq_onp pred_data);
   523     val rel_eq_onp = safe_mk_meta_eq (Transfer.rel_eq_onp pred_data);
       
   524     val rel_eq_onps = insert Thm.eq_thm rel_eq_onp rel_eq_onps
   513     val R_conv = Transfer.top_sweep_rewr_conv @{thms eq_onp_top_eq_eq[symmetric, THEN eq_reflection]}
   525     val R_conv = Transfer.top_sweep_rewr_conv @{thms eq_onp_top_eq_eq[symmetric, THEN eq_reflection]}
   514       then_conv Conv.rewr_conv rel_eq_onp
   526       then_conv Conv.rewr_conv rel_eq_onp
   515     val quot_thm = Conv.fconv_rule(HOLogic.Trueprop_conv (Quotient_R_conv R_conv)) quot_thm;
   527     val quot_thm = Conv.fconv_rule(HOLogic.Trueprop_conv (Quotient_R_conv R_conv)) quot_thm;
   516   in
   528   in
   517     if is_none (code_dt_of lthy (rty, qty)) then
   529     if is_none (code_dt_of lthy (rty, qty)) then
   520         val pred = quot_thm_rel quot_thm |> dest_comb |> snd;
   532         val pred = quot_thm_rel quot_thm |> dest_comb |> snd;
   521         val (pred, lthy) = yield_singleton (Variable.import_terms true) pred lthy;
   533         val (pred, lthy) = yield_singleton (Variable.import_terms true) pred lthy;
   522         val TFrees = Term.add_tfreesT qty []
   534         val TFrees = Term.add_tfreesT qty []
   523 
   535 
   524         fun non_empty_typedef_tac non_empty_pred ctxt i =
   536         fun non_empty_typedef_tac non_empty_pred ctxt i =
   525           (SELECT_GOAL (Local_Defs.unfold_tac ctxt [mem_Collect_eq]) THEN' rtac non_empty_pred) i
   537           (Method.insert_tac [non_empty_pred] THEN' 
   526 
   538             SELECT_GOAL (Local_Defs.unfold_tac ctxt [mem_Collect_eq]) THEN' atac) i
   527         val uTname = unique_Tname (rty, qty)
   539         val uTname = unique_Tname (rty, qty)
   528         val Tdef_set = HOLogic.mk_Collect ("x", rty, pred $ Free("x", rty));
   540         val Tdef_set = HOLogic.mk_Collect ("x", rty, pred $ Free("x", rty));
   529         val ((_, tcode_dt), lthy) = conceal_naming_result (typedef (Binding.concealed uTname, TFrees, NoSyn)
   541         val ((_, tcode_dt), lthy) = conceal_naming_result (typedef (Binding.concealed uTname, TFrees, NoSyn)
   530           Tdef_set NONE (fn lthy => non_empty_typedef_tac non_empty_pred lthy 1)) lthy;
   542           Tdef_set NONE (fn lthy => HEADGOAL (non_empty_typedef_tac non_empty_pred lthy))) lthy;
   531         val type_definition_thm = tcode_dt |> snd |> #type_definition;
   543         val type_definition_thm = tcode_dt |> snd |> #type_definition;
   532         val qty_isom = tcode_dt |> fst |> #abs_type;
   544         val qty_isom = tcode_dt |> fst |> #abs_type;
   533 
   545 
   534         val config = { notes = false}
   546         val config = { notes = false}
   535         val (binding, lthy) = conceal_naming_result (Lifting_Setup.setup_by_typedef_thm
   547         val (binding, lthy) = conceal_naming_result (Lifting_Setup.setup_by_typedef_thm
   540         val lthy = lthy
   552         val lthy = lthy
   541           |> update_code_dt code_dt
   553           |> update_code_dt code_dt
   542           |> Local_Theory.restore
   554           |> Local_Theory.restore
   543           |> mk_rep_isom binding (rty, qty, qty_isom) |> snd
   555           |> mk_rep_isom binding (rty, qty, qty_isom) |> snd
   544       in
   556       in
   545         (quot_thm, (lthy, rel_eq_onp :: rel_eq_onps))
   557         (quot_thm, (lthy, rel_eq_onps))
   546       end
   558       end
   547     else
   559     else
   548       (quot_thm, (lthy, rel_eq_onp :: rel_eq_onps))
   560       (quot_thm, (lthy, rel_eq_onps))
   549   end
   561   end
   550 and lift_def_code_dt config var qty rhs tac par_thms lthy = gen_lift_def (add_lift_def_code_dt config)
   562 and lift_def_code_dt config var qty rhs tac par_thms lthy = gen_lift_def (add_lift_def_code_dt config)
   551   var qty rhs tac par_thms lthy
   563   var qty rhs tac par_thms lthy
   552 
   564 
   553 
   565 
   574 
   586 
   575   lift_definition command. It opens a proof of a corresponding respectfulness
   587   lift_definition command. It opens a proof of a corresponding respectfulness
   576   theorem in a user-friendly, readable form. Then add_lift_def_code_dt is called internally.
   588   theorem in a user-friendly, readable form. Then add_lift_def_code_dt is called internally.
   577 
   589 
   578 **)
   590 **)
       
   591 
       
   592 local
       
   593   val eq_onp_assms_tac_fixed_rules = map (Transfer.prep_transfer_domain_thm @{context})
       
   594     [@{thm pcr_Domainp_total}, @{thm pcr_Domainp_par_left_total}, @{thm pcr_Domainp_par}, 
       
   595       @{thm pcr_Domainp}]
       
   596 in
       
   597 fun mk_readable_rsp_thm_eq tm lthy =
       
   598   let
       
   599     val ctm = Thm.cterm_of lthy tm
       
   600     
       
   601     fun assms_rewr_conv tactic rule ct =
       
   602       let
       
   603         fun prove_extra_assms thm =
       
   604           let
       
   605             val assms = cprems_of thm
       
   606             fun finish thm = if Thm.no_prems thm then SOME (Goal.conclude thm) else NONE
       
   607             fun prove ctm = Option.mapPartial finish (SINGLE tactic (Goal.init ctm))
       
   608           in
       
   609             map_interrupt prove assms
       
   610           end
       
   611     
       
   612         fun cconl_of thm = Drule.strip_imp_concl (Thm.cprop_of thm)
       
   613         fun lhs_of thm = fst (Thm.dest_equals (cconl_of thm))
       
   614         fun rhs_of thm = snd (Thm.dest_equals (cconl_of thm))
       
   615         val rule1 = Thm.incr_indexes (Thm.maxidx_of_cterm ct + 1) rule;
       
   616         val lhs = lhs_of rule1;
       
   617         val rule2 = Thm.rename_boundvars (Thm.term_of lhs) (Thm.term_of ct) rule1;
       
   618         val rule3 =
       
   619           Thm.instantiate (Thm.match (lhs, ct)) rule2
       
   620             handle Pattern.MATCH => raise CTERM ("assms_rewr_conv", [lhs, ct]);
       
   621         val proved_assms = prove_extra_assms rule3
       
   622       in
       
   623         case proved_assms of
       
   624           SOME proved_assms =>
       
   625             let
       
   626               val rule3 = proved_assms MRSL rule3
       
   627               val rule4 =
       
   628                 if lhs_of rule3 aconvc ct then rule3
       
   629                 else
       
   630                   let val ceq = Thm.dest_fun2 (Thm.cprop_of rule3)
       
   631                   in rule3 COMP Thm.trivial (Thm.mk_binop ceq ct (rhs_of rule3)) end
       
   632             in Thm.transitive rule4 (Thm.beta_conversion true (rhs_of rule4)) end
       
   633           | NONE => Conv.no_conv ct
       
   634       end
       
   635 
       
   636     fun assms_rewrs_conv tactic rules = Conv.first_conv (map (assms_rewr_conv tactic) rules)
       
   637 
       
   638     fun simp_arrows_conv ctm =
       
   639       let
       
   640         val unfold_conv = Conv.rewrs_conv 
       
   641           [@{thm rel_fun_eq_eq_onp[THEN eq_reflection]}, 
       
   642             @{thm rel_fun_eq_onp_rel[THEN eq_reflection]},
       
   643             @{thm rel_fun_eq[THEN eq_reflection]},
       
   644             @{thm rel_fun_eq_rel[THEN eq_reflection]}, 
       
   645             @{thm rel_fun_def[THEN eq_reflection]}]
       
   646         fun binop_conv2 cv1 cv2 = Conv.combination_conv (Conv.arg_conv cv1) cv2
       
   647         val eq_onp_assms_tac_rules = @{thm left_unique_OO} :: 
       
   648             eq_onp_assms_tac_fixed_rules @ (Transfer.get_transfer_raw lthy)
       
   649         val intro_top_rule = @{thm eq_onp_top_eq_eq[symmetric, THEN eq_reflection]}
       
   650         val kill_tops = Transfer.top_sweep_rewr_conv [@{thm eq_onp_top_eq_eq[THEN eq_reflection]}]
       
   651         val eq_onp_assms_tac = (CONVERSION kill_tops THEN' 
       
   652           TRY o REPEAT_ALL_NEW (resolve_tac lthy eq_onp_assms_tac_rules) 
       
   653           THEN_ALL_NEW (DETERM o Transfer.eq_tac lthy)) 1
       
   654         val relator_eq_onp_conv = Conv.bottom_conv
       
   655           (K (Conv.try_conv (assms_rewrs_conv eq_onp_assms_tac
       
   656             (intro_top_rule :: Lifting_Info.get_relator_eq_onp_rules lthy)))) lthy
       
   657           then_conv kill_tops
       
   658         val relator_eq_conv = Conv.bottom_conv
       
   659           (K (Conv.try_conv (Conv.rewrs_conv (Transfer.get_relator_eq lthy)))) lthy
       
   660       in
       
   661         case (Thm.term_of ctm) of
       
   662           Const (@{const_name "rel_fun"}, _) $ _ $ _ => 
       
   663             (binop_conv2 simp_arrows_conv simp_arrows_conv then_conv unfold_conv) ctm
       
   664           | _ => (relator_eq_onp_conv then_conv relator_eq_conv) ctm
       
   665       end
       
   666     
       
   667     val unfold_ret_val_invs = Conv.bottom_conv 
       
   668       (K (Conv.try_conv (Conv.rewr_conv @{thm eq_onp_same_args[THEN eq_reflection]}))) lthy
       
   669     val unfold_inv_conv = 
       
   670       Conv.top_sweep_conv (K (Conv.rewr_conv @{thm eq_onp_def[THEN eq_reflection]})) lthy
       
   671     val simp_conv = HOLogic.Trueprop_conv (Conv.fun2_conv simp_arrows_conv)
       
   672     val univq_conv = Conv.rewr_conv @{thm HOL.all_simps(6)[symmetric, THEN eq_reflection]}
       
   673     val univq_prenex_conv = Conv.top_conv (K (Conv.try_conv univq_conv)) lthy
       
   674     val beta_conv = Thm.beta_conversion true
       
   675     val eq_thm = 
       
   676       (simp_conv then_conv univq_prenex_conv then_conv beta_conv then_conv unfold_ret_val_invs
       
   677          then_conv unfold_inv_conv) ctm
       
   678   in
       
   679     Object_Logic.rulify lthy (eq_thm RS Drule.equal_elim_rule2)
       
   680   end
       
   681 end
       
   682 
       
   683 fun rename_to_tnames ctxt term =
       
   684   let
       
   685     fun all_typs (Const (@{const_name Pure.all}, _) $ Abs (_, T, t)) = T :: all_typs t
       
   686       | all_typs _ = []
       
   687 
       
   688     fun rename (Const (@{const_name Pure.all}, T1) $ Abs (_, T2, t)) (new_name :: names) = 
       
   689         (Const (@{const_name Pure.all}, T1) $ Abs (new_name, T2, rename t names)) 
       
   690       | rename t _ = t
       
   691 
       
   692     val (fixed_def_t, _) = yield_singleton (Variable.importT_terms) term ctxt
       
   693     val new_names = Old_Datatype_Prop.make_tnames (all_typs fixed_def_t)
       
   694   in
       
   695     rename term new_names
       
   696   end
   579 
   697 
   580 fun lift_def_cmd (params, raw_var, rhs_raw, par_xthms) lthy =
   698 fun lift_def_cmd (params, raw_var, rhs_raw, par_xthms) lthy =
   581   let
   699   let
   582     val config = evaluate_params params
   700     val config = evaluate_params params
   583     val ((binding, SOME qty, mx), lthy) = yield_singleton Proof_Context.read_vars raw_var lthy
   701     val ((binding, SOME qty, mx), lthy) = yield_singleton Proof_Context.read_vars raw_var lthy
   584     val var = (binding, mx)
   702     val var = (binding, mx)
   585     val rhs = (Syntax.check_term lthy o Syntax.parse_term lthy) rhs_raw
   703     val rhs = (Syntax.check_term lthy o Syntax.parse_term lthy) rhs_raw
   586     val par_thms = Attrib.eval_thms lthy par_xthms
   704     val par_thms = Attrib.eval_thms lthy par_xthms
   587     val (goal, after_qed) = prepare_lift_def (add_lift_def_code_dt config) var qty rhs par_thms lthy
   705     val (goal, after_qed) = prepare_lift_def (add_lift_def_code_dt config) var qty rhs par_thms lthy
       
   706     val (goal, after_qed) =
       
   707       case goal of
       
   708         NONE => (goal, K (after_qed Drule.dummy_thm))
       
   709         | SOME prsp_tm =>
       
   710           let
       
   711             val readable_rsp_thm_eq = mk_readable_rsp_thm_eq prsp_tm lthy
       
   712             val (readable_rsp_tm, _) = Logic.dest_implies (Thm.prop_of readable_rsp_thm_eq)
       
   713             val readable_rsp_tm_tnames = rename_to_tnames lthy readable_rsp_tm
       
   714         
       
   715             fun after_qed' [[thm]] lthy = 
       
   716               let
       
   717                 val internal_rsp_thm = Goal.prove lthy [] [] prsp_tm 
       
   718                     (fn {context = ctxt, ...} =>
       
   719                       rtac readable_rsp_thm_eq 1 THEN Proof_Context.fact_tac ctxt [thm] 1)
       
   720               in
       
   721                 after_qed internal_rsp_thm lthy
       
   722               end
       
   723           in
       
   724             (SOME readable_rsp_tm_tnames, after_qed')
       
   725           end 
   588   in
   726   in
   589     Proof.theorem NONE (snd oo after_qed) [map (rpair []) (the_list goal)] lthy
   727     Proof.theorem NONE (snd oo after_qed) [map (rpair []) (the_list goal)] lthy
   590   end
   728   end
   591 
   729 
   592 fun quot_thm_err ctxt (rty, qty) pretty_msg =
   730 fun quot_thm_err ctxt (rty, qty) pretty_msg =