src/Pure/Tools/codegen_data.ML
changeset 22050 859e5784c58c
parent 22033 8e19bad4125f
child 22184 a125f38a559a
equal deleted inserted replaced
22049:a995f9a8f669 22050:859e5784c58c
    18   val add_datatype: string * (((string * sort) list * (string * typ list) list) * thm list Susp.T)
    18   val add_datatype: string * (((string * sort) list * (string * typ list) list) * thm list Susp.T)
    19     -> theory -> theory
    19     -> theory -> theory
    20   val del_datatype: string -> theory -> theory
    20   val del_datatype: string -> theory -> theory
    21   val add_inline: thm -> theory -> theory
    21   val add_inline: thm -> theory -> theory
    22   val del_inline: thm -> theory -> theory
    22   val del_inline: thm -> theory -> theory
    23   val add_inline_proc: (theory -> cterm list -> thm list) -> theory -> theory
    23   val add_inline_proc: string * (theory -> cterm list -> thm list) -> theory -> theory
    24   val add_preproc: (theory -> thm list -> thm list) -> theory -> theory
    24   val del_inline_proc: string -> theory -> theory
       
    25   val add_preproc: string * (theory -> thm list -> thm list) -> theory -> theory
       
    26   val del_preproc: string -> theory -> theory
       
    27   val class_arity: theory -> class -> string -> sort list
    25   val these_funcs: theory -> CodegenConsts.const -> thm list
    28   val these_funcs: theory -> CodegenConsts.const -> thm list
    26   val get_datatype: theory -> string
    29   val get_datatype: theory -> string
    27     -> ((string * sort) list * (string * typ list) list) option
    30     -> ((string * sort) list * (string * typ list) list) option
    28   val get_datatype_of_constr: theory -> CodegenConsts.const -> string option
    31   val get_datatype_of_constr: theory -> CodegenConsts.const -> string option
    29 
    32 
   156 
   159 
   157 structure Consttab = CodegenConsts.Consttab;
   160 structure Consttab = CodegenConsts.Consttab;
   158 
   161 
   159 datatype preproc = Preproc of {
   162 datatype preproc = Preproc of {
   160   inlines: thm list,
   163   inlines: thm list,
   161   inline_procs: (serial * (theory -> cterm list -> thm list)) list,
   164   inline_procs: (string * (serial * (theory -> cterm list -> thm list))) list,
   162   preprocs: (serial * (theory -> thm list -> thm list)) list
   165   preprocs: (string * (serial * (theory -> thm list -> thm list))) list
   163 };
   166 };
   164 
   167 
   165 fun mk_preproc ((inlines, inline_procs), preprocs) =
   168 fun mk_preproc ((inlines, inline_procs), preprocs) =
   166   Preproc { inlines = inlines, inline_procs = inline_procs, preprocs = preprocs };
   169   Preproc { inlines = inlines, inline_procs = inline_procs, preprocs = preprocs };
   167 fun map_preproc f (Preproc { inlines, inline_procs, preprocs }) =
   170 fun map_preproc f (Preproc { inlines, inline_procs, preprocs }) =
   168   mk_preproc (f ((inlines, inline_procs), preprocs));
   171   mk_preproc (f ((inlines, inline_procs), preprocs));
   169 fun merge_preproc (Preproc { inlines = inlines1, inline_procs = inline_procs1, preprocs = preprocs1 },
   172 fun merge_preproc (Preproc { inlines = inlines1, inline_procs = inline_procs1, preprocs = preprocs1 },
   170   Preproc { inlines = inlines2, inline_procs = inline_procs2, preprocs = preprocs2 }) =
   173   Preproc { inlines = inlines2, inline_procs = inline_procs2, preprocs = preprocs2 }) =
   171     let
   174     let
   172       val (touched1, inlines) = merge_thms (inlines1, inlines2);
   175       val (touched1, inlines) = merge_thms (inlines1, inlines2);
   173       val (touched2, inline_procs) = merge_alist (op =) (K true) (inline_procs1, inline_procs2);
   176       val (touched2, inline_procs) = merge_alist (op =) (eq_fst (op =)) (inline_procs1, inline_procs2);
   174       val (touched3, preprocs) = merge_alist (op =) (K true) (preprocs1, preprocs2);
   177       val (touched3, preprocs) = merge_alist (op =) (eq_fst (op =)) (preprocs1, preprocs2);
   175     in (touched1 orelse touched2 orelse touched3,
   178     in (touched1 orelse touched2 orelse touched3,
   176       mk_preproc ((inlines, inline_procs), preprocs)) end;
   179       mk_preproc ((inlines, inline_procs), preprocs)) end;
   177 
   180 
   178 fun join_func_thms (tabs as (tab1, tab2)) =
   181 fun join_func_thms (tabs as (tab1, tab2)) =
   179   let
   182   let
   335                    Pretty.block
   338                    Pretty.block
   336                       (Pretty.str c :: Pretty.brk 1 :: Pretty.str "of" :: Pretty.brk 1
   339                       (Pretty.str c :: Pretty.brk 1 :: Pretty.str "of" :: Pretty.brk 1
   337                       :: Pretty.breaks (map (Pretty.quote o Sign.pretty_typ thy) tys))) cos)
   340                       :: Pretty.breaks (map (Pretty.quote o Sign.pretty_typ thy) tys))) cos)
   338         )
   341         )
   339       val inlines = (#inlines o the_preproc) exec;
   342       val inlines = (#inlines o the_preproc) exec;
       
   343       val inline_procs = (map fst o #inline_procs o the_preproc) exec;
       
   344       val preprocs = (map fst o #preprocs o the_preproc) exec;
   340       val funs = the_funcs exec
   345       val funs = the_funcs exec
   341         |> Consttab.dest
   346         |> Consttab.dest
   342         |> (map o apfst) (CodegenConsts.string_of_const thy)
   347         |> (map o apfst) (CodegenConsts.string_of_const thy)
   343         |> sort (string_ord o pairself fst);
   348         |> sort (string_ord o pairself fst);
   344       val dtyps = the_dtyps exec
   349       val dtyps = the_dtyps exec
   349       (Pretty.writeln o Pretty.block o Pretty.fbreaks) ([
   354       (Pretty.writeln o Pretty.block o Pretty.fbreaks) ([
   350         Pretty.str "code theorems:",
   355         Pretty.str "code theorems:",
   351         Pretty.str "function theorems:" ] @
   356         Pretty.str "function theorems:" ] @
   352           map pretty_func funs @ [
   357           map pretty_func funs @ [
   353         Pretty.block (
   358         Pretty.block (
   354           Pretty.str "inlined theorems:"
   359           Pretty.str "inlining theorems:"
   355           :: Pretty.fbrk
   360           :: Pretty.fbrk
   356           :: (Pretty.fbreaks o map (ProofContext.pretty_thm ctxt)) inlines
   361           :: (Pretty.fbreaks o map (ProofContext.pretty_thm ctxt)) inlines
       
   362         ),
       
   363         Pretty.block (
       
   364           Pretty.str "inlining procedures:"
       
   365           :: Pretty.fbrk
       
   366           :: (Pretty.fbreaks o map Pretty.str) inline_procs
       
   367         ),
       
   368         Pretty.block (
       
   369           Pretty.str "preprocessors:"
       
   370           :: Pretty.fbrk
       
   371           :: (Pretty.fbreaks o map Pretty.str) preprocs
   357         ),
   372         ),
   358         Pretty.block (
   373         Pretty.block (
   359           Pretty.str "datatypes:"
   374           Pretty.str "datatypes:"
   360           :: Pretty.fbrk
   375           :: Pretty.fbrk
   361           :: (Pretty.fbreaks o map pretty_dtyp) dtyps
   376           :: (Pretty.fbreaks o map pretty_dtyp) dtyps
   490 fun certify_datatype thy dtco cs thms =
   505 fun certify_datatype thy dtco cs thms =
   491   (op @) (check_freeness thy cs thms);
   506   (op @) (check_freeness thy cs thms);
   492 
   507 
   493 
   508 
   494 
   509 
       
   510 (** operational sort algebra **)
       
   511 
       
   512 local
       
   513 
       
   514 fun aggr_neutr f y [] = y
       
   515   | aggr_neutr f y (x::xs) = aggr_neutr f (f y x) xs;
       
   516 
       
   517 fun aggregate f [] = NONE
       
   518   | aggregate f (x::xs) = SOME (aggr_neutr f x xs);
       
   519 
       
   520 fun inter_sorts thy =
       
   521   let
       
   522     val algebra = Sign.classes_of thy;
       
   523     val inters = curry (Sorts.inter_sort algebra);
       
   524   in aggregate (map2 inters) end;
       
   525 
       
   526 fun get_raw_funcs thy tyco clsop =
       
   527   let
       
   528     val vs = Name.invents Name.context "" (Sign.arity_number thy tyco);
       
   529     val c = CodegenConsts.norm thy (clsop, [Type (tyco, map (TFree o rpair []) vs)])
       
   530   in
       
   531     Consttab.lookup ((the_funcs o get_exec) thy) c
       
   532     |> Option.map (Susp.force o fst)
       
   533     |> these
       
   534     |> map (Thm.transfer thy)
       
   535   end;
       
   536 
       
   537 fun constraints thy class tyco =
       
   538   let
       
   539     val vs = Name.invents Name.context "" (Sign.arity_number thy tyco);
       
   540     val clsops = (these o Option.map snd o try (AxClass.params_of_class thy)) class;
       
   541     val funcs = maps (get_raw_funcs thy tyco o fst) clsops;
       
   542     val sorts = map (map (snd o dest_TVar) o snd o dest_Type o the_single
       
   543       o Sign.const_typargs thy o fst o CodegenFunc.dest_func) funcs;
       
   544   in inter_sorts thy sorts end;
       
   545 
       
   546 fun weakest_constraints thy class tyco =
       
   547   case constraints thy class tyco
       
   548    of sorts as SOME _ => sorts
       
   549     | NONE => let
       
   550         val sorts = map_filter (fn class => weakest_constraints thy class tyco)
       
   551           (Sign.super_classes thy class);
       
   552       in inter_sorts thy sorts end;
       
   553 
       
   554 in
       
   555 
       
   556 fun class_arity thy class tyco =
       
   557   weakest_constraints thy class tyco
       
   558   |> the_default (Sign.arity_sorts thy tyco [class]);
       
   559 
       
   560 fun upward_compatible_constraints thy sorts class tyco =
       
   561   case constraints thy class tyco
       
   562    of SOME sorts' => forall (Sign.subsort thy) (sorts ~~ sorts')
       
   563     | NONE => forall (fn class => upward_compatible_constraints thy sorts class tyco)
       
   564         (Graph.imm_preds ((#classes o Sorts.rep_algebra o Sign.classes_of) thy) class);
       
   565 
       
   566 end;
       
   567 
       
   568 
       
   569 
   495 (** interfaces **)
   570 (** interfaces **)
   496 
   571 
   497 fun gen_add_func mk_func thm thy =
   572 fun gen_add_func mk_func thm thy =
   498   let
   573   let
   499     val thms = mk_func thm;
   574     val thms = mk_func thm;
   550   (map_exec_purge NONE o map_preproc o apfst o apfst) (fold (insert eq_thm) (CodegenFunc.mk_rew thm)) thy;
   625   (map_exec_purge NONE o map_preproc o apfst o apfst) (fold (insert eq_thm) (CodegenFunc.mk_rew thm)) thy;
   551 
   626 
   552 fun del_inline thm thy =
   627 fun del_inline thm thy =
   553   (map_exec_purge NONE o map_preproc o apfst o apfst) (fold (remove eq_thm) (CodegenFunc.mk_rew thm)) thy ;
   628   (map_exec_purge NONE o map_preproc o apfst o apfst) (fold (remove eq_thm) (CodegenFunc.mk_rew thm)) thy ;
   554 
   629 
   555 fun add_inline_proc f =
   630 fun add_inline_proc (name, f) =
   556   (map_exec_purge NONE o map_preproc o apfst o apsnd) (cons (serial (), f));
   631   (map_exec_purge NONE o map_preproc o apfst o apsnd) (AList.update (op =) (name, (serial (), f)));
   557 
   632 
   558 fun add_preproc f =
   633 fun del_inline_proc name =
   559   (map_exec_purge NONE o map_preproc o apsnd) (cons (serial (), f));
   634   (map_exec_purge NONE o map_preproc o apfst o apsnd) (AList.delete (op =) name);
       
   635 
       
   636 fun add_preproc (name, f) =
       
   637   (map_exec_purge NONE o map_preproc o apsnd) (AList.update (op =) (name, (serial (), f)));
       
   638 
       
   639 fun del_preproc name =
       
   640   (map_exec_purge NONE o map_preproc o apsnd) (AList.delete (op =) name);
   560 
   641 
   561 local
   642 local
   562 
   643 
   563 fun gen_apply_inline_proc prep post thy f x =
   644 fun gen_apply_inline_proc prep post thy f x =
   564   let
   645   let
   589 
   670 
   590 in
   671 in
   591 
   672 
   592 fun preprocess thy thms =
   673 fun preprocess thy thms =
   593   thms
   674   thms
   594   |> fold (fn (_, f) => apply_preproc thy f) ((#preprocs o the_preproc o get_exec) thy)
   675   |> fold (fn (_, (_, f)) => apply_preproc thy f) ((#preprocs o the_preproc o get_exec) thy)
   595   |> map (CodegenFunc.rewrite_func ((#inlines o the_preproc o get_exec) thy))
   676   |> map (CodegenFunc.rewrite_func ((#inlines o the_preproc o get_exec) thy))
   596   |> fold (fn (_, f) => apply_inline_proc thy f) ((#inline_procs o the_preproc o get_exec) thy)
   677   |> fold (fn (_, (_, f)) => apply_inline_proc thy f) ((#inline_procs o the_preproc o get_exec) thy)
   597 (*FIXME - must check: rewrite rule, function equation, proper constant |> map (snd o check_func false thy) *)
   678 (*FIXME - must check: rewrite rule, function equation, proper constant |> map (snd o check_func false thy) *)
   598   |> sort (cmp_thms thy)
   679   |> sort (cmp_thms thy)
   599   |> common_typ_funcs;
   680   |> common_typ_funcs;
   600 
   681 
   601 fun preprocess_cterm ct =
   682 fun preprocess_cterm ct =
   604   in
   685   in
   605     ct
   686     ct
   606     |> Thm.reflexive
   687     |> Thm.reflexive
   607     |> fold (rhs_conv o MetaSimplifier.rewrite false o single)
   688     |> fold (rhs_conv o MetaSimplifier.rewrite false o single)
   608       ((#inlines o the_preproc o get_exec) thy)
   689       ((#inlines o the_preproc o get_exec) thy)
   609     |> fold (fn (_, f) => rhs_conv (apply_inline_proc_cterm thy f))
   690     |> fold (fn (_, (_, f)) => rhs_conv (apply_inline_proc_cterm thy f))
   610       ((#inline_procs o the_preproc o get_exec) thy)
   691       ((#inline_procs o the_preproc o get_exec) thy)
   611   end;
   692   end;
   612 
   693 
   613 end; (*local*)
   694 end; (*local*)
   614 
   695