## From “Hoare Logic” to “Dijkstra Monads”

MPRI 2-30, Paris, Friday, 27 January 2017

### Today: verifying stateful programs

• Verifying stateful programs in a functional language

• Looking a bit behind the F* curtain

• Hoare-style specifications

• inspired by Hoare Type Theory / Ynot
• Computing weakest preconditions

• inspired by Dijkstra Monads in F*

### core.org

• A core syntax inspired by (Micro-)F*
• Aimed at teaching verification of stateful programs
• 2 variants:
• Hoare style
• Weakest precondition style

### Imperative factorial

val factorial_tot : nat -> Tot nat
let rec factorial_tot x = if x = 0 then 1 else x * factorial_tot (x - 1)

(* TODO: write a stronger ensures clause for factorial that proves
it does the same thing as factorial_tot *)
val factorial : r1:ref nat -> r2:ref nat -> ST unit
(requires (fun h' -> True))
(ensures (fun h' a h -> True))
let rec factorial r1 r2 =
let x1 = !r1 in
if x1 = 0
then r2 := 1
else
(r1 := x1 - 1;
factorial r1 r2;
r2 := !r2 * x1)

### Monotonic log

(* global log of integers *)
val log : ref (list int)
let log = alloc []

val add_to_log : e:int -> ST unit
(requires (fun h0 -> True))
(ensures (fun h0 _ h1 ->
mem e (sel h1 log) (* p1: new element added *)
/\ (forall x. mem x (sel h0 log) ==> mem x (sel h1 log))
(* p2: all old elements preserved *)
))
log := (e :: !log)

let main =
assert (mem 1 log1); (* proved by p1 *)
assert (mem 2 log2  (* proved by p1 *)
/\ mem 1 log2) (* proved by p2! *)