1140 lines
45 KiB
TeX
1140 lines
45 KiB
TeX
|
|
\section{Unify}\label{sec:unify}
|
|
\newcommand{\gtype}[1]{\type{#1}}
|
|
%\newcommand{\tw}[1]{\tv{#1}_?}
|
|
The \unify{} algorithm computes the type solution.
|
|
|
|
\begin{description}
|
|
\item[Input:] List of constraints $C = \set{ \type{T} \lessdot \type{T}, \type{T} \doteq \type{T} \ldots}$
|
|
|
|
The input constraints must be of the following format:
|
|
|
|
\begin{tabular}{lcll}
|
|
$c $ &$::=$ & $\type{T} \lessdot \type{U}$ & Constraint \\
|
|
$\type{T}, \type{U}, \type{L} $ & $::=$ & $\tv{a} \mid \wtv{a} \mid \ntype{N}$ & Type variable or Wildcard Variable or Type \\
|
|
$\ntype{N}, \ntype{S}$ & $::=$ & $\wctype{\overline{\wildcard{X}{U}{L}}}{C}{\ol{T}} $ & Class Type \\
|
|
\end{tabular}\\[0.5em]
|
|
|
|
\noindent
|
|
Additional requirements:
|
|
\begin{itemize}
|
|
\item The input only consists of $\lessdot$ constraints
|
|
% \item No free variables in type parameters.
|
|
% A constraint like $\tv{a} \lessdot \exptype{List}{\rwildcard{X}}$ is prohibited.
|
|
% $\tv{a} \lessdot \wctype{\rwildcard{X}}{List}{\rwildcard{X}}$ is valid.
|
|
\item the input is a list of constraints. It cannot be a set.
|
|
A constraint set containing the constraint $\tv{a} \lessdot \type{T}$ twice
|
|
is a different to one that contains it only once.
|
|
%\item every wildcard is bound to its enclosing type.
|
|
\item Naming scheme of every wildcard environment has to be the same.
|
|
%TODO: We need this so that wildcard substitutions get the correct name. also the Equals rule needs this condition
|
|
%Example:
|
|
Although alpha renaming of wildcards inside a type is allowed by the type system the \unify{} algorithm never does it.
|
|
Renaming wildcards leads to additional problems in the substitution rules and in the result containing substitutions with renamed wildcards.
|
|
For the \rulename{Equals} to work properly it is adviced to name all wildcards in a specific scheme.
|
|
For example by numbering them according to their appereance inside the type parameters
|
|
(e.g. $\wctype{\rwildcard{1}, \rwildcard{2}}{Pair}{\rwildcard{1}, \rwildcard{2}}$).
|
|
\end{itemize}
|
|
|
|
\item[Output:]
|
|
Set of unifiers $Uni = \set{\sigma_1, \ldots, \sigma_n}$ and an environment $\Delta$
|
|
\end{description}
|
|
|
|
The \unify{} algorithm internally uses the following data types:
|
|
|
|
\begin{tabular}{lcll}
|
|
$C $ &$::=$ &$\overline{c}$ & Constraint set \\
|
|
$c $ &$::=$ & $\type{T} \lessdot \type{T} \mid \type{T} \lessdotCC \type{T} \mid \type{T} \doteq \type{T}$ & Constraint \\
|
|
$\type{T}, \type{U}, \type{L} $ & $::=$ & $\tv{a} \mid \wtv{a} \mid \gtype{G}$ & Type variable or Type \\
|
|
$\gtype{G}$ & $::=$ & $\type{X} \mid \ntype{N}$ & Wildcard, or Class Type \\
|
|
$\ntype{N}, \ntype{S}$ & $::=$ & $\wctype{\triangle}{C}{\ol{T}} $ & Class Type \\
|
|
$\triangle$ & $::=$ & $\overline{\wtype{W}}$ & Wildcard Environment \\
|
|
$\wtype{W}$ & $::=$ & $\wildcard{X}{U}{L}$ & Wildcard \\
|
|
\end{tabular}
|
|
|
|
The $\wtv{a}$ type variables are flagged as wildcard type variables.
|
|
These type variables can be substituted by a wildcard or a type with free wildcard variables.
|
|
As long as a type variable is flagged with as $\wtv{a}$ it will only be used by the subst-wc rule in step 1.
|
|
In step 2 all of the wildcard flags are dismissed.
|
|
The output therefore never contains these flags.
|
|
|
|
\unify{} applies a capture conversion everywhere it is possible (see \rulename{Capture} rule).
|
|
Capture conversion removes a types bounding environment $\Delta$.
|
|
Type variables used in its type parameters are now bound to a global scope and not locally anymore.
|
|
|
|
With \texttt{C} being class names and \texttt{A} being wildcard names.
|
|
The wildcard type $\wildcard{X}{U}{L}$ consist out of an upper bound $\type{U}$, a lower bound $\type{L}$
|
|
and a name $\mathtt{X}$.
|
|
|
|
The \rulename{Normalize} rule eliminates wildcards. % TODO
|
|
This is done by setting the upper and lower bound to the same value.
|
|
\unify{} generates wildcards with the \rulename{\generalizeRule} rule.
|
|
It is important to generate new wildcards in a standardized fashion.
|
|
When having two constraints $\type{T} \lessdot \tv{a}$ and $\type{T} \lessdot \tv{b}$,
|
|
then after applying the \rulename{\generalizeRule} rule the freshly generated constraints are
|
|
$\tv{a} \doteq \type{T'}, \tv{b} \doteq \type{T'}$.
|
|
Both type variables get assigned the same type.
|
|
This is necessary for the \rulename{Equals} rule to work properly.
|
|
|
|
|
|
\begin{figure}
|
|
\begin{center}
|
|
\leavevmode
|
|
\fbox{
|
|
\begin{tabular}[t]{l@{~}l}
|
|
\rulename{Subst} &
|
|
$\begin{array}[c]{l}
|
|
\wildcardEnv \vdash C \cup \set{\tv{a} \doteq \type{T}}\\
|
|
\hline
|
|
[\type{T}/\tv{a}]\wildcardEnv \vdash [\type{T}/\tv{a}]
|
|
C \cup \set{\tv{a} \doteq \type{T}}
|
|
\end{array}
|
|
\quad \begin{array}{c}
|
|
\tv{a} \notin \type{T} \\
|
|
\text{fv}(\type{T}) = \emptyset
|
|
\end{array}$\\
|
|
\\
|
|
\rulename{Subst-WC} &$
|
|
\begin{array}[c]{l}
|
|
\wildcardEnv \vdash C \cup \set{\wtv{a} \doteq \rwildcard{G}}\\
|
|
\hline
|
|
[\type{G}/\wtv{a}]\wildcardEnv \vdash [\type{G}/\wtv{a}]C \cup \set{\tv{a} \doteq \type{G}}
|
|
\end{array} \quad \wtv{a} \notin \type{G}
|
|
$
|
|
\end{tabular}}
|
|
\end{center}
|
|
\caption{Substitution rules}\label{fig:subst-rules}
|
|
\end{figure}
|
|
|
|
|
|
\begin{figure}
|
|
\begin{center}
|
|
\leavevmode
|
|
\fbox{
|
|
\begin{tabular}[t]{l@{~}l}
|
|
% \rulename{normalize}
|
|
% & $
|
|
% \begin{array}[c]{l}
|
|
% \wildcardEnv \cup \set{\wildcard{A}{\type{U}}{\type{L}}, \wildcard{B}{U'}{L'}} \vdash C \cup \, \set{ \rwildcard{A} \doteq \rwildcard{B} } \\
|
|
% \hline
|
|
% \vspace*{-0.4cm}\\
|
|
% \wildcardEnv \cup \set{\wildcard{A}{\type{U}}{\type{L}}, \wildcard{B}{U'}{L'}} \vdash C \cup \, \set{ \type{L} \doteq \type{U} , \type{U} \doteq \type{U'}, \type{L} \doteq \type{L'} }
|
|
% \end{array}
|
|
% $
|
|
% \\\\
|
|
\rulename{Upper}
|
|
& $
|
|
\begin{array}[c]{l}
|
|
\wildcardEnv \cup \set{\wildcard{A}{U}{L}} \vdash C \cup \, \set{ \type{A} \lessdot \type{T} } \\
|
|
\hline
|
|
\vspace*{-0.4cm}\\
|
|
\wildcardEnv \cup \set{\wildcard{A}{U}{L}} \vdash C \cup \, \set{ \type{U} \lessdot \type{T} }
|
|
\end{array}
|
|
$
|
|
\\\\
|
|
\rulename{Lower}
|
|
& $
|
|
\begin{array}[c]{l}
|
|
\wildcardEnv \cup \set{\wildcard{A}{U}{L}} \vdash C \cup \set{ \type{T} \lessdot \type{A} } \\
|
|
\hline
|
|
\vspace*{-0.4cm}\\
|
|
\wildcardEnv \cup \set{\wildcard{A}{U}{L}} \vdash C \cup \set{ \type{T} \lessdot \type{L} }
|
|
\end{array}
|
|
$
|
|
\\\\
|
|
\rulename{Bot}
|
|
& $
|
|
\begin{array}[c]{l}
|
|
\wildcardEnv \vdash C \cup \set{ \bot \lessdot \type{T} } \\
|
|
\hline
|
|
\vspace*{-0.4cm}\\
|
|
\wildcardEnv \vdash C
|
|
\end{array}
|
|
$
|
|
\\\\
|
|
\rulename{Pit}
|
|
& $
|
|
\begin{array}[c]{l}
|
|
\wildcardEnv \vdash C \cup \set{ \tv{a} \lessdot \bot } \\
|
|
\hline
|
|
\vspace*{-0.4cm}\\
|
|
\wildcardEnv \vdash C \cup \set{ \tv{a} \doteq \bot }
|
|
\end{array}
|
|
$
|
|
\\\\
|
|
\end{tabular}}
|
|
\end{center}
|
|
\caption{Wildcard reduce rules}\label{fig:wildcard-rules}
|
|
\end{figure}
|
|
|
|
\begin{figure}
|
|
\begin{center}
|
|
\leavevmode
|
|
\fbox{
|
|
\begin{tabular}[t]{l@{~}l}
|
|
\rulename{normalize}
|
|
& $
|
|
\begin{array}[c]{l}
|
|
\wildcardEnv \cup \set{\wildcard{A}{\type{U}}{\type{L}}, \wildcard{B}{U'}{L'}} \vdash C \cup \, \set{ \rwildcard{A} \doteq \rwildcard{B} } \\
|
|
\hline
|
|
\vspace*{-0.4cm}\\
|
|
\wildcardEnv \cup \set{\wildcard{A}{\type{U}}{\type{L}}, \wildcard{B}{U'}{L'}} \vdash C \cup \, \set{ \type{L} \doteq \type{U} , \type{U'} \doteq \type{L'}, \type{U} \doteq \type{U'} }
|
|
\end{array} \quad
|
|
\text{fv}(\type{U}, \type{U'}, \type{L}, \type{L'}) = \emptyset
|
|
$
|
|
\\\\
|
|
\rulename{Tame}
|
|
& $
|
|
\begin{array}[c]{l}
|
|
\wildcardEnv \cup \set{\wildcard{A}{\type{U}}{\type{L}}} \vdash C \cup \, \set{ \rwildcard{A} \doteq \type{T} } \\
|
|
\hline
|
|
\vspace*{-0.4cm}\\
|
|
\wildcardEnv \cup \set{\wildcard{A}{\type{U}}{\type{L}}} \vdash C \cup \, \set{ \type{L} \doteq \type{T}, \type{U} \doteq \type{T} }
|
|
\end{array} \quad \text{fv}(\type{U}, \type{L}) = \emptyset
|
|
$
|
|
\\\\
|
|
% \rulename{Equals} %TODO
|
|
% & $
|
|
% \begin{array}[c]{l}
|
|
% \wildcardEnv \vdash C \cup \, \set{ \type{N} \doteq \type{N'} } \\
|
|
% \hline
|
|
% \vspace*{-0.4cm}\\
|
|
% \wildcardEnv \vdash C \cup \,
|
|
% \set{
|
|
% \type{N} \lessdot \type{N'}, \type{N'} \lessdot \type{N}
|
|
% }
|
|
% \end{array} \quad \text{fv}(\type{N}) = \text{fv}(\type{N'}) = \emptyset
|
|
% $
|
|
% \\\\
|
|
\rulename{Equals} %TODO
|
|
& $
|
|
\begin{array}[c]{l}
|
|
\wildcardEnv \vdash C \cup \, \set{ \wctype{\Delta}{C}{\ol{T}} \doteq \wctype{\Delta}{C}{\ol{T'}} } \\
|
|
\hline
|
|
\vspace*{-0.4cm}\\
|
|
\wildcardEnv \vdash C \cup \,
|
|
\set{
|
|
% \pi(\ol{T}) \doteq \pi(\ol{T'} )
|
|
\ol{T} \doteq \ol{T'}
|
|
}
|
|
\end{array}
|
|
% \quad \begin{array}{l}
|
|
% \text{given a permutation}\ \pi\ \text{with:}\\
|
|
% \pi(\Delta) = \pi(\Delta')
|
|
% \end{array}
|
|
$
|
|
\\\\
|
|
\rulename{Erase}
|
|
& $
|
|
\begin{array}[c]{l}
|
|
\wildcardEnv \vdash C \cup \, \set{ \type{T} \doteq \type{T} } \\
|
|
\hline
|
|
\vspace*{-0.4cm}\\
|
|
\wildcardEnv \vdash C
|
|
\end{array}
|
|
$
|
|
\\\\
|
|
\rulename{Erase}
|
|
& $
|
|
\begin{array}[c]{l}
|
|
\wildcardEnv \vdash C \cup \, \set{ \type{T} \lessdot \type{T} } \\
|
|
\hline
|
|
\vspace*{-0.4cm}\\
|
|
\wildcardEnv \vdash C
|
|
\end{array}
|
|
$
|
|
\\\\
|
|
\rulename{Swap} & $
|
|
\begin{array}[c]{l}
|
|
\wildcardEnv \vdash C \cup \set{\type{G} \doteq \tv{a}}\\
|
|
\hline
|
|
\wildcardEnv \vdash C \cup \set{\tv{a} \doteq \type{G}}
|
|
\end{array}
|
|
\quad
|
|
\begin{array}[c]{l}
|
|
\wildcardEnv \vdash C \cup \set{\type{G} \doteq \wtv{a}}\\
|
|
\hline
|
|
\wildcardEnv \vdash C \cup \set{\wtv{a} \doteq \type{G}}
|
|
\end{array} \quad
|
|
\begin{array}[c]{l}
|
|
\wildcardEnv \vdash C \cup \set{\type{N} \doteq \rwildcard{A}}\\
|
|
\hline
|
|
\wildcardEnv \vdash C \cup \set{\rwildcard{A} \doteq \type{N}}
|
|
\end{array}$
|
|
\\\\
|
|
\rulename{Circle} & $
|
|
\begin{array}[c]{l}
|
|
\wildcardEnv \vdash C \cup \, \set{\tv{a}_1 \lessdot
|
|
\tv{a}_2, \tv{a}_2 \lessdot \tv{a}_3, \dots, \tv{a}_n \lessdot \tv{a}_1}\\
|
|
\hline
|
|
\wildcardEnv \vdash C \cup \, \set{\tv{a}_1 \doteq \tv{a}_2, \tv{a}_2 \doteq \tv{a}_3, \dots , \tv{a}_n \doteq \tv{a}_1}
|
|
\end{array} \quad n>0
|
|
$
|
|
\end{tabular}}
|
|
\end{center}
|
|
\caption{Constraint normalize rules}\label{fig:normalizing-rules}
|
|
\end{figure}
|
|
|
|
The \rulename{match} rule generates fresh wildcards $\overline{\wildcard{A}{\tv{u}}{\tv{l}}}$.
|
|
Their upper and lower bounds are fresh type variables.
|
|
|
|
%Unify only renames the wildcards in the reduce rule
|
|
% It's the only place where wildcards are coming into play (theres always a reduce step before a wildcard substitution is possible)
|
|
|
|
|
|
% die wildcard variablen sollten erst am Ende ausgetauscht werden gegen normale variablen
|
|
% das funktioniert, da die im Reduce step erstellten direkt substituiert werden
|
|
% die anderen erlauben Capture Conversion aber nur wenn der Methodentyp und Parametertyp schon feststeht! (gleich Mächtig wie TI in Java)
|
|
% a? <. T ->
|
|
% T <. a? ->
|
|
% a? =. T -> substitute!
|
|
% bei normalen Typvariablen werden keine Wildcards substituiert
|
|
|
|
% \begin{tcolorbox}
|
|
% $
|
|
% \wctype{\rwildcard{X}}{Box}{\rwildcard{X}} \lessdot \exptype{Box}{\tv{a}_?}, \\
|
|
% \exptype{Box}{\tv{a}_?} \lessdot \wctype{\rwildcard{X}}{Box}{\rwildcard{X}}
|
|
% $
|
|
% \end{tcolorbox}
|
|
|
|
\begin{figure}
|
|
\begin{center}
|
|
\leavevmode
|
|
\fbox{
|
|
\begin{tabular}[t]{l@{~}l}
|
|
\rulename{Match}
|
|
& $
|
|
\begin{array}[c]{@{}ll}
|
|
\begin{array}[c]{l}
|
|
\wildcardEnv \vdash C \cup \, \set{
|
|
\tv{a} \lessdot \wctype{\Delta}{D}{\ol{T}}, \tv{a} \lessdot \wctype{\Delta'}{D'}{\ol{T'}} }\\
|
|
\hline
|
|
\vspace*{-0.4cm}\\
|
|
\wildcardEnv \vdash C \cup \, \left\{ \begin{array}[c]{l}
|
|
\tv{a} \lessdot \wctype{\overline{\wildcard{A}{\tv{u}}{\tv{l}}}}{C}{\overline{\rwildcard{A}}},
|
|
\ol{\tv{l}} \lessdot \ol{\tv{u}}, \\
|
|
\wctype{\overline{\wildcard{A}{\tv{u}}{\tv{l}}}}{C}{\overline{\rwildcard{A}}}
|
|
\lessdot \wctype{\Delta}{D}{\ol{T}}, \\
|
|
\wctype{\overline{\wildcard{A}{\tv{u}}{\tv{l}}}}{C}{\overline{\rwildcard{A}}}
|
|
\lessdot \wctype{\Delta'}{D'}{\ol{T'}}
|
|
\end{array}
|
|
\right\}
|
|
\end{array}
|
|
&\begin{array}[c]{l}
|
|
\text{fresh}\ \overline{\wildcard{A}{\tv{u}}{\tv{l}}} \\
|
|
\type{C} \ll \type{D}\\
|
|
\type{C} \ll \type{D'} % TODO: THe match rule has to pick the most general type for C
|
|
\end{array}
|
|
\end{array}
|
|
$
|
|
\\\\
|
|
\ruleReduceWC{}
|
|
&
|
|
$
|
|
\begin{array}[c]{@{}ll}
|
|
\begin{array}[c]{l}
|
|
\wildcardEnv \vdash
|
|
C \cup \, \set{ \exptype{C}{\ol{S}} \lessdot
|
|
\wctype{\overline{\wildcard{A}{\type{U}}{\type{L}}}}{C}{\ol{T}} } \\
|
|
\hline
|
|
\vspace*{-0.4cm}\\
|
|
\wildcardEnv
|
|
\vdash C \cup \, \set{
|
|
\ol{\type{S}} \doteq [\ol{\wtv{a}}/\overline{\rwildcard{A}}]\ol{\type{T}},
|
|
\ol{\wtv{a}} \lessdot [\ol{\wtv{a}}/\overline{\rwildcard{A}}]\ol{U}, [\ol{\wtv{a}}/\overline{\rwildcard{A}}]\ol{L} \lessdot \ol{\wtv{a}} }
|
|
\end{array}
|
|
%\quad \ol{Y} = \textit{fresh}(\ol{X})
|
|
\quad \begin{array}[c]{l}
|
|
\ol{\wtv{a}} \ \text{fresh}\\
|
|
%\text{fv}(\exptype{C}{\ol{S}}) \subseteq \text{dom}(\overline{\wildcard{B}{\type{U'}}{\type{L'}}})
|
|
%\text{dom}(\overline{\wildcard{A}{\type{U}}{\type{L}}}) \subseteq \text{fv}(\exptype{C}{\ol{T}}) \\
|
|
%\text{fv}(\wctype{\overline{\wildcard{A}{\type{U}}{\type{L}}}}{C}{\ol{T}}) = \emptyset
|
|
\end{array}
|
|
\end{array}
|
|
$
|
|
\\\\
|
|
\rulename{Capture}
|
|
&
|
|
$
|
|
\begin{array}[c]{@{}ll}
|
|
\begin{array}[c]{l}
|
|
\wildcardEnv \vdash
|
|
C \cup \, \set{ \wctype{\overline{\wildcard{B}{\type{U}}{\type{L}}}}{C}{\ol{S}} \lessdotCC \wctype{\Delta}{C}{\ol{T}} } \\
|
|
\hline
|
|
\vspace*{-0.4cm}\\
|
|
\wildcardEnv \cup \overline{\wildcard{C}{\type{U}}{\type{L}}}
|
|
\vdash C \cup \, \set{
|
|
[\ol{\rwildcard{C}}/\ol{\rwildcard{B}}] \exptype{C}{\ol{S}} \lessdot \wctype{\Delta}{C}{\ol{T}} }
|
|
\end{array}
|
|
%\quad \ol{Y} = \textit{fresh}(\ol{X})
|
|
\quad \begin{array}[c]{l}
|
|
\ol{\rwildcard{C}} \ \text{fresh}\\
|
|
%\text{fv}(\type{T}) \neq \emptyset
|
|
\end{array}
|
|
\end{array}
|
|
$
|
|
\\\\
|
|
\rulename{Prepare}
|
|
&
|
|
$
|
|
\begin{array}[c]{@{}ll}
|
|
\begin{array}[c]{l}
|
|
\wildcardEnv \vdash
|
|
C \cup \, \set{ \wctype{\Delta}{C}{\ol{S}} \lessdot \wctype{\Delta'}{C}{\ol{T}} } \\
|
|
\hline
|
|
\vspace*{-0.4cm}\\
|
|
\wildcardEnv \vdash
|
|
C \cup \, \set{ \wctype{\Delta}{C}{\ol{S}} \lessdotCC \wctype{\Delta'}{C}{\ol{T}} } \\
|
|
\end{array}
|
|
%\quad \ol{Y} = \textit{fresh}(\ol{X})
|
|
\quad \begin{array}[c]{l}
|
|
\text{fv}(\wctype{\Delta}{C}{\ol{S}}, \wctype{\Delta'}{C}{\ol{T}}) = \emptyset
|
|
\end{array}
|
|
\end{array}
|
|
$
|
|
\\\\
|
|
\rulename{Adopt}
|
|
& $
|
|
\begin{array}[c]{@{}ll}
|
|
\begin{array}[c]{l}
|
|
\wildcardEnv \vdash C \cup \, \set{
|
|
\tv{b} \lessdot \tv{a},
|
|
\tv{a} \lessdot \type{N}, \tv{b} \lessdot \type{N'}} \\
|
|
\hline
|
|
\vspace*{-0.4cm}\\
|
|
\wildcardEnv \vdash C \cup \, \set{
|
|
\tv{b} \lessdot \type{N},
|
|
\tv{b} \lessdot \tv{a},
|
|
\tv{a} \lessdot \type{N} , \tv{b} \lessdot \type{N'}
|
|
}
|
|
\end{array}
|
|
\end{array}
|
|
$
|
|
\\\\
|
|
\rulename{Adapt}
|
|
&
|
|
$
|
|
\begin{array}[c]{@{}ll}
|
|
\begin{array}[c]{l}
|
|
\wildcardEnv \vdash C \cup \, \set{ \wctype{\Delta}{C}{\ol{T}} \lessdot
|
|
\wctype{\Delta'}{D'}{\ol{T'}} } \\
|
|
\hline
|
|
\vspace*{-0.4cm}\\
|
|
\wildcardEnv \vdash C \cup \, \set{ \wctype{\Delta}{D}{[\ol{\type{T}}/\ol{X}]\ol{S}} \lessdot \wctype{\Delta'}{D'}{\ol{T'}} }
|
|
|
|
\end{array}
|
|
& \begin{array}[c]{l}
|
|
\type{C} \ll \type{D'} \\
|
|
\texttt{class} \ \exptype{C}{\ol{X} \triangleleft \ol{N}} \triangleleft \exptype{D}{\ol{S}}
|
|
\end{array}
|
|
\end{array}
|
|
$
|
|
\end{tabular}}
|
|
\end{center}
|
|
\caption{Constraint reduce rules}\label{fig:reduce-rules}
|
|
\end{figure}
|
|
|
|
The new constraint generated by the adopt rule may be eliminated by the match rule.
|
|
The adopt rule still needs to be applied only once per constraint.
|
|
|
|
Wildcards consist out of three parts.
|
|
A name, a scope and a upper and lower bound.
|
|
|
|
% The \unify{} algorithm from \cite{plue09_1} substitutes type variables with wildcards.
|
|
% A constraint $\wctype{\wildcard{X}{\type{Object}}{\bot}}{C}{\rwildcard{X}} \lessdot \exptype{C}{\tv{a}}$
|
|
% has no solution.
|
|
% Replacing the type variable $\tv{a}$ with the wildcard $\rwildcard{X}$ is not correct!
|
|
% The wildcard $\rwildcard{X}$ cannot leave its scope and the type $\exptype{C}{\rwildcard{X}}$
|
|
% is considered invalid.
|
|
|
|
Wildcards are not reflexive. A box of type $\wctype{\rwildcard{X}}{Box}{\rwildcard{X}}$
|
|
is able to hold a value of any type. It could be a $\exptype{Box}{String}$ or a $\exptype{Box}{Integer}$ etc.
|
|
Also two of those boxes do not necessarily contain the same type.
|
|
But there are situations where it is possible to assume that.
|
|
For example the type $\wctype{\rwildcard{X}}{Pair}{\exptype{Box}{\rwildcard{X}}, \exptype{Box}{\rwildcard{X}}}$
|
|
is a pair of two boxes, which always contain the same type.
|
|
Inside the scope of the \texttt{Pair} type, the wildcard $\rwildcard{X}$ stays the same.
|
|
|
|
The algorithm starts with an empty wildcard environment $\wildcardEnv{}$.
|
|
Only the reduce rule adds wildcards to that environment.
|
|
And every added wildcard gets a fresh unique name.
|
|
This ensures the wildcard environment $\wildcardEnv{}$ never
|
|
gets the same wildcard twice.
|
|
|
|
When a new type is generated by the \unify{} algorithm it always has the form
|
|
$\wctype{\ol{\rwildcard{A}}}{C}{\ol{\rwildcard{A}}}$.
|
|
|
|
\textbf{Step 1:}
|
|
Apply the rules depicted in the figures \ref{fig:normalizing-rules}, \ref{fig:reduce-rules} and \ref{fig:wildcard-rules} exhaustively.
|
|
Starting with the \rulename{circle} rule. Afterwards the other rules in figure \ref{fig:normalizing-rules}.
|
|
|
|
If we find an illicit constraint assigning a type containing free variables to a type placeholder not flagged as a wildcard placeholder the algorithm fails.
|
|
|
|
$\set{\tv{a} \doteq \type{N}} \in C$ with $\text{fv}(\type{N}) \neq \emptyset$ $\implies$ fail!
|
|
|
|
The first step of the algorithm is able to remove wildcards.
|
|
Removing a wildcard works by setting its lower and upper bound to be equal.
|
|
(Def: $\type{Object} = \wildcard{A}{Object}{Object}$).
|
|
The \rulename{Equals} rule is responsible for this.
|
|
|
|
\textbf{Example:}
|
|
\begin{displaymath}
|
|
\begin{array}[c]{@{}ll}
|
|
\begin{array}[c]{l}
|
|
\wildcardEnv \cup \set{ \wildcard{X}{\tv{u}}{\tv{l}} } \vdash
|
|
C \cup \, \set{ \type{Object} \doteq \type{X}, \tv{l} \lessdot \tv{u} } \\
|
|
\hline
|
|
\vspace*{-0.4cm}\\
|
|
\wildcardEnv \cup \set{ \wildcard{X}{\tv{u}}{\tv{l}} } \vdash C \cup \,
|
|
\set{\type{Object} \lessdot \type{X}, \type{X} \lessdot \type{Object}, \tv{l} \lessdot \tv{u}
|
|
}\\
|
|
\hline
|
|
\vspace*{-0.4cm}\\
|
|
\wildcardEnv \cup \set{ \wildcard{X}{\tv{u}}{\tv{l}} } \vdash C \cup \,
|
|
\set{\type{Object} \lessdot \tv{l}, \tv{u} \lessdot \type{Object}, \tv{l} \lessdot \tv{u}
|
|
}\\
|
|
\hline
|
|
\vspace*{-0.4cm}\\
|
|
\ldots\\
|
|
\hline
|
|
\vspace*{-0.4cm}\\
|
|
\wildcardEnv \cup \set{ \wildcard{X}{\type{Object}}{\type{Object}} } \vdash C \\
|
|
\end{array}
|
|
\end{array}
|
|
\end{displaymath}
|
|
|
|
\textbf{Helper functions:}
|
|
\begin{description}
|
|
\item[$\tph{}$] returns all type placeholders inside a given type.
|
|
|
|
\textit{Example:} $\tph(\wctype{\wildcard{X}{\tv{a}}{\bot}}{Pair}{\wtv{b},\rwildcard{X}}) = \set{\tv{a}, \wtv{b}}$
|
|
\item [$\ll$ relation:]
|
|
The $\ll$ relation is the reflexive and transitive closure of the \texttt{extends} relations:
|
|
\begin{displaymath}
|
|
\begin{array}[c]{c}
|
|
\exptype{C}{\ol{X} \triangleleft \ol{N}} \triangleleft \exptype{D}{\ol{N}} \\
|
|
\hline
|
|
\vspace*{-0.4cm}\\
|
|
\texttt{C} \ll \texttt{D}
|
|
\end{array}
|
|
\quad
|
|
\begin{array}[c]{l}
|
|
\\
|
|
\hline
|
|
\vspace*{-0.4cm}\\
|
|
\texttt{C} \ll \texttt{C}
|
|
\end{array}
|
|
\quad
|
|
\begin{array}[c]{l}
|
|
\texttt{C} \ll \texttt{D}, \texttt{D} \ll \texttt{E} \\
|
|
\hline
|
|
\vspace*{-0.4cm}\\
|
|
\texttt{C} \ll \texttt{E}
|
|
\end{array}
|
|
\end{displaymath}
|
|
The algorithm uses it to determine if two types are possible subtypes of one another.
|
|
This is needed in the \rulename{adapt} and \rulename{match} rules.
|
|
|
|
%\textbf{Wildcard renaming}\\
|
|
\item[Wildcard renaming:]
|
|
The \rulename{reduce} rule separates wildcards from their environment.
|
|
At this point each wildcard gets a new and unique name.
|
|
To only rename the respective wildcards the reduce rule renames wildcards up to alpha conversion:
|
|
($[\ol{C}/\ol{B}]$ in the \rulename{reduce} rule)
|
|
\begin{align*}
|
|
[\type{A}/\type{B}]\type{B} &= \type{A} \\
|
|
[\type{A}/\type{B}]\type{C} &= \type{C} & \text{if}\ \type{B} \neq \type{C}\\
|
|
[\type{A}/\type{B}]\wcNtype{\Delta}{N} &= \wcNtype{\Delta}{[\type{A}/\type{B}]N} & \text{if}\ \type{B} \notin \Delta \\
|
|
[\type{A}/\type{B}]\wcNtype{\Delta}{N} &= \wcNtype{\Delta}{N} & \text{if}\ \type{B} \in \Delta \\
|
|
\end{align*}
|
|
|
|
\item[Free Variables:]
|
|
The $\text{fv}$ function assumes every wildcard type variable to be a free variable aswell.
|
|
|
|
%\textbf{Fresh Wildcards}\\
|
|
\item[Fresh Wildcards:]
|
|
$\text{fresh}\ \overline{\wildcard{A}{\tv{u}}{\tv{l}}}$ generates fresh wildcards.
|
|
The new names $\ol{A}$ are fresh, aswell as the type variables $\ol{\tv{u}}$ and $\ol{\tv{l}}$,
|
|
which are used for the upper and lower bounds.
|
|
\end{description}
|
|
% \noindent
|
|
% \textbf{Example: (reduce-rule)}
|
|
% %The \ruleReduceWC{} resembles the \texttt{S-Exists} subtyping rule.
|
|
% %It converts wildcard types to fresh type variables.
|
|
% %For example take the input constraint $\exptype{Pair}{\ntype{Object},\tv{b}} \lessdot \wctype{\wildcard{A}{\tv{c}}{\tv{d}}}{Pair}{\wildcard{A}{\tv{c}}{\tv{d}},\wildcard{A}{\tv{c}}{\tv{d}}}$.
|
|
% %First we apply the \ruleReduceWC{} rule, which replaces $\wildcard{A}{\tv{c}}{\tv{d}}$ with a fresh type variable $\tv{a}$:
|
|
% We assume the input constraints $C = \exptype{Pair}{\ntype{Object},\tv{b}} \lessdot \wctype{\wildcard{A}{\tv{c}}{\tv{d}}}{Pair}{\wildcard{A}{\tv{c}}{\tv{d}},\wildcard{A}{\tv{c}}{\tv{d}}}$.
|
|
% The type on the right side $\wctype{\wildcard{A}{\tv{c}}{\tv{d}}}{Pair}{\wildcard{A}{\tv{c}}{\tv{d}},\wildcard{A}{\tv{c}}{\tv{d}}}$
|
|
% \begin{align*}
|
|
% \ddfrac{
|
|
% \exptype{Pair}{\ntype{Object},\tv{b}} \lessdot \wctype{\wildcard{A}{\tv{c}}{\tv{d}}}{Pair}{\wildcard{A}{\tv{c}}{\tv{d}},\wildcard{A}{\tv{c}}{\tv{d}}}
|
|
% }{
|
|
% \ntype{Object} \doteq \tv{a}, \tv{b} \doteq \tv{a}, \tv{a} \lessdot \tv{c}, \tv{d} \lessdot \tv{a}
|
|
% } \ruleReduceWC{}
|
|
% \end{align*}
|
|
|
|
% By substition we get the result: % $\tv{a} \doteq \type{Object}$, $\tv{a} \doteq \type{Object}$, $\ldots$.
|
|
|
|
% \begin{align*}
|
|
% \ddfrac{
|
|
% \ntype{Object} \doteq \tv{a}, \tv{b} \doteq \tv{a}, \tv{a} \lessdot \tv{c}, \tv{d} \lessdot \tv{a}
|
|
% }{
|
|
% \tv{a} \doteq \ntype{Object} , \tv{b} \doteq \ntype{Object}, \ntype{Object} \lessdot \tv{c}, \tv{d} \lessdot \ntype{Object}
|
|
% } \rulename{Subst}
|
|
% \end{align*}
|
|
% \\[1em]
|
|
|
|
\noindent
|
|
\textbf{Step 2:}
|
|
%If there are no $(\type{T} \lessdot \tv{a})$ constraints remaining in the constraint set $C$
|
|
%resume with step 4.
|
|
|
|
The rules in figure \ref{fig:step2-rules} offer multiple possibilities to deal with constraints of the form $\type{N} \lessdot \tv{a}$.
|
|
This builds a search tree over multiple possible solutions.
|
|
\unify{} has to try each branch and accumulate the resulting solutions into a solution set.
|
|
|
|
\begin{figure}
|
|
\begin{center}
|
|
\fbox{
|
|
\begin{tabular}[t]{l@{~}l}
|
|
\rulename{\generalizeRule}
|
|
& $
|
|
\begin{array}[c]{l}
|
|
\wildcardEnv \vdash C \cup \wctype{\Delta}{C}{\ol{T}} \lessdot \tv{a}\\
|
|
\hline
|
|
\wildcardEnv \vdash C \cup \set{\wctype{\Delta}{C}{\ol{T}} \lessdot \tv{a},
|
|
\tv{a} \doteq \wctype{\overline{\wildcard{X}{\tv{u}}{\tv{l}}}}{C}{\overline{\rwildcard{X}}},
|
|
%\overline{\tv{l} \lessdot \tv{u}}, % not needed, due to subst and reduce rule which are used afterwards
|
|
\overline{\tv{u} \lessdot \type{S}}
|
|
}
|
|
\end{array} \quad \begin{array}[c]{l}
|
|
\texttt{class} \ \exptype{C}{\ol{X \triangleleft \type{S}}} \triangleleft \exptype{D}{\ol{N}} \\
|
|
\text{fresh}\ \overline{\wildcard{X}{\tv{u}}{\tv{l}}}
|
|
\end{array}
|
|
$
|
|
\\\\
|
|
\rulename{Super}
|
|
& $
|
|
\begin{array}[c]{l}
|
|
\wildcardEnv \vdash C \cup \wctype{\Delta}{C}{\ol{T}} \lessdot \tv{a}\\
|
|
\hline
|
|
\wildcardEnv \vdash C \cup \set{ \wctype{\Delta}{D}{[\ol{T}/\ol{X}]\ol{N}} \lessdot \tv{a} }
|
|
%\set{\wctype{\ol{\wtype{W}}}{D}{[\ol{X}/\ol{Y}]\ol{Z}} \lessdot \tv{a}}
|
|
\end{array} \quad
|
|
\begin{array}{l}
|
|
\texttt{class} \ \exptype{C}{\ol{X}} \triangleleft \exptype{D}{\ol{N}} \\
|
|
\ol{X} \notin \wildcardEnv \cup \Delta
|
|
\end{array}
|
|
$
|
|
\\\\
|
|
\rulename{Settle}
|
|
& $
|
|
\begin{array}[c]{l}
|
|
\wildcardEnv \vdash C \cup \set{ \tv{a} \lessdot \type{N},
|
|
\tv{a} \lessdot^* \tv{b}}
|
|
\\
|
|
\hline
|
|
\wildcardEnv \vdash C \cup \set{ \tv{a} \lessdot^* \tv{b}, \tv{b} \lessdot \type{N} }
|
|
\end{array}
|
|
$
|
|
\\\\
|
|
\rulename{Raise}
|
|
& $
|
|
\begin{array}[c]{l}
|
|
\wildcardEnv \vdash C \cup \set{ \tv{a} \lessdot \type{N},
|
|
\tv{a} \lessdot \tv{b}}
|
|
\\
|
|
\hline
|
|
\wildcardEnv \vdash C \cup \set{\tv{a} \lessdot \type{N}, \type{N} \lessdot \tv{b} }
|
|
\end{array}
|
|
$
|
|
\\\\
|
|
\end{tabular}}
|
|
\end{center}
|
|
\caption{Step 2 branching: Multiple rules can be applied to the same constraint}
|
|
\label{fig:step2-rules}
|
|
\end{figure}
|
|
|
|
|
|
%For every $\type{T} \lessdot \tv{a}$ constraint, the unify algorithm has to consider every possible supertype of $\type{T}$.
|
|
%For every $\type{N}$ with $\type{T} \leq \type{N}$: ($\texttt{class} \ \exptype{T}{\ol{Y} \triangleleft \ol{N}} \triangleleft \type{N}$)
|
|
%There are two different ways of handling a $\type{T} \lessdot \tv{a}$ constraint:
|
|
%TODO: why the \generalizeRule is basically the Same rule for regular type placeholders
|
|
|
|
%where is the mistake in the old unify algorithm?
|
|
%when working with equality the problems arise! Free variables should not escape their scope
|
|
% Replacing regular type placeholders causes problems related to method calls and capture conversion.
|
|
|
|
% <X> List<X> same(List<X> a, List<X> b){}
|
|
|
|
% This program has no correct type. the same method requires
|
|
% \begin{lstlisting}
|
|
% List<?> f;
|
|
% List<?> problem(){
|
|
% return same(problem(), problem()) ?: f;
|
|
% }
|
|
% \end{lstlisting}
|
|
% \begin{constraints}
|
|
% r <. List<x?>
|
|
% r <. List<x?>
|
|
% X.List<X> <. r
|
|
% \end{constraints}
|
|
% %TODO
|
|
|
|
\unify{} generates wildcard types for constraints of the form $\type{N} \lessdot \tv{a}$ with the \rulename{\generalizeRule} rule.
|
|
Otherwise only the wildcards already defined in the input constraints will be included in the result.
|
|
\rulename{\generalizeRule} attempts to give $\tv{a}$ a more general type by replacing only the type parameters with fresh wildcards.
|
|
The second variation sets $\tv{a}$ to the direct supertype of type \texttt{C}.
|
|
For the constraint $\texttt{Object} \lessdot \tv{a}$ the algorithm can only apply $\tv{a} \doteq \texttt{Object}$,
|
|
because \texttt{Object} has no other supertype than itself.
|
|
|
|
Constraints of the form $\set{ \tv{a} \lessdot \type{N}, \tv{a} \lessdot^* \tv{b}}$
|
|
need to be handled in a similiar fashion.
|
|
The type variable $\tv{b}$ could either be a sub or a supertype of the type $\type{N}$.
|
|
We have to consider both possibilities.
|
|
\\[1em]
|
|
% The specification of the \unify{} algorithm has only two rules generating $\doteq$-Constraints
|
|
% , \rulename{Reduce} and \rulename{Ground}.
|
|
% $\doteq$-Constraints and the accompaning substitutions are dangerous respective to the soundness of the algorithm.
|
|
% For the soundness proof of the \unify{} algorithm we have to show every generation of equals constraints
|
|
% and the subsequent application of the \rulename{subst} rule is correct.
|
|
% We try to use them as sparsely as possible to simplify the soundness proof.
|
|
% You can notice this at \rulename{Equals} or \rulename{Force}:
|
|
% Instead of setting $\type{U} \doteq \type{L}$, we say
|
|
% $\type{U} \lessdot \type{L}, \type{L} \lessdot \type{U}$.
|
|
|
|
\noindent
|
|
\textbf{Step 3}
|
|
\textbf{(Eliminate Wildcard Variables):}
|
|
If no more rules in step 2 are applicable \unify{} has to eliminate all wildcard variables by applying the \rulename{Remove} rule
|
|
and start over at step 1.
|
|
If $C$ does not contain any wildcard variables the algorithm proceeds with step 4.
|
|
\begin{center}
|
|
\fbox{
|
|
\begin{tabular}[t]{l@{~}l}
|
|
\rulename{Remove}
|
|
& $
|
|
\begin{array}[c]{@{}ll}
|
|
\begin{array}[c]{l}
|
|
\wildcardEnv \vdash C \\
|
|
% \cup \, \set{ \wtv{a} \lessdot \type{T} }\\
|
|
\hline
|
|
\vspace*{-0.4cm}\\
|
|
\subst{\tv{a}}{\wtv{a}}\wildcardEnv \vdash [\tv{a}/\wtv{a}]C
|
|
\end{array}
|
|
&\begin{array}[c]{l}
|
|
\wtv{a} \in C \\
|
|
\tv{a} \ \text{fresh}
|
|
\end{array}
|
|
\end{array}
|
|
$
|
|
\end{tabular}}
|
|
\end{center}
|
|
|
|
% \begin{figure}
|
|
% \begin{center}
|
|
% \fbox{
|
|
% \begin{tabular}[t]{l@{~}l}
|
|
% \rulename{Remove}
|
|
% & $
|
|
% \begin{array}[c]{@{}ll}
|
|
% \begin{array}[c]{l}
|
|
% \wildcardEnv \vdash C \\
|
|
% % \cup \, \set{ \wtv{a} \lessdot \type{T} }\\
|
|
% \hline
|
|
% \vspace*{-0.4cm}\\
|
|
% \wildcardEnv \vdash [\tv{a}/\wtv{a}]C
|
|
% \end{array}
|
|
% &\begin{array}[c]{l}
|
|
% \wtv{a} \in C \\
|
|
% \tv{a} \ \text{fresh}
|
|
% \end{array}
|
|
% \end{array}
|
|
% $
|
|
% \\\\
|
|
% % \rulename{Trim}
|
|
% % & $
|
|
% % \begin{array}[c]{@{}ll}
|
|
% % \begin{array}[c]{l}
|
|
% % \wildcardEnv \vdash C
|
|
% % \cup \, \set{ \wcNtype{\Delta}{N} \lessdot \wctype{\Delta', \wildcard{B}{\type{U}}{\type{L}}}{C}{\ol{S}} }\\
|
|
% % \hline
|
|
% % \vspace*{-0.4cm}\\
|
|
% % C \cup \, \set{ \wcNtype{\Delta}{N} \lessdot \wctype{\Delta'}{C}{\ol{S}} }
|
|
% % \end{array}
|
|
% % &\begin{array}[c]{l}
|
|
% % \rwildcard{B} \notin \ol{S}
|
|
% % \end{array}
|
|
% % \end{array}
|
|
% % $
|
|
% % \\\\
|
|
% \end{tabular}}
|
|
% \end{center}
|
|
% \caption{Wildcard variable substitution rules}\label{fig:wtv-rules}
|
|
% \end{figure}
|
|
|
|
|
|
% We apply the \rulename{Clean} rule exhaustively to $C''$:
|
|
% \begin{gather*}
|
|
% \begin{array}[c]{lll}
|
|
% \rulename{Clean} &
|
|
% \begin{array}[c]{l}
|
|
% \wildcardEnv \vdash C\\
|
|
% \hline
|
|
% [\tv{a}/\wtv{a}]\wildcardEnv, [\tv{a}/\wtv{a}]\sigma \vdash [\tv{a}/\wtv{a}]C %\cup \set{\tv{b} \doteq \tv{a}}
|
|
% \end{array}
|
|
% \quad \wtv{a} \in C
|
|
% \end{array}
|
|
% \end{gather*}
|
|
|
|
% \begin{gather*}
|
|
% \begin{array}[c]{lll}
|
|
% \rulename{Subst} &
|
|
% \begin{array}[c]{l}
|
|
% \wildcardEnv \vdash C \cup \set{\tv{a} \doteq \wctype{\triangle}{C}{\ol{T}}}\\
|
|
% \hline
|
|
% [\wctype{\triangle}{C}{\ol{T}}/\tv{a}]\wildcardEnv \vdash [\wctype{\triangle}{C}{\ol{T}}/\tv{a}]
|
|
% C \cup \set{\tv{a} \doteq \wctype{\triangle}{C}{\ol{T}}}
|
|
% \end{array}
|
|
% & \tv{a} \notin \ol{T} \\
|
|
% & \\
|
|
% \rulename{Subst-wc} &
|
|
% \begin{array}[c]{l}
|
|
% \wildcardEnv \vdash C \cup \set{\tv{a} \doteq \rwildcard{A}}\\
|
|
% \hline
|
|
% [\rwildcard{A}/\tv{a}]\wildcardEnv \vdash [\rwildcard{A}/\tv{a}] C \cup \set{\tv{a} \doteq \rwildcard{A}}
|
|
% \end{array}
|
|
% \end{array}
|
|
% \end{gather*}
|
|
|
|
%or $\type{T}$ is not of the form $\wctype{\triangle}{C}{\ol{G}}$ with $\text{fv}(\ol{G}) = \emptyset$.
|
|
%Here the $\text{fv}(\ol{G})$ also applies to type variables.
|
|
%$\tv{x} \doteq \exptype{C}{\tv{a}}$ is invalid, because $\tv{a}$ could become a free wildcard in that context.
|
|
|
|
\noindent
|
|
\textbf{Step 4:}
|
|
We apply the rules in figure \ref{fig:cleanup-rules} exhaustively and proceed with step 5.
|
|
%and start over at step 1.
|
|
%If the constraint set is in solved form afterwards the algorithm proceeds with step 5.
|
|
|
|
\begin{figure}
|
|
\begin{center}
|
|
\leavevmode
|
|
\fbox{
|
|
\begin{tabular}[t]{l@{~}l}
|
|
\rulename{SubElim}
|
|
& $\begin{array}[c]{l}
|
|
\wildcardEnv \vdash C \cup \set{\tv{a} \lessdot \tv{b}}\\
|
|
\hline
|
|
[\tv{a}/\tv{b}]\wildcardEnv \vdash [\tv{a}/\tv{b}]C \cup \set{ \tv{b} \doteq \tv{a} }
|
|
\end{array}
|
|
$
|
|
\\\\
|
|
\rulename{Ground}
|
|
& $\begin{array}[c]{@{}ll}
|
|
\begin{array}[c]{l}
|
|
\wildcardEnv \cup \overline{\set{\wildcard{X}{\type{U}}{\tv{a}}}} \vdash C \cup \, \set{
|
|
\overline{\tv{a} \lessdot \type{T}} } \\
|
|
\hline
|
|
\vspace*{-0.4cm}\\
|
|
\wildcardEnv \cup \overline{\set{\wildcard{X}{\type{U}}{\bot}}} \vdash
|
|
C \cup \set{ \tv{a} \doteq \bot }
|
|
\end{array}
|
|
&\begin{array}[c]{l}
|
|
%\forall \wctype{\Delta}{C}{\ol{T}} \in C: \tv{a} \notin \ol{T} \\
|
|
\tv{a} \notin C, \, \rwildcard{X} \notin C, \, \tv{a} \notin \overline{T} %\\
|
|
%\text{length}( \overline{\tv{a} \lessdot \type{T}} ) > 1
|
|
\end{array}
|
|
\end{array}$
|
|
\\\\
|
|
\rulename{Crunch}
|
|
& $\begin{array}[c]{@{}ll}
|
|
\begin{array}[c]{l}
|
|
\wildcardEnv \vdash C \cup \, \set{ \tv{a} \doteq \wctype{\Delta', \set{\overline{\wildcard{X}{\type{U}}{\type{L}}}}}{C}{\ol{S}} } \\
|
|
\hline
|
|
\vspace*{-0.4cm}\\
|
|
\wildcardEnv \vdash
|
|
C \cup \set{ \tv{a} \doteq \wctype{\Delta'}{C}{[\ol{U}/\ol{X}]\ol{S}}}
|
|
\end{array}
|
|
&\begin{array}[c]{l}
|
|
\ol{U} = \ol{L}
|
|
\end{array}
|
|
\end{array}$
|
|
\\\\
|
|
\rulename{Crunch}
|
|
& $\begin{array}[c]{@{}ll}
|
|
\begin{array}[c]{l}
|
|
\wildcardEnv \vdash C \cup \, \set{ \tv{a} \lessdot \wctype{\Delta', \set{\overline{\wildcard{X}{\type{U}}{\type{L}}}}}{C}{\ol{S}} } \\
|
|
\hline
|
|
\vspace*{-0.4cm}\\
|
|
\wildcardEnv \vdash
|
|
C \cup \set{ \tv{a} \lessdot \wctype{\Delta'}{C}{[\ol{U}/\ol{X}]\ol{S}}}
|
|
\end{array}
|
|
&\begin{array}[c]{l}
|
|
\ol{U} = \ol{L}
|
|
\end{array}
|
|
\end{array}$
|
|
% \\\\ % The force rule is unnecessary because every type placeholder has an upper bound Object (a <. Object) The match rule eliminates those wildcards
|
|
% \rulename{Force} &$
|
|
% \begin{array}[c]{@{}ll}
|
|
% \begin{array}[c]{l}
|
|
% \wildcardEnv \cup \set{\wildcard{X}{\type{U}}{\type{L}}}
|
|
% \vdash C \cup \, \set{
|
|
% \tv{a} \lessdot \type{N} } \\
|
|
% \hline
|
|
% \vspace*{-0.4cm}\\
|
|
% \wildcardEnv
|
|
% \vdash
|
|
% C \cup \, \set{ \tv{a} \lessdot [\type{U}/\rwildcard{X}]\type{N},
|
|
% \type{U} \doteq \type{L} }
|
|
% \end{array}
|
|
% &\begin{array}[c]{l}
|
|
% \type{X} \in \text{fv}(\type{N}) \\
|
|
% %\Delta' = \Delta \cup \set{\wildcard{X}{\type{U}}{\type{L}}}
|
|
% \end{array}
|
|
% \end{array}$
|
|
% \\\\
|
|
% \rulename{FlatOut} &$
|
|
% \begin{array}[c]{@{}ll}
|
|
% \begin{array}[c]{l}
|
|
% \wildcardEnv \cup \set{\wildcard{X}{\type{U}}{\type{L}}}
|
|
% \vdash C \cup \, \set{
|
|
% \tv{a} \lessdot \wcNtype{\Delta}{N} } \\
|
|
% \hline
|
|
% \vspace*{-0.4cm}\\
|
|
% \wildcardEnv \cup \set{\wildcard{X}{\type{U}}{\type{L}}}
|
|
% \vdash
|
|
% C
|
|
% \end{array}
|
|
% &\begin{array}[c]{l}
|
|
% \type{X} \in \text{fv}(\wcNtype{\Delta}{N}) \\
|
|
% \tv{a} \notin C , \, \tv{a} \notin \wildcardEnv, \tv{a} \notin \sigma
|
|
% \end{array}
|
|
% \end{array}$
|
|
\end{tabular}}
|
|
\end{center}
|
|
\caption{Cleanup rules}\label{fig:cleanup-rules}
|
|
\end{figure}
|
|
|
|
The cleanup step prepares the constraint set for the last step by applying the following concepts:
|
|
%Two transformations are done which also help to remove unnecessary types from the solution set.
|
|
\begin{description}
|
|
\item[Bottom type]
|
|
The bottom type $\bot$ is used to generate \texttt{? extends} wildcard definitions.
|
|
This is the only possible solution when dealing with multiple upper bounds:
|
|
$\tv{a} \lessdot \type{T}, \tv{a} \lessdot \type{S}$ is usually not a correct solution (given $\type{S}$ and $\type{T}$ are no subtypes of eachother).
|
|
But if $\tv{a}$ is a lower bound of a wildcard it can be set to $\bot$.
|
|
Those constraints only stay in the constraint set after the first step if $\type{S}$ and $\type{T}$ do not have a common subtype.
|
|
The \rulename{Ground} rule uses this concept to generate \texttt{extends} Wildcards.
|
|
|
|
\item[Eliminating Wildcards]
|
|
Wildcards that have the same upper and lower bounds can be removed.
|
|
This is done by the \rulename{Crunch} rule.
|
|
|
|
\textit{Example:} The type $\wctype{\wildcard{X}{\type{String}}{\type{String}}}{List}{\rwildcard{X}}$
|
|
becomes $\exptype{List}{\type{String}}$.
|
|
|
|
|
|
%TODO: The a =. T (with T containing free variables) could be removed here.
|
|
% Not needed for the soundness of the algorithm, but handy for the implementation (check this when implementing the algorithm)
|
|
\end{description}
|
|
|
|
\noindent
|
|
\textbf{Step 5 (Generating Result):}
|
|
Apply the rules in figure \ref{fig:generation-rules} until $\wildcardEnv = \emptyset$ and $C = \emptyset$.
|
|
The resulting $\Delta, \sigma$ is a correct solution.
|
|
|
|
For this step to succeed there should only be four kinds of constraints left.
|
|
\begin{enumerate}
|
|
%\item\label{item:3} $\tv{a} \lessdot \tv{b}$ %, with $a$ and $b$ both isolated type variables
|
|
\item $\tv{a} \doteq \tv{b}$
|
|
%\item $\wtv{a} \doteq \type{G}$
|
|
\item\label{item:1} $\tv{a} \lessdot \wctype{\ol{\wtype{W}}}{C}{\ol{\type{T}}}$, with $\text{fv}(\wctype{\ol{\wtype{W}}}{C}{\ol{\type{T}}}) = \emptyset$
|
|
\item\label{item:2} $\tv{a} \doteq \wctype{\ol{\wtype{W}}}{C}{\ol{\type{T}}}$, with $\tv{a} \notin \ol{\type{T}}$ % and $\text{fv}(\wctype{\ol{\wtype{W}}}{C}{\ol{\type{T}}}) = \emptyset$
|
|
\item\label{item:3} $\tv{a} \doteq \rwildcard{X}$
|
|
\end{enumerate}
|
|
% Constraints of the form $\tv{a} \doteq \rwildcard{X}$ are also possible.
|
|
% should we add those to the \Delta environment?
|
|
% How about removing them completely from the result set? Check with soundness condition
|
|
|
|
%Each type placeholder $\tv{a}$ must solely appear on the left side of a constraint.
|
|
\unify{} fails if there is any $\tv{a} \doteq \type{T}$ such that $\tv{a}$ occurs in $\type{T}$.
|
|
For the cases \ref{item:1}, \ref{item:2}, and \ref{item:3} the placeholder $\tv{a}$
|
|
cannot appear anywhere else in the constraint set.
|
|
Otherwise the generation rules \rulename{GenSigma} and \rulename{GenDelta} will not be able to process every constraint.
|
|
|
|
% After applying the GenDelta and GenSigma rules unifiers $\sigma$ do not contain
|
|
% a unifier of the form $\tv{a} \to \tv{b}$.
|
|
% Otherwise the found solution is incorrect.
|
|
% This only happens if the input constraints contain type variables with no upper bound constraint like $\tv{a} \lessdot \type{N}$.
|
|
|
|
% \begin{displaymath}
|
|
% \deduction{
|
|
% \wildcardEnv \cup \set{\wildcard{B}{\type{G}}{\type{G'}}} \vdash C \implies \Delta, \sigma
|
|
% }{
|
|
% \wildcardEnv \vdash C \implies \Delta \cup \set{\wildcard{B}{\type{G}}{\type{G'}}}, \sigma
|
|
% }\quad \text{tph}(\type{G}) = \emptyset, \text{tph}(\type{G'}) = \emptyset,
|
|
% \rwildcard{B} \notin \text{dom}(\Delta)
|
|
% \quad \rulename{AddDelta}
|
|
% \end{displaymath}
|
|
|
|
\begin{figure}
|
|
\begin{center}
|
|
\fbox{
|
|
\begin{tabular}[t]{l@{~}l}
|
|
\rulename{GenDelta}
|
|
& $
|
|
\deduction{
|
|
\wildcardEnv \vdash C \cup \set{\tv{b} \lessdot \type{N} } \implies \Delta, \sigma
|
|
}{
|
|
\wildcardEnv \vdash [\type{B}/\tv{b}]C \implies \Delta \cup \set{\wildcard{B}{\type{N}}{\bot}}, \sigma \cup \set{\tv{b} \to \type{B}}
|
|
} \quad
|
|
\begin{array}{l}
|
|
\tph(\type{N}) = \emptyset, \text{fv}(\type{N}) \subseteq \Delta \\
|
|
\rwildcard{B} \ \text{fresh}, \tv{b} \notin \text{dom}(\sigma), \Delta \vdash \type{N} \ \ok
|
|
\end{array}
|
|
$
|
|
\\\\
|
|
%TODO: make Subst-WC to keep the wildcard flag on variables (the remove rule is not allowed to alter those constraints)
|
|
% TODO: change solved-form accordingly
|
|
% we can then proof (in soundness for TYPE), that when a constraint a <. T -> X.C<X> <. T , then only variables in X and Delta are used in T
|
|
\rulename{AddSigma} %This rule adds the substitutions for a? variables
|
|
& $
|
|
\deduction{
|
|
\wildcardEnv \vdash C \cup \set{\wtv{a} \doteq \type{T}} \implies \Delta, \sigma
|
|
}{
|
|
\wildcardEnv \vdash C \cup \set{\wtv{a} \doteq \type{T}} \implies \Delta, \sigma
|
|
\cup \set{\wtv{a} \to \rwildcard{T}}
|
|
} \quad
|
|
\begin{array}{l}
|
|
\tph(\type{T}) = \emptyset \\
|
|
\tv{a} \notin \text{dom}(\sigma)
|
|
\end{array}
|
|
$
|
|
\\\\
|
|
\rulename{GenSigma}
|
|
& $
|
|
\deduction{
|
|
\wildcardEnv \vdash C \cup
|
|
\set{\tv{a} \doteq \type{T} } \implies \Delta, \sigma
|
|
}{
|
|
\wildcardEnv \vdash C \implies \Delta, \sigma \cup
|
|
\set{\tv{a} \to \type{T} }
|
|
} \quad
|
|
\begin{array}{l}
|
|
\tph(\type{T}) = \emptyset \\ %,\, \text{fv}(\type{T}) \subseteq \Delta \\ % T ok implies that
|
|
\tv{a} \notin \text{dom}(\sigma),\, \Delta \vdash \type{T} \ \ok
|
|
\end{array}
|
|
$
|
|
\\\\
|
|
\end{tabular}}
|
|
\end{center}
|
|
\caption{Generate result}
|
|
\label{fig:generation-rules}
|
|
\end{figure}
|
|
|
|
%TODO: Solved form is obsolete due to GenSigma/GenDelta
|
|
% \begin{figure}
|
|
% \begin{description}
|
|
% \item[Solved form]
|
|
% A set $C$ of constraints is in solved form if it only contains
|
|
% constraints of the following form:
|
|
% \begin{enumerate}
|
|
% %\item\label{item:3} $\tv{a} \lessdot \tv{b}$ %, with $a$ and $b$ both isolated type variables
|
|
% \item $\tv{a} \doteq \tv{b}$
|
|
% %\item $\wtv{a} \doteq \type{G}$
|
|
% \item\label{item:1} $\tv{a} \lessdot \wctype{\ol{\wtype{W}}}{C}{\ol{\type{T}}}$, with $\text{fv}(\wctype{\ol{\wtype{W}}}{C}{\ol{\type{T}}}) = \emptyset$
|
|
% \item\label{item:2} $\tv{a} \doteq \wctype{\ol{\wtype{W}}}{C}{\ol{\type{T}}}$, with $\tv{a} \notin \ol{\type{T}}$ % and $\text{fv}(\wctype{\ol{\wtype{W}}}{C}{\ol{\type{T}}}) = \emptyset$
|
|
% \end{enumerate}
|
|
% %Each type variable $\tv{a}$ can only appear once on a left side of a constraint.
|
|
% In case~\ref{item:1} the type variable $\tv{a}$ must not appear on the left of another constraint.
|
|
% In case~\ref{item:2} the type variabel $\tv{a}$ must not appear anywhere else in the constraint set $C$.
|
|
% % of the form~\ref{item:1} or~\ref{item:2} or ~\ref{item:3} .
|
|
% \end{description}
|
|
% \caption{Solved form definition}\label{def:solved-form}
|
|
% \end{figure}
|
|
|
|
% Wildcards with the same name are interlinked.
|
|
% The \ruleReduceWC{} replaces all wildcards with the same name with type variables.
|
|
% We also use the fact that wildcards of the same name represent the same type at all times.
|
|
% So we can erase them in the \rulename{Same} rule.
|
|
|
|
% We have to ensure that every wildcard definition is unique.
|
|
% When substituting types, every time a type with wildcard definitions is added somewhere, we have to rename those wildcards.
|
|
|
|
%\subsection{Unify as Pseudocode}
|
|
% The subst rule can be applied multiple times to the same constraint, but its better to mark the a =. T constraint to do it only once
|
|
% The step 3 has to clone the constraint set and the wildcard environment and try every way
|
|
|
|
% \section{High-Level rules}
|
|
% The \unify{} specification tries to be as simple as possible
|
|
% with each rule doing only one simple transformation.
|
|
% We define additional transformation rules, which deviate directly from the given algorithm.
|
|
% They come to use in the examples section.
|
|
|
|
% \begin{figure}
|
|
% \begin{center}
|
|
% \leavevmode
|
|
% \fbox{
|
|
% \begin{tabular}[t]{l@{~}l}
|
|
% \rulename{Encase}
|
|
% & $
|
|
% \deduction{
|
|
% \wildcardEnv \vdash C \cup \set{ \exptype{C}{\type{T}} \lessdot \wctype{\wildcard{X}{\type{U}}{\type{L}}}{C}{\rwildcard{X}} }
|
|
% }{
|
|
% \wildcardEnv \vdash \subst{\type{T}}{\tv{x}}C \cup \set{ \type{T} \lessdot \type{U}, \type{L} \lessdot \type{T} }
|
|
% }
|
|
% $
|
|
% \\\\
|
|
% \rulename{Flatten}
|
|
% & $
|
|
% \deduction{
|
|
% \wildcardEnv \vdash C \cup \set{ \type{T} \lessdot \tv{a}, \tv{a} \lessdot \type{T} }
|
|
% }{
|
|
% \wildcardEnv \vdash \subst{\type{T}}{\tv{a}}C \cup \set{ \tv{a} \doteq \type{T} }
|
|
% }
|
|
% $
|
|
% \\\\
|
|
% \rulename{Assimilate}
|
|
% & $
|
|
% \deduction{
|
|
% \wildcardEnv \vdash C \cup \set{\wctype{\wildcard{X}{\tv{u}}{\tv{l}}}{C}{\rwildcard{X}} \lessdot \exptype{C}{\type{T}}, \tv{l} \lessdot \tv{u} }
|
|
% }{
|
|
% \wildcardEnv \vdash
|
|
% C \cup \set{\tv{u} \doteq \type{T}, \tv{l} \doteq \type{T}}
|
|
% }
|
|
% $
|
|
% \\\\
|
|
% \rulename{Narrow}
|
|
% &
|
|
% $\deduction{
|
|
% \wildcardEnv \vdash C \cup \set{
|
|
% \wctype{\wildcard{X}{\type{U}}{\type{L}}}{C}{\rwildcard{X}} \lessdot \wctype{\wildcard{X}{\type{U'}}{\type{L'}}}{C}{\rwildcard{X}}
|
|
% }
|
|
% }{
|
|
% \wildcardEnv \vdash C \cup \set{
|
|
% \type{L'} \lessdot \type{L}, \type{U} \lessdot \type{U'}
|
|
% }
|
|
% }$
|
|
% \\\\
|
|
% \rulename{Redeem}
|
|
% &
|
|
% $\deduction{
|
|
% \wildcardEnv \vdash C \cup \set{\wctype{\Delta}{C}{\rwildcard{X}} \lessdot \wctype{\wildcard{X}{\type{Object}}{\bot}}{C}{\rwildcard{X}}}
|
|
% }{
|
|
% \wildcardEnv \vdash C
|
|
% }$
|
|
% \\\\
|
|
% \rulename{Standoff}
|
|
% &
|
|
% $\deduction{
|
|
% \wildcardEnv \cup \set{ \wildcard{X}{\type{U}}{\type{L}}, \wildcard{Y}{\type{U'}}{\type{L'}} } \vdash \rwildcard{X} \doteq \rwildcard{Y}
|
|
% }{
|
|
% \wildcardEnv \cup \set{ \wildcard{X}{\type{U}}{\type{L}}, \wildcard{Y}{\type{U'}}{\type{L'}} } \vdash \rwildcard{U} \lessdot \type{L'}, \type{U'} \lessdot \type{L}
|
|
% }$
|
|
% \\\\
|
|
% \end{tabular}}
|
|
% \end{center}
|
|
% \caption{Common transformations}\label{fig:wildcard-rules}
|
|
% \end{figure}
|