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: bool -> string list -> theory -> theory *) |
10 (*val add_equations_of: bool -> 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 is_registered : theory -> string -> bool |
12 val is_registered : theory -> string -> bool |
13 val fetch_pred_data : theory -> string -> (thm list * thm * int) |
13 (* val fetch_pred_data : theory -> string -> (thm list * thm * int) *) |
14 val predfun_intro_of: theory -> string -> mode -> thm |
14 val predfun_intro_of: theory -> string -> mode -> thm |
15 val predfun_elim_of: theory -> string -> mode -> thm |
15 val predfun_elim_of: theory -> string -> mode -> thm |
16 val strip_intro_concl: int -> term -> term * (term list * term list) |
16 val strip_intro_concl: int -> term -> term * (term list * term list) |
17 val predfun_name_of: theory -> string -> mode -> string |
17 val predfun_name_of: theory -> string -> mode -> string |
18 val all_preds_of : theory -> string list |
18 val all_preds_of : theory -> string list |
76 theory -> (moded_clause list) pred_mode_table -> unit |
76 theory -> (moded_clause list) pred_mode_table -> unit |
77 val print_compiled_terms : theory -> term pred_mode_table -> unit |
77 val print_compiled_terms : theory -> term pred_mode_table -> unit |
78 (*val rpred_prove_preds : theory -> term pred_mode_table -> thm pred_mode_table*) |
78 (*val rpred_prove_preds : theory -> term pred_mode_table -> thm pred_mode_table*) |
79 val rpred_compfuns : compilation_funs |
79 val rpred_compfuns : compilation_funs |
80 val dest_funT : typ -> typ * typ |
80 val dest_funT : typ -> typ * typ |
81 val depending_preds_of : theory -> thm list -> string list |
81 (* val depending_preds_of : theory -> thm list -> string list *) |
82 val add_quickcheck_equations : string list -> theory -> theory |
82 val add_quickcheck_equations : string list -> theory -> theory |
83 val add_sizelim_equations : string list -> theory -> theory |
83 val add_sizelim_equations : string list -> theory -> theory |
84 val is_inductive_predicate : theory -> string -> bool |
84 val is_inductive_predicate : theory -> string -> bool |
85 val terms_vs : term list -> string list |
85 val terms_vs : term list -> string list |
86 val subsets : int -> int -> int list list |
86 val subsets : int -> int -> int list list |
463 val intro = Goal.prove (ProofContext.init thy) names [] intro_t |
463 val intro = Goal.prove (ProofContext.init thy) names [] intro_t |
464 (fn {...} => etac @{thm FalseE} 1) |
464 (fn {...} => etac @{thm FalseE} 1) |
465 val elim = Goal.prove (ProofContext.init thy) ("P" :: names) [] elim_t |
465 val elim = Goal.prove (ProofContext.init thy) ("P" :: names) [] elim_t |
466 (fn {...} => etac elim 1) |
466 (fn {...} => etac elim 1) |
467 in |
467 in |
468 ([intro], elim, 0) |
468 ([intro], elim) |
469 end |
469 end |
470 |
470 |
471 fun fetch_pred_data thy name = |
471 fun fetch_pred_data thy name = |
472 case try (Inductive.the_inductive (ProofContext.init thy)) name of |
472 case try (Inductive.the_inductive (ProofContext.init thy)) name of |
473 SOME (info as (_, result)) => |
473 SOME (info as (_, result)) => |
479 val intros = ind_set_codegen_preproc thy ((map (preprocess_intro thy)) |
479 val intros = ind_set_codegen_preproc thy ((map (preprocess_intro thy)) |
480 (filter is_intro_of (#intrs result))) |
480 (filter is_intro_of (#intrs result))) |
481 val pre_elim = nth (#elims result) (find_index (fn s => s = name) (#names (fst info))) |
481 val pre_elim = nth (#elims result) (find_index (fn s => s = name) (#names (fst info))) |
482 val nparams = length (Inductive.params_of (#raw_induct result)) |
482 val nparams = length (Inductive.params_of (#raw_induct result)) |
483 val elim = singleton (ind_set_codegen_preproc thy) (preprocess_elim thy nparams pre_elim) |
483 val elim = singleton (ind_set_codegen_preproc thy) (preprocess_elim thy nparams pre_elim) |
|
484 val (intros, elim) = if null intros then noclause thy name elim else (intros, elim) |
484 in |
485 in |
485 if null intros then noclause thy name elim else (intros, elim, nparams) |
486 mk_pred_data ((intros, SOME elim, nparams), ([], [], [])) |
486 end |
487 end |
487 | NONE => error ("No such predicate: " ^ quote name) |
488 | NONE => error ("No such predicate: " ^ quote name) |
488 |
489 |
489 (* updaters *) |
490 (* updaters *) |
490 |
491 |
498 in PredData.map (Graph.map_node name (map_pred_data add)) end |
499 in PredData.map (Graph.map_node name (map_pred_data add)) end |
499 |
500 |
500 fun is_inductive_predicate thy name = |
501 fun is_inductive_predicate thy name = |
501 is_some (try (Inductive.the_inductive (ProofContext.init thy)) name) |
502 is_some (try (Inductive.the_inductive (ProofContext.init thy)) name) |
502 |
503 |
503 fun depending_preds_of thy intros = fold Term.add_const_names (map Thm.prop_of intros) [] |
504 fun depending_preds_of thy (key, value) = |
504 |> filter (fn c => is_inductive_predicate thy c orelse is_registered thy c) |
505 let |
505 |
506 val intros = (#intros o rep_pred_data) value |
|
507 in |
|
508 fold Term.add_const_names (map Thm.prop_of intros) [] |
|
509 |> filter (fn c => (not (c = key)) andalso (is_inductive_predicate thy c orelse is_registered thy c)) |
|
510 end; |
|
511 |
|
512 |
506 (* code dependency graph *) |
513 (* code dependency graph *) |
507 |
514 (* |
508 fun dependencies_of thy name = |
515 fun dependencies_of thy name = |
509 let |
516 let |
510 val (intros, elim, nparams) = fetch_pred_data thy name |
517 val (intros, elim, nparams) = fetch_pred_data thy name |
511 val data = mk_pred_data ((intros, SOME elim, nparams), ([], [], [])) |
518 val data = mk_pred_data ((intros, SOME elim, nparams), ([], [], [])) |
512 val keys = depending_preds_of thy intros |
519 val keys = depending_preds_of thy intros |
513 in |
520 in |
514 (data, keys) |
521 (data, keys) |
515 end; |
522 end; |
|
523 *) |
516 |
524 |
517 (* TODO: add_edges - by analysing dependencies *) |
525 (* TODO: add_edges - by analysing dependencies *) |
518 fun add_intro thm thy = let |
526 fun add_intro thm thy = let |
519 val (name, _) = dest_Const (fst (strip_intro_concl 0 (prop_of thm))) |
527 val (name, _) = dest_Const (fst (strip_intro_concl 0 (prop_of thm))) |
520 fun cons_intro gr = |
528 fun cons_intro gr = |
521 case try (Graph.get_node gr) name of |
529 case try (Graph.get_node gr) name of |
522 SOME pred_data => Graph.map_node name (map_pred_data |
530 SOME pred_data => Graph.map_node name (map_pred_data |
523 (apfst (fn (intro, elim, nparams) => (thm::intro, elim, nparams)))) gr |
531 (apfst (fn (intro, elim, nparams) => (thm::intro, elim, nparams)))) gr |
524 | NONE => |
532 | NONE => |
525 let |
533 let |
526 val nparams = the_default 0 (try (#3 o fetch_pred_data thy) name) |
534 val nparams = the_default 0 (try (#nparams o rep_pred_data o (fetch_pred_data thy)) name) |
527 in Graph.new_node (name, mk_pred_data (([thm], NONE, nparams), ([], [], []))) gr end; |
535 in Graph.new_node (name, mk_pred_data (([thm], NONE, nparams), ([], [], []))) gr end; |
528 in PredData.map cons_intro thy end |
536 in PredData.map cons_intro thy end |
529 |
537 |
530 fun set_elim thm = let |
538 fun set_elim thm = let |
531 val (name, _) = dest_Const (fst |
539 val (name, _) = dest_Const (fst |
535 |
543 |
536 fun set_nparams name nparams = let |
544 fun set_nparams name nparams = let |
537 fun set (intros, elim, _ ) = (intros, elim, nparams) |
545 fun set (intros, elim, _ ) = (intros, elim, nparams) |
538 in PredData.map (Graph.map_node name (map_pred_data (apfst set))) end |
546 in PredData.map (Graph.map_node name (map_pred_data (apfst set))) end |
539 |
547 |
540 fun register_predicate (intros, elim, nparams) = let |
548 fun register_predicate (pre_intros, pre_elim, nparams) thy = let |
541 val (name, _) = dest_Const (fst (strip_intro_concl nparams (prop_of (hd intros)))) |
549 val (name, _) = dest_Const (fst (strip_intro_concl nparams (prop_of (hd pre_intros)))) |
542 in |
550 (* preprocessing *) |
543 PredData.map (Graph.new_node (name, mk_pred_data ((intros, SOME elim, nparams), ([], [], [])))) |
551 val intros = ind_set_codegen_preproc thy (map (preprocess_intro thy) pre_intros) |
|
552 val elim = singleton (ind_set_codegen_preproc thy) (preprocess_elim thy nparams pre_elim) |
|
553 in |
|
554 PredData.map |
|
555 (Graph.new_node (name, mk_pred_data ((intros, SOME elim, nparams), ([], [], [])))) thy |
544 end |
556 end |
545 |
557 |
546 fun set_generator_name pred mode name = |
558 fun set_generator_name pred mode name = |
547 let |
559 let |
548 val set = (apsnd o apsnd3 o cons) (mode, mk_function_data (name, NONE)) |
560 val set = (apsnd o apsnd3 o cons) (mode, mk_function_data (name, NONE)) |
1811 val intrs = maps (intros_of thy) prednames |
1823 val intrs = maps (intros_of thy) prednames |
1812 |> map (Logic.unvarify o prop_of) |
1824 |> map (Logic.unvarify o prop_of) |
1813 val nparams = nparams_of thy (hd prednames) |
1825 val nparams = nparams_of thy (hd prednames) |
1814 val preds = distinct (op =) (map (dest_Const o fst o (strip_intro_concl nparams)) intrs) |
1826 val preds = distinct (op =) (map (dest_Const o fst o (strip_intro_concl nparams)) intrs) |
1815 val extra_modes = all_modes_of thy |> filter_out (fn (name, _) => member (op =) prednames name) |
1827 val extra_modes = all_modes_of thy |> filter_out (fn (name, _) => member (op =) prednames name) |
1816 val _ = Output.tracing ("extra_modes are: " ^ |
1828 (*val _ = Output.tracing ("extra_modes are: " ^ |
1817 cat_lines (map (fn (name, modes) => name ^ " has modes:" ^ |
1829 cat_lines (map (fn (name, modes) => name ^ " has modes:" ^ |
1818 (commas (map string_of_mode modes))) extra_modes)) |
1830 (commas (map string_of_mode modes))) extra_modes)) *) |
1819 val _ $ u = Logic.strip_imp_concl (hd intrs); |
1831 val _ $ u = Logic.strip_imp_concl (hd intrs); |
1820 val params = List.take (snd (strip_comb u), nparams); |
1832 val params = List.take (snd (strip_comb u), nparams); |
1821 val param_vs = maps term_vs params |
1833 val param_vs = maps term_vs params |
1822 val all_vs = terms_vs intrs |
1834 val all_vs = terms_vs intrs |
1823 fun dest_prem t = |
1835 fun dest_prem t = |
1882 |> Theory.checkpoint |
1894 |> Theory.checkpoint |
1883 in |
1895 in |
1884 thy'' |
1896 thy'' |
1885 end |
1897 end |
1886 |
1898 |
|
1899 fun extend' value_of edges_of key (G, visited) = |
|
1900 let |
|
1901 val _ = Output.tracing ("calling extend' with " ^ key) |
|
1902 val (G', v) = case try (Graph.get_node G) key of |
|
1903 SOME v => (G, v) |
|
1904 | NONE => (Graph.new_node (key, value_of key) G, value_of key) |
|
1905 val (G'', visited') = fold (extend' value_of edges_of) (edges_of (key, v) \\ visited) |
|
1906 (G', key :: visited) |
|
1907 in |
|
1908 (fold (Graph.add_edge o (pair key)) (edges_of (key, v)) G'', visited') |
|
1909 end; |
|
1910 |
|
1911 fun extend value_of edges_of key G = fst (extend' value_of edges_of key (G, [])) |
|
1912 |
1887 fun gen_add_equations steps names thy = |
1913 fun gen_add_equations steps names thy = |
1888 let |
1914 let |
1889 val thy' = PredData.map (fold (Graph.extend (dependencies_of thy)) names) thy |> Theory.checkpoint; |
1915 val thy' = PredData.map (fold (extend (fetch_pred_data thy) (depending_preds_of thy)) names) thy |> Theory.checkpoint; |
1890 fun strong_conn_of gr keys = |
1916 fun strong_conn_of gr keys = |
1891 Graph.strong_conn (Graph.subgraph (member (op =) (Graph.all_succs gr keys)) gr) |
1917 Graph.strong_conn (Graph.subgraph (member (op =) (Graph.all_succs gr keys)) gr) |
1892 val scc = strong_conn_of (PredData.get thy') names |
1918 val scc = strong_conn_of (PredData.get thy') names |
1893 val thy'' = fold_rev |
1919 val thy'' = fold_rev |
1894 (fn preds => fn thy => |
1920 (fn preds => fn thy => |
1960 |
1986 |
1961 (* TODO: make TheoryDataFun to GenericDataFun & remove duplication of local theory and theory *) |
1987 (* TODO: make TheoryDataFun to GenericDataFun & remove duplication of local theory and theory *) |
1962 (* TODO: must create state to prove multiple cases *) |
1988 (* TODO: must create state to prove multiple cases *) |
1963 fun generic_code_pred prep_const raw_const lthy = |
1989 fun generic_code_pred prep_const raw_const lthy = |
1964 let |
1990 let |
1965 |
|
1966 val thy = ProofContext.theory_of lthy |
1991 val thy = ProofContext.theory_of lthy |
1967 val const = prep_const thy raw_const |
1992 val const = prep_const thy raw_const |
1968 val _ = Output.tracing "extending graph" |
1993 val lthy' = LocalTheory.theory (PredData.map |
1969 val lthy' = LocalTheory.theory (PredData.map (Graph.extend (dependencies_of thy) const)) lthy |
1994 (extend (fetch_pred_data thy) (depending_preds_of thy) const)) lthy |
1970 |> LocalTheory.checkpoint |
1995 |> LocalTheory.checkpoint |
1971 val _ = Output.tracing "code_pred graph extended..." |
|
1972 val thy' = ProofContext.theory_of lthy' |
1996 val thy' = ProofContext.theory_of lthy' |
1973 val preds = Graph.all_preds (PredData.get thy') [const] |> filter_out (has_elim thy') |
1997 val preds = Graph.all_preds (PredData.get thy') [const] |> filter_out (has_elim thy') |
1974 |
|
1975 fun mk_cases const = |
1998 fun mk_cases const = |
1976 let |
1999 let |
1977 val nparams = nparams_of thy' const |
2000 val nparams = nparams_of thy' const |
1978 val intros = intros_of thy' const |
2001 val intros = intros_of thy' const |
1979 in mk_casesrule lthy' nparams intros end |
2002 in mk_casesrule lthy' nparams intros end |