Skip to content

Commit d337ade

Browse files
committed
v0.9.5 of uclid5.
What's new? + Much improved tutorial. + Initial support for SyGuS + New operators (distinct, bv_sign_extend, bv_zero_extend). + Local scoped variables are allowed in every block now. + We have the beginnings of an optimizer. + Lots and lots and lots of bugfixes.
1 parent 50ccbbd commit d337ade

File tree

186 files changed

+6081
-1193
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

186 files changed

+6081
-1193
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Download the latest stable pre-built package from [releases tab](https://github.
1616

1717
# Install From Source
1818

19-
Or, you could clone this repository and build from source.
19+
Or, you could clone this repository and build from source. If you run into problems here, don't forget you can always fall back on the pre-built binaries linked above.
2020

2121
## Compiling uclid5
2222

build.sbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name := "uclid"
2-
version := "0.9.1"
2+
version := "0.9.5"
33
scalaVersion := "2.12.0"
44

55
scalacOptions += "-feature"

examples/README

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,11 @@ setuid.ucl
2525
setuid_fixed.ucl
2626
- This is a "fixed" version of the setuid model.
2727

28+
two-safety.ucl
29+
- This is an example of verifying a simple hyperproperty (a 2-safety property)
30+
by self-composition. It is based on an example in Chapter 17 of Lee & Seshia.
31+
32+
simple-datapath.ucl
33+
- This is an example from the original UCLID work on processor verification (Bryant, Lahiri, Seshia, CAV'02),
34+
showing Burch-Dill style correspondence (refinement) checking.
35+

examples/cpu_induction.ucl

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,12 @@ module common {
2626
}
2727

2828
module cpu {
29-
type addr_t = common.addr_t;
30-
type mem_t = common.mem_t;
31-
type word_t = common.word_t;
32-
type op_t = common.op_t;
33-
type mode_t = common.mode_t;
29+
// type addr_t = common.addr_t;
30+
// type mem_t = common.mem_t;
31+
// type word_t = common.word_t;
32+
// type op_t = common.op_t;
33+
// type mode_t = common.mode_t;
34+
type * = common.*;
3435

3536
type regindex_t;
3637
type regs_t = [regindex_t]word_t;
@@ -168,7 +169,7 @@ module main {
168169
type mode_t = common.mode_t;
169170
type regindex_t = cpu.regindex_t;
170171

171-
// Instruction memory is the same for both CPUs.
172+
// Instruction memory for the CPUs.
172173
var imem1, imem2 : mem_t;
173174

174175
// Create two instances of the CPU module.

examples/crypto.ucl

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
module main
2+
{
3+
type plaintext_t;
4+
type ciphertext_t;
5+
type key_t;
6+
7+
const pt : plaintext_t;
8+
var ct : ciphertext_t;
9+
var sk : key_t; // secret key
10+
11+
input ik : key_t; // input key
12+
var dt : plaintext_t; // "decoded" text
13+
14+
function enc(k : key_t, pt : plaintext_t) : ciphertext_t;
15+
function dec(k : key_t, ct : ciphertext_t) : plaintext_t;
16+
17+
axiom dec_enc :
18+
(forall (k1, k2 : key_t, p : plaintext_t) ::
19+
(dec(k2, enc(k1, p)) == p) <==> (k1 == k2));
20+
21+
init {
22+
ct = enc(sk, pt);
23+
}
24+
25+
next {
26+
dt' = dec(ik, ct);
27+
assert (dt' == pt) ==> (ik == sk);
28+
}
29+
30+
control {
31+
v = unroll(5);
32+
check;
33+
print_results;
34+
}
35+
}

examples/simple-datapath.ucl

Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
1+
// Simple pipelined datapath, based on old uclid model in the old UCLID user manual
2+
3+
module common {
4+
// Types
5+
// Words -- Addresses, Data, etc.
6+
type word_t = bv32;
7+
// Registers
8+
type reg_t = bv8; // arbit choice
9+
// Register file
10+
type rf_t = [reg_t]word_t;
11+
// OpCode
12+
type op_t = bv8; // arbit choice
13+
14+
// Uninterpreted functions
15+
function newPC(a: word_t) : word_t;
16+
const pc0 : word_t;
17+
function rf0 (r : reg_t) : word_t;
18+
function src1 (i : word_t) : reg_t;
19+
function src2 (i : word_t) : reg_t;
20+
function dest (i : word_t) : reg_t;
21+
function op (i : word_t) : op_t;
22+
function alu (op : op_t, arg1: word_t, arg2 : word_t) : word_t;
23+
24+
}
25+
26+
// Specification/ISA model
27+
module spec {
28+
29+
input proj_impl : boolean;
30+
input impl_RF : common.rf_t;
31+
input impl_PC : common.word_t;
32+
33+
var sPC : common.word_t;
34+
var sRF : common.rf_t;
35+
36+
procedure update_sRF()
37+
modifies sRF;
38+
{
39+
sRF[common.dest(sPC)] = common.alu(common.op(sPC),
40+
sRF[common.src1(sPC)],
41+
sRF[common.src2(sPC)]);
42+
}
43+
44+
init {
45+
sPC = common.pc0;
46+
assume (forall (i : common.reg_t) :: (sRF[i] == common.rf0(i)));
47+
}
48+
49+
next {
50+
if (proj_impl) {
51+
sPC' = impl_PC;
52+
sRF' = impl_RF;
53+
}
54+
else {
55+
sPC' = common.newPC(sPC);
56+
call update_sRF();
57+
}
58+
}
59+
}
60+
61+
// Pipeline model
62+
module impl {
63+
64+
input flush : boolean;
65+
input reinit : boolean;
66+
67+
var pPC : common.word_t;
68+
var pRF : common.rf_t;
69+
var eOP : common.op_t;
70+
var eSRC2 : common.reg_t;
71+
var eDEST : common.reg_t;
72+
var eARG1 : common.word_t;
73+
var eARG2 : common.word_t;
74+
var eWRT : boolean;
75+
var wVAL : common.word_t;
76+
var wDEST : common.reg_t;
77+
var wWRT : boolean;
78+
79+
const op0 : common.op_t;
80+
const s0, d0, d1 : common.reg_t;
81+
const a1, a2, x0 : common.word_t;
82+
const w0, w1 : boolean;
83+
84+
procedure update_pRF()
85+
modifies pRF;
86+
{
87+
if (wWRT) { pRF[wDEST] = wVAL; }
88+
}
89+
90+
define stall() : boolean = eWRT && (common.src1(pPC) == eDEST);
91+
92+
init {
93+
// initialize PC and RF same as spec module
94+
pPC = common.pc0;
95+
assume (forall (i : common.reg_t) :: (pRF[i] == common.rf0(i)));
96+
// all other state variables get arbit symbolic initialization
97+
eOP = op0;
98+
eSRC2 = s0;
99+
eARG1 = a1;
100+
eARG2 = a2;
101+
eDEST = d0;
102+
eWRT = w0;
103+
wVAL = x0;
104+
wDEST = d1;
105+
wWRT = w1;
106+
}
107+
108+
109+
next {
110+
if (reinit) {
111+
pPC' = common.pc0;
112+
havoc pRF;
113+
assume (forall (i : common.reg_t) :: (pRF'[i] == common.rf0(i)));
114+
// all other state variables get same arbit symbolic initialization as before
115+
eOP' = op0;
116+
eSRC2' = s0;
117+
eARG1' = a1;
118+
eARG2' = a2;
119+
eDEST' = d0;
120+
eWRT' = w0;
121+
wVAL' = x0;
122+
wDEST' = d1;
123+
wWRT' = w1;
124+
}
125+
else {
126+
// updates to PC and RF
127+
if ((!flush) && (! stall())) { pPC' = common.newPC(pPC); }
128+
call update_pRF();
129+
// Execute stage
130+
eOP' = common.op(pPC);
131+
eSRC2' = common.src2(pPC);
132+
eARG1' = pRF'[common.src1(pPC)];
133+
eARG2' = pRF'[common.src2(pPC)];
134+
eDEST' = common.dest(pPC);
135+
eWRT' = (!stall()) && (!flush);
136+
// Writeback stage
137+
wDEST' = eDEST;
138+
wWRT' = eWRT;
139+
if (wWRT && (wDEST == eSRC2)) // fwding logic
140+
{
141+
wVAL' = common.alu(eOP,eARG1,wVAL);
142+
}
143+
else {
144+
wVAL' = common.alu(eOP,eARG1,eARG2);
145+
}
146+
}
147+
}
148+
149+
}
150+
151+
// Main module
152+
module main {
153+
154+
var flush_pipeline : boolean;
155+
var reinit : boolean;
156+
var project_impl : boolean;
157+
158+
var step : integer;
159+
160+
// Variables to store impl state
161+
var I_pc : common.word_t;
162+
var I_rf : common.rf_t;
163+
// Variables to store spec state
164+
var S_pc0 : common.word_t; // after 0 steps
165+
var S_rf0 : common.rf_t;
166+
var S_pc1 : common.word_t; // after 1 step
167+
var S_rf1 : common.rf_t;
168+
169+
// instantiate spec and impl modules
170+
instance impl_i : impl(flush : (flush_pipeline), reinit : (reinit));
171+
instance spec_i : spec(proj_impl : (project_impl), impl_RF : (impl_i.pRF), impl_PC : (impl_i.pPC));
172+
173+
init {
174+
step = 0;
175+
flush_pipeline = false;
176+
project_impl = false;
177+
reinit = false;
178+
}
179+
180+
next {
181+
step' = step + 1;
182+
case
183+
(step == 0) : {
184+
flush_pipeline' = true;
185+
next(impl_i); // step impl module, normal step
186+
}
187+
(step == 1) : {
188+
flush_pipeline' = true;
189+
next(impl_i); // step impl module, flush
190+
}
191+
(step == 2) : {
192+
flush_pipeline' = false;
193+
reinit' = true;
194+
next(impl_i); // step impl module, flush
195+
}
196+
(step == 3) : {
197+
flush_pipeline' = true;
198+
reinit' = false;
199+
I_pc' = impl_i.pPC; // store impl state after pipeline flushed for 2 steps
200+
I_rf' = impl_i.pRF;
201+
next(impl_i); // step impl module, reinitialize
202+
}
203+
(step == 4) : {
204+
flush_pipeline' = true;
205+
next(impl_i); // step impl module, flush
206+
}
207+
(step == 5) : {
208+
flush_pipeline' = false;
209+
project_impl' = true;
210+
next(impl_i); // step impl module, flush
211+
}
212+
(step == 6) : {
213+
project_impl' = false;
214+
next(spec_i); // step spec to project impl state onto spec
215+
}
216+
(step == 7) : { // step spec module
217+
S_pc0' = spec_i.sPC; // initial state of spec
218+
S_rf0' = spec_i.sRF;
219+
next(spec_i); // step
220+
}
221+
(step == 8) : { // store spec state after one step
222+
S_pc1' = spec_i.sPC;
223+
S_rf1' = spec_i.sRF;
224+
}
225+
(step == 9) : {
226+
// assert(false); // sanity check to make sure execution can get here
227+
// correspondence check
228+
assert(((S_pc1 == I_pc) && (S_rf1 == I_rf)) || ((S_pc0 == I_pc) && (S_rf0 == I_rf)));
229+
}
230+
esac;
231+
232+
}
233+
234+
235+
control {
236+
vobj = unroll(10);
237+
check;
238+
print_results;
239+
vobj.print_cex(step, flush_pipeline, reinit, project_impl, I_pc, I_rf, S_pc0, S_rf0, S_pc1, S_rf1, impl_i.pPC, impl_i.pRF, spec_i.sPC, spec_i.sRF, impl_i.wVAL);
240+
}
241+
242+
243+
}

examples/tutorial/ex2.1-alu.ucl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ module main {
2121
call set_init_state();
2222
}
2323

24+
define double(arg : bv8) : bv8 = (arg + arg);
25+
2426
procedure exec_cmd()
2527
returns (r : result_t)
2628
modifies regs;
@@ -39,12 +41,12 @@ module main {
3941

4042
next {
4143
call (result') = exec_cmd();
42-
cnt' = cnt + cnt;
44+
cnt' = double(cnt);
4345
}
4446

4547
assume regindex_zero : (r1 == 0bv3 && r2 == 0bv3);
4648
assume cmd_is_add : (cmd == add) && valid;
47-
invariant result_eq_cnd : (cnt == result.value);
49+
invariant result_eq_cnt : (cnt == result.value);
4850

4951
control {
5052
f = unroll (5);

examples/tutorial/ex3.4-fib-model-revisited.ucl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module main {
2-
// System description. blah
2+
// System description.
33
var a, b : integer;
44
const flag : boolean;
55

0 commit comments

Comments
 (0)