{#abstractrefinements} ======================== Abstract Refinements -------------------- Abstract Refinements ==================== Two Problems ------------

**Problem 1:** How to specify increasing *and* decreasing lists?

**Problem 2:** How to specify *iteration-dependence* in higher-order functions?
Problem Is Pervasive -------------------- Lets distill it to a simple example...

(First, a few aliases)
\begin{code} {-@ type Odd = {v:Int | (v mod 2) = 1} @-} {-@ type Even = {v:Int | (v mod 2) = 0} @-} \end{code}
Example: `maxInt` ----------------- Compute the larger of two `Int`s: \begin{code}
maxInt :: Int -> Int -> Int maxInt x y = if y <= x then x else y \end{code} Example: `maxInt` ----------------- Has **many incomparable** refinement types \begin{code}
maxInt :: Nat -> Nat -> Nat maxInt :: Even -> Even -> Even maxInt :: Odd -> Odd -> Odd \end{code}
Oh no! **Which** one should we use?
Refinement Polymorphism ----------------------- `maxInt` returns *one of* its two inputs `x` and `y`

--------- --- ------------------------------------------- **If** : the *inputs* satisfy a property **Then** : the *output* satisfies that property --------- --- -------------------------------------------
Above holds *for all properties*!

**Need to abstract properties over types**
Parametric Refinements ---------------------- Enable *quantification over refinements* ...
\begin{code} {-@ maxInt :: forall

Prop>. Int

-> Int

-> Int

@-} maxInt x y = if x <= y then y else x \end{code}


Type says: **for any** `p` that is a property of `Int`,
-
`max` **takes** two `Int`s that satisfy `p`,
-
`max` **returns** an `Int` that satisfies `p`.
Parametric Refinements ---------------------- Enable *quantification over refinements* ...
\begin{code}
{-@ maxInt :: forall

Prop>. Int

-> Int

-> Int

@-} maxInt x y = if x <= y then y else x \end{code}
[Key idea: ](http://goto.ucsd.edu/~rjhala/papers/abstract_refinement_types.html)   `Int

`   is just   $\reft{v}{\Int}{p(v)}$
Abstract Refinement is **uninterpreted function** in SMT logic Parametric Refinements ---------------------- \begin{code}
{-@ maxInt :: forall

Prop>. Int

-> Int

-> Int

@-} maxInt x y = if x <= y then y else x \end{code}
**Check Implementation via SMT** Parametric Refinements ---------------------- \begin{code}
{-@ maxInt :: forall

Prop>. Int

-> Int

-> Int

@-} maxInt x y = if x <= y then y else x \end{code}
**Check Implementation via SMT**
$$\begin{array}{rll} \ereft{x}{\Int}{p(x)},\ereft{y}{\Int}{p(y)} & \vdash \reftx{v}{v = y} & \subty \reftx{v}{p(v)} \\ \ereft{x}{\Int}{p(x)},\ereft{y}{\Int}{p(y)} & \vdash \reftx{v}{v = x} & \subty \reftx{v}{p(v)} \\ \end{array}$$ Parametric Refinements ---------------------- \begin{code}
{-@ maxInt :: forall

Prop>. Int

-> Int

-> Int

@-} maxInt x y = if x <= y then y else x \end{code}
**Check Implementation via SMT**
$$\begin{array}{rll} {p(x)} \wedge {p(y)} & \Rightarrow {v = y} & \Rightarrow {p(v)} \\ {p(x)} \wedge {p(y)} & \Rightarrow {v = x} & \Rightarrow {p(v)} \\ \end{array}$$ Using Abstract Refinements -------------------------- -

**When** we call `maxInt` with args with some refinement,
-
**Then** `p` instantiated with *same* refinement,
-
**Result** of call will also have *same* concrete refinement.

\begin{code} {-@ o' :: Odd @-} o' = maxInt 3 7 -- p := \v -> Odd v {-@ e' :: Even @-} e' = maxInt 2 8 -- p := \v -> Even v \end{code}

Infer **Instantiation** by Liquid Typing At call-site, instantiate `p` with unknown $\kvar{p}$ and solve!
Recap ----- 1. Refinements: Types + Predicates 2. Subtyping: SMT Implication 3. Measures: Strengthened Constructors 4. **Abstract Refinements** over Types

Abstract Refinements are *very* expressive ... [continue]