{#laziness} ============ Lazy Evaluation? ---------------- Lazy Evaluation =============== SMT based Verification ---------------------- Techniques developed for *strict* languages
----------------------- --- ------------------------------------------ **Floyd-Hoare** : `ESCJava`, `SpecSharp` ... **Model Checkers** : `Slam`, `Blast` ... **Refinement Types** : `DML`, `Stardust`, `F7`, `F*`, `Sage` ... ----------------------- --- ------------------------------------------

Surely soundness carries over to Haskell, right?
Back To the Beginning --------------------- \begin{code} {-@ divide :: Int -> {v:Int| v /= 0} -> Int @-} divide n 0 = liquidError "div-by-zero!" divide n d = n `div` d \end{code}
Should only try to `divide` by non-zero values
An Innocent Function -------------------- `foo` returns a value *strictly less than* input.
\begin{code} {-@ foo :: n:Nat -> {v:Nat | v < n} @-} foo n | n > 0 = n - 1 | otherwise = foo n \end{code} LiquidHaskell Lies! ------------------- \begin{code} explode = let z = 0 in (\x -> (2013 `divide` z)) (foo z) \end{code}
Why is this deemed *safe*?

(Where's the *red* highlight when you want it?)
Safe With Eager Eval -------------------- \begin{code}
{- foo :: n:Nat -> {v:Nat | v < n} -} foo n | n > 0 = n - 1 | otherwise = foo n explode = let z = 0 in (\x -> (2013 `divide` z)) (foo z) \end{code}
In Java, ML, etc: program spins away, *never hits* divide-by-zero
Unsafe With Lazy Eval --------------------- \begin{code}
{- foo :: n:Nat -> {v:Nat | v < n} -} foo n | n > 0 = n - 1 | otherwise = foo n explode = let z = 0 in (\x -> (2013 `divide` z)) (foo z) \end{code}
In Haskell, program *skips* `(foo z)` & hits divide-by-zero! Problem: Divergence -------------------
What is denoted by `e :: {v:Int | 0 <= v}` ?

`e` evaluates to a `Nat`
or **diverges**!

Classical Floyd-Hoare notion of [partial correctness](http://en.wikipedia.org/wiki/Hoare_logic#Partial_and_total_correctness)
Problem: Divergence ------------------- Suppose `e :: {v:Int | 0 <= v}`
**Consider** `let x = e in body` With Eager Evaluation --------------------- Suppose `e :: {v:Int | 0 <= v}`
**Consider** `let x = e in body`
**Can** assume `x` is a `Nat` when checking `body`
But With Lazy Evaluation ------------------------ Suppose `e :: {v:Int | 0 <= v}`
**Consider** `let x = e in body`
**Cannot** assume `x` is a `Nat` when checking e!
Oops. Now what? --------------- **Solution** Only assign *non-trivial* refinements to *non-diverging* terms!
**Require A Termination Analysis** (Oh dear.)
Demo:Disable `"--no-termination" and see what happens! Recap ----- 1. **Refinements:** Types + Predicates 2. **Subtyping:** SMT Implication 3. **Measures:** Strengthened Constructors 4. **Abstract Refinements:* Decouple Invariants 5. **Lazy Evaluation:** Requires Termination 6.
**Termination:** Via Refinements!