Skip to content

Commit 566e054

Browse files
committed
adding some tests, very early beginnings of Pulse.Lib.C support library, etc.
1 parent f6bec42 commit 566e054

9 files changed

Lines changed: 71 additions & 35 deletions

File tree

build.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@ if ! [[ -x "$HERE/external/pulse/out/lib/pulse/pulse.cmxs" ]]; then
2424
make -C $HERE/external/pulse -j$(nproc) ADMIT=1 FSTAR_EXE=$(realpath $HERE/external/FStar/bin/fstar.exe)
2525
fi
2626

27+
28+
if ! [[ -x "./include/pulse/_cache/Pulse.Lib.C.Int32.fst.checked" ]]; then
29+
echo "Building Pulse.Lib.C libraries"
30+
make -C $HERE/include/pulse -j$(nproc)
31+
fi
32+
2733
if [[ -x "$CLANG_BIN/c2pulse" ]]; then
2834
echo "C2Pulse exists in $CLANG_BIN!"
2935
echo "Rebuilding existing project!"

include/pulse/Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
PULSE_ROOT ?= ../../external/pulse
3+
FSTAR_EXE ?= ../../external/FStar/bin/fstar.exe
4+
5+
include $(PULSE_ROOT)/mk/test.mk
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
module Pulse.Lib.C.Int32
2+
open FStar.Int32
3+
module I32 = FStar.Int32
4+
5+
let int32 = FStar.Int32.t
6+
let as_int (x: I32.t) : int = I32.v x
7+
let fits (op : int -> int -> int) (vx vy : int) : prop =
8+
FStar.Int32.fits (op vx vy)
9+
let min_int32 = FStar.Int.min_int I32.n
10+
let max_int32 = FStar.Int.max_int I32.n
11+
let (+^) = FStar.Int32.add

include/pulse/fstar.include

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
_cache

run.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ C_STD="-std=c23"
1010
C2PULSE="$(realpath $HERE/external/llvm-project/build/bin/c2pulse)"
1111
FSTAR_BIN="$(realpath $HERE/external/FStar/bin/fstar.exe)"
1212
PULSE_DIR="$(realpath $HERE/external/pulse/out/lib/pulse)"
13+
PULSE_LIB_C_DIR="$(realpath $HERE/include/pulse)"
1314

1415
# Check input
1516
if [ "$#" -lt 1 ]; then
@@ -96,5 +97,6 @@ done
9697
# Run fstar on all files at once
9798
exec "$FSTAR_BIN" \
9899
--include "$PULSE_DIR" \
100+
--include "$PULSE_LIB_C_DIR" \
99101
--query_stats --z3version 4.13.3 \
100102
"${SRC_FILES[@]}"

run_fstar.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ set -euo pipefail
44
HERE=$(dirname $0)
55
FSTAR_BIN="$(realpath $HERE/external/FStar/bin/fstar.exe)"
66
PULSE_DIR="$(realpath $HERE/external/pulse/out/lib/pulse)"
7+
AUX_LIBS="$(realpath $HERE/include/pulse)"
78

89
if [ $# -lt 1 ]; then
910
echo "Usage: $0 <source_file.fst> [additional F* args]"
@@ -13,4 +14,4 @@ fi
1314
SRC_FILE="$1"
1415
shift
1516

16-
exec "$FSTAR_BIN" --include "$PULSE_DIR" --z3version 4.13.3 "$SRC_FILE" "$@"
17+
exec "$FSTAR_BIN" --include "$PULSE_DIR" --include "$AUX_LIBS" --z3version 4.13.3 "$SRC_FILE" "$@"

test/Cfg.fst.config.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"--z3version", "4.13.3"
88
],
99
"include_dirs": [
10-
"../external/pulse/out/lib/pulse"
10+
"../external/pulse/out/lib/pulse",
11+
"../include/pulse"
1112
]
1213
}

test-transpiler/c/general/pulse_tutorial_intro.c renamed to test/pulse_tutorial_intro.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,31 @@
11
#include <stdint.h>
22
#include <stdlib.h>
3-
#include "../pulse_macros.h"
3+
#include "../include/PulseMacros.h"
44

55
REQUIRES("x |-> 'i")
66
REQUIRES("pure FStar.Int32.(fits (v 'i + 1))")
7-
ENSURES("x |-> ('i + 1)")
7+
ENSURES("exists* j. (x |-> j) ** pure FStar.Int32.(v 'i + 1 == v j)")
88
void incr (int *x)
99
{
1010
*x = *x + 1;
1111
}
1212

13-
ERASED_ARG(i)
13+
ERASED_ARG(#i:_)
1414
REQUIRES(x |-> i)
1515
REQUIRES(pure FStar.Int32.(fits (v i + 1)))
16-
ENSURES(x |-> (i + 1))
16+
ENSURES("exists* j. (x |-> j) ** pure FStar.Int32.(v i + 1 == v j)")
1717
void incr_explicit_i (int *x)
1818
{
1919
*x = *x + 1;
2020
}
2121

22-
ERASED_ARG(i)
23-
ERASED_ARG(j)
24-
REQUIRES(x |-> i ** y |-> j)
22+
ERASED_ARG(#i:_)
23+
ERASED_ARG(#j:_)
24+
REQUIRES(x |-> i)
25+
REQUIRES(y |-> j)
2526
REQUIRES(pure FStar.Int32.(fits (v i + 1)))
26-
ENSURES(x |-> (i + 1) ** y |-> j)
27+
ENSURES("exists* j. (x |-> j) ** pure FStar.Int32.(v i + 1 == v j)")
28+
ENSURES(y |-> j)
2729
void incr_frame(int *x, int *y)
2830
{
2931
incr(x);

test-transpiler/c/general/pulse_tutorial_ref.c renamed to test/pulse_tutorial_ref.c

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
#include <stdint.h>
22
#include <stdlib.h>
3-
#include "../pulse_macros.h"
3+
#include "../include/PulseMacros.h"
44

55
REQUIRES("r |-> 'v")
6-
RETURNS(v)
6+
RETURNS(v:Pulse.Lib.C.Int32.int32)
77
ENSURES("r |-> 'v")
88
ENSURES("pure (v == 'v)")
99
int value_of(int *r)
1010
{
1111
return *r;
1212
}
1313

14-
ERASED_ARG(w)
14+
ERASED_ARG(#w:erased _)
1515
REQUIRES(r |-> w)
16-
RETURNS(v)
16+
RETURNS(v:Pulse.Lib.C.Int32.int32)
1717
ENSURES(r |-> w)
1818
ENSURES(pure (v == w))
1919
int value_of_explicit(int *r)
@@ -35,44 +35,45 @@ void assign_alt(int *r, int v)
3535
*r = v;
3636
}
3737

38-
ERASED_ARG(w)
38+
ERASED_ARG(#w:erased _)
3939
REQUIRES(r |-> w)
40-
REQUIRES(pure FStar.Int32.(fits (v w + n)))
41-
ENSURES(exists* ww. r |-> ww ** pure FStar.Int32.(v ww == v w + n))
40+
REQUIRES(pure Pulse.Lib.C.Int32.(fits (+) (as_int w) (as_int n)))
41+
ENSURES(exists* ww. (r |-> ww) ** pure Pulse.Lib.C.Int32.(as_int ww == as_int w + as_int n))
4242
void add(int *r, int n)
4343
{
4444
*r = *r + n;
4545
}
4646

47-
ERASED_ARG(w : FStar.Int32.t { FStar.Int32.(fits (v w + n)) })
47+
ERASED_ARG(#w : erased _ { Pulse.Lib.C.Int32.(fits (+) (as_int w) (as_int n)) })
4848
REQUIRES(r |-> w)
49-
ENSURES(r |-> FStar.Int32.(w +^ n))
49+
ENSURES(r |-> Pulse.Lib.C.Int32.(w +^ n))
5050
void add_alt(int *r, int n)
5151
{
5252
*r = *r + n;
5353
}
5454

55-
ERASED_ARG(w : FStar.Int32.t { FStar.Int32.fits(4 * v w) })
55+
ERASED_ARG(#w : erased _ { Pulse.Lib.C.Int32.(fits op_Multiply 4 (as_int w)) })
5656
REQUIRES(r |-> w)
57-
ENSURES(exists* ww. r |-> ww ** pure FStar.Int32.(v ww == 4 * v w))
57+
ENSURES(exists* ww. (r |-> ww) ** pure Pulse.Lib.C.Int32.(as_int ww == 4 `op_Multiply` as_int w))
5858
void quadruple(int *r)
5959
{
6060
add(r, *r);
6161
add(r, *r);
6262
}
6363

64-
ERASED_ARG(w:FStar.Int32.t)
64+
65+
ERASED_ARG(#w:erased _)
6566
ERASED_ARG(p:perm)
6667
REQUIRES(x |-> Frac p w)
67-
RETURNS(i)
68+
RETURNS(i:Pulse.Lib.C.Int32.int32)
6869
ENSURES(x |-> Frac p w)
6970
ENSURES(pure (i == w))
7071
int value_of_perm(int *x)
7172
{
7273
return *x;
7374
}
7475

75-
ERASED_ARG(v)
76+
ERASED_ARG(#v:erased _)
7677
ERASED_ARG(p:perm)
7778
REQUIRES(x |-> Frac p v)
7879
ENSURES(x |-> Frac (p /. 2.0R) v)
@@ -82,8 +83,9 @@ void share_ref(int *x)
8283
LEMMA(share(x));
8384
}
8485

85-
ERASED_ARG(v0)
86-
ERASED_ARG(v1)
86+
87+
ERASED_ARG(#v0:erased _)
88+
ERASED_ARG(#v1:erased _)
8789
ERASED_ARG(p:perm)
8890
REQUIRES(x |-> Frac (p /. 2.0R) v0)
8991
REQUIRES(x |-> Frac (p /. 2.0R) v1)
@@ -94,7 +96,8 @@ void gather_ref(int *x)
9496
LEMMA(gather(x));
9597
}
9698

97-
ERASED_ARG(v)
99+
100+
ERASED_ARG(#v:erased _)
98101
ERASED_ARG(p:perm)
99102
REQUIRES(x |-> Frac p v)
100103
REQUIRES(pure (~(p <=. 1.0R)))
@@ -105,10 +108,10 @@ void max_perm (int *x)
105108
LEMMA(unreachable());
106109
}
107110

108-
ERASED_ARG(v)
111+
ERASED_ARG(#v:erased _)
109112
ERASED_ARG(p:perm)
110113
REQUIRES(r |-> Frac p v)
111-
RETURNS(s)
114+
RETURNS(s: ref Pulse.Lib.C.Int32.int32)
112115
ENSURES(s |-> Frac (p /. 2.0R) v)
113116
ENSURES(s |-> Frac (p /. 2.0R) v)
114117
ENSURES(pure (s == r))
@@ -118,29 +121,33 @@ int* alias_ref(int *r)
118121
return r;
119122
}
120123

121-
ERASED_ARG(vr)
124+
125+
ERASED_ARG(#vr:erased _)
122126
REQUIRES(r |-> vr)
123-
ENSURES(exists* w. r |-> w ** pure FStar.Int32.(v w == v vr + 1))
127+
REQUIRES(pure Pulse.Lib.C.Int32.(fits (+) (as_int vr) 1))
128+
ENSURES(exists* w. (r |-> w) ** pure Pulse.Lib.C.Int32.(as_int w == as_int vr + 1))
124129
int incr (int *r)
125130
{
126131
*r = *r + 1;
127132
}
128133

129-
130-
RETURNS(i)
131-
ENSURES(pure (i == 1l))
134+
/**
135+
REQUIRES(emp)
136+
RETURNS(i:Pulse.Lib.C.Int32.int32)
137+
ENSURES(pure Pulse.Lib.C.Int32.(as_int i == 1))
132138
int one()
133139
{
134140
int i = 0;
135141
incr(&i);
136142
return i;
137143
}
138144
145+
/*
139146
EXPECT_FAILURE(19)
140147
RETURNS(s)
141148
ENSURES(s |-> 0l)
142149
int* refs_are_scoped()
143150
{
144151
int s = 0;
145152
return &s;
146-
}
153+
}*/

0 commit comments

Comments
 (0)