\documentclass[a4paper,11pt]{article}
\usepackage{mathpartir}
\usepackage{amssymb}

\begin{document}

\title{Transfer Type Checking}
\author{Bj\"orn Bringert \\ \texttt{bringert@cs.chalmers.se}}
\maketitle

\section{Type Checking Algorithm}

This is the beginnings of a type checking algorithm for the 
Transfer Core language. It is far from complete,
and some of the rules make no sense at all at the moment.

\subsection{Notation}

$\overline{a}$ is a list of $a$s. 

$x$ stands for variables.

$A$,$B$,$C$ are terms which we use for types.

$s$,$t$ are any terms.

$l$ refers to record labels.

$p$ refers to patterns.

$c$ refers to constructors.

$\Delta$ is a set of constructor typings.

$\Gamma$ is a set of variable typings.

$\Delta;\Gamma \vdash t \uparrow A$ means that in the
variable typing context $\Gamma$ and the constructor
typing context $\Delta$, the type of $t$ can be inferred 
to be $A$.

$\Delta;\Gamma \vdash t \downarrow A$ means that in the
variable typing context $\Gamma$ and the constructor
typing context $\Delta$, the type of $t$ can be 
checked to be $A$.

$\Delta \vdash_p p \downarrow A; \Gamma$ means that
in the constructor typing context $\Delta$,
the pattern $p$ can matched against a value of type
$A$, and if the match succeeds, it will create
variable bindings with the typings $\Gamma$.

$A \leq B$ means that $A$ is a subtype of of $B$.

$A \lesssim B$ means that $A$ is convertible
to a subtype of $B$.

\subsection{Language}

\begin{eqnarray*}
s,t,u & ::= & \textrm{let} \ x = s \ \textrm{in} \ t  \\
& & | \ \textrm{case} \ s \ \textrm{of} \{ \overline{p \mid t \rightarrow u} \} \\
& & | \ \lambda x . t \\
& & | \ (x : s) \rightarrow t \\
& & | \ s \ t \\
& & | \ s.l \\
& & | \ \textrm{sig} \ \{ \overline{l : t} \} \\
& & | \ \textrm{rec} \ \{ \overline{l = t} \} \\
& & | \ x \\
& & | \ Type \\
& & | \ string \\
& & | \ integer \\
& & | \ double \\
p & ::= & x \ | \ \_ \ | \ (c \overline{p}) \ | \ rec \ \{ \overline{l = p} \} \ | \ string \ | \ integer 
\end{eqnarray*}



\subsection{Rules}

\begin{figure}
\begin{mathpar}

\inferrule[Type annotation]
{ \Delta;\Gamma \vdash t \downarrow A }
{ \Delta;\Gamma \vdash t : A \uparrow A }

\and

\inferrule[Check by inferring]
{ \Delta;\Gamma \vdash t \uparrow A' \\
  A' \lesssim A}
{ \Delta;\Gamma \vdash t \downarrow A }

\and

\inferrule[Variable]
{ x : A \in \Gamma }
{ \Delta;\Gamma \vdash x \uparrow A }

\and 

\inferrule[Constructor]
{ c : A \in \Delta }
{ \Delta;\Gamma \vdash c \uparrow A }

\and 

\inferrule[Function type]
{ \Delta;\Gamma \vdash A \downarrow Type \\
  \Delta;\Gamma, x : A \vdash B \downarrow Type }
{ \Delta;\Gamma \vdash (x : A) \rightarrow B \downarrow Type }

\and

\inferrule[Abstraction]
{ \Delta;\Gamma, x : A \vdash s \downarrow B }
{ \Delta;\Gamma \vdash \lambda x. s \downarrow (x : A) \rightarrow B }

\and 

\inferrule[Application]
{ \Delta;\Gamma \vdash s \uparrow (x : A) \rightarrow B \\ 
  \Delta;\Gamma \vdash t \downarrow A
}
{ \Delta;\Gamma \vdash s \ t \uparrow B [x / t] }

\and 

\inferrule[Local definition]
{ \Delta;\Gamma \vdash s \uparrow A \\ 
  \Delta;\Gamma, x : A \vdash t \uparrow B }
{ \Delta;\Gamma \vdash \textrm{let} \ x = s \ \textrm{in} \ t \uparrow B }

\and 

\inferrule[Case analysis]
{ \Delta;\Gamma \vdash s \uparrow A \\
  B = B_1 \vee \ldots \vee B_n \\
  \Delta \vdash_p p_1 \downarrow A; \Gamma_1 \\
  \Delta;\Gamma,\Gamma_1 \vdash g_1 \downarrow Bool \\
  \Delta;\Gamma,\Gamma_1 \vdash t_1 \uparrow B_1 \\
  \ldots \\
  \Delta p_n \vdash_p A; \Gamma_n \\
  \Delta;\Gamma, \Gamma_n \vdash g_n \downarrow Bool \\
  \Delta;\Gamma, \Gamma_n \vdash t_n \uparrow B_n
}
{ \Delta;\Gamma \vdash \textrm{case} \ s \ \textrm{of} \ \{ 
    p_1 \mid g_1 \rightarrow t_1;
    \ldots;
    p_n \mid g_n \rightarrow t_n
  \} \uparrow B }

\end{mathpar}
\caption{Basics.}
\label{fig:basics}
\end{figure}

\begin{figure}
\begin{mathpar}

\inferrule[Record type]
{ \Delta;\Gamma \vdash T_1 \uparrow Type \\ 
  \ldots \\
  \Delta;\Gamma, l_1 : T_1, \ldots, l_{n-1} : T_{n-1} \vdash T_n \uparrow Type \\
  l_1 \ldots l_n \ \textrm{different}
}
{ \Delta;\Gamma \vdash \textrm{sig} \{ l_1 : T_1, \ldots, l_n : T_n \} \uparrow Type }

\and

\inferrule[Record]
{ \Delta;\Gamma \vdash t_1 \uparrow T_1 \\ 
  \ldots \\
  \Delta;\Gamma \vdash t_n \uparrow T_n [l_{n-1} / t_{n-1}] \ldots [l_1 / t_1] \\
  l_1 \ldots l_n \ \textrm{different} }
{ \Delta;\Gamma \vdash \textrm{rec} \{ l_1 = t_1, \ldots, l_n = t_n \} 
  \uparrow \textrm{sig} \{ l_1 : T_1, \ldots, l_n : T_n \} }

\and 

\inferrule[Record projection]
{ \Delta;\Gamma \vdash t \downarrow \textrm{sig} \{ l : T \} }
{ \Delta;\Gamma \vdash t . l \uparrow T }

\end{mathpar}
\caption{Records.}
\label{fig:records}
\end{figure}


\begin{figure}
\begin{mathpar}

\inferrule[Variable pattern]
{  }
{ \Delta \vdash_p x \downarrow \ A; \{ x : A \} }

\and 

\inferrule[Wildcard pattern]
{  }
{ \Delta \vdash_p \_ \ \downarrow \ A; \{ \} }

\and 

\inferrule[Constructor pattern]
{ c : (x_1 : T_1) \rightarrow \ldots \rightarrow (x_n : T_n) \rightarrow T' \in \Delta \\
  T' = T \\
  \Delta \vdash_p p_1 \downarrow T_1; \Gamma_1 \\
  \ldots \\
  \Delta \vdash_p p_n \downarrow T_n; \Gamma_n \\
  \Gamma_1 \ldots \Gamma_n \ \textrm{disjoint} \\
  \textrm{FIXME: $x_k$ can occur in $T_{k+1}$}
  }
{ \Delta \vdash_p c \ p_1 \ldots p_n \ \downarrow \ T; \Gamma_1, \ldots, \Gamma_n }

\and 

\inferrule[Record pattern]
{ \textrm{FIXME: allow more fields in type, ignore order} \\
  \textrm{FIXME: types can depend on field values} \\
\Delta \vdash_p p_1 \ \downarrow \ T_1; \Gamma_1 \\
  \ldots \\
  \Delta \vdash_p p_n \ \downarrow \ T_n; \Gamma_n \\
  \Gamma_1 \ldots \Gamma_n \ \textrm{disjoint} \\
  l_1 \ldots l_n \ \textrm{different}
  }
{ \Delta \vdash_p \textrm{rec} \ \{ l_1 = p_1; \ldots; l_n = p_n \} \ \downarrow \ 
  \textrm{sig} \ \{ l_1 : T_1; \ldots; l_n : T_n \}; \Gamma_1, \ldots, \Gamma_n }

\and 

\inferrule[Integer literal pattern]
{  }
{ \Delta \vdash_p integer \ \downarrow \ Integer; \{ \} }

\and 

\inferrule[String literal pattern]
{  }
{ \Delta \vdash_p string \ \downarrow \ String; \{ \} }

\and 

\end{mathpar}
\caption{Type-checking patterns.}
\label{fig:typing-patterns}
\end{figure}





\begin{figure}
\begin{mathpar}

\inferrule[Integer type]
{ }
{ \Delta;\Gamma \vdash Integer \uparrow Type }

\and 

\inferrule[Integer literal]
{ }
{ \Delta;\Gamma \vdash integer \uparrow Integer }

\and 

\inferrule[Double type]
{ }
{ \Delta;\Gamma \vdash Double \uparrow Type }

\and 

\inferrule[Double literal]
{ }
{ \Delta;\Gamma \vdash double \uparrow Double }

\and 

\inferrule[String type]
{ }
{ \Delta;\Gamma \vdash String \uparrow Type }

\and 

\inferrule[String literal]
{ }
{ \Delta;\Gamma \vdash string \uparrow String }

\end{mathpar}
\caption{Primitive types.}
\label{fig:primitive-types}
\end{figure}

\begin{figure}
\begin{mathpar}

\inferrule[Subtype conversion]
{ \vdash s \Downarrow_{wh} s' \\
  \vdash t \Downarrow_{wh} t' \\
  s' \leq t' }
{ s \lesssim t }

\and 

\inferrule[Function type conversion]
{ A_2 \lesssim A_1 \\
  B_1 [x_1/z] \lesssim B_2 [x_2/z] }
{ (x_1 : A_1) \rightarrow B_1 
  \leq (x_2 : A_2) \rightarrow B_2 }

\and 

\inferrule[Constructor conversion]
{ s_1 \lesssim t_1 \\ 
  \ldots \\ 
  s_n \lesssim t_n \\ 
}
{ c \ s_1 \ldots s_n \leq c \ t_1 \ldots t_n }

\and 

\inferrule[Record type conversion]
{ A_1 \lesssim B_1 \ldots A_n \lesssim B_n \\ 
  \textrm{FIXME: types can depend on fields} \\
  \textrm{FIXME: allow more fields on the left, ignore order} }
{ \textrm{sig} \ \{ l_1 : A_1 \ldots l_n : A_n \} 
  \leq 
  \textrm{sig} \ \{ k_1 : B_1 \ldots k_m : B_m \}  }

\and 

\inferrule[Record conversion]
{ 
  \textrm{FIXME: allow more fields on the left, ignore order} \\
  s_1 \lesssim t_1 \ldots s_n \lesssim s_n
}
{ \textrm{rec} \ \{ l_1 = s_1 \ldots l_n = s_n \} 
  \leq 
  \textrm{rec} \ \{ k_1 = t_1 \ldots k_m = t_m \}  }

\and 

\inferrule[Integer conversion]
{ i_1 \ \textrm{integer} \\
  i_2 \ \textrm{integer} \\
  i_1 =_{integer} i_2}
{ i_1 \leq i_2 }

\and 

\inferrule[String conversion]
{ i_1 \ \textrm{string} \\
  i_2 \ \textrm{string} \\
  i_1 =_{string} i_2}
{ i_1 \leq i_2 }

\and 

\inferrule[Double conversion]
{ i_1 \ \textrm{double} \\
  i_2 \ \textrm{double} \\
  i_1 =_{double} i_2}
{ i_1 \leq i_2 }

\end{mathpar}
\caption{Conversion and subtyping.}
\label{fig:conversion}
\end{figure}

\begin{figure}
\begin{mathpar}

\inferrule[WHNF-Let]
{ s \Downarrow_{wh} s' \\ 
  \textrm{This is a weird way to evaluate a let} }
{ \Gamma \vdash \textrm{let} \ x = s \ \textrm{in} \ t 
                \Downarrow_{wh} t [x/s']
}

\and

\inferrule[WHNF-Case]
{ \textrm{FIXME: find the right case arm} \\
  \textrm{FIXME: bind / substitute variables in RHS} }
{ \Gamma \vdash \textrm{case} \ s \ \textrm{of} \{ \overline{p \mid t \rightarrow u} \}
  \Downarrow_{wh}
}

\and

\inferrule[WHNF-Beta]
{ \Gamma \vdash s \Downarrow_{wh} \lambda x . s' \\
  \Gamma \vdash t \Downarrow_{wh} t' }
{ \Gamma \vdash s \ t \Downarrow_{wh} s' [x/t'] \}
}

\and

\inferrule[WHNF-Proj]
{ \Gamma \vdash s \Downarrow_{wh} \textrm{rec} \ \{ \ldots, l = t, \ldots \} }
{ \Gamma \vdash s.l \Downarrow_{wh} t }

\and

\inferrule[WHNF-Var]
{ x = t \in \Gamma \\
  \textrm{FIXME: there shouldn't be any free variables (but there can be functions and constructors)} }
{ \Gamma \vdash x \Downarrow_{wh} t }


% unchanged:

\and

\inferrule[WHNF-Lambda]
{ }
{ \Gamma \vdash \lambda x . t \Downarrow_{wh} \lambda x . t }

\and

\inferrule[WHNF-Pi]
{ }
{ \Gamma \vdash (x : s) \rightarrow t \Downarrow_{wh} (x : s) \rightarrow t
}

\and

\inferrule[WHNF-Sig]
{ }
{ \Gamma \vdash \textrm{sig} \ \{ l_1 : A_1, \ldots, l_n : A_n \} 
   \Downarrow_{wh} \textrm{sig} \ \{ l_1 : A_1, \ldots, l_n : A_n \} }

\and

\inferrule[WHNF-Rec]
{ }
{ \Gamma \vdash \textrm{rec} \ \{ l_1 = t_1, \ldots, l_n = t_n \} 
   \Downarrow_{wh} \textrm{rec} \ \{ l_1 = t_1, \ldots, l_n = t_n \} }

\and

\inferrule[WHNF-Type]
{ }
{ \Gamma \vdash Type \Downarrow_{wh} Type }

\and

\inferrule[WHNF-String]
{ }
{ \Gamma \vdash string \Downarrow_{wh} string }

\and

\inferrule[WHNF-Integer]
{ }
{ \Gamma \vdash integer \Downarrow_{wh} integer }

\and

\inferrule[WHNF-Double]
{ }
{ \Gamma \vdash double \Downarrow_{wh} double }

% FIXME: applications which are not beta redexes?




\end{mathpar}
\caption{Weak head normal form evaluation.}
\label{fig:whnf-evaluation}
\end{figure}



\end{document}
