\input{preamble}

\title{Resource Analysis: Problem Set 3}% \\ Type Inference and Unification}
\setcounter{section}{3}

\begin{document}
\maketitle

\begin{center}
  \noindent
  \large{Due before 1:30pm on Monday, February 8}
\end{center}
\subsection{(12 Points) Unique Types}

Consider the following subset of the type rules of the monomorphic
type system and the corresponding subset of syntactic forms.

  \def \MathparLineskip {\lineskip=0.45cm}
  \begin{mathpar}
    \Rule{T:Var}
    { \Gamma(x) = T
    }
    {\Gamma \tmono x : T}

    \Rule{T:Abs}
    {\Gamma,x{:}T_1 \tmono e : T_2
    }
    {\Gamma \tmono \absS{x}{e} : T_1 \to T_2}

    \Rule{T:App}
    {  \Gamma \tmono e_1 : T_2 \to T
    \\ \Gamma \tmono e_2 : T_2
    }
    {\Gamma \tmono \appS{e_1}{e_2} : T}

    \Rule{T:Nil}
    {
    }
    {\Gamma \tmono \nilS : L(T)}

    \Rule{T:Cons}
    { \Gamma \tmono e_1 : T
    \\ \Gamma \tmono e_2 : \liT{T}
    }
    {\Gamma \tmono \consS{e_1}{e_2} : \liT{T}}

    \Rule{T:MatL}
    { \Gamma \tmono e : \liT{T'}
    \\ \Gamma \tmono e_1 : T
    \\ \Gamma,x_1{:}T',x_2{:}\liT{T'} \tmono e_2 : T
    }
    {\Gamma \tmono \matchLS{e}{e_1}{x_1}{x_2}{e_2}  : T}

    \Rule{T:Rec}
    {\Gamma,f{:}T_1 \to T_2, x{:}T_1 \tmono e_f : T_1 \to T_2
    \\ \Gamma,f{:}T_1 \to T_2 \tmono e : T
    }
    {\Gamma \tmono \recS{f}{x}{e_f}{e} : T}
  \end{mathpar}
\begin{enumerate}[a)]
\item Show that there are expressions $e$
  such that $\Gamma \tmono e : T$
  and $\Gamma \tmono e : T'$
  for monomorphic types $T \neq T'$ and a type context $\Gamma$.
\item Add a minimal number of type annotations to the syntactic forms
  to make types unique.
\item Prove that your annotations make types unique: If
  $\Gamma \tmono e : T$
  and $\Gamma \tmono e : T'$
  in the modified type system then $T = T'$.
  For example, the rule \textsc{T:Pair} with type annotations could
  look as follows.
%
\begin{mathpar}
    \Rule{T:Pair}
    {  \Gamma \tmono e_1 : T_1
    \\ \Gamma \tmono e_2 : T_2
    }
    {\Gamma \tmono \pairS{e_1:T_1}{e_2:T_2} : T_1*T_2}
\end{mathpar}

\item Prove that your annotations are minimal: Show that every type
  system that you obtain after removing one annotation has the property stated in part (a).
\end{enumerate}



\subsection{(18 Points) Unification in OCaml}

A naive implementation of the declarative unification rules that we
discussed in the lecture can be quite inefficient. To make type
inference efficient, the developers of the OCaml compiler took the
following approach. First, types are represented by the following
mutually recursive type.
\begin{lstlisting}
type type_exp = 
  { mutable desc : type_desc; mutable mark : int }

and type_desc = 
    Var 
  | Arr of type_exp * type_exp
  | Pair of type_exp * type_exp
  | Link of type_exp
\end{lstlisting}
%
The record type \texttt{type\_exp} contains to mutable fields. Mutable
fields are a convenient short form and equivalent to fields that
contain references. See
\url{https://realworldocaml.org/v1/en/html/records.html} . (In fact,
references are derived from mutable records.)

The mutual recursion in the type is a common pattern in OCaml code.
It makes it more convenient to access (and update) data that is shared
among all constructors of an inductive type. The type $a * a \to b$
can be represented as follows. Note that type-variable names are
implicitly represented by ``heap addresses''.
%
\begin{lstlisting}
let type_exp d : type_exp = {desc = d; mark = 0} in

let a = type_exp Var in       
let b = type_exp Var in
let s = type_exp (Pair(a, a)) in
type_exp (Arr(s, b))
\end{lstlisting}
%
Values of type \texttt{type\_exp} can by used as a union-find data
structure.
\begin{lstlisting}
(* union find operations *)
let rec find (t : type_exp) : type_exp =
    match t.desc with
    | Link l -> 
        let r = find l 
        in t.desc <- Link r; 
           r
    | _ -> t

let union (t1 : type_exp) (t2 : type_exp) : unit =
  (find t1).desc <- Link (find t2)
\end{lstlisting}
Recall the rule \textsc{U:Elim2}:
\begin{mathpar}
  \Rule{U:Elim2}
    {\tsubst = \{X \mapsto T\} 
    \\ X \not\in \vars{T}
    }
    {\{\teq{X}{T}\} \cup \consts
     \unif 
      \{\teq{X}{T}\} \cup \tsubsT(\consts)
    }
\end{mathpar}
As the first step of OCaml's unification algorithm, the rule
\textsc{E:Elim2} is basically implemented by a call to the function
\texttt{union} without checking the side condition
$X \not\in \vars{T}$.
In this way, a graph structure is created on the heap. The record
field \texttt{mark} is not used in this first step. In the second,
step the graph structure is traversed to identify cycles. If a cycle
is found then the types are not unifyable. Otherwise, the unifyied
type can be derived by following the pointers on the heap (see
function \texttt{string\_of\_type} in \texttt{unify.ml}).

\begin{enumerate}[a)]
\item Implement OCaml's efficient unification algorithm by completing
  the OCaml file \texttt{unify.ml} that is available on the web page.
\item Argue informally why this approach is equivalent to the
  declarative rules presented in the lecture.
\item In your solution, provide three (different) pairs of (different)
  values of type \texttt{type\_exp} that are not unifyable. Similarly,
  provide three pairs of values of type \texttt{type\_exp} that are
  unifyable.
\end{enumerate}


\end{document}

%%% Local Variables:
%%% mode: latex
%%% mode: flyspell
%%% TeX-master: t
%%% End:
