Abstract Refinements {#composition}
===================================
Very General Mechanism
----------------------
**Next:** Lets add parameters...
\begin{code}
module Composition where
import Prelude hiding ((.))
plus :: Int -> Int -> Int
plus3' :: Int -> Int
\end{code}
Example: `plus`
---------------
\begin{code}
{-@ plus :: x:_ -> y:_ -> {v:_ | v=x+y} @-}
plus x y = x + y
\end{code}
Example: `plus 3`
-----------------
\begin{code}
{-@ plus3' :: x:Int -> {v:Int | v = x + 3} @-}
plus3' = plus 3
\end{code}
Easily verified by LiquidHaskell
A Composed Variant
------------------
Lets define `plus3` by *composition*
A Composition Operator
----------------------
\begin{code}
(#) :: (b -> c) -> (a -> b) -> a -> c
(#) f g x = f (g x)
\end{code}
`plus3` By Composition
-----------------------
\begin{code}
{-@ plus3'' :: x:Int -> {v:Int | v = x + 3} @-}
plus3'' = plus 1 # plus 2
\end{code}
Yikes! Verification *fails*. But why?
(Hover mouse over `#` for a clue)
How to type compose (#) ?
-------------------------
This specification is *too weak*
\begin{spec}
(#) :: (b -> c) -> (a -> b) -> (a -> c)
\end{spec}
Output type does not *relate* `c` with `a`!
How to type compose (.) ?
-------------------------
Write specification with abstract refinement type:
\begin{code}
{-@ (.) :: forall c->Prop,
q :: a->b->Prop>.
f:(x:b -> c
)
-> g:(x:a -> b)
-> y:a -> exists[z:b].c
@-}
(.) f g y = f (g y)
\end{code}
Using (.) Operator
------------------
\begin{code}
{-@ plus3 :: x:Int -> {v:Int | v = x + 3} @-}
plus3 = plus 1 . plus 2
\end{code}
*Verifies!*
Using (.) Operator
------------------
\begin{spec}
{-@ plus3 :: x:Int -> {v:Int | v = x + 3} @-}
plus3 = plus 1 . plus 2
\end{spec}
LiquidHaskell *instantiates*
- `p` with `\x -> v = x + 1`
- `q` with `\x -> v = x + 2`
Using (.) Operator
------------------
\begin{spec}
{-@ plus3 :: x:Int -> {v:Int | v = x + 3} @-}
plus3 = plus 1 . plus 2
\end{spec}
To *infer* that output of `plus3` has type:
`exists [z:{v = y + 2}].{v = z + 1}`
`<:`
`{v:Int|v=3}`
Recap
-----
1. **Refinements:** Types + Predicates
2. **Subtyping:** SMT Implication
3. **Measures:** Strengthened Constructors
4. **Abstract:** Refinements over Type Signatures
+ *Dependencies* using refinement parameters