1. Rewrite the algorithm into a pure and non IO effect one ◦ Usually difficult ◦ How to guarantee the equality of the algorithms? 2. Prove it directly ◦ Simple, but how to handle variables and arrays? ◦ ➡ IO monad!
⇒ ('a × heap)" primrec execute :: "'a io ⇒ heap ⇒ ('a × heap)" where [code del]: "execute (IO f) = f" - IO monad as a state monad of heap - “heap” means memory state (variables and arrays are there) - Normal memory operations can be defined, including allocate, read and write
to the value whose type is ‘a - Operators (all are in IO context): - ref x: allocate a new cell and initialize by the value x - ! r: read the value - r := v: write the value v into the ref r
arr in forMu [0..<n] (λi. do { min_ref ← ref i; forMu [i+1..<n] (λj. do { valJ ← read arr j; m ← ! min_ref; valMin ← read arr m; whenu (valJ < valMin) (min_ref := j) }); m ← ! min_ref; swap arr i m; return () })
“sorted” - Allocate an array and initialize using given list - Do the sort - Read the array and check if it’s sorted primrec sorted :: "'a::ord list ⇒ bool" where "sorted [] = True" | "sorted (x#xs) = ((∀y∈set xs. x ≤ y) ∧ sorted xs)"
as the program become long - One way and never go wrong (when calculation has done) lemma assumes "effect program h h' r" shows "h' = super_complex_calculation(h)" and "r = super_complex_function(r)"
(need a gut) - Sometimes many ways to go ahead - “loop invariant condition”, or more generally, “program invariant condition” lemma assumes "P (forM [] program)" and "\forall i. P (forM (take i xs) program) ==> P (forM (take (i+1) xs) program)" shows "P (forM xs program)" Big-step Observation