-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRela.v
More file actions
413 lines (362 loc) · 11.5 KB
/
Copy pathRela.v
File metadata and controls
413 lines (362 loc) · 11.5 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
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
From Rela Require Import Proc.
From Rela Require Import Inliner.
From Rela Require Import Com.
From Rela Require Import Sem.
From Rela Require Import Sigma.
From Rela Require Import Hoare_Triple.
From Rela Require Import Quadruple.
From Stdlib Require Import Lists.List.
Import ListNotations.
Local Open Scope nat_scope.
Import Arith.
(** Definition of relational Precondition **)
Definition r_precondition : Type := list sigma -> Prop.
Definition empty_r_precondition : r_precondition := (fun _ => False).
(** Defintion of relational Postcondition **)
Definition r_postcondition : Type := list sigma -> list sigma -> Prop.
Definition empty_r_postcondition : r_postcondition := (fun _ _ => True).
(** Definition of the relational evaluation of program **)
Inductive rceval : list com -> list sigma -> Psi.psi -> list sigma -> Prop :=
| E_Empty : forall ps, rceval [] [] ps []
| E_Seq : forall c qc s q s' q' ps,
ceval c s ps s' ->
rceval qc q ps q' ->
rceval (c::qc) (s::q) ps (s'::q').
(** Definition of relational properties **)
Definition relational_prop (P: r_precondition) (Q: r_postcondition)
(c : list com) (ps : Psi.psi) : Prop :=
forall s s', length s = length c -> length s' = length c ->
P s -> rceval c s ps s' -> Q s' s.
(** A Hoare Triple is a Relational Property for a list of program of size one **)
Module Single_Rela_Prop.
Lemma list_length_one:
forall (A: Type) (h:A) (q : list A), length (h :: q) = 1 -> q = [].
Proof.
intros.
simpl in H.
apply eq_add_S in H.
apply length_zero_iff_nil in H.
assumption.
Qed.
Lemma hoare_is_rela :
forall P Q c ps,
hoare_triple (fun s => P [s]) (fun s' s => Q [s'] [s]) c ps ->
relational_prop P Q [c] ps.
Proof.
unfold hoare_triple.
unfold relational_prop.
intros P Q c ps H s s' Hs Hs' HPre He.
inversion He;subst.
apply list_length_one in Hs.
apply list_length_one in Hs'.
subst.
apply H;assumption.
Qed.
Lemma one_rela_is_hoare :
forall (P: precondition) (Q: postcondition) c ps,
relational_prop (fun s: list sigma => P (hd default_sigma s))
(fun s' s => Q (hd default_sigma s') (hd default_sigma s)) [c] ps ->
hoare_triple P Q c ps.
Proof.
unfold hoare_triple.
unfold relational_prop.
intros.
specialize (H [s] [s']).
simpl in H.
apply H.
reflexivity.
reflexivity.
assumption.
apply E_Seq.
assumption.
apply E_Empty.
Qed.
End Single_Rela_Prop.
(** Definition of a relational contract **)
Definition r_clause : Type := r_precondition * r_postcondition.
Definition empty_r_clause : r_clause := (empty_r_precondition, empty_r_postcondition).
Definition get_r_pre (an:r_clause) :=
let (pre,post) := an in
pre.
Definition get_r_post (an:r_clause) :=
let (pre,post) := an in
post.
(** Definition of relational contract environments :
a map from list of procedure name to relational clauses **)
Module R_Phi.
Definition phi : Type := list Proc.t -> r_clause.
Definition empty_phi: phi := fun _ => empty_r_clause.
End R_Phi.
(** Defintion of a relational properties with inliner **)
Definition i_relational_prop (n: nat) (P: r_precondition) (Q: r_postcondition)
(c : list com) (ps : Psi.psi) : Prop :=
forall s s', length s = length c -> length s' = length c ->
P s -> rceval c s (Inline1.k_inliner_ps n ps) s' -> Q s' s.
Lemma n_inline_ps_rceval :
forall (p : list com) (s : list Sigma.sigma) (ps : Psi.psi)
(s' : list Sigma.sigma) (n : nat),
length s = length p -> length s' = length p ->
rceval p s (Inline1.k_inliner_ps n ps) s' -> rceval p s ps s'.
Proof.
induction p;intros s' ps s n Hs' Hs He.
- apply length_zero_iff_nil in Hs;subst.
apply length_zero_iff_nil in Hs';subst.
apply E_Empty.
- destruct s ;[discriminate Hs |].
destruct s';[discriminate Hs' |].
inversion He;subst.
apply E_Seq.
+ apply (Inline1.n_inline_ps_ceval _ _ _ _ n).
assumption.
+ apply (IHp _ _ _ n).
* inversion Hs' ; reflexivity.
* inversion Hs; reflexivity.
* assumption.
Qed.
Lemma rceval_n_inline_ps_S n p s ps s':
length s = length p -> length s' = length p ->
rceval p s (Inline1.k_inliner_ps n ps) s' ->
forall m, n <= m -> rceval p s (Inline1.k_inliner_ps m ps) s'.
Proof.
generalize dependent s.
generalize dependent s'.
induction p; intros s' s Hs Hs' He m Hnm.
- apply length_zero_iff_nil in Hs;subst.
apply length_zero_iff_nil in Hs';subst.
apply E_Empty.
- destruct s;[discriminate Hs|].
destruct s';[discriminate Hs'|].
inversion He;subst; simpl.
apply E_Seq.
+ apply (Inline1.ceval_n_inline_ps_S n); assumption.
+ apply IHp.
* inversion Hs; reflexivity.
* inversion Hs'; reflexivity.
* assumption.
* assumption.
Qed.
Lemma rceval_n_inline_ps :
forall (p : list com)
(s : list Sigma.sigma)
(ps : Psi.psi)
(s' : list Sigma.sigma),
length s = length p -> length s' = length p ->
rceval p s ps s' -> exists n : nat, rceval p s (Inline1.k_inliner_ps n ps) s'.
Proof.
induction p; intros s ps s' Hs Hs' He.
- apply length_zero_iff_nil in Hs;subst.
apply length_zero_iff_nil in Hs';subst.
exists 0.
apply E_Empty.
- destruct s;[discriminate Hs|].
destruct s';[discriminate Hs'|].
inversion He;subst;simpl.
specialize (Inline1.ceval_n_inline_ps a s ps s1 H4) as [m H].
inversion He;subst.
inversion Hs.
inversion Hs'.
specialize (IHp s0 ps s' H1 H2 H10) as [n Hr].
destruct (Nat.max_dec n m).
+ exists n.
apply E_Seq;[ | apply Hr].
apply (Inline1.ceval_n_inline_ps_S m).
assumption.
apply PeanoNat.Nat.max_l_iff.
assumption.
+ exists m.
apply E_Seq;[ apply H | ].
apply (rceval_n_inline_ps_S n).
all: try assumption.
apply PeanoNat.Nat.max_r_iff.
assumption.
Qed.
Lemma i_relational_prop_relational_prop :
forall P Q p ps,
relational_prop P Q p ps <-> forall n, i_relational_prop n P Q p ps.
Proof.
unfold relational_prop, i_relational_prop;split;intros H.
- intros n s s' Hs Hs' Pre Heval.
apply H.
all: try assumption.
apply n_inline_ps_rceval in Heval.
all: try assumption.
- intros s s' Hs Hs' HPre Heval.
apply rceval_n_inline_ps in Heval;[ | assumption | assumption].
destruct Heval as [n Heval].
apply (H n).
all: try assumption.
Qed.
(** Relational property for a com list with procedure context **)
Definition fold_call := List.map (fun p => CCall p).
Lemma fold_call_length (f : list Proc.t) : length (fold_call f) = length f.
Proof.
apply map_length.
Qed.
Definition relational_prop_ctx
(rcl:R_Phi.phi) (ps: Psi.psi)
(P: r_precondition) (Q : r_postcondition) (c: list com) :=
(forall p, 0 < length p ->
relational_prop (get_r_pre (rcl p)) (get_r_post (rcl p)) (fold_call p) ps) ->
relational_prop P Q c ps.
(** Relational property for a procedure list with procedure context **)
Definition fold_proc (ps: Psi.psi) := List.map (fun f => ps f).
Lemma fold_proc_length (ps: Psi.psi) (f : list Proc.t) :
length (fold_proc ps f) = length f.
Proof.
apply map_length.
Qed.
Definition relational_prop_proc_ctx (rcl: R_Phi.phi) (ps_init: Psi.psi):=
forall p ps,
relational_prop_ctx rcl ps (get_r_pre (rcl p))
(get_r_post (rcl p)) (fold_proc ps_init p).
Lemma rceval_inf_loop p s ps s':
0 < length p ->
rceval (fold_call p) s (Inline1.k_inliner_ps 0 ps) s' -> False.
Proof.
intros H Heval.
destruct p.
* inversion H.
* inversion Heval;subst.
inversion H2;subst.
apply ceval_inf_loop in H1.
contradiction H1.
Qed.
Lemma r_n_inline_ps_inline:
forall (n : nat)
(f : list Proc.t) (s : list Sigma.sigma)
(ps : Psi.psi) (s' : list Sigma.sigma),
length s = length f -> length s' = length f ->
rceval (fold_call f) s (Inline1.k_inliner_ps (S n) ps) s' ->
rceval (fold_proc ps f ) s (Inline1.k_inliner_ps n ps) s'.
Proof.
induction f; intros s ps s' Hs Hs' He.
- apply length_zero_iff_nil in Hs;subst.
apply length_zero_iff_nil in Hs';subst.
apply E_Empty.
- destruct s;[discriminate Hs|].
destruct s';[discriminate Hs'|].
inversion He;subst.
apply E_Seq.
+ apply Inline1.n_inline_ps_inline.
assumption.
+ apply IHf.
* inversion Hs; reflexivity.
* inversion Hs'; reflexivity.
* assumption.
Qed.
Lemma r_recursive_proc ps rcl:
relational_prop_proc_ctx rcl ps ->
(forall p, 0 < length p ->
relational_prop (get_r_pre (rcl p)) (get_r_post (rcl p)) (fold_call p) ps).
Proof.
intros.
apply i_relational_prop_relational_prop.
intros n.
generalize dependent p.
induction n.
- intros p Hp s s' Hs Hs' HPre Heval.
destruct p.
+ inversion Hp.
+ apply rceval_inf_loop in Heval.
* contradiction Heval.
* assumption.
- intros p Hp s s' Hs Hs' HPre Heval.
rewrite fold_call_length in Hs.
rewrite fold_call_length in Hs'.
apply r_n_inline_ps_inline in Heval;(try assumption).
apply (H p (Inline1.k_inliner_ps n ps));(try assumption).
+ rewrite fold_proc_length; assumption.
+ rewrite fold_proc_length; assumption.
Qed.
(** Modular Relational properties Verification **)
Lemma recursion_relational :
forall P Q p ps rcl,
relational_prop_proc_ctx rcl ps ->
relational_prop_ctx rcl ps P Q p ->
relational_prop P Q p ps.
Proof.
intros.
apply H0.
apply r_recursive_proc.
assumption.
Qed.
(** Extended Modular Relational properties Verification **)
Definition rela_pre qcl rcl (l : list Proc.t) : r_precondition :=
match l with
| [l1; l2] =>
(fun m =>
match m with
| [m1;m2] => (get_q_pre (qcl l1 l2)) m1 m2 /\
(get_r_pre (rcl l)) m
| _ => False
end)
| _ => empty_r_precondition
end.
Definition rela_post qcl rcl (l : list Proc.t) : r_postcondition :=
match l with
| [l1; l2] =>
(fun m m' =>
match m, m' with
| [m1;m2],[m3;m4] => (get_q_post (qcl l1 l2)) m1 m2 m3 m4 /\
(get_r_post (rcl l)) m m'
| _ ,_ => False
end)
| _ => empty_r_postcondition
end.
Definition rela_clause qcl rcl l: r_clause :=
(rela_pre qcl rcl l, rela_post qcl rcl l).
Lemma ext_recursion_relational :
forall P Q p ps rcl qcl,
quadruple_proc_ctx qcl ps ps ->
relational_prop_proc_ctx rcl ps ->
relational_prop_ctx
(fun l => if List.length l =? 2 then
rela_clause qcl rcl l
else rcl l)
ps P Q p ->
relational_prop P Q p ps.
Proof.
intros.
apply H1.
intros.
destruct (length p0) eqn: Hp0.
- inversion H2.
- destruct n.
+ apply r_recursive_proc.
assumption.
rewrite Hp0.
auto.
+ destruct n.
* simpl.
destruct p0. inversion Hp0.
destruct p0. inversion Hp0.
destruct p0;[|inversion Hp0].
intros s s' Hs Hs' HPre Heval.
destruct s. inversion Hs.
destruct s0. inversion Hs.
destruct s1;[|inversion Hs].
destruct s'. inversion Hs'.
destruct s'. inversion Hs'.
destruct s';[|inversion Hs'].
simpl. simpl in HPre.
split.
-- simpl in Heval.
inversion Heval;subst.
inversion H11;subst.
inversion H13;subst.
eapply ext_q_recursive_proc.
apply H. apply HPre.
auto. auto.
-- eapply r_recursive_proc.
eauto.
rewrite Hp0.
assumption.
reflexivity.
reflexivity.
apply HPre.
assumption.
* apply r_recursive_proc.
assumption.
rewrite Hp0.
auto.
Qed.