{v_1}{}\tstimes\tyof{v_1}{}$. Then we have $v\in t\iffdef\tyof
v{}\leq t$.
We also need to perform intersections of type schemes so as to intersect the static type of an expression (i.e., the one deduced by conventional rules) with the one deduced by occurrence typing (i.e., the one derived by $\vdashp$). For our algorithmic system (see \Rule{Env$_{\scriptscriptstyle\mathcal{A}}$} in Section~\ref{sec:algorules}) all we need to define is the intersection of a type scheme with a type:
\begin{lemma}[\cite{Frisch2008}]
Let $\ts$ be a type scheme and $t$ a type. We can compute a type scheme, written $t \tsand\ts$, such that
\(\tsint{t \tsand\ts}=\{s \alt\exists t' \in\tsint\ts.\ t \land t' \leq s \}\)
\end{lemma}
Finally, given a type scheme $\ts$ it is straightforward to choose in its interpretation a type $\tsrep\ts$ which serves as the canonical representative of the set (i.e., $\tsrep\ts\in\tsint\ts$):
\begin{definition}[Representative]
We define a function $\tsrep{\_}$ that maps every non-empty type scheme into a type, \textit{representative} of the set of types denoted by the scheme.\vspace{-2mm}
\begin{align*}
\begin{array}{lcllcl}
\tsrep t &=& t &\tsrep{\ts_1 \tstimes\ts_2}&=&\pair{\tsrep{\ts_1}}{\tsrep{\ts_2}}\\
\subsubsection{Operators for type constructors}\label{sec:typeops}
...
...
@@ -124,13 +60,13 @@ Finally, given a type scheme $\ts$ it is straightforward to choose in its interp
In order to define the algorithmic typing of expressions like
applications and projections we need to define the operators on
types we used in Section~\ref{sec:ideas}. Consider the rule \Rule{App} for applications. It essentially
does three things: $(1)$ it checks that the function has functional
type; $(2)$ it checks that the argument is in the domain of the
function, and $(3)$ it returns the type of the application. In systems
does three things: $(i)$ it checks that the function has functional
type; $(ii)$ it checks that the argument is in the domain of the
function, and $(iii)$ it returns the type of the application. In systems
without set-theoretic types these operations are quite
straightforward: $(1)$ corresponds to checking that the function has
an arrow type, $(2)$ corresponds to checking that the argument is in
the domain of the arrow deduced for the function and $(3)$ corresponds
straightforward: $(i)$ corresponds to checking that the function has
an arrow type, $(ii)$ corresponds to checking that the argument is in
the domain of the arrow deduced for the function, and $(iii)$ corresponds
to returning the codomain of that same arrow. With set-theoretic types
things get more difficult, since a function can be typed by, say, a
union of intersection of arrows and negations of types. Checking that
...
...
@@ -161,7 +97,7 @@ then we define:\vspace{-1.2mm}
\end{equation}
All the operators above but $\worra{}{}$ are already present in the
theory of semantic subtyping: the reader can find how to compute them
and how to extend their definition to type schemes in~\cite[Section
in~\cite[Section
6.11]{Frisch2008} (see also~\citep[\S4.4]{Cas15} for a detailed description). Below we just show the formula that computes
$\worra t s$ for a $t$ subtype of $\Empty\to\Any$. For that, we use a
result of semantic subtyping that states that every type $t$ is
...
...
@@ -188,33 +124,33 @@ Appendix~\ref{app:worra}.
\subsubsection{Type environments for occurrence typing}\label{sec:typenv}
The last step for our presentation is to define the algorithm for the
The second ingredient necessary to the definition of our algorithmic systems is the algorithm for the
deduction of $\Gamma\evdash e t \Gamma'$, that is an algorithm that
takes as input $\Gamma$, $e$, and $t$, and returns an environment that
extends $\Gamma$ with hypotheses on the occurrences of $e$ that are
the most general that can be deduced by assuming that $e\int$ succeeds. For that we need the notation $\tyof{e}{\Gamma}$ which denotes the type scheme deduced for $e$ under the type environment $\Gamma$ in the algorithmic type system of Section~\ref{sec:algorules}.
That is, $\tyof{e}{\Gamma}=\ts$ if and only if $\Gamma\vdashA e:\ts$ is provable.
the most general that can be deduced by assuming that $e\,{\in}\,t$ succeeds. For that we need the notation $\tyof{e}{\Gamma}$ which denotes the type deduced for $e$ under the type environment $\Gamma$ in the algorithmic type system of Section~\ref{sec:algorules}.
That is, $\tyof{e}{\Gamma}=t$ if and only if $\Gamma\vdashA e:t$ is provable.
We start by defining the algorithm for each single occurrence, that is for the deduction of $\pvdash\Gamma e t \varpi:t'$. This is obtained by defining two mutually recursive functions $\constrf$ and $\env{}{}$:\vspace{-1.3mm}
\env{\Gamma,e,t} (\varpi) & = &\tsrep{\constr\varpi{\Gamma,e,t}\tsand\tyof{\occ e \varpi}\Gamma}\label{otto}
\env{\Gamma,e,t} (\varpi) & = &{\constr\varpi{\Gamma,e,t}\wedge\tyof{\occ e \varpi}\Gamma}\label{otto}
\end{eqnarray}\vspace{-5mm}\\
All the functions above are defined if and only if the initial path
$\varpi$ is valid for $e$ (i.e., $\occ e{\varpi}$ is defined) and $e$
is well-typed (which implies that all $\tyof{\occ e{\varpi}}\Gamma$
in the definition are defined).\footnote{Note that the definition is
well-founded. This can be seen by analyzing the rule
\Rule{Case\Aa}: the definition of $\Refine{e,t}\Gamma$ and
\Rule{Case\Aa} of Section~\ref{sec:algorules}: the definition of $\Refine{e,t}\Gamma$ and
$\Refine{e,\neg t}\Gamma$ use $\tyof{\occ e{\varpi}}\Gamma$, and
this is defined for all $\varpi$ since the first premisses of
\Rule{Case\Aa} states that $\Gamma\vdash e:\ts_0$ (and this is
\Rule{Case\Aa} states that $\Gamma\vdash e:t_0$ (and this is
possible only if we were able to deduce under the hypothesis
$\Gamma$ the type of every occurrence of $e$.)\vspace{-3mm}}
...
...
@@ -275,6 +211,7 @@ not converge. As an example, consider the (dumb) expression $\tcase
$\Refinef$ yields for $x_1$ a type strictly more precise than the type deduced in the
previous iteration.
\beppe{REWRITE BELOW TILL THE END OF THE SUBSECTION TO STRESS SEMI-DECIDABILITY INSTEAD OF UNCOMPLETENESS}
The solution we adopt here is to bound the number of iterations to some number $n_o$.
From a formal point of view, this means to give up the completeness of the algorithm: $\Refinef$ will be complete (i.e., it will find all solutions) for the deductions of $\Gamma\evdash e t \Gamma'$ of depth at most $n_o$. This is obtained by the following definition of $\Refinef$\vspace{-1mm}
\[
...
...
@@ -330,8 +267,8 @@ We now have all the notions we need for our typing algorithm, which is defined b
{ x\in\dom\Gamma}
\vspace{-2mm}\\
\Infer[Env\Aa]
{\Gamma\setminus\{e\}\vdashA e : \ts}
{\Gamma\vdashA e: \Gamma(e) \tsand\ts}
{\Gamma\setminus\{e\}\vdashA e : t}
{\Gamma\vdashA e: \Gamma(e) \wedge t}
{\begin{array}{c}e\in\dom\Gamma\text{ and }\\[-1mm] e \text{ not a variable}\end{array}}
\qquad
\Infer[Const\Aa]
...
...
@@ -340,55 +277,56 @@ We now have all the notions we need for our typing algorithm, which is defined b