hange Equals rule. Add explanations

This commit is contained in:
Andreas Stadelmeier 2024-02-06 18:04:31 +01:00
parent 98a66bbced
commit f40299a36c
3 changed files with 157 additions and 159 deletions

View File

@ -17,6 +17,68 @@ In Java this is done implicitly by a process called capture conversion \cite{Jav
The type system in \cite{WildcardsNeedWitnessProtection} makes this process explicit by using \texttt{let} statements. The type system in \cite{WildcardsNeedWitnessProtection} makes this process explicit by using \texttt{let} statements.
Our type inference algorithm will accept an input program without let statements and add them where necessary. Our type inference algorithm will accept an input program without let statements and add them where necessary.
We figured the \texttt{let} statements to be obsolete for our use case.
Once the type inference algorithm found a correct type solution
\begin{figure}[tp]
\begin{subfigure}[t]{\linewidth}
\begin{lstlisting}[style=fgj]
class List<A> {
List<A> add(A v) { ... }
}
class Example {
m(l, la, lb){
return l
.add(la.add(1))
.add(lb.add("str"));
}
}
\end{lstlisting}
\caption{Java method with missing return type}
\label{fig:nested-list-example-typeless}
\end{subfigure}
~
\begin{subfigure}[t]{\linewidth}
\begin{lstlisting}[style=tfgj]
class List<A> {
List<A> add(A v) { ... }
}
class Example {
m((*@$\exptype{List}{\wctype{\wildcard{X}{\type{Object}}{\bot}}{List}{\rwildcard{X}}}$@*) l, List<Integer> la, List<String> lb){
return l
.add(la.add(1))
.add(lb.add("str"));
}
}
\end{lstlisting}
\caption{Featherweight Java Representation}
\label{fig:nested-list-example-typed}
\end{subfigure}
~
\begin{subfigure}[t]{\linewidth}
\begin{lstlisting}[style=tfgj]
class List<A> {
List<A> add(A v) { ... }
}
class Example {
m(List<List<? extends Object>> l, List<Integer> la, List<String> lb){
return l
.add(la.add(1))
.add(lb.add("str"));
}
}
\end{lstlisting}
\caption{Java Representation}
\label{fig:nested-list-example-typed}
\end{subfigure}
%\caption{Example code}
%\label{fig:intro-example-code}
\end{figure}
%TODO %TODO
% The goal is to proof soundness in respect to the type rules introduced by \cite{aModelForJavaWithWildcards} % The goal is to proof soundness in respect to the type rules introduced by \cite{aModelForJavaWithWildcards}
% and \cite{WildcardsNeedWitnessProtection}. % and \cite{WildcardsNeedWitnessProtection}.
@ -59,23 +121,27 @@ In Java this is done implicitly.
%Our type inference algorithm has to add let statements surrounding method invocations. %Our type inference algorithm has to add let statements surrounding method invocations.
\begin{figure}[tp] \begin{figure}[tp]
\begin{subfigure}[t]{0.49\linewidth} \begin{constraintset}
\begin{subfigure}[t]{\linewidth}
\begin{lstlisting}[style=fgj] \begin{lstlisting}[style=fgj]
List<? super Integer> ls = ...; List<? super Integer> ls = ...;
ls.add(new Integer()); ls.add(new Integer());
\end{lstlisting} \end{lstlisting}
\caption{Method invocation} \caption{Method invocation}
\label{fig:intro-example-typeless} \label{fig:intro-example-typeless}
\end{subfigure} \end{subfigure}
~ \end{constraintset}
\begin{subfigure}[t]{0.49\linewidth}
\begin{constraintset}
\begin{subfigure}[t]{\linewidth}
\begin{lstlisting}[style=tfgj] \begin{lstlisting}[style=tfgj]
List<? super Integer> ls = ...; List<? super Integer> ls = ...;
let x : (*@ $\wctype{\wildcard{X}{\texttt{Object}}{\texttt{Integer}}}{List}{\rwildcard{X}}$ @*) = ls in ls.add(new Integer()); let x : (*@ $\wctype{\wildcard{X}{\texttt{Object}}{\texttt{Integer}}}{List}{\rwildcard{X}}$ @*) = ls in x.add(new Integer());
\end{lstlisting} \end{lstlisting}
\caption{Capture Conversion by \texttt{let}-statement} \caption{Capture Conversion by \texttt{let}-statement}
\label{fig:intro-example-typed} \label{fig:intro-example-typed}
\end{subfigure} \end{subfigure}
\end{constraintset}
\end{figure} \end{figure}
% \subsection{Wildcards} % \subsection{Wildcards}
@ -115,6 +181,7 @@ This paper describes a \unify{} algorithm to solve these constraints and calcula
For the example above a correct solution would be $\sigma(\tv{a}) = \wctype{\rwildcard{X}}{List}{\rwildcard{X}}$. For the example above a correct solution would be $\sigma(\tv{a}) = \wctype{\rwildcard{X}}{List}{\rwildcard{X}}$.
\subsection{Challenges}\label{challenges} \subsection{Challenges}\label{challenges}
The introduction of wildcards adds additional challenges. The introduction of wildcards adds additional challenges.
% we cannot replace every type variable with a wildcard % we cannot replace every type variable with a wildcard
Type variables can also be used as type parameters, for example Type variables can also be used as type parameters, for example
@ -184,8 +251,6 @@ The main challenge was to find an algorithm which computes $\sigma(\tv{a}) = \rw
% A wildcard type is only treated like a wildcard while his definition is in scope (during the reduce rule) % A wildcard type is only treated like a wildcard while his definition is in scope (during the reduce rule)
% \subsection{Capture Conversion} % \subsection{Capture Conversion}
% \begin{verbatim} % \begin{verbatim}
% <A> List<A> add(A a, List<A> la) {} % <A> List<A> add(A a, List<A> la) {}

View File

@ -348,7 +348,11 @@ holds with any $\Delta'$ so that $(\text{fv}(\exptype{C}{\ol{S}}) \cup \text{fv}
\item[Circle] S-Refl \item[Circle] S-Refl
\item[Swap] by definition \item[Swap] by definition
\item[Erase] S-Refl \item[Erase] S-Refl
\item[Equals] by definition \item[Equals] %by definition
%TODO
% Unify does never contain wildcard environments with unused wildcards. Therefore after N <: N' and N' <: N, both types have the same wildcard environment
% \item[Reduce] % \item[Reduce]
% The renaming from $\rwildcard{C}$ to $\rwildcard{B}$ is not a problem. It's allowed to rename wildcards inside a type. % The renaming from $\rwildcard{C}$ to $\rwildcard{B}$ is not a problem. It's allowed to rename wildcards inside a type.
% Removing $\rwildcard{C}$ from the environment does not change anything because it was freshly generated and is used nowhere. % Removing $\rwildcard{C}$ from the environment does not change anything because it was freshly generated and is used nowhere.

229
unify.tex
View File

@ -1,5 +1,50 @@
\section{Unify}\label{sec:unify} \section{Unify}\label{sec:unify}
\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 algorithm works in a recursive fashion.
The input constraints are transformed until they reach a irreducible state,
which the last step of the algorithm eventually transforms into a solution.
A constraint set is convertable to a correct type solution, if it only contains constraints of the form
$\tv{a} \doteq \type{T}$ (where $\tv{a} \notin \text{tph}(\type{T})$) and $\tv{a} \lessdot \type{T}$.
We call this \textit{Solved Form}.
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.
A $\bot \lessdot \type{T}$ constraint is always satisfied and can be ignored. It will be removed by the \rulename{Bot} rule.
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.
Example:
$\exptype{List}{\tv{a}} \lessdot \wctype{\wildcard{X}{\type{Object}}{\bot}}{List}{\rwildcard{X}}$
The \rulename{Reduce} rule converts this to
$\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.
The \rulename{Erase} rule will remove redundant $\type{T} \doteq \type{T}$ constraints.
But what about constraints like $\wctype{\wildcard{X}{\tv{a}}{\tv{b}}}{List}{\rwildcard{X}} \doteq \wctype{\wildcard{Y}{\type{Object}}{\tv{String}}}{List}{\rwildcard{Y}}$
The \rulename{Equals} rule converts this to
% The equals rule is complicated, because
% X.List<X> =. Y.List<Y> -> is the same
% X^String.List<X> =. X.List<X> -> is not!
% T =. T => T <. T
% Special cases: lessdotCC, Normalize/Tame rule,
The $\lessdotCC$ constraints and the wildcard placeholders $\wtv{a}$ are kept as long as possible.
%TODO: Example where lessdotCC constraints get spared until they can be captured
\subsection{Algorithm}
\newcommand{\gtype}[1]{\type{#1}} \newcommand{\gtype}[1]{\type{#1}}
%\newcommand{\tw}[1]{\tv{#1}_?} %\newcommand{\tw}[1]{\tv{#1}_?}
The \unify{} algorithm computes the type solution. The \unify{} algorithm computes the type solution.
@ -99,10 +144,10 @@ C \cup \set{\tv{a} \doteq \type{T}}
\\ \\
\rulename{Subst-WC} &$ \rulename{Subst-WC} &$
\begin{array}[c]{l} \begin{array}[c]{l}
\wildcardEnv \vdash C \cup \set{\wtv{a} \doteq \rwildcard{G}}\\ \wildcardEnv \vdash C \cup \set{\wtv{a} \doteq \rwildcard{T}}\\
\hline \hline
[\type{G}/\wtv{a}]\wildcardEnv \vdash [\type{G}/\wtv{a}]C \cup \set{\tv{a} \doteq \type{G}} [\type{T}/\wtv{a}]\wildcardEnv \vdash [\type{T}/\wtv{a}]C
\end{array} \quad \wtv{a} \notin \type{G} \end{array} \quad \wtv{a} \notin \type{T}
$ $
\end{tabular}} \end{tabular}}
\end{center} \end{center}
@ -203,37 +248,37 @@ $
\end{array} \quad \text{fv}(\type{U}, \type{L}) \subseteq \Delta_in \end{array} \quad \text{fv}(\type{U}, \type{L}) \subseteq \Delta_in
$ $
\\\\ \\\\
% \rulename{Equals} %TODO \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} \begin{array}[c]{l}
\wildcardEnv \vdash C \cup \, \set{ \wctype{\Delta}{C}{\ol{T}} \doteq \wctype{\Delta}{C}{\ol{T'}} } \\ \wildcardEnv \vdash C \cup \, \set{ \type{N} \doteq \type{N'} } \\
\hline \hline
\vspace*{-0.4cm}\\ \vspace*{-0.4cm}\\
\wildcardEnv \vdash C \cup \, \wildcardEnv \vdash C \cup \,
\set{ \set{
% \pi(\ol{T}) \doteq \pi(\ol{T'} ) \type{N} \lessdot \type{N'}, \type{N'} \lessdot \type{N}
\ol{T} \doteq \ol{T'}
} }
\end{array} \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} % \quad \begin{array}{l}
% \text{given a permutation}\ \pi\ \text{with:}\\ % \text{given a permutation}\ \pi\ \text{with:}\\
% \pi(\Delta) = \pi(\Delta') % \pi(\Delta) = \pi(\Delta')
% \end{array} % \end{array}
$ % $
\\\\ % \\\\
\rulename{Erase} \rulename{Erase}
& $ & $
\begin{array}[c]{l} \begin{array}[c]{l}
@ -262,9 +307,9 @@ $
\end{array} \end{array}
\quad \quad
\begin{array}[c]{l} \begin{array}[c]{l}
\wildcardEnv \vdash C \cup \set{\type{G} \doteq \wtv{a}}\\ \wildcardEnv \vdash C \cup \set{\type{T} \doteq \wtv{a}}\\
\hline \hline
\wildcardEnv \vdash C \cup \set{\wtv{a} \doteq \type{G}} \wildcardEnv \vdash C \cup \set{\wtv{a} \doteq \type{T}}
\end{array} \quad \end{array} \quad
\begin{array}[c]{l} \begin{array}[c]{l}
\wildcardEnv \vdash C \cup \set{\type{N} \doteq \rwildcard{A}}\\ \wildcardEnv \vdash C \cup \set{\type{N} \doteq \rwildcard{A}}\\
@ -389,7 +434,7 @@ Their upper and lower bounds are fresh type variables.
\end{array} \end{array}
%\quad \ol{Y} = \textit{fresh}(\ol{X}) %\quad \ol{Y} = \textit{fresh}(\ol{X})
\quad \begin{array}[c]{l} \quad \begin{array}[c]{l}
\text{fv}(\wctype{\Delta}{C}{\ol{S}}, \wctype{\Delta'}{C}{\ol{T}}) \subseteq \Delta_in \text{fv}(\wctype{\Delta}{C}{\ol{S}}, \wctype{\Delta'}{C}{\ol{T}}) \subseteq \Delta_{in}
\end{array} \end{array}
\end{array} \end{array}
$ $
@ -469,9 +514,16 @@ $\wctype{\ol{\rwildcard{A}}}{C}{\ol{\rwildcard{A}}}$.
Apply the rules depicted in the figures \ref{fig:normalizing-rules}, \ref{fig:reduce-rules} and \ref{fig:wildcard-rules} exhaustively. 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}. Starting with the \rulename{circle} rule. Afterwards the other rules in figure \ref{fig:normalizing-rules}.
\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. 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}) \cap \Delta_in \neq \emptyset$ $\implies$ fail! $\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}
The first step of the algorithm is able to remove wildcards. 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. Removing a wildcard works by setting its lower and upper bound to be equal.
@ -975,23 +1027,6 @@ Otherwise the generation rules \rulename{GenSigma} and \rulename{GenDelta} will
\end{array} \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} \rulename{GenSigma}
& $ & $
\deduction{ \deduction{
@ -1013,112 +1048,6 @@ Otherwise the generation rules \rulename{GenSigma} and \rulename{GenDelta} will
\label{fig:generation-rules} \label{fig:generation-rules}
\end{figure} \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}
\subsection{Capture Conversion during Unification} \subsection{Capture Conversion during Unification}
The \unify{} algorithm applies a capture conversion when needed. The \unify{} algorithm applies a capture conversion when needed.
A constraint of the form $\wcNtype{\Delta'}{N} \lessdot \type{T}$, A constraint of the form $\wcNtype{\Delta'}{N} \lessdot \type{T}$,