7 *) |
7 *) |
8 |
8 |
9 signature CODE = |
9 signature CODE = |
10 sig |
10 sig |
11 val add_func: thm -> theory -> theory |
11 val add_func: thm -> theory -> theory |
|
12 val add_nonlinear_func: thm -> theory -> theory |
12 val add_liberal_func: thm -> theory -> theory |
13 val add_liberal_func: thm -> theory -> theory |
13 val add_default_func: thm -> theory -> theory |
14 val add_default_func: thm -> theory -> theory |
14 val add_default_func_attr: Attrib.src |
15 val add_default_func_attr: Attrib.src |
15 val del_func: thm -> theory -> theory |
16 val del_func: thm -> theory -> theory |
16 val del_funcs: string -> theory -> theory |
17 val del_funcs: string -> theory -> theory |
17 val add_funcl: string * thm list Susp.T -> theory -> theory |
18 val add_funcl: string * (thm * bool) list Susp.T -> theory -> theory |
18 val map_pre: (MetaSimplifier.simpset -> MetaSimplifier.simpset) -> theory -> theory |
19 val map_pre: (MetaSimplifier.simpset -> MetaSimplifier.simpset) -> theory -> theory |
19 val map_post: (MetaSimplifier.simpset -> MetaSimplifier.simpset) -> theory -> theory |
20 val map_post: (MetaSimplifier.simpset -> MetaSimplifier.simpset) -> theory -> theory |
20 val add_inline: thm -> theory -> theory |
21 val add_inline: thm -> theory -> theory |
21 val del_inline: thm -> theory -> theory |
22 val del_inline: thm -> theory -> theory |
22 val add_post: thm -> theory -> theory |
23 val add_post: thm -> theory -> theory |
32 val add_undefined: string -> theory -> theory |
33 val add_undefined: string -> theory -> theory |
33 val purge_data: theory -> theory |
34 val purge_data: theory -> theory |
34 |
35 |
35 val coregular_algebra: theory -> Sorts.algebra |
36 val coregular_algebra: theory -> Sorts.algebra |
36 val operational_algebra: theory -> (sort -> sort) * Sorts.algebra |
37 val operational_algebra: theory -> (sort -> sort) * Sorts.algebra |
37 val these_funcs: theory -> string -> thm list |
38 val these_funcs: theory -> string -> (thm * bool) list |
38 val get_datatype: theory -> string -> ((string * sort) list * (string * typ list) list) |
39 val get_datatype: theory -> string -> ((string * sort) list * (string * typ list) list) |
39 val get_datatype_of_constr: theory -> string -> string option |
40 val get_datatype_of_constr: theory -> string -> string option |
40 val get_case_data: theory -> string -> (int * string list) option |
41 val get_case_data: theory -> string -> (int * string list) option |
41 val is_undefined: theory -> string -> bool |
42 val is_undefined: theory -> string -> bool |
42 val default_typ: theory -> string -> (string * sort) list * typ |
43 val default_typ: theory -> string -> (string * sort) list * typ |
113 end; |
114 end; |
114 |
115 |
115 |
116 |
116 (** logical and syntactical specification of executable code **) |
117 (** logical and syntactical specification of executable code **) |
117 |
118 |
118 (* defining equations with default flag and lazy theorems *) |
119 (* defining equations with linear flag, default flag and lazy theorems *) |
119 |
120 |
120 fun pretty_lthms ctxt r = case Susp.peek r |
121 fun pretty_lthms ctxt r = case Susp.peek r |
121 of SOME thms => map (ProofContext.pretty_thm ctxt) thms |
122 of SOME thms => map (ProofContext.pretty_thm ctxt o fst) thms |
122 | NONE => [Pretty.str "[...]"]; |
123 | NONE => [Pretty.str "[...]"]; |
123 |
124 |
124 fun certificate thy f r = |
125 fun certificate thy f r = |
125 case Susp.peek r |
126 case Susp.peek r |
126 of SOME thms => (Susp.value o f thy) thms |
127 of SOME thms => (Susp.value o burrow_fst (f thy)) thms |
127 | NONE => let |
128 | NONE => let |
128 val thy_ref = Theory.check_thy thy; |
129 val thy_ref = Theory.check_thy thy; |
129 in Susp.delay (fn () => (f (Theory.deref thy_ref) o Susp.force) r) end; |
130 in Susp.delay (fn () => (burrow_fst (f (Theory.deref thy_ref)) o Susp.force) r) end; |
130 |
131 |
131 fun add_drop_redundant verbose thm thms = |
132 fun add_drop_redundant (thm, linear) thms = |
132 let |
133 let |
133 fun warn thm' = (if verbose |
|
134 then warning ("Code generator: dropping redundant defining equation\n" ^ Display.string_of_thm thm') |
|
135 else (); true); |
|
136 val thy = Thm.theory_of_thm thm; |
134 val thy = Thm.theory_of_thm thm; |
137 val args_of = snd o strip_comb o fst o Logic.dest_equals o Thm.plain_prop_of; |
135 val args_of = snd o strip_comb o fst o Logic.dest_equals o Thm.plain_prop_of; |
138 val args = args_of thm; |
136 val args = args_of thm; |
139 fun matches [] _ = true |
137 fun matches_args args' = length args <= length args' andalso |
140 | matches (Var _ :: xs) [] = matches xs [] |
138 Pattern.matchess thy (args, curry Library.take (length args) args'); |
141 | matches (_ :: _) [] = false |
139 fun drop (thm', _) = if matches_args (args_of thm') then |
142 | matches (x :: xs) (y :: ys) = Pattern.matches thy (x, y) andalso matches xs ys; |
140 (warning ("Code generator: dropping redundant defining equation\n" ^ Display.string_of_thm thm'); true) |
143 fun drop thm' = matches args (args_of thm') andalso warn thm'; |
141 else false; |
144 in thm :: filter_out drop thms end; |
142 in (thm, linear) :: filter_out drop thms end; |
145 |
143 |
146 fun add_thm _ thm (false, thms) = (false, Susp.value (add_drop_redundant true thm (Susp.force thms))) |
144 fun add_thm _ thm (false, thms) = (false, Susp.map_force (add_drop_redundant thm) thms) |
147 | add_thm true thm (true, thms) = (true, Susp.value (Susp.force thms @ [thm])) |
145 | add_thm true thm (true, thms) = (true, Susp.map_force (fn thms => thms @ [thm]) thms) |
148 | add_thm false thm (true, thms) = (false, Susp.value [thm]); |
146 | add_thm false thm (true, thms) = (false, Susp.value [thm]); |
149 |
147 |
150 fun add_lthms lthms _ = (false, lthms); |
148 fun add_lthms lthms _ = (false, lthms); |
151 |
149 |
152 fun del_thm thm = apsnd (Susp.value o remove Thm.eq_thm_prop thm o Susp.force); |
150 fun del_thm thm = (apsnd o Susp.map_force) (remove (eq_fst Thm.eq_thm_prop) (thm, true)); |
153 |
151 |
154 fun merge_defthms ((true, _), defthms2) = defthms2 |
152 fun merge_defthms ((true, _), defthms2) = defthms2 |
155 | merge_defthms (defthms1 as (false, _), (true, _)) = defthms1 |
153 | merge_defthms (defthms1 as (false, _), (true, _)) = defthms1 |
156 | merge_defthms ((false, _), defthms2 as (false, _)) = defthms2; |
154 | merge_defthms ((false, _), defthms2 as (false, _)) = defthms2; |
157 |
155 |
171 |
169 |
172 |
170 |
173 (* specification data *) |
171 (* specification data *) |
174 |
172 |
175 datatype spec = Spec of { |
173 datatype spec = Spec of { |
176 funcs: (bool * thm list Susp.T) Symtab.table, |
174 funcs: (bool * (thm * bool) list Susp.T) Symtab.table, |
177 dtyps: ((string * sort) list * (string * typ list) list) Symtab.table, |
175 dtyps: ((string * sort) list * (string * typ list) list) Symtab.table, |
178 cases: (int * string list) Symtab.table * unit Symtab.table |
176 cases: (int * string list) Symtab.table * unit Symtab.table |
179 }; |
177 }; |
180 |
178 |
181 fun mk_spec (funcs, (dtyps, cases)) = |
179 fun mk_spec (funcs, (dtyps, cases)) = |
477 val vs = Name.invents Name.context "" (Sign.arity_number thy tyco); |
475 val vs = Name.invents Name.context "" (Sign.arity_number thy tyco); |
478 val classparams = (map fst o these o try (#params o AxClass.get_info thy)) class; |
476 val classparams = (map fst o these o try (#params o AxClass.get_info thy)) class; |
479 val funcs = classparams |
477 val funcs = classparams |
480 |> map_filter (fn c => try (AxClass.param_of_inst thy) (c, tyco)) |
478 |> map_filter (fn c => try (AxClass.param_of_inst thy) (c, tyco)) |
481 |> map (Symtab.lookup ((the_funcs o the_exec) thy)) |
479 |> map (Symtab.lookup ((the_funcs o the_exec) thy)) |
482 |> (map o Option.map) (Susp.force o snd) |
480 |> (map o Option.map) (map fst o Susp.force o snd) |
483 |> maps these |
481 |> maps these |
484 |> map (Thm.transfer thy); |
482 |> map (Thm.transfer thy); |
485 fun sorts_of [Type (_, tys)] = map (snd o dest_TVar) tys |
483 fun sorts_of [Type (_, tys)] = map (snd o dest_TVar) tys |
486 | sorts_of tys = map (snd o dest_TVar) tys; |
484 | sorts_of tys = map (snd o dest_TVar) tys; |
487 val sorts = map (sorts_of o Sign.const_typargs thy o const_of thy) funcs; |
485 val sorts = map (sorts_of o Sign.const_typargs thy o const_of thy) funcs; |
598 case AxClass.inst_of_param thy c |
596 case AxClass.inst_of_param thy c |
599 of SOME (c, tyco) => check_typ_classparam tyco (c, thm) |
597 of SOME (c, tyco) => check_typ_classparam tyco (c, thm) |
600 | NONE => check_typ_fun (c, thm); |
598 | NONE => check_typ_fun (c, thm); |
601 in check_typ (const_of_func thy thm, thm) end; |
599 in check_typ (const_of_func thy thm, thm) end; |
602 |
600 |
603 val mk_func = Code_Unit.error_thm (assert_func_typ o Code_Unit.mk_func); |
601 fun mk_func linear = Code_Unit.error_thm (assert_func_typ o Code_Unit.mk_func linear); |
604 val mk_liberal_func = Code_Unit.warning_thm (assert_func_typ o Code_Unit.mk_func); |
602 val mk_liberal_func = Code_Unit.warning_thm (assert_func_typ o Code_Unit.mk_func true); |
605 val mk_default_func = Code_Unit.try_thm (assert_func_typ o Code_Unit.mk_func); |
603 val mk_syntactic_func = Code_Unit.warning_thm (assert_func_typ o Code_Unit.mk_func false); |
|
604 val mk_default_func = Code_Unit.try_thm (assert_func_typ o Code_Unit.mk_func true); |
606 |
605 |
607 end; (*local*) |
606 end; (*local*) |
608 |
607 |
609 |
608 |
610 (** interfaces and attributes **) |
609 (** interfaces and attributes **) |
639 |
638 |
640 val get_case_data = Symtab.lookup o fst o the_cases o the_exec; |
639 val get_case_data = Symtab.lookup o fst o the_cases o the_exec; |
641 |
640 |
642 val is_undefined = Symtab.defined o snd o the_cases o the_exec; |
641 val is_undefined = Symtab.defined o snd o the_cases o the_exec; |
643 |
642 |
644 fun gen_add_func strict default thm thy = |
643 fun gen_add_func linear strict default thm thy = |
645 case (if strict then SOME o mk_func else mk_liberal_func) thm |
644 case (if strict then SOME o mk_func linear else mk_liberal_func) thm |
646 of SOME func => |
645 of SOME func => |
647 let |
646 let |
648 val c = const_of_func thy func; |
647 val c = const_of_func thy func; |
649 val _ = if strict andalso (is_some o AxClass.class_of_param thy) c |
648 val _ = if strict andalso (is_some o AxClass.class_of_param thy) c |
650 then error ("Rejected polymorphic equation for overloaded constant:\n" |
649 then error ("Rejected polymorphic equation for overloaded constant:\n" |
654 then error ("Rejected equation for datatype constructor:\n" |
653 then error ("Rejected equation for datatype constructor:\n" |
655 ^ Display.string_of_thm func) |
654 ^ Display.string_of_thm func) |
656 else (); |
655 else (); |
657 in |
656 in |
658 (map_exec_purge (SOME [c]) o map_funcs) (Symtab.map_default |
657 (map_exec_purge (SOME [c]) o map_funcs) (Symtab.map_default |
659 (c, (true, Susp.value [])) (add_thm default func)) thy |
658 (c, (true, Susp.value [])) (add_thm default (func, linear))) thy |
660 end |
659 end |
661 | NONE => thy; |
660 | NONE => thy; |
662 |
661 |
663 val add_func = gen_add_func true false; |
662 val add_func = gen_add_func true true false; |
664 val add_liberal_func = gen_add_func false false; |
663 val add_liberal_func = gen_add_func true false false; |
665 val add_default_func = gen_add_func false true; |
664 val add_default_func = gen_add_func true false true; |
666 |
665 val add_nonlinear_func = gen_add_func false true false; |
667 fun del_func thm thy = case mk_liberal_func thm |
666 |
|
667 fun del_func thm thy = case mk_syntactic_func thm |
668 of SOME func => let |
668 of SOME func => let |
669 val c = const_of_func thy func; |
669 val c = const_of_func thy func; |
670 in map_exec_purge (SOME [c]) (map_funcs |
670 in map_exec_purge (SOME [c]) (map_funcs |
671 (Symtab.map_entry c (del_thm func))) thy |
671 (Symtab.map_entry c (del_thm func))) thy |
672 end |
672 end |
760 add_attribute (name, Args.del |-- Scan.succeed (mk_attribute del) |
760 add_attribute (name, Args.del |-- Scan.succeed (mk_attribute del) |
761 || Scan.succeed (mk_attribute add)) |
761 || Scan.succeed (mk_attribute add)) |
762 in |
762 in |
763 TypeInterpretation.init |
763 TypeInterpretation.init |
764 #> add_del_attribute ("func", (add_func, del_func)) |
764 #> add_del_attribute ("func", (add_func, del_func)) |
|
765 #> add_simple_attribute ("nbe", add_nonlinear_func) |
765 #> add_del_attribute ("inline", (add_inline, del_inline)) |
766 #> add_del_attribute ("inline", (add_inline, del_inline)) |
766 #> add_del_attribute ("post", (add_post, del_post)) |
767 #> add_del_attribute ("post", (add_post, del_post)) |
767 end)); |
768 end)); |
768 |
769 |
769 |
770 |
845 |
846 |
846 fun get_funcs thy const = |
847 fun get_funcs thy const = |
847 Symtab.lookup ((the_funcs o the_exec) thy) const |
848 Symtab.lookup ((the_funcs o the_exec) thy) const |
848 |> Option.map (Susp.force o snd) |
849 |> Option.map (Susp.force o snd) |
849 |> these |
850 |> these |
850 |> map (Thm.transfer thy); |
851 |> (map o apfst) (Thm.transfer thy); |
851 |
852 |
852 in |
853 in |
853 |
854 |
854 fun these_funcs thy const = |
855 fun these_funcs thy const = |
855 let |
856 let |
856 fun drop_refl thy = filter_out (is_equal o Term.fast_term_ord o Logic.dest_equals |
857 fun drop_refl thy = filter_out (is_equal o Term.fast_term_ord o Logic.dest_equals |
857 o ObjectLogic.drop_judgment thy o Thm.plain_prop_of); |
858 o ObjectLogic.drop_judgment thy o Thm.plain_prop_of o fst); |
858 in |
859 in |
859 get_funcs thy const |
860 get_funcs thy const |
860 |> preprocess thy |
861 |> burrow_fst (preprocess thy) |
861 |> drop_refl thy |
862 |> drop_refl thy |
862 end; |
863 end; |
863 |
864 |
864 fun default_typ thy c = case default_typ_proto thy c |
865 fun default_typ thy c = case default_typ_proto thy c |
865 of SOME ty => Code_Unit.typscheme thy (c, ty) |
866 of SOME ty => Code_Unit.typscheme thy (c, ty) |
866 | NONE => (case get_funcs thy c |
867 | NONE => (case get_funcs thy c |
867 of thm :: _ => snd (Code_Unit.head_func (AxClass.unoverload thy thm)) |
868 of (thm, _) :: _ => snd (Code_Unit.head_func (AxClass.unoverload thy thm)) |
868 | [] => Code_Unit.typscheme thy (c, Sign.the_const_type thy c)); |
869 | [] => Code_Unit.typscheme thy (c, Sign.the_const_type thy c)); |
869 |
870 |
870 end; (*local*) |
871 end; (*local*) |
871 |
872 |
872 end; (*struct*) |
873 end; (*struct*) |