src/Tools/Code/code_eval.ML
author wenzelm
Sun, 07 Feb 2010 18:04:48 +0100
changeset 35019 1ec0a3ff229e
parent 34032 f13b5c023e65
child 35228 ac2cab4583f4
permissions -rw-r--r--
simplified interface for ML antiquotations, struct_name is always "Isabelle";
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
34028
1e6206763036 split off evaluation mechanisms in separte module Code_Eval
haftmann
parents: 33992
diff changeset
     1
(*  Title:      Tools/code/code_eval.ML_
28054
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
     2
    Author:     Florian Haftmann, TU Muenchen
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
     3
34028
1e6206763036 split off evaluation mechanisms in separte module Code_Eval
haftmann
parents: 33992
diff changeset
     4
Runtime services building on code generation into implementation language SML.
28054
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
     5
*)
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
     6
34028
1e6206763036 split off evaluation mechanisms in separte module Code_Eval
haftmann
parents: 33992
diff changeset
     7
signature CODE_EVAL =
28054
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
     8
sig
34028
1e6206763036 split off evaluation mechanisms in separte module Code_Eval
haftmann
parents: 33992
diff changeset
     9
  val target: string
32740
9dd0a2f83429 explicit indication of Unsynchronized.ref;
wenzelm
parents: 32123
diff changeset
    10
  val eval: string option -> string * (unit -> 'a) option Unsynchronized.ref
30970
3fe2e418a071 generic postprocessing scheme for term evaluations
haftmann
parents: 30962
diff changeset
    11
    -> ((term -> term) -> 'a -> 'a) -> theory -> term -> string list -> 'a
34028
1e6206763036 split off evaluation mechanisms in separte module Code_Eval
haftmann
parents: 33992
diff changeset
    12
  val evaluation_code: theory -> string list -> string list
1e6206763036 split off evaluation mechanisms in separte module Code_Eval
haftmann
parents: 33992
diff changeset
    13
    -> string * ((string * string) list * (string * string) list)
28054
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
    14
  val setup: theory -> theory
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
    15
end;
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
    16
34028
1e6206763036 split off evaluation mechanisms in separte module Code_Eval
haftmann
parents: 33992
diff changeset
    17
structure Code_Eval : CODE_EVAL =
28054
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
    18
struct
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
    19
33992
bf22ff4f3d19 signatures for generated code; tuned
haftmann
parents: 33636
diff changeset
    20
(** generic **)
bf22ff4f3d19 signatures for generated code; tuned
haftmann
parents: 33636
diff changeset
    21
34028
1e6206763036 split off evaluation mechanisms in separte module Code_Eval
haftmann
parents: 33992
diff changeset
    22
val target = "Eval";
28054
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
    23
34032
f13b5c023e65 simplified notion of empty module name
haftmann
parents: 34028
diff changeset
    24
val eval_struct_name = "Code";
33992
bf22ff4f3d19 signatures for generated code; tuned
haftmann
parents: 33636
diff changeset
    25
34028
1e6206763036 split off evaluation mechanisms in separte module Code_Eval
haftmann
parents: 33992
diff changeset
    26
fun evaluation_code thy tycos consts =
33992
bf22ff4f3d19 signatures for generated code; tuned
haftmann
parents: 33636
diff changeset
    27
  let
34028
1e6206763036 split off evaluation mechanisms in separte module Code_Eval
haftmann
parents: 33992
diff changeset
    28
    val (consts', (naming, program)) = Code_Thingol.consts_program thy consts;
1e6206763036 split off evaluation mechanisms in separte module Code_Eval
haftmann
parents: 33992
diff changeset
    29
    val tycos' = map (the o Code_Thingol.lookup_tyco naming) tycos;
1e6206763036 split off evaluation mechanisms in separte module Code_Eval
haftmann
parents: 33992
diff changeset
    30
    val (ml_code, target_names) = Code_ML.evaluation_code_of thy target
34032
f13b5c023e65 simplified notion of empty module name
haftmann
parents: 34028
diff changeset
    31
      eval_struct_name naming program (consts' @ tycos');
34028
1e6206763036 split off evaluation mechanisms in separte module Code_Eval
haftmann
parents: 33992
diff changeset
    32
    val (consts'', tycos'') = chop (length consts') target_names;
1e6206763036 split off evaluation mechanisms in separte module Code_Eval
haftmann
parents: 33992
diff changeset
    33
    val consts_map = map2 (fn const => fn NONE =>
1e6206763036 split off evaluation mechanisms in separte module Code_Eval
haftmann
parents: 33992
diff changeset
    34
        error ("Constant " ^ (quote o Code.string_of_const thy) const
1e6206763036 split off evaluation mechanisms in separte module Code_Eval
haftmann
parents: 33992
diff changeset
    35
          ^ "\nhas a user-defined serialization")
1e6206763036 split off evaluation mechanisms in separte module Code_Eval
haftmann
parents: 33992
diff changeset
    36
      | SOME const'' => (const, const'')) consts consts''
1e6206763036 split off evaluation mechanisms in separte module Code_Eval
haftmann
parents: 33992
diff changeset
    37
    val tycos_map = map2 (fn tyco => fn NONE =>
1e6206763036 split off evaluation mechanisms in separte module Code_Eval
haftmann
parents: 33992
diff changeset
    38
        error ("Type " ^ (quote o Sign.extern_type thy) tyco
1e6206763036 split off evaluation mechanisms in separte module Code_Eval
haftmann
parents: 33992
diff changeset
    39
          ^ "\nhas a user-defined serialization")
1e6206763036 split off evaluation mechanisms in separte module Code_Eval
haftmann
parents: 33992
diff changeset
    40
      | SOME tyco'' => (tyco, tyco'')) tycos tycos'';
1e6206763036 split off evaluation mechanisms in separte module Code_Eval
haftmann
parents: 33992
diff changeset
    41
  in (ml_code, (tycos_map, consts_map)) end;
28054
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
    42
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
    43
34028
1e6206763036 split off evaluation mechanisms in separte module Code_Eval
haftmann
parents: 33992
diff changeset
    44
(** evaluation **)
28054
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
    45
30970
3fe2e418a071 generic postprocessing scheme for term evaluations
haftmann
parents: 30962
diff changeset
    46
fun eval some_target reff postproc thy t args =
28054
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
    47
  let
28275
8dab53900e8c ML_Context.evaluate: proper context (for ML environment);
wenzelm
parents: 28064
diff changeset
    48
    val ctxt = ProofContext.init thy;
31063
88aaab83b6fc dropped explicit suppport for frees in evaluation conversion stack
haftmann
parents: 31054
diff changeset
    49
    fun evaluator naming program ((_, (_, ty)), t) deps =
28054
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
    50
      let
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
    51
        val _ = if Code_Thingol.contains_dictvar t then
28724
haftmann
parents: 28708
diff changeset
    52
          error "Term to be evaluated contains free dictionaries" else ();
28663
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28350
diff changeset
    53
        val value_name = "Value.VALUE.value"
28054
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
    54
        val program' = program
28663
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28350
diff changeset
    55
          |> Graph.new_node (value_name,
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28350
diff changeset
    56
              Code_Thingol.Fun (Term.dummy_patternN, (([], ty), [(([], t), (Drule.dummy_thm, true))])))
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28350
diff changeset
    57
          |> fold (curry Graph.add_edge value_name) deps;
34028
1e6206763036 split off evaluation mechanisms in separte module Code_Eval
haftmann
parents: 33992
diff changeset
    58
        val (value_code, [SOME value_name']) = Code_ML.evaluation_code_of thy
34032
f13b5c023e65 simplified notion of empty module name
haftmann
parents: 34028
diff changeset
    59
          (the_default target some_target) "" naming program' [value_name];
28054
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
    60
        val sml_code = "let\n" ^ value_code ^ "\nin " ^ value_name'
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
    61
          ^ space_implode " " (map (enclose "(" ")") args) ^ " end";
30672
beaadd5af500 more systematic type use_context, with particular values ML_Parse.global_context and ML_Context.local_context;
wenzelm
parents: 30648
diff changeset
    62
      in ML_Context.evaluate ctxt false reff sml_code end;
32123
8bac9ee4b28d integrated add_triv_classes into evaluation stack
haftmann
parents: 31934
diff changeset
    63
  in Code_Thingol.eval thy postproc evaluator t end;
28054
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
    64
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
    65
34028
1e6206763036 split off evaluation mechanisms in separte module Code_Eval
haftmann
parents: 33992
diff changeset
    66
(** instrumentalization by antiquotation **)
28054
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
    67
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
    68
local
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
    69
33519
e31a85f92ce9 adapted Generic_Data, Proof_Data;
wenzelm
parents: 33038
diff changeset
    70
structure CodeAntiqData = Proof_Data
28054
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
    71
(
30962
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
    72
  type T = (string list * string list) * (bool * (string
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
    73
    * (string * ((string * string) list * (string * string) list)) lazy));
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
    74
  fun init _ = (([], []), (true, ("", Lazy.value ("", ([], [])))));
28054
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
    75
);
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
    76
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
    77
val is_first_occ = fst o snd o CodeAntiqData.get;
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
    78
30962
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
    79
fun register_code new_tycos new_consts ctxt =
28054
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
    80
  let
30962
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
    81
    val ((tycos, consts), (_, (struct_name, _))) = CodeAntiqData.get ctxt;
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
    82
    val tycos' = fold (insert (op =)) new_tycos tycos;
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
    83
    val consts' = fold (insert (op =)) new_consts consts;
28054
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
    84
    val (struct_name', ctxt') = if struct_name = ""
33992
bf22ff4f3d19 signatures for generated code; tuned
haftmann
parents: 33636
diff changeset
    85
      then ML_Antiquote.variant eval_struct_name ctxt
28054
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
    86
      else (struct_name, ctxt);
34028
1e6206763036 split off evaluation mechanisms in separte module Code_Eval
haftmann
parents: 33992
diff changeset
    87
    val acc_code = Lazy.lazy (fn () => evaluation_code (ProofContext.theory_of ctxt) tycos' consts');
30962
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
    88
  in CodeAntiqData.put ((tycos', consts'), (false, (struct_name', acc_code))) ctxt' end;
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
    89
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
    90
fun register_const const = register_code [] [const];
28054
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
    91
30962
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
    92
fun register_datatype tyco constrs = register_code [tyco] constrs;
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
    93
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
    94
fun print_const const all_struct_name tycos_map consts_map =
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
    95
  (Long_Name.append all_struct_name o the o AList.lookup (op =) consts_map) const;
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
    96
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
    97
fun print_datatype tyco constrs all_struct_name tycos_map consts_map =
28054
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
    98
  let
30962
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
    99
    val upperize = implode o nth_map 0 Symbol.to_ascii_upper o explode;
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
   100
    fun check_base name name'' =
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
   101
      if upperize (Long_Name.base_name name) = upperize name''
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
   102
      then () else error ("Name as printed " ^ quote name''
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
   103
        ^ "\ndiffers from logical base name " ^ quote (Long_Name.base_name name) ^ "; sorry.");
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
   104
    val tyco'' = (the o AList.lookup (op =) tycos_map) tyco;
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
   105
    val constrs'' = map (the o AList.lookup (op =) consts_map) constrs;
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
   106
    val _ = check_base tyco tyco'';
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
   107
    val _ = map2 check_base constrs constrs'';
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
   108
  in "datatype " ^ tyco'' ^ " = datatype " ^ Long_Name.append all_struct_name tyco'' end;
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
   109
35019
1ec0a3ff229e simplified interface for ML antiquotations, struct_name is always "Isabelle";
wenzelm
parents: 34032
diff changeset
   110
fun print_code is_first print_it ctxt =
30962
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
   111
  let
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
   112
    val (_, (_, (struct_code_name, acc_code))) = CodeAntiqData.get ctxt;
33992
bf22ff4f3d19 signatures for generated code; tuned
haftmann
parents: 33636
diff changeset
   113
    val (ml_code, (tycos_map, consts_map)) = Lazy.force acc_code;
bf22ff4f3d19 signatures for generated code; tuned
haftmann
parents: 33636
diff changeset
   114
    val ml_code = if is_first then ml_code
28054
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
   115
      else "";
35019
1ec0a3ff229e simplified interface for ML antiquotations, struct_name is always "Isabelle";
wenzelm
parents: 34032
diff changeset
   116
    val all_struct_name = "Isabelle." ^ struct_code_name;
30962
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
   117
  in (ml_code, print_it all_struct_name tycos_map consts_map) end;
28054
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
   118
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
   119
in
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
   120
35019
1ec0a3ff229e simplified interface for ML antiquotations, struct_name is always "Isabelle";
wenzelm
parents: 34032
diff changeset
   121
fun ml_code_antiq raw_const background =
28054
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
   122
  let
31156
90fed3d4430f merged module code_unit.ML into code.ML
haftmann
parents: 31121
diff changeset
   123
    val const = Code.check_const (ProofContext.theory_of background) raw_const;
28054
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
   124
    val is_first = is_first_occ background;
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
   125
    val background' = register_const const background;
35019
1ec0a3ff229e simplified interface for ML antiquotations, struct_name is always "Isabelle";
wenzelm
parents: 34032
diff changeset
   126
  in (print_code is_first (print_const const), background') end;
30962
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
   127
35019
1ec0a3ff229e simplified interface for ML antiquotations, struct_name is always "Isabelle";
wenzelm
parents: 34032
diff changeset
   128
fun ml_code_datatype_antiq (raw_tyco, raw_constrs) background =
30962
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
   129
  let
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
   130
    val thy = ProofContext.theory_of background;
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
   131
    val tyco = Sign.intern_type thy raw_tyco;
31156
90fed3d4430f merged module code_unit.ML into code.ML
haftmann
parents: 31121
diff changeset
   132
    val constrs = map (Code.check_const thy) raw_constrs;
30962
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
   133
    val constrs' = (map fst o snd o Code.get_datatype thy) tyco;
33038
8f9594c31de4 dropped redundant gen_ prefix
haftmann
parents: 32926
diff changeset
   134
    val _ = if eq_set (op =) (constrs, constrs') then ()
30962
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
   135
      else error ("Type " ^ quote tyco ^ ": given constructors diverge from real constructors")
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
   136
    val is_first = is_first_occ background;
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
   137
    val background' = register_datatype tyco constrs background;
35019
1ec0a3ff229e simplified interface for ML antiquotations, struct_name is always "Isabelle";
wenzelm
parents: 34032
diff changeset
   138
  in (print_code is_first (print_datatype tyco constrs), background') end;
28054
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
   139
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
   140
end; (*local*)
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
   141
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
   142
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
   143
(** Isar setup **)
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
   144
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
   145
val _ = ML_Context.add_antiq "code" (fn _ => Args.term >> ml_code_antiq);
30962
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
   146
val _ = ML_Context.add_antiq "code_datatype" (fn _ =>
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
   147
  (Args.tyname --| Scan.lift (Args.$$$ "=")
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
   148
    -- (Args.term ::: Scan.repeat (Scan.lift (Args.$$$ "|") |-- Args.term)))
f5fd07c558f9 code_datatype antiquotation; tuned
haftmann
parents: 30947
diff changeset
   149
      >> ml_code_datatype_antiq);
28054
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
   150
34028
1e6206763036 split off evaluation mechanisms in separte module Code_Eval
haftmann
parents: 33992
diff changeset
   151
val setup = Code_Target.extend_target (target, (Code_ML.target_SML, K I));
28054
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
   152
2b84d34c5d02 restructured and split code serializer module
haftmann
parents:
diff changeset
   153
end; (*struct*)