src/Pure/Isar/code_unit.ML
changeset 24423 ae9cd0e92423
parent 24219 e558fe311376
child 24624 b8383b1bbae3
equal deleted inserted replaced
24422:c0b5ff9e9e4d 24423:ae9cd0e92423
     1 (*  Title:      Pure/Isar/code_unit.ML
     1 (*  Title:      Pure/Isar/code_unit.ML
     2     ID:         $Id$
     2     ID:         $Id$
     3     Author:     Florian Haftmann, TU Muenchen
     3     Author:     Florian Haftmann, TU Muenchen
     4 
     4 
     5 Basic units of code generation:  Identifying (possibly overloaded) constants
     5 Basic units of code generation.  Auxiliary.
     6 by name plus optional type constructor.  Convenient data structures for constants.
       
     7 Defining equations ("func"s).  Auxiliary.
       
     8 *)
     6 *)
     9 
     7 
    10 signature CODE_UNIT =
     8 signature CODE_UNIT =
    11 sig
     9 sig
    12   type const = string * string option (*constant name, possibly instance*)
       
    13   val const_ord: const * const -> order
       
    14   val eq_const: const * const -> bool
       
    15   structure Consttab: TABLE
       
    16   val const_of_cexpr: theory -> string * typ -> const
       
    17   val string_of_typ: theory -> typ -> string
    10   val string_of_typ: theory -> typ -> string
    18   val string_of_const: theory -> const -> string
    11   val string_of_const: theory -> string -> string
       
    12   val no_args: theory -> string -> int
    19   val read_bare_const: theory -> string -> string * typ
    13   val read_bare_const: theory -> string -> string * typ
    20   val read_const: theory -> string -> const
    14   val read_const: theory -> string -> string
    21   val read_const_exprs: theory -> (const list -> const list)
    15   val read_const_exprs: theory -> (string list -> string list)
    22     -> string list -> bool * const list
    16     -> string list -> bool * string list
    23 
    17 
    24   val co_of_const: theory -> const
    18   val constrset_of_consts: theory -> (string * typ) list
    25     -> string * ((string * sort) list * (string * typ list))
       
    26   val co_of_const': theory -> const
       
    27     -> (string * ((string * sort) list * (string * typ list))) option
       
    28   val cos_of_consts: theory -> const list
       
    29     -> string * ((string * sort) list * (string * typ list) list)
    19     -> string * ((string * sort) list * (string * typ list) list)
    30   val const_of_co: theory -> string -> (string * sort) list
       
    31     -> string * typ list -> const
       
    32   val consts_of_cos: theory -> string -> (string * sort) list
       
    33     -> (string * typ list) list -> const list
       
    34   val no_args: theory -> const -> int
       
    35 
       
    36   val typargs: theory -> string * typ -> typ list
       
    37   val typ_sort_inst: Sorts.algebra -> typ * sort
    20   val typ_sort_inst: Sorts.algebra -> typ * sort
    38     -> sort Vartab.table -> sort Vartab.table
    21     -> sort Vartab.table -> sort Vartab.table
    39 
    22 
    40   val assert_rew: thm -> thm
    23   val assert_rew: thm -> thm
    41   val mk_rew: thm -> thm
    24   val mk_rew: thm -> thm
    42   val mk_func: thm -> thm
    25   val mk_func: thm -> thm
    43   val head_func: thm -> const * typ
    26   val head_func: thm -> string * typ
    44   val bad_thm: string -> 'a
    27   val bad_thm: string -> 'a
    45   val error_thm: (thm -> thm) -> thm -> thm
    28   val error_thm: (thm -> thm) -> thm -> thm
    46   val warning_thm: (thm -> thm) -> thm -> thm option
    29   val warning_thm: (thm -> thm) -> thm -> thm option
    47 
    30 
    48   val inst_thm: sort Vartab.table -> thm -> thm
    31   val inst_thm: sort Vartab.table -> thm -> thm
    62 fun bad_thm msg = raise BAD_THM msg;
    45 fun bad_thm msg = raise BAD_THM msg;
    63 fun error_thm f thm = f thm handle BAD_THM msg => error msg;
    46 fun error_thm f thm = f thm handle BAD_THM msg => error msg;
    64 fun warning_thm f thm = SOME (f thm) handle BAD_THM msg
    47 fun warning_thm f thm = SOME (f thm) handle BAD_THM msg
    65   => (warning ("code generator: " ^ msg); NONE);
    48   => (warning ("code generator: " ^ msg); NONE);
    66 
    49 
    67 
       
    68 (* basic data structures *)
       
    69 
       
    70 type const = string * string option;
       
    71 val const_ord = prod_ord fast_string_ord (option_ord string_ord);
       
    72 val eq_const = is_equal o const_ord;
       
    73 
       
    74 structure Consttab =
       
    75   TableFun(
       
    76     type key = const;
       
    77     val ord = const_ord;
       
    78   );
       
    79 
       
    80 fun string_of_typ thy = setmp show_sorts true (Sign.string_of_typ thy);
    50 fun string_of_typ thy = setmp show_sorts true (Sign.string_of_typ thy);
    81 
    51 fun string_of_const thy c = case Class.param_const thy c
    82 
    52  of SOME (c, tyco) => Sign.extern_const thy c ^ " " ^ enclose "[" "]" (Sign.extern_type thy tyco)
    83 (* conversion between constant expressions and constants *)
    53   | NONE => Sign.extern_const thy c;
    84 
    54 
    85 fun const_of_cexpr thy (c_ty as (c, _)) =
    55 fun no_args thy = length o fst o strip_type o Sign.the_const_type thy;
    86   case AxClass.class_of_param thy c
       
    87    of SOME class => (case Sign.const_typargs thy c_ty
       
    88        of [Type (tyco, _)] => if can (Sorts.mg_domain (Sign.classes_of thy) tyco) [class]
       
    89               then (c, SOME tyco)
       
    90               else (c, NONE)
       
    91         | [_] => (c, NONE))
       
    92     | NONE => (c, NONE);
       
    93 
       
    94 fun string_of_const thy (c, NONE) = Sign.extern_const thy c
       
    95   | string_of_const thy (c, SOME tyco) = Sign.extern_const thy c
       
    96       ^ " " ^ enclose "[" "]" (Sign.extern_type thy tyco);
       
    97 
       
    98 
    56 
    99 (* reading constants as terms and wildcards pattern *)
    57 (* reading constants as terms and wildcards pattern *)
   100 
    58 
   101 fun read_bare_const thy raw_t =
    59 fun read_bare_const thy raw_t =
   102   let
    60   let
   104   in case try dest_Const t
    62   in case try dest_Const t
   105    of SOME c_ty => c_ty
    63    of SOME c_ty => c_ty
   106     | NONE => error ("Not a constant: " ^ Sign.string_of_term thy t)
    64     | NONE => error ("Not a constant: " ^ Sign.string_of_term thy t)
   107   end;
    65   end;
   108 
    66 
   109 fun read_const thy = const_of_cexpr thy o read_bare_const thy;
    67 fun read_const thy = Class.unoverload_const thy o read_bare_const thy;
   110 
    68 
   111 local
    69 local
   112 
    70 
   113 fun consts_of thy some_thyname =
    71 fun consts_of thy some_thyname =
   114   let
    72   let
   115     val this_thy = Option.map theory some_thyname |> the_default thy;
    73     val this_thy = Option.map theory some_thyname |> the_default thy;
   116     val cs = Symtab.fold (fn (c, (_, NONE)) => cons c | _ => I)
    74     val cs = Symtab.fold (fn (c, (_, NONE)) => cons c | _ => I)
   117       ((snd o #constants o Consts.dest o #consts o Sign.rep_sg) this_thy) [];
    75       ((snd o #constants o Consts.dest o #consts o Sign.rep_sg) this_thy) [];
   118     fun classop c = case AxClass.class_of_param thy c
    76     fun belongs_here thyname c =
   119      of NONE => [(c, NONE)]
       
   120       | SOME class => Symtab.fold
       
   121           (fn (tyco, classes) => if AList.defined (op =) classes class
       
   122             then cons (c, SOME tyco) else I)
       
   123           ((#arities o Sorts.rep_algebra o Sign.classes_of) this_thy)
       
   124           [(c, NONE)];
       
   125     val consts = maps classop cs;
       
   126     fun test_instance thy (class, tyco) =
       
   127       can (Sorts.mg_domain (Sign.classes_of thy) tyco) [class]
       
   128     fun belongs_here thyname (c, NONE) =
       
   129           not (exists (fn thy' => Sign.declared_const thy' c) (Theory.parents_of this_thy))
    77           not (exists (fn thy' => Sign.declared_const thy' c) (Theory.parents_of this_thy))
   130       | belongs_here thyname (c, SOME tyco) =
       
   131           let
       
   132             val SOME class = AxClass.class_of_param thy c
       
   133           in not (exists (fn thy' => test_instance thy' (class, tyco))
       
   134             (Theory.parents_of this_thy))
       
   135           end;
       
   136   in case some_thyname
    78   in case some_thyname
   137    of NONE => consts
    79    of NONE => cs
   138     | SOME thyname => filter (belongs_here thyname) consts
    80     | SOME thyname => filter (belongs_here thyname) cs
   139   end;
    81   end;
   140 
    82 
   141 fun read_const_expr thy "*" = ([], consts_of thy NONE)
    83 fun read_const_expr thy "*" = ([], consts_of thy NONE)
   142   | read_const_expr thy s = if String.isSuffix ".*" s
    84   | read_const_expr thy s = if String.isSuffix ".*" s
   143       then ([], consts_of thy (SOME (unsuffix ".*" s)))
    85       then ([], consts_of thy (SOME (unsuffix ".*" s)))
   150    of (consts, []) => (false, consts)
    92    of (consts, []) => (false, consts)
   151     | (consts, consts') => (true, consts @ select consts');
    93     | (consts, consts') => (true, consts @ select consts');
   152 
    94 
   153 end; (*local*)
    95 end; (*local*)
   154 
    96 
   155 (* conversion between constants, constant expressions and datatype constructors *)
    97 
   156 
    98 (* constructor sets *)
   157 fun const_of_co thy tyco vs (co, tys) =
    99 
   158   const_of_cexpr thy (co, tys ---> Type (tyco, map TFree vs));
   100 fun constrset_of_consts thy cs =
   159 
   101   let
   160 fun consts_of_cos thy tyco vs cos =
   102     fun no_constr (c, ty) = error ("Not a datatype constructor: " ^ string_of_const thy c
   161   let
   103       ^ " :: " ^ string_of_typ thy ty);
   162     val dty = Type (tyco, map TFree vs);
   104     fun last_typ c_ty ty =
   163     fun mk_co (co, tys) = const_of_cexpr thy (co, tys ---> dty);
   105       let
   164   in map mk_co cos end;
   106         val frees = typ_tfrees ty;
   165 
   107         val (tyco, vs) = ((apsnd o map) (dest_TFree) o dest_Type o snd o strip_type) ty
   166 local
   108           handle TYPE _ => no_constr c_ty
   167 
   109         val _ = if has_duplicates (eq_fst (op =)) vs then no_constr c_ty else ();
   168 exception BAD of string;
   110         val _ = if length frees <> length vs then no_constr c_ty else ();
   169 
   111       in (tyco, vs) end;
   170 fun mg_typ_of_const thy (c, NONE) = Sign.the_const_type thy c
   112     fun ty_sorts (c, ty) =
   171   | mg_typ_of_const thy (c, SOME tyco) =
   113       let
   172       let
   114         val ty_decl = (Logic.unvarifyT o Sign.the_const_type thy) c;
   173         val SOME class = AxClass.class_of_param thy c;
   115         val (tyco, vs_decl) = last_typ (c, ty) ty_decl;
   174         val ty = Sign.the_const_type thy c;
   116         val (_, vs) = last_typ (c, ty) ty;
   175           (*an approximation*)
   117       in ((tyco, map snd vs), (c, (map fst vs, ty_decl))) end;
   176         val sorts = Sorts.mg_domain (Sign.classes_of thy) tyco [class]
   118     fun add ((tyco', sorts'), c) ((tyco, sorts), cs) =
   177           handle CLASS_ERROR => raise BAD ("No such instance: " ^ tyco ^ " :: " ^ class
   119       let
   178             ^ ",\nrequired for overloaded constant " ^ c);
   120         val _ = if tyco' <> tyco
   179         val vs = Name.invents Name.context "'a" (length sorts);
   121           then error "Different type constructors in constructor set"
   180       in map_atyps (K (Type (tyco, map (fn v => TVar ((v, 0), [])) vs))) ty end;
   122           else ();
   181 
   123         val sorts'' = map2 (curry (Sorts.inter_sort (Sign.classes_of thy))) sorts' sorts
   182 fun gen_co_of_const thy const =
   124       in ((tyco, sorts), c :: cs) end;
   183   let
   125     fun inst vs' (c, (vs, ty)) =
   184     val (c, _) = const;
   126       let
   185     val ty = (Logic.unvarifyT o mg_typ_of_const thy) const;
   127         val the_v = the o AList.lookup (op =) (vs ~~ vs');
   186     fun err () = raise BAD
   128         val ty' = map_atyps (fn TFree (v, _) => TFree (the_v v)) ty;
   187       ("Illegal type for datatype constructor: " ^ string_of_typ thy ty);
   129       in (c, (fst o strip_type) ty') end;
   188     val (tys, ty') = strip_type ty;
   130     val c' :: cs' = map ty_sorts cs;
   189     val (tyco, vs) = ((apsnd o map) dest_TFree o dest_Type) ty'
   131     val ((tyco, sorts), cs'') = fold add cs' (apsnd single c');
   190       handle TYPE _ => err ();
   132     val vs = Name.names Name.context "'a" sorts;
   191     val sorts = if has_duplicates (eq_fst op =) vs then err ()
   133     val cs''' = map (inst vs) cs'';
   192       else map snd vs;
   134   in (tyco, (vs, cs''')) end;
   193     val vs_names = Name.invent_list [] "'a" (length vs);
       
   194     val vs_map = map fst vs ~~ vs_names;
       
   195     val vs' = vs_names ~~ sorts;
       
   196     val tys' = (map o map_type_tfree) (fn (v, sort) =>
       
   197       (TFree ((the o AList.lookup (op =) vs_map) v, sort))) tys
       
   198       handle Option => err ();
       
   199   in (tyco, (vs', (c, tys'))) end;
       
   200 
       
   201 in
       
   202 
       
   203 fun co_of_const thy const = gen_co_of_const thy const handle BAD msg => error msg;
       
   204 fun co_of_const' thy const = SOME (gen_co_of_const thy const) handle BAD msg => NONE;
       
   205 
       
   206 fun no_args thy = length o fst o strip_type o mg_typ_of_const thy;
       
   207 
       
   208 end;
       
   209 
       
   210 fun cos_of_consts thy consts =
       
   211   let
       
   212     val raw_cos  = map (co_of_const thy) consts;
       
   213     val (tyco, (vs_names, sorts_cos)) = if (length o distinct (eq_fst op =)) raw_cos = 1
       
   214       then ((fst o hd) raw_cos, ((map fst o fst o snd o hd) raw_cos,
       
   215         map ((apfst o map) snd o snd) raw_cos))
       
   216       else error ("Term constructors not referring to the same type: "
       
   217         ^ commas (map (string_of_const thy) consts));
       
   218     val sorts = foldr1 ((uncurry o map2 o curry o Sorts.inter_sort) (Sign.classes_of thy))
       
   219       (map fst sorts_cos);
       
   220     val cos = map snd sorts_cos;
       
   221     val vs = vs_names ~~ sorts;
       
   222   in (tyco, (vs, cos)) end;
       
   223 
   135 
   224 
   136 
   225 (* dictionary values *)
   137 (* dictionary values *)
   226 
       
   227 fun typargs thy (c_ty as (c, ty)) =
       
   228   let
       
   229     val opt_class = AxClass.class_of_param thy c;
       
   230     val tys = Sign.const_typargs thy (c, ty);
       
   231   in case (opt_class, tys)
       
   232    of (SOME class, ty as [Type (tyco, tys')]) =>
       
   233         if can (Sorts.mg_domain (Sign.classes_of thy) tyco) [class]
       
   234         then tys' else ty
       
   235     | _ => tys
       
   236   end;
       
   237 
   138 
   238 fun typ_sort_inst algebra =
   139 fun typ_sort_inst algebra =
   239   let
   140   let
   240     val inters = Sorts.inter_sort algebra;
   141     val inters = Sorts.inter_sort algebra;
   241     fun match _ [] = I
   142     fun match _ [] = I
   322 val mk_func = assert_func o mk_rew;
   223 val mk_func = assert_func o mk_rew;
   323 
   224 
   324 fun head_func thm =
   225 fun head_func thm =
   325   let
   226   let
   326     val thy = Thm.theory_of_thm thm;
   227     val thy = Thm.theory_of_thm thm;
   327     val (Const (c_ty as (_, ty))) = (fst o strip_comb o fst o Logic.dest_equals
   228     val Const (c, ty) = (fst o strip_comb o fst o Logic.dest_equals
   328       o ObjectLogic.drop_judgment thy o Thm.plain_prop_of) thm;
   229       o ObjectLogic.drop_judgment thy o Thm.plain_prop_of) thm;
   329     val const = const_of_cexpr thy c_ty;
   230   in (c, ty) end;
   330   in (const, ty) end;
       
   331 
   231 
   332 
   232 
   333 (* utilities *)
   233 (* utilities *)
   334 
   234 
   335 fun inst_thm tvars' thm =
   235 fun inst_thm tvars' thm =