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; |