4 to equations. |
4 to equations. |
5 *) |
5 *) |
6 |
6 |
7 signature PREDICATE_COMPILE_CORE = |
7 signature PREDICATE_COMPILE_CORE = |
8 sig |
8 sig |
|
9 val setup: theory -> theory |
|
10 val code_pred: bool -> string -> Proof.context -> Proof.state |
|
11 val code_pred_cmd: bool -> string -> Proof.context -> Proof.state |
9 type smode = (int * int list option) list |
12 type smode = (int * int list option) list |
10 type mode = smode option list * smode |
13 type mode = smode option list * smode |
11 datatype tmode = Mode of mode * smode * tmode option list; |
14 datatype tmode = Mode of mode * smode * tmode option list; |
12 (*val add_equations_of: bool -> string list -> theory -> theory *) |
15 (*val add_equations_of: bool -> string list -> theory -> theory *) |
13 val register_predicate : (thm list * thm * int) -> theory -> theory |
16 val register_predicate : (thm list * thm * int) -> theory -> theory |
|
17 val register_intros : thm list -> theory -> theory |
14 val is_registered : theory -> string -> bool |
18 val is_registered : theory -> string -> bool |
15 (* val fetch_pred_data : theory -> string -> (thm list * thm * int) *) |
19 (* val fetch_pred_data : theory -> string -> (thm list * thm * int) *) |
16 val predfun_intro_of: theory -> string -> mode -> thm |
20 val predfun_intro_of: theory -> string -> mode -> thm |
17 val predfun_elim_of: theory -> string -> mode -> thm |
21 val predfun_elim_of: theory -> string -> mode -> thm |
18 val strip_intro_concl: int -> term -> term * (term list * term list) |
22 val strip_intro_concl: int -> term -> term * (term list * term list) |
22 val string_of_mode : mode -> string |
26 val string_of_mode : mode -> string |
23 val intros_of: theory -> string -> thm list |
27 val intros_of: theory -> string -> thm list |
24 val nparams_of: theory -> string -> int |
28 val nparams_of: theory -> string -> int |
25 val add_intro: thm -> theory -> theory |
29 val add_intro: thm -> theory -> theory |
26 val set_elim: thm -> theory -> theory |
30 val set_elim: thm -> theory -> theory |
27 val setup: theory -> theory |
31 val set_nparams : string -> int -> theory -> theory |
28 val code_pred: string -> Proof.context -> Proof.state |
|
29 val code_pred_cmd: string -> Proof.context -> Proof.state |
|
30 val print_stored_rules: theory -> unit |
32 val print_stored_rules: theory -> unit |
31 val print_all_modes: theory -> unit |
33 val print_all_modes: theory -> unit |
32 val do_proofs: bool ref |
34 val do_proofs: bool ref |
33 val mk_casesrule : Proof.context -> int -> thm list -> term |
35 val mk_casesrule : Proof.context -> int -> thm list -> term |
34 val analyze_compr: theory -> term -> term |
36 val analyze_compr: theory -> term -> term |
185 val (params, args) = chop nparams all_args |
188 val (params, args) = chop nparams all_args |
186 in (pred, (params, args)) end |
189 in (pred, (params, args)) end |
187 |
190 |
188 (** data structures **) |
191 (** data structures **) |
189 |
192 |
190 type smode = (int * int list option) list; |
193 type smode = (int * int list option) list |
191 type mode = smode option list * smode; |
194 type mode = smode option list * smode; |
192 datatype tmode = Mode of mode * smode * tmode option list; |
195 datatype tmode = Mode of mode * smode * tmode option list; |
193 |
196 |
194 fun gen_split_smode (mk_tuple, strip_tuple) smode ts = |
197 fun gen_split_smode (mk_tuple, strip_tuple) smode ts = |
195 let |
198 let |
236 |
239 |
237 fun string_of_tmode (Mode (predmode, termmode, param_modes)) = |
240 fun string_of_tmode (Mode (predmode, termmode, param_modes)) = |
238 "predmode: " ^ (string_of_mode predmode) ^ |
241 "predmode: " ^ (string_of_mode predmode) ^ |
239 (if null param_modes then "" else |
242 (if null param_modes then "" else |
240 "; " ^ "params: " ^ commas (map (the_default "NONE" o Option.map string_of_tmode) param_modes)) |
243 "; " ^ "params: " ^ commas (map (the_default "NONE" o Option.map string_of_tmode) param_modes)) |
|
244 |
|
245 (* generation of case rules from user-given introduction rules *) |
|
246 |
|
247 fun mk_casesrule ctxt nparams introrules = |
|
248 let |
|
249 val intros = map (Logic.unvarify o prop_of) introrules |
|
250 val (pred, (params, args)) = strip_intro_concl nparams (hd intros) |
|
251 val ([propname], ctxt1) = Variable.variant_fixes ["thesis"] ctxt |
|
252 val prop = HOLogic.mk_Trueprop (Free (propname, HOLogic.boolT)) |
|
253 val (argnames, ctxt2) = Variable.variant_fixes |
|
254 (map (fn i => "a" ^ string_of_int i) (1 upto (length args))) ctxt1 |
|
255 val argvs = map2 (curry Free) argnames (map fastype_of args) |
|
256 fun mk_case intro = |
|
257 let |
|
258 val (_, (_, args)) = strip_intro_concl nparams intro |
|
259 val prems = Logic.strip_imp_prems intro |
|
260 val eqprems = map (HOLogic.mk_Trueprop o HOLogic.mk_eq) (argvs ~~ args) |
|
261 val frees = (fold o fold_aterms) |
|
262 (fn t as Free _ => |
|
263 if member (op aconv) params t then I else insert (op aconv) t |
|
264 | _ => I) (args @ prems) [] |
|
265 in fold Logic.all frees (Logic.list_implies (eqprems @ prems, prop)) end |
|
266 val assm = HOLogic.mk_Trueprop (list_comb (pred, params @ argvs)) |
|
267 val cases = map mk_case intros |
|
268 in Logic.list_implies (assm :: cases, prop) end; |
241 |
269 |
|
270 |
242 datatype indprem = Prem of term list * term | Negprem of term list * term | Sidecond of term | |
271 datatype indprem = Prem of term list * term | Negprem of term list * term | Sidecond of term | |
243 GeneratorPrem of term list * term | Generator of (string * typ); |
272 GeneratorPrem of term list * term | Generator of (string * typ); |
244 |
273 |
245 type moded_clause = term list * (indprem * tmode) list |
274 type moded_clause = term list * (indprem * tmode) list |
246 type 'a pred_mode_table = (string * (mode * 'a) list) list |
275 type 'a pred_mode_table = (string * (mode * 'a) list) list |
577 let |
606 let |
578 fun find is n [] = is |
607 fun find is n [] = is |
579 | find is n (x :: xs) = find (if pred x then (n :: is) else is) (n + 1) xs; |
608 | find is n (x :: xs) = find (if pred x then (n :: is) else is) (n + 1) xs; |
580 in rev (find [] 0 xs) end; |
609 in rev (find [] 0 xs) end; |
581 |
610 |
582 fun is_predT (T as Type("fun", [_, _])) = (snd (strip_type T) = HOLogic.boolT) |
|
583 | is_predT _ = false |
|
584 |
|
585 fun guess_nparams T = |
611 fun guess_nparams T = |
586 let |
612 let |
587 val argTs = binder_types T |
613 val argTs = binder_types T |
588 val nparams = fold (curry Int.max) |
614 val nparams = fold (curry Int.max) |
589 (map (fn x => x + 1) (find_indexes is_predT argTs)) 0 |
615 (map (fn x => x + 1) (find_indexes is_predT argTs)) 0 |
609 |
635 |
610 fun set_nparams name nparams = let |
636 fun set_nparams name nparams = let |
611 fun set (intros, elim, _ ) = (intros, elim, nparams) |
637 fun set (intros, elim, _ ) = (intros, elim, nparams) |
612 in PredData.map (Graph.map_node name (map_pred_data (apfst set))) end |
638 in PredData.map (Graph.map_node name (map_pred_data (apfst set))) end |
613 |
639 |
614 fun register_predicate (pre_intros, pre_elim, nparams) thy = let |
640 fun register_predicate (pre_intros, pre_elim, nparams) thy = |
|
641 let |
615 val (name, _) = dest_Const (fst (strip_intro_concl nparams (prop_of (hd pre_intros)))) |
642 val (name, _) = dest_Const (fst (strip_intro_concl nparams (prop_of (hd pre_intros)))) |
616 (* preprocessing *) |
643 (* preprocessing *) |
617 val intros = ind_set_codegen_preproc thy (map (preprocess_intro thy) pre_intros) |
644 val intros = ind_set_codegen_preproc thy (map (preprocess_intro thy) pre_intros) |
618 val elim = singleton (ind_set_codegen_preproc thy) (preprocess_elim thy nparams pre_elim) |
645 val elim = singleton (ind_set_codegen_preproc thy) (preprocess_elim thy nparams pre_elim) |
619 in |
646 in |
620 PredData.map |
647 if not (member (op =) (Graph.keys (PredData.get thy)) name) then |
|
648 PredData.map |
621 (Graph.new_node (name, mk_pred_data ((intros, SOME elim, nparams), ([], [], [])))) thy |
649 (Graph.new_node (name, mk_pred_data ((intros, SOME elim, nparams), ([], [], [])))) thy |
|
650 else thy |
622 end |
651 end |
|
652 |
|
653 fun register_intros pre_intros thy = |
|
654 let |
|
655 val (_, T) = dest_Const (fst (strip_intro_concl 0 (prop_of (hd pre_intros)))) |
|
656 val nparams = guess_nparams T |
|
657 val pre_elim = |
|
658 (Drule.standard o (setmp quick_and_dirty true (SkipProof.make_thm thy))) |
|
659 (mk_casesrule (ProofContext.init thy) nparams pre_intros) |
|
660 in register_predicate (pre_intros, pre_elim, nparams) thy end |
623 |
661 |
624 fun set_generator_name pred mode name = |
662 fun set_generator_name pred mode name = |
625 let |
663 let |
626 val set = (apsnd o apsnd3 o cons) (mode, mk_function_data (name, NONE)) |
664 val set = (apsnd o apsnd3 o cons) (mode, mk_function_data (name, NONE)) |
627 in |
665 in |
862 fun subsets i j = if i <= j then |
900 fun subsets i j = if i <= j then |
863 let val is = subsets (i+1) j |
901 let val is = subsets (i+1) j |
864 in merge (map (fn ks => i::ks) is) is end |
902 in merge (map (fn ks => i::ks) is) is end |
865 else [[]]; |
903 else [[]]; |
866 |
904 |
867 (* FIXME: should be in library - map_prod *) |
905 (* FIXME: should be in library - cprod = map_prod I *) |
868 fun cprod ([], ys) = [] |
906 fun cprod ([], ys) = [] |
869 | cprod (x :: xs, ys) = map (pair x) ys @ cprod (xs, ys); |
907 | cprod (x :: xs, ys) = map (pair x) ys @ cprod (xs, ys); |
870 |
908 |
871 fun cprods xss = foldr (map op :: o cprod) [[]] xss; |
909 fun cprods xss = foldr (map op :: o cprod) [[]] xss; |
872 |
910 |
984 val T = the (AList.lookup (op =) vTs v) |
1022 val T = the (AList.lookup (op =) vTs v) |
985 in |
1023 in |
986 (Generator (v, T), Mode (([], []), [], [])) |
1024 (Generator (v, T), Mode (([], []), [], [])) |
987 end; |
1025 end; |
988 |
1026 |
989 fun gen_prem (Prem (us, t)) = GeneratorPrem (us, t) |
1027 fun gen_prem (Prem (us, t)) = GeneratorPrem (us, t) |
|
1028 | gen_prem (Negprem (us, t)) = error "it is a negated prem" |
|
1029 | gen_prem (Sidecond t) = error "it is a sidecond" |
990 | gen_prem _ = error "gen_prem : invalid input for gen_prem" |
1030 | gen_prem _ = error "gen_prem : invalid input for gen_prem" |
991 |
1031 |
992 fun param_gen_prem param_vs (p as Prem (us, t as Free (v, _))) = |
1032 fun param_gen_prem param_vs (p as Prem (us, t as Free (v, _))) = |
993 if member (op =) param_vs v then |
1033 if member (op =) param_vs v then |
994 GeneratorPrem (us, t) |
1034 GeneratorPrem (us, t) |
995 else p |
1035 else p |
996 | param_gen_prem param_vs p = p |
1036 | param_gen_prem param_vs p = p |
997 |
1037 |
998 fun check_mode_clause with_generator thy param_vs modes gen_modes (iss, is) (ts, ps) = |
1038 fun check_mode_clause with_generator thy param_vs modes gen_modes (iss, is) (ts, ps) = |
999 let |
1039 let |
|
1040 (* |
|
1041 val _ = Output.tracing ("param_vs:" ^ commas param_vs) |
|
1042 val _ = Output.tracing ("iss:" ^ |
|
1043 commas (map (fn is => case is of SOME is => string_of_smode is | NONE => "NONE") iss)) |
|
1044 *) |
1000 val modes' = modes @ List.mapPartial |
1045 val modes' = modes @ List.mapPartial |
1001 (fn (_, NONE) => NONE | (v, SOME js) => SOME (v, [([], js)])) |
1046 (fn (_, NONE) => NONE | (v, SOME js) => SOME (v, [([], js)])) |
1002 (param_vs ~~ iss); |
1047 (param_vs ~~ iss); |
1003 val gen_modes' = gen_modes @ List.mapPartial |
1048 val gen_modes' = gen_modes @ List.mapPartial |
1004 (fn (_, NONE) => NONE | (v, SOME js) => SOME (v, [([], js)])) |
1049 (fn (_, NONE) => NONE | (v, SOME js) => SOME (v, [([], js)])) |
1008 fun check_mode_prems acc_ps vs [] = SOME (acc_ps, vs) |
1053 fun check_mode_prems acc_ps vs [] = SOME (acc_ps, vs) |
1009 | check_mode_prems acc_ps vs ps = (case select_mode_prem thy modes' vs ps of |
1054 | check_mode_prems acc_ps vs ps = (case select_mode_prem thy modes' vs ps of |
1010 NONE => |
1055 NONE => |
1011 (if with_generator then |
1056 (if with_generator then |
1012 (case select_mode_prem thy gen_modes' vs ps of |
1057 (case select_mode_prem thy gen_modes' vs ps of |
1013 SOME (p, SOME mode) => check_mode_prems ((gen_prem p, mode) :: acc_ps) |
1058 SOME (p as Prem _, SOME mode) => check_mode_prems ((gen_prem p, mode) :: acc_ps) |
1014 (case p of Prem (us, _) => vs union terms_vs us | _ => vs) |
1059 (case p of Prem (us, _) => vs union terms_vs us | _ => vs) |
1015 (filter_out (equal p) ps) |
1060 (filter_out (equal p) ps) |
1016 | NONE => |
1061 | NONE => |
1017 let |
1062 let |
1018 val all_generator_vs = all_subsets (prem_vs \\ vs) |> sort (int_ord o (pairself length)) |
1063 val all_generator_vs = all_subsets (prem_vs \\ vs) |> sort (int_ord o (pairself length)) |
1019 in |
1064 in |
1020 case (find_first (fn generator_vs => is_some |
1065 case (find_first (fn generator_vs => is_some |
1021 (select_mode_prem thy modes' (vs union generator_vs) ps)) all_generator_vs) of |
1066 (select_mode_prem thy modes' (vs union generator_vs) ps)) all_generator_vs) of |
1022 SOME generator_vs => check_mode_prems ((map (generator vTs) generator_vs) @ acc_ps) |
1067 SOME generator_vs => check_mode_prems ((map (generator vTs) generator_vs) @ acc_ps) |
1023 (vs union generator_vs) ps |
1068 (vs union generator_vs) ps |
1024 | NONE => NONE |
1069 | NONE => let |
|
1070 val _ = Output.tracing ("ps:" ^ (commas |
|
1071 (map (fn p => string_of_moded_prem thy (p, Mode (([], []), [], []))) ps))) |
|
1072 in error "mode analysis failed" end |
1025 end) |
1073 end) |
1026 else |
1074 else |
1027 NONE) |
1075 NONE) |
1028 | SOME (p, SOME mode) => check_mode_prems ((if with_generator then param_gen_prem param_vs p else p, mode) :: acc_ps) |
1076 | SOME (p, SOME mode) => check_mode_prems ((if with_generator then param_gen_prem param_vs p else p, mode) :: acc_ps) |
1029 (case p of Prem (us, _) => vs union terms_vs us | _ => vs) |
1077 (case p of Prem (us, _) => vs union terms_vs us | _ => vs) |
1491 val unfolddef_tac = Simplifier.asm_full_simp_tac (HOL_basic_ss addsimps simprules) 1 |
1539 val unfolddef_tac = Simplifier.asm_full_simp_tac (HOL_basic_ss addsimps simprules) 1 |
1492 val introthm = Goal.prove (ProofContext.init thy) (argnames @ param_names @ param_names' @ ["y"]) [] introtrm (fn {...} => unfolddef_tac) |
1540 val introthm = Goal.prove (ProofContext.init thy) (argnames @ param_names @ param_names' @ ["y"]) [] introtrm (fn {...} => unfolddef_tac) |
1493 val P = HOLogic.mk_Trueprop (Free ("P", HOLogic.boolT)); |
1541 val P = HOLogic.mk_Trueprop (Free ("P", HOLogic.boolT)); |
1494 val elimtrm = Logic.list_implies ([funpropE, Logic.mk_implies (predpropE, P)], P) |
1542 val elimtrm = Logic.list_implies ([funpropE, Logic.mk_implies (predpropE, P)], P) |
1495 val elimthm = Goal.prove (ProofContext.init thy) (argnames @ param_names @ param_names' @ ["y", "P"]) [] elimtrm (fn {...} => unfolddef_tac) |
1543 val elimthm = Goal.prove (ProofContext.init thy) (argnames @ param_names @ param_names' @ ["y", "P"]) [] elimtrm (fn {...} => unfolddef_tac) |
1496 val _ = Output.tracing (Display.string_of_thm_global thy elimthm) |
|
1497 val _ = Output.tracing (Display.string_of_thm_global thy introthm) |
|
1498 |
|
1499 in |
1544 in |
1500 (introthm, elimthm) |
1545 (introthm, elimthm) |
1501 end; |
1546 end; |
1502 |
1547 |
1503 fun create_constname_of_mode thy prefix name mode = |
1548 fun create_constname_of_mode thy prefix name mode = |
1607 end; |
1652 end; |
1608 val predterm = PredicateCompFuns.mk_Enum (mk_split_lambda xouts |
1653 val predterm = PredicateCompFuns.mk_Enum (mk_split_lambda xouts |
1609 (list_comb (Const (name, T), xparams' @ xargs))) |
1654 (list_comb (Const (name, T), xparams' @ xargs))) |
1610 val lhs = list_comb (Const (mode_cname, funT), xparams @ xins) |
1655 val lhs = list_comb (Const (mode_cname, funT), xparams @ xins) |
1611 val def = Logic.mk_equals (lhs, predterm) |
1656 val def = Logic.mk_equals (lhs, predterm) |
1612 val _ = Output.tracing ("def:" ^ (Syntax.string_of_term_global thy def)) |
|
1613 val ([definition], thy') = thy |> |
1657 val ([definition], thy') = thy |> |
1614 Sign.add_consts_i [(Binding.name mode_cbasename, funT, NoSyn)] |> |
1658 Sign.add_consts_i [(Binding.name mode_cbasename, funT, NoSyn)] |> |
1615 PureThy.add_defs false [((Binding.name (mode_cbasename ^ "_def"), def), [])] |
1659 PureThy.add_defs false [((Binding.name (mode_cbasename ^ "_def"), def), [])] |
1616 val (intro, elim) = |
1660 val (intro, elim) = |
1617 create_intro_elim_rule mode definition mode_cname funT (Const (name, T)) thy' |
1661 create_intro_elim_rule mode definition mode_cname funT (Const (name, T)) thy' |
1618 val _ = Output.tracing (Display.string_of_thm_global thy' definition) |
|
1619 in thy' |
1662 in thy' |
1620 |> add_predfun name mode (mode_cname, definition, intro, elim) |
1663 |> add_predfun name mode (mode_cname, definition, intro, elim) |
1621 |> PureThy.store_thm (Binding.name (mode_cbasename ^ "I"), intro) |> snd |
1664 |> PureThy.store_thm (Binding.name (mode_cbasename ^ "I"), intro) |> snd |
1622 |> PureThy.store_thm (Binding.name (mode_cbasename ^ "E"), elim) |> snd |
1665 |> PureThy.store_thm (Binding.name (mode_cbasename ^ "E"), elim) |> snd |
1623 |> Theory.checkpoint |
1666 |> Theory.checkpoint |
2118 fun all_smodes_of_typs Ts = cprods_subset ( |
2161 fun all_smodes_of_typs Ts = cprods_subset ( |
2119 map_index (fn (i, U) => |
2162 map_index (fn (i, U) => |
2120 case HOLogic.strip_tupleT U of |
2163 case HOLogic.strip_tupleT U of |
2121 [] => [(i + 1, NONE)] |
2164 [] => [(i + 1, NONE)] |
2122 | [U] => [(i + 1, NONE)] |
2165 | [U] => [(i + 1, NONE)] |
2123 | Us => map (pair (i + 1) o SOME) ((subsets 1 (length Us)) \\ [[], 1 upto (length Us)])) |
2166 | Us => (i + 1, NONE) :: |
|
2167 (map (pair (i + 1) o SOME) ((subsets 1 (length Us)) \\ [[], 1 upto (length Us)]))) |
2124 Ts) |
2168 Ts) |
2125 in |
2169 in |
2126 cprod (cprods (map (fn T => case strip_type T of |
2170 cprod (cprods (map (fn T => case strip_type T of |
2127 (Rs as _ :: _, Type ("bool", [])) => map SOME (all_smodes_of_typs Rs) | _ => [NONE]) Ts), |
2171 (Rs as _ :: _, Type ("bool", [])) => map SOME (all_smodes_of_typs Rs) | _ => [NONE]) Ts), |
2128 all_smodes_of_typs Us) |
2172 all_smodes_of_typs Us) |
2218 are_not_defined = (fn thy => fn preds => true), (* TODO *) |
2262 are_not_defined = (fn thy => fn preds => true), (* TODO *) |
2219 qname = "rpred_equation"} |
2263 qname = "rpred_equation"} |
2220 |
2264 |
2221 (** user interface **) |
2265 (** user interface **) |
2222 |
2266 |
2223 (* generation of case rules from user-given introduction rules *) |
|
2224 |
|
2225 fun mk_casesrule ctxt nparams introrules = |
|
2226 let |
|
2227 val intros = map (Logic.unvarify o prop_of) introrules |
|
2228 val (pred, (params, args)) = strip_intro_concl nparams (hd intros) |
|
2229 val ([propname], ctxt1) = Variable.variant_fixes ["thesis"] ctxt |
|
2230 val prop = HOLogic.mk_Trueprop (Free (propname, HOLogic.boolT)) |
|
2231 val (argnames, ctxt2) = Variable.variant_fixes |
|
2232 (map (fn i => "a" ^ string_of_int i) (1 upto (length args))) ctxt1 |
|
2233 val argvs = map2 (curry Free) argnames (map fastype_of args) |
|
2234 fun mk_case intro = |
|
2235 let |
|
2236 val (_, (_, args)) = strip_intro_concl nparams intro |
|
2237 val prems = Logic.strip_imp_prems intro |
|
2238 val eqprems = map (HOLogic.mk_Trueprop o HOLogic.mk_eq) (argvs ~~ args) |
|
2239 val frees = (fold o fold_aterms) |
|
2240 (fn t as Free _ => |
|
2241 if member (op aconv) params t then I else insert (op aconv) t |
|
2242 | _ => I) (args @ prems) [] |
|
2243 in fold Logic.all frees (Logic.list_implies (eqprems @ prems, prop)) end |
|
2244 val assm = HOLogic.mk_Trueprop (list_comb (pred, params @ argvs)) |
|
2245 val cases = map mk_case intros |
|
2246 in Logic.list_implies (assm :: cases, prop) end; |
|
2247 |
|
2248 (* code_pred_intro attribute *) |
2267 (* code_pred_intro attribute *) |
2249 |
2268 |
2250 fun attrib f = Thm.declaration_attribute (fn thm => Context.mapping (f thm) I); |
2269 fun attrib f = Thm.declaration_attribute (fn thm => Context.mapping (f thm) I); |
2251 |
2270 |
2252 val code_pred_intros_attrib = attrib add_intro; |
2271 val code_pred_intros_attrib = attrib add_intro; |
2253 |
2272 |
2254 local |
2273 |
|
2274 (*FIXME |
|
2275 - Naming of auxiliary rules necessary? |
|
2276 - add default code equations P x y z = P_i_i_i x y z |
|
2277 *) |
|
2278 |
|
2279 val setup = PredData.put (Graph.empty) #> |
|
2280 Attrib.setup @{binding code_pred_intros} (Scan.succeed (attrib add_intro)) |
|
2281 "adding alternative introduction rules for code generation of inductive predicates" |
|
2282 (* Attrib.setup @{binding code_ind_cases} (Scan.succeed add_elim_attrib) |
|
2283 "adding alternative elimination rules for code generation of inductive predicates"; |
|
2284 *) |
|
2285 (*FIXME name discrepancy in attribs and ML code*) |
|
2286 (*FIXME intros should be better named intro*) |
|
2287 (*FIXME why distinguished attribute for cases?*) |
2255 |
2288 |
2256 (* TODO: make TheoryDataFun to GenericDataFun & remove duplication of local theory and theory *) |
2289 (* TODO: make TheoryDataFun to GenericDataFun & remove duplication of local theory and theory *) |
2257 fun generic_code_pred prep_const raw_const lthy = |
2290 fun generic_code_pred prep_const rpred raw_const lthy = |
2258 let |
2291 let |
2259 val thy = ProofContext.theory_of lthy |
2292 val thy = ProofContext.theory_of lthy |
2260 val const = prep_const thy raw_const |
2293 val const = prep_const thy raw_const |
2261 val lthy' = LocalTheory.theory (PredData.map |
2294 val lthy' = LocalTheory.theory (PredData.map |
2262 (extend (fetch_pred_data thy) (depending_preds_of thy) const)) lthy |
2295 (extend (fetch_pred_data thy) (depending_preds_of thy) const)) lthy |
2280 fun after_qed thms goal_ctxt = |
2313 fun after_qed thms goal_ctxt = |
2281 let |
2314 let |
2282 val global_thms = ProofContext.export goal_ctxt |
2315 val global_thms = ProofContext.export goal_ctxt |
2283 (ProofContext.init (ProofContext.theory_of goal_ctxt)) (map the_single thms) |
2316 (ProofContext.init (ProofContext.theory_of goal_ctxt)) (map the_single thms) |
2284 in |
2317 in |
2285 goal_ctxt |> LocalTheory.theory (fold set_elim global_thms #> add_equations [const]) |
2318 goal_ctxt |> LocalTheory.theory (fold set_elim global_thms #> |
|
2319 (if rpred then |
|
2320 (add_sizelim_equations [const] #> add_quickcheck_equations [const]) |
|
2321 else add_equations [const])) |
2286 end |
2322 end |
2287 in |
2323 in |
2288 Proof.theorem_i NONE after_qed (map (single o (rpair [])) cases_rules) lthy'' |
2324 Proof.theorem_i NONE after_qed (map (single o (rpair [])) cases_rules) lthy'' |
2289 end; |
2325 end; |
2290 |
|
2291 structure P = OuterParse |
|
2292 |
|
2293 in |
|
2294 |
2326 |
2295 val code_pred = generic_code_pred (K I); |
2327 val code_pred = generic_code_pred (K I); |
2296 val code_pred_cmd = generic_code_pred Code.read_const |
2328 val code_pred_cmd = generic_code_pred Code.read_const |
2297 |
|
2298 val setup = PredData.put (Graph.empty) #> |
|
2299 Attrib.setup @{binding code_pred_intros} (Scan.succeed (attrib add_intro)) |
|
2300 "adding alternative introduction rules for code generation of inductive predicates" |
|
2301 (* Attrib.setup @{binding code_ind_cases} (Scan.succeed add_elim_attrib) |
|
2302 "adding alternative elimination rules for code generation of inductive predicates"; |
|
2303 *) |
|
2304 (*FIXME name discrepancy in attribs and ML code*) |
|
2305 (*FIXME intros should be better named intro*) |
|
2306 (*FIXME why distinguished attribute for cases?*) |
|
2307 |
|
2308 val _ = OuterSyntax.local_theory_to_proof "code_pred" |
|
2309 "prove equations for predicate specified by intro/elim rules" |
|
2310 OuterKeyword.thy_goal (P.term_group >> code_pred_cmd) |
|
2311 |
|
2312 end |
|
2313 |
|
2314 (*FIXME |
|
2315 - Naming of auxiliary rules necessary? |
|
2316 - add default code equations P x y z = P_i_i_i x y z |
|
2317 *) |
|
2318 |
2329 |
2319 (* transformation for code generation *) |
2330 (* transformation for code generation *) |
2320 |
2331 |
2321 val eval_ref = ref (NONE : (unit -> term Predicate.pred) option); |
2332 val eval_ref = ref (NONE : (unit -> term Predicate.pred) option); |
2322 |
2333 |
2340 | [m] => m |
2351 | [m] => m |
2341 | m :: _ :: _ => (warning ("Multiple modes possible for comprehension " |
2352 | m :: _ :: _ => (warning ("Multiple modes possible for comprehension " |
2342 ^ Syntax.string_of_term_global thy t_compr); m); |
2353 ^ Syntax.string_of_term_global thy t_compr); m); |
2343 val (inargs, outargs) = split_smode user_mode' args; |
2354 val (inargs, outargs) = split_smode user_mode' args; |
2344 val t_pred = list_comb (compile_expr NONE thy (m, list_comb (pred, params)), inargs); |
2355 val t_pred = list_comb (compile_expr NONE thy (m, list_comb (pred, params)), inargs); |
2345 val t_eval = if null outargs then t_pred else let |
2356 val t_eval = if null outargs then t_pred else |
|
2357 let |
2346 val outargs_bounds = map (fn Bound i => i) outargs; |
2358 val outargs_bounds = map (fn Bound i => i) outargs; |
2347 val outargsTs = map (nth Ts) outargs_bounds; |
2359 val outargsTs = map (nth Ts) outargs_bounds; |
2348 val T_pred = HOLogic.mk_tupleT outargsTs; |
2360 val T_pred = HOLogic.mk_tupleT outargsTs; |
2349 val T_compr = HOLogic.mk_ptupleT fp Ts; |
2361 val T_compr = HOLogic.mk_ptupleT fp Ts; |
2350 val arrange_bounds = map_index I outargs_bounds |
2362 val arrange_bounds = map_index I outargs_bounds |
2359 fun eval thy t_compr = |
2371 fun eval thy t_compr = |
2360 let |
2372 let |
2361 val t = analyze_compr thy t_compr; |
2373 val t = analyze_compr thy t_compr; |
2362 val T = dest_predT PredicateCompFuns.compfuns (fastype_of t); |
2374 val T = dest_predT PredicateCompFuns.compfuns (fastype_of t); |
2363 val t' = mk_map PredicateCompFuns.compfuns T HOLogic.termT (HOLogic.term_of_const T) t; |
2375 val t' = mk_map PredicateCompFuns.compfuns T HOLogic.termT (HOLogic.term_of_const T) t; |
2364 in (T, Code_ML.eval NONE ("Predicate_Compile.eval_ref", eval_ref) Predicate.map thy t' []) end; |
2376 in (T, Code_ML.eval NONE ("Predicate_Compile_Core.eval_ref", eval_ref) Predicate.map thy t' []) end; |
2365 |
2377 |
2366 fun values ctxt k t_compr = |
2378 fun values ctxt k t_compr = |
2367 let |
2379 let |
2368 val thy = ProofContext.theory_of ctxt; |
2380 val thy = ProofContext.theory_of ctxt; |
2369 val (T, t) = eval thy t_compr; |
2381 val (T, t) = eval thy t_compr; |