Skip to content

Commit b050c64

Browse files
authored
Merge pull request #587 from FStarLang/gebner_dup
Automation for duplicable.
2 parents bb45852 + 8ddada8 commit b050c64

37 files changed

Lines changed: 277 additions & 326 deletions

lib/pulse/lib/Pulse.Lib.AnchoredReference.fst

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,9 @@ fn dup_snapshot (#a:Type) (#p:_) (#anc:anchor_rel p) (r : ref a p anc) (#v:a)
277277
fold_snapshot r #v k
278278
}
279279

280+
instance duplicable_snapshot #t #pre #anc r v : duplicable (snapshot #t #pre #anc r v) =
281+
{ dup_f = fun _ -> dup_snapshot r }
282+
280283
ghost
281284
fn take_snapshot_core (#a:Type) (#p:_) (#f:perm) (#anc:anchor_rel p) (r : ref a p anc) (#b:bool) (#v:a)
282285
preserves core_pts_to r #f v b
@@ -313,7 +316,7 @@ fn take_snapshot_full (#a:Type) (#p:_) (#f:perm) (#anc:anchor_rel p) (r : ref a
313316
ghost
314317
fn recall_snapshot (#a:Type) (#p:_) (#anc:anchor_rel p) (r : ref a p anc) #f (#v0 #v:a)
315318
preserves pts_to r #f v
316-
preserves snapshot r v0
319+
requires snapshot r v0
317320
ensures pure (p v0 v /\ True)
318321
{
319322
unfold (pts_to r #f v);

lib/pulse/lib/Pulse.Lib.AnchoredReference.fsti

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,7 @@ fn recall_anchor (#a:Type) (#p:_) (#anc:anchor_rel p) (r : ref a p anc) (#v:a) (
119119
preserves anchored r va
120120
ensures pure (anc va v)
121121

122-
ghost
123-
fn dup_snapshot (#a:Type) (#p:_) (#anc:anchor_rel p) (r : ref a p anc) (#v:a)
124-
preserves snapshot r v
125-
ensures snapshot r v
122+
instance val duplicable_snapshot #t #pre #anc r v : duplicable (snapshot #t #pre #anc r v)
126123

127124
ghost
128125
fn take_snapshot (#a:Type) (#p:_) (#f:perm) (#anc:anchor_rel p) (r : ref a p anc) (#v:a)
@@ -137,5 +134,5 @@ fn take_snapshot_full (#a:Type) (#p:_) (#f:perm) (#anc:anchor_rel p) (r : ref a
137134
ghost
138135
fn recall_snapshot (#a:Type) (#p:_) (#anc:anchor_rel p) (r : ref a p anc) #f (#v0 #v:a)
139136
preserves pts_to r #f v
140-
preserves snapshot r v0
137+
requires snapshot r v0
141138
ensures pure (p v0 v /\ True)

lib/pulse/lib/Pulse.Lib.Array.Core.fst

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -118,14 +118,13 @@ let visibility_of_array #a (x:array a) : visibility = x.vis
118118
ghost fn is_send_across_pts_to_mask' u#a (#t: Type u#a) a f v mask : is_send_across (visibility_of_array a) (pts_to_mask #t a #f v mask) = l1 l2 {
119119
ghost_impersonate l1 (on l1 (pts_to_mask a #f v mask)) (on l2 (pts_to_mask a #f v mask)) fn _ {
120120
on_elim _;
121-
unfold pts_to_mask;
122-
loc_gather l1;
121+
unfold pts_to_mask; with l'. _;
122+
loc_gather l1 #l';
123123
ghost_impersonate l2
124124
(pcm_pts_to (lptr_of a) (mk_carrier' a f v mask (a.vis l1)) **
125125
pure (Seq.length v == reveal a.length /\ (mask_nonempty mask a.length ==> f <=. 1.0R)))
126126
(on l2 (pts_to_mask a #f v mask))
127127
fn _ {
128-
loc_dup l2;
129128
fold pts_to_mask a #f v mask;
130129
on_intro (pts_to_mask a #f v mask)
131130
}
@@ -219,7 +218,7 @@ ghost fn mask_ext u#a (#t: Type u#a) (arr: array t) #f #v #mask v' (mask': nat -
219218
fn mask_alloc_with_vis u#a (elt: Type u#a) {| small_type u#a |}
220219
(n: SZ.t) (#l:loc_id)
221220
(vis:visibility)
222-
preserves loc l
221+
requires loc l
223222
returns a: array elt
224223
ensures exists* (s : Seq.seq (option elt)).
225224
pure (Seq.length s == SZ.v n) **
@@ -230,7 +229,6 @@ fn mask_alloc_with_vis u#a (elt: Type u#a) {| small_type u#a |}
230229
visibility_of_array a == vis /\
231230
loc_id_of_array a == l)
232231
{
233-
loc_dup l;
234232
let v = mk_carrier #elt 0 (SZ.v n) 1.0R (Seq.create (SZ.v n) None) (fun _ -> true) (vis l);
235233
FStar.PCM.compatible_refl (pcm elt (SZ.v n)) v;
236234
let b = alloc #_ #(pcm elt (SZ.v n)) v;
@@ -253,7 +251,6 @@ fn mask_alloc u#a (elt: Type u#a) {| small_type u#a |} (n: SZ.t)
253251
{
254252
let l = loc_get ();
255253
let arr = mask_alloc_with_vis elt n process_of;
256-
drop_ (loc l);
257254
arr
258255
}
259256

@@ -299,7 +296,7 @@ ghost fn pcm_share u#a (#t: Type u#a) #l
299296
(a: array t) p s m
300297
(a1: array t) p1 s1 m1
301298
(a2: array t) p2 s2 m2
302-
preserves loc l
299+
requires loc l
303300
requires pts_to_mask a #p s m
304301
requires pure (Seq.length s1 == a1.length)
305302
requires pure (Seq.length s2 == a2.length)
@@ -315,8 +312,8 @@ ghost fn pcm_share u#a (#t: Type u#a) #l
315312
ensures pts_to_mask a1 #p1 s1 m1
316313
ensures pts_to_mask a2 #p2 s2 m2
317314
{
318-
unfold pts_to_mask a #p s m;
319-
loc_gather l;
315+
unfold pts_to_mask a #p s m; with l'. _;
316+
loc_gather l #l';
320317
share (lptr_of a) (mk_carrier' a1 p1 s1 m1 (a1.vis l)) (mk_carrier' a2 p2 s2 m2 (a2.vis l));
321318
rewrite
322319
pcm_pts_to (lptr_of a) (mk_carrier' a1 p1 s1 m1 (a1.vis l)) as
@@ -328,19 +325,17 @@ ghost fn pcm_share u#a (#t: Type u#a) #l
328325
let i2 = get_mask_idx m2 (length a2);
329326
assert pure (mask_nonempty m1 (length a1) ==>
330327
Some? (Map.sel (mk_carrier' a p s m (a.vis l)) (i1 + a1.offset)));
331-
loc_dup l;
332328
fold pts_to_mask a1 #p1 s1 m1;
333329
assert pure (mask_nonempty m2 (length a2) ==>
334330
Some? (Map.sel (mk_carrier' a p s m (a.vis l)) (i2 + a2.offset)));
335-
loc_dup l;
336331
fold pts_to_mask a2 #p2 s2 m2;
337332
}
338333

339334
ghost fn pcm_gather u#a (#t: Type u#a) #l
340335
(a: array t) p s m
341336
(a1: array t) p1 s1 m1
342337
(a2: array t) p2 s2 m2
343-
preserves loc l
338+
requires loc l
344339
requires pure (Seq.length s == a.length)
345340
requires pure (
346341
a1.base_len == a.base_len /\ a2.base_len == a.base_len /\
@@ -360,10 +355,10 @@ ghost fn pcm_gather u#a (#t: Type u#a) #l
360355
`Map.equal` mk_carrier' a p s m (a.vis l)
361356
)
362357
{
363-
unfold pts_to_mask a1 #p1 s1 m1;
364-
loc_gather l;
365-
unfold pts_to_mask a2 #p2 s2 m2;
366-
loc_gather l;
358+
unfold pts_to_mask a1 #p1 s1 m1; with l'. _;
359+
loc_gather l #l'; rewrite each l' as l;
360+
unfold pts_to_mask a2 #p2 s2 m2; with l'. _;
361+
loc_gather l #l'; rewrite each l' as l;
367362
rewrite
368363
pcm_pts_to (lptr_of a1) (mk_carrier' a1 p1 s1 m1 (a1.vis l)) as
369364
pcm_pts_to (lptr_of a) (mk_carrier' a1 p1 s1 m1 (a1.vis l));
@@ -374,7 +369,6 @@ ghost fn pcm_gather u#a (#t: Type u#a) #l
374369
let i = get_mask_idx m (length a);
375370
assert pure (mask_nonempty m a.length ==>
376371
Map.sel (mk_carrier' a p s m (a.vis l)) (i + a.offset) == Some ((Seq.index s i, a.vis l), p));
377-
loc_dup l;
378372
fold pts_to_mask a #p s m;
379373
}
380374

@@ -391,7 +385,6 @@ fn mask_share_gen u#a (#a: Type u#a) (arr:array a) #s #p (p1: perm) (p2: perm) #
391385
arr p s mask
392386
arr p1 s mask
393387
arr p2 s mask;
394-
drop_ (loc _);
395388
}
396389

397390
ghost
@@ -423,7 +416,6 @@ ghost fn mask_gather u#a (#t: Type u#a) (arr: array t) #p1 #p2 #s1 #s2 #mask1 #m
423416
assert pure (forall (i: nat). (i < Seq.length s1 /\ mask1 i) ==>
424417
Map.sel (mk_carrier' arr p1 s1 mask1 (process_of l)) (i + arr.offset) ==
425418
Some ((Seq.index s1 i, process_of l), p1));
426-
drop_ (loc l);
427419
}
428420

429421
ghost fn split_mask u#a (#t: Type u#a) (arr: array t) #f #v #mask (pred: nat -> prop)
@@ -437,7 +429,6 @@ ghost fn split_mask u#a (#t: Type u#a) (arr: array t) #f #v #mask (pred: nat ->
437429
arr f v mask
438430
arr f v (mask_isect mask pred)
439431
arr f v (mask_diff mask pred);
440-
drop_ (loc _);
441432
}
442433

443434
let mix #t (v1: Seq.seq t) (v2: Seq.seq t { Seq.length v1 == Seq.length v2 }) (mask: nat -> prop) :
@@ -469,7 +460,6 @@ ghost fn join_mask u#a (#t: Type u#a) (arr: array t) #f #v1 #v2 #mask1 #mask2
469460
arr f v mask
470461
arr f v1 mask1
471462
arr f v2 mask2;
472-
drop_ (loc _);
473463
}
474464

475465
[@@allow_ambiguous]
@@ -492,15 +482,13 @@ fn pts_to_mask_injective_eq u#a (#a: Type u#a) #p0 #p1 #s0 #s1 #mask0 #mask1 (ar
492482
(forall (i: nat). i < Seq.length s0 /\ mask0 i /\ mask1 i ==>
493483
Seq.index s0 i == Seq.index s1 i))
494484
{
495-
unfold pts_to_mask arr #p0 s0 mask0;
496-
with l. assert loc l;
497-
unfold pts_to_mask arr #p1 s1 mask1;
498-
loc_gather l;
485+
unfold pts_to_mask arr #p0 s0 mask0; with l. _;
486+
unfold pts_to_mask arr #p1 s1 mask1; with l'. _;
487+
loc_gather l #l';
499488
gather (lptr_of arr) (mk_carrier' arr p0 s0 mask0 (arr.vis l)) (mk_carrier' arr p1 s1 mask1 (arr.vis l));
500489
share (lptr_of arr) (mk_carrier' arr p0 s0 mask0 (arr.vis l)) (mk_carrier' arr p1 s1 mask1 (arr.vis l));
501490
assert pure (forall (i: nat). i < Seq.length s0 /\ mask0 i ==>
502491
Map.sel (mk_carrier' arr p0 s0 mask0 (arr.vis l)) (i + arr.offset) == Some ((Seq.index s0 i, arr.vis l), p0));
503-
loc_dup l;
504492
fold pts_to_mask arr #p0 s0 mask0;
505493
fold pts_to_mask arr #p1 s1 mask1;
506494
}

lib/pulse/lib/Pulse.Lib.Array.Core.fsti

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ ghost fn mask_ext u#a (#t: Type u#a) (arr: array t) #f #v #mask v' (mask': nat -
109109
fn mask_alloc_with_vis u#a (elt: Type u#a) {| small_type u#a |}
110110
(n: SZ.t) (#l:loc_id)
111111
(vis:visibility)
112-
preserves loc l
112+
requires loc l
113113
returns a: array elt
114114
ensures exists* (s : Seq.seq (option elt)).
115115
pure (Seq.length s == SZ.v n) **

0 commit comments

Comments
 (0)