-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathSoundInfrules.v
362 lines (347 loc) · 13.9 KB
/
SoundInfrules.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
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 Validator.
Require Import GenericValues.
Require AssnMem.
Require AssnState.
Require Import SoundBase.
Require Import TODOProof.
Require Import SoundInfruleIntroGhost.
Require Import SoundInfruleSubstitute.
Require Import SoundInfruleTransitivity.
Require Import SoundInfruleReduceMaydiff.
Require Import Exprs.
Set Implicit Arguments.
Lemma apply_not_interesting_infrule_sound
m_src m_tgt
conf_src st_src
conf_tgt st_tgt
invst0 assnmem0 inv0
infrule
(INTEREST: Hints.Infrule.is_of_interest infrule = false)
(CONF: AssnState.valid_conf m_src m_tgt conf_src conf_tgt)
(STATE: AssnState.Rel.sem conf_src conf_tgt st_src st_tgt invst0 assnmem0 inv0)
(MEM: AssnMem.Rel.sem conf_src conf_tgt st_src.(Mem) st_tgt.(Mem) assnmem0):
exists invst1 assnmem1,
<<STATE: AssnState.Rel.sem conf_src conf_tgt st_src st_tgt invst1 assnmem1
(Infrules.apply_infrule m_src m_tgt infrule inv0)>> /\
<<MEM: AssnMem.Rel.sem conf_src conf_tgt st_src.(Mem) st_tgt.(Mem) assnmem1>> /\
<<MEMLE: AssnMem.Rel.le assnmem0 assnmem1>>.
Proof.
ADMIT "We will not prove the soundness of arithmetic infrules as Alive (SMT solver) can prove them.
Also, we will not prove the soundness of infrules that are only used inside instcombine pass.".
Qed.
Lemma apply_interesting_infrule_sound
m_src m_tgt
conf_src st_src
conf_tgt st_tgt
invst0 assnmem0 inv0
infrule
(INTEREST: Hints.Infrule.is_of_interest infrule = true)
(CONF: AssnState.valid_conf m_src m_tgt conf_src conf_tgt)
(STATE: AssnState.Rel.sem conf_src conf_tgt st_src st_tgt invst0 assnmem0 inv0)
(MEM: AssnMem.Rel.sem conf_src conf_tgt st_src.(Mem) st_tgt.(Mem) assnmem0):
exists invst1 assnmem1,
<<STATE: AssnState.Rel.sem conf_src conf_tgt st_src st_tgt invst1 assnmem1
(Infrules.apply_infrule m_src m_tgt infrule inv0)>> /\
<<MEM: AssnMem.Rel.sem conf_src conf_tgt st_src.(Mem) st_tgt.(Mem) assnmem1>> /\
<<MEMLE: AssnMem.Rel.le assnmem0 assnmem1>>.
Proof.
destruct infrule; compute in INTEREST; try (by contradict INTEREST).
- (* transitivity *)
exists invst0, assnmem0. splits; eauto; [|reflexivity].
ss.
match goal with
| [|- context[if ?c then _ else _]] => destruct c eqn:C
end; ss.
inv STATE. econs; eauto. ss. clear TGT MAYDIFF ALLOCAS.
econs; try apply SRC; eauto; ss.
red. i. apply Exprs.ExprPairSetFacts.add_iff in H.
des; cycle 1.
{ eapply SRC; eauto. }
destruct x; ss. clarify.
rename t into __e0__.
rename e2 into __e1__.
rename t0 into __e2__.
des_bool; des.
abstr (AssnState.Rel.src invst0) invst.
clear MEM CONF. clear_tac.
solve_leibniz. clarify.
assert(LD01: AssnState.Unary.sem_lessdef conf_src st_src invst (__e0__, __e1__)).
{ clear C0. repeat (des_bool; des).
- eapply AssnState.Rel.lessdef_expr_spec2; eauto.
- eapply AssnState.Rel.lessdef_expr_spec2; eauto;
repeat rewrite <- load_realign_sem_expr; eauto.
- eapply AssnState.Rel.lessdef_expr_spec2; eauto;
repeat rewrite <- load_realign_sem_expr; eauto.
- eapply AssnState.Rel.lessdef_expr_spec2; eauto;
repeat rewrite <- load_realign_sem_expr; eauto.
}
assert(LD12: AssnState.Unary.sem_lessdef conf_src st_src invst (__e1__, __e2__)).
{ clear C. repeat (des_bool; des).
- eapply AssnState.Rel.lessdef_expr_spec2; eauto.
- eapply AssnState.Rel.lessdef_expr_spec2; eauto;
repeat rewrite <- load_realign_sem_expr; eauto.
- eapply AssnState.Rel.lessdef_expr_spec2; eauto;
repeat rewrite <- load_realign_sem_expr; eauto.
- eapply AssnState.Rel.lessdef_expr_spec2; eauto;
repeat rewrite <- load_realign_sem_expr; eauto.
}
eapply AssnState.Unary.sem_lessdef_trans; eauto.
- (* transitivity_tgt *)
exists invst0, assnmem0.
esplits; eauto; [ | reflexivity ].
ss.
match goal with
| [|- context[if ?c then _ else _]] => destruct c eqn:C
end; ss.
econs; eauto; try apply STATE. ss.
inv STATE. clear - TGT C.
des_bool; des.
abstr (AssnState.Rel.tgt invst0) invst.
econs; try apply TGT; eauto; ss.
red. i. apply Exprs.ExprPairSetFacts.add_iff in H.
des; cycle 1.
{ eapply TGT; eauto. }
destruct x; ss. clarify.
rename t into __e0__.
rename e2 into __e1__.
rename t0 into __e2__.
solve_leibniz. clarify.
assert(LD01: AssnState.Unary.sem_lessdef conf_tgt st_tgt invst (__e0__, __e1__)).
{ clear C0. repeat (des_bool; des).
- eapply AssnState.Rel.lessdef_expr_spec2; eauto.
- eapply AssnState.Rel.lessdef_expr_spec2; eauto;
repeat rewrite <- load_realign_sem_expr; eauto.
- eapply AssnState.Rel.lessdef_expr_spec2; eauto;
repeat rewrite <- load_realign_sem_expr; eauto.
- eapply AssnState.Rel.lessdef_expr_spec2; eauto;
repeat rewrite <- load_realign_sem_expr; eauto.
}
assert(LD12: AssnState.Unary.sem_lessdef conf_tgt st_tgt invst (__e1__, __e2__)).
{ clear C. repeat (des_bool; des).
- eapply AssnState.Rel.lessdef_expr_spec2; eauto.
- eapply AssnState.Rel.lessdef_expr_spec2; eauto;
repeat rewrite <- load_realign_sem_expr; eauto.
- eapply AssnState.Rel.lessdef_expr_spec2; eauto;
repeat rewrite <- load_realign_sem_expr; eauto.
- eapply AssnState.Rel.lessdef_expr_spec2; eauto;
repeat rewrite <- load_realign_sem_expr; eauto.
}
eapply AssnState.Unary.sem_lessdef_trans; eauto.
- (* substitute *)
exists invst0, assnmem0.
esplits; eauto; [ | reflexivity ].
ss. des_ifs.
econs; eauto; try apply STATE.
hexploit AssnState.Rel.lessdef_expr_spec2; eauto; try apply STATE.
intro LD; des. clear Heq.
inv STATE. clear - SRC LD.
eapply substitute_spec_unary; eauto.
- (* substitute_rev *)
exists invst0, assnmem0.
esplits; eauto; [ | reflexivity ].
ss. des_ifs.
econs; eauto; try apply STATE.
hexploit AssnState.Rel.lessdef_expr_spec2; eauto; try apply STATE.
intro LD; des. clear Heq.
inv STATE. clear - SRC LD.
eapply substitute_spec_unary_rev; eauto.
- (* substitute_tgt *)
exists invst0, assnmem0.
esplits; eauto; [ | reflexivity ].
ss. des_ifs.
econs; eauto; try apply STATE.
hexploit AssnState.Rel.lessdef_expr_spec2; eauto; try apply STATE.
intro LD; des. clear Heq.
inv STATE. clear - TGT LD.
eapply substitute_spec_unary; eauto.
- (* intro_ghost *)
ss. des_ifs; cycle 1.
{ esplits; eauto. reflexivity. }
repeat (des_bool; des).
rename g into i0.
rename x into x0.
Local Opaque AssnState.Unary.clear_idt.
destruct (AssnState.Unary.sem_expr conf_src st_src
(AssnState.Rel.clear_idt (Exprs.Tag.ghost, i0) invst0).(AssnState.Rel.src) x0) eqn:T0; cycle 1.
{
exists (AssnState.Rel.clear_idt (Exprs.Tag.ghost, i0) invst0), assnmem0.
splits; ss; eauto; [|reflexivity].
exploit clear_idt_ghost_spec; eauto.
{ instantiate (1:= (Exprs.Tag.ghost, i0)). ss. }
intro STATE_CLEAR; des.
clear - STATE_CLEAR T0.
unfold Hints.Assertion.update_tgt, Hints.Assertion.update_src, Hints.Assertion.update_lessdef. ss.
econs; eauto; try apply STATE_CLEAR.
+ ss.
inv STATE_CLEAR. clear - SRC T0.
econs; eauto; try apply SRC.
ss.
inv SRC. clear - LESSDEF T0.
ii.
apply Exprs.ExprPairSetFacts.add_iff in H. des.
* solve_leibniz. clarify. ss. rewrite T0 in *. clarify.
* eapply LESSDEF; eauto.
+ ss.
inv STATE_CLEAR. clear - TGT T0.
econs; eauto; try apply TGT.
ss.
inv TGT. clear - LESSDEF T0.
ii.
apply Exprs.ExprPairSetFacts.add_iff in H. des.
* clarify. ss.
assert(NONE: AssnState.Unary.sem_idT
st_tgt (AssnState.Rel.tgt
(AssnState.Rel.clear_idt
(Exprs.Tag.ghost, i0) invst0)) (Exprs.Tag.ghost, i0) = None).
{ clear - i0.
unfold AssnState.Unary.sem_idT. ss.
ss.
Local Transparent AssnState.Unary.clear_idt. ss.
rewrite lookup_AL_filter_spec. des_ifs. des_bool; des_sumbool. ss.
Local Opaque AssnState.Unary.clear_idt.
}
unfold AssnState.Rel.clear_idt in *. ss.
solve_leibniz. clarify. ss.
rewrite NONE in *. clarify.
* ss. eapply LESSDEF; eauto.
}
rename T0 into GV_SRC.
rename g into gv_src.
assert(GV_TGT: exists gv_tgt,
AssnState.Unary.sem_expr conf_tgt st_tgt
(AssnState.Rel.clear_idt (Exprs.Tag.ghost, i0) invst0).(AssnState.Rel.tgt) x0
= Some gv_tgt
/\ genericvalues_inject.gv_inject assnmem0.(AssnMem.Rel.inject) gv_src gv_tgt).
{
hexploit AssnState.Rel.not_in_maydiff_expr_spec; try apply GV_SRC; try apply STATE; eauto.
{ ii.
assert(id0 <> (Exprs.Tag.ghost, i0)).
{
ii. clarify. ss.
exploit clear_idt_inv_spec_id; try eassumption; ss.
i. unfold proj_sumbool in *. des_ifs.
}
ss.
erewrite <- clear_idt_spec_id; ss; cycle 1.
{ unfold proj_sumbool. des_ifs. }
inv STATE.
eapply MAYDIFF; ss.
erewrite clear_idt_spec_id; try eassumption; cycle 1.
unfold proj_sumbool. des_ifs.
}
}
des. rename GV_TGT0 into GV_INJ.
des.
exploit clear_idt_ghost_spec; eauto.
{ instantiate (1:= (Exprs.Tag.ghost, i0)). ss. }
intro STATE_CLEAR; des.
clear - STATE_CLEAR GV_SRC GV_TGT GV_INJ MEM.
exists (cons_idt (Exprs.Tag.ghost, i0) gv_src gv_tgt
(AssnState.Rel.clear_idt (Exprs.Tag.ghost, i0) invst0)), assnmem0.
splits; ss; eauto; [|reflexivity].
{
econs; eauto; try apply STATE_CLEAR.
- ss.
eapply Subset_unary_sem; eauto.
eapply cons_ghost_unary_spec; try apply STATE_CLEAR; eauto.
{ eapply sem_expr_preserves_valid_ptr; try apply STATE_CLEAR; try apply MEM; eauto. }
unfold compose.
econs; ss; eauto.
+ ii. apply Exprs.ExprPairSetFacts.add_iff. right. ss.
+ split; ss.
- ss.
eapply Subset_unary_sem; eauto.
eapply cons_ghost_unary_spec; try apply STATE_CLEAR; eauto.
{ eapply sem_expr_preserves_valid_ptr; try apply STATE_CLEAR; try apply MEM; eauto. }
unfold compose.
econs; ss; eauto.
+ ii.
apply Exprs.ExprPairSetFacts.add_iff in H. des.
{ apply Exprs.ExprPairSetFacts.add_iff. left. ss. }
apply Exprs.ExprPairSetFacts.add_iff. right.
apply Exprs.ExprPairSetFacts.add_iff. right. ss.
+ split; ss.
- i.
unfold Hints.Assertion.update_lessdef in NOTIN. ss.
inv STATE_CLEAR.
clear SRC TGT TGT_NOUNIQ ALLOCAS.
ii. ss.
destruct (Exprs.IdT.eq_dec id0 (Exprs.Tag.ghost, i0)).
{ clarify.
unfold AssnState.Unary.sem_idT in *. ss. des_ifs.
esplits; eauto.
}
erewrite <- cons_idt_spec_id in VAL_SRC; cycle 1.
{ unfold proj_sumbool; des_ifs. }
erewrite <- cons_idt_spec_id; cycle 1.
{ unfold proj_sumbool; des_ifs. }
eapply MAYDIFF; eauto.
}
- (* intro_eq_tgt *)
exists invst0, assnmem0. splits; eauto; [|reflexivity].
inv STATE. econs; eauto. ss.
inv TGT. econs; eauto. ss.
ii. apply Exprs.ExprPairSetFacts.add_iff in H. des.
+ subst. solve_leibniz. clarify. esplits; eauto. apply GVs.lessdef_refl.
+ eapply LESSDEF; eauto.
- exploit reduce_maydiff_lessdef_sound; eauto. i.
esplits; eauto. reflexivity.
- exploit reduce_maydiff_non_physical_sound; eauto. i. des.
esplits; eauto. reflexivity.
Qed.
Lemma apply_infrule_sound
m_src m_tgt
conf_src st_src
conf_tgt st_tgt
invst0 assnmem0 inv0
infrule
(CONF: AssnState.valid_conf m_src m_tgt conf_src conf_tgt)
(STATE: AssnState.Rel.sem conf_src conf_tgt st_src st_tgt invst0 assnmem0 inv0)
(MEM: AssnMem.Rel.sem conf_src conf_tgt st_src.(Mem) st_tgt.(Mem) assnmem0):
exists invst1 assnmem1,
<<STATE: AssnState.Rel.sem conf_src conf_tgt st_src st_tgt invst1 assnmem1
(Infrules.apply_infrule m_src m_tgt infrule inv0)>> /\
<<MEM: AssnMem.Rel.sem conf_src conf_tgt st_src.(Mem) st_tgt.(Mem) assnmem1>> /\
<<MEMLE: AssnMem.Rel.le assnmem0 assnmem1>>.
Proof.
destruct (Hints.Infrule.is_of_interest infrule) eqn:T; ss.
- eapply apply_interesting_infrule_sound; eauto.
- eapply apply_not_interesting_infrule_sound; eauto.
Qed.
Lemma apply_infrules_sound
m_src m_tgt
conf_src st_src
conf_tgt st_tgt
invst0 assnmem0 inv0
infrules
(CONF: AssnState.valid_conf m_src m_tgt conf_src conf_tgt)
(STATE: AssnState.Rel.sem conf_src conf_tgt st_src st_tgt invst0 assnmem0 inv0)
(MEM: AssnMem.Rel.sem conf_src conf_tgt st_src.(Mem) st_tgt.(Mem) assnmem0):
exists invst1 assnmem1,
<<STATE: AssnState.Rel.sem conf_src conf_tgt st_src st_tgt invst1 assnmem1
(Infrules.apply_infrules m_src m_tgt infrules inv0)>> /\
<<MEM: AssnMem.Rel.sem conf_src conf_tgt st_src.(Mem) st_tgt.(Mem) assnmem1>> /\
<<MEMLE: AssnMem.Rel.le assnmem0 assnmem1>>.
Proof.
unfold Infrules.apply_infrules. rewrite <- fold_left_rev_right.
move infrules at top. revert_until infrules. induction (rev infrules); i.
- esplits; eauto. reflexivity.
- exploit IHl0; eauto. i. des.
exploit apply_infrule_sound; eauto. i. des.
esplits; eauto.
etransitivity; eauto.
Qed.