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
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)