src/Pure/Isar/code.ML
changeset 28350 715163ec93c0
parent 28143 e5c6c4aac52c
child 28353 40306cc4d16a
equal deleted inserted replaced
28349:46a0dc9b51bb 28350:715163ec93c0
     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 
   799     val pre = (Simplifier.theory_context thy o #pre o the_thmproc o the_exec) thy;
   800     val pre = (Simplifier.theory_context thy o #pre o the_thmproc o the_exec) thy;
   800   in
   801   in
   801     thms
   802     thms
   802     |> apply_functrans thy
   803     |> apply_functrans thy
   803     |> map (Code_Unit.rewrite_func pre)
   804     |> map (Code_Unit.rewrite_func pre)
   804     (*FIXME - must check gere: rewrite rule, defining equation, proper constant *)
   805     (*FIXME - must check here: rewrite rule, defining equation, proper constant *)
   805     |> map (AxClass.unoverload thy)
   806     |> map (AxClass.unoverload thy)
   806     |> common_typ_funcs
   807     |> common_typ_funcs
   807   end;
   808   end;
   808 
   809 
   809 
   810 
   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*)