7 signature PREDICATE_COMPILE = |
7 signature PREDICATE_COMPILE = |
8 sig |
8 sig |
9 type mode = int list option list * int list |
9 type mode = int list option list * int list |
10 val add_equations_of: string list -> theory -> theory |
10 val add_equations_of: string list -> theory -> theory |
11 val register_predicate : (thm list * thm * int) -> theory -> theory |
11 val register_predicate : (thm list * thm * int) -> theory -> theory |
|
12 val fetch_pred_data : theory -> string -> (thm list * thm * int) |
12 val predfun_intro_of: theory -> string -> mode -> thm |
13 val predfun_intro_of: theory -> string -> mode -> thm |
13 val predfun_elim_of: theory -> string -> mode -> thm |
14 val predfun_elim_of: theory -> string -> mode -> thm |
14 val strip_intro_concl: int -> term -> term * (term list * term list) |
15 val strip_intro_concl: int -> term -> term * (term list * term list) |
15 val predfun_name_of: theory -> string -> mode -> string |
16 val predfun_name_of: theory -> string -> mode -> string |
16 val all_preds_of : theory -> string list |
17 val all_preds_of : theory -> string list |
17 val modes_of: theory -> string -> mode list |
18 val modes_of: theory -> string -> mode list |
18 val intros_of: theory -> string -> thm list |
19 val intros_of: theory -> string -> thm list |
19 val nparams_of: theory -> string -> int |
20 val nparams_of: theory -> string -> int |
|
21 val add_intro: thm -> theory -> theory |
|
22 val set_elim: thm -> theory -> theory |
20 val setup: theory -> theory |
23 val setup: theory -> theory |
21 val code_pred: string -> Proof.context -> Proof.state |
24 val code_pred: string -> Proof.context -> Proof.state |
22 val code_pred_cmd: string -> Proof.context -> Proof.state |
25 val code_pred_cmd: string -> Proof.context -> Proof.state |
23 (* val print_alternative_rules: theory -> theory (*FIXME diagnostic command?*) *) |
26 val print_stored_rules: theory -> unit |
24 val do_proofs: bool ref |
27 val do_proofs: bool ref |
|
28 val mk_casesrule : Proof.context -> int -> thm list -> term |
25 val analyze_compr: theory -> term -> term |
29 val analyze_compr: theory -> term -> term |
26 val eval_ref: (unit -> term Predicate.pred) option ref |
30 val eval_ref: (unit -> term Predicate.pred) option ref |
27 val add_equations : string -> theory -> theory |
31 val add_equations : string -> theory -> theory |
|
32 val code_pred_intros_attrib : attribute |
28 end; |
33 end; |
29 |
34 |
30 structure Predicate_Compile : PREDICATE_COMPILE = |
35 structure Predicate_Compile : PREDICATE_COMPILE = |
31 struct |
36 struct |
32 |
37 |
221 |
226 |
222 val predfun_intro_of = #intro ooo the_predfun_data |
227 val predfun_intro_of = #intro ooo the_predfun_data |
223 |
228 |
224 val predfun_elim_of = #elim ooo the_predfun_data |
229 val predfun_elim_of = #elim ooo the_predfun_data |
225 |
230 |
226 |
231 fun print_stored_rules thy = |
227 (* replaces print_alternative_rules *) |
232 let |
228 (* TODO: |
233 val preds = (Graph.keys o PredData.get) thy |
229 fun print_alternative_rules thy = let |
234 fun print pred () = let |
230 val d = IndCodegenData.get thy |
235 val _ = writeln ("predicate: " ^ pred) |
231 val preds = (Symtab.keys (#intro_rules d)) union (Symtab.keys (#elim_rules d)) |
236 val _ = writeln ("number of parameters: " ^ string_of_int (nparams_of thy pred)) |
232 val _ = tracing ("preds: " ^ (makestring preds)) |
237 val _ = writeln ("introrules: ") |
233 fun print pred = let |
238 val _ = fold (fn thm => fn u => writeln (Display.string_of_thm thm)) |
234 val _ = tracing ("predicate: " ^ pred) |
239 (rev (intros_of thy pred)) () |
235 val _ = tracing ("introrules: ") |
240 in |
236 val _ = fold (fn thm => fn u => tracing (makestring thm)) |
241 if (has_elim thy pred) then |
237 (rev (Symtab.lookup_list (#intro_rules d) pred)) () |
242 writeln ("elimrule: " ^ Display.string_of_thm (the_elim_of thy pred)) |
238 val _ = tracing ("casesrule: ") |
243 else |
239 val _ = tracing (makestring (Symtab.lookup (#elim_rules d) pred)) |
244 writeln ("no elimrule defined") |
240 in () end |
245 end |
241 val _ = map print preds |
246 in |
242 in thy end; |
247 fold print preds () |
243 *) |
248 end; |
244 |
249 |
|
250 (** preprocessing rules **) |
245 |
251 |
246 fun imp_prems_conv cv ct = |
252 fun imp_prems_conv cv ct = |
247 case Thm.term_of ct of |
253 case Thm.term_of ct of |
248 Const ("==>", _) $ _ $ _ => Conv.combination_conv (Conv.arg_conv cv) (imp_prems_conv cv) ct |
254 Const ("==>", _) $ _ $ _ => Conv.combination_conv (Conv.arg_conv cv) (imp_prems_conv cv) ct |
249 | _ => Conv.all_conv ct |
255 | _ => Conv.all_conv ct |
296 |
302 |
297 fun add_predfun name mode data = let |
303 fun add_predfun name mode data = let |
298 val add = apsnd (cons (mode, mk_predfun_data data)) |
304 val add = apsnd (cons (mode, mk_predfun_data data)) |
299 in PredData.map (Graph.map_node name (map_pred_data add)) end |
305 in PredData.map (Graph.map_node name (map_pred_data add)) end |
300 |
306 |
|
307 fun is_inductive_predicate thy name = |
|
308 is_some (try (Inductive.the_inductive (ProofContext.init thy)) name) |
|
309 |
|
310 fun depending_preds_of thy intros = fold Term.add_consts (map Thm.prop_of intros) [] |> map fst |
|
311 |> filter (fn c => is_inductive_predicate thy c orelse is_pred thy c) |
|
312 |
|
313 (* code dependency graph *) |
|
314 fun dependencies_of thy name = |
|
315 let |
|
316 val (intros, elim, nparams) = fetch_pred_data thy name |
|
317 val data = mk_pred_data ((intros, SOME elim, nparams), []) |
|
318 val keys = depending_preds_of thy intros |
|
319 in |
|
320 (data, keys) |
|
321 end; |
|
322 |
|
323 (* TODO: add_edges - by analysing dependencies *) |
301 fun add_intro thm thy = let |
324 fun add_intro thm thy = let |
302 val (name, _) = dest_Const (fst (strip_intro_concl 0 (prop_of thm))) |
325 val (name, _) = dest_Const (fst (strip_intro_concl 0 (prop_of thm))) |
303 fun cons_intro gr = |
326 fun cons_intro gr = |
304 case try (Graph.get_node gr) name of |
327 case try (Graph.get_node gr) name of |
305 SOME pred_data => Graph.map_node name (map_pred_data |
328 SOME pred_data => Graph.map_node name (map_pred_data |
318 |
341 |
319 fun set_nparams name nparams = let |
342 fun set_nparams name nparams = let |
320 fun set (intros, elim, _ ) = (intros, elim, nparams) |
343 fun set (intros, elim, _ ) = (intros, elim, nparams) |
321 in PredData.map (Graph.map_node name (map_pred_data (apfst set))) end |
344 in PredData.map (Graph.map_node name (map_pred_data (apfst set))) end |
322 |
345 |
323 fun register_predicate (intros, elim, nparams) = let |
346 fun register_predicate (intros, elim, nparams) thy = let |
324 val (name, _) = dest_Const (fst (strip_intro_concl nparams (prop_of (hd intros)))) |
347 val (name, _) = dest_Const (fst (strip_intro_concl nparams (prop_of (hd intros)))) |
325 fun set _ = (intros, SOME elim, nparams) |
348 fun set _ = (intros, SOME elim, nparams) |
326 in PredData.map (Graph.new_node (name, mk_pred_data ((intros, SOME elim, nparams), []))) end |
349 in |
|
350 PredData.map (Graph.new_node (name, mk_pred_data ((intros, SOME elim, nparams), [])) |
|
351 #> fold Graph.add_edge (map (pair name) (depending_preds_of thy intros))) thy |
|
352 end |
327 |
353 |
328 |
354 |
329 (* Mode analysis *) |
355 (* Mode analysis *) |
330 |
356 |
331 (*** check if a term contains only constructor functions ***) |
357 (*** check if a term contains only constructor functions ***) |
1241 THEN print_tac "after prove_match2:" |
1267 THEN print_tac "after prove_match2:" |
1242 THEN rest_tac |
1268 THEN rest_tac |
1243 end; |
1269 end; |
1244 val prems_tac = prove_prems2 in_ts' param_vs ps |
1270 val prems_tac = prove_prems2 in_ts' param_vs ps |
1245 in |
1271 in |
1246 print_tac "starting prove_clause2" |
1272 new_print_tac "starting prove_clause2" |
1247 THEN etac @{thm bindE} 1 |
1273 THEN etac @{thm bindE} 1 |
1248 THEN (etac @{thm singleE'} 1) |
1274 THEN (etac @{thm singleE'} 1) |
1249 THEN (TRY (etac @{thm Pair_inject} 1)) |
1275 THEN (TRY (etac @{thm Pair_inject} 1)) |
1250 THEN print_tac "after singleE':" |
1276 THEN print_tac "after singleE':" |
1251 THEN prems_tac |
1277 THEN prems_tac |
1257 THEN (prove_clause2 thy all_vs param_vs modes mode clause pred i) |
1283 THEN (prove_clause2 thy all_vs param_vs modes mode clause pred i) |
1258 in |
1284 in |
1259 (DETERM (TRY (rtac @{thm unit.induct} 1))) |
1285 (DETERM (TRY (rtac @{thm unit.induct} 1))) |
1260 THEN (REPEAT_DETERM (CHANGED (rewtac @{thm split_paired_all}))) |
1286 THEN (REPEAT_DETERM (CHANGED (rewtac @{thm split_paired_all}))) |
1261 THEN (rtac (predfun_intro_of thy pred mode) 1) |
1287 THEN (rtac (predfun_intro_of thy pred mode) 1) |
|
1288 THEN (REPEAT_DETERM (rtac @{thm refl} 2)) |
1262 THEN (EVERY (map prove_clause (clauses ~~ (1 upto (length clauses))))) |
1289 THEN (EVERY (map prove_clause (clauses ~~ (1 upto (length clauses))))) |
1263 end; |
1290 end; |
1264 |
1291 |
1265 fun prove_pred thy all_vs param_vs modes clauses (((pred, T), mode), t) = let |
1292 fun prove_pred thy all_vs param_vs modes clauses (((pred, T), mode), t) = let |
1266 val ctxt = ProofContext.init thy |
1293 val ctxt = ProofContext.init thy |
1407 in fold Logic.all frees (Logic.list_implies (eqprems @ prems, prop)) end |
1434 in fold Logic.all frees (Logic.list_implies (eqprems @ prems, prop)) end |
1408 val assm = HOLogic.mk_Trueprop (list_comb (pred, params @ argvs)) |
1435 val assm = HOLogic.mk_Trueprop (list_comb (pred, params @ argvs)) |
1409 val cases = map mk_case intros |
1436 val cases = map mk_case intros |
1410 in Logic.list_implies (assm :: cases, prop) end; |
1437 in Logic.list_implies (assm :: cases, prop) end; |
1411 |
1438 |
1412 (* code dependency graph *) |
|
1413 |
|
1414 fun dependencies_of thy name = |
|
1415 let |
|
1416 fun is_inductive_predicate thy name = |
|
1417 is_some (try (Inductive.the_inductive (ProofContext.init thy)) name) |
|
1418 val (intro, elim, nparams) = fetch_pred_data thy name |
|
1419 val data = mk_pred_data ((intro, SOME elim, nparams), []) |
|
1420 val intros = map Thm.prop_of (#intros (rep_pred_data data)) |
|
1421 val keys = fold Term.add_consts intros [] |> map fst |
|
1422 |> filter (is_inductive_predicate thy) |
|
1423 in |
|
1424 (data, keys) |
|
1425 end; |
|
1426 |
|
1427 fun add_equations name thy = |
1439 fun add_equations name thy = |
1428 let |
1440 let |
1429 val thy' = PredData.map (Graph.extend (dependencies_of thy) name) thy |> Theory.checkpoint; |
1441 val thy' = PredData.map (Graph.extend (dependencies_of thy) name) thy |> Theory.checkpoint; |
1430 (*val preds = Graph.all_preds (PredData.get thy') [name] |> filter_out (has_elim thy') *) |
1442 (*val preds = Graph.all_preds (PredData.get thy') [name] |> filter_out (has_elim thy') *) |
1431 fun strong_conn_of gr keys = |
1443 fun strong_conn_of gr keys = |
1435 (fn preds => fn thy => |
1447 (fn preds => fn thy => |
1436 if forall (null o modes_of thy) preds then add_equations_of preds thy else thy) |
1448 if forall (null o modes_of thy) preds then add_equations_of preds thy else thy) |
1437 scc thy' |> Theory.checkpoint |
1449 scc thy' |> Theory.checkpoint |
1438 in thy'' end |
1450 in thy'' end |
1439 |
1451 |
|
1452 |
|
1453 fun attrib f = Thm.declaration_attribute (fn thm => Context.mapping (f thm) I); |
|
1454 |
|
1455 val code_pred_intros_attrib = attrib add_intro; |
|
1456 |
1440 (** user interface **) |
1457 (** user interface **) |
1441 |
1458 |
1442 local |
1459 local |
1443 |
|
1444 fun attrib f = Thm.declaration_attribute (fn thm => Context.mapping (f thm) I); |
|
1445 |
|
1446 (* |
|
1447 val add_elim_attrib = attrib set_elim; |
|
1448 *) |
|
1449 |
|
1450 |
1460 |
1451 (* TODO: make TheoryDataFun to GenericDataFun & remove duplication of local theory and theory *) |
1461 (* TODO: make TheoryDataFun to GenericDataFun & remove duplication of local theory and theory *) |
1452 (* TODO: must create state to prove multiple cases *) |
1462 (* TODO: must create state to prove multiple cases *) |
1453 fun generic_code_pred prep_const raw_const lthy = |
1463 fun generic_code_pred prep_const raw_const lthy = |
1454 let |
1464 let |