Ecoop2024_TIforWildFJ/unify.tex

1625 lines
69 KiB
TeX
Raw Normal View History

2024-03-04 14:37:21 +00:00
% TODO: unify changes
% delete wildcard tphs a? when needed
% aswell ass free variables:
% a <. T with fv(T) not empty and not in \Delta' must be removed by U = L
% also in T <. T constraints no free variables are allowed on both sides (why? this is wrong i think)
2024-03-04 14:37:21 +00:00
% the algorithm only removes wildcards, never adds them
\section{Unify}\label{sec:unify}
Our \unify{} process uses a similar concept as the standard unification by Martelli and Montanari \cite{MM82},
consisting of terms, relations and variables.
Instead of terms we have types of the form $\exptype{C}{\ol{T}}$ and
the variables are called type placeholders.
The input consist out of subtype relations.
The goal is to find a solution (an unifier) which is a substitution for type placeholders
which satisfies all input subtype constraints.
Types are reduced until they %either reach a discrepancy like $\type{String} \doteq \type{Integer}$
reach a form like $\tv{a} \doteq \type{T}$.
Afterwards \unify{} substitutes type placeholder $\tv{a}$ with $\type{T}$.
This is done until a substitution for all type placeholders and therefore a valid solution is reached.
The reduction and substitutions are done in the first step of the algorithm.
The algorithms state consists out of a wildcard environment and a constraint set ($\wildcardEnv \vdash C$).
Initially they are set to $\Delta_{in}$ and the input constraints.
Each calculation step of the algorithm is expressed as a transformation rule consisting of three parts.
The input is shown above the line, the output below, and additional premises are displayed on the right side.
If the wildcard environment $\wildcardEnv$ and the constraint set $C$ match the pattern declared as the input
the transformation will reduce them into the specified output.
The \rulename{Subst} rule for example takes a constraint set that has atleas one constraint of the form
$\ntv{a} \doteq \type{T}$ and replaces every occurence of $\ntv{a}$ by $\type{T}$
in the wildcard environment $\wildcardEnv{}$ aswell as the remaining constraint set $C$.
The \rulename{Upper} and \rulename{Lower} conversions (figure \ref{fig:wildcard-rules}) replace wildcards with their respective bounds when appearing in a subtype constraint.
\rulename{Lower} has to check if the wildcard is part of the input wildcards $\Delta_{in}$.
If that is the case the wildcard can be part of the type solution and stays in the constraint set.
\textit{Note:} The subtype constraints in these rules are annotated with numbers $\lessdot_1$.
All rule inputs containing subtype constraints $(\lessdot)$ are always meant for both,
subtype constraints and capture constraints ($\lessdotCC$) aswell.
If multiple constraints are stated in the input format they will be annotated with numbers which map them to the constraints used in the output of the rule.
Constraints with the same number stay the same kind.
So if the input to \rulename{Upper} is $\rwildcard{A} \lessdotCC \type{G}$ the output will be something like $\type{U} \lessdotCC \type{G}$.
If the input is a normal subtype constraint the output has to be a normal subtype constraint too.
%TODO: Rephrase
%The reason being that capture constraints are treated like regular subtype constraints in these rules.
%All transformations for subtype constraints work for capture constraints aswell.
%For clarification Subtype constraints are marked with a number.
But the \rulename{Adopt} rule for example takes multiple subtype constraints and also adds a new one.
Here the numbered annotations are necessary.
\textit{Example:} Having the constraints
$\ntv{a} \lessdotCC \wtv{b}, \ntv{a} \lessdot \type{String}, \wtv{b} \lessdot \type{Object}$
would lead to
$\wtv{b} \lessdot \type{String}, \ntv{a} \lessdotCC \wtv{b}, \ntv{a} \lessdot \type{String}, \wtv{b} \lessdotCC \type{Object}$
after applying \rulename{Adopt}.
Note that the new generated constraint $\wtv{b} \lessdot \type{String}$ is a normal subtype constraint.
%The type placeholders which are annotated as wildcard placeholders also stay wildcard placeholders.
%The only rule that replaces wildcard type placeholders with regular placeholders is the \rulename{Normalize} rule.
\begin{figure}
\begin{center}
\leavevmode
\fbox{
\begin{tabular}[t]{l@{~}l}
\rulename{Upper}
& $
\begin{array}[c]{l}
\wildcardEnv \cup \set{\wildcard{A}{U}{L}} \vdash C \cup \, \set{ \type{A} \lessdot_1 \type{G} } \\
\hline
\vspace*{-0.4cm}\\
\wildcardEnv \cup \set{\wildcard{A}{U}{L}} \vdash C \cup \, \set{ \type{U} \lessdot_1 \type{G} }
\end{array}
$
\\\\
\rulename{Lower}
& $
\begin{array}[c]{l}
\wildcardEnv \cup \set{\wildcard{A}{U}{L}} \vdash C \cup \set{ \type{G} \lessdot_1 \type{A} } \\
\hline
\vspace*{-0.4cm}\\
\wildcardEnv \cup \set{\wildcard{A}{U}{L}} \vdash C \cup \set{ \type{G} \lessdot_1 \type{L} }
\end{array}
$
\\\\
\rulename{Lower}
& $
\begin{array}[c]{l}
\wildcardEnv \cup \set{\wildcard{A}{U}{L}} \vdash C \cup \set{ \ntv{a} \lessdot_1 \type{A} } \\
\hline
\vspace*{-0.4cm}\\
\wildcardEnv \cup \set{\wildcard{A}{U}{L}} \vdash C \cup \set{ \ntv{a} \lessdot_1 \type{L} }
\end{array} \quad \type{A} \notin \Delta_{in}
$
\\\\
\rulename{Bot}
& $
\begin{array}[c]{l}
\wildcardEnv \vdash C \cup \set{ \bot \lessdot \type{T} } \\
\hline
\vspace*{-0.4cm}\\
\wildcardEnv \vdash C
\end{array}
$
\quad
\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}
2024-05-01 19:37:27 +00:00
\subsection{Adding Wildcards to the mix}
\unify{} is able to create wildcard solutions even when the input set of constraints do not contain any wildcard variables.
%Input constraints originating from a completely untyped input program do not contain any existential types.
%Those are added during \unify{}.
Wildcard types are added preemptively and if necessary can be removed later down the line.
The parts where existential types are created are the \rulename{Match} and \rulename{General} transformations.
Everytime a constraint of the form $\type{T} \lessdot \tv{a}$ occurs,
it could be possible that a wildcard type for $\tv{a}$ is needed.
For example the constraint $\exptype{List}{\type{String}} \lessdot \tv{a}$
results in $\tv{a} \doteq \wctype{\wildcard{X}{\tv{u}}{\tv{l}}}{List}{\rwildcard{X}}$.
The upper and lower bounds of the freshly generated wildcard $\rwildcard{X}$ are type placeholders.
If a second constraint like $\tv{a} \lessdot \exptype{List}{\type{String}}$
exists the wildcard $\rwildcard{X}$ has to be removed by setting both lower and upper bound to $\type{String}$.
2024-05-03 15:37:43 +00:00
\textit{Example:}
\begin{displaymath}
\prftree[r]{\rulename{Reduce}}{
\prftree[r]{\rulename{Subst}}{
\prftree[r]{\rulename{Same}}{\exptype{List}{\type{Integer}} \lessdot \tv{r}}
{\exptype{List}{\type{Integer}} \lessdot \tv{r},
\tv{r} \doteq \wctype{\wildcard{X}{\ntv{u}}{\ntv{l}}}{List}{\rwildcard{X}}
}}
{\exptype{List}{\type{Integer}} \lessdot \wctype{\wildcard{X}{\ntv{u}}{\ntv{l}}}{List}{\rwildcard{X}}}
}
{\type{Integer} \lessdot \ntv{u}, \ntv{l} \lessdot \type{Integer}}
\end{displaymath}
2024-05-01 19:37:27 +00:00
%Wildcard creation. % TODO: Explain by the example from the Bad Honnef Talk
%Wildcards are bound to a type.
% and can therefore only be created at T <. a constraints
% After a reduce step the information to which Type the wildcard was bound is lost!
\begin{lstlisting}
<X> List<X> concat(List<X> l, List<X> r){ ... }
someList(){
return new List("String") :? new List(42);
}
\end{lstlisting}
2024-05-02 14:14:35 +00:00
Constraints for the untyped \texttt{someList} method:
\begin{constraintset}
$\begin{array}{l}
2024-05-03 15:37:43 +00:00
\exptype{List}{\ntv{x}} \lessdot {\ntv{r}}, \type{String} \lessdot {\ntv{x}},
\exptype{List}{\ntv{y}} \lessdot {\ntv{r}}, \type{Integer} \lessdot {\ntv{y}}
2024-05-02 14:14:35 +00:00
\end{array}$
\end{constraintset}
2024-05-03 15:37:43 +00:00
\begin{displaymath}
\prftree[r]{\rulename{Subst}}
{
\prftree[r]{\rulename{Same}}{\type{String} \lessdot \ntv{x}}
{\type{String} \lessdot \ntv{x}, \ntv{x} \doteq \type{String}}
}
{
\prftree[r]{\rulename{Same}}{\type{Integer} \lessdot \ntv{y}}
{\type{Integer} \lessdot \ntv{y}, \ntv{y} \doteq \type{Integer}}
}
{
\prftree[r]{\rulename{Reduce}}{\type{String} \lessdot \type{String}, \type{Integer} \lessdot \type{Integer}, \ntv{x} \doteq \type{String}, \ntv{y} \doteq \type{Integer}}
{\ntv{x} \doteq \type{String},\ntv{y} \doteq \type{Integer}}
}
\end{displaymath}
%After another substitution this leads to the constraints:
%$\exptype{List}{\type{String}} \lessdot {\ntv{r}}, \exptype{List}{\type{Integer}} \lessdot {\ntv{r}}$
2024-05-02 14:14:35 +00:00
The constraint $\type{String} \lessdot {\ntv{x}}$ is solved by applying
2024-05-04 11:56:55 +00:00
\rulename{Super} and afterwards substituting $\type{String}$ for $\ntv{x}$,
same for $\type{Integer} \lessdot \ntv{y}$,
2024-05-03 15:37:43 +00:00
resulting in the two constraints \linebreak[2]
2024-05-04 11:56:55 +00:00
$\exptype{List}{\type{Integer}} \lessdot {\ntv{r}}$ \linebreak[2] and \linebreak[2]
$\exptype{List}{\type{String}} \lessdot {\ntv{r}}$.
Now comes the part where \unify{} creates existential types by applying the \rulename{Same} transformation.
An existential type is created with fresh type placeholders as upper and lower bound.
After a substitution all $\tv{r}$ are replaced with this new existential type.
\unify{} can now determine type replacements for the freshly created bounds $\tv{u}$ and $\tv{l}$.
2024-05-03 15:37:43 +00:00
\begin{displaymath}
\prftree[r]{\rulename{Reduce}}{
\prftree[r]{\rulename{Subst}}{
\prftree[r]{\rulename{Same}}{\exptype{List}{\type{Integer}} \lessdot \tv{r},\exptype{List}{\type{Integer}} \lessdot \tv{r}}
{\exptype{List}{\type{String}} \lessdot \tv{r},
\exptype{List}{\type{Integer}} \lessdot \tv{r},
\tv{r} \doteq \wctype{\wildcard{X}{\ntv{u}}{\ntv{l}}}{List}{\rwildcard{X}}
}}
{\exptype{List}{\type{String}} \lessdot \wctype{\wildcard{X}{\ntv{u}}{\ntv{l}}}{List}{\rwildcard{X}},
\exptype{List}{\type{Integer}} \lessdot \wctype{\wildcard{X}{\ntv{u}}{\ntv{l}}}{List}{\rwildcard{X}}}
}
{\type{String} \lessdot \ntv{u}, \ntv{l} \lessdot \type{String},
\type{Integer} \lessdot \ntv{u}, \ntv{l} \lessdot \type{Integer}}
\end{displaymath}
2024-05-02 14:14:35 +00:00
2024-05-04 11:56:55 +00:00
In this example a correct solution is $\sigma(\tv{u}) = \type{Object}$ and $\sigma(\tv{l}) = \bot$.
Remember that the substitution for the type placeholder $\tv{r}$ is $\wctype{\wildcard{X}{\ntv{u}}{\ntv{l}}}{List}{\rwildcard{X}}$
leading to \texttt{List<?>} as a return type for the \texttt{someList} method after applying $\sigma$.
2024-05-02 14:42:15 +00:00
2024-05-04 11:56:55 +00:00
\begin{lstlisting}
List<? extends Object> someList(){
return new List("String") :? new List(42);
}
\end{lstlisting}
2024-05-02 14:42:15 +00:00
2024-05-06 10:11:57 +00:00
\subsection{Wildcard Elimination Example}
\begin{lstlisting}
<X> List<X> concat(List<X> l, List<X> l2){ ... }
someList(){
return new List("String") :? new List(42);
}
concat(someList(), someList());
\end{lstlisting}
Let's add an additional method call to the previous example.
The \texttt{concat} method takes two lists of the same generic type.
\texttt{concat} cannot be invoked with two existential lists.
%TODO: Explain capture conversion
2024-02-06 17:04:31 +00:00
\subsection{Description}
The \unify{} algorithm tries to find a solution for a set of constraints like
$\set{\exptype{List}{String} \lessdot \tv{a}, \exptype{List}{Integer} \lessdot \tv{a}}$.
Those two constraints imply that we have to find a type replacement for type variable $\tv{a}$,
which is a supertype of $\exptype{List}{String}$ aswell as $\exptype{List}{Integer}$.
The input constraints are transformed until they reach a solved form which is then converted to a type solution.
A constraint set is in solved form if it only consists of constraints of the form
$\tv{a} \doteq \type{T}$ and $\tv{a} \lessdot \type{T}$.
\unify{} is described as a nondeterministic algorithm.
Some constraints allow for multiple transformations from which
the algorithm has to pick the right one.
There are also cases where there is more than on correct transformation and
therefore more than one correct solution to the given input constraints.
For that case still only one correct solution is returned by this specification of the algorithm.
Our implementation of the algorithm considers this and tries every possible transformation option
and gathers all possible type solutions.
We skip the definition of this practice, because it is already described in \cite{TIforFGJ}
and only needed for a proof of completeness.
2024-02-06 17:04:31 +00:00
The \unify{} algorithm applies conversions according to the subtyping rules (depicted in figure \ref{fig:subtyping}).
At every step we try to find a reduction, which brings us closer to solved form without excluding any possible solution.
\textit{Examples:}
\begin{itemize}
\item A $\bot \lessdot \type{T}$ constraint is always satisfied and can be ignored. It will be removed by the \rulename{Bot} rule.
2024-02-06 17:04:31 +00:00
For the type placeholder $\tv{a}$ in the constraint $\tv{a} \lessdot \bot$ only the $\bot$ type is a possible substitution,
which is set by the \rulename{Pit} rule.
\item The \rulename{Reduce} rule represents the S-Exists type rule.
2024-02-07 09:28:28 +00:00
This rule uses wildcard placeholders ($\ol{\wtv{a}}$) to find a possible substitution for the wildcards on the right side.
The constraint $\type{N} \lessdot \wcNtype{\overline{\wildcard{X}{\type{U}}{\type{L}}}}{N'}$ is satisfied if
there is a substitution $[\ol{T}/\ol{X}]\type{N} = \type{N'}$ with $\ol{T}$ inside the bounds $\ol{U}$ and $\ol{L}$.
For example the constraint
2024-02-06 17:04:31 +00:00
$\exptype{List}{\tv{a}} \lessdot \wctype{\wildcard{X}{\type{Object}}{\bot}}{List}{\rwildcard{X}}$
is converted to
2024-02-06 17:04:31 +00:00
$\set{\tv{a} \doteq \wtv{x}, \wtv{x} \lessdot \type{Object}, \bot \lessdot \wtv{x} }$.
After applying \rulename{Swap} and \rulename{Subst-WC} on $\tv{a} \doteq \wtv{x}$ we get
$\set{\tv{a} \lessdot \type{Object}, \bot \lessdot \tv{a}}$ and can now apply the \rulename{Bot} rule.
This leaves us with $\set{\tv{a} \lessdot \type{Object}}$.
\item The \rulename{Erase} rule will remove redundant $\type{T} \doteq \type{T}$ constraints
\item \rulename{Equals} ensures equality of two types by ensuring they are mutual subtypes.
Constraints like $\wctype{\wildcard{X}{\tv{a}}{\tv{b}}}{List}{\rwildcard{X}} \doteq \wctype{\wildcard{Y}{\type{Object}}{\tv{String}}}{List}{\rwildcard{Y}}$
are transformed to
$\wctype{\wildcard{X}{\tv{a}}{\tv{b}}}{List}{\rwildcard{X}} \lessdot \wctype{\wildcard{Y}{\type{Object}}{\tv{String}}}{List}{\rwildcard{Y}}$
and $\wctype{\wildcard{Y}{\type{Object}}{\tv{String}}}{List}{\rwildcard{Y}} \lessdot \wctype{\wildcard{X}{\tv{a}}{\tv{b}}}{List}{\rwildcard{X}}$.
% The types $\wctype{\rwildcard{X}}{List}{\rwildcard{X}}$ and $\wctype{\rwildcard{Y}}{List}{\rwildcard{Y}}$
% are equal.
\end{itemize}
2024-02-06 17:04:31 +00:00
We define two types as equal if they are mutual subtypes of each other.
%This relation is symmetric, reflexive and transitive by the definition of subtyping.
%This definition is sufficient for proving soundness.
\begin{definition}{Type Equality:}\label{def:equal}
$\Delta \vdash \type{S} = \type{T}$ if $\Delta \vdash \type{T} <: \type{S}$ and $\Delta \vdash \type{T} <: \type{S}$
\end{definition}
%This definition makes sense
% The symmetric subtyping allows this type to be substit
% We define types to be equal if they are symmetric subtypes.
% This allows the substitution of these types with eachother.
% If $\Delta \vdash \type{S} = \type{S'}$ and $\Delta \vdash \type{T} <: \type{T'}$,
% then $\Delta \vdash [\type{S}/\type{S'}]\type{T} <: \type{T'}$.
\textbf{Wildcard Environment:}
Additional to a constraint set \unify{} holds a wildcard environment $\wildcardEnv{}$ keeping free variables.
The algorithm starts with an empty wildcard environment $\wildcardEnv{}$.
Only the \rulename{Capture} 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.
% \subsection{Capture Conversion}
% % TODO: Describe Capture conversion
% Capture conversion is done during the \unify{} algorithm.
% \unify{} has to make two promises to ensure soundness of our type inference algorithm.
% Capture conversion can only be applied at capture constraints.
% Free variables are not allowed to leave their scope.
% This is ensured by type variables which are not allowed to be assigned type holding free variables.
2024-02-06 17:04:31 +00:00
2024-04-04 12:38:16 +00:00
\textbf{Wildcard Placeholders:}
The vital part are the \rulename{Subst} and \rulename{Normalize} rules.
They assert that a normal type placeholder is never replaced by a type containing free variables.
\rulename{Normalize} replaces Wildcard placeholders with normal placeholders right before they get substituted by \rulename{Subst}.
The idea is to keep the possibility of replacing a wildcard placeholder with a free variable as long as possible.
2024-04-08 19:45:54 +00:00
As soon as they appear in a $\ntv{a} \doteq \type{T}$ constraint they have to be replaced with normal placeholders.
2024-04-04 12:38:16 +00:00
A type solution for a normal type placeholder will never contain free variables.
This is needed to guarantee well-formed type solutions and also keep free variables inside their scope.
2024-04-08 19:45:54 +00:00
\begin{example}{Free variables must not leave the scope of the surrounding \texttt{let} statement}
\noindent
\begin{minipage}{0.40\textwidth}
2024-04-04 12:38:16 +00:00
\begin{lstlisting}
2024-04-08 19:45:54 +00:00
m(l) = let v = l in v.get()
\end{lstlisting}
\end{minipage}%
\hfill
\begin{minipage}{0.59\textwidth}
\begin{constraintset}
$\tv{l} \lessdot \tv{v}, \tv{v} \lessdotCC \exptype{List}{\wtv{x}},
\wtv{x} \lessdot \tv{r}$
\end{constraintset}
\end{minipage}
Lets assume the variables \texttt{l} and \texttt{v}
get the type $\wctype{\wildcard{X}{\type{Object}}{\type{String}}}{List}{\rwildcard{X}}$ assigned to them.
After application of the \rulename{Capture} and \rulename{SubstWC} rules the constraint set looks like this:
$\begin{array}[c]{l}
\wctype{\wildcard{X}{\type{Object}}{\type{String}}}{List}{\rwildcard{X}} \lessdotCC \exptype{List}{\wtv{x}}, \wtv{x} \lessdot \ntv{r}
\\
\hline
\vspace*{-0.4cm}\\
\wildcard{X}{\type{Object}}{\type{String}} \vdash \wtv{x} \doteq \rwildcard{X}, \rwildcard{X} \lessdot \ntv{r}
\end{array}
$
Replacing $\tv{r}$ with $\rwildcard{X}$ would solve the constraint set but lead to the method type
\texttt{X m(List<? super String> l)} which makes no sense.
The normal type placeholder $\ntv{r}$ has to be replaced by a type without free type variables
($\ntv{r} \doteq \type{Object}$) leading to
\texttt{Object m(List<? super String> l)}.
\end{example}
2024-04-04 12:38:16 +00:00
2024-02-06 17:04:31 +00:00
\subsection{Algorithm}
%\newcommand{\tw}[1]{\tv{#1}_?}
\begin{description}
\item[Input:] An environment $\Delta'$
and a set of constraints $C = \set{ \type{T} \lessdot \type{T}, \type{T} \lessdotCC \type{T}, \type{T} \doteq \type{T} \ldots}$
\item[Output:]
Set of unifiers $Uni = \set{\sigma_1, \ldots, \sigma_n}$ and an environment $\Delta$
\end{description}
%The transformation steps are not applied all at once but in a specific order:
\unify{} executes the following steps until a type solution is found:
\begin{description}
\item[Step 1:]
2024-04-03 13:54:08 +00:00
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.
\item[Step 2:]
%If there are no $(\type{T} \lessdot \tv{a})$ constraints remaining in the constraint set $C$
%resume with step 4.
2024-04-03 13:54:08 +00:00
The second step is nondeterministic.
%\unify{} has to pick the right transformation for each constraint of the form $\type{N} \lessdot \tv{a}$.
%The rules in figure \ref{fig:step2-rules} offer three possibilities to deal with constraints $\type{N} \lessdot \tv{a}$.
For every $\type{T} \lessdot \tv{a}$ constraint \unify{} has to pick exactly one transformation from figure \ref{fig:step2-rules}.
The same principle goes for constraints of the form $\tv{a} \lessdot \type{N}, \tv{a} \lessdot \tv{b}$ and the two transformations in figure \ref{fig:step2-rules2}.
%They have to be applied until the constraint set holds no constraints of the form $\tv{a} \lessdot \type{N}, \tv{a} \lessdot \tv{b}$.
If atleast one transformation was applied in this step revert to step 1.
Otherwise proceed with step 3.
%This builds a search tree over multiple possible solutions.
%\unify{} has to try each branch and accumulate the resulting solutions into a solution set.
2024-04-03 13:54:08 +00:00
%$\type{T} \lessdot \ntv{a}$ constraints have three and $\type{T} \lessdot \wtv{a}$ constraints have five possible transformations.
\textit{Hint:}
When implementing this step via backtracking
the rules \rulename{General} and \rulename{Super} should be tried first.
% is the Same rule really necessary?
The \rulename{Settle} and \rulename{Raise} rules should only be used when none of the rules in figure \ref{fig:step2-rules} can be applied.
\item[Step 3:]
Apply the rules in figure \ref{fig:cleanup-rules} exhaustively.
\rulename{Ground} and \rulename{Flatten} deal with constraints containing free variables.
If a type placeholder is solely used as lower bound \rulename{Ground} can replace it with the bottom type.
Otherwise the \rulename{Flatten} rule has to remove the wildcards responsible for the free variable.
\text{Note:} Only one of those rules has to be applied per constraint.
If the constraint set has been changed by one of these rules the algorithm must return to step 1.
But if only the \rulename{SubElim} rule is applied or the constraint set is not changed at all,
the algorithm can proceed with step 4.
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.
\end{description}
\item[Step 4:] \textit{(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}}}) \subseteq \Delta_in$
\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}
%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.
% \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}
\end{description}
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 as $\wtv{a}$ it can be used by the \rulename{Subst-WC} rule in step 1.
With \texttt{C} being class names and \texttt{A} being wildcard names.
The wildcard type $\wildcard{X}{U}{L}$ consist of an upper bound $\type{U}$, a lower bound $\type{L}$
and a name $\mathtt{X}$.
The \rulename{Tame} rule eliminates wildcards. %TODO
This is done by setting the upper and lower bound to the same value.
\unify{} applies a capture conversion everywhere it is possible (see \rulename{Capture} rule).
Capture conversion removes a types bounding environment $\Delta$ and adds the included wildcard definitions to the global environment $\wildcardEnv{}$.
%Type variables used in its type parameters are now bound to a global scope and not locally anymore.
The \rulename{match} rule generates fresh wildcards $\overline{\wildcard{A}{\tv{u}}{\tv{l}}}$.
Their upper and lower bounds are fresh type variables.
\unify{} is able to remove wildcards by assigning their upper and lower bounds the same type
(Def: $\type{Object} = \wildcard{A}{Object}{Object}$ by definition \ref{def:equal}).
This is used by the \rulename{Tame} rule.
\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{\overline{\wildcard{X}{\type{U}}{\type{L}}}}{N} &= \wcNtype{\overline{\wildcard{X}{[\type{A}/\type{B}]\type{U}}{[\type{A}/\type{B}]\type{L}}}}{[\type{A}/\type{B}]N} & \text{if}\ \type{B} \notin \overline{\rwildcard{X}} \\
[\type{A}/\type{B}]\wcNtype{\overline{\wildcard{X}{\type{U}}{\type{L}}}}{N} &= \wcNtype{\overline{\wildcard{X}{\type{U}}{\type{L}}}}{N} & \text{if}\ \type{B} \in \overline{\rwildcard{X}} \\
\end{align*}
\item[Free Variables:]
The $\text{fv}$ function assumes every wildcard type variable to be a free variable aswell.
% TODO: describe a function which determines free variables? or do an example?
2024-04-03 13:54:08 +00:00
\begin{align*}
\text{fv}(\rwildcard{A}) &= \set{ \rwildcard{A} } \\
\text{fv}(\tv{a}) &= \emptyset \\
%\text{fv}(\wtv{a}) &= \set{\wtv{a}} \\
2024-04-03 13:54:08 +00:00
\text{fv}(\wctype{\Delta}{C}{\ol{T}}) &= \set{\text{fv}(\type{T}) \mid \type{T} \in \ol{T}} / \text{dom}(\Delta) \\
\end{align*}
\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]
% \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}
% if there are a <. List<x?> constraints remaining in the end, then this can be a sign of a irregular input constraint set.
2024-04-08 20:51:06 +00:00
\begin{figure}
\begin{center}
\leavevmode
\fbox{
\begin{tabular}[t]{l@{~}l}
2024-02-14 00:56:35 +00:00
\rulename{Subst} &
$\begin{array}[c]{l}
\wildcardEnv \vdash C \cup \set{\ntv{a} \doteq \type{T}}\\
\hline
[\type{T}/\tv{a}]\wildcardEnv \vdash [\type{T}/\tv{a}]
C \cup \set{\ntv{a} \doteq \type{T}}
\end{array}
\quad \begin{array}{c}
\ntv{a} \notin \type{T} \\
\text{fv}(\type{T}) \subseteq \Delta', \, \text{wtv}(\type{T}) = \emptyset
\end{array}$\\
\\
\rulename{Subst-WC} &$
\begin{array}[c]{l}
\wildcardEnv \vdash C \cup \set{\wtv{a} \doteq \rwildcard{T}}\\
\hline
[\type{T}/\wtv{a}]\wildcardEnv \vdash [\type{T}/\wtv{a}]C
\end{array} \quad \wtv{a} \notin \type{T}
$\\
\\
\rulename{Normalize} &
2024-02-14 00:56:35 +00:00
$\begin{array}[c]{l}
\wildcardEnv \vdash C \cup \set{\ntv{a} \doteq \type{T}}\\
2024-02-14 00:56:35 +00:00
\hline
[\ntv{b}/\wtv{b}]\wildcardEnv \vdash [\ntv{b}/\wtv{b}]
C \cup \set{\ntv{a} \doteq [\ntv{b}/\wtv{b}]\type{T}}
\end{array}
\quad \begin{array}{c}
\wtv{b} \in \text{wtv}(\type{T})\\
\ntv{b} \ \text{fresh}
\end{array}$\\
\\
\rulename{Contract} &
$\begin{array}[c]{l}
\wildcardEnv \cup \set{\wildcard{A}{\type{U}}{\type{L}}} \vdash C \cup \set{\ntv{a} \doteq \type{T}}\\
\hline
[\type{U}/\type{A}]\wildcardEnv \vdash [\type{U}/\type{A}]
C \cup [\type{U}/\type{A}]\set{\ntv{a} \doteq \type{T}, \type{L} \doteq \type{U}}
\end{array}
\quad \begin{array}{c}
\rwildcard{A} \in \text{fv}(\type{T})\\
\end{array}$\\
\end{tabular}}
\end{center}
\caption{Substitution rules}\label{fig:subst-rules}
\end{figure}
% all possible variations have to be converted
There are n different rules to deal with $\type{N} \lessdot \type{N}$ constraints.
Prepare, Capture, Reduce, Trim, Clear, Exclude, Adapt
2024-04-08 19:45:54 +00:00
% % TODO:
% a <c C<X>
% -------------
% a <. X.C<X>, X.C<X> <c C<X>
2024-04-08 19:45:54 +00:00
% a <. C<X>
% ---------
% a <. C<U>, U = L
%The capture constraints are preserved when applying the \rulename{Upper} rule.
% This is legal: a T <c S constraint indicates a let-statement can be inserted. Therefore there must exist a type T' with T <. T' <c S
2024-03-19 19:52:04 +00:00
\begin{figure}
\begin{center}
\leavevmode
\fbox{
\begin{tabular}[t]{l@{~}l}
2024-02-13 18:14:10 +00:00
% \rulename{normalize} %obsolete because of Tame
% & $
% \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'}) \subseteq \Delta_in
% $
% \\\\
\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} }
2024-02-09 20:49:41 +00:00
\end{array} %\quad \text{fv}(\type{U}, \type{L}) \subseteq \Delta_in
2024-02-14 13:00:37 +00:00
\quad \type{T} \ \text{is no wildcard placeholder}
$
\\\\
\rulename{Equals} %TODO
& $
\begin{array}[c]{l}
\wildcardEnv \vdash C \cup \, \set{ \wcNtype{\Delta}{N} \doteq \wcNtype{\Delta'}{N'} } \\
\hline
\vspace*{-0.4cm}\\
\wildcardEnv \vdash C \cup \,
\set{
\wcNtype{\Delta}{N} \lessdot \wcNtype{\Delta'}{N'}, \wcNtype{\Delta'}{N'} \lessdot \wcNtype{\Delta}{N}
}
\end{array} %\quad |\Delta| = |\Delta'|
% \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}
2024-04-03 13:54:08 +00:00
\quad
\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}
2024-02-06 17:04:31 +00:00
\wildcardEnv \vdash C \cup \set{\type{T} \doteq \wtv{a}}\\
\hline
2024-02-06 17:04:31 +00:00
\wildcardEnv \vdash C \cup \set{\wtv{a} \doteq \type{T}}
\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} \quad
\begin{array}[c]{l}
\wildcardEnv \vdash C \cup \set{\ntv{a} \doteq \rwildcard{A}}\\
\hline
\wildcardEnv \vdash C \cup \set{\rwildcard{A} \doteq \ntv{a}}
\end{array}$
\end{tabular}}
\end{center}
\caption{Constraint normalize rules}\label{fig:normalizing-rules}
\end{figure}
\begin{figure}
\begin{center}
\leavevmode
\fbox{
\begin{tabular}[t]{l@{~}l}
\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{Rules for normal placeholders}\label{fig:reduce-rules}
\end{figure}
\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_1 \wctype{\Delta}{D}{\ol{T}}, \tv{a} \lessdot_2 \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_1 \wctype{\Delta}{D}{\ol{T}}, \\
\wctype{\overline{\wildcard{A}{\tv{u}}{\tv{l}}}}{C}{\overline{\rwildcard{A}}}
\lessdot_2 \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 \type{T} } \\
\hline
\vspace*{-0.4cm}\\
\wildcardEnv \cup \overline{\wildcard{C}{[\ol{\rwildcard{C}}/\ol{\rwildcard{B}}]\type{U}}{[\ol{\rwildcard{C}}/\ol{\rwildcard{B}}]\type{L}}}
\vdash C \cup \, \set{
[\ol{\rwildcard{C}}/\ol{\rwildcard{B}}] \exptype{C}{\ol{S}} \lessdot \type{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}
$
2024-01-10 15:03:23 +00:00
\\\\
2024-02-10 07:18:58 +00:00
\rulename{Adopt}
& $
\begin{array}[c]{@{}ll}
\begin{array}[c]{l}
\wildcardEnv \vdash C \cup \, \set{
\tv{b} \lessdot_1 \tv{a},
\tv{a} \lessdot_2 \type{N}, \tv{b} \lessdot_3 \type{N'}} \\
2024-02-10 07:18:58 +00:00
\hline
\vspace*{-0.4cm}\\
\wildcardEnv \vdash C \cup \, \set{
\tv{b} \lessdot \type{N},
\tv{b} \lessdot_1 \tv{a},
\tv{a} \lessdot_2 \type{N} , \tv{b} \lessdot_3 \type{N'}
2024-02-10 07:18:58 +00:00
}
\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}
\begin{figure}
\begin{center}
\leavevmode
\fbox{
\begin{tabular}[t]{l@{~}l}
\rulename{Prepare} %The lessdotCC constraint only ensures that the left side looses its wildcardEnvironment.
%It does not ensure that the left side doesn't contain free variables. If you want to ensure that you have to give the left side a normal placeholder
&
$
\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{T}}) \subseteq \Delta_{in}
\end{array}
\end{array}
$
\\\\
\rulename{Trim}
&
$
\begin{array}[c]{@{}ll}
\begin{array}[c]{l}
\wildcardEnv \vdash
C \cup \, \set{ \wctype{\Delta,\Delta'}{C}{\ol{S}} \lessdot \type{T} } \\
\hline
\vspace*{-0.4cm}\\
\wildcardEnv \vdash
C \cup \, \set{ \wctype{\Delta}{C}{\ol{S}} \lessdot \type{T} } \\
\end{array}
%\quad \ol{Y} = \textit{fresh}(\ol{X})
\quad \begin{array}[c]{l}
\text{fv}(\ol{S}) \cap \Delta' = \emptyset
\end{array}
\end{array}
$
\\\\
\rulename{Clear}
&
$
\begin{array}[c]{@{}ll}
\begin{array}[c]{l}
\wildcardEnv \cup \set{\wildcard{A}{\type{U}}{\type{L}}} \vdash
C \cup \, \set{ \wctype{\Delta}{C}{\ol{S}} \lessdot \type{T} } \\
\hline
\vspace*{-0.4cm}\\
\subst{\type{U}}{\rwildcard{A}}\wildcardEnv \vdash
[\type{U}/\rwildcard{A}]C \cup \, [\type{U}/\rwildcard{A}]\set{ \wctype{\Delta}{C}{\ol{S}} \lessdot \type{T}, \type{U} \doteq \type{L} } \\
\end{array}
%\quad \ol{Y} = \textit{fresh}(\ol{X})
\quad \begin{array}[c]{l}
\Delta \neq \emptyset\\
\rwildcard{A} \in \text{fv}(\type{T})
\end{array}
\end{array}
$
\\\\
\rulename{Exclude}
&
$
\begin{array}[c]{@{}ll}
\begin{array}[c]{l}
\wildcardEnv \vdash
C \cup \, \set{ \wctype{\Delta}{C}{\ol{S}} \lessdot \type{T} } \\
\hline
\vspace*{-0.4cm}\\
\subst{\tv{a}}{\wtv{a}}\wildcardEnv \vdash
[\tv{a}/\wtv{a}]C \cup \, [\tv{a}/\wtv{a}]\set{ \wctype{\Delta}{C}{\ol{S}} \lessdot \type{T} } \\
\end{array}
%\quad \ol{Y} = \textit{fresh}(\ol{X})
\quad \begin{array}[c]{l}
\Delta \neq \emptyset\\
\wtv{a} \in \text{fv}(\type{T}), \tv{a} \ \text{fresh}
\end{array}
\end{array}
$
\end{tabular}}
\end{center}
\caption{Dealing with wildcard types on the left side of a subtype constraint}
\end{figure}
2024-02-06 17:04:31 +00:00
\begin{figure}
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.
2024-02-06 17:04:31 +00:00
$\set{\tv{a} \doteq \type{N}} \in C$ with $\text{fv}(\type{N}) \cap \Delta_{in} \neq \emptyset$ $\implies$ fail!
% if T <. S with not T << S
% T <. S with fv(T) cup fv(S) not empty (free variables in a non capture conversion constraint)
\caption{Fail conditions}
\end{figure}
2024-02-14 00:56:35 +00:00
\def\boxit#1#2{%
\smash{\color{red}\fboxrule=1pt\relax\fboxsep=2pt\relax%
\llap{\rlap{\fbox{\phantom{\rule{#1}{#2}}}}~}}\ignorespaces
}
\begin{figure}
\begin{center}
\fbox{
\begin{tabular}[t]{l@{~}l}
\rulename{Same}
& $
\begin{array}[c]{l}
\wildcardEnv \vdash
C \cup \type{G} \lessdot \tv{a}\\
\hline
\wildcardEnv \vdash
C \cup \set{
\tv{a} \doteq \type{G}
}
\end{array}
$
\\\\
% \cdashline{1-2} \\
% \rulename{Same}
% & $
% \begin{array}[c]{l}
% \wildcardEnv \cup \set{\overline{\wildcard{A}{\type{U}}{\type{L}}}} \vdash
% C \cup \wctype{\Delta'}{C}{\ol{X}} \lessdot \ntv{a}\\
% \hline
% \wildcardEnv \cup \set{\overline{\wildcard{A}{\type{U}}{\type{L}}}} \vdash
% C \cup \set{
% \ntv{a} \doteq \wctype{\Delta',\overline{\wildcard{A}{\type{U}}{\type{L}}}}{C}{\ol{X}}
% }
% \end{array} \quad \begin{array}[c]{l}
% \text{fv}(\wctype{\Delta'}{C}{\ol{X}}) / \Delta_{in} = \overline{\rwildcard{A}}
% \end{array}
% $
% \\\\
2024-02-14 00:56:35 +00:00
\cdashline{1-2} \\
\rulename{\generalizeRule}
& $
\begin{array}[c]{l}
2024-02-14 01:22:14 +00:00
\wildcardEnv \vdash C \cup \wctype{\Delta}{C}{\ol{T}} \lessdot \ntv{a}\\
2024-02-14 00:56:35 +00:00
\hline
2024-02-14 01:22:14 +00:00
\wildcardEnv \vdash C \cup \set{\wctype{\Delta}{C}{\ol{T}} \lessdot \ntv{a},
2024-02-14 01:24:27 +00:00
\ntv{a} \doteq \wctype{\overline{\wildcard{X}{\tv{u}}{\tv{l}}}}{C}{\overline{\rwildcard{X}}},
2024-02-14 00:56:35 +00:00
%\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}
2024-02-14 01:22:14 +00:00
$
2024-02-14 00:56:35 +00:00
\\\\
\cdashline{1-2} \\
\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,\, \Delta' = \Delta \cap \text{fv}([\ol{T}/\ol{X}]\ol{N})
\end{array}
$
% \\\\
% \hline \\
% \rulename{SameW}
% & $
% \begin{array}[c]{l}
% \wildcardEnv \vdash
% C \cup \type{G} \lessdot \wtv{a}\\
% \hline
% \wildcardEnv \vdash
% C \cup \set{
% \wtv{a} \doteq \type{G}
% }
% \end{array}
% $
% \\\\
% \cdashline{1-2} \\
% \rulename{\generalizeRule{}W} %TODO: Change description for step 2!
% & $
% \begin{array}[c]{l}
% \wildcardEnv \vdash C \cup \wctype{\Delta}{C}{\ol{T}} \lessdot \wtv{a}\\
% \hline
% \wildcardEnv \vdash C \cup \set{\wctype{\Delta}{C}{\ol{T}} \lessdot \wtv{a},
% \wtv{a} \doteq \wctype{\overline{\wildcard{X}{\wtv{u}}{\wtv{l}}}}{C}{\overline{\rwildcard{X}}},
% %\overline{\tv{l} \lessdot \tv{u}}, % not needed, due to subst and reduce rule which are used afterwards
% \overline{\wtv{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}{\wtv{u}}{\wtv{l}}}
% \end{array}
% $
% %The idea behind the GeneralW rule is, that a constraint X.Pair<X,X> <. a? can be resolved:
% % X.Pair<X,X> <. Y,Z.Pair<Y,Z>
% % X =. y, X =. z, y <. yu?, z <. zu?, yl? <. y, zl? <. z
% % X <. yu?, X <. zu?, yl? <. X, zl? <. X
% % ???
2024-02-14 00:56:35 +00:00
\end{tabular}
}
\end{center}
\caption{Step 2 branching: Multiple rules can be applied to the same constraint}
\label{fig:step2-rules}
\end{figure}
\begin{figure}
\begin{center}
\fbox{
\begin{tabular}[t]{l@{~}l}
\rulename{Subst-X}
& $
\begin{array}[c]{l}
\wildcardEnv \cup \set{\wildcard{X}{\type{U}}{\type{L}}} \vdash
C \cup \rwildcard{X} \lessdot \tv{a}\\
\hline
\wildcardEnv \cup \set{\wildcard{X}{\type{U}}{\type{L}}} \vdash
C \cup \set{
\tv{a} \doteq \rwildcard{X}
}
\end{array} \quad \begin{array}[c]{l}
\rwildcard{X} \in \Delta_{in}
\end{array}
$
\\\\
\cdashline{1-2} \\
\rulename{Gen-X}
& $
\begin{array}[c]{l}
\wildcardEnv \cup \set{\wildcard{X}{\type{U}}{\type{L}}} \vdash
C \cup \rwildcard{X} \lessdot \tv{a}\\
\hline
\wildcardEnv \cup \set{\wildcard{X}{\type{U}}{\type{L}}} \vdash
C \cup \set{
\type{U} \lessdot \tv{a}
}
\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}
\begin{figure}
\begin{center}
\fbox{
\begin{tabular}[t]{l@{~}l}
\rulename{Settle}
& $
\begin{array}[c]{l}
\wildcardEnv \vdash C \cup \set{ \tv{a} \lessdot \type{N},
2024-03-19 19:52:04 +00:00
\tv{a} \lessdot_1 \tv{b}}
2024-02-14 00:56:35 +00:00
\\
\hline
2024-03-19 19:52:04 +00:00
\wildcardEnv \vdash C \cup \set{ \tv{a} \lessdot_1 \tv{b}, \tv{b} \lessdot \type{N} }
2024-02-14 00:56:35 +00:00
\end{array}
$
\\\\
\cdashline{1-2} \\
\rulename{Raise}
& $
\begin{array}[c]{l}
2024-03-19 19:52:04 +00:00
\wildcardEnv \vdash C \cup \set{ \tv{a} \lessdot_1 \type{N},
2024-02-14 00:56:35 +00:00
\tv{a} \lessdot \tv{b}}
\\
\hline
2024-03-19 19:52:04 +00:00
\wildcardEnv \vdash C \cup \set{\tv{a} \lessdot_1 \type{N}, \type{N} \lessdot \tv{b} }
2024-02-14 00:56:35 +00:00
\end{array}
$
\end{tabular}
}
\end{center}
\caption{Step 2 branching: Multiple rules can be applied to the same constraint}
2024-04-03 13:54:08 +00:00
\label{fig:step2-rules2}
2024-02-14 00:56:35 +00:00
\end{figure}
2024-03-19 19:52:04 +00:00
\begin{figure}
\begin{center}
\leavevmode
\fbox{
\begin{tabular}[t]{l@{~}l}
2024-02-10 07:18:58 +00:00
\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} % why does this rule need a X \notin C premise? a \notin C is needed because there could be a constraint b <. List<a> (a is only allowed to be used as lower bound)
& $\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}}{\tv{a}}}} \vdash
C \cup \set{ \overline{\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, \, \tv{a} \notin \overline{T}, \, \tv{a} \notin \wildcardEnv % , \, \rwildcard{X} \notin C\\
%\text{length}( \overline{\tv{a} \lessdot \type{T}} ) > 1
\end{array}
\end{array}$
\\\\
\rulename{Flatten}
& $\begin{array}[c]{l}
\wildcardEnv \cup \set{\wildcard{X}{\type{U}}{\type{L}}} \vdash C \cup \set{\tv{a} \lessdot \type{T}}\\
\hline
[\type{U}/\rwildcard{X}]\wildcardEnv \vdash [\type{U}/\rwildcard{X}]C \cup [\type{U}/\rwildcard{X}]\set{\tv{a} \lessdot \type{T}, \type{U} \doteq \type{L}}
\end{array} \quad \rwildcard{X} \in \text{fv}(\type{T})
$
\end{tabular}}
\end{center}
\caption{Cleanup rules}\label{fig:cleanup-rules}
\end{figure}
\begin{figure}
\begin{center}
\fbox{
\begin{tabular}[t]{l@{~}l}
\rulename{GenDelta}
& $
\deduction{
\wildcardEnv \vdash C \cup \set{\ntv{b} \lessdot \type{T} } \implies \Delta, \sigma
}{
\wildcardEnv \vdash [\type{B}/\ntv{b}]C \implies \Delta \cup \set{\wildcard{B}{\type{T}}{\bot}}, \sigma \cup \set{\ntv{b} \to \type{B}}
} \quad
\begin{array}{l}
2024-02-02 12:22:55 +00:00
\tph(\type{T}) = \emptyset, \text{fv}(\type{T}) \subseteq \Delta \cup \Delta_{in} \\
\rwildcard{B} \ \text{fresh}, \ntv{b} \notin \text{dom}(\sigma), \Delta, \Delta_{in} \vdash \type{T} \ \ok
\end{array}
$
\\\\
\rulename{GenDelta'}
& $
\deduction{
\wildcardEnv \vdash C \cup \set{\wtv{b} \lessdot \type{T} } \implies \Delta, \sigma
}{
\wildcardEnv \vdash [\type{B}/\ntv{b}]C \implies \Delta \cup \set{\wildcard{B}{\type{T}}{\bot}}, \sigma
} \quad
\begin{array}{l}
\tph(\type{T}) = \emptyset, \text{fv}(\type{T}) \subseteq \Delta \cup \Delta_{in} \\
\rwildcard{B} \ \text{fresh}, \Delta, \Delta_{in} \vdash \type{T} \ \ok
\end{array}
$
\\\\
\rulename{GenSigma}
& $
\deduction{
\wildcardEnv \vdash C \cup
\set{\ntv{a} \doteq \type{T} } \implies \Delta, \sigma
}{
\wildcardEnv \vdash C \implies \Delta, \sigma \cup
\set{\ntv{a} \to \type{T} }
} \quad
\begin{array}{l}
2024-01-04 00:33:36 +00:00
\tph(\type{T}) = \emptyset \\ %,\, \text{fv}(\type{T}) \subseteq \Delta \\ % T ok implies that
\ntv{a} \notin \text{dom}(\sigma),\, \Delta, \Delta_{in} \vdash \type{T} \ \ok % TODO: Is it possible to imply well-formedness as long as input is well-formed?
\end{array}
$
\\\\
\end{tabular}}
\end{center}
\caption{Generate result}
\label{fig:generation-rules}
\end{figure}
\begin{figure}
\begin{center}
\fbox{
\begin{tabular}[t]{l@{~}l}
\rulename{Equals} %TODO
& $
\begin{array}[c]{l}
\wildcardEnv \vdash C \cup \, \set{ \wcNtype{\Delta}{N} \doteq \wcNtype{\Delta'}{N'} } \\
\hline
\vspace*{-0.4cm}\\
\wildcardEnv \vdash C \cup \,
\set{
\wcNtype{\Delta}{N} \lessdot \wcNtype{\Delta'}{N'}, \wcNtype{\Delta'}{N'} \lessdot \wcNtype{\Delta}{N}
}
\end{array} %\quad |\Delta| = |\Delta'|
% \quad \text{fv}(\type{N}) = \text{fv}(\type{N'}) = \emptyset
$
\\\\
\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 \type{T} } \\
\hline
\vspace*{-0.4cm}\\
\wildcardEnv \cup \overline{\wildcard{C}{[\ol{\rwildcard{C}}/\ol{\rwildcard{B}}]\type{U}}{[\ol{\rwildcard{C}}/\ol{\rwildcard{B}}]\type{L}}}
\vdash C \cup \, \set{
[\ol{\rwildcard{C}}/\ol{\rwildcard{B}}] \exptype{C}{\ol{S}} \lessdot \type{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} %The lessdotCC constraint only ensures that the left side looses its wildcardEnvironment.
%It does not ensure that the left side doesn't contain free variables. If you want to ensure that you have to give the left side a normal placeholder
&
$
\begin{array}[c]{@{}ll}
\begin{array}[c]{l}
\wildcardEnv \vdash
C \cup \, \set{ \type{N} \lessdot \type{N'} } \\
\hline
\vspace*{-0.4cm}\\
\wildcardEnv \vdash
C \cup \, \set{ \type{N} \lessdotCC \type{N'} } \\
\end{array}
%\quad \ol{Y} = \textit{fresh}(\ol{X})
\quad \begin{array}[c]{l}
\text{fv}(\type{N'}) \subseteq \Delta_{in} \\
\text{wtv}(\type{N'}) = \emptyset
\end{array}
\end{array}
$
\end{tabular}}
\end{center}
\caption{Type Reduction rules}\label{fig:reductionRules}
\end{figure}
\subsection{Explanations}
%The type reduction is done by the rules in figure \ref{fig:reductionRules}
\begin{description}
\item[Prepare]
The \rulename{Prepare} transformation is always applied together with the \rulename{Reduce} transformation.
\unify{} cannot reduce constraints without checking a few prerequisites.
%Take the constraint $\wctype{\rwildcard{X}}{C}{\rwildcard{X}} \lessdot \exptype{C}{\wtv{a}}$ for example.
%If we apply a reduction here we get $\rwildcard{X} \doteq \wtv{a}$.
%The resulting $\sigma(\wtv{a}) = \rwildcard{X}$ seems like a correct substitution,
%but by S-Exists $\wctype{\rwildcard{X}}{C}{\rwildcard{X}} \nless: \exptype{C}{\rwildcard{X}}$.
%Reason: Free variables on the right side of a subtype relations are not allowed to show up as bound variables on the left side.
%$\rwildcard{X}$ in this case.
%Therefore the \rulename{Reduce} rule only reduces constraints where the left side does not declare any wildcards.
%But if the right side neither contains wildcard type placeholders nor free variables the constraint can be reduced anyways.
%The \rulename{Prepare} rule then converts this constraint to a capture constraint.
%Afterwards the \rulename{Capture} rule removes the wildcard declarations on the left side an the constraint can be reduced.
%We loose information during the unification process.
When reducing the constraint
$\wctype{\rwildcard{X}}{List}{\exptype{List}{\rwildcard{X}}} \lessdot \exptype{List}{\exptype{List}{\wtv{x}}}$
it turns into $\exptype{List}{\rwildcard{X}} \doteq \exptype{List}{\wtv{x}}$
and now it seems that $\wtv{x} \doteq \rwildcard{X}$ is a correct solution.
This is indeed wrong because $\wctype{\rwildcard{X}}{List}{\exptype{List}{\rwildcard{X}}} \nless: \exptype{List}{\exptype{List}{\rwildcard{X}}}$.
A correct solution is to remove the wildcard $\rwildcard{X}$ if possible.
% X.List<X> <. List<x> // incorrect
% X.List<List<X>> <. List<List<x>> // incorrect
Therefore the \rulename{Prepare} rule checks if there are any free variables or wildcard placeholders on the right side of the constraint.
If that is the case one of the rules \rulename{Trim}, \rulename{Clear}, or \rulename{Exclude} have to be applied.
In our example this would be the \rulename{Exclude} rule replacing the wildcard placeholder with $\wtv{x}$ with a normal placeholder.
Afterwards \rulename{Prepare} can be used eventually leading to the erasure of the wildcard $\rwildcard{X}$ by equalizing its upper and lower bounds:
\begin{displaymath}
\prftree[r]{\rulename{Contract}}{
\prftree[r]{\rulename{Reduce}}{
\prftree[r]{\rulename{Equals}}{
\prftree[r]{\rulename{Prepare}}{
\wctype{\wildcard{X}{\tv{u}}{\tv{l}}}{List}{\exptype{List}{\rwildcard{X}}} \lessdot \exptype{List}{\exptype{List}{\ntv{x}}}
}
{
\wildcard{X}{\tv{u}}{\tv{l}} \vdash \exptype{List}{\rwildcard{X}} \doteq \exptype{List}{\ntv{x}}
}}
{
\exptype{List}{\rwildcard{X}} \lessdot \exptype{List}{\ntv{x}}, \exptype{List}{\ntv{x}} \lessdot \exptype{List}{\rwildcard{X}}
}
}
{
\wildcard{X}{\tv{u}}{\tv{l}} \vdash \ntv{x} \doteq \rwildcard{X}
}}{
\text{equalize upper and lower bound of }\rwildcard{X}: \quad
\ntv{x} \doteq \tv{u}, \tv{u} \doteq \tv{l}
}
\end{displaymath}
\end{description}
\subsection{Examples}
\textit{Example} of the type reduction rules in figure \ref{fig:reductionRules} with the input
$\wctype{\rwildcard{X}}{Pair}{\wctype{\rwildcard{Y}}{List}{\rwildcard{Y}}, \rwildcard{X}} \lessdot \exptype{Pair}{\wctype{\rwildcard{Y}}{List}{\rwildcard{Y}}, \wtv{a}}$
The first step is the \rulename{Capture} rule.
%The right side of the constraint does not contain any free variables.
$\begin{array}{c}
\wctype{\rwildcard{X}}{Pair}{\wctype{\rwildcard{Y}}{List}{\rwildcard{Y}}, \rwildcard{X}} \lessdot \exptype{Pair}{\wctype{\rwildcard{Y}}{List}{\rwildcard{Y}}, \wtv{a}}\\
\hline %Capture
\wctype{\rwildcard{X}}{Pair}{\wctype{\rwildcard{Y}}{List}{\rwildcard{Y}}, \rwildcard{X}} \lessdotCC \exptype{Pair}{\wctype{\rwildcard{Y}}{List}{\rwildcard{Y}}, \wtv{a}}
\end{array}$
\begin{NiceTabular}{l}
$\ \wctype{\rwildcard{X}}{Pair}{\wctype{\rwildcard{Y}}{List}{\rwildcard{Y}}, \rwildcard{X}} \lessdot \exptype{Pair}{\wctype{\rwildcard{Y}}{List}{\rwildcard{Y}}, \wtv{a}}$ \\
$\nextdeduction{
\wctype{\rwildcard{X}}{Pair}{\wctype{\rwildcard{Y}}{List}{\rwildcard{Y}}, \rwildcard{X}} \lessdotCC \exptype{Pair}{\wctype{\rwildcard{Y}}{List}{\rwildcard{Y}}, \wtv{a}}
} $\\
$\nextdeduction{
\rwildcard{X} \vdash \exptype{Pair}{\wctype{\rwildcard{Y}}{List}{\rwildcard{Y}}, \rwildcard{X}} \lessdot \exptype{Pair}{\wctype{\rwildcard{Y}}{List}{\rwildcard{Y}}, \wtv{a}}
} $\\
$\nextdeduction{
\rwildcard{X} \vdash \wctype{\rwildcard{Y}}{List}{\rwildcard{Y}} \doteq \wctype{\rwildcard{Y}}{List}{\rwildcard{Y}}, \rwildcard{X} \doteq \wtv{a}
} $\\
$\nextdeduction{
\wildcard{X}{Object}{\type{String}} \vdash
\type{String} \lessdot \mathcolorbox{addition}{\type{String}}, \tv{a} \doteq \rwildcard{X}
} $\\
$\nextdeduction{
\wildcard{X}{Object}{\type{String}} \vdash
\cancel{\type{String} \lessdot \rwildcard{X}}, \tv{a} \doteq \rwildcard{X}
} $\\
\CodeAfter
\begin{tikzpicture}
\node [right] at (2-|last) { \colorbox{white}{\rulename{Prepare}} } ;
\node [right] at (3-|last) { \colorbox{white}{\rulename{Capture}} } ;
\node [right] at (4-|last) { \colorbox{white}{\rulename{Reduce}} } ;
\node [right] at (5-|last) { \colorbox{white}{\rulename{Equals}} } ;
\node [right] at (6-|last) { \colorbox{white}{\rulename{Erase}} } ;
\end{tikzpicture}
\end{NiceTabular}
\subsection{Capture Conversion during Unification}
The \unify{} algorithm applies a capture conversion when needed.
A constraint of the form $\wcNtype{\Delta'}{N} \lessdot \type{T}$,
where $\text{fv}(\type{T}) \neq \emptyset$ is not solvable without capture conversion.
\unify{} converts those constraints to $\type{N} \lessdot \type{T}$.
This is only possible for subtype constraints which originated from a method call.
Capture conversion only works with constraints containing free variables.
It also introduces fresh free variables into the constraint set.
Both have to be regulated.
It is not allowed to substitute free type variables freely.
The algorithm introduces a new type of variables: $\wtv{a}$.
\unify{} treats those as free type variables.
This makes it possible to replace a $\wtv{a}$ with a captured wildcard variable
without having to worry about introducing free type variables at unwanted places.
The challenge for a type inference algorithm is to apply capture conversion during type inference.
Given a program
\begin{verbatim}
class TypeInferenceExample{
m(l){
return swap(make(l));
}
}
\end{verbatim}
During the time of the type inference algorithm the type of the parameter \texttt{l} is not known.
Due to the call to the method \texttt{make} it is clear that it has to be a subtype of
\texttt{List}.
These subtype relations are expressed with constraints.
$\tv{l} \lessdot \exptype{List}{\tv{a}}$ in this case.
$\tv{l}$ and $\tv{a}$ are type placeholders.
$\tv{l}$ is a type placeholder for the method parameter \texttt{l}.
One correct solution for this constraint is the substitution $\tv{l} \doteq \exptype{List}{\type{Object}}$,
which leads to the program:
\begin{verbatim}
class TypeInferenceExample{
Pair<Object, Object> m(List<Object> l){
return swap(make(l));
}
}
\end{verbatim}
But $\tv{l} \doteq \wctype{\rwildcard{X}}{List}{\rwildcard{X}}$ is also a possible solution.
Eventhough the constraint $\wctype{\rwildcard{X}}{List}{\rwildcard{X}} \lessdot \exptype{List}{\tv{a}}$
is not solvable.
But when we apply capture conversion to create $\exptype{List}{\rwildcard{Y}} \lessdot \exptype{List}{\tv{a}}$
we can substitute $\tv{a} \doteq \rwildcard{Y}$.
The \unify{} algorithm has to apply capture conversions during the unification of type constraints.
But this renders additional problems:
\begin{itemize}
\item Capture conversion is not allowed for every constraint.
\item Capture Converted variables are not allowed to leave their scope
\item \unify{} generates type substitution which cannot be translated to Java types.
\end{itemize}
2024-05-03 15:37:43 +00:00
\subsection{Completeness}\label{sec:completeness}
It is not possible to create all super types of a type.
The General rule only creates the ones expressable by Java syntax, which still are infinitly many in some cases \cite{TamingWildcards}.
%thats not true. it can spawn X^T_T2.List<X> where T and T2 are types and we need to choose one inbetween them
Otherwise the algorithm could generate more solutions, but they have to be filterd out afterwards, because they cannot be translated into Java.
\letfj{} is not able to represent all Java programs. %TODO: this makes ist impossible for our algorithm to be complete on Java
2024-05-03 15:37:43 +00:00
%Loss of completeness:
% a <. b, b <c List<x>
% Example
\begin{lstlisting}
m(l){
return let x = l in x.add(1);
}
\end{lstlisting}
Here generality is lost.
Constraints: $\ntv{l} \lessdot \ntv{x}, \ntv{x} \lessdotCC \exptype{List}{\wtv{x}}$
Correct solution would be:
\begin{lstlisting}
m(List<? super Int> l){
return let x = l in x.add(1);
}
\end{lstlisting}
Our solution:
\begin{lstlisting}
<X extends List<Integer> m(X l){
return let x = l in x.add(1);
}
m(List<? super Integer>)
\end{lstlisting}
$\tv{a} \lessdotCC \type{T}$ constraints allow for existential types on the left side,
because there will be a capture conversion.
We do not cover this and only apply capture conversion when the left side is known.
So $\tv{a}$ will not be assigned a existential type, which explains our less general solution.
If all of the program is given this may be not much of an issue.
The $\tv{a} \lessdotCC \type{T}$ constraint is kept until the end and if the method
is called and $\tv{a}$ gets a type, then this type can be an existential type aswell.
% Problem: There are infinite subtypes to a type Pair<x,y> when capture conversion is allowed
% a <. b, b <c List<X>
% b <. X.List<X>, X.List<X> <c List<x> (is this sound? -> yes)
% ( is this complete? X,Y.Pair<X,Y> <c X.Pair<X,X>)
\subsection{Implementation}
%List this under implementation details
Every constraint that is not in solved form and is not able to be processed by any of the rules accounts as a error constraint and renders the constraint set unsolvable
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.
2024-03-27 13:12:50 +00:00
\textbf{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}}$.
2024-03-27 13:12:50 +00:00
\begin{tabular}[t]{l@{~}l}
\\\\
\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}$
\end{tabular}
% 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}$.