author | haftmann |
Mon, 06 Feb 2017 20:56:32 +0100 | |
changeset 64988 | 93aaff2b0ae0 |
parent 64987 | 1985502518ce |
child 64989 | 40c36a4aee1f |
permissions | -rw-r--r-- |
39401 | 1 |
(* Title: Tools/Code/code_runtime.ML |
28054 | 2 |
Author: Florian Haftmann, TU Muenchen |
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 | 5 |
*) |
6 |
||
39401 | 7 |
signature CODE_RUNTIME = |
28054 | 8 |
sig |
34028
1e6206763036
split off evaluation mechanisms in separte module Code_Eval
haftmann
parents:
33992
diff
changeset
|
9 |
val target: string |
39912
2ffe7060ca75
avoid antiquotation processing for code_reflect; moved ML_Context.value to Code_Runtime
haftmann
parents:
39816
diff
changeset
|
10 |
val value: Proof.context -> |
2ffe7060ca75
avoid antiquotation processing for code_reflect; moved ML_Context.value to Code_Runtime
haftmann
parents:
39816
diff
changeset
|
11 |
(Proof.context -> unit -> 'a) * ((unit -> 'a) -> Proof.context -> Proof.context) * string -> |
2ffe7060ca75
avoid antiquotation processing for code_reflect; moved ML_Context.value to Code_Runtime
haftmann
parents:
39816
diff
changeset
|
12 |
string * string -> 'a |
39473
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
13 |
type 'a cookie = (Proof.context -> unit -> 'a) * ((unit -> 'a) -> Proof.context -> Proof.context) * string |
55757 | 14 |
val dynamic_value: 'a cookie -> Proof.context -> string option |
39473
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
15 |
-> ((term -> term) -> 'a -> 'a) -> term -> string list -> 'a option |
55757 | 16 |
val dynamic_value_strict: 'a cookie -> Proof.context -> string option |
39473
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
17 |
-> ((term -> term) -> 'a -> 'a) -> term -> string list -> 'a |
55757 | 18 |
val dynamic_value_exn: 'a cookie -> Proof.context -> string option |
39473
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
19 |
-> ((term -> term) -> 'a -> 'a) -> term -> string list -> 'a Exn.result |
56973
62da80041afd
syntactic means to prevent accidental mixup of static and dynamic context
haftmann
parents:
56969
diff
changeset
|
20 |
val static_value: 'a cookie -> { ctxt: Proof.context, target: string option, |
62da80041afd
syntactic means to prevent accidental mixup of static and dynamic context
haftmann
parents:
56969
diff
changeset
|
21 |
lift_postproc: (term -> term) -> 'a -> 'a, consts: string list } |
62da80041afd
syntactic means to prevent accidental mixup of static and dynamic context
haftmann
parents:
56969
diff
changeset
|
22 |
-> Proof.context -> term -> 'a option |
62da80041afd
syntactic means to prevent accidental mixup of static and dynamic context
haftmann
parents:
56969
diff
changeset
|
23 |
val static_value_strict: 'a cookie -> { ctxt: Proof.context, target: string option, |
62da80041afd
syntactic means to prevent accidental mixup of static and dynamic context
haftmann
parents:
56969
diff
changeset
|
24 |
lift_postproc: (term -> term) -> 'a -> 'a, consts: string list } |
62da80041afd
syntactic means to prevent accidental mixup of static and dynamic context
haftmann
parents:
56969
diff
changeset
|
25 |
-> Proof.context -> term -> 'a |
62da80041afd
syntactic means to prevent accidental mixup of static and dynamic context
haftmann
parents:
56969
diff
changeset
|
26 |
val static_value_exn: 'a cookie -> { ctxt: Proof.context, target: string option, |
62da80041afd
syntactic means to prevent accidental mixup of static and dynamic context
haftmann
parents:
56969
diff
changeset
|
27 |
lift_postproc: (term -> term) -> 'a -> 'a, consts: string list } |
62da80041afd
syntactic means to prevent accidental mixup of static and dynamic context
haftmann
parents:
56969
diff
changeset
|
28 |
-> Proof.context -> term -> 'a Exn.result |
55757 | 29 |
val dynamic_holds_conv: Proof.context -> conv |
56973
62da80041afd
syntactic means to prevent accidental mixup of static and dynamic context
haftmann
parents:
56969
diff
changeset
|
30 |
val static_holds_conv: { ctxt: Proof.context, consts: string list } -> Proof.context -> conv |
40421
b41aabb629ce
constructors to datatypes in code_reflect can be globbed; dropped unused code
haftmann
parents:
40320
diff
changeset
|
31 |
val code_reflect: (string * string list option) list -> string list -> string |
b41aabb629ce
constructors to datatypes in code_reflect can be globbed; dropped unused code
haftmann
parents:
40320
diff
changeset
|
32 |
-> string option -> theory -> theory |
39473
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
33 |
datatype truth = Holds |
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
34 |
val put_truth: (unit -> truth) -> Proof.context -> Proof.context |
64987 | 35 |
val mount_computation: Proof.context -> (string * typ) list -> typ |
64988 | 36 |
-> (term -> 'ml) -> ((term -> term) -> 'ml option -> 'a) -> Proof.context -> term -> 'a |
64987 | 37 |
val polyml_as_definition: (binding * typ) list -> Path.T list -> theory -> theory |
57435 | 38 |
val trace: bool Config.T |
28054 | 39 |
end; |
40 |
||
39401 | 41 |
structure Code_Runtime : CODE_RUNTIME = |
28054 | 42 |
struct |
43 |
||
55150 | 44 |
open Basic_Code_Symbol; |
39473
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
45 |
|
64957 | 46 |
(** ML compiler as evaluation environment **) |
33992 | 47 |
|
39473
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
48 |
(* technical prerequisites *) |
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
49 |
|
64959 | 50 |
val thisN = "Code_Runtime"; |
64987 | 51 |
val prefix_this = Long_Name.append thisN; |
52 |
val truthN = prefix_this "truth"; |
|
53 |
val HoldsN = prefix_this "Holds"; |
|
39473
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
54 |
|
34028
1e6206763036
split off evaluation mechanisms in separte module Code_Eval
haftmann
parents:
33992
diff
changeset
|
55 |
val target = "Eval"; |
28054 | 56 |
|
39473
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
57 |
datatype truth = Holds; |
39422 | 58 |
|
53171 | 59 |
val _ = Theory.setup |
59104 | 60 |
(Code_Target.add_derived_target (target, [(Code_ML.target_SML, I)]) |
55150 | 61 |
#> Code_Target.set_printings (Type_Constructor (@{type_name prop}, |
64959 | 62 |
[(target, SOME (0, (K o K o K) (Code_Printer.str truthN)))])) |
55150 | 63 |
#> Code_Target.set_printings (Constant (@{const_name Code_Generator.holds}, |
64959 | 64 |
[(target, SOME (Code_Printer.plain_const_syntax HoldsN))])) |
65 |
#> Code_Target.add_reserved target thisN |
|
53171 | 66 |
#> fold (Code_Target.add_reserved target) ["oo", "ooo", "oooo", "upto", "downto", "orf", "andf"]); |
39485
f7270a5e2550
closures preserve static serializer context for static evaluation; tuned
haftmann
parents:
39482
diff
changeset
|
67 |
(*avoid further pervasive infix names*) |
39473
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
68 |
|
57435 | 69 |
val trace = Attrib.setup_config_bool @{binding "code_runtime_trace"} (K false); |
40150 | 70 |
|
63163 | 71 |
fun compile_ML verbose code context = |
72 |
(if Config.get_generic context trace then tracing code else (); |
|
63164 | 73 |
Code_Preproc.timed "compiling ML" Context.proof_of |
74 |
(ML_Context.exec (fn () => ML_Compiler0.ML ML_Env.context |
|
63163 | 75 |
{line = 0, file = "generated code", verbose = verbose, |
63164 | 76 |
debug = false} code)) context); |
39912
2ffe7060ca75
avoid antiquotation processing for code_reflect; moved ML_Context.value to Code_Runtime
haftmann
parents:
39816
diff
changeset
|
77 |
|
2ffe7060ca75
avoid antiquotation processing for code_reflect; moved ML_Context.value to Code_Runtime
haftmann
parents:
39816
diff
changeset
|
78 |
fun value ctxt (get, put, put_ml) (prelude, value) = |
2ffe7060ca75
avoid antiquotation processing for code_reflect; moved ML_Context.value to Code_Runtime
haftmann
parents:
39816
diff
changeset
|
79 |
let |
62889 | 80 |
val code = |
81 |
prelude ^ "\nval _ = Context.put_generic_context (SOME (Context.map_proof (" ^ |
|
82 |
put_ml ^ " (fn () => " ^ value ^ ")) (Context.the_generic_context ())))"; |
|
39912
2ffe7060ca75
avoid antiquotation processing for code_reflect; moved ML_Context.value to Code_Runtime
haftmann
parents:
39816
diff
changeset
|
83 |
val ctxt' = ctxt |
64957 | 84 |
|> put (fn () => error ("Bad compilation for " ^ quote put_ml)) |
63163 | 85 |
|> Context.proof_map (compile_ML false code); |
63164 | 86 |
val computator = get ctxt'; |
87 |
in Code_Preproc.timed_exec "running ML" computator ctxt' end; |
|
39912
2ffe7060ca75
avoid antiquotation processing for code_reflect; moved ML_Context.value to Code_Runtime
haftmann
parents:
39816
diff
changeset
|
88 |
|
39473
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
89 |
|
64957 | 90 |
(* evaluation into ML language values *) |
39473
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
91 |
|
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
92 |
type 'a cookie = (Proof.context -> unit -> 'a) * ((unit -> 'a) -> Proof.context -> Proof.context) * string; |
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
93 |
|
55757 | 94 |
fun reject_vars ctxt t = |
95 |
((Sign.no_frees ctxt o Sign.no_vars ctxt o map_types (K dummyT)) t; t); |
|
39605 | 96 |
|
64957 | 97 |
fun build_compilation_text ctxt some_target program consts = |
98 |
Code_Target.compilation_text ctxt (the_default target some_target) program consts false |
|
63157
65a81a4ef7f8
clarified naming conventions and code for code evaluation sandwiches
haftmann
parents:
63156
diff
changeset
|
99 |
#>> (fn ml_modules => space_implode "\n\n" (map snd ml_modules)); |
65a81a4ef7f8
clarified naming conventions and code for code evaluation sandwiches
haftmann
parents:
63156
diff
changeset
|
100 |
|
64957 | 101 |
fun run_compilation_text cookie ctxt comp vs_t args = |
55757 | 102 |
let |
63157
65a81a4ef7f8
clarified naming conventions and code for code evaluation sandwiches
haftmann
parents:
63156
diff
changeset
|
103 |
val (program_code, value_name) = comp vs_t; |
39473
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
104 |
val value_code = space_implode " " |
41347
064133cb4ef6
evaluator separating static and dynamic operations
haftmann
parents:
41343
diff
changeset
|
105 |
(value_name :: "()" :: map (enclose "(" ")") args); |
40235
87998864284e
use Exn.interruptible_capture to keep user-code interruptible (Exn.capture not immediately followed by Exn.release here);
wenzelm
parents:
40150
diff
changeset
|
106 |
in Exn.interruptible_capture (value ctxt cookie) (program_code, value_code) end; |
39473
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
107 |
|
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
108 |
fun partiality_as_none e = SOME (Exn.release e) |
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
109 |
handle General.Match => NONE |
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
110 |
| General.Bind => NONE |
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
111 |
| General.Fail _ => NONE; |
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
112 |
|
55757 | 113 |
fun dynamic_value_exn cookie ctxt some_target postproc t args = |
39473
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
114 |
let |
55757 | 115 |
val _ = reject_vars ctxt t; |
57435 | 116 |
val _ = if Config.get ctxt trace |
55757 | 117 |
then tracing ("Evaluation of term " ^ quote (Syntax.string_of_term ctxt t)) |
41099 | 118 |
else () |
63157
65a81a4ef7f8
clarified naming conventions and code for code evaluation sandwiches
haftmann
parents:
63156
diff
changeset
|
119 |
fun comp program _ vs_ty_t deps = |
64957 | 120 |
run_compilation_text cookie ctxt (build_compilation_text ctxt some_target program deps) vs_ty_t args; |
63157
65a81a4ef7f8
clarified naming conventions and code for code evaluation sandwiches
haftmann
parents:
63156
diff
changeset
|
121 |
in Code_Thingol.dynamic_value ctxt (Exn.map_res o postproc) comp t end; |
39473
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
122 |
|
55757 | 123 |
fun dynamic_value_strict cookie ctxt some_target postproc t args = |
124 |
Exn.release (dynamic_value_exn cookie ctxt some_target postproc t args); |
|
39473
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
125 |
|
55757 | 126 |
fun dynamic_value cookie ctxt some_target postproc t args = |
127 |
partiality_as_none (dynamic_value_exn cookie ctxt some_target postproc t args); |
|
39473
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
128 |
|
56973
62da80041afd
syntactic means to prevent accidental mixup of static and dynamic context
haftmann
parents:
56969
diff
changeset
|
129 |
fun static_value_exn cookie { ctxt, target, lift_postproc, consts } = |
55757 | 130 |
let |
64957 | 131 |
fun compilation' { program, deps } = |
63157
65a81a4ef7f8
clarified naming conventions and code for code evaluation sandwiches
haftmann
parents:
63156
diff
changeset
|
132 |
let |
64957 | 133 |
val compilation'' = run_compilation_text cookie ctxt |
134 |
(build_compilation_text ctxt target program (map Constant deps)); |
|
135 |
in fn _ => fn _ => fn vs_ty_t => fn _ => compilation'' vs_ty_t [] end; |
|
136 |
val compilation = Code_Thingol.static_value { ctxt = ctxt, |
|
61077
06cca32aa519
thread context for exceptions from forks, e.g. relevant when printing errors;
wenzelm
parents:
60956
diff
changeset
|
137 |
lift_postproc = Exn.map_res o lift_postproc, consts = consts } |
64957 | 138 |
compilation'; |
139 |
in fn ctxt' => compilation ctxt' o reject_vars ctxt' end; |
|
39473
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
140 |
|
64928
18a6b96f8b00
corrected static scope: multi-argument composition does not apply partially
haftmann
parents:
63184
diff
changeset
|
141 |
fun static_value_strict cookie x = Exn.release oo static_value_exn cookie x; |
41347
064133cb4ef6
evaluator separating static and dynamic operations
haftmann
parents:
41343
diff
changeset
|
142 |
|
64928
18a6b96f8b00
corrected static scope: multi-argument composition does not apply partially
haftmann
parents:
63184
diff
changeset
|
143 |
fun static_value cookie x = partiality_as_none oo static_value_exn cookie x; |
39473
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
144 |
|
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
145 |
|
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
146 |
(* evaluation for truth or nothing *) |
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
147 |
|
39820 | 148 |
structure Truth_Result = Proof_Data |
149 |
( |
|
59155 | 150 |
type T = unit -> truth; |
151 |
val empty: T = fn () => raise Fail "Truth_Result"; |
|
152 |
fun init _ = empty; |
|
39473
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
153 |
); |
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
154 |
val put_truth = Truth_Result.put; |
64987 | 155 |
val truth_cookie = (Truth_Result.get, put_truth, prefix_this "put_truth"); |
39473
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
156 |
|
58558
30cc7ee5ac10
basic support for fully static evaluator generation without dynamic compiler invocation
haftmann
parents:
58557
diff
changeset
|
157 |
local |
39605 | 158 |
|
58558
30cc7ee5ac10
basic support for fully static evaluator generation without dynamic compiler invocation
haftmann
parents:
58557
diff
changeset
|
159 |
val reject_vars = fn ctxt => tap (reject_vars ctxt o Thm.term_of); |
41349
0e2a3f22f018
evaluator separating static and dynamic operations
haftmann
parents:
41348
diff
changeset
|
160 |
|
55757 | 161 |
fun check_holds ctxt evaluator vs_t ct = |
39473
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
162 |
let |
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
163 |
val t = Thm.term_of ct; |
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
164 |
val _ = if fastype_of t <> propT |
59633 | 165 |
then error ("Not a proposition: " ^ Syntax.string_of_term ctxt t) |
39473
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
166 |
else (); |
59633 | 167 |
val iff = Thm.cterm_of ctxt (Term.Const (@{const_name Pure.eq}, propT --> propT --> propT)); |
64957 | 168 |
val result = case partiality_as_none (run_compilation_text truth_cookie ctxt evaluator vs_t []) |
39473
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
169 |
of SOME Holds => true |
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
170 |
| _ => false; |
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
171 |
in |
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
172 |
Thm.mk_binop iff ct (if result then @{cprop "PROP Code_Generator.holds"} else ct) |
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
173 |
end; |
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
174 |
|
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
175 |
val (_, raw_check_holds_oracle) = Context.>>> (Context.map_theory_result |
43619
3803869014aa
proper @{binding} antiquotations (relevant for formal references);
wenzelm
parents:
43560
diff
changeset
|
176 |
(Thm.add_oracle (@{binding holds_by_evaluation}, |
55757 | 177 |
fn (ctxt, evaluator, vs_t, ct) => check_holds ctxt evaluator vs_t ct))); |
39473
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
178 |
|
56920
d651b944c67e
normalizing of type variables before evaluation with explicit resubstitution function: make nbe work with funny type variables like \<AA>;
haftmann
parents:
56618
diff
changeset
|
179 |
fun check_holds_oracle ctxt evaluator vs_ty_t ct = |
d651b944c67e
normalizing of type variables before evaluation with explicit resubstitution function: make nbe work with funny type variables like \<AA>;
haftmann
parents:
56618
diff
changeset
|
180 |
raw_check_holds_oracle (ctxt, evaluator, vs_ty_t, ct); |
41349
0e2a3f22f018
evaluator separating static and dynamic operations
haftmann
parents:
41348
diff
changeset
|
181 |
|
0e2a3f22f018
evaluator separating static and dynamic operations
haftmann
parents:
41348
diff
changeset
|
182 |
in |
39485
f7270a5e2550
closures preserve static serializer context for static evaluation; tuned
haftmann
parents:
39482
diff
changeset
|
183 |
|
55757 | 184 |
fun dynamic_holds_conv ctxt = Code_Thingol.dynamic_conv ctxt |
56969
7491932da574
dropped obsolete hand-waving adjustion of type variables: safely done in preprocessor
haftmann
parents:
56920
diff
changeset
|
185 |
(fn program => fn vs_t => fn deps => |
64957 | 186 |
check_holds_oracle ctxt (build_compilation_text ctxt NONE program deps) vs_t) |
55757 | 187 |
o reject_vars ctxt; |
39473
33638f4883ac
dynamic and static value computation; built-in evaluation of propositions
haftmann
parents:
39422
diff
changeset
|
188 |
|
56973
62da80041afd
syntactic means to prevent accidental mixup of static and dynamic context
haftmann
parents:
56969
diff
changeset
|
189 |
fun static_holds_conv (ctxt_consts as { ctxt, ... }) = |
63156 | 190 |
Code_Thingol.static_conv_thingol ctxt_consts (fn { program, deps } => fn ctxt' => fn vs_t => |
64957 | 191 |
K (check_holds_oracle ctxt' (build_compilation_text ctxt NONE program (map Constant deps)) vs_t o reject_vars ctxt')); |
41349
0e2a3f22f018
evaluator separating static and dynamic operations
haftmann
parents:
41348
diff
changeset
|
192 |
|
0e2a3f22f018
evaluator separating static and dynamic operations
haftmann
parents:
41348
diff
changeset
|
193 |
end; (*local*) |
39404
a8c337299bc1
Code_Runtime.value, corresponding to ML_Context.value; tuned
haftmann
parents:
39401
diff
changeset
|
194 |
|
a8c337299bc1
Code_Runtime.value, corresponding to ML_Context.value; tuned
haftmann
parents:
39401
diff
changeset
|
195 |
|
64957 | 196 |
(** generator for computations -- partial implementations of the universal morphism from Isabelle to ML terms **) |
197 |
||
198 |
(* auxiliary *) |
|
64940
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
199 |
|
64957 | 200 |
val generated_computationN = "Generated_Computation"; |
201 |
||
202 |
||
203 |
(* possible type signatures of constants *) |
|
64943
c5618df67c2a
explicit a-priori detection of unsuitable terms for computations
haftmann
parents:
64940
diff
changeset
|
204 |
|
64940
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
205 |
fun typ_signatures_for T = |
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
206 |
let |
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
207 |
val (Ts, T') = strip_type T; |
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
208 |
in map_range (fn n => (drop n Ts ---> T', take n Ts)) (length Ts + 1) end; |
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
209 |
|
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
210 |
fun typ_signatures cTs = |
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
211 |
let |
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
212 |
fun add (c, T) = |
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
213 |
fold (fn (T, Ts) => Typtab.map_default (T, []) (cons (c, Ts))) |
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
214 |
(typ_signatures_for T); |
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
215 |
in |
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
216 |
Typtab.empty |
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
217 |
|> fold add cTs |
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
218 |
|> Typtab.lookup_list |
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
219 |
end; |
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
220 |
|
64957 | 221 |
|
222 |
(* name mangling *) |
|
223 |
||
224 |
local |
|
225 |
||
226 |
fun tycos_of (Type (tyco, Ts)) = maps tycos_of Ts @ [tyco] |
|
227 |
| tycos_of _ = []; |
|
228 |
||
229 |
val ml_name_of = Name.desymbolize NONE o Long_Name.base_name; |
|
230 |
||
231 |
in |
|
232 |
||
64959 | 233 |
val covered_constsN = "covered_consts"; |
234 |
||
64957 | 235 |
fun of_term_for_typ Ts = |
236 |
let |
|
237 |
val names = Ts |
|
238 |
|> map (suffix "_of_term" o space_implode "_" o map ml_name_of o tycos_of) |
|
239 |
|> Name.variant_list []; |
|
240 |
in the o AList.lookup (op =) (Ts ~~ names) end; |
|
241 |
||
242 |
fun eval_for_const ctxt cTs = |
|
243 |
let |
|
244 |
fun symbol_list (c, T) = c :: maps tycos_of (Sign.const_typargs (Proof_Context.theory_of ctxt) (c, T)) |
|
245 |
val names = cTs |
|
246 |
|> map (prefix "eval_" o space_implode "_" o map ml_name_of o symbol_list) |
|
247 |
|> Name.variant_list []; |
|
248 |
in the o AList.lookup (op =) (cTs ~~ names) end; |
|
249 |
||
250 |
end; |
|
251 |
||
252 |
||
253 |
(* checks for input terms *) |
|
254 |
||
255 |
fun monomorphic T = fold_atyps ((K o K) false) T true; |
|
256 |
||
257 |
fun check_typ ctxt T t = |
|
258 |
Syntax.check_term ctxt (Type.constraint T t); |
|
259 |
||
260 |
fun check_computation_input ctxt cTs t = |
|
261 |
let |
|
262 |
fun check t = check_comb (strip_comb t) |
|
263 |
and check_comb (t as Abs _, _) = |
|
264 |
error ("Bad term, contains abstraction: " ^ Syntax.string_of_term ctxt t) |
|
265 |
| check_comb (t as Const (cT as (c, T)), ts) = |
|
266 |
let |
|
267 |
val _ = if not (member (op =) cTs cT) |
|
268 |
then error ("Bad term, computation cannot proceed on constant " ^ Syntax.string_of_term ctxt t) |
|
269 |
else (); |
|
270 |
val _ = if not (monomorphic T) |
|
271 |
then error ("Bad term, contains polymorphic constant " ^ Syntax.string_of_term ctxt t) |
|
272 |
else (); |
|
273 |
val _ = map check ts; |
|
274 |
in () end; |
|
275 |
val _ = check t; |
|
276 |
in t end; |
|
277 |
||
278 |
||
279 |
(* code generation for of the universal morphism *) |
|
280 |
||
64959 | 281 |
val print_const = ML_Syntax.print_pair ML_Syntax.print_string ML_Syntax.print_typ; |
282 |
||
64940
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
283 |
fun print_of_term_funs { typ_sign_for, eval_for_const, of_term_for_typ } Ts = |
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
284 |
let |
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
285 |
val var_names = map_range (fn n => "t" ^ string_of_int (n + 1)); |
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
286 |
fun print_lhs c xs = "Const (" ^ quote c ^ ", _)" |
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
287 |
|> fold (fn x => fn s => s ^ " $ " ^ x) xs |
64943
c5618df67c2a
explicit a-priori detection of unsuitable terms for computations
haftmann
parents:
64940
diff
changeset
|
288 |
|> enclose "(" ")"; |
64940
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
289 |
fun print_rhs c Ts T xs = eval_for_const (c, Ts ---> T) |
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
290 |
|> fold2 (fn T' => fn x => fn s => |
64943
c5618df67c2a
explicit a-priori detection of unsuitable terms for computations
haftmann
parents:
64940
diff
changeset
|
291 |
s ^ (" (" ^ of_term_for_typ T' ^ " " ^ x ^ ")")) Ts xs |
64940
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
292 |
fun print_eq T (c, Ts) = |
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
293 |
let |
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
294 |
val xs = var_names (length Ts); |
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
295 |
in print_lhs c xs ^ " = " ^ print_rhs c Ts T xs end; |
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
296 |
fun print_eqs T = |
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
297 |
let |
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
298 |
val typ_signs = typ_sign_for T; |
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
299 |
val name = of_term_for_typ T; |
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
300 |
in |
64943
c5618df67c2a
explicit a-priori detection of unsuitable terms for computations
haftmann
parents:
64940
diff
changeset
|
301 |
map (print_eq T) typ_signs |
64940
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
302 |
|> map (prefix (name ^ " ")) |
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
303 |
|> space_implode "\n | " |
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
304 |
end; |
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
305 |
in |
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
306 |
map print_eqs Ts |
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
307 |
|> space_implode "\nand " |
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
308 |
|> prefix "fun " |
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
309 |
end; |
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
310 |
|
64959 | 311 |
fun print_computation_code ctxt compiled_value [] requested_Ts = ("", []) |
312 |
| print_computation_code ctxt compiled_value cTs requested_Ts = |
|
313 |
let |
|
314 |
val proper_cTs = map_filter I cTs; |
|
315 |
val typ_sign_for = typ_signatures proper_cTs; |
|
316 |
fun add_typ T Ts = |
|
317 |
if member (op =) Ts T |
|
318 |
then Ts |
|
319 |
else Ts |
|
320 |
|> cons T |
|
321 |
|> fold (fold add_typ o snd) (typ_sign_for T); |
|
322 |
val required_Ts = fold add_typ requested_Ts []; |
|
323 |
val of_term_for_typ' = of_term_for_typ required_Ts; |
|
324 |
val eval_for_const' = eval_for_const ctxt proper_cTs; |
|
325 |
val eval_for_const'' = the_default "_" o Option.map eval_for_const'; |
|
326 |
val eval_tuple = enclose "(" ")" (commas (map eval_for_const' proper_cTs)); |
|
327 |
fun mk_abs s = "fn " ^ s ^ " => "; |
|
328 |
val eval_abs = space_implode "" |
|
329 |
(map (mk_abs o eval_for_const'') cTs); |
|
330 |
val of_term_code = print_of_term_funs { |
|
331 |
typ_sign_for = typ_sign_for, |
|
332 |
eval_for_const = eval_for_const', |
|
333 |
of_term_for_typ = of_term_for_typ' } required_Ts; |
|
334 |
val of_term_names = map (Long_Name.append generated_computationN |
|
335 |
o of_term_for_typ') requested_Ts; |
|
336 |
in |
|
337 |
cat_lines [ |
|
338 |
"structure " ^ generated_computationN ^ " =", |
|
339 |
"struct", |
|
340 |
"", |
|
341 |
"val " ^ covered_constsN ^ " = " ^ ML_Syntax.print_list print_const proper_cTs ^ ";", |
|
342 |
"", |
|
343 |
"val " ^ eval_tuple ^ " = " ^ compiled_value ^ " ()", |
|
344 |
" (" ^ eval_abs, |
|
345 |
" " ^ eval_tuple ^ ");", |
|
346 |
"", |
|
347 |
of_term_code, |
|
348 |
"", |
|
349 |
"end" |
|
350 |
] |> rpair of_term_names |
|
351 |
end; |
|
64940
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
352 |
|
64987 | 353 |
fun checked_computation cTs T raw_computation ctxt = |
354 |
check_typ ctxt T |
|
355 |
#> reject_vars ctxt |
|
356 |
#> check_computation_input ctxt cTs |
|
64988 | 357 |
#> Exn.capture raw_computation |
358 |
#> partiality_as_none; |
|
64987 | 359 |
|
64957 | 360 |
fun mount_computation ctxt cTs T raw_computation lift_postproc = |
361 |
Code_Preproc.static_value { ctxt = ctxt, lift_postproc = lift_postproc, consts = [] } |
|
64987 | 362 |
(K (checked_computation cTs T raw_computation)); |
64943
c5618df67c2a
explicit a-priori detection of unsuitable terms for computations
haftmann
parents:
64940
diff
changeset
|
363 |
|
64959 | 364 |
|
365 |
(** variants of universal runtime code generation **) |
|
64940
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
366 |
|
64959 | 367 |
(*FIXME consolidate variants*) |
64940
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
368 |
|
64959 | 369 |
fun runtime_code'' ctxt module_name program tycos consts = |
33992 | 370 |
let |
55757 | 371 |
val thy = Proof_Context.theory_of ctxt; |
48568 | 372 |
val (ml_modules, target_names) = |
55757 | 373 |
Code_Target.produce_code_for ctxt |
55683 | 374 |
target NONE module_name [] program false (map Constant consts @ map Type_Constructor tycos); |
48568 | 375 |
val ml_code = space_implode "\n\n" (map snd ml_modules); |
55147
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
haftmann
parents:
53171
diff
changeset
|
376 |
val (consts', tycos') = chop (length consts) target_names; |
42359 | 377 |
val consts_map = map2 (fn const => |
378 |
fn NONE => |
|
379 |
error ("Constant " ^ (quote o Code.string_of_const thy) const ^ |
|
380 |
"\nhas a user-defined serialization") |
|
55147
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
haftmann
parents:
53171
diff
changeset
|
381 |
| SOME const' => (const, const')) consts consts' |
42359 | 382 |
val tycos_map = map2 (fn tyco => |
383 |
fn NONE => |
|
55304 | 384 |
error ("Type " ^ quote (Proof_Context.markup_type ctxt tyco) ^ |
42359 | 385 |
"\nhas a user-defined serialization") |
55147
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
haftmann
parents:
53171
diff
changeset
|
386 |
| SOME tyco' => (tyco, tyco')) tycos tycos'; |
34028
1e6206763036
split off evaluation mechanisms in separte module Code_Eval
haftmann
parents:
33992
diff
changeset
|
387 |
in (ml_code, (tycos_map, consts_map)) end; |
28054 | 388 |
|
64959 | 389 |
fun runtime_code' ctxt some_module_name named_tycos named_consts computation_Ts program evals vs_ty_evals deps = |
390 |
let |
|
391 |
val thy = Proof_Context.theory_of ctxt; |
|
392 |
fun the_const (Const cT) = cT |
|
393 |
| the_const t = error ("No constant after preprocessing: " ^ Syntax.string_of_term ctxt t) |
|
394 |
val raw_computation_cTs = case evals of |
|
395 |
Abs (_, _, t) => (map the_const o snd o strip_comb) t |
|
396 |
| _ => error ("Bad term after preprocessing: " ^ Syntax.string_of_term ctxt evals); |
|
397 |
val computation_cTs = fold_rev (fn cT => fn cTs => |
|
398 |
(if member (op =) cTs (SOME cT) then NONE else SOME cT) :: cTs) raw_computation_cTs []; |
|
399 |
val consts' = fold (fn NONE => I | SOME (c, _) => insert (op =) c) |
|
400 |
computation_cTs named_consts; |
|
401 |
val program' = Code_Thingol.consts_program ctxt consts'; |
|
402 |
(*FIXME insufficient interfaces require double invocation of code generator*) |
|
403 |
val ((ml_modules, compiled_value), deresolve) = |
|
404 |
Code_Target.compilation_text' ctxt target some_module_name program' |
|
405 |
(map Code_Symbol.Type_Constructor named_tycos @ map Code_Symbol.Constant consts' @ deps) true vs_ty_evals; |
|
406 |
(*FIXME constrain signature*) |
|
407 |
fun deresolve_const c = case (deresolve o Code_Symbol.Constant) c of |
|
408 |
NONE => error ("Constant " ^ (quote o Code.string_of_const thy) c ^ |
|
409 |
"\nhas a user-defined serialization") |
|
410 |
| SOME c' => c'; |
|
411 |
fun deresolve_tyco tyco = case (deresolve o Code_Symbol.Type_Constructor) tyco of |
|
412 |
NONE => error ("Type " ^ quote (Proof_Context.markup_type ctxt tyco) ^ |
|
413 |
"\nhas a user-defined serialization") |
|
414 |
| SOME c' => c'; |
|
415 |
val tyco_names = map deresolve_const named_tycos; |
|
416 |
val const_names = map deresolve_const named_consts; |
|
417 |
val generated_code = space_implode "\n\n" (map snd ml_modules); |
|
418 |
val (of_term_code, of_term_names) = |
|
419 |
print_computation_code ctxt compiled_value computation_cTs computation_Ts; |
|
420 |
val compiled_computation = generated_code ^ "\n" ^ of_term_code; |
|
421 |
in |
|
422 |
compiled_computation |
|
423 |
|> rpair { tyco_map = named_tycos ~~ tyco_names, |
|
424 |
const_map = named_consts ~~ const_names, |
|
425 |
of_term_map = computation_Ts ~~ of_term_names } |
|
426 |
end; |
|
427 |
||
428 |
fun funs_of_maps { tyco_map, const_map, of_term_map } = |
|
429 |
{ name_for_tyco = the o AList.lookup (op =) tyco_map, |
|
430 |
name_for_const = the o AList.lookup (op =) const_map, |
|
431 |
of_term_for_typ = the o AList.lookup (op =) of_term_map }; |
|
432 |
||
433 |
fun runtime_code ctxt some_module_name named_tycos named_consts computation_Ts program evals vs_ty_evals deps = |
|
434 |
runtime_code' ctxt some_module_name named_tycos named_consts computation_Ts program evals vs_ty_evals deps |
|
435 |
||> funs_of_maps; |
|
436 |
||
437 |
||
438 |
(** code and computation antiquotations **) |
|
439 |
||
64987 | 440 |
val mount_computationN = prefix_this "mount_computation"; |
64959 | 441 |
|
28054 | 442 |
local |
443 |
||
38930
072363be3fd9
modernized; avoid pointless tinkering with structure names
haftmann
parents:
38929
diff
changeset
|
444 |
structure Code_Antiq_Data = Proof_Data |
28054 | 445 |
( |
64955 | 446 |
type T = { named_consts: string list, |
64959 | 447 |
computation_Ts: typ list, computation_cTs: (string * typ) list, |
448 |
position_index: int, |
|
449 |
generated_code: (string * { |
|
450 |
name_for_tyco: string -> string, |
|
451 |
name_for_const: string -> string, |
|
452 |
of_term_for_typ: typ -> string |
|
453 |
}) lazy |
|
64955 | 454 |
}; |
455 |
val empty: T = { named_consts = [], |
|
64959 | 456 |
computation_Ts = [], computation_cTs = [], |
457 |
position_index = 0, |
|
458 |
generated_code = Lazy.lazy (fn () => raise Fail "empty") |
|
64955 | 459 |
}; |
59150 | 460 |
fun init _ = empty; |
28054 | 461 |
); |
462 |
||
64959 | 463 |
val current_position_index = #position_index o Code_Antiq_Data.get; |
64955 | 464 |
|
64959 | 465 |
fun register { named_consts, computation_Ts, computation_cTs } ctxt = |
64955 | 466 |
let |
64959 | 467 |
val data = Code_Antiq_Data.get ctxt; |
468 |
val named_consts' = union (op =) named_consts (#named_consts data); |
|
469 |
val computation_Ts' = union (op =) computation_Ts (#computation_Ts data); |
|
470 |
val computation_cTs' = union (op =) computation_cTs (#computation_cTs data); |
|
471 |
val position_index' = #position_index data + 1; |
|
472 |
fun generated_code' () = |
|
473 |
let |
|
474 |
val evals = Abs ("eval", map snd computation_cTs' ---> |
|
475 |
TFree (Name.aT, []), list_comb (Bound 0, map Const computation_cTs')); |
|
476 |
in Code_Thingol.dynamic_value ctxt |
|
477 |
(K I) (runtime_code ctxt NONE [] named_consts' computation_Ts') evals |
|
478 |
end; |
|
64955 | 479 |
in |
480 |
ctxt |
|
481 |
|> Code_Antiq_Data.put { |
|
64959 | 482 |
named_consts = named_consts', |
483 |
computation_Ts = computation_Ts', |
|
484 |
computation_cTs = computation_cTs', |
|
485 |
position_index = position_index', |
|
486 |
generated_code = Lazy.lazy generated_code' |
|
64955 | 487 |
} |
488 |
end; |
|
30962 | 489 |
|
64959 | 490 |
fun register_const const = |
491 |
register { named_consts = [const], |
|
492 |
computation_Ts = [], |
|
493 |
computation_cTs = [] }; |
|
494 |
||
495 |
fun register_computation cTs T = |
|
496 |
register { named_consts = [], |
|
497 |
computation_Ts = [T], |
|
498 |
computation_cTs = cTs }; |
|
499 |
||
500 |
fun print body_code_for ctxt ctxt' = |
|
30962 | 501 |
let |
64959 | 502 |
val position_index = current_position_index ctxt; |
503 |
val (code, name_ofs) = (Lazy.force o #generated_code o Code_Antiq_Data.get) ctxt'; |
|
504 |
val context_code = if position_index = 0 then code else ""; |
|
505 |
val body_code = body_code_for name_ofs (ML_Context.struct_name ctxt') position_index; |
|
64958 | 506 |
in (context_code, body_code) end; |
28054 | 507 |
|
64959 | 508 |
fun print_code ctxt const = |
509 |
print (fn { name_for_const, ... } => fn prfx => fn _ => |
|
510 |
Long_Name.append prfx (name_for_const const)) ctxt; |
|
511 |
||
512 |
fun print_computation ctxt T = |
|
513 |
print (fn { of_term_for_typ, ... } => fn prfx => fn _ => |
|
514 |
space_implode " " [ |
|
515 |
mount_computationN, |
|
516 |
"(Context.proof_of (Context.the_generic_context ()))", |
|
517 |
Long_Name.implode [prfx, generated_computationN, covered_constsN], |
|
518 |
(ML_Syntax.atomic o ML_Syntax.print_typ) T, |
|
519 |
Long_Name.append prfx (of_term_for_typ T) |
|
520 |
]) ctxt; |
|
521 |
||
28054 | 522 |
in |
523 |
||
56069
451d5b73f8cf
simplified programming interface to define ML antiquotations -- NB: the transformed context ignores updates of the context parser;
wenzelm
parents:
55757
diff
changeset
|
524 |
fun ml_code_antiq raw_const ctxt = |
28054 | 525 |
let |
53169
e2d31807cbf6
clarified type ML_Context.antiq: context parser maintains compilation context, declaration is applied to final context;
wenzelm
parents:
52435
diff
changeset
|
526 |
val thy = Proof_Context.theory_of ctxt; |
e2d31807cbf6
clarified type ML_Context.antiq: context parser maintains compilation context, declaration is applied to final context;
wenzelm
parents:
52435
diff
changeset
|
527 |
val const = Code.check_const thy raw_const; |
64959 | 528 |
in (print_code ctxt const, register_const const ctxt) end; |
529 |
||
530 |
fun ml_computation_antiq (raw_ts, raw_T) ctxt = |
|
531 |
let |
|
532 |
val ts = map (Syntax.check_term ctxt) raw_ts; |
|
64987 | 533 |
val cTs = (fold o fold_aterms) |
534 |
(fn (t as Const (cT as (_, T))) => |
|
535 |
if not (monomorphic T) then error ("Polymorphic constant: " ^ Syntax.string_of_term ctxt t) |
|
536 |
else insert (op =) cT | _ => I) ts []; |
|
64959 | 537 |
val T = Syntax.check_typ ctxt raw_T; |
538 |
val _ = if not (monomorphic T) |
|
539 |
then error ("Polymorphic type: " ^ Syntax.string_of_typ ctxt T) |
|
540 |
else (); |
|
541 |
in (print_computation ctxt T, register_computation cTs T ctxt) end; |
|
30962 | 542 |
|
28054 | 543 |
end; (*local*) |
544 |
||
545 |
||
58558
30cc7ee5ac10
basic support for fully static evaluator generation without dynamic compiler invocation
haftmann
parents:
58557
diff
changeset
|
546 |
(** reflection support **) |
36470 | 547 |
|
40421
b41aabb629ce
constructors to datatypes in code_reflect can be globbed; dropped unused code
haftmann
parents:
40320
diff
changeset
|
548 |
fun check_datatype thy tyco some_consts = |
36470 | 549 |
let |
63174
57c0d60e491c
do not export abstract constructors in code_reflect
haftmann
parents:
63164
diff
changeset
|
550 |
val declared_constrs = (map fst o snd o fst o Code.get_type thy) tyco; |
57c0d60e491c
do not export abstract constructors in code_reflect
haftmann
parents:
63164
diff
changeset
|
551 |
val constrs = case some_consts |
57c0d60e491c
do not export abstract constructors in code_reflect
haftmann
parents:
63164
diff
changeset
|
552 |
of SOME [] => [] |
57c0d60e491c
do not export abstract constructors in code_reflect
haftmann
parents:
63164
diff
changeset
|
553 |
| SOME consts => |
40421
b41aabb629ce
constructors to datatypes in code_reflect can be globbed; dropped unused code
haftmann
parents:
40320
diff
changeset
|
554 |
let |
63174
57c0d60e491c
do not export abstract constructors in code_reflect
haftmann
parents:
63164
diff
changeset
|
555 |
val missing_constrs = subtract (op =) consts declared_constrs; |
40421
b41aabb629ce
constructors to datatypes in code_reflect can be globbed; dropped unused code
haftmann
parents:
40320
diff
changeset
|
556 |
val _ = if null missing_constrs then [] |
45430 | 557 |
else error ("Missing constructor(s) " ^ commas_quote missing_constrs |
40421
b41aabb629ce
constructors to datatypes in code_reflect can be globbed; dropped unused code
haftmann
parents:
40320
diff
changeset
|
558 |
^ " for datatype " ^ quote tyco); |
63174
57c0d60e491c
do not export abstract constructors in code_reflect
haftmann
parents:
63164
diff
changeset
|
559 |
val false_constrs = subtract (op =) declared_constrs consts; |
40421
b41aabb629ce
constructors to datatypes in code_reflect can be globbed; dropped unused code
haftmann
parents:
40320
diff
changeset
|
560 |
val _ = if null false_constrs then [] |
45430 | 561 |
else error ("Non-constructor(s) " ^ commas_quote false_constrs |
40421
b41aabb629ce
constructors to datatypes in code_reflect can be globbed; dropped unused code
haftmann
parents:
40320
diff
changeset
|
562 |
^ " for datatype " ^ quote tyco) |
63174
57c0d60e491c
do not export abstract constructors in code_reflect
haftmann
parents:
63164
diff
changeset
|
563 |
in consts end |
57c0d60e491c
do not export abstract constructors in code_reflect
haftmann
parents:
63164
diff
changeset
|
564 |
| NONE => declared_constrs; |
40421
b41aabb629ce
constructors to datatypes in code_reflect can be globbed; dropped unused code
haftmann
parents:
40320
diff
changeset
|
565 |
in (tyco, constrs) end; |
36470 | 566 |
|
567 |
fun add_eval_tyco (tyco, tyco') thy = |
|
568 |
let |
|
569 |
val k = Sign.arity_number thy tyco; |
|
40421
b41aabb629ce
constructors to datatypes in code_reflect can be globbed; dropped unused code
haftmann
parents:
40320
diff
changeset
|
570 |
fun pr pr' _ [] = tyco' |
b41aabb629ce
constructors to datatypes in code_reflect can be globbed; dropped unused code
haftmann
parents:
40320
diff
changeset
|
571 |
| pr pr' _ [ty] = |
36470 | 572 |
Code_Printer.concat [pr' Code_Printer.BR ty, tyco'] |
40421
b41aabb629ce
constructors to datatypes in code_reflect can be globbed; dropped unused code
haftmann
parents:
40320
diff
changeset
|
573 |
| pr pr' _ tys = |
36470 | 574 |
Code_Printer.concat [Code_Printer.enum "," "(" ")" (map (pr' Code_Printer.BR) tys), tyco'] |
575 |
in |
|
576 |
thy |
|
55150 | 577 |
|> Code_Target.set_printings (Type_Constructor (tyco, [(target, SOME (k, pr))])) |
36470 | 578 |
end; |
579 |
||
36514 | 580 |
fun add_eval_constr (const, const') thy = |
581 |
let |
|
582 |
val k = Code.args_number thy const; |
|
583 |
fun pr pr' fxy ts = Code_Printer.brackify fxy |
|
38922 | 584 |
(const' :: the_list (Code_Printer.tuplify pr' Code_Printer.BR (map fst ts))); |
36514 | 585 |
in |
586 |
thy |
|
55150 | 587 |
|> Code_Target.set_printings (Constant (const, |
52435
6646bb548c6b
migration from code_(const|type|class|instance) to code_printing and from code_module to code_identifier
haftmann
parents:
52434
diff
changeset
|
588 |
[(target, SOME (Code_Printer.simple_const_syntax (k, pr)))])) |
36514 | 589 |
end; |
590 |
||
55150 | 591 |
fun add_eval_const (const, const') = Code_Target.set_printings (Constant |
52435
6646bb548c6b
migration from code_(const|type|class|instance) to code_printing and from code_module to code_identifier
haftmann
parents:
52434
diff
changeset
|
592 |
(const, [(target, SOME (Code_Printer.simple_const_syntax (0, (K o K o K) const')))])); |
36470 | 593 |
|
39912
2ffe7060ca75
avoid antiquotation processing for code_reflect; moved ML_Context.value to Code_Runtime
haftmann
parents:
39816
diff
changeset
|
594 |
fun process_reflection (code, (tyco_map, (constr_map, const_map))) module_name NONE thy = |
38935
2cf3d8305b47
corrected misbehaved additional qualification of generated names
haftmann
parents:
38933
diff
changeset
|
595 |
thy |
2cf3d8305b47
corrected misbehaved additional qualification of generated names
haftmann
parents:
38933
diff
changeset
|
596 |
|> Code_Target.add_reserved target module_name |
63163 | 597 |
|> Context.theory_map (compile_ML true code) |
38935
2cf3d8305b47
corrected misbehaved additional qualification of generated names
haftmann
parents:
38933
diff
changeset
|
598 |
|> fold (add_eval_tyco o apsnd Code_Printer.str) tyco_map |
2cf3d8305b47
corrected misbehaved additional qualification of generated names
haftmann
parents:
38933
diff
changeset
|
599 |
|> fold (add_eval_constr o apsnd Code_Printer.str) constr_map |
2cf3d8305b47
corrected misbehaved additional qualification of generated names
haftmann
parents:
38933
diff
changeset
|
600 |
|> fold (add_eval_const o apsnd Code_Printer.str) const_map |
39912
2ffe7060ca75
avoid antiquotation processing for code_reflect; moved ML_Context.value to Code_Runtime
haftmann
parents:
39816
diff
changeset
|
601 |
| process_reflection (code, _) _ (SOME file_name) thy = |
36470 | 602 |
let |
37950
bc285d91041e
moved basic thy file name operations from Thy_Load to Thy_Header;
wenzelm
parents:
37744
diff
changeset
|
603 |
val preamble = |
46737 | 604 |
"(* Generated from " ^ |
56208 | 605 |
Path.implode (Resources.thy_path (Path.basic (Context.theory_name thy))) ^ |
46737 | 606 |
"; DO NOT EDIT! *)"; |
39912
2ffe7060ca75
avoid antiquotation processing for code_reflect; moved ML_Context.value to Code_Runtime
haftmann
parents:
39816
diff
changeset
|
607 |
val _ = File.write (Path.explode file_name) (preamble ^ "\n\n" ^ code); |
36470 | 608 |
in |
609 |
thy |
|
610 |
end; |
|
611 |
||
612 |
fun gen_code_reflect prep_type prep_const raw_datatypes raw_functions module_name some_file thy = |
|
613 |
let |
|
55757 | 614 |
val ctxt = Proof_Context.init_global thy; |
36470 | 615 |
val datatypes = map (fn (raw_tyco, raw_cos) => |
55757 | 616 |
(prep_type ctxt raw_tyco, (Option.map o map) (prep_const thy) raw_cos)) raw_datatypes; |
40421
b41aabb629ce
constructors to datatypes in code_reflect can be globbed; dropped unused code
haftmann
parents:
40320
diff
changeset
|
617 |
val (tycos, constrs) = map_split (uncurry (check_datatype thy)) datatypes |
b41aabb629ce
constructors to datatypes in code_reflect can be globbed; dropped unused code
haftmann
parents:
40320
diff
changeset
|
618 |
|> apsnd flat; |
36470 | 619 |
val functions = map (prep_const thy) raw_functions; |
58557 | 620 |
val consts = constrs @ functions; |
63159 | 621 |
val program = Code_Thingol.consts_program ctxt consts; |
64959 | 622 |
val result = runtime_code'' ctxt module_name program tycos consts |
36514 | 623 |
|> (apsnd o apsnd) (chop (length constrs)); |
36470 | 624 |
in |
625 |
thy |
|
39485
f7270a5e2550
closures preserve static serializer context for static evaluation; tuned
haftmann
parents:
39482
diff
changeset
|
626 |
|> process_reflection result module_name some_file |
36470 | 627 |
end; |
628 |
||
39422 | 629 |
val code_reflect = gen_code_reflect Code_Target.cert_tyco (K I); |
36470 | 630 |
val code_reflect_cmd = gen_code_reflect Code_Target.read_tyco Code.read_const; |
631 |
||
632 |
||
28054 | 633 |
(** Isar setup **) |
634 |
||
56069
451d5b73f8cf
simplified programming interface to define ML antiquotations -- NB: the transformed context ignores updates of the context parser;
wenzelm
parents:
55757
diff
changeset
|
635 |
val _ = |
64959 | 636 |
Theory.setup (ML_Antiquotation.declaration @{binding code} |
637 |
Args.term (fn _ => ml_code_antiq)); |
|
638 |
||
639 |
val _ = |
|
640 |
Theory.setup (ML_Antiquotation.declaration @{binding computation} |
|
64987 | 641 |
(Scan.repeat Args.term --| Scan.lift (Args.$$$ "::") -- Args.typ) |
642 |
(fn _ => ml_computation_antiq)); |
|
28054 | 643 |
|
36470 | 644 |
local |
645 |
||
36960
01594f816e3a
prefer structure Keyword, Parse, Parse_Spec, Outer_Syntax;
wenzelm
parents:
36610
diff
changeset
|
646 |
val parse_datatype = |
63174
57c0d60e491c
do not export abstract constructors in code_reflect
haftmann
parents:
63164
diff
changeset
|
647 |
Parse.name -- Scan.optional (@{keyword "="} |-- |
40711
81bc73585eec
globbing constant expressions use more idiomatic underscore rather than star
haftmann
parents:
40422
diff
changeset
|
648 |
(((Parse.sym_ident || Parse.string) >> (fn "_" => NONE | _ => Scan.fail ())) |
63174
57c0d60e491c
do not export abstract constructors in code_reflect
haftmann
parents:
63164
diff
changeset
|
649 |
|| ((Parse.term ::: (Scan.repeat (@{keyword "|"} |-- Parse.term))) >> SOME))) (SOME []); |
36470 | 650 |
|
651 |
in |
|
652 |
||
653 |
val _ = |
|
59936
b8ffc3dc9e24
@{command_spec} is superseded by @{command_keyword};
wenzelm
parents:
59633
diff
changeset
|
654 |
Outer_Syntax.command @{command_keyword code_reflect} |
46961
5c6955f487e5
outer syntax command definitions based on formal command_spec derived from theory header declarations;
wenzelm
parents:
46949
diff
changeset
|
655 |
"enrich runtime environment with generated code" |
63174
57c0d60e491c
do not export abstract constructors in code_reflect
haftmann
parents:
63164
diff
changeset
|
656 |
(Parse.name -- Scan.optional (@{keyword "datatypes"} |-- Parse.!!! (parse_datatype |
46949 | 657 |
::: Scan.repeat (@{keyword "and"} |-- parse_datatype))) [] |
52434 | 658 |
-- Scan.optional (@{keyword "functions"} |-- Parse.!!! (Scan.repeat1 Parse.name)) [] |
659 |
-- Scan.option (@{keyword "file"} |-- Parse.!!! Parse.name) |
|
46961
5c6955f487e5
outer syntax command definitions based on formal command_spec derived from theory header declarations;
wenzelm
parents:
46949
diff
changeset
|
660 |
>> (fn (((module_name, raw_datatypes), raw_functions), some_file) => Toplevel.theory |
5c6955f487e5
outer syntax command definitions based on formal command_spec derived from theory header declarations;
wenzelm
parents:
46949
diff
changeset
|
661 |
(code_reflect_cmd raw_datatypes raw_functions module_name some_file))); |
36470 | 662 |
|
663 |
end; (*local*) |
|
664 |
||
39816
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
665 |
|
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
666 |
(** using external SML files as substitute for proper definitions -- only for polyml! **) |
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
667 |
|
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
668 |
local |
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
669 |
|
39820 | 670 |
structure Loaded_Values = Theory_Data |
671 |
( |
|
39816
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
672 |
type T = string list |
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
673 |
val empty = [] |
41472
f6ab14e61604
misc tuning and comments based on review of Theory_Data, Proof_Data, Generic_Data usage;
wenzelm
parents:
41376
diff
changeset
|
674 |
val extend = I |
39820 | 675 |
fun merge data : T = Library.merge (op =) data |
39816
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
676 |
); |
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
677 |
|
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
678 |
fun notify_val (string, value) = |
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
679 |
let |
62495 | 680 |
val _ = #enterVal ML_Env.name_space (string, value); |
53171 | 681 |
val _ = Theory.setup (Loaded_Values.map (insert (op =) string)); |
39816
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
682 |
in () end; |
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
683 |
|
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
684 |
fun abort _ = error "Only value bindings allowed."; |
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
685 |
|
62494 | 686 |
val notifying_context : ML_Compiler0.context = |
62354 | 687 |
{name_space = |
62495 | 688 |
{lookupVal = #lookupVal ML_Env.name_space, |
689 |
lookupType = #lookupType ML_Env.name_space, |
|
690 |
lookupFix = #lookupFix ML_Env.name_space, |
|
691 |
lookupStruct = #lookupStruct ML_Env.name_space, |
|
692 |
lookupSig = #lookupSig ML_Env.name_space, |
|
693 |
lookupFunct = #lookupFunct ML_Env.name_space, |
|
39816
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
694 |
enterVal = notify_val, |
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
695 |
enterType = abort, |
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
696 |
enterFix = abort, |
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
697 |
enterStruct = abort, |
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
698 |
enterSig = abort, |
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
699 |
enterFunct = abort, |
62495 | 700 |
allVal = #allVal ML_Env.name_space, |
701 |
allType = #allType ML_Env.name_space, |
|
702 |
allFix = #allFix ML_Env.name_space, |
|
703 |
allStruct = #allStruct ML_Env.name_space, |
|
704 |
allSig = #allSig ML_Env.name_space, |
|
705 |
allFunct = #allFunct ML_Env.name_space}, |
|
62716
d80b9f4990e4
explicit print_depth for the sake of Spec_Check.determine_type;
wenzelm
parents:
62607
diff
changeset
|
706 |
print_depth = NONE, |
62495 | 707 |
here = #here ML_Env.context, |
708 |
print = #print ML_Env.context, |
|
709 |
error = #error ML_Env.context}; |
|
39816
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
710 |
|
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
711 |
in |
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
712 |
|
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
713 |
fun use_file filepath thy = |
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
714 |
let |
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
715 |
val thy' = Loaded_Values.put [] thy; |
62889 | 716 |
val _ = Context.put_generic_context ((SOME o Context.Theory) thy'); |
60956 | 717 |
val _ = |
62902
3c0f53eae166
more conventional theory syntax for ML bootstrap, with 'ML_file' instead of 'use';
wenzelm
parents:
62889
diff
changeset
|
718 |
ML_Compiler0.ML notifying_context |
60956 | 719 |
{line = 0, file = Path.implode filepath, verbose = false, debug = false} |
720 |
(File.read filepath); |
|
62876 | 721 |
val thy'' = Context.the_global_context (); |
39912
2ffe7060ca75
avoid antiquotation processing for code_reflect; moved ML_Context.value to Code_Runtime
haftmann
parents:
39816
diff
changeset
|
722 |
val names = Loaded_Values.get thy''; |
40320
abc52faa7761
polyml_as_definition does not require explicit dependencies on external ML files
haftmann
parents:
40257
diff
changeset
|
723 |
in (names, thy'') end; |
39816
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
724 |
|
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
725 |
end; |
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
726 |
|
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
727 |
fun add_definiendum (ml_name, (b, T)) thy = |
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
728 |
thy |
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
729 |
|> Code_Target.add_reserved target ml_name |
63178 | 730 |
|> Specification.axiomatization [(b, SOME T, NoSyn)] [] [] [] |
39816
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
731 |
|-> (fn ([Const (const, _)], _) => |
55150 | 732 |
Code_Target.set_printings (Constant (const, |
52435
6646bb548c6b
migration from code_(const|type|class|instance) to code_printing and from code_module to code_identifier
haftmann
parents:
52434
diff
changeset
|
733 |
[(target, SOME (Code_Printer.simple_const_syntax (0, (K o K o K o Code_Printer.str) ml_name)))])) |
64940
19ca3644ec46
experimental computations: use arbitrary generated code for RHSs, not just constants
haftmann
parents:
64928
diff
changeset
|
734 |
#> tap (fn thy => Code_Target.produce_code (Proof_Context.init_global thy) false [const] target NONE Code_Target.generatedN [])); |
39816
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
735 |
|
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
736 |
fun process_file filepath (definienda, thy) = |
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
737 |
let |
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
738 |
val (ml_names, thy') = use_file filepath thy; |
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
739 |
val superfluous = subtract (fn ((name1, _), name2) => name1 = name2) definienda ml_names; |
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
740 |
val _ = if null superfluous then () |
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
741 |
else error ("Value binding(s) " ^ commas_quote superfluous |
41944
b97091ae583a
Path.print is the official way to show file-system paths to users -- note that Path.implode often indicates violation of the abstract datatype;
wenzelm
parents:
41486
diff
changeset
|
742 |
^ " found in external file " ^ Path.print filepath |
39816
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
743 |
^ " not present among the given contants binding(s)."); |
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
744 |
val these_definienda = AList.make (the o AList.lookup (op =) definienda) ml_names; |
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
745 |
val thy'' = fold add_definiendum these_definienda thy'; |
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
746 |
val definienda' = fold (AList.delete (op =)) ml_names definienda; |
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
747 |
in (definienda', thy'') end; |
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
748 |
|
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
749 |
fun polyml_as_definition bTs filepaths thy = |
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
750 |
let |
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
751 |
val definienda = map (fn bT => ((Binding.name_of o fst) bT, bT)) bTs; |
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
752 |
val (remaining, thy') = fold process_file filepaths (definienda, thy); |
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
753 |
val _ = if null remaining then () |
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
754 |
else error ("Constant binding(s) " ^ commas_quote (map fst remaining) |
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
755 |
^ " not present in external file(s)."); |
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
756 |
in thy' end; |
c7cec137c48a
added polyml_as_definition -- using external SML files as substitute for proper definitions -- only for polyml!
haftmann
parents:
39605
diff
changeset
|
757 |
|
28054 | 758 |
end; (*struct*) |