\chapter{Introduction}

%\subsection{Overview}

Functional programming languages, like ML and Haskell,
come with strong static type systems, which detect a lot 
of errors at compile-time and enhance code documentation.


The usefulness of these type systems stems from their ability to predict, 
at compile-time, invariants about the run-time values computed by the program. 
%
Unfortunately, traditional type systems only
capture relatively coarse invariants. For example, the system can
express the fact that a variable @i@ is of type @Int@, 
meaning that it is always an integer, 
but not that it is always an integer with a
certain property, say different than zero. 
%
Thus, the type system is unable to statically ensure the safety of critical operations, 
such as division by @i@. 
%
Several authors have proposed the
use of refinement types \cite{FreemanPfenning91, flanagan06, LiquidPLDI08, Greenberg12} as a mechanism for enhancing the
expressiveness of type systems. 

\textit{Refinement types} refine a vanilla type with a predicate.
For example, one can give @i@ the following type:
$$\centering\begin{tabular}{c}
\begin{code}
i :: {v:Int | v != 0}
\end{code}
\end{tabular}$$
%
that describes a value @v@ of type @Int@,
while the refinement constraints 
this value @v@ to be different than @0@.


One can use this refinement type to define a safe division operator:
%
$$\centering\begin{tabular}{c}
\begin{code}
safeDiv :: Int -> {v:Int | v != 0} -> Int
\end{code}
\end{tabular}$$
%
This type captures that the division operator takes two
@Int@ arguments and returns an @Int@.
Moreover, it restricts the second argument to be different that
zero, to eliminate division by zero operations. 

At the call site of @safeDiv@ 
the type system should check that the real arguments do not
violate its specification.
%
For instance, 
@safeDiv 8 9@ is safe, since @9@ is always different that zero,
but @safeDiv 8 0@ should raise a type error.
Apart from concrete values, @safeDiv@ can be applied to arbitrary program expressions:
@safeDiv n m@ is safe only if 
@m@ is an integer different than zero.

\mypara{Refinement Function Types}
\textit{Refinement function types}~\cite{cayenne, flanagan06} allow the specification of the 
result to depend on the argument.
%
A parameter is used to bind the argument
and can appear in the refinement of the result.
%
%Dependent types, allow the refinement of the result of a function
%to depend on function's arguments.
As an example, we define a @pred@ function, 
which takes as argument a positive integer @n@ and returns its predecessor.
Refinement function types allow us to give @pred@ a type
that exactly captures this behaviour:
%
$$\centering\begin{tabular}{c}\begin{code}
pred :: n : {v:Int | v > 0} -> {v:Int | v = n-1}
pred n = n-1
\end{code}\end{tabular}$$
%
This type denotes that for each positive integer argument @n@, 
the result is an @Int@ exactly equal to @n-1@.
When @pred@ is applied to a concrete value, 
the parameter @n@ is substituted with this value.
For example 
$$\centering\begin{tabular}{c}\begin{code}
pred 2 :: {v:Int | v = n-1}[2/n] = {v:Int | v = 1}
\end{code}\end{tabular}$$
%
Thus, for each concrete argument, the result should be the predecessor 
of this argument.

\mypara{Specifications}
A \textit{specification}~\cite{Lamsweerde00} is the expression in some 
formal language and at some level 
of abstraction of a collection of properties 
some program should satisfy.
%
%Specifications have syntax and semantics to 
%describe and interpret program properties. 
%
Specifications can be expressed in various techniques.
%based on the kind of properties they are to express.
%
For example,
temporal logic can be used to express history-based
specifications,
e.g., to reason about program's behaviour over time,
while monitors can be used to express state-based specifications, 
e.g., reasoning about concurrency.
%
In this paper we use refinement type signatures
to describe (pure) functional specifications, 
i.e., the program is specified as a collection of mathematical functions.
%
This way, we limit ourselves to ignore features such as
temporal constrains, imperative features and concurrency. 


\mypara{Verification}
\textit{Verification} is a procedure that takes as input 
a program, i.e.,  definitions for functions and values,
and some specifications, i.e., refinement type signatures for functions and values,
and decides whether the specifications hold for the program.
%
Informally, it checks that 
each expression satisfies its type, 
for example, that the @pred@ definition actually returns the 
predecessor of its argument,
or that 
at each function application the arguments satisfy
the function's preconditions, 
as in the @safeDiv@ example.
%
If the specifications hold, the program is \textit{Safe}, 
otherwise it is \textit{Unsafe}. 

Higher-order programming languages, such as ML or Haskell, 
treat functions as first order objects.
Thus, one can use functions in refinements and 
create higher-order predicates. 
For instance, the following type
%
$$\centering\begin{tabular}{c}\begin{code}
f:(a->b) -> {v:Bool|terminates f}
\end{code}\end{tabular}$$
%
describes that an arbitrary functional argument
should satisfy a predicate @terminates@.
%
Reasoning in a higher-order logic is undecidable, 
thus if arbitrary program values appear in the refinements,
the verification procedure is undecidable.
%
As we shall see, 
if the refinement language is restricted, i.e., is less expressive,
verification can be decidable.

The rest of this paper is organized as follows:
In \S~\ref{subsec:formal} we present a core calculus
that constitutes the base for many refinement type systems.
In \S~\ref{sec:undec}
we describe reasoning in undecidable refinement type systems.
In \S~\ref{sec:liquid}
we present less expressive type systems (like LiquidTypes)
that are decidable.
In \S~\ref{sec:abstract} 
we present how abstraction over refinements
enhances expressiveness of decidable type systems. 
Then \S~\ref{sec:liquidhaskell} we present \toolname
that combines liquidTypes with abstraction over refinements
to enhance expressiveness of LiquidTypes.
\toolname is a quite expressive verification tool for Haskell programs 
that can be used to check termination (\S~\ref{sec:termination}), 
totality (\S~\ref{sec:totality}) and general functional correctness   (\S~\ref{sec:structures}).
Finally, we evaluate \toolname and conclude.

\chapter{Preliminaries}\label{subsec:formal}

To formally describe and compare type systems, 
we define a core calculus, following \cite{flanagan06, LiquidPLDI08, Greenberg12}.
We refer to our calculus as $\lambda_C$, 
and in this section we present its syntax and type system.

\section{Syntax}
The syntax of expressions and types is summarized in Figure \ref{fig:coresyntax}.
$\lambda_C$ expressions include variables, constants,
typed $\lambda$-abstractions
and function applications. 
%
Constants include primitive integers:
$0, 1, 2, \dots$ and primitive booleans: \texttt{true} or \texttt{false},
which take the basic types, integer and boolean, respectively.
%
A basic type can be refined with a predicate to construct a basic
refinement type.
Refinement types also contain function types, 
in which 
a variable binds the argument,
so that the result refinement can refer to it.  
%
The predicate $p$ is
not yet defined. 
As noted earlier, if $p$ contains arbitrary program 
expressions, the type system is undecidable, but 
$p$ can be restricted in such a way as to render 
the type system decidable.
%
Finally, we define a typing environment $\Gamma$ that maps variables to their type,
and will be used in the typing rules that we will discuss.


\begin{figure}[t!]
\centering
$$
\begin{array}{rrcl}
\emphbf{Expressions} \quad 
  & e 
  & ::= 
  &      x 
  \spmid c 
  \spmid \efunt{x}{\tau}{e} 
  \spmid \eapp{e}{e} 
%  \spmid \etabs{\alpha}{e} 
%  \spmid \etapp{e}{\tau} 
  \\[0.05in] 

\emphbf{Predicates} \quad 
  & p
  & ::= 
  & \dots
  \\[0.05in] 

\emphbf{Basic Types} \quad 
  & b 
  & ::= 
  &      \tbint
  \spmid \tbbool
%  \spmid \alpha
  \\[0.05in]

\emphbf{Refinement Types} \quad 
  & \tau 
  & ::= 
  &      \tref{b}{p} 
  \spmid \tfun{x}{\tau}{\tau}
  \\[0.05in]

\emphbf{Typing Environment} \quad 
  & \Gamma 
  & ::= 
  &      \emptyset 
  \spmid x:\tau, \Gamma

\end{array}
$$
\caption{\textbf{Syntax of $\lambda_C$}}
\label{fig:coresyntax}
\end{figure}



\section{Typing}
The typing rules used by $\lambda_C$ are summarized in Figure \ref{fig:corerules}.

% \subsubsection*{typing}
\mypara{Type Checking}
Type checking rules state that
an expression $e$ has a type $\tau$ under an environment $\Gamma$,
that is, when the free variables in $e$ are bound to values described by 
$\Gamma$, the expression $e$ will evaluate to a value described by $\tau$.
We write \hastype{\Gamma}{e}{\tau} and create one rule for each program expression.

The rule \tconst uses a function $tc$ that maps each primitive constant 
to its predefined type.
%
The rule \tvariable checks the type of a variable, according 
to the environment $\Gamma$.
%
The rule \tfunction checks the type of the function-body
in the environment, extended with the argument of the function.
Since the argument type is given, it could be any arbitrary type,
say \tref{b}{1},
which is invalid, as a base type is refined with 
the value $1$, which cannot be a valid predicate.
%
A well-formedness rule is used to 
check that the argument type is \textit{well-formed}, 
i.e., its refinements are valid predicate expressions.
%
Finally, the rule \tapp checks that in an application \eapp{e_1}{e_2}
the expression $e_1$ has a function type
whose argument is the type of the argument $e_2$.
%
As we discussed in the introduction, in the final type,
the parameter $x$ should be replaced with the actual argument $e_2$.

%\subsubsection{wf}
\mypara{Well-formedness Rules}
Well-formedness rules  
state that a type $\tau$ is well-formed under an environment
$\Gamma$, that is, the refinements in $\tau$ are boolean 
expressions in the environment $\Gamma$.
%
We write \isWellFormed{\Gamma}{\tau} and create one rule for each type.

The rule \wtBase checks that in a basic refinement type,  
the refinement is a valid boolean expression.
The environment of this check is extended with the value that is refined;
for instance, to check the validity of \tref{\texttt{int}}{v > 0}, 
we check that $v > 0$ is a boolean expression, in an 
environment where $v$ is an integer value.
%
The rule \wtFun recursively applies the well-formedness rule to
the argument type of the function, and to the result type, 
in an environment extended with the argument parameter.

%\subsubsection{sub}
\mypara{Subtyping Rules}
Consider that the predefined type for the integer $2$
is an integer that is exactly equal to $2$.
The type system can check, via the rule \tconst , that 
\hastype{\emptyset}{2}{\tref{\texttt{int}}{v = 2}}.
If $2$ is applied to a function that expects a
positive integer, say $f::\tfun{x}{\tref{\texttt{int}}{v>0}}{\tau}$,
the type system should also check that 
\hastype{\emptyset}{2}{\tref{\texttt{int}}{v > 0}}.
%
There are many ways for this check to succeed.
We follow \textit{syntactic subtyping},
in which subtyping reduces to implication checking.
In our example, $v = 2 \Rightarrow v > 0 $ implies 
$\tref{\texttt{int}}{v=2} \preceq \tref{\texttt{int}}{v>0}$.


In the general case, subtyping rules
state that the type $\tau_1$ is a subtype of the type
$\tau_2$ under environment $\Gamma$, i.e., when the free variables
of $\tau_1$ and $\tau_2$
are bound to values described by $\Gamma$, the set of values described
by $\tau_1$ is contained in the set of values described by $\tau_2$. 
We write \isSubType{\Gamma}{\tau_1}{\tau_2} and create one rule for every type.

The rule \tsubBase serves two purposes.
Firstly,
it checks that the basic type is the same in the two types.
Secondly, it checks that under the environment $\Gamma$, 
the left hand side refinement implies the right hand side.
The implication checking is enforced by a predicate \texttt{Valid} 
which varies between the systems that we will describe.
%
The rule \tsubFun relates two function types according to the contravariant rule.


In the rest of this paper, we will use the core calculus $\lambda_C$
upon which we will build a subset of three typing systems~\cite{LiquidPLDI08, Greenberg12, Vazou13}.


\begin{figure}[ht!]
\medskip \judgementHead{Type Checking}{$\hastype{\Gamma}{e}{\tau}$}
\begin{comment}
$$\begin{array}{cc}

\inference
  {  \hastype{\Gamma}{e}{\tau_2} && \isSubType{\Gamma}{\tau_2}{\tau_1} 
  && \isWellFormed{\Gamma}{\tau_1}
  }
  {\hastype{\Gamma}{e}{\tau_1}}
  [\tsub]
\end{array}$$
\end{comment}
$$\begin{array}{cc}
\inference
  {}
  {\hastype{\Gamma}{c}{\tc{c}}}
  [\tconst]
&
\inference
  {x:\tau \in \Gamma}
  {\hastype{\Gamma}{x}{\tau}} 
  [\tvariable]
\end{array}$$
$$\begin{array}{cc}
\inference
  {\hastype{\Gamma, x:\tau_x}{e}{\tau} &&     
  \isWellFormed{\Gamma}{\tau_x}
  }
  {\hastype{\Gamma}{\efunt{x}{\tau_x}{e}}{(\tfun{x}{\tau_x}{\tau})}}
  [\tfunction]
&
\inference
  {\hastype{\Gamma}{e_1}{\tfun{x}{\tau_x}{\tau}} &&
   \hastype{\Gamma}{e_2}{\tau_x}
  }
  {\hastype{\Gamma}{\eapp{e_1}{e_2}}{\tau[e_2/x]}} 
  [\tapp]
\end{array}$$
\judgementHead{Well-Formedness}{\isWellFormed{\Gamma}{\tau}}
$$\inference
    {\hastype{\Gamma, v:b}{p}{\tbbool}}
    {\isWellFormed{\Gamma}{\tref{b}{p}}}
    [\wtBase]
\qquad
\inference
    {
    \isWellFormed{\Gamma}{\tau_x} &&
	\isWellFormed{\Gamma, x:\tau_x}{\tau}
    }
    {\isWellFormed{\Gamma}{\tfun{x}{\tau_x}{\tau}}}
    [\wtFun]
$$
\medskip \judgementHead{Subtyping}{\isSubType{\Gamma}{\tau}{\tau}}
$$
\inference
   {(\Gamma, v:b \vdash \texttt{Valid}(p_1 \Rightarrow p_2))}
   {\isSubType{\Gamma}{\tref{b}{p_1}}{\tref{b}{p_2}}}
   [\tsubBase]
$$
$$
\inference
   {\isSubType{\Gamma}{\tau_{21}}{\tau_{11}} &
	\isSubType{\Gamma, x_2:{\tau_{21}}}{\SUBST{\tau_{12}}{x_1}{x_2}}{\tau_{22}}	
   }
   {\isSubType{\Gamma}
	  {\tfun{x_1}{\tau_{11}}{\tau_{12}}}
	  {\tfun{x_2}{\tau_{21}}{\tau_{22}}}
}[\tsubFun]
$$
\caption{\textbf{Static Semantics for $\lambda_C$}}
\label{fig:corerules}
\end{figure}