-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSaturationLoop.v
More file actions
675 lines (557 loc) · 14 KB
/
SaturationLoop.v
File metadata and controls
675 lines (557 loc) · 14 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
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
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
(* Time-stamp: <Wed 11/22/23 11:28 Dan Dougherty SaturationLoop.v> *)
From Coq Require Import
List
String
Classical_Prop
Classical_Pred_Type
Wellfounded
.
Import ListNotations.
From RC Require Import
CpdtTactics
TacticsMatch
Utilities
Decidability
ListUtil
Iteration
Act
Sorts
Term
Role
Proc
SaturationClass
SaturationRules
.
(** ** The Closure loop *)
(* ======================================= *)
Section Close.
Variable unv: Terms.
(** Firing the closure rules to acheive being closed *)
Definition max_term_size : nat :=
list_max (map size_term unv).
Definition do_step (pr: Proc) : Stmts :=
apply_first_not_nil
[
do_pairE ;
do_encrE ;
do_hashChck ;
do_pairI unv ;
do_encrI unv;
do_hashI unv ;
do_qotChck ;
do_sortChck ;
do_sameChck ;
do_kyprChck
] pr.
Lemma do_step_is (pr: Proc) :
do_step pr = do_pairE pr
\/ do_step pr = do_encrE pr
\/ do_step pr = do_hashChck pr
\/ do_step pr = do_pairI unv pr
\/ do_step pr = do_encrI unv pr
\/ do_step pr = do_hashI unv pr
\/ do_step pr = do_qotChck pr
\/ do_step pr = do_sortChck pr
\/ do_step pr = do_sameChck pr
\/ do_step pr = do_kyprChck pr .
Proof.
unfold do_step;
unfold apply_first_not_nil;
(* destruct (do_pairEL pr); *)
destruct (do_pairE pr);
destruct (do_encrE pr);
destruct (do_hashChck pr);
destruct (do_pairI unv pr);
destruct (do_encrI unv pr);
destruct (do_hashI unv pr);
destruct (do_qotChck pr);
destruct (do_sortChck pr);
destruct (do_sameChck pr);
destruct (do_kyprChck pr);
tauto.
Qed.
Definition close_step (pr: Proc) : Proc :=
pr ++ (do_step pr).
Lemma close_step_is (pr: Proc) :
close_step pr = pr ++ do_pairE pr
(* \/ close_step pr = pr ++ do_pairER pr *)
\/ close_step pr = pr ++ do_encrE pr
\/ close_step pr = pr ++ do_hashChck pr
\/ close_step pr = pr ++ do_pairI unv pr
\/ close_step pr = pr ++ do_encrI unv pr
\/ close_step pr = pr ++ do_hashI unv pr
\/ close_step pr = pr ++ do_qotChck pr
\/ close_step pr = pr ++ do_sortChck pr
\/ close_step pr = pr ++ do_sameChck pr
\/ close_step pr = pr ++ do_kyprChck pr.
Proof.
unfold close_step.
assert (h:= do_step_is pr).
destruct h as
[h1 | [h2 | [h3 | [h4 | [h5 | [h6 | [h7 | [h8 | [h9 | h10]]]]]]]]].
rewrite h1; tauto.
rewrite h2; tauto.
rewrite h3; tauto.
rewrite h4; tauto.
rewrite h5; tauto.
rewrite h6; tauto.
rewrite h7; tauto.
rewrite h8; tauto.
rewrite h9; tauto.
rewrite h10; tauto.
Qed.
Definition close_steps_n : nat -> Proc -> Proc :=
loop (close_step).
Definition proc_measure (pr: Proc) : nat :=
((length unv) + (3 * max_term_size)) .
Definition close (pr: Proc) : Proc :=
close_steps_n (proc_measure pr) pr .
(* -----------------------*)
(** For testing *)
Definition close_n_diff
(n: nat) (pr: Proc) : Proc:=
set_diff (close_steps_n n pr)
pr.
Definition close_diff
(pr: Proc) : Proc:=
set_diff (close pr) pr.
End Close.
(* ------------------------------ *)
(** * Properties *)
(** ** Closed *)
Definition closed
(unv : Terms) (pr: Proc) :=
pairE_closed pr
/\ pairI_closed unv pr
/\ encrE_closed pr
/\ encrI_closed unv pr
/\ hashI_closed unv pr
/\ hashChck_closed pr
/\ sameChck_closed pr
/\ sortChck_closed pr
/\ qotChck_closed pr
/\ kyprChck_closed pr
.
#[export]
Instance closed_dec :
forall (unv: Terms) (pr: Proc) ,
(Decision (closed unv pr)).
Proof.
intros unv pr. unfold closed.
apply _.
Defined.
(* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *)
(* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *)
(** ** Justified *)
(** Do we have all the minor premisses we should ? *)
(** *** Justified Hashes *)
(* *)
(** A hash is justified if we know its body *)
Definition hash_justified
(pr: Proc) (s: Stmt) :=
match s with
| (Bind ((Hs t), _) _) =>
term_is_bound pr t
| _ => True
end.
#[export]
Instance hash_justified_dec :
forall pr s, Decision (hash_justified pr s).
Proof.
intros pr s.
unfold hash_justified;
destruct s; auto.
destruct t; auto.
destruct t; auto.
apply term_is_bound_dec.
Defined.
(** IF smt is a bind of some [Hs t] then [t] is bound as well *)
Definition hash_justifiedb (pr: Proc) (smt: Stmt) :bool :=
match smt with
Bind ((Hs t), _ ) _ =>
term_is_boundb pr t
|_ => true
end.
Definition hashes_justified (pr: Proc) : Prop :=
forall s, In s pr -> hash_justified pr s.
(* *)
Global Instance hashes_justified_dec pr :
Decision (hashes_justified pr).
apply _.
Defined.
Definition hashes_justifiedb (pr: Proc) : bool :=
forallb (hash_justifiedb pr) pr.
(** *** Justified Encryptions *)
(** An encryption is [justified] if either we built it or the symbolic
inverse of its encryption key is available *)
Definition encryption_justifiedb
(pr: Proc) (smt: Stmt) : bool :=
match smt with
(Bind ((En p k), _) ee) =>
is_encr_expb ee ||
term_is_boundb pr (inv k)
| _ => true
end.
Definition encryptions_justifiedb (pr: Proc) :=
forallb (encryption_justifiedb pr) pr.
Definition encryption_justified
(pr: Proc) (smt: Stmt) : Prop :=
match smt with
(Bind ((En p k), _) ee) =>
(* is_encr_exp ee \/ *)
(is_encr_expression_for pr
(En p k) ee) = true \/
term_is_bound pr (inv k)
| _ => True
end.
Global Instance encryption_justified_dec pr smt :
Decision (encryption_justified pr smt).
Proof.
hnf.
(* unfold hash_justified. *)
destruct smt as [[ t l] e | ev | l1 l2 | l1 l2 | l1 l2 | l s | l s |s].
shelve.
all: left; simpl; easy.
Unshelve.
destruct t.
10: shelve.
all: left; simpl; easy.
Unshelve.
unfold encryption_justified.
apply or_dec; apply _.
Defined.
Definition encryptions_justified (pr: Proc) : Prop :=
forall s, In s pr -> encryption_justified pr s.
Global Instance encryptions_justified_dec pr :
Decision (encryptions_justified pr ).
Proof.
apply _.
Defined.
(** *** Justified *)
Definition justified_pr (pr: Proc) :=
hashes_justified pr
/\ encryptions_justified pr .
(* *)
#[export]
Instance justified_pr_dec :
forall pr, Decision (justified_pr pr).
Proof.
apply _.
Defined.
Definition justifiedb_pr (pr: Proc) : bool :=
hashes_justifiedb pr && encryptions_justifiedb pr .
(** ** Summary : Saturation *)
Definition saturated_pr
(unv: Terms) (pr: Proc) : Prop :=
closed unv pr
/\ justified_pr pr
.
(* *)
#[export] Instance saturated_pr_dec :
forall (unv: Terms) (pr: Proc) ,
(Decision (saturated_pr unv pr)).
Proof.
intros unv pr. apply _.
Defined.
(** To saturate is to do closure, then
test for being justified
*)
Definition saturate
(unv: Terms) (pr: Proc) : optionE Proc :=
let closepr := (close unv pr) in
match decide (closed unv closepr) with
right _ => NoneE
"saturation leaves non-closed proc"
| left _ =>
match decide (justified_pr closepr) with
| right _ => NoneE
"saturation leaves unjustified proc"
| left _ =>
SomeE closepr
end end
.
(* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *)
(** * Proofs *)
(** ** Proofs about the empty pr *)
(* --- *)
(** The initial, empty, pr will be saturated *)
Lemma empty_saturated_pr :
forall unv, saturated_pr unv [].
Proof.
unfold saturated_pr.
intros; split.
- unfold closed.
split;
hnf; intros; easy.
- split; hnf; intros; easy.
Qed.
(** ** Proofs about Closedness *)
(** *** Closing Yields Closed *)
(**
This asserts that we have reached a fixed point for the saturation rules.
If this fails it is a program bug, eg not doing enough iterations.
Not used currently
*)
(* Theorem close_is_closed : *)
(* forall (unv: Terms) (pr: Proc), *)
(* closed unv (close unv pr) . *)
(** *** Succesful saturation is really closing *)
Lemma sat_is_close unv pr pr' :
saturate unv pr = SomeE pr' ->
pr' = close unv pr.
Proof.
intros H.
unfold saturate in H.
destruct_all_matches.
Qed.
Lemma saturate_gives_saturated unv pr pr' :
saturate unv pr = SomeE pr' ->
saturated_pr unv pr'.
Proof.
unfold saturate; unfold saturated_pr; intros H.
destruct_all_matches. crush.
Qed.
(** ** Proofs about Justified *)
Lemma hashes_justified_then pr t lh eh :
hashes_justified pr ->
In (Bind ((Hs t), lh) eh) pr ->
exists lt et,
In (Bind (t,lt) et) pr.
Proof. intros H1 H2.
unfold hashes_justified in *.
specialize (H1 (Bind ((Hs t),lh) eh) H2).
unfold hash_justified in *.
apply H1.
Qed.
Lemma encryptions_justified_then pr p k le ee :
encryptions_justified pr ->
In (Bind ((En p k), le) ee) pr ->
(* is_encr_exp ee \/ *)
(is_encr_expression_for pr
(En p k) ee) = true \/
exists ld ed,
In (Bind ( (inv k) , ld) ed) pr.
Proof. intros H1 H2.
unfold encryptions_justified in *.
specialize (H1 (Bind ((En p k), le) ee) H2) .
unfold encryption_justified in *.
destruct H1.
- now left.
- right.
hnf in H.
apply H.
Qed.
(** ** Saturation is inflationary *)
(* prove it for one close-step *)
Lemma close_step_superset sts unv :
subset sts (close_step unv sts).
Proof.
assert (h:= close_step_is unv sts).
assert (h0:= subset_app_introR).
apply h0.
Qed.
(* thence for any number of steps *)
Proposition close_steps_superset sts unv k :
subset sts (close_steps_n unv k sts).
Proof.
unfold close_steps_n.
apply Iteration.pre_post.
- unfold reflexive.
apply subset_refl.
- unfold transitive.
apply subset_trans.
- intros. apply close_step_superset.
Qed.
Theorem saturate_superset (unv: Terms) (sts x: list Stmt) :
saturate unv sts = SomeE x ->
subset sts x.
Proof.
intros H.
unfold saturate in H.
destruct_all_matches.
inv H.
apply close_steps_superset.
Qed.
(** ** Saturation doesn't change the trace *)
(* boilerplate, each rule, ... zzzzz *)
Lemma do_pairE_trace sts :
prtrace (do_pairE sts) = [].
Proof.
unfold do_pairE;
destruct (pick_pairE_redex sts).
unfold fire_pairE.
destruct x.
(* destruct (proj1_sig s). *)
destruct t; destruct t.
all: auto.
Qed.
Lemma do_encrE_trace sts :
prtrace (do_encrE sts) = [].
Proof.
unfold do_encrE;
destruct (pick_encrE_redex sts);
unfold fire_encrE.
destruct (proj1_sig s).
destruct s0. destruct t.
all: auto.
destruct t.
all: auto.
destruct s1.
all: auto.
destruct t.
all: auto.
Qed.
Lemma do_hashChck_trace sts :
prtrace (do_hashChck sts) = [].
Proof.
unfold do_hashChck;
destruct (pick_hashChck_redex sts);
unfold fire_hashChck.
destruct (proj1_sig s).
destruct s0. all: auto.
destruct t. all: auto.
destruct t. all: auto.
destruct s1. all: auto.
destruct t0 as [t3 ln].
destruct (decide (t=t3)). all: auto.
Qed.
Lemma do_pairI_trace unv sts :
prtrace (do_pairI unv sts) = [].
Proof.
unfold do_pairI;
destruct (pick_pairI_redex unv sts);
unfold fire_pairI.
destruct x; auto.
destruct s; auto.
destruct t; auto.
destruct s0; auto.
destruct t0; auto.
auto.
Qed.
Lemma do_encrI_trace unv sts :
prtrace (do_encrI unv sts) = [].
Proof.
unfold do_encrI;
destruct (pick_encrI_redex unv sts);
unfold fire_encrI.
destruct x; auto.
destruct s; auto.
destruct t; auto.
destruct s0; auto.
destruct t0; auto.
auto.
Qed.
Lemma do_hashI_trace unv sts :
prtrace (do_hashI unv sts) = [].
Proof.
unfold do_hashI;
destruct (pick_hashI_redex unv sts);
unfold fire_hashI.
destruct x; auto.
destruct t; auto.
auto.
Qed.
Lemma do_qotChck_trace sts :
prtrace (do_qotChck sts) = [].
Proof.
unfold do_qotChck;
destruct (pick_qotChck_redex sts);
unfold fire_qotChck.
destruct (proj1_sig s).
destruct t; destruct t.
all: auto.
Qed.
Lemma do_sortChck_trace sts :
prtrace (do_sortChck sts) = [].
Proof.
unfold do_sortChck;
destruct (pick_sortChck_redex sts);
unfold fire_sortChck.
destruct (proj1_sig s).
destruct t; destruct t.
all: auto.
Qed.
Lemma do_sameChck_trace sts :
prtrace (do_sameChck sts) = [].
Proof.
unfold do_sameChck;
destruct (pick_sameChck_redex sts);
unfold fire_sameChck.
destruct (proj1_sig s); auto.
- destruct t; auto.
- auto.
Qed.
Lemma do_kyprChck_trace sts :
prtrace (do_kyprChck sts) = [].
Proof.
unfold do_kyprChck;
destruct (pick_kyprChck_redex sts);
unfold fire_kyprChck.
destruct (proj1_sig s).
destruct s0; auto.
destruct t; auto.
destruct s1; auto.
all: auto.
destruct t0; auto.
Qed.
(* prove it for one close_step, using all the individual step results
*)
Lemma close_step_trace sts unv :
prtrace (close_step unv sts) = prtrace sts.
Proof.
assert (h:= close_step_is unv sts).
assert (h0 := prtrace_app).
destruct h as
[h1 | [h2 | [h3 | [h4 | [h5 | [h6 | [h7 | [h8 | [h9 | ]]]]]]]]].
- rewrite h1; rewrite h0;
rewrite do_pairE_trace;
apply app_nil_r.
- rewrite h2; rewrite h0;
rewrite do_encrE_trace;
apply app_nil_r.
- rewrite h3; rewrite h0;
rewrite do_hashChck_trace;
apply app_nil_r.
- rewrite h4; rewrite h0;
rewrite do_pairI_trace;
apply app_nil_r.
- rewrite h5; rewrite h0;
rewrite do_encrI_trace;
apply app_nil_r.
- rewrite h6; rewrite h0;
rewrite do_hashI_trace;
apply app_nil_r.
- rewrite h7; rewrite h0;
rewrite do_qotChck_trace;
apply app_nil_r.
- rewrite h8; rewrite h0;
rewrite do_sortChck_trace;
apply app_nil_r.
- rewrite h9; rewrite h0;
rewrite do_sameChck_trace;
apply app_nil_r.
- rewrite H; rewrite h0;
rewrite do_kyprChck_trace;
apply app_nil_r.
Qed.
Proposition close_trace unv pr :
prtrace (close unv pr) = prtrace pr.
Proof.
unfold close.
unfold close_steps_n.
apply Iteration.pre_post.
- unfold reflexive.
auto.
- unfold transitive.
intros. congruence.
- intros. apply close_step_trace.
Qed.
Theorem saturate_trace unv pr pr' :
saturate unv pr = SomeE pr' ->
prtrace pr' = prtrace pr.
Proof.
intros H.
apply sat_is_close in H.
rewrite H.
apply close_trace.
Qed.