src/Tools/code/code_funcgr.ML
author wenzelm
Sat, 17 May 2008 13:54:30 +0200
changeset 26928 ca87aff1ad2d
parent 26740 6c8cd101f875
child 26939 1035c89b4c02
permissions -rw-r--r--
structure Display: less pervasive operations;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
     1
(*  Title:      Tools/code/code_funcgr.ML
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
     2
    ID:         $Id$
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
     3
    Author:     Florian Haftmann, TU Muenchen
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
     4
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
     5
Retrieving, normalizing and structuring defining equations in graph
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
     6
with explicit dependencies.
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
     7
*)
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
     8
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
     9
signature CODE_FUNCGR =
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    10
sig
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    11
  type T
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    12
  val timing: bool ref
24423
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
    13
  val funcs: T -> string -> thm list
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
    14
  val typ: T -> string -> typ
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
    15
  val all: T -> string list
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    16
  val pretty: theory -> T -> Pretty.T
24423
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
    17
  val make: theory -> string list -> T
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
    18
  val make_consts: theory -> string list -> string list * T
26740
6c8cd101f875 more general evaluation combinators
haftmann
parents: 26642
diff changeset
    19
  val eval_conv: theory -> (term -> term * (T -> term -> thm)) -> cterm -> thm
6c8cd101f875 more general evaluation combinators
haftmann
parents: 26642
diff changeset
    20
  val eval_term: theory -> (term -> term * (T -> term -> 'a)) -> term -> 'a
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    21
end
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    22
24283
haftmann
parents: 24219
diff changeset
    23
structure CodeFuncgr : CODE_FUNCGR =
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    24
struct
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    25
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    26
(** the graph type **)
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    27
24423
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
    28
type T = (typ * thm list) Graph.T;
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    29
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    30
fun funcs funcgr =
24423
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
    31
  these o Option.map snd o try (Graph.get_node funcgr);
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    32
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    33
fun typ funcgr =
24423
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
    34
  fst o Graph.get_node funcgr;
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    35
24423
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
    36
fun all funcgr = Graph.keys funcgr;
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    37
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    38
fun pretty thy funcgr =
24423
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
    39
  AList.make (snd o Graph.get_node funcgr) (Graph.keys funcgr)
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    40
  |> (map o apfst) (CodeUnit.string_of_const thy)
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    41
  |> sort (string_ord o pairself fst)
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    42
  |> map (fn (s, thms) =>
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    43
       (Pretty.block o Pretty.fbreaks) (
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    44
         Pretty.str s
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    45
         :: map Display.pretty_thm thms
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    46
       ))
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    47
  |> Pretty.chunks;
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    48
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    49
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    50
(** generic combinators **)
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    51
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    52
fun fold_consts f thms =
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    53
  thms
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    54
  |> maps (op :: o swap o apfst (snd o strip_comb) o Logic.dest_equals o Thm.plain_prop_of)
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    55
  |> (fold o fold_aterms) (fn Const c => f c | _ => I);
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    56
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    57
fun consts_of (const, []) = []
24423
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
    58
  | consts_of (const, thms as _ :: _) = 
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    59
      let
24423
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
    60
        fun the_const (c, _) = if c = const then I else insert (op =) c
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    61
      in fold_consts the_const thms [] end;
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    62
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    63
fun insts_of thy algebra c ty_decl ty =
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    64
  let
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    65
    val tys_decl = Sign.const_typargs thy (c, ty_decl);
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    66
    val tys = Sign.const_typargs thy (c, ty);
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    67
    fun class_relation (x, _) _ = x;
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    68
    fun type_constructor tyco xs class =
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    69
      (tyco, class) :: maps (maps fst) xs;
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    70
    fun type_variable (TVar (_, sort)) = map (pair []) sort
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    71
      | type_variable (TFree (_, sort)) = map (pair []) sort;
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    72
    fun mk_inst ty (TVar (_, sort)) = cons (ty, sort)
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    73
      | mk_inst ty (TFree (_, sort)) = cons (ty, sort)
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    74
      | mk_inst (Type (_, tys1)) (Type (_, tys2)) = fold2 mk_inst tys1 tys2;
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    75
    fun of_sort_deriv (ty, sort) =
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    76
      Sorts.of_sort_derivation (Sign.pp thy) algebra
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    77
        { class_relation = class_relation, type_constructor = type_constructor,
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    78
          type_variable = type_variable }
26517
ef036a63f6e9 canonical meet_sort operation
haftmann
parents: 26331
diff changeset
    79
        (ty, sort) handle Sorts.CLASS_ERROR _ => [] (*permissive!*)
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    80
  in
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    81
    flat (maps of_sort_deriv (fold2 mk_inst tys tys_decl []))
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    82
  end;
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    83
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    84
fun drop_classes thy tfrees thm =
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    85
  let
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    86
    val (_, thm') = Thm.varifyT' [] thm;
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    87
    val tvars = Term.add_tvars (Thm.prop_of thm') [];
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    88
    val unconstr = map (Thm.ctyp_of thy o TVar) tvars;
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    89
    val instmap = map2 (fn (v_i, _) => fn (v, sort) => pairself (Thm.ctyp_of thy)
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    90
      (TVar (v_i, []), TFree (v, sort))) tvars tfrees;
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    91
  in
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    92
    thm'
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    93
    |> fold Thm.unconstrainT unconstr
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    94
    |> Thm.instantiate (instmap, [])
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    95
    |> Tactic.rule_by_tactic ((REPEAT o CHANGED o ALLGOALS o Tactic.resolve_tac) (AxClass.class_intros thy))
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    96
  end;
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    97
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    98
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    99
(** graph algorithm **)
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   100
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   101
val timing = ref false;
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   102
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   103
local
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   104
26331
92120667172f error tuning
haftmann
parents: 25597
diff changeset
   105
exception CLASS_ERROR of string list * string;
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   106
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   107
fun resort_thms algebra tap_typ [] = []
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   108
  | resort_thms algebra tap_typ (thms as thm :: _) =
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   109
      let
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   110
        val thy = Thm.theory_of_thm thm;
26331
92120667172f error tuning
haftmann
parents: 25597
diff changeset
   111
        val pp = Sign.pp thy;
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   112
        val cs = fold_consts (insert (op =)) thms [];
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   113
        fun match_const c (ty, ty_decl) =
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   114
          let
24423
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   115
            val tys = Sign.const_typargs thy (c, ty);
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   116
            val sorts = map (snd o dest_TVar) (Sign.const_typargs thy (c, ty_decl));
26517
ef036a63f6e9 canonical meet_sort operation
haftmann
parents: 26331
diff changeset
   117
          in fn tab => fold2 (curry (Sorts.meet_sort algebra)) tys sorts tab
26642
454d11701fa4 Sorts.class_error: produce message only (formerly msg_class_error);
wenzelm
parents: 26517
diff changeset
   118
            handle Sorts.CLASS_ERROR e => raise CLASS_ERROR ([c], Sorts.class_error pp e ^ ",\n"
26331
92120667172f error tuning
haftmann
parents: 25597
diff changeset
   119
              ^ "for constant " ^ CodeUnit.string_of_const thy c
92120667172f error tuning
haftmann
parents: 25597
diff changeset
   120
              ^ "\nin defining equations(s)\n"
26928
ca87aff1ad2d structure Display: less pervasive operations;
wenzelm
parents: 26740
diff changeset
   121
              ^ (cat_lines o map Display.string_of_thm) thms)
26517
ef036a63f6e9 canonical meet_sort operation
haftmann
parents: 26331
diff changeset
   122
            (*handle Sorts.CLASS_ERROR _ => tab (*permissive!*)*)
26331
92120667172f error tuning
haftmann
parents: 25597
diff changeset
   123
          end;
26517
ef036a63f6e9 canonical meet_sort operation
haftmann
parents: 26331
diff changeset
   124
        fun match (c, ty) = case tap_typ c
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   125
           of SOME ty_decl => match_const c (ty, ty_decl)
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   126
            | NONE => I;
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   127
        val tvars = fold match cs Vartab.empty;
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   128
      in map (CodeUnit.inst_thm tvars) thms end;
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   129
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   130
fun resort_funcss thy algebra funcgr =
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   131
  let
24423
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   132
    val typ_funcgr = try (fst o Graph.get_node funcgr);
26331
92120667172f error tuning
haftmann
parents: 25597
diff changeset
   133
    val resort_dep = apsnd (resort_thms algebra typ_funcgr);
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   134
    fun resort_rec tap_typ (const, []) = (true, (const, []))
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   135
      | resort_rec tap_typ (const, thms as thm :: _) =
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   136
          let
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   137
            val (_, ty) = CodeUnit.head_func thm;
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   138
            val thms' as thm' :: _ = resort_thms algebra tap_typ thms
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   139
            val (_, ty') = CodeUnit.head_func thm';
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   140
          in (Sign.typ_equiv thy (ty, ty'), (const, thms')) end;
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   141
    fun resort_recs funcss =
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   142
      let
24423
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   143
        fun tap_typ c =
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   144
          AList.lookup (op =) funcss c
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   145
          |> these
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   146
          |> try hd
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   147
          |> Option.map (snd o CodeUnit.head_func);
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   148
        val (unchangeds, funcss') = split_list (map (resort_rec tap_typ) funcss);
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   149
        val unchanged = fold (fn x => fn y => x andalso y) unchangeds true;
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   150
      in (unchanged, funcss') end;
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   151
    fun resort_rec_until funcss =
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   152
      let
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   153
        val (unchanged, funcss') = resort_recs funcss;
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   154
      in if unchanged then funcss' else resort_rec_until funcss' end;
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   155
  in map resort_dep #> resort_rec_until end;
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   156
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   157
fun instances_of thy algebra insts =
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   158
  let
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   159
    val thy_classes = (#classes o Sorts.rep_algebra o Sign.classes_of) thy;
24835
8c26128f8997 clarified relationship of code generator conversions and evaluations
haftmann
parents: 24713
diff changeset
   160
    fun all_classparams tyco class =
24969
b38527eefb3b removed obsolete AxClass.params_of_class;
wenzelm
parents: 24835
diff changeset
   161
      these (try (#params o AxClass.get_info thy) class)
26517
ef036a63f6e9 canonical meet_sort operation
haftmann
parents: 26331
diff changeset
   162
      |> map_filter (fn (c, _) => try (AxClass.param_of_inst thy) (c, tyco))
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   163
  in
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   164
    Symtab.empty
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   165
    |> fold (fn (tyco, class) =>
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   166
        Symtab.map_default (tyco, []) (insert (op =) class)) insts
24835
8c26128f8997 clarified relationship of code generator conversions and evaluations
haftmann
parents: 24713
diff changeset
   167
    |> (fn tab => Symtab.fold (fn (tyco, classes) => append (maps (all_classparams tyco)
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   168
         (Graph.all_succs thy_classes classes))) tab [])
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   169
  end;
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   170
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   171
fun instances_of_consts thy algebra funcgr consts =
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   172
  let
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   173
    fun inst (cexpr as (c, ty)) = insts_of thy algebra c
26517
ef036a63f6e9 canonical meet_sort operation
haftmann
parents: 26331
diff changeset
   174
      ((fst o Graph.get_node funcgr) c) ty;
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   175
  in
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   176
    []
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   177
    |> fold (fold (insert (op =)) o inst) consts
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   178
    |> instances_of thy algebra
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   179
  end;
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   180
24283
haftmann
parents: 24219
diff changeset
   181
fun ensure_const' thy algebra funcgr const auxgr =
24423
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   182
  if can (Graph.get_node funcgr) const
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   183
    then (NONE, auxgr)
24423
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   184
  else if can (Graph.get_node auxgr) const
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   185
    then (SOME const, auxgr)
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   186
  else if is_some (Code.get_datatype_of_constr thy const) then
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   187
    auxgr
24423
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   188
    |> Graph.new_node (const, [])
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   189
    |> pair (SOME const)
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   190
  else let
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   191
    val thms = Code.these_funcs thy const
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   192
      |> CodeUnit.norm_args
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   193
      |> CodeUnit.norm_varnames CodeName.purify_tvar CodeName.purify_var;
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   194
    val rhs = consts_of (const, thms);
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   195
  in
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   196
    auxgr
24423
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   197
    |> Graph.new_node (const, thms)
24283
haftmann
parents: 24219
diff changeset
   198
    |> fold_map (ensure_const thy algebra funcgr) rhs
24423
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   199
    |-> (fn rhs' => fold (fn SOME const' => Graph.add_edge (const, const')
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   200
                           | NONE => I) rhs')
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   201
    |> pair (SOME const)
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   202
  end
24283
haftmann
parents: 24219
diff changeset
   203
and ensure_const thy algebra funcgr const =
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   204
  let
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   205
    val timeap = if !timing
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   206
      then Output.timeap_msg ("time for " ^ CodeUnit.string_of_const thy const)
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   207
      else I;
24283
haftmann
parents: 24219
diff changeset
   208
  in timeap (ensure_const' thy algebra funcgr const) end;
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   209
24283
haftmann
parents: 24219
diff changeset
   210
fun merge_funcss thy algebra raw_funcss funcgr =
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   211
  let
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   212
    val funcss = raw_funcss
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   213
      |> resort_funcss thy algebra funcgr
24423
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   214
      |> filter_out (can (Graph.get_node funcgr) o fst);
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   215
    fun typ_func c [] = Code.default_typ thy c
25597
34860182b250 moved instance parameter management from class.ML to axclass.ML
haftmann
parents: 25485
diff changeset
   216
      | typ_func c (thms as thm :: _) = case AxClass.inst_of_param thy c
24423
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   217
         of SOME (c', tyco) => 
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   218
              let
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   219
                val (_, ty) = CodeUnit.head_func thm;
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   220
                val SOME class = AxClass.class_of_param thy c';
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   221
                val sorts_decl = Sorts.mg_domain algebra tyco [class];
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   222
                val tys = Sign.const_typargs thy (c, ty);
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   223
                val sorts = map (snd o dest_TVar) tys;
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   224
              in if sorts = sorts_decl then ty
26331
92120667172f error tuning
haftmann
parents: 25597
diff changeset
   225
                else raise CLASS_ERROR ([c], "Illegal instantation for class operation "
24423
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   226
                  ^ CodeUnit.string_of_const thy c
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   227
                  ^ "\nin defining equations\n"
26928
ca87aff1ad2d structure Display: less pervasive operations;
wenzelm
parents: 26740
diff changeset
   228
                  ^ (cat_lines o map (Display.string_of_thm o AxClass.overload thy)) thms)
24423
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   229
              end
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   230
          | NONE => (snd o CodeUnit.head_func) thm;
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   231
    fun add_funcs (const, thms) =
24423
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   232
      Graph.new_node (const, (typ_func const thms, thms));
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   233
    fun add_deps (funcs as (const, thms)) funcgr =
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   234
      let
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   235
        val deps = consts_of funcs;
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   236
        val insts = instances_of_consts thy algebra funcgr
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   237
          (fold_consts (insert (op =)) thms []);
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   238
      in
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   239
        funcgr
24283
haftmann
parents: 24219
diff changeset
   240
        |> ensure_consts' thy algebra insts
24423
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   241
        |> fold (curry Graph.add_edge const) deps
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   242
        |> fold (curry Graph.add_edge const) insts
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   243
       end;
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   244
  in
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   245
    funcgr
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   246
    |> fold add_funcs funcss
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   247
    |> fold add_deps funcss
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   248
  end
24283
haftmann
parents: 24219
diff changeset
   249
and ensure_consts' thy algebra cs funcgr =
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   250
  let
24423
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   251
    val auxgr = Graph.empty
24283
haftmann
parents: 24219
diff changeset
   252
      |> fold (snd oo ensure_const thy algebra funcgr) cs;
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   253
  in
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   254
    funcgr
24283
haftmann
parents: 24219
diff changeset
   255
    |> fold (merge_funcss thy algebra)
24423
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   256
         (map (AList.make (Graph.get_node auxgr))
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   257
         (rev (Graph.strong_conn auxgr)))
26331
92120667172f error tuning
haftmann
parents: 25597
diff changeset
   258
  end handle CLASS_ERROR (cs', msg)
92120667172f error tuning
haftmann
parents: 25597
diff changeset
   259
    => raise CLASS_ERROR (fold (insert (op =)) cs' cs, msg);
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   260
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   261
in
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   262
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   263
(** retrieval interfaces **)
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   264
24423
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   265
fun ensure_consts thy algebra consts funcgr =
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   266
  ensure_consts' thy algebra consts funcgr
26331
92120667172f error tuning
haftmann
parents: 25597
diff changeset
   267
    handle CLASS_ERROR (cs', msg) => error (msg ^ ",\nwhile preprocessing equations for constant(s) "
24423
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   268
    ^ commas (map (CodeUnit.string_of_const thy) cs'));
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   269
24283
haftmann
parents: 24219
diff changeset
   270
fun check_consts thy consts funcgr =
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   271
  let
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   272
    val algebra = Code.coregular_algebra thy;
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   273
    fun try_const const funcgr =
24283
haftmann
parents: 24219
diff changeset
   274
      (SOME const, ensure_consts' thy algebra [const] funcgr)
26331
92120667172f error tuning
haftmann
parents: 25597
diff changeset
   275
      handle CLASS_ERROR (cs', msg) => (NONE, funcgr);
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   276
    val (consts', funcgr') = fold_map try_const consts funcgr;
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   277
  in (map_filter I consts', funcgr') end;
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   278
26740
6c8cd101f875 more general evaluation combinators
haftmann
parents: 26642
diff changeset
   279
fun proto_eval thy cterm_of evaluator_fr evaluator proto_ct funcgr =
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   280
  let
26740
6c8cd101f875 more general evaluation combinators
haftmann
parents: 26642
diff changeset
   281
    val ct = cterm_of proto_ct;
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   282
    val _ = Sign.no_vars (Sign.pp thy) (Thm.term_of ct);
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   283
    val _ = Term.fold_types (Type.no_tvars #> K I) (Thm.term_of ct) ();
26740
6c8cd101f875 more general evaluation combinators
haftmann
parents: 26642
diff changeset
   284
    fun consts_of t = fold_aterms (fn Const c_ty => cons c_ty | _ => I)
6c8cd101f875 more general evaluation combinators
haftmann
parents: 26642
diff changeset
   285
      t [];
6c8cd101f875 more general evaluation combinators
haftmann
parents: 26642
diff changeset
   286
    val algebra = Code.coregular_algebra thy;
6c8cd101f875 more general evaluation combinators
haftmann
parents: 26642
diff changeset
   287
    val thm = Code.preprocess_conv ct;
6c8cd101f875 more general evaluation combinators
haftmann
parents: 26642
diff changeset
   288
    val ct' = Thm.rhs_of thm;
6c8cd101f875 more general evaluation combinators
haftmann
parents: 26642
diff changeset
   289
    val t' = Thm.term_of ct';
6c8cd101f875 more general evaluation combinators
haftmann
parents: 26642
diff changeset
   290
    val consts = map fst (consts_of t');
6c8cd101f875 more general evaluation combinators
haftmann
parents: 26642
diff changeset
   291
    val funcgr' = ensure_consts thy algebra consts funcgr;
6c8cd101f875 more general evaluation combinators
haftmann
parents: 26642
diff changeset
   292
    val (t'', evaluator') = apsnd evaluator_fr (evaluator t');
6c8cd101f875 more general evaluation combinators
haftmann
parents: 26642
diff changeset
   293
    val consts' = consts_of t'';
6c8cd101f875 more general evaluation combinators
haftmann
parents: 26642
diff changeset
   294
    val dicts = instances_of_consts thy algebra funcgr' consts';
6c8cd101f875 more general evaluation combinators
haftmann
parents: 26642
diff changeset
   295
    val funcgr'' = ensure_consts thy algebra dicts funcgr';
6c8cd101f875 more general evaluation combinators
haftmann
parents: 26642
diff changeset
   296
  in (evaluator' thm funcgr'' t'', funcgr'') end;
6c8cd101f875 more general evaluation combinators
haftmann
parents: 26642
diff changeset
   297
6c8cd101f875 more general evaluation combinators
haftmann
parents: 26642
diff changeset
   298
fun proto_eval_conv thy =
6c8cd101f875 more general evaluation combinators
haftmann
parents: 26642
diff changeset
   299
  let
6c8cd101f875 more general evaluation combinators
haftmann
parents: 26642
diff changeset
   300
    fun evaluator evaluator' thm1 funcgr t =
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   301
      let
26740
6c8cd101f875 more general evaluation combinators
haftmann
parents: 26642
diff changeset
   302
        val thm2 = evaluator' funcgr t;
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   303
        val thm3 = Code.postprocess_conv (Thm.rhs_of thm2);
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   304
      in
26740
6c8cd101f875 more general evaluation combinators
haftmann
parents: 26642
diff changeset
   305
        Thm.transitive thm1 (Thm.transitive thm2 thm3) handle THM _ =>
6c8cd101f875 more general evaluation combinators
haftmann
parents: 26642
diff changeset
   306
          error ("could not construct evaluation proof (probably due to wellsortedness problem):\n"
26928
ca87aff1ad2d structure Display: less pervasive operations;
wenzelm
parents: 26740
diff changeset
   307
          ^ (cat_lines o map Display.string_of_thm) [thm1, thm2, thm3])
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   308
      end;
26740
6c8cd101f875 more general evaluation combinators
haftmann
parents: 26642
diff changeset
   309
  in proto_eval thy I evaluator end;
24283
haftmann
parents: 24219
diff changeset
   310
26740
6c8cd101f875 more general evaluation combinators
haftmann
parents: 26642
diff changeset
   311
fun proto_eval_term thy =
24283
haftmann
parents: 24219
diff changeset
   312
  let
26740
6c8cd101f875 more general evaluation combinators
haftmann
parents: 26642
diff changeset
   313
    fun evaluator evaluator' _ funcgr t = evaluator' funcgr t;
6c8cd101f875 more general evaluation combinators
haftmann
parents: 26642
diff changeset
   314
  in proto_eval thy (Thm.cterm_of thy) evaluator end;
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   315
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   316
end; (*local*)
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   317
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   318
structure Funcgr = CodeDataFun
24713
8b3b6d09ef40 tuned functor application;
wenzelm
parents: 24423
diff changeset
   319
(
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   320
  type T = T;
24423
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   321
  val empty = Graph.empty;
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   322
  fun merge _ _ = Graph.empty;
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   323
  fun purge _ NONE _ = Graph.empty
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   324
    | purge _ (SOME cs) funcgr =
24423
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   325
        Graph.del_nodes ((Graph.all_preds funcgr 
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   326
          o filter (can (Graph.get_node funcgr))) cs) funcgr;
24713
8b3b6d09ef40 tuned functor application;
wenzelm
parents: 24423
diff changeset
   327
);
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   328
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   329
fun make thy =
24423
ae9cd0e92423 overloaded definitions accompanied by explicit constants
haftmann
parents: 24283
diff changeset
   330
  Funcgr.change thy o ensure_consts thy (Code.coregular_algebra thy);
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   331
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   332
fun make_consts thy =
24283
haftmann
parents: 24219
diff changeset
   333
  Funcgr.change_yield thy o check_consts thy;
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   334
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   335
fun eval_conv thy f =
26740
6c8cd101f875 more general evaluation combinators
haftmann
parents: 26642
diff changeset
   336
  fst o Funcgr.change_yield thy o proto_eval_conv thy f;
24283
haftmann
parents: 24219
diff changeset
   337
haftmann
parents: 24219
diff changeset
   338
fun eval_term thy f =
26740
6c8cd101f875 more general evaluation combinators
haftmann
parents: 26642
diff changeset
   339
  fst o Funcgr.change_yield thy o proto_eval_term thy f;
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   340
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   341
end; (*struct*)