src/HOL/Tools/BNF/bnf_fp_rec_sugar_transfer.ML
changeset 59281 1b4dc8a9f7d9
parent 59276 d207455817e8
child 59297 7ca42387fbf5
equal deleted inserted replaced
59280:2949ace404c3 59281:1b4dc8a9f7d9
     5 Parametricity of primitively (co)recursive functions.
     5 Parametricity of primitively (co)recursive functions.
     6 *)
     6 *)
     7 
     7 
     8 signature BNF_FP_REC_SUGAR_TRANSFER =
     8 signature BNF_FP_REC_SUGAR_TRANSFER =
     9 sig
     9 sig
    10   val primrec_transfer_interpretation: BNF_FP_Rec_Sugar_Util.fp_rec_sugar -> Proof.context ->
    10   val lfp_rec_sugar_transfer_interpretation: BNF_FP_Rec_Sugar_Util.fp_rec_sugar -> Proof.context ->
    11     Proof.context
    11     Proof.context
    12   val primcorec_transfer_interpretation: BNF_FP_Rec_Sugar_Util.fp_rec_sugar -> Proof.context ->
    12   val gfp_rec_sugar_transfer_interpretation: BNF_FP_Rec_Sugar_Util.fp_rec_sugar -> Proof.context ->
    13     Proof.context
    13     Proof.context
    14 end;
    14 end;
    15 
    15 
    16 structure BNF_FP_Rec_Sugar_Transfer : BNF_FP_REC_SUGAR_TRANSFER =
    16 structure BNF_FP_Rec_Sugar_Transfer : BNF_FP_REC_SUGAR_TRANSFER =
    17 struct
    17 struct
    20 open Ctr_Sugar_Tactics
    20 open Ctr_Sugar_Tactics
    21 open BNF_Def
    21 open BNF_Def
    22 open BNF_FP_Util
    22 open BNF_FP_Util
    23 open BNF_FP_Def_Sugar
    23 open BNF_FP_Def_Sugar
    24 open BNF_FP_Rec_Sugar_Util
    24 open BNF_FP_Rec_Sugar_Util
       
    25 open BNF_LFP_Rec_Sugar
    25 
    26 
    26 val transferN = "transfer";
    27 val transferN = "transfer";
    27 
    28 
    28 fun mk_primrec_transfer_tac ctxt def =
    29 fun mk_lfp_rec_sugar_transfer_tac ctxt def =
    29   Ctr_Sugar_Tactics.unfold_thms_tac ctxt [def] THEN
    30   Ctr_Sugar_Tactics.unfold_thms_tac ctxt [def] THEN
    30   HEADGOAL (Transfer.transfer_prover_tac ctxt);
    31   HEADGOAL (Transfer.transfer_prover_tac ctxt);
    31 
    32 
    32 fun mk_primcorec_transfer_tac apply_transfer ctxt f_def corec_def type_definitions
    33 fun mk_gfp_rec_sugar_transfer_tac apply_transfer ctxt f_def corec_def type_definitions
    33     dtor_corec_transfers rel_pre_defs disc_eq_cases cases case_distribs case_congs =
    34     dtor_corec_transfers rel_pre_defs disc_eq_cases cases case_distribs case_congs =
    34   let
    35   let
    35     fun instantiate_with_lambda thm =
    36     fun instantiate_with_lambda thm =
    36       let
    37       let
    37         val prop = Thm.prop_of thm;
    38         val prop = Thm.prop_of thm;
   111         if_all_bnfs lthy fpTs
   112         if_all_bnfs lthy fpTs
   112           (fn bnfs => fn () => prove n bnfs f_names f def lthy)
   113           (fn bnfs => fn () => prove n bnfs f_names f def lthy)
   113           (fn () => error "Function is not parametric" (*FIXME: wording*)) ())
   114           (fn () => error "Function is not parametric" (*FIXME: wording*)) ())
   114     (transfers ~~ fun_names ~~ funs ~~ fun_defs) lthy;
   115     (transfers ~~ fun_names ~~ funs ~~ fun_defs) lthy;
   115 
   116 
   116 fun prim_co_rec_transfer_interpretation prove =
   117 fun fp_rec_sugar_transfer_interpretation prove =
   117   prove_parametricity_if_bnf (fn n => fn bnfs => fn f_name => fn f => fn def => fn lthy =>
   118   prove_parametricity_if_bnf (fn n => fn bnfs => fn f_name => fn f => fn def => fn lthy =>
   118     (case try (prove n bnfs f def) lthy of
   119     (case try (prove n bnfs f def) lthy of
   119       NONE => error "Failed to prove parametricity"
   120       NONE => error "Failed to prove parametricity"
   120     | SOME thm =>
   121     | SOME thm =>
   121       let
   122       let
   123           |> massage_simple_notes f_name;
   124           |> massage_simple_notes f_name;
   124       in
   125       in
   125         snd (Local_Theory.notes notes lthy)
   126         snd (Local_Theory.notes notes lthy)
   126       end));
   127       end));
   127 
   128 
   128 val primrec_transfer_interpretation = prim_co_rec_transfer_interpretation
   129 val lfp_rec_sugar_transfer_interpretation = fp_rec_sugar_transfer_interpretation
   129   (fn _ => fn _ => fn f => fn def => fn lthy =>
   130   (fn _ => fn _ => fn f => fn def => fn lthy =>
   130      let val (goal, names_lthy) = mk_goal lthy f in
   131      let val (goal, names_lthy) = mk_goal lthy f in
   131        Goal.prove lthy [] [] goal (fn {context = ctxt, prems = _} =>
   132        Goal.prove lthy [] [] goal (fn {context = ctxt, prems = _} =>
   132          mk_primrec_transfer_tac ctxt def)
   133          mk_lfp_rec_sugar_transfer_tac ctxt def)
   133        |> singleton (Proof_Context.export names_lthy lthy)
   134        |> singleton (Proof_Context.export names_lthy lthy)
   134        |> Thm.close_derivation
   135        |> Thm.close_derivation
   135      end);
   136      end);
   136 
   137 
   137 val primcorec_transfer_interpretation = prim_co_rec_transfer_interpretation
   138 val gfp_rec_sugar_transfer_interpretation = fp_rec_sugar_transfer_interpretation
   138   (fn n => fn bnfs => fn f => fn def => fn lthy =>
   139   (fn n => fn bnfs => fn f => fn def => fn lthy =>
   139      let
   140      let
   140        val fp_sugars = map (the o fp_sugar_of_bnf lthy) bnfs;
   141        val fp_sugars = map (the o fp_sugar_of_bnf lthy) bnfs;
   141        val (goal, names_lthy) = mk_goal lthy f;
   142        val (goal, names_lthy) = mk_goal lthy f;
   142        val (disc_eq_cases, case_thms, case_distribs, case_congs) =
   143        val (disc_eq_cases, case_thms, case_distribs, case_congs) =
   153              Option.map (add_thms quad) (fp_sugar_of_bnf lthy bnf)
   154              Option.map (add_thms quad) (fp_sugar_of_bnf lthy bnf)
   154              |> the_default quad
   155              |> the_default quad
   155            end) (fastype_of f) ([], [], [], []);
   156            end) (fastype_of f) ([], [], [], []);
   156      in
   157      in
   157        Goal.prove lthy [] [] goal (fn {context = ctxt, prems = _} =>
   158        Goal.prove lthy [] [] goal (fn {context = ctxt, prems = _} =>
   158          mk_primcorec_transfer_tac true ctxt def
   159          mk_gfp_rec_sugar_transfer_tac true ctxt def
   159          (#co_rec_def (#fp_co_induct_sugar (nth fp_sugars n)))
   160          (#co_rec_def (#fp_co_induct_sugar (nth fp_sugars n)))
   160          (map (#type_definition o #absT_info) fp_sugars)
   161          (map (#type_definition o #absT_info) fp_sugars)
   161          (maps (#xtor_co_rec_transfers o #fp_res) fp_sugars)
   162          (maps (#xtor_co_rec_transfers o #fp_res) fp_sugars)
   162          (map (rel_def_of_bnf o #pre_bnf) fp_sugars)
   163          (map (rel_def_of_bnf o #pre_bnf) fp_sugars)
   163          disc_eq_cases case_thms case_distribs case_congs)
   164          disc_eq_cases case_thms case_distribs case_congs)
   164        |> singleton (Proof_Context.export names_lthy lthy)
   165        |> singleton (Proof_Context.export names_lthy lthy)
   165        |> Thm.close_derivation
   166        |> Thm.close_derivation
   166      end);
   167      end);
   167 
   168 
   168 val _ = Theory.setup (BNF_LFP_Rec_Sugar.primrec_interpretation Transfer_BNF.transfer_plugin
   169 val _ = Theory.setup (lfp_rec_sugar_interpretation Transfer_BNF.transfer_plugin
   169   primrec_transfer_interpretation);
   170   lfp_rec_sugar_transfer_interpretation);
   170 
   171 
   171 end;
   172 end;