forked from CakeML/cakeml
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cfStoreScript.sml
215 lines (187 loc) · 6.42 KB
/
cfStoreScript.sml
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
(*
Conversion from semantic stores to heaps.
*)
open preamble
open set_sepTheory helperLib ConseqConv
open semanticPrimitivesTheory ml_translatorTheory
open cfHeapsTheory cfHeapsBaseLib
val _ = temp_delsimps ["lift_disj_eq", "lift_imp_disj"]
val _ = new_theory "cfStore"
(* Definitions *)
val store2heap_aux_def = Define `
store2heap_aux n [] = ({}: heap) /\
store2heap_aux n (v :: t) = (Mem n v) INSERT (store2heap_aux (n+1: num) t)`
(* store2heap: v store -> heap *)
val store2heap_def = Define `store2heap l = store2heap_aux (0: num) l`
val ffi_has_index_in_def = Define `
ffi_has_index_in ns (IO_event (ExtCall i) conf ws) = (MEM i ns) /\
ffi_has_index_in _ _ = F`;
val parts_ok_def = Define `
parts_ok st ((proj,parts):'ffi ffi_proj) <=>
ALL_DISTINCT (FLAT (MAP FST parts)) /\
EVERY (ffi_has_index_in (FLAT (MAP FST parts))) st.io_events /\
(!ns u.
MEM (ns,u) parts ==>
?s. !n. MEM n ns ==> FLOOKUP (proj st.ffi_state) n = SOME s) /\
(!x conf bytes m ns u.
MEM (ns,u) parts /\ MEM m ns /\
u m conf bytes (proj x ' m) = SOME FFIdiverge ==>
st.oracle (ExtCall m) x conf bytes = Oracle_final(FFI_diverged)) /\
!x conf bytes w new_bytes m ns u.
MEM (ns,u) parts /\ MEM m ns /\
u m conf bytes (proj x ' m) = SOME(FFIreturn new_bytes w) ==>
LENGTH new_bytes = LENGTH bytes /\
?y.
st.oracle (ExtCall m) x conf bytes = Oracle_return y new_bytes /\
proj x |++ (MAP (\n. (n,w)) ns) = proj y`
val ffi2heap_def = Define `
ffi2heap ((proj,parts):'ffi ffi_proj) st =
if parts_ok st (proj,parts) then
FFI_split INSERT
{ FFI_part s u ns ts |
MEM (ns,u) parts /\ ns <> [] /\
ts = FILTER (ffi_has_index_in ns) st.io_events /\
!n. MEM n ns ==> FLOOKUP (proj st.ffi_state) n = SOME s }
else
{ FFI_full st.io_events }`;
(* st2heap: 'ffi state -> heap *)
val st2heap_def = Define `
st2heap (f:'ffi ffi_proj) (st: 'ffi semanticPrimitives$state) =
store2heap st.refs UNION ffi2heap f st.ffi`
(* Lemmas *)
Theorem store2heap_aux_append:
!s n x.
store2heap_aux n (s ++ [x]) =
(Mem (LENGTH s + n) x) INSERT store2heap_aux n s
Proof
Induct THENL [all_tac, Cases] \\ fs [store2heap_aux_def, INSERT_COMM]
\\ fs [DECIDE ``(LENGTH s + 1) = SUC (LENGTH s)``]
QED
Theorem store2heap_append:
!s x. store2heap (s ++ [x]) = Mem (LENGTH s) x INSERT store2heap s
Proof
fs [store2heap_def, store2heap_aux_append]
QED
Theorem store2heap_aux_suc:
!s n u v.
(Mem u v IN store2heap_aux n s) =
(Mem (SUC u) v IN store2heap_aux (SUC n) s)
Proof
Induct
THEN1 (strip_tac \\ fs [store2heap_def, store2heap_aux_def])
THEN1 (
Cases \\
once_rewrite_tac [store2heap_aux_def] \\ rpt strip_tac \\
pop_assum (qspecl_then [`n+1`, `u`, `v`] assume_tac) \\
fs [DECIDE ``SUC n + 1 = SUC (n + 1)``]
)
QED
Theorem store2heap_aux_IN_bound:
!s n u v. Mem u v IN store2heap_aux n s ==> (u >= n)
Proof
Induct THENL [all_tac, Cases] \\ fs [store2heap_aux_def] \\
rpt strip_tac \\ fs [] \\ first_assum (qspecl_then [`n+1`, `u`, `v`] drule) \\
rw_tac arith_ss []
QED
Theorem store2heap_alloc_disjoint:
!s x. ~ (Mem (LENGTH s) x IN (store2heap s))
Proof
Induct
THEN1 (strip_tac \\ fs [store2heap_def, store2heap_aux_def])
THEN1 (
Cases \\ fs [store2heap_def, store2heap_aux_def] \\
rewrite_tac [ONE] \\
fs [GSYM store2heap_aux_suc]
)
QED
Theorem store2heap_IN_LENGTH:
!s r x. Mem r x IN (store2heap s) ==> r < LENGTH s
Proof
Induct THENL [all_tac, Cases] \\
fs [store2heap_def, store2heap_aux_def] \\
Cases_on `r` \\ fs [] \\ rewrite_tac [ONE] \\
rpt strip_tac \\ fs [GSYM store2heap_aux_suc] \\ metis_tac []
QED
val tac_store2heap_IN =
Induct THENL [all_tac, Cases] \\ fs [store2heap_def, store2heap_aux_def] \\
Cases_on `r` \\ fs [] \\
rewrite_tac [ONE] \\ rpt strip_tac \\
fs [GSYM store2heap_aux_suc] \\ TRY (metis_tac []) \\
qspecl_then [`s`, `1`, `0`, `x'`] drule store2heap_aux_IN_bound \\
rw_tac arith_ss []
Theorem store2heap_IN_EL:
!s r x. Mem r x IN (store2heap s) ==> EL r s = x
Proof
tac_store2heap_IN
QED
Theorem store2heap_IN_unique_key:
!s r x.
Mem r x IN (store2heap s) ==>
!x'. Mem r x' IN (store2heap s) ==> x = x'
Proof
tac_store2heap_IN
QED
Theorem Mem_NOT_IN_ffi2heap:
~(Mem rv x IN ffi2heap (p:'ffi ffi_proj) f)
Proof
PairCases_on `p` \\ fs [ffi2heap_def] \\ rw []
QED
Theorem FFI_split_NOT_IN_store2heap_aux:
∀n s. FFI_split ∉ store2heap_aux n s
Proof
Induct_on `s` \\ fs [store2heap_aux_def]
QED
Theorem FFI_part_NOT_IN_store2heap_aux:
∀n s. FFI_part x1 x2 x3 x4 ∉ store2heap_aux n s
Proof
Induct_on `s` \\ fs [store2heap_aux_def]
QED
Theorem FFI_full_NOT_IN_store2heap_aux:
∀n s. FFI_full x1 ∉ store2heap_aux n s
Proof
Induct_on `s` \\ fs [store2heap_aux_def]
QED
Theorem FFI_part_NOT_IN_store2heap:
!s. ~(FFI_split ∈ store2heap s) /\
~(FFI_part x1 x2 x3 x4 ∈ store2heap s) /\
~(FFI_full y2 ∈ store2heap s)
Proof
fs [store2heap_def,FFI_part_NOT_IN_store2heap_aux,
FFI_full_NOT_IN_store2heap_aux,FFI_split_NOT_IN_store2heap_aux]
QED
Theorem store2heap_LUPDATE:
!s r x y.
Mem r y IN (store2heap s) ==>
store2heap (LUPDATE x r s) = Mem r x INSERT ((store2heap s) DELETE Mem r y)
Proof
Induct \\
fs [store2heap_def, store2heap_aux_def] \\
Cases_on `r` \\ qx_genl_tac [`v`, `x`, `y`] \\
qspecl_then [`s`, `1`, `0`, `y`] assume_tac store2heap_aux_IN_bound \\
fs [LUPDATE_def, INSERT_DEF, DELETE_DEF, EXTENSION, store2heap_aux_def]
THEN1 (metis_tac []) \\
strip_tac \\ qx_gen_tac `u` \\
Cases_on `u = Mem 0 v` \\ fs [] \\ Cases_on `u`
\\ fs [FFI_split_NOT_IN_store2heap_aux,
FFI_part_NOT_IN_store2heap_aux,
FFI_full_NOT_IN_store2heap_aux]
THEN1 (
rename1 `m <> 0n` \\ Cases_on `m` \\ fs [] \\
qpat_x_assum `_ IN _` mp_tac \\
rewrite_tac [ONE, GSYM store2heap_aux_suc] \\ rpt strip_tac \\
first_assum drule \\
disch_then (qspecl_then [`x`, `Mem n' s'`] assume_tac) \\ fs [])
THEN1 (
Cases_on `n'` \\ fs []
THEN1 (eq_tac \\ rw [] \\ imp_res_tac store2heap_aux_IN_bound \\ fs []) \\
qpat_x_assum `_ IN _` mp_tac \\
rewrite_tac [ONE, GSYM store2heap_aux_suc] \\ rpt strip_tac \\
first_assum drule \\
disch_then (qspecl_then [`x`, `Mem n'' s'`] assume_tac) \\ fs [])
QED
Theorem st2heap_clock:
!st ck. st2heap (p:'ffi ffi_proj) (st with clock := ck) = st2heap p st
Proof
fs [st2heap_def]
QED
val _ = export_theory ()