Skip to content

Commit 8a6619b

Browse files
Lef IoannidisCopilot
andcommitted
Strengthen push_back/pop_back postconditions with precise capacity
push_back: cap unchanged when room exists, doubled when full. pop_back: cap halved when size == cap/2 > 0, unchanged otherwise. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 12128d3 commit 8a6619b

2 files changed

Lines changed: 16 additions & 4 deletions

File tree

lib/pulse/lib/Pulse.Lib.Vector.fst

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,9 @@ fn push_back (#t:Type0) (v:vector t) (x:t)
138138
pure (Seq.length s < SZ.v cap \/ SZ.fits (SZ.v cap + SZ.v cap))
139139
ensures exists* (cap':SZ.t).
140140
is_vector v (Seq.snoc s x) cap' **
141-
pure (SZ.v cap' >= Seq.length s + 1 /\ SZ.v cap' > 0)
141+
pure (SZ.v cap' >= Seq.length s + 1 /\ SZ.v cap' > 0 /\
142+
(Seq.length s < SZ.v cap ==> cap' == cap) /\
143+
(Seq.length s == SZ.v cap ==> SZ.v cap' == SZ.v cap + SZ.v cap))
142144
{
143145
unfold (is_vector v s cap);
144146
with vi buf. _;
@@ -183,7 +185,11 @@ fn pop_back (#t:Type0) (v:vector t)
183185
ensures exists* (cap':SZ.t).
184186
is_vector v (Seq.slice s 0 (Seq.length s - 1)) cap' **
185187
pure (x == Seq.index s (Seq.length s - 1) /\
186-
SZ.v cap' >= Seq.length s - 1 /\ SZ.v cap' > 0)
188+
SZ.v cap' >= Seq.length s - 1 /\ SZ.v cap' > 0 /\
189+
(Seq.length s - 1 == SZ.v cap / 2 /\ SZ.v cap / 2 > 0
190+
==> SZ.v cap' == SZ.v cap / 2) /\
191+
(~(Seq.length s - 1 == SZ.v cap / 2 /\ SZ.v cap / 2 > 0)
192+
==> cap' == cap))
187193
{
188194
unfold (is_vector v s cap);
189195
with vi buf. _;

lib/pulse/lib/Pulse.Lib.Vector.fsti

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,9 @@ fn push_back (#t:Type0) (v:vector t) (x:t)
7777
pure (Seq.length s < SZ.v cap \/ SZ.fits (SZ.v cap + SZ.v cap))
7878
ensures exists* (cap':SZ.t).
7979
is_vector v (Seq.snoc s x) cap' **
80-
pure (SZ.v cap' >= Seq.length s + 1 /\ SZ.v cap' > 0)
80+
pure (SZ.v cap' >= Seq.length s + 1 /\ SZ.v cap' > 0 /\
81+
(Seq.length s < SZ.v cap ==> cap' == cap) /\
82+
(Seq.length s == SZ.v cap ==> SZ.v cap' == SZ.v cap + SZ.v cap))
8183

8284
/// Remove and return the last element. Halves capacity when size == floor(cap/2).
8385
/// Requires: vector is non-empty
@@ -88,7 +90,11 @@ fn pop_back (#t:Type0) (v:vector t)
8890
ensures exists* (cap':SZ.t).
8991
is_vector v (Seq.slice s 0 (Seq.length s - 1)) cap' **
9092
pure (x == Seq.index s (Seq.length s - 1) /\
91-
SZ.v cap' >= Seq.length s - 1 /\ SZ.v cap' > 0)
93+
SZ.v cap' >= Seq.length s - 1 /\ SZ.v cap' > 0 /\
94+
(Seq.length s - 1 == SZ.v cap / 2 /\ SZ.v cap / 2 > 0
95+
==> SZ.v cap' == SZ.v cap / 2) /\
96+
(~(Seq.length s - 1 == SZ.v cap / 2 /\ SZ.v cap / 2 > 0)
97+
==> cap' == cap))
9298

9399
/// Resize the vector to new_size elements.
94100
/// Preserves the first min(old_size, new_size) elements.

0 commit comments

Comments
 (0)