{-@ LIQUID "--no-termination" @-}
{-@ LIQUID "--diff" @-}
{-@ LIQUID "--short-names" @-}
module SimpleRefinements where
import Prelude hiding (abs, max)
zero, zero', zero'', four, four' :: Int
nats :: [Int]
{-@ plus :: x:Int -> y:Int -> {v:Int | v = x + y} @-}
plus :: Int -> Int -> Int
plus x y = x + y
{-@ minus:: x:Int -> y:Int -> {v:Int | v = x - y} @-}
minus :: Int -> Int -> Int
minus x y = x - y
-- zero' :: Int
-- safeDiv :: Int -> Int -> Int
-- size, size' :: [a] -> Int
Basic Refinement Types
Refinement Types = Types + Predicates
Types
b := Int | Bool | ... -- primitives
| a, b, c -- type variables
t := {x:b | p} -- refined base
| x:t -> t -- refined function
p
is a predicate from a SMT decidable logic
Predicates
Quantifier-Free Logic of Uninterpreted Functions & Linear Arithmetic
Predicates
Quantifier-Free Logic of Uninterpreted Functions & Linear Arithmetic
e := x, y, z, ... -- variables
| 0, 1, 2, ... -- constants
| e + e | c * e | ... -- arithmetic
| f e1 ... en -- uninterpreted function
Predicates
Quantifier-Free Logic of Uninterpreted Functions & Linear Arithmetic
e := x, y, z, ... -- variables
| 0, 1, 2, ... -- constants
| e + e | c * e | ... -- arithmetic
| f e1 ... en -- uninterpreted function
Congruence Axiom for Uninterpreted Functions
\[\forall \overline{x}, \overline{y}.\ \overline{x} = \overline{y}\ \Rightarrow\ f(x) = f(y)\]
Predicates
Quantifier-Free Logic of Uninterpreted Functions & Linear Arithmetic
e := x, y, z, ... -- variables
| 0, 1, 2, ... -- constants
| e + e | c * e | ... -- arithmetic
| f e1 ... en -- uninterpreted function
p := e <= e | ... -- atoms
| p && p | p || p | !p -- boolean combinations
Predicates
Quantifier-Free Logic of Uninterpreted Functions & Linear Arithmetic
Given a Verification Condition (VC)
\[p_1 \Rightarrow \ldots \Rightarrow p_n\]
SMT solvers can decide if VC is Valid ("always true")
Example: "Singletons"
The alias Zero
describes a type inhabited by a single Int
value 0
{-@ type Zero = {v:Int | v == 0} @-}
{-@ zero :: Zero @-}
zero = 0
Refinement types via special comments {-@ ... @-}
Exercise: What happens if you modify the code or type?
Example: Natural Numbers
{-@ type Nat = {v:Int | 0 <= v} @-}
{-@ nats :: [Nat] @-}
nats = [0, 1, 2, 3]
Exercise: What happens if you modify the code or type?
A Term Can Have Many Types
What is the type of 0
?
{-@ zero' :: Nat @-}
zero' = zero
Is it {v:Int|v=0}
or is it {v:Int|0<=v}
?
In environment \(\Gamma\) the type \(t_1\) is a subtype of \(t_2\)
\[\boxed{\Gamma \vdash t_1 \preceq t_2}\]
In environment \(\Gamma\) the type \(t_1\) is a subtype of \(t_2\)
\[\boxed{\Gamma \vdash t_1 \preceq t_2}\]
Where \(\Gamma\) is variable-and-type bindings that are in-scope
\[\Gamma \doteq \overline{\bindx{x_i}{P_i}}\]
In environment \(\Gamma\) the type \(t_1\) is a subtype of \(t_2\)
\[\boxed{\Gamma \vdash t_1 \preceq t_2}\]
\[
\begin{array}{rll}
{\mathbf{If\ VC\ is\ Valid}} & \bigwedge_i p_i \Rightarrow q \Rightarrow r & (\mbox{By SMT}) \\
& & \\
{\mathbf{Then}} & \overline{\bindx{x_i}{p_i}} \vdash \reft{v}{b}{q} \preceq \reft{v}{b}{r} & \\
\end{array}
\]
Example: Natural Numbers
\[
\begin{array}{rcrccll}
\mathbf{VC\ is\ Valid:} & \True & \Rightarrow & v = 0 & \Rightarrow & 0 \leq v & \mbox{(by SMT)} \\
\mathbf{So:} & \emptyset & \vdash & \Zero & \preceq & \Nat & \\
\end{array}
\]
Example: Natural Numbers
\[
\begin{array}{rcrccll}
\mathbf{VC\ is\ Valid:} & \True & \Rightarrow & v = 0 & \Rightarrow & 0 \leq v & \mbox{(by SMT)} \\
\mathbf{So:} & \emptyset & \vdash & \Zero & \preceq & \Nat & \\
\end{array}
\]
And so, we can type:
{-@ zero'' :: Nat @-}
zero'' = 0 -- as |- Zero <: Nat
2. Typing Applications (Function Calls)
Terms built up by function-applications.
2. Typing Applications (Function Calls)
Terms built up by function-applications.
Built-in Functions
plus :: x:Int -> y:Int -> {v:Int|v = x + y}
minus :: x:Int -> y:Int -> {v:Int|v = x - y}
Output Type is a Post-Condition
Specifies the output value equals the sum/difference of the inputs
2. Typing Applications (Function Calls)
Terms built up by function-applications.
{-@ four :: Nat @-}
four = plus x 1
where
x = 3
How to prove four :: Nat
?
2. Typing Applications (Function Calls)
Dependent Application
\[\begin{array}{rl}
{\mathbf{If}} & \Gamma \vdash f :: \bindx{x}{s} \rightarrow t \\
& \Gamma \vdash y :: s \\
{\mathbf{Then}} & \Gamma \vdash f\ y :: t[x \mapsto y] \\
\end{array}\]
i.e. Output type with formals substituted by actuals
2. Typing Applications (Function Calls)
Dependent Application: Example
\[
\begin{array}{rl}
{\mathbf{If}} & \Gamma \vdash \mathit{plus} :: \bindx{a}{\Int} \rightarrow
\bindx{b}{\Int} \rightarrow
\reft{v}{\Int}{v = a + b} \\
& \Gamma \vdash x :: \Int \\
& \Gamma \vdash 1 :: \Int \\
& \\
{\mathbf{Then}} & \Gamma \vdash \mathit{plus}\ x\ 1 :: \reft{v}{\Int}{v = x + 1}
\end{array}
\]
2. Typing Applications (Function Calls)
And so, we can type:
{-@ four' :: Nat @-}
four' = plus x 1 -- x = 3 |- {v = x+1} <: Nat
where -- as
x = 3 -- x = 3 => v = x+1 => 0 <= v
Exercise: What happens if you replace plus
with minus
?
2. Typing Applications (Function Calls)
Similarly, we can type:
{-@ incr :: Nat -> Nat @-}
incr x = plus x 1 -- {0 <= x} |- {v = x + 1} <: Nat
-- as
-- (0 <= x) => v = x + 1 => 0 <= v
Exercise: Now, what happens if you replace plus
with minus
?
Recap: Basic Refinement Types
Refinement Types
Types + Predicates
Recap: Basic Refinement Types
Refinement Types
Types + Predicates
Refinement Checking
Dependent Application + Predicate Subtyping
Recap: Refinement Types 101
Refinement Types
Types + Predicates
Refinement Checking
Dependent Application + Predicate Subtyping