Abstract Refinements {#data} ============================ Recap ----- **So far** Abstract Invariants from Functions
**Next** Decouple invariants from **recursive** data structures
Decouple Invariants From Data {#recursive} ========================================== {#asd} ------- Recursive Structures -------------------- Lets see another example of decoupling... Decouple Invariants From Recursive Data ======================================= Recall: Lists ------------- \begin{code} data L a = N | C { hd :: a, tl :: L a } \end{code} Recall: Refined Constructors ---------------------------- Define **increasing** Lists with *strengthened constructors*: \begin{spec}
data L a where N :: L a C :: hd:a -> tl: L {v:a | hd <= v} -> L a \end{spec} Problem: Decreasing Lists? -------------------------- What if we need *both* [increasing *and* decreasing lists?](http://hackage.haskell.org/package/base-4.7.0.0/docs/src/Data-List.html#sort)
Abstract That Refinement! ------------------------- \begin{code} {-@ data L a

a -> Prop> = N | C { hd :: a, tl :: L

a

} @-} \end{code}

`p` is a **binary relation** between two `a` values

Definition relates `hd` with **all** the elements of `tl`

Recursive: `p` holds for **every pair** of elements!
Example ------- Consider a list with *three* or more elements \begin{spec}
x1 `C` x2 `C` x3 `C` rest :: L

a \end{spec} Example: Unfold Once -------------------- \begin{spec}
x1 :: a x2 `C` x3 `C` rest :: L

a

\end{spec} Example: Unfold Twice --------------------- \begin{spec}
x1 :: a x2 :: a

x3 `C` rest :: L

a

\end{spec} Example: Unfold Thrice ---------------------- \begin{spec}
x1 :: a x2 :: a

x3 :: a

rest :: L

a

\end{spec}

Note how `p` holds between **every pair** of elements in the list.
A Concrete Example ------------------ That was a rather *abstract*!
How can we *use* fact that `p` holds between *every pair*?
**Instantiate** `p` with a *concrete* refinement
Example: Increasing Lists ------------------------- **Instantiate** `p` with a *concrete* refinement
\begin{code} {-@ type IncL a = L <{\hd v -> hd <= v}> a @-} \end{code}
Refinement says:   `hd` less than **every** `v` in tail,

i.e., `IncL` denotes **increasing** lists.

[DEMO 02_AbstractRefinements.hs #3](02_AbstractRefinements.hs)
Example: Sorting Lists ---------------------- Now we can check all the usual list sorting algorithms
Demo: List Sorting

[DEMO GhcListSort.hs](../hs/GhcListSort.hs) Example: Binary Trees --------------------- `Map` from keys of type `k` to values of type `a`
Implemented, as a binary tree:
\begin{code} data Map k a = Tip | Bin Int k a (Map k a) (Map k a) \end{code}
Two Abstract Refinements ------------------------ - `l` : relates root `key` with `left`-subtree keys - `r` : relates root `key` with `right`-subtree keys
\begin{code} {-@ data Map k a < l :: k -> k -> Prop , r :: k -> k -> Prop > = Tip | Bin { sz :: Int , key :: k , val :: a , left :: Map k a , right :: Map k a} @-} \end{code} Ex: Binary Search Trees ----------------------- Keys are *Binary-Search* Ordered
\begin{code} {-@ type BST k a = Map <{\r v -> v < r }, {\r v -> v > r }> k a @-} \end{code} Ex: Minimum Heaps ----------------- Root contains *minimum* value
\begin{code} {-@ type MinHeap k a = Map <{\r v -> r <= v}, {\r v -> r <= v}> k a @-} \end{code} Ex: Maximum Heaps ----------------- Root contains *maximum* value
\begin{code} {-@ type MaxHeap k a = Map <{\r v -> r >= v}, {\r v -> r >= v}> k a @-} \end{code} Example: Data.Map ----------------- Standard Key-Value container
-
1300+ non-comment lines
-
`insert`, `split`, `merge`,...
-
Rotation, Rebalance,...

SMT & inference crucial for [verification](https://github.com/ucsd-progsys/liquidhaskell/blob/master/benchmarks/esop2013-submission/Base.hs)

Demo: Binary Search Maps
Example: Red-Black Tree -----------------------
Binary-Search Ordered Keys
[DEMO RBTree-Ord.hs](../hs/RBTree-ord.hs) Example: Infinite Streams -------------------------
How to distinguish between **finite** and **infinite** lists?
[DEMO Streams.hs](../hs/Streams.hs) Recap: Abstract Refinements ---------------------------
Decouple invariants from **functions** + `max` + `foldr`

Decouple invariants from **data** + `List` + `Tree`
Recap ----- 1. Refinements: Types + Predicates 2. Subtyping: SMT Implication 3. Measures: Strengthened Constructors 4. Abstract Refinements over Functions 5. **Abstract** Refinements over Recursive Data 6.
[Evaluation](11_Evaluation.lhs.slides.html)


[[continue...]](11_Evaluation.lhs.slides.html)