Repository navigation
Expand file tree
/
Copy pathrepl_initScript.sml
More file actions
380 lines (357 loc) · 15.4 KB
/
Copy pathrepl_initScript.sml
File metadata and controls
380 lines (357 loc) · 15.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
(*
Proves repl_types for the initial env and types from which the REPL starts.
*)
Theory repl_init
Ancestors
ml_prog repl_types basis_ffi repl_init_envProg repl_moduleProg
repl_init_types repl_inputRepresentation
Libs
preamble ml_progLib helperLib
val _ = Parse.hide "types"
val _ = (max_print_depth := 12);
val th2 = Decls_repl_prog |> REWRITE_RULE [GSYM repl_prog_def,SNOC]
|> CONV_RULE (RAND_CONV EVAL)
|> Q.GEN ‘ffi’ |> Q.ISPEC ‘basis_ffi ext cl fs’
|> REWRITE_RULE (APPEND::(DB.find "refs_def" |> map (#1 o #2)))
Overload repl_prog_env = (th2 |> concl |> rator |> rand);
Definition repl_prog_st_def:
repl_prog_st ext cl fs = ^(th2 |> concl |> rand)
End
val th2 = REWRITE_RULE [GSYM repl_prog_st_def] th2;
Theorem repl_prog_st_input:
repl_prog_st ext cl fs = input_repl_state (basis_ffi ext cl fs)
Proof
simp [repl_prog_st_def,repl_inputInitTheory.input_repl_state_def] >>
EVAL_TAC >>
simp (APPEND :: (DB.find "refs_def" |> map (#1 o #2)))
QED
Theorem merge_env_intro:
extend_dec_env = merge_env
Proof
fs [FUN_EQ_THM,semanticPrimitivesTheory.extend_dec_env_def,merge_env_def]
QED
Definition the_Loc_def:
the_Loc (semanticPrimitives$Loc _ n) = n
End
Overload repl_init_env =
(repl_init_envProg_env_def |> concl
|> find_term (can (match_term “Env _”)) |> rand);
Theorem repl_init_env_input:
repl_init_env = repl_init_types$repl_prog_env
Proof
simp [repl_init_typesTheory.repl_prog_env_def]
QED
Theorem evaluate_decs_append: (* TODO: move to evaluateProps *)
∀xs ys st env.
evaluate_decs st env (xs ++ ys) =
case evaluate_decs st env xs of
| (st1,Rerr e) => (st1,Rerr e)
| (st1,Rval env1) =>
case evaluate_decs st1 (extend_dec_env env1 env) ys of
| (st2,r) => (st2,combine_dec_result env1 r)
Proof
Induct \\ fs [evaluateTheory.evaluate_decs_def,
semanticPrimitivesTheory.extend_dec_env_def]
>- (rw [] \\ CASE_TAC \\ Cases_on ‘r’
\\ fs [semanticPrimitivesTheory.combine_dec_result_def])
\\ once_rewrite_tac [evaluatePropsTheory.evaluate_decs_cons]
\\ rw [] \\ CASE_TAC \\ fs []
\\ rw [] \\ CASE_TAC \\ fs []
\\ rw [] \\ CASE_TAC \\ fs []
\\ rw [] \\ CASE_TAC \\ fs [semanticPrimitivesTheory.combine_dec_result_def]
\\ fs [semanticPrimitivesTheory.extend_dec_env_def]
\\ CASE_TAC \\ fs []
\\ CASE_TAC \\ fs []
QED
Theorem app_frame[local]:
app p f xs P Q ⇒ ∀H. app p f xs (P * H) (Q *+ H)
Proof
rw []
\\ drule_then irule cfAppTheory.app_wgframe
\\ qexists_tac ‘H’ \\ fs []
\\ fs [set_sepTheory.SEP_IMP_REFL,cfHeapsBaseTheory.SEP_IMPPOST_def]
\\ Cases
\\ fs [cfHeapsBaseTheory.STARPOST_def]
\\ irule (cfHeapsBaseTheory.SEP_IMP_frame_single_l
|> ONCE_REWRITE_RULE [set_sepTheory.STAR_COMM])
\\ fs [set_sepTheory.SEP_IMP_def,set_sepTheory.emp_def,cfHeapsBaseTheory.GC_def]
\\ rw [set_sepTheory.SEP_EXISTS_THM]
\\ qexists_tac ‘K T’ \\ fs []
QED
Theorem app_frame_POSTv[local]:
app p f xs P ($POSTv Q) ⇒ ∀H. app p f xs (P * H) (POSTv v. Q v * H)
Proof
rw [] \\ drule_then (qspec_then ‘H’ mp_tac) app_frame
\\ match_mp_tac (METIS_PROVE [] “b=c ⇒ b ⇒ c”)
\\ AP_TERM_TAC
\\ fs [FUN_EQ_THM,cfHeapsBaseTheory.POSTv_def]
\\ fs [cfHeapsBaseTheory.POST_def]
\\ fs [cfHeapsBaseTheory.STARPOST_def]
\\ Cases \\ fs [set_sepTheory.SEP_CLAUSES]
QED
Theorem CommandLine_arguments_lemma[local] =
CommandLineProofTheory.CommandLine_arguments_spec
|> Q.GEN ‘uv’
|> SIMP_RULE std_ss [ml_translatorTheory.UNIT_TYPE_def]
|> MATCH_MP app_frame_POSTv
|> Q.ISPEC ‘STDIO fs’
|> SIMP_RULE (srw_ss()++helperLib.sep_cond_ss)
[cfAppTheory.app_def,cfAppTheory.app_basic_def,
cfDivTheory.POSTv_eq,PULL_EXISTS,set_sepTheory.cond_STAR,
cfAppTheory.evaluate_to_heap_def]
|> SIMP_RULE std_ss [AC set_sepTheory.STAR_ASSOC set_sepTheory.STAR_COMM]
|> Q.GEN ‘p’ |> Q.ISPEC ‘(basis_proj1, basis_proj2)’ |> SPEC_ALL;
Theorem Repl_charsFrom_lemma[local] =
charsFrom_spec |> UNDISCH
|> MATCH_MP app_frame_POSTv
|> Q.ISPEC ‘COMMANDLINE cl’
|> SIMP_RULE (srw_ss()++helperLib.sep_cond_ss)
[cfAppTheory.app_def,cfAppTheory.app_basic_def,
cfDivTheory.POSTv_eq,PULL_EXISTS,set_sepTheory.cond_STAR,
cfAppTheory.evaluate_to_heap_def]
|> SIMP_RULE std_ss [AC set_sepTheory.STAR_ASSOC set_sepTheory.STAR_COMM]
|> Q.GEN ‘p’ |> Q.ISPEC ‘(basis_proj1, basis_proj2)’ |> SPEC_ALL
|> DISCH_ALL |> REWRITE_RULE [AND_IMP_INTRO,GSYM CONJ_ASSOC]
|> Q.GEN ‘fname’ |> Q.SPEC ‘«config_enc_str.txt»’
|> REWRITE_RULE [GSYM AND_IMP_INTRO]
|> UNDISCH |> UNDISCH
|> Q.GEN ‘fnamev’ |> SIMP_RULE std_ss [EVAL “FILENAME «config_enc_str.txt» fnamev”]
|> DISCH_ALL |> REWRITE_RULE [AND_IMP_INTRO,GSYM CONJ_ASSOC];
Theorem repl_types_clock:
repl_types catalogue slots T x (types,s,env) ==>
!k. repl_types catalogue slots T x (types,s with clock := s.clock - k,env)
Proof
rw [] >> PairCases_on `x` >>
drule_then irule repl_types_skip_alt >> gs []
QED
Theorem repl_types_refs:
repl_types catalogue slots T x (types,s,env) ==>
!junk. repl_types catalogue slots T x (types,s with refs := s.refs ++ junk,env)
Proof
rw [] >> PairCases_on `x` >>
drule_then irule repl_types_skip_alt >> gs []
QED
Theorem extend_dec_env_empty:
extend_dec_env <|v := nsEmpty; c := nsEmpty|> env = env
Proof
EVAL_TAC
\\ fs [semanticPrimitivesTheory.sem_env_component_equality]
\\ Cases_on ‘env.v’ \\ Cases_on ‘env.c’
\\ fs [namespaceTheory.nsAppend_def]
QED
Theorem parts_ok_basis_ffi:
parts_ok (basis_ffi ext cls fs) (basis_proj1,basis_proj2)
Proof
mp_tac basis_ffiTheory.parts_ok_basis_st
\\ fs (DB.find "TextIOProg_st" |> map (#1 o #2))
QED
Theorem st2heap_basis:
wfcl cl ∧ wfFS fs ∧ STD_streams fs ∧
(repl_prog_st ext cl fs).refs ≼ st.refs ∧
(repl_prog_st ext cl fs).ffi = st.ffi ⇒
∃h_i h_k.
SPLIT (st2heap (basis_proj1,basis_proj2) st) (h_i,h_k) ∧
(COMMANDLINE cl * STDIO fs) h_i
Proof
rw []
\\ qsuff_tac ‘∃h_i.
h_i SUBSET st2heap (basis_proj1,basis_proj2) st ∧
(COMMANDLINE cl * STDIO fs) h_i’
>- (rw [] \\ pop_assum $ irule_at Any
\\ rename [‘SPLIT xx’] \\ qexists_tac ‘xx DIFF h_i’
\\ fs [SUBSET_DEF,set_sepTheory.SPLIT_def,IN_DISJOINT,EXTENSION] \\ metis_tac [])
\\ fs [set_sepTheory.STAR_def,PULL_EXISTS]
\\ drule_at Any (DISCH_ALL STDIO_precond |> REWRITE_RULE [AND_IMP_INTRO])
\\ disch_then (drule_at Any)
\\ fs (DB.find "refs_def" |> map (#1 o #2))
\\ disch_then $ irule_at Any
\\ fs [CommandLineProofTheory.COMMANDLINE_def,set_sepTheory.cond_STAR]
\\ fs [clFFITheory.cl_ffi_part_def]
\\ fs [cfHeapsBaseTheory.IOx_def]
\\ fs [cfHeapsBaseTheory.IO_def]
\\ fs [GSYM clFFITheory.cl_ffi_part_def]
\\ fs [set_sepTheory.SEP_EXISTS_THM,PULL_EXISTS,set_sepTheory.cond_STAR]
\\ fs [set_sepTheory.one_def]
\\ fs [set_sepTheory.SPLIT_def,PULL_EXISTS]
\\ fs [EVAL “MAP FST (SND (SND fs_ffi_part))”]
\\ qmatch_goalsub_abbrev_tac ‘Mem rr’
\\ ‘∃v. LENGTH v ≥ 2052 ∧ Mem rr (W8array v) ∈ st2heap (basis_proj1,basis_proj2) st’ by
(unabbrev_all_tac
\\ fs [cfStoreTheory.st2heap_def,cfStoreTheory.store2heap_def]
\\ fs [repl_prog_st_def]
\\ every_case_tac \\ fs []
\\ gvs []
\\ qmatch_goalsub_abbrev_tac ‘_ :: W8array (_::ys) :: _’
\\ qexists_tac ‘0w::ys’ \\ fs [EVAL “store2heap_aux 0 (W8array x :: xs)”]
\\ unabbrev_all_tac \\ EVAL_TAC)
\\ rpt (pop_assum $ irule_at Any)
\\ fs [cfStoreTheory.st2heap_def,cfAppTheory.FFI_part_NOT_IN_store2heap]
\\ simp [cfStoreTheory.ffi2heap_def]
\\ unabbrev_all_tac
\\ pop_assum mp_tac
\\ simp [repl_prog_st_def]
\\ disch_then (assume_tac o GSYM) \\ fs [parts_ok_basis_ffi]
\\ fs [basis_proj2_def,SF DNF_ss]
\\ fs [basis_proj1_def,SF DNF_ss]
\\ Cases_on ‘(basis_ffi ext cl fs).ffi_state’ \\ fs []
\\ fs [basis_ffi_def]
\\ EVAL_TAC
QED
Theorem repl_types_repl_prog:
Prog init_env
(init_state (basis_ffi ext cl fs) with
eval_state := SOME (EvalDecs (s with env_id_counter := ns))) xs env
st ∧
evaluate_decs
(init_state (basis_ffi ext cl fs) with
<|clock := ck; eval_state := SOME (EvalDecs s)|>) init_env (xs ++ ys) =
(s1,res) ∧ s.env_id_counter = ns ∧ repl_prog ≼ xs ∧
prog_syntax_ok repl_prog ∧
(repl_prog_st ext cl fs).refs ≼ st.refs ∧
(repl_prog_st ext cl fs).next_type_stamp ≤ st.next_type_stamp ∧
(repl_prog_st ext cl fs).next_exn_stamp ≤ st.next_exn_stamp ∧
st.ffi = (repl_prog_st ext cl fs).ffi ∧ wfcl cl ∧ wfFS fs ∧ STD_streams fs ∧
hasFreeFD fs ∧ file_content fs «config_enc_str.txt» = SOME content
⇒
res = Rerr (Rabort Rtimeout_error) ∨
∃ck1 r1 env_cl e_cl s_cl res_cl.
evaluate_decs (st with clock := ck1) (merge_env env init_env) ys =
(s1,r1) ∧ combine_dec_result env r1 = res ∧
repl_types repl_input_catalogue repl_input_slots T
(basis_ffi ext cl fs,repl_rs)
(repl_prog_types,st with <|eval_state := NONE; clock := ck1|>,
repl_init_env) ∧
do_opapp [CommandLine_arguments_v; Conv NONE []] = SOME (env_cl,e_cl) ∧
evaluate (st with <|eval_state := NONE; clock := ck1 − entry_cost|>) env_cl
[e_cl] = (s_cl,res_cl) ∧
(res_cl ≠ Rerr (Rabort Rtimeout_error) ⇒
∃cl_v.
LIST_TYPE STRING_TYPE (TL cl) cl_v ∧ res_cl = Rval [cl_v] ∧
∀ck junk. ∃env_pr e_pr res_pr s_pr.
do_opapp [Repl_charsFrom_v; Litv (StrLit «config_enc_str.txt»)] =
SOME (env_pr,e_pr) ∧
evaluate
(s_cl with
<|clock := s_cl.clock − (ck + 3); refs := s_cl.refs ++ junk|>)
env_pr [e_pr] = (s_pr,res_pr) ∧
(res_pr ≠ Rerr (Rabort Rtimeout_error) ⇒
∃pr_v.
res_pr = Rval [pr_v] ∧ LIST_TYPE CHAR content pr_v ∧
repl_types repl_input_catalogue repl_input_slots T
(basis_ffi ext cl fs,repl_rs)
(repl_prog_types,s_pr,repl_init_env)))
Proof
rpt strip_tac
\\ gvs [evaluate_decs_append,merge_env_intro]
\\ ‘(s with env_id_counter := s.env_id_counter) = s’ by
fs [semanticPrimitivesTheory.eval_decs_state_component_equality]
\\ fs [] \\ pop_assum kall_tac
\\ qabbrev_tac ‘st4 = init_state (basis_ffi ext cl fs) with eval_state := SOME (EvalDecs s)’
\\ qpat_x_assum ‘Prog init_env st4 _ _ _’ mp_tac
\\ simp [Once Prog_def] \\ strip_tac
\\ qmatch_asmsub_rename_tac
`evaluate_decs (st4 with clock := initial_clock) init_env xs =
(st with clock := final_clock,Rval env)`
\\ Cases_on ‘res = Rerr (Rabort Rtimeout_error)’ \\ fs []
\\ namedCases_on `evaluate_decs (st4 with clock := ck) init_env xs`
["prefix_state prefix_result"] \\ gvs []
\\ Cases_on `prefix_result = Rerr (Rabort Rtimeout_error)` >- gvs []
\\ dxrule evaluatePropsTheory.evaluate_decs_add_to_clock
\\ dxrule evaluatePropsTheory.evaluate_decs_add_to_clock
\\ fs []
\\ disch_then (qspec_then ‘ck’ assume_tac)
\\ disch_then (qspec_then `initial_clock` assume_tac)
\\ gvs []
\\ `prefix_state = st with clock := prefix_state.clock` by gvs [semanticPrimitivesTheory.state_component_equality]
\\ qpat_x_assum ‘_ = (s1,res)’ mp_tac
\\ pop_assum (once_rewrite_tac o single)
\\ CASE_TAC \\ strip_tac \\ gvs []
\\ qexists_tac `prefix_state.clock` \\ fs []
\\ simp [GSYM PULL_EXISTS]
\\ conj_asm1_tac >- (
qmatch_goalsub_rename_tac `st with <|clock := prefix_state.clock; eval_state := NONE|>` >>
mp_tac (Q.ISPECL [`T`,`basis_ffi ext cl fs`] repl_input_initial_reachable) >>
rewrite_tac [GSYM repl_prog_st_input,GSYM repl_init_env_input] >>
strip_tac >> drule repl_types_set_clock >>
disch_then (qspec_then `prefix_state.clock` assume_tac) >>
irule repl_types_skip_alt >>
qexists_tac `repl_prog_st ext cl fs with clock := prefix_state.clock` >>
simp [] >> simp [repl_prog_st_def])
\\ qmatch_goalsub_abbrev_tac ‘evaluate s12’
\\ ‘∃h_i h_k.
SPLIT (st2heap (basis_proj1,basis_proj2) s12) (h_i,h_k) ∧
(COMMANDLINE cl * STDIO fs) h_i’ by
(fs [cfStoreTheory.st2heap_def,Abbr‘s12’]
\\ qpat_x_assum ‘st.ffi = _’ (assume_tac o GSYM)
\\ fs [GSYM cfStoreTheory.st2heap_def]
\\ drule_all st2heap_basis
\\ strip_tac \\ first_x_assum $ irule_at $ Pos hd \\ fs [])
\\ drule_all CommandLine_arguments_lemma
\\ strip_tac \\ fs []
\\ fs [cfAppTheory.evaluate_ck_def]
\\ qmatch_asmsub_rename_tac
`evaluate (s12 with clock := command_clock) command_env [command_exp] =
(command_state,Rval [command_value])`
\\ qmatch_asmsub_rename_tac
`SPLIT (st2heap (basis_proj1,basis_proj2) s12) (initial_io_heap,frame_heap)`
\\ qmatch_asmsub_rename_tac
`SPLIT3 (st2heap (basis_proj1,basis_proj2) command_state)
(command_io_heap,frame_heap,command_junk_heap)`
\\ drule evaluatePropsTheory.evaluate_set_init_clock \\ fs []
\\ disch_then $ qspec_then ‘s12.clock’ mp_tac \\ fs []
\\ strip_tac \\ gvs []
\\ rpt gen_tac
\\ qmatch_goalsub_abbrev_tac ‘evaluate s13’
\\ drule Repl_charsFrom_lemma \\ simp []
\\ `?h1 h2. SPLIT (st2heap (basis_proj1,basis_proj2) s13) (h1,h2) /\
(COMMANDLINE cl * STDIO fs) h1`
by (
qpat_x_assum `SPLIT3 _ _` mp_tac \\ unabbrev_all_tac
\\ qpat_x_assum `(COMMANDLINE cl * STDIO fs) command_io_heap` mp_tac
\\ rpt (pop_assum kall_tac)
\\ fs [cfStoreTheory.st2heap_def,cfAppTheory.store2heap_append_many]
\\ rename [‘x ∪ y ∪ z’]
\\ fs [set_sepTheory.SPLIT_def,cfHeapsBaseTheory.SPLIT3_def]
\\ rw [] \\ last_x_assum $ irule_at $ Pos last
\\ qexists_tac `(frame_heap UNION command_junk_heap UNION y) DIFF command_io_heap`
\\ fs [UNION_ASSOC]
\\ fs [IN_DISJOINT,EXTENSION] \\ metis_tac [])
\\ disch_then drule_all
\\ strip_tac \\ fs []
\\ fs [cfAppTheory.evaluate_ck_def]
\\ drule evaluatePropsTheory.evaluate_set_init_clock \\ fs []
\\ qmatch_asmsub_rename_tac
`evaluate (s13 with clock := config_clock) config_env [config_exp] =
(config_state,Rval [config_value])`
\\ disch_then $ qspec_then ‘s13.clock’ mp_tac \\ fs []
\\ strip_tac \\ gvs []
\\ drule_then (qspec_then ‘1’ assume_tac) repl_types_clock \\ gvs []
\\ assume_tac infertype_prog_inc_CommandLine_arguments
\\ drule_then (qspec_then `command_clock+1` assume_tac) repl_types_set_clock
\\ drule_then drule repl_types_eval \\ fs []
\\ pop_assum kall_tac
\\ simp [evaluateTheory.evaluate_decs_def,astTheory.pat_bindings_def]
\\ simp [evaluateTheory.evaluate_def,
semanticPrimitivesTheory.check_exp_constructors_def,
semanticPrimitivesTheory.do_con_check_def]
\\ simp [semanticPrimitivesTheory.build_conv_def]
\\ CONV_TAC (DEPTH_CONV ml_progLib.nsLookup_conv) \\ simp []
\\ fs [evaluateTheory.dec_clock_def,semanticPrimitivesTheory.pmatch_def,
extend_dec_env_empty,Abbr‘s12’]
\\ strip_tac
\\ drule_then (qspec_then ‘junk’ assume_tac) repl_types_refs \\ fs []
\\ drule_then (qspec_then `config_clock+1` assume_tac) repl_types_set_clock
\\ assume_tac infertype_prog_inc_Repl_charsFrom
\\ drule_then drule repl_types_eval \\ fs []
\\ pop_assum kall_tac
\\ simp [evaluateTheory.evaluate_decs_def,astTheory.pat_bindings_def]
\\ simp [evaluateTheory.evaluate_def,
semanticPrimitivesTheory.check_exp_constructors_def,
semanticPrimitivesTheory.do_con_check_def]
\\ CONV_TAC (DEPTH_CONV ml_progLib.nsLookup_conv) \\ simp []
\\ fs [evaluateTheory.dec_clock_def,semanticPrimitivesTheory.pmatch_def,
extend_dec_env_empty,Abbr‘s13’]
\\ strip_tac
\\ irule repl_types_set_clock
\\ asm_rewrite_tac []
QED