{#measures} ============ Recap -----

1.
**Refinements:** Types + Predicates
2.
**Subtyping:** SMT Implication


So far: only specify properties of **base values** (e.g. `Int`) ...

How to specify properties of **structures**?
{#meas} ==================== Measuring Data Types -------------------- Measuring Data Types ==================== Example: Length of a List ------------------------- Given a type for lists:
\begin{code} data L a = N | C a (L a) \end{code}

We can define the **length** as:
\begin{code} {-@ measure size :: (L a) -> Int size (N) = 0 size (C x xs) = (1 + size xs) @-} \end{code} Example: Length of a List ------------------------- \begin{spec} {-@ measure size :: (L a) -> Int size (N) = 0 size (C x xs) = 1 + size xs @-} \end{spec}
We **strengthen** data constructor types
\begin{spec}
data L a where N :: {v: L a | size v = 0} C :: a -> t:_ -> {v:_| size v = 1 + size t} \end{spec} Measures Are Uninterpreted -------------------------- \begin{spec}
data L a where N :: {v: L a | size v = 0} C :: a -> t:_ -> {v:_| size v = 1 + size t} \end{spec}
`size` is an **uninterpreted function** in SMT logic Measures Are Uninterpreted --------------------------
In SMT, [uninterpreted function](http://fm.csl.sri.com/SSFT12/smt-euf-arithmetic.pdf) $f$ obeys **congruence** axiom:
$$\forall \overline{x}, \overline{y}. \overline{x} = \overline{y} \Rightarrow f(\overline{x}) = f(\overline{y})$$
Other properties of `size` asserted when typing **fold** & **unfold**

Crucial for *efficient*, *decidable* and *predictable* verification.
Measures Are Uninterpreted -------------------------- Other properties of `size` asserted when typing **fold** & **unfold**
\begin{spec}**Fold**
z = C x y -- z :: {v | size v = 1 + size y} \end{spec}

\begin{spec}**Unfold**
case z of N -> e1 -- z :: {v | size v = 0} C x y -> e2 -- z :: {v | size v = 1 + size y} \end{spec}
Example: Using Measures -----------------------

[DEMO: 001_Refinements.hs](../hs/001_Refinements.hs) Multiple Measures ================= {#adasd} --------- Can support *many* measures for a type Ex: List Emptiness ------------------ Measure describing whether a `List` is empty \begin{code} {-@ measure isNull :: (L a) -> Prop isNull (N) = true isNull (C x xs) = false @-} \end{code}
LiquidHaskell **strengthens** data constructors \begin{spec} data L a where N :: {v : L a | isNull v} C :: a -> L a -> {v:(L a) | not (isNull v)} \end{spec}
Conjoining Refinements ---------------------- Data constructor refinements are **conjoined** \begin{spec} data L a where N :: {v:L a | size v = 0 && isNull v } C :: a -> xs:L a -> {v:L a | size v = 1 + size xs && not (isNull v) } \end{spec} Multiple Measures: Red Black Trees ================================== {#elements} ------------


[continue] Recap -----

1. Refinements: Types + Predicates 2. Subtyping: SMT Implication 3. **Measures:** Strengthened Constructors
Automatic Verification of Data Structures