-
Notifications
You must be signed in to change notification settings - Fork 1
/
SoundInfruleSubstitute.v
470 lines (434 loc) · 13.3 KB
/
SoundInfruleSubstitute.v
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
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
Require Import syntax.
Require Import alist.
Require Import FMapWeakList.
Require Import Classical.
Require Import Coqlib.
Require Import infrastructure.
Require Import Metatheory.
Import LLVMsyntax.
Import LLVMinfra.
Require Import opsem.
Require Import sflib.
Require Import paco.
Import Opsem.
Require Import TODO.
Require Import TODOProof.
Require Import Decs.
Require Import Exprs.
Require Import Validator.
Require Import GenericValues.
Require Import Inject.
Require AssnMem.
Require AssnState.
Require Import Hints.
Require Import memory_props.
Import Memory.
Require Import opsem_wf.
Require Import genericvalues_inject.
Require Import memory_sim.
Require Import MemAux.
Require Import SoundBase.
Set Implicit Arguments.
Section NONE.
Lemma subst_none_value
conf st invst0 x v
(NONE: AssnState.Unary.sem_idT st invst0 x = None)
val1
(SEM: AssnState.Unary.sem_valueT conf st invst0 v = Some val1)
y
:
<<NO_X: (ValueT.substitute x y v) = v>>
.
Proof.
red.
destruct v; ss.
des_ifs.
Qed.
Lemma subst_none_list_value
conf st invst0 x
(NONE: AssnState.Unary.sem_idT st invst0 x = None)
l0 lsv
(SEM: AssnState.Unary.sem_list_valueT conf st invst0 lsv = Some l0)
y
:
<<NO_X: List.map (fun x0 : sz * ValueT.t => (fst x0, ValueT.substitute x y (snd x0))) lsv = lsv>>
.
Proof.
red.
ginduction lsv; ii; ss.
des_ifs. ss.
repeat erewrite subst_none_value; eauto.
f_equal.
eapply IHlsv; eauto.
Qed.
Lemma subst_none_expr
conf st invst0 x e
(NONE: AssnState.Unary.sem_idT st invst0 x = None)
val1
(SEM: AssnState.Unary.sem_expr conf st invst0 e = Some val1)
y
:
<<NO_X: (Expr.substitute x y e) = e>>
.
Proof.
red.
destruct e; ss; des_ifs.
- ss. repeat erewrite subst_none_value; eauto.
- ss. repeat erewrite subst_none_value; eauto.
- ss. repeat erewrite subst_none_value; eauto.
- ss. repeat erewrite subst_none_value; eauto.
- ss. repeat erewrite subst_none_value; eauto.
f_equal.
erewrite subst_none_list_value; eauto.
- ss. repeat erewrite subst_none_value; eauto.
- ss. repeat erewrite subst_none_value; eauto.
- ss. repeat erewrite subst_none_value; eauto.
- ss. repeat erewrite subst_none_value; eauto.
- ss. repeat erewrite subst_none_value; eauto.
- ss. repeat erewrite subst_none_value; eauto.
- ss. repeat erewrite subst_none_value; eauto.
- ss. repeat erewrite subst_none_value; eauto.
Qed.
Lemma subst_none_value_rev
conf st invst0 y v
(NONE: AssnState.Unary.sem_valueT conf st invst0 y = None)
x val1
(SEM: AssnState.Unary.sem_valueT conf st invst0 (ValueT.substitute x y v) = Some val1)
:
<<NO_X: (ValueT.substitute x y v) = v>>
.
Proof.
red.
destruct v; ss.
des_ifs.
Qed.
Lemma subst_none_list_value_rev
conf st invst0 y
(NONE: AssnState.Unary.sem_valueT conf st invst0 y = None)
l0 lsv x
(SEM: AssnState.Unary.sem_list_valueT
conf st invst0
(List.map (fun x0 : sz * ValueT.t => (fst x0, ValueT.substitute x y (snd x0))) lsv) =
Some l0)
:
<<NO_X: List.map (fun x0 : sz * ValueT.t => (fst x0, ValueT.substitute x y (snd x0))) lsv = lsv>>
.
Proof.
red.
ginduction lsv; ii; ss.
des_ifs. destruct a; ss.
erewrite subst_none_value_rev; eauto.
f_equal; ss.
eapply IHlsv; eauto.
Qed.
Lemma subst_none_expr_rev
conf st invst0 y e
(NONE: AssnState.Unary.sem_valueT conf st invst0 y = None)
x val1
(SEM: AssnState.Unary.sem_expr conf st invst0 (Expr.substitute x y e) = Some val1)
:
<<NO_X: (Expr.substitute x y e) = e>>
.
Proof.
red.
destruct e; ss; des_ifs;
f_equal; try erewrite subst_none_value_rev; eauto.
erewrite subst_none_list_value_rev; eauto.
Qed.
End NONE.
Section SPEC.
(* TODO: location *)
Lemma const_eqb_refl_list
l0
(IH: Forall (fun a : const => const_eqb a a) l0)
:
(fix f (lc1 lc2 : list const) {struct lc1} : bool :=
match lc1 with
| [] => match lc2 with
| [] => true
| _ :: _ => false
end
| hd1 :: tl1 => match lc2 with
| [] => false
| hd2 :: tl2 => const_eqb hd1 hd2 && f tl1 tl2
end
end) l0 l0
.
Proof.
ginduction l0; ii; ss.
inv IH.
rewrite H1; ss.
eapply IHl0; eauto.
Qed.
(* TODO: location *)
Lemma const_eqb_refl
a
:
<<REFL: const_eqb a a>>
.
Proof.
red.
induction a using const_ind_gen; ss; unfold proj_sumbool in *; des_ifs; ss;
repeat (apply andb_true_iff; split; ss);
try (by eapply const_eqb_refl_list; eauto); ss.
Qed.
(* TODO: location *)
Lemma forallb_const_eqb_refl
lc
:
<<EQ: list_forallb2 const_eqb lc lc = true>>
.
Proof.
red.
ginduction lc; ii; ss.
rewrite IHlc; ss.
unfold proj_sumbool in *.
apply andb_true_iff; split; ss.
apply const_eqb_refl; ss.
Qed.
Lemma substitute_same_modulo_spec
e from to
:
<<SUBST: Expr.same_modulo_value e (Expr.substitute from to e) = true>>
.
Proof.
red.
destruct e; ss; unfold proj_sumbool in *; ss; des_ifs; ss.
- apply andb_true_iff. split; ss.
apply forallb_const_eqb_refl; ss.
- apply forallb_const_eqb_refl; ss.
- clear_tac.
exfalso. ginduction lsv; ii; ss.
apply n. f_equal.
exploit IHlsv; try eassumption.
{ ii. rewrite <- H in *. ss. }
i; ss.
Qed.
(* TODO: location *)
Lemma map_valueTs_get_valueTs_spec
f e
:
List.map f (Expr.get_valueTs e) = (Expr.get_valueTs (Expr.map_valueTs e f))
.
Proof.
destruct e; ss.
f_equal.
clear_tac.
ginduction lsv; ii; ss.
f_equal. eauto.
Qed.
Lemma substitute_lessdef_spec
conf st invst0
(from: IdT.t) (to: ValueT.t)
(LDFROMTO : AssnState.Unary.sem_lessdef conf st invst0 (Expr.value from, Expr.value to))
e
:
Forall2 (fun v1 v2 : ValueT.t =>
AssnState.Unary.sem_lessdef conf st invst0 (Expr.value v1, Expr.value v2))
(Expr.get_valueTs e) (Expr.get_valueTs (Expr.substitute from to e))
.
Proof.
unfold Expr.substitute.
rewrite <- map_valueTs_get_valueTs_spec.
abstr (Expr.get_valueTs e) tt.
clear_tac.
ginduction tt; ii; ss.
econs; eauto.
ii; ss.
destruct a; ss.
- des_ifs.
+ eapply LDFROMTO; eauto.
+ esplits; eauto.
eapply GVs.lessdef_refl.
- esplits; eauto.
eapply GVs.lessdef_refl.
Qed.
Lemma substitute_lessdef_spec_rev
conf st invst0
(from: IdT.t) (to: ValueT.t)
(LDFROMTO : AssnState.Unary.sem_lessdef conf st invst0 (Expr.value to, Expr.value from))
e
:
Forall2 (fun v1 v2 : ValueT.t =>
AssnState.Unary.sem_lessdef conf st invst0 (Expr.value v1, Expr.value v2))
(Expr.get_valueTs (Expr.substitute from to e)) (Expr.get_valueTs e)
.
Proof.
unfold Expr.substitute.
rewrite <- map_valueTs_get_valueTs_spec.
abstr (Expr.get_valueTs e) tt.
clear_tac.
ginduction tt; ii; ss.
econs; eauto.
ii; ss.
destruct a; ss.
- des_ifs.
+ eapply LDFROMTO; eauto.
+ esplits; eauto.
eapply GVs.lessdef_refl.
- esplits; eauto.
eapply GVs.lessdef_refl.
Qed.
(* TODO: location *)
Lemma same_modulo_value_comm
a b
(SAME: Expr.same_modulo_value a b)
:
<<SAME: Expr.same_modulo_value b a>>
(* <<COMM: Expr.same_modulo_value a b = Expr.same_modulo_value b a>> <--- little harder to prove, skip *)
.
Proof.
red.
destruct a, b; ss; unfold proj_sumbool in *; des_ifs; unfold is_true in *; ss; des_bool; des; clear_tac.
- apply AssnState.Rel.list_forallb_const_eqb in SAME. des. clarify.
eapply forallb_const_eqb_refl; eauto.
- ss.
- apply AssnState.Rel.list_forallb_const_eqb in SAME. des. clarify.
eapply forallb_const_eqb_refl; eauto.
- rewrite e1 in *. ss.
Qed.
End SPEC.
Section SOME.
Lemma substitute_some_id
conf st from to idt0 invst0 val0 from_gv to_gv
(FROM: AssnState.Unary.sem_idT st invst0 from = Some from_gv)
(TO: AssnState.Unary.sem_valueT conf st invst0 to = Some to_gv)
(LD: GVs.lessdef from_gv to_gv)
(SEM: AssnState.Unary.sem_idT st invst0 idt0 = Some val0)
:
exists val1 : GenericValue,
<<SEM: AssnState.Unary.sem_valueT conf st invst0
(if IdT.eq_dec from idt0 then to else idt0) = Some val1>>
/\ <<LD: GVs.lessdef val0 val1 >>
.
Proof.
des_ifs.
- esplits; eauto.
- esplits; eauto.
eapply GVs.lessdef_refl.
Qed.
Lemma substitute_some_value
conf st from to v0 invst0 val0 from_gv to_gv
(FROM: AssnState.Unary.sem_idT st invst0 from = Some from_gv)
(TO: AssnState.Unary.sem_valueT conf st invst0 to = Some to_gv)
(LD: GVs.lessdef from_gv to_gv)
(SEM: AssnState.Unary.sem_valueT conf st invst0 v0 = Some val0)
:
exists val1 : GenericValue,
<<SEM: AssnState.Unary.sem_valueT conf st invst0 (ValueT.substitute from to v0) = Some val1 >> /\
<<LD: GVs.lessdef val0 val1 >>
.
Proof.
destruct v0; ss.
- eapply substitute_some_id; eauto.
- esplits; eauto. eapply GVs.lessdef_refl.
Qed.
Lemma substitute_some_expr
conf st from to e invst0 val0 from_gv to_gv
(FROM: AssnState.Unary.sem_idT st invst0 from = Some from_gv)
(TO: AssnState.Unary.sem_valueT conf st invst0 to = Some to_gv)
(LD: GVs.lessdef from_gv to_gv)
(SEM: AssnState.Unary.sem_expr conf st invst0 e = Some val0)
:
exists val1 : GenericValue,
<<SEM: AssnState.Unary.sem_expr conf st invst0 (Expr.substitute from to e) = Some val1 >> /\
<<LD: GVs.lessdef val0 val1 >>
.
Proof.
eapply AssnState.Rel.lessdef_expr_spec3; eauto.
{ eapply substitute_same_modulo_spec; eauto. }
{ assert(LDFROMTO: AssnState.Unary.sem_lessdef conf st invst0 (Expr.value from, Expr.value to)).
{ ii; esplits; eauto. ss. rewrite VAL1 in *. clarify. }
clear - LDFROMTO.
eapply substitute_lessdef_spec; eauto.
}
Qed.
Lemma substitute_some_expr_rev
conf st from to e invst0 val0 from_gv to_gv
(TO: AssnState.Unary.sem_valueT conf st invst0 to = Some to_gv)
(FROM: AssnState.Unary.sem_idT st invst0 from = Some from_gv)
(LD: GVs.lessdef to_gv from_gv)
(SEM: AssnState.Unary.sem_expr conf st invst0 (Expr.substitute from to e) = Some val0)
:
exists val1 : GenericValue,
<<SEM: AssnState.Unary.sem_expr conf st invst0 e = Some val1 >> /\ <<LD: GVs.lessdef val0 val1 >>
.
Proof.
eapply AssnState.Rel.lessdef_expr_spec3; eauto.
{ rewrite same_modulo_value_comm; ss.
eapply substitute_same_modulo_spec; eauto. }
{ assert(LDFROMTO: AssnState.Unary.sem_lessdef conf st invst0 (Expr.value to, Expr.value from)).
{ ii; esplits; eauto. ss. rewrite VAL1 in *. clarify. }
clear - LDFROMTO.
eapply substitute_lessdef_spec_rev; eauto.
}
Qed.
End SOME.
Lemma substitute_spec_unary
conf st x y e pubs gmax
invst0 assnmem0 inv0
(SEM: AssnState.Unary.sem conf st invst0 assnmem0 gmax pubs inv0)
(LD: AssnState.Unary.sem_lessdef conf st invst0
(Exprs.Expr.value (Exprs.ValueT.id x), Exprs.Expr.value y))
:
<<SEM: AssnState.Unary.sem
conf st invst0 assnmem0 gmax pubs
(Hints.Assertion.update_lessdef
(Exprs.ExprPairSet.add (e, Exprs.Expr.substitute x y e)) inv0)>>
.
Proof.
econs; eauto; try apply SEM.
inv SEM. clear - LESSDEF LD.
ii.
apply Exprs.ExprPairSetFacts.add_iff in H.
des; cycle 1.
{ eapply LESSDEF; eauto. }
clear LESSDEF.
clarify. ss.
unfold AssnState.Unary.sem_lessdef in *.
ss.
destruct (AssnState.Unary.sem_idT st invst0 x) eqn:T; cycle 1.
{ clear LD.
solve_leibniz.
clear - VAL1 T.
erewrite subst_none_expr; eauto. esplits; eauto. eapply GVs.lessdef_refl.
}
specialize (LD g eq_refl). des.
clear_tac.
solve_leibniz.
eapply substitute_some_expr; eauto.
Qed.
Lemma substitute_spec_unary_rev
conf st x y e pubs gmax
invst0 assnmem0 inv0
(SEM: AssnState.Unary.sem conf st invst0 assnmem0 gmax pubs inv0)
(LD: AssnState.Unary.sem_lessdef conf st invst0
(Exprs.Expr.value y, Exprs.Expr.value (Exprs.ValueT.id x)))
:
<<SEM: AssnState.Unary.sem
conf st invst0 assnmem0 gmax pubs
(Hints.Assertion.update_lessdef
(Exprs.ExprPairSet.add (Exprs.Expr.substitute x y e, e)) inv0)>>
.
Proof.
econs; eauto; try apply SEM.
inv SEM. clear - LESSDEF LD.
ii.
apply Exprs.ExprPairSetFacts.add_iff in H.
des; cycle 1.
{ eapply LESSDEF; eauto. }
clear LESSDEF.
clarify. ss.
unfold AssnState.Unary.sem_lessdef in *.
ss.
destruct (AssnState.Unary.sem_valueT conf st invst0 y) eqn:T; cycle 1.
{ clear LD.
solve_leibniz.
clear - VAL1 T.
erewrite subst_none_expr_rev in VAL1; eauto. esplits; eauto. eapply GVs.lessdef_refl.
}
specialize (LD g eq_refl). des.
clear_tac.
solve_leibniz.
eapply substitute_some_expr_rev; eauto.
Qed.