Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions lib/common/Pulse.Lib.Core.fsti
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,16 @@ let match_rewrite_tac (_:unit) : T.Tac unit =
T.mapply (`slprop_equiv_ext');
T.trefl ()

let match_rename_tac (_:unit) : T.Tac unit =
let open T in
let b = T.nth_var (-1) in
T.norm []; // Needed, or otherwise the `tcut` in grewrite_eq can fail, unsure why.
try (
T.grewrite_eq b;
T.trefl ()
)
with _ -> T.smt()

[@@deprecated "Use (rewrite .. as .. by ..) syntax instead!"]
val rewrite_by (p:slprop) (q:slprop)
(t:unit -> T.Tac unit)
Expand Down
18 changes: 3 additions & 15 deletions lib/pulse/lib/Pulse.Lib.AVLTree.fst
Original file line number Diff line number Diff line change
Expand Up @@ -120,14 +120,16 @@ fn cases_of_is_tree #t (x:tree_t t) (ft:T.tree t)
T.Leaf -> {
unfold (is_tree x T.Leaf);
fold (is_tree_cases None ft);
rewrite is_tree_cases None ft as is_tree_cases x ft;
}
T.Node data ltree rtree -> {
unfold (is_tree x (T.Node data ltree rtree));
with p lct rct. _;
with n. assert p |-> n;
with l'. rewrite is_tree lct l' as is_tree n.left l';
with r'. rewrite is_tree rct r' as is_tree n.right r';
fold (is_tree_cases (Some p) (T.Node data ltree rtree))
fold (is_tree_cases (Some p) ft);
rewrite (is_tree_cases (Some p) ft) as is_tree_cases x ft;
}
}
}
Expand Down Expand Up @@ -240,8 +242,6 @@ fn node_cons (#t:Type0) (v:t) (ltree:tree_t t) (rtree:tree_t t) (#l:(T.tree t))
ensures is_tree y (T.Node v l r) ** (pure (Some? y))
{
let y = Box.alloc { data=v; left =ltree; right = rtree };
rewrite each ltree as ({data = v; left = ltree; right = rtree}).left in (is_tree ltree l);
rewrite each rtree as ({data = v; left = ltree; right = rtree}).right in (is_tree rtree r);
intro_is_tree_node (Some y) y;
Some y
}
Expand Down Expand Up @@ -293,18 +293,12 @@ fn rec append_left (#t:Type0) (x:tree_t t) (v:t) (#ft:G.erased (T.tree t))

is_tree_case_some (Some vl) vl;

with _node _ltree _rtree._;

let node = !vl;

let left_new = append_left node.left v;

vl := {node with left = left_new};

rewrite each left_new as ({ node with left = left_new }).left in (is_tree left_new ((T.append_left (reveal _ltree) v)));

rewrite each node.right as ({ node with left = left_new }).right in (is_tree node.right _rtree);

intro_is_tree_node x vl;

x
Expand Down Expand Up @@ -344,18 +338,12 @@ fn rec append_right (#t:Type0) (x:tree_t t) (v:t) (#ft:G.erased (T.tree t))
Some np -> {
is_tree_case_some (Some np) np;

with _node _ltree _rtree._;

let node = !np;

let right_new = append_right node.right v;

np := {node with right = right_new};

rewrite each right_new as ({ node with right = right_new }).right in (is_tree right_new ((T.append_right (reveal _rtree) v)));

rewrite each node.left as ({node with right = right_new}).left in (is_tree node.left _ltree);

intro_is_tree_node x np;

x
Expand Down
10 changes: 5 additions & 5 deletions lib/pulse/lib/Pulse.Lib.Borrow.fst
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ noeq type blockchain_root = {
type lifetime : Type0 =
ref blockchain_root

let fpts_to #t (r: ref t) (x: t) = exists* p. pts_to r #p x
let fpts_to #t ([@@@mkey] r: ref t) (x: t) = exists* p. pts_to r #p x

ghost fn dup_fpts_to u#t (t: Type u#t) r x () : duplicable_f (fpts_to #t r x) = {
unfold fpts_to r x;
Expand Down Expand Up @@ -189,7 +189,7 @@ type stored_shape =
| Stored
| StoredBoth : stored_shape -> stored_shape -> stored_shape

let rec bc_stored ([@@@mkey] x: blockchain_edge) ([@@@mkey] d: stored_shape) (y: slprop) : Tot slprop (decreases d) =
let rec bc_stored ([@@@mkey] x: blockchain_edge) (d: stored_shape) (y: slprop) : Tot slprop (decreases d) =
match d with
| Stored -> exists* z. slprop_ref_pts_to x.be_prop z ** later z ** trade (later z) y
| StoredCheckedOut -> live x.be_ref ** y
Expand All @@ -199,15 +199,15 @@ let rec bc_stored ([@@@mkey] x: blockchain_edge) ([@@@mkey] d: stored_shape) (y:
bc_stored b db yb **
trade (ya ** yb) y

let rec rt_stored ([@@@mkey] x: ref blockchain_root) ([@@@mkey] n: unat) (b: slprop) : Tot slprop (decreases n) =
let rec rt_stored ([@@@mkey] x: ref blockchain_root) (n: unat) (b: slprop) : Tot slprop (decreases n) =
match n with
| Zero -> trade emp b
| Succ n -> exists* r (b1 b2: slprop). fpts_to x r **
(exists* d. bc_stored r.rt_tree d b1) **
rt_stored r.rt_next n b2 **
trade (b1 ** b2) b

let owns_end ([@@@mkey] x: ref blockchain_root) ([@@@mkey] n: unat) =
let owns_end ([@@@mkey] x: ref blockchain_root) (n: unat) =
exists* y. root_idx x n y ** live y

ghost fn elim_owns_end_zero x
Expand Down Expand Up @@ -574,7 +574,7 @@ ghost fn share_borrow' #a (p q1 q2: slprop)
dup (slprop_ref_pts_to eb.be_prop q2) ();
fold valid_split l.be_prop ea.be_prop eb.be_prop;
dup (bc_idx r.rt_tree is l) ();
dup (valid_split l.be_prop ra rb) ();
dup (valid_split l.be_prop ea.be_prop eb.be_prop) ();
push_bc_idx r.rt_tree is false l;
push_bc_idx r.rt_tree is true l;
dup (root_idx' a n r) ();
Expand Down
4 changes: 2 additions & 2 deletions lib/pulse/lib/Pulse.Lib.CancellableInvariant.fsti
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ val cinv : Type0
instance val non_informative_cinv
: NonInformative.non_informative cinv

val cinv_vp (c:cinv) (v:slprop) : slprop
val cinv_vp ([@@@mkey] c:cinv) (v:slprop) : slprop

val active (c:cinv) (p:perm) : slprop
val active ([@@@mkey] c:cinv) (p:perm) : slprop

val active_timeless (c:cinv) (p:perm)
: Lemma (timeless (active c p))
Expand Down
2 changes: 1 addition & 1 deletion lib/pulse/lib/Pulse.Lib.ConditionVar.fst
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ ensures
later_intro (cvar_inv b.core p);
drop_ (Box.pts_to b.core.r #0.5R _)
};
drop_ _
drop_ (inv _ _)
}

fn signal (c:cvar_t) (#p:slprop)
Expand Down
20 changes: 4 additions & 16 deletions lib/pulse/lib/Pulse.Lib.Deque.fst
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,6 @@ type deque (t:Type0) = {
tail: option (node_ptr t);
}

(* Note: since within this module there is usually a *single* linked list
around, we mark the list predicated with no_mkeys so the matcher can be
more liberal. Crucially, this attribute is only set behind the interface,
and clients will just use the mkey in is_deque.

This is a bit of a hack, the fact that F* allows the attributes to differ
between fst/fsti is probably wrong. Maybe we should have a typeclass? *)

[@@no_mkeys]
let rec is_deque_suffix
(#t:Type0)
([@@@mkey] p:node_ptr t)
Expand Down Expand Up @@ -82,7 +73,6 @@ fn fold_is_deque_suffix_cons



[@@no_mkeys]
let is_deque #t ([@@@mkey] x:deque t) (l:list t)
: Tot slprop (decreases l)
= match l with
Expand Down Expand Up @@ -120,7 +110,7 @@ fn push_front_empty (#t:Type) (l : deque t) (x : t)
};
let node = Box.alloc vnode;

fold (is_deque_suffix node [x] None node);
fold (is_deque_suffix node [x] None node None);

let l' = {
head = Some node;
Expand Down Expand Up @@ -287,10 +277,8 @@ let is_deque_suffix_factored
: Tot slprop
= exists* (v:node t).
pts_to x v **
pure (
v.value == List.Tot.hd l /\
v.dprev == prev
) **
pure (v.value == List.Tot.hd l) **
pure (v.dprev == prev) **
is_deque_suffix_factored_next x l tail last v.dnext


Expand Down Expand Up @@ -655,7 +643,7 @@ fn pop_front (#t:Type) (l : deque t)
{
let b = is_singleton l;
if b {
pop_front_nil l;
pop_front_nil l #x;
} else {
pop_front_cons l;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/pulse/lib/Pulse.Lib.Forall.fst
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ fn elim_forall u#a
{
unfold (forall* x. p x);
unfold uquant (F.on_dom a (fun x -> p x));
with v. assert token v; unfold token v;
with v. unfold token v;
extract_q v (F.on_domain a (fun x -> p x)) () x;
}

Expand Down
24 changes: 8 additions & 16 deletions lib/pulse/lib/Pulse.Lib.GhostPCMReference.fst
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ fn read u#a
returns v:(v:a { compatible p x v /\ p.refine v })
ensures pts_to r (f v)
{
with inst. assert small_token u#a inst; let inst = inst;
with inst. unfold small_token u#a inst; let inst = inst; fold small_token inst;
U.downgrade_val (C.ghost_read #(U.raise_t a) #(raise p) r (hide (U.raise_val (reveal x))) (raise_refine p x f));
}

Expand Down Expand Up @@ -92,7 +92,7 @@ fn write u#a
requires pts_to r x
ensures pts_to r y
{
with inst. assert small_token u#a inst; let inst = inst;
with inst. unfold small_token u#a inst; let inst = inst; fold small_token inst;
C.ghost_write #(U.raise_t a) #(raise p) r (hide (U.raise_val (reveal x))) (hide (U.raise_val (reveal y)))
(raise_upd f)
}
Expand All @@ -107,18 +107,12 @@ fn share u#a
requires pts_to r (v0 `op pcm` v1)
ensures pts_to r v0 ** pts_to r v1
{
with inst. assert small_token u#a inst; let inst = inst;
fold small_token u#a inst;
with inst. unfold small_token u#a inst; let inst = inst;
fold small_token inst;
fold small_token inst;
C.ghost_share #_ #(PR.raise pcm) r (U.raise_val v0) (U.raise_val v1)
}

[@@allow_ambiguous]
ghost fn drop_amb (p: slprop)
requires p
{
drop_ p
}

[@@allow_ambiguous]
ghost
fn gather u#a
Expand All @@ -131,11 +125,9 @@ fn gather u#a
returns squash (composable pcm v0 v1)
ensures pts_to r (op pcm v0 v1)
{
with inst. assert C.ghost_pcm_pts_to #_ #(raise #a #inst pcm) r (U.raise_val v1);
with inst'. assert C.ghost_pcm_pts_to #_ #(raise #a #inst' pcm) r (U.raise_val v1);
drop_amb (small_token u#a inst');
let inst = inst;
C.ghost_gather #_ #(PR.raise pcm) r (U.raise_val v0) (U.raise_val v1)
with inst. assert C.ghost_pcm_pts_to #_ #(raise #a #inst pcm) r (U.raise_val #a #inst v1);
drop_ (small_token inst);
C.ghost_gather #_ #(PR.raise #a #inst pcm) r (U.raise_val #a #inst v0) (U.raise_val #a #inst v1)
}

ghost fn pts_to_not_null u#a (#a:Type u#a)
Expand Down
2 changes: 0 additions & 2 deletions lib/pulse/lib/Pulse.Lib.HashTable.fst
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,6 @@ fn delete
if (voff = ht.sz)
{
cont := false;
rewrite each vcont as false; // also relying on #110
}
else
{
Expand Down Expand Up @@ -584,7 +583,6 @@ fn delete
{
cont := false;
assert (pure (pht.repr == (PHT.delete pht k).repr));
rewrite each vcont as false; // also relying on #110
}
Zombie ->
{
Expand Down
4 changes: 2 additions & 2 deletions lib/pulse/lib/Pulse.Lib.HashTable.fsti
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@ let related #kt #vt (ht:ht_t kt vt) (pht:pht_t kt vt) : prop =
SZ.v ht.sz == pht.repr.sz /\
pht.repr.hashf == lift_hash_fun ht.hashf

let models #kt #vt (ht:ht_t kt vt) (pht:pht_t kt vt) : slprop =
let models #kt #vt ([@@@mkey]ht: ht_t kt vt) (pht:pht_t kt vt) : slprop =
V.pts_to ht.contents pht.repr.seq **
pure (related ht pht /\
V.is_full_vec ht.contents /\
SZ.fits (2 `op_Multiply` SZ.v ht.sz))

val models_timeless #kt #vt (ht:ht_t kt vt) (pht:pht_t kt vt)
val models_timeless #kt #vt ([@@@mkey] ht:ht_t kt vt) (pht:pht_t kt vt)
: Lemma (timeless (models ht pht))
[SMTPat (timeless (models ht pht))]

Expand Down
2 changes: 2 additions & 0 deletions lib/pulse/lib/Pulse.Lib.InsertionSort.fst
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ let step_outer_invariant
#pop-options


#push-options "--z3rlimit_factor 2"
fn insertion_sort u#a
(#t:Type u#a)
{| total_order t |}
Expand Down Expand Up @@ -202,6 +203,7 @@ ensures exists* s'. (a |-> s') **
with s'. assert (a |-> s');
assert pure (Seq.slice s' 0 (Seq.length s') `Seq.equal` s');
}
#pop-options

instance total_order_int : total_order int = {
compare = FStar.Order.compare_int;
Expand Down
19 changes: 13 additions & 6 deletions lib/pulse/lib/Pulse.Lib.LinkedList.fst
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,9 @@ fn move_next (#t:Type) (x:llist t)
let node = !np;
intro_yields_cons np;
rewrite each (Some np) as x;
with tl. assert is_list node.tail tl;
rewrite trade (is_list node.tail tl) (is_list x (node.head :: tl))
as trade (is_list node.tail tl) (is_list x 'l);
node.tail
}

Expand Down Expand Up @@ -408,20 +411,24 @@ fn non_empty_list (#t:Type0) (x:llist t)
intro_is_list_cons x v #n #tl;
}

let is_cons #t ([@@@mkey] x: list t) hd tl = pure (x == hd :: tl)

fn move_next_forall (#t:Type) (x:llist t)
requires is_list x 'l ** pure (Some? x)
returns y:llist t
ensures exists* hd tl.
is_list y tl **
(forall* tl'. is_list y tl' @==> is_list x (hd::tl')) **
pure ('l == hd::tl)
is_cons 'l hd tl
{
let np = Some?.v x;
is_list_cases_some x np;
let node = !np;
intro (forall* tl'. is_list node.tail tl' @==> is_list x (node.head::tl')) #(np |-> node) fn _ tl' {
intro_is_list_cons x np;
};
with tl. assert is_list node.tail tl;
fold is_cons 'l node.head tl;
node.tail
}

Expand Down Expand Up @@ -458,14 +465,14 @@ fn append_iter (#t:Type) (x y:llist t)
with ll pfx sfx. _;
some_iff_cons ll;
let next = move_next_forall Pulse.Lib.Reference.(!cur);
with hd tl. _;
with hd tl. unfold is_cons sfx hd tl;
(* this is the key induction step *)
FA.trans_compose
(is_list next) (is_list ll) (is_list x)
(fun tl -> hd :: tl)
(fun tl -> reveal hd :: tl)
(fun tl -> pfx @ tl);
rewrite (forall* tl. is_list next tl @==> is_list x (pfx@(hd::tl)))
as (forall* tl. is_list next tl @==> is_list x ((pfx@[hd])@tl));
rewrite (forall* tl. is_list next tl @==> is_list x (pfx@(reveal hd::tl)))
as (forall* tl. is_list next tl @==> is_list x ((pfx@[reveal hd])@tl));
Pulse.Lib.Reference.(cur := next);
};
with ll pfx sfx. _;
Expand Down Expand Up @@ -526,7 +533,7 @@ fn split (#t:Type0) (x:llist t) (n:U32.t) (#xl:erased (list t))
{
with i ll pfx sfx. _;
let next = move_next_forall Pulse.Lib.Reference.(!cur);
with hd tl. _;
with hd tl. unfold is_cons sfx hd tl;
(* this is the key induction step *)
FA.trans_compose
(is_list next) (is_list ll) (is_list x)
Expand Down
2 changes: 1 addition & 1 deletion lib/pulse/lib/Pulse.Lib.MonotonicGhostRef.fst
Original file line number Diff line number Diff line change
Expand Up @@ -131,5 +131,5 @@ fn update (#t:Type) (#p:preorder t) (r:mref p) (#u:t) (v:t)
unfold pts_to;
with f h. assert (GR.pts_to r (f, h));
GR.write r _ _ (FP.mk_frame_preserving_upd p h v);
fold pts_to;
fold pts_to r #1.0R v;
}
2 changes: 1 addition & 1 deletion lib/pulse/lib/Pulse.Lib.Mutex.fst
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ fn unlock (#a:Type0) (#v:a -> slprop) (#p:perm) (m:mutex a) (mg:mutex_guard a)
unfold (mg `belongs_to` m);
with x. rewrite (pts_to mg x) as (R.pts_to (B.box_to_ref m.r) x);
B.to_box_pts_to m.r;
fold lock_inv;
fold lock_inv m.r v;
release m.l;
fold (mutex_live m #p v)
}
Expand Down
Loading
Loading