29.01.2014 Views

A CIL Tutorial - Department of Computer Science - ETH Zürich

A CIL Tutorial - Department of Computer Science - ETH Zürich

A CIL Tutorial - Department of Computer Science - ETH Zürich

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

CHAPTER 11. PROGRAM VERIFICATION 97<br />

let iterm <strong>of</strong> bterm (t : T.term) : T.term = T.t if t (term <strong>of</strong> int 1) (term <strong>of</strong> int 0)<br />

let bterm <strong>of</strong> iterm (t : T.term) : T.term = T.t neq t (term <strong>of</strong> int 0)<br />

let rec term <strong>of</strong> exp (wc : wctxt) (e : exp) : T.term = (∗ ... ∗)<br />

and term <strong>of</strong> uop (wc : wctxt) (u : unop) (e : exp) : T.term = (∗ ... ∗)<br />

and term <strong>of</strong> bop (wc : wctxt) (b : binop) (e1 : exp) (e2 : exp) : T.term = (∗ ... ∗)<br />

With expressions translated to terms, we can now begin calculating the VC. We are using the<br />

backwards method <strong>of</strong> VC construction, but we accomplish this by traversing the program in the<br />

forwards direction, building up a continuation that will then be applied to the function's postcondition.<br />

Therefore, both term <strong>of</strong> inst and term <strong>of</strong> stmt return functions that take as an argument<br />

the term generated by the next instruction or statement, and yield the term modied according to<br />

the current instruction or statement.<br />

This method <strong>of</strong> VC generation is not very ecient. In particular it prevents the hashcons<br />

optimizations inside <strong>of</strong> the Why3 library from being applied until the continuation we build up<br />

is nally applied. It would be more sensible, especially for dealing with large programs, to use a<br />

forwards method <strong>of</strong> VC construction.<br />

The function term <strong>of</strong> inst generates Why3 let bindings for assignments. These let bindings<br />

automatically take care <strong>of</strong> any necessary variable renaming. Currently, the translation does not<br />

handle writes to struct elds. Accomplishing this will be discussed in one <strong>of</strong> the exercises.<br />

let term <strong>of</strong> inst (wc : wctxt) (i : instr) : T.term → T.term =<br />

match i with<br />

| Set((Var vi, NoOffset), e, loc) →<br />

let te = term <strong>of</strong> exp wc e in<br />

let vs = SM.find vi.vname wc.vars in<br />

T.t let close vs te<br />

(∗ Also the case for a memory write ∗)<br />

| → Em.s (Em.error "term <strong>of</strong> inst: We can only handle assignment")<br />

The function term <strong>of</strong> stmt generates the continuation for calculating the VC for a statement. For<br />

instruction statements, it folds over the list <strong>of</strong> instructions. For if statements it generates a Why3<br />

if-then-else term. It recursively descends into block statements, and treats return statements as<br />

no-ops. Loop statements are more complex. Handling loops is described in detail below.<br />

let rec term <strong>of</strong> stmt (wc : wctxt) (s : stmt) : T.term → T.term =<br />

match s.skind with<br />

| Instr il → L.fold right (fun i t → (term <strong>of</strong> inst wc i) t) il<br />

| If(e, tb, fb, loc) → term <strong>of</strong> if wc e tb fb<br />

| Loop(b, loc, bo, co) → term <strong>of</strong> loop wc b<br />

| Block b → term <strong>of</strong> block wc b<br />

| Return(eo, loc) → (fun t → t)

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!