\chapter{Related Work}

This dissertation draws upon several large veins of research.  At the
highest level, this includes complexity, semantics, logic, and program
analysis.  This chapter surveys related work to sketch applications
and draw parallels with existing work.

\section{Monovariant Flow Analysis}

In the setting of first-order programming languages, \citet{reps-ai96}
gives a complexity investigation of program analyses and shows
interprocedural slicing to be complete for \ptime\ and that obtaining
``meet-over-all-valid-paths'' solutions of distributive data-flow
analysis problems \cite{hecht} is \ptime-hard in general, and
\ptime-complete when there are only a finite number of data-flow
facts.  A circuit-value construction by interprocedural data-flow
analysis is given using Boolean circuitry encoded as call graph
gadgets, similar in spirit to our constructions in
\autoref{chapter-0cfa}.

In the setting of higher-order programming languages,
\citet{melski-reps00} give a complexity investigation of 0CFA-like,
inclusion-based monovariant flow analysis for a functional language
with pattern matching.
%
The analysis takes the form of a constraint satisfaction problem and
this satisfaction problem is shown to be complete for \ptime.
%
See  \autoref{sec-context-free-lang-reach} for further discussion.

The impact of pattern matching on analysis complexity is further
examined by \citet{heintze-mcallester-icfp97}, which shows how deep
pattern matching affects monovariant analysis, making it complete for
\exptime.

\section{Linearity and Static Analysis}

% \subsection{Linearity and Flow analysis}

\citet{jagannathan-etal-popl98} observe that flow analysis, which is a
{\em may} analysis, can be adapted to answer {\em must} analysis
questions by incorporating a ``per-program-point {\em variable
  cardinality map}, which indicates whether all reachable environments
binding a variable $x$ hold the same value.  If so, $x$ is marked
single at that point; otherwise $x$ is marked multiple.''  The
resulting must-alias information facilities program optimization such
as lightweight closure conversion \cite{steckler-wand-toplas97}.  This
must analysis is a simple instance of tracking linearity information
in order to increase the precision of the analysis.
\citet{might-shivers-icfp06} use a similar approach of {\em abstract
  counting}, which distinguish singleton and non-singleton flow sets,
to improve flow analysis precision.

Something similar can be observed in 0CFA without cardinality maps;
singleton flow sets $\cache(\ell) = \{\lambda x.e\}$, which are
interpreted as ``the expression labelled $\ell$ {\em may} evaluate to
one of $\{ \lambda x.e \}$,'' convey {\em must} information.  The
expression labelled $\ell$ either diverges or evaluates to $\lambda
x.e$.  When $\lambda x.e$ is linearly closed---the variables map to
singleton sets containing linear closures---then the run-time value
produced by the expression labelled $\ell$ can be determined
completely at analysis time.  The idea of taking this special case of
{\em must} analysis within a {\em may} analysis to its logical
conclusion is the basis of \autoref{chapter-0cfa}.

\citet{damian-danvy-jfp03} have investigated the impact of linear
$\beta$-reduction on the result of flow analysis and show how
leastness is preserved.  The result is used to show that leastness is
preserved through CPS and administrative reductions, which are linear.

%\subsection{Linearity and Type analysis}

An old, but key, observation about the type inference problem for
simply typed $\lambda$-terms is that, when the term is linear (every
bound variable occurs exactly once), the most general type and normal
form are isomorphic
\cite{hindley-tcs89,hirokawa-tacs91,henglein-mairson-popl91,mairson-jfp04}.%
\footnote{The seed of inspiration for this work came from a close
  study of \citet{mairson-jfp04} in the Spring of 2005 for a seminar
  presentation given in a graduate course on advanced topics in
  complexity theory at the University of Vermont.}

The observation translates to flow analysis, as shown in
\autoref{chapter-0cfa}, but in a typed setting, it also scales to
richer systems.
%
The insight leads to an elegant reproof of the \exptime-hardness of
ML-type inference result from \citet{mairson-popl90}
\cite{henglein-unpub90}.
%
It was used to prove novel lower bounds on type inference for System
$F_\omega$ \cite{henglein-mairson-popl91} and rank-bound intersection
type inference \cite{neergaard-mairson-icfp04}.
%
See \autoref{sec-quantifier-elim} for further discussion.


\section{Context-Free-Language Reachability}
\label{sec-context-free-lang-reach}

\citet{melski-reps00} show the interconvertibility between a number of
set-constraint problems and the context-free-language (CFL)
reachability problem, which is known to be complete for \ptime\
\cite{ullman-allen-sfcs86}.  \citet{heintze-lfp94} develops a
set-based approach to flow analysis for a simple untyped functional
language with functions, applications, pattern-matching, and
recursion.  The analysis works by making a pass over the program,
generating set constraints, which can then be solved to compute flow
analysis results.  Following Melski and Reps, we refer to this
constraint system as ML set-constraints.  For the subset of the
language considered in this dissertation, solving these constraints
computes a monovariant flow analysis that coincides with 0CFA.

In addition to the many set-constraint problems considered, which have
applications to static analysis of first-order programming languages,
[section 5] \citet{melski-reps00} also investigate the problem of
solving the ML set-constraints used by Heintze.  They show this class
of set-constraint problems can be solved in cubic time with respect to
the size of the input constraints.  Since \citet{heintze-lfp94} gave a
$O(n^3)$ algorithm for solving these constraints, Melski and Reps'
result demonstrates the conversion to CFL-reachability preserves
cubic-solvability, while allowing CFL-reachability formulations of
static analyses, such as program slicing and shape analysis, to be
brought to bear on higher-order languages, where previously they had
only been applied in a first-order setting.

After showing ML set-constraints can be solved using CFL-reachability,
[section 6] \citet{melski-reps00} also prove the converse holds:
CFL-reachability problems can be solved by reduction to ML
set-constraint problems while preserving the worse-case asymptotic
complexity.  By the known \ptime-hardness of CFL-reachability, this
implies ML set-constraint satisfaction is \ptime-complete.  It does
not follow, however, that 0CFA is also \ptime-complete.

It is worth noting that Melski and Reps are concerned with constraint
satisfaction, and not directly with flow analysis---the two are
intimately related, but the distinction is important.  It follows as a
corollary that since ML set-constraints can be solved, through a
reduction to CFL-reachability, flow analysis can be performed in cubic
time.  [page 314] \citet{heintze-lfp94} observes that the size of the
set-constraint problem generated by the initial pass of the program is
linear in the size of the program being analyzed.  Therefore it is
straightforward to derive from the ML set-constraint to
CFL-reachability reduction the (known) inclusion of 0CFA in \ptime.

In the other direction, it is not clear that it follows from the
\ptime-hardness of ML set-constraint satisfaction that flow analysis
of Heintze's subject language is \ptime-hard.  Melski and Reps use the
constraint language directly in their encoding of CFL-reachability.
What remains to be seen is whether there are programs which could be
constructed that would induce these constraints.  Moreover, their
reduction relies soley on the ``case'' constraints of Heintze, which
are set constraints induced by pattern matching expressions in the
source language.

If the source language lacks pattern matching, the Boolean circuit
machinery of Melski and Reps can no longer be constructed since no
expressions induce the needed ``case'' constraints.  For this
language, the \ptime-hardness of constraint satisfaction and 0CFA does
not follow from the results of Melski and Reps.

This reiterates the importance of Reps' own observation that analysis
problems should be formulated in ``trimmed-down form,'' which both
leads to a wider applicability of the lower bounds and ``allows one to
gain greater insight into exactly what aspects of an [\dots] analysis
problem introduce what computational limitations on algorithms for
these problems,'' [section 2] \cite{reps-ai96}.

By considering only the core subset of every higher-order programming
language and relying on the specification of analysis, rather than its
implementation technology, the 0CFA \ptime-completeness result implies
as an immediate corollary the \ptime-completeness of the ML
set-constraint problem considered by Melski and Reps.  Moreover, as we
have seen, our proof technique of using linearity to subvert
approximation is broadly applicable to further analysis
approximations, whereas CFL-reachability reductions must be replayed
{\em mutatis mutandis}.

%\section{Two-way non-deterministic pushdown automata}
\section{2NPDA and the Cubic Bottleneck}
\label{sec-2npda}

The class \twonpda\ contains all languages that are recognizable by a
two-way non-deterministic push-down automaton.\footnote{This section
  is derived from material in \citet{midtgaard-vanhorn-tr09}.}
%
The familiar PDAs found in undergraduate textbooks~\cite{martin-97},
both deterministic and non-deterministic, are one-way: consuming their
input from left-to-right.
%
In contrast, two-way NPDAs accept their input on a read-only input
tape marked with special begin and end markers, on which they can move
the read-head forwards, backwards, or not at all.

Over a decade ago, \citet{heintze-mcallester-lics97} proved deciding a
monovariant flow analysis problem to be at least as hard as \twonpda,
and argued this provided evidence the ``cubic bottleneck'' of flow
analysis was unlikely to be overcome since the best known algorithm
for \twonpda\ was cubic and had not been improved since its
formulation by \citet{aho-hopcroft-ullman-ic68}.
%
This statement was made by several other %subsequent followup
papers~\cite{neal-89,heintze-mcallester-lics97,heintze-mcallester-pldi97,
%McAllester:SAS99,
  melski-reps00,mcallester-jacm02,vanhorn-mairson-sas08}.
%
Yet collectively, this is simply an oversight in the history of
events; \citet{rytter-ic85} improved the cubic bound by a logarithmic
factor.

Since then, Rytter's technique has been used in various contexts: in
diameter verification, in Boolean matrix multiplication, and for the
all pairs shortest paths
problem~\cite{basch-etal-95,zwick-alg06,chan-stoc07}, as
well as for reachability in recursive state
machines~\cite{chaudhuri-popl08},
%
and for maximum node-weighted $k$-clique~\cite{vassilevska-ipl09} to name
a few.
%
In particular, \citet{chaudhuri-popl08} recently used Rytter's
techniques to formulate a subcubic algorithm for the related problem
of context-free language (CFL) reachability.
%
Perhaps unknown to most, indirectly this constitutes the first
subcubic inclusion-based flow analysis algorithm when combined with a
reduction due to \citet{melski-reps00}.

The logarithmic improvement can be carried over to the flow analysis
problem directly, by applying the same known set compression
techniques \citet{rytter-ic85} applies to improve deciding \twonpda.
Moreover, refined analyses similar to
\citet{heintze-mcallester-icfp97} that incorporate notions of
reachability to improve precision remain subcubic.  See
\citet{midtgaard-vanhorn-tr09} for details.

0CFA is complete for both \twonpda\ \cite{heintze-mcallester-lics97} and
\ptime\ (\autoref{chapter-0cfa}).  Yet, it is not clear what relation
these class have to each other.

The \twonpda\ inclusion proof of Heintze and McAllester is sensitive to
representation choices and problem formulations. They use an encoding
of programs that requires a non-standard bit string labelling scheme
in which identical subterms have the same labels. The authors remark
that without this labelling scheme, the problem ``appears not to be in
\twonpda.'' 

Moreover, the notions of reduction employed in the definitions of
\twonpda-hardness and \ptime-hardness rely on different computational
models.  For a problem to be \twonpda-hard, all problems in the class
must be reducible to it in $O(nR(\log n))$ time on a RAM, where $R$ is
a polynomial. Whereas for a problem to be \ptime-hard, all problems in
the class must be reducible to it using a $O(\log n)$ space work-tape
on a Turing machine.

\section{\kcfa}
\label{sec-rel-kcfa}

Our coding of Turing machines is descended from work on Datalog
(Prolog with variables, but without constants or function symbols), a
programming language that was of considerable interest to researchers
in database theory during the 1980s; see \citet{hkmv,gmsv}.

In $k$CFA and abstract interpretation more generally, an expression
can evaluate to a set of values from a finite universe, clearly motivating
the idiom of programming with sets.  Relational database queries
take as input a finite set of tuples, and compute new tuples from
them; since the universe of tuples is finite and the computation is
monotone, a fixed-point is reached in a finite number of iterations.  The
machine simulation here follows that framework very closely.  Even the
idea of splitting a machine configuration among many tuples has its
ancestor in \citet{hkmv}, where a ternary ${\tt cons}(A,L,R)$ is used
to simulate a {\tt cons}-cell at memory address $A$, with pointers
$L,R$.  It needs emphasis that the computing with sets described in
this paper has little to do with normalization, and everything to do
with the approximation inherent in the abstract interpretation.

Although $k$CFA and ML-type inference are two static analyses complete
for \exptime\ \cite{mairson-popl90}, the proofs of these respective
theorems is fundamentally different.  The ML proof relies on type
inference simulating exact normalization (analogous to the
\ptime-completeness proof for 0CFA), hence subverting the approximation
of the analysis.  In contrast, the $k$CFA proof harnesses the
approximation that results from nonlinearity.

\section{Class Analysis}

Flow analysis of functional languages is complicated by the fact that
{\em computations are expressible values}.
%
This makes basic questions about control flow undecidable in the
general case.
%
But the same is true in object-oriented programs---computations may be
package up as values, passed as arguments, stored in data-structures,
etc.---and so program analyses in object-oriented settings often deal
with the same issues as flow analysis. 
%
A close analogue of flow analysis is {\em class analysis}.

Expressions in object-oriented languages may have a declared class (or
type) but, at run-time, they can evaluate to objects of every subclass
of the class.
%
Class analysis computes the actual set of classes that an expression
can have at run-time \cite{johnson-etal-oopsla88,
  chambers-ungar-pldi90, palsberg-schwartzbach-oopsla91,
  bacon-sweeney-oopsla96}.
%
Class analysis is sometimes called receiver class analysis, type
analysis, or concrete type inference; it informs static method
resolution, inlining, and other program optimizations.

An object-oriented language is higher-order in the same way as a
language with first-class functions and exactly the same circularity
noted by Shivers occurs in the class analysis of an object-oriented
language.

\citet{grove-chambers-toplas01}:
\begin{quote}
  In object-oriented languages, the method invoked by a dynamically
  dispatched message send depends on the class of the object receiving
  the message; in languages with function values, the procedure
  invoked by the application of a computed function value is
  determined by the function value itself. In general, determining the
  flow of values needed to build a useful call graph requires an
  interprocedural data and control flow analysis of the program. But
  interprocedural analysis in turn requires that a call graph be built
  prior to the analysis being performed.
\end{quote}

Ten years earlier, [page 6] \citet{shivers-phd}%
%% It never hurts to kiss a committee member's ass a bit.  Especially
%% when the praise is true.
\footnote{It is a testament to Shivers' power as a writer that his
  original story has been told over and over again in so many places,
  usually with half the style.} had written essentially the same:
\begin{quote}
  So, if we wish to have a control-flow graph for a piece of Scheme
  code, we need to answer the following question: for every procedure
  call in the program, what are the possible lambda expressions that
  call could be a jump to? But this is a flow analysis question! So
  with regard to flow analysis in an HOL, we are faced with the
  following unfortunate situation:
\begin{itemize}
\item In order to do flow analysis, we need a control-flow graph. 
\item In order to determine control-flow graphs, we need to do flow analysis.
\end{itemize}
\end{quote}


Class analysis is often presented using the terminology of type
inference, however these type systems typically more closely resemble
flow analysis: types are finite sets of classes appearing
syntactically in the program and subtyping is interpreted as set
inclusion.

In other words, objects are treated much like functions in the flow
analysis of a functional language---typically both are approximated by
a set of definition sites, i.e. an object is approximated by a set of
class names that appear in the program; a function is approximated by
a set of $\lambda$ occurrences that appear in the program.  In an
object-oriented program, we may ask of a subexpression, what classes
may the subexpression evaluate to?  In a functional language we may
ask, what $\lambda$ terms may this expression evaluate to?  Notice
both are general questions that analysis must answer in a higher order
setting if you want to know about control flow.  To know where control
may transfer to from $(f\;x)$ we have to know what $f$ may be.  To
know where control may transfer to from \verb|f.apply(x)| we have to
know what \verb|f| may be.  In both cases, if we approximate functions
by sets of $\lambda$s and objects by sets of class names, we may
determine a set of possible places in code where control may transfer,
but we will not know about the {\em environment} of this code,
i.e. the environment component of a closure or the record component of
an object.





\citet{spoto-jensen-toplas03} give a reformulation of several class
analyses, including that of \citet{palsberg-schwartzbach-oopsla91,
  bacon-sweeney-oopsla96, diwan-etal-oopsla96}, using abstract
interpretation.

\citet{defouw-etal-popl98} presents a number of variations on the
theme of monovariant class analysis.  They develop a framework that
can be instantiated to obtain inclusion, equality, and optimistic
based class analyses with close analogies to 0CFA, simple closure
analysis, and rapid type analysis \cite{bacon-sweeney-oopsla96},
respectively.
%
Each of these instantiations enjoy the same asymptotic running times
as their functional language counterparts; cubic, near linear, and
linear, respectively.

Although some papers give upper bounds for the algorithms they
present, there are very few lower bound results in the
literature.\footnote{I was able to find zero papers that deal directly
  with lower bounds on class analysis complexity.}

Class analysis is closely related to {\em points-to} analysis in
object-oriented languages.
%
``{\em Points-to analysis} is a fundamental static analysis used by
optimizing compilers and software engineering tools to determine the
set of objects whose addresses may be stored in reference variables
and reference fields of objects,'' \cite{milanova-etal-tosem05}.
%
When a points-to analysis is {\em flow-sensitive}---``analyses take
into account the flow of control between program points inside a
method, and compute separate solutions for these points,''
\cite{milanova-etal-tosem05}---the analysis necessarily involves some
kind of class analysis.

% Interprocedural ``class'' analysis.  (??)

In object-oriented languages, context-sensitive is typically
distinguished as being object-sensitive \cite{milanova-etal-tosem05},
call-site sensitive \cite{grove-chambers-toplas01}, or partially flow
sensitivity \cite{rinetzky-etal-toplas08}.

\citet{grove-chambers-toplas01} provide a framework for a functional
and object-oriented hybrid language that can be instantiated to obtain
a $k$CFA analysis and an object-oriented analogue called {\em
  $k$-$l$-CFA}.  There is a discussion and references in Section
9.1.
%
In this discussion, \citet{grove-chambers-toplas01} cite
\citet{oxhoj-etal-ecoop92} as giving ``1-CFA extension to Palsberg and
Schwartzbach's algorithm,'' although the paper develops the analysis
as a type inference problem.
  % 
Grove and Chambers also cite \citet{vitek-etal-cc92} as one of several
``adaptations of $k$CFA to object-oriented programs,'' and although
this paper actually has analogies to $k$CFA in an object-oriented
setting (they give a call-string approach to call graph context
sensitivity in section 7), it seems to be developed completely
independently of Shivers' $k$CFA work or any functional flow analysis
work.  

% The paper presented a parameterized framework much in the
% spirit of \citet{nielson-nielson-popl97}.
%, which is abstracted over 3 sets\dots

\begin{figure}
{\small
\begin{verbatim}
new Fun<Fun<B,List<B>>,List<B>>() {
 public List<B> apply(Fun<B,List<B>> f1) {
   f1.apply(true);
   return f1.apply(false);
 }
}.apply(new Fun<B,List<B>>() {
  public List<B> apply(final B x1) {
    return
      new Fun<Fun<B,List<B>>,List<B>>() {
       public List<B> apply(Fun<B,List<B>> f2) {
         f2.apply(true);
         return f2.apply(false);
       }
      }.apply(new Fun<B,List<B>>() {
        public List<B> apply(final B x2) {
          return
            ...
            new Fun<Fun<B,List<B>>,List<B>>() {
             public List<B> apply(Fun<B,List<B>> fn) {
               fn.apply(true);
               return fn.apply(false);
             }
            }.apply(new Fun<B,List<B>>() {
              public List<B> apply(final B xn) {
                return
                  new List<B>{x1,x2,...xn};}}
\end{verbatim}}
  \caption{Translation of $k$CFA \exptime-construction into an
    object-oriented language.}
  \label{fig-kcfa-java-construction}
\end{figure}

The construction of \autoref{fig-kcfa-construction} can be translated
in an object-oriented language such as Java, as given in
\autoref{fig-kcfa-java-construction}.\footnote{This translation is
  Java except for the made up list constructor and some abbreviation
  in type names for brevity, i.e.~{\tt B} is shorthand for {\tt
    Boolean}.}  Functions are simulated as objects with an apply
method.  The crucial subterm in \autoref{fig-kcfa-java-construction}
is the construction of the list \verb|{x1,x2,..xn}|, where
\verb|x|$_i$ occur free with the context of the innermost ``lambda''
term, \verb|new Fun() {...}|. To be truly faithful to the original
construction, lists would be Church-encoded, and thus represented with
a function of one argument, which is applied to \verb|x1| through
\verb|xn|.  An analysis with a similar context abstraction to 1CFA
will approximate the term representing the list \verb|x1,x2,...,xn|
with an abstract object that includes 1 bit of context information for
each {\em instance variable}, and thus there would be $2^n$ values
flowing from this program point, one for each mapping \verb|x|$_i$ to
the calling context in which it was bound to either true or false for
all possible combinations.  \citet{grove-chambers-toplas01} develop a
framework for call-graph construction which can be instantiated in the
style of 1CFA and the construction above should be adaptable to show
this instantiation is \exptime-hard.

% \cite{milanova-etal-tosem05} has notes about the ``functional approach
% to context sensitivity'' vs. call chain context sensitivity, which are
% incomparable in terms of precision, Sharir and Pnueli 81.

% ``makes feasible the most precise context-sensitive analyses reported
% in the literature.''
% \cite{bravenboer-smaragdakis-oopsla09}.

A related question is whether the insights about linearity can be
carried over to the setting of pointer analysis in a first-order
language to obtain simple proofs of lower bounds.  If so, is it
possible higher-order constructions can be transformed systematically
to obtain first-order constructions?

Type hierarchy analysis is a kind of class analysis particularly
relevant to the discussion in \autoref{sec:approach} and the broader
applicability of the approach to proving lower bounds employed in
\autoref{chapter-0cfa}.  Type hierarchy analysis is an analysis of
statically typed object-oriented languages that bounds the set of
procedures a method invocation may call by examining the type
hierarchy declarations for method overrides.
%
``Type hierarchy analysis does not examine what the program actually
does, just its type and method declarations,''
\cite{diwan-etal-oopsla96}.
%
It seems unlikely that the technique of \autoref{sec:approach} can be
applied to prove lower bounds about this analysis since it has nothing
to do with approximating evaluation.

\section{Pointer Analysis}
\label{sec-pointer-analysis}

Just as flow analysis plays a fundamental role in the analysis of
higher-order functional programs, {\em pointer analysis}\footnote{Also
  known as {\em alias} and {\em points-to} analysis.} plays a
fundamental role in imperative languages with pointers
\cite{landi-phd92} and object-oriented languages, and informs later
program analyses such as live variables, available expressions, and
constant propagation.  Moreover, flow and alias analysis variants are
often developed along the same axes and have natural analogues with
each other.  

For example, Henglein's \shortcite{henglein92d} simple closure
analysis and Steensgaard's \shortcite{steensgaard-popl96} points-to
analysis are natural analogues.  Both operate in near linear time by
relying on equality-based (rather than inclusion-based) set
constraints, which can be implemented using a union-find
data-structure.  Steensgaard algorithm ``is inspired by Henglein's
\shortcite{henglein-fplca91} binding time analysis by type
inference,'' which also forms the conceptual basis for
\citet{henglein92d}.  Palsberg's \shortcite{palsberg-toplas95} and
Heintze's \shortcite{heintze-lfp94} constraint-based flow analysis
and Andersen's \shortcite{andersen-phd94} pointer analysis are
similarly analogous and bear a strong resemblance in their use of
subset constraints.


To get a full sense of the correspondence between pointer analysis and
flow analysis, read their respective surveys in parallel
\cite{hind-paste01,midtgaard-07}.  These comprise major, mostly
independent, lines of research.  Given the numerous analogies, it is
natural to wonder what the pointer analysis parallels are to the
results presented in this dissertation.  The landscape of the pointer
analysis literature is much like that of flow analysis; there are
hundreds of papers; similar, over-loaded, and abused terminology is
frequently used; it concerns a huge variety of tools, frameworks,
notations, proof techniques, implementation techniques, etc.  Without
delving into too much detail, we recall some of the fundamental
concepts of pointer analysis, cite relevant results, and try to more
fully develop the analogies between flow analysis and pointer
analysis.

A pointer analysis attempts to statically determine the possible
run-time values of a pointer.  Given a program and two variables $p$
and $q$, points-to analysis determines if $p$ can point to $q$
\cite{chakaravarthy-popl03}.  It is clear that in general, like all
interesting properties of programs, it is not decidable if $p$ can
point $q$.  A traditional assumption in this community is that all
paths in the program are executable.  However, even under this
conservative assumption, the problem is undecidable.  The history of
pointer analysis can be understood largely in terms of the trade-offs
between complexity and precision.

% There are two kinds of aliasing \cite{landi-loplas92}:
% \begin{itemize}
% \item {\em may alias} occur during some execution of the program
% \item {\em must alias} occur during all executions of the program
% \end{itemize}

Analyses are characterized along several dimensions
\cite{hind-paste01}, but of particular relevance are those of:
\begin{itemize}
\item {\em Equality-based}: assignment is treated as an undirected
  flow of values.
\item {\em Subset-based}: assignment is treated as a directed flow of values.

\item {\em Flow sensitivity}

  A points-to analysis is {\em flow-sensitive} analysis if it is given
  the control flow graph for the analyzed program.  The control flow
  graphs informs the paths considered when determining the points-to
  relation.  A {\em flow-insensitive} analysis is not given the
  control flow graph and it is assumed statements can be executed in
  any order.  See also section 4.4 of \citet{hind-paste01} and section
  2.3 of \citet{rinetzky-etal-toplas08}.

\item {\em Context sensitivity}

calling context is considered when
  analyzing a function so that calls return to their caller.
See also section 4.4 of \cite{hind-paste01}.

\citet{bravenboer-smaragdakis-oopsla09} remark:
\begin{quote}
  In full context-sensitive pointer analysis, there is an ongoing
  search for context abstractions that provide precise pointer
  information, and do not cause massive redundant
  computation.\footnote{That search has been reflected in the
    functional community as well, see for example, \citet{shivers-phd,
      jagannathan-weeks-popl95, banerjee-icfp97, faxen-lomaps97,
      nielson-nielson-popl97, sereni-icfp07, ashley-dybvig-toplas98,
      wright-jagannathan-toplas98, might-shivers-popl06, might-phd}.}
\end{quote}
\end{itemize}

The complexity of pointer analysis has been deeply studied
\cite{meyers-popl81, landi-ryder-popl91, landi-phd92, landi-loplas92,
  choi-etal-popl93,
  ramalingam-toplas94, % a re-proof of \cite{landi-loplas92}.
  horwitz-toplas97, muth-debray-popl00, chaterjee-etal-tse01,
  chakaravarthy-horwitz-ai02, chakaravarthy-popl03,
  rinetzky-etal-toplas08}.

Flow sensitive points-to analysis with dynamic memory is not decidable
\cite{landi-loplas92,ramalingam-toplas94,chakaravarthy-popl03}.  Flow
sensitive points-to analysis without dynamic memory is \pspace-hard
\cite{landi-phd92,muth-debray-popl00}, even when pointers are
well-typed and restricted to only two levels of dereferencing
\cite{chakaravarthy-popl03}.  
%
Context-sensitive pointer analysis can
be done efficiently in practice
\cite{emami-etal-pldi94,wilson-lam-pldi95}.  
%
Flow and context-sensitive points-to analysis for Java can be
efficient and practical even for large programs
\cite{milanova-etal-tosem05}.  

See \citet{muth-debray-popl00,chakaravarthy-popl03} for succinct
overview of complexity results and open problems.



\section{Logic Programming}

\citet{mcallester-jacm02} argues ``bottom-up logic program
presentations are clearer and simpler to analyze, for both correctness
and {\em complexity}'' and provides theorems for characterizing their
run-time.  McAllester argues bottom-up logic programming is especially
appropriate for static analysis algorithms.  The paper gives a
bottom-up logic presentation of evaluation (Fig. 4) and flow analysis
(Fig 5.) for the $\lambda$-calculus with pairing and uses the run-time
theorem to derive a cubic upper bound for the analysis.

Recent work by \citet{bravenboer-smaragdakis-oopsla09} demonstrates
how Datalog can be used to specify and efficiently implement pointer
analysis.  
%
By the \ptime-completeness of Datalog, any analysis that can be
specified is included in \ptime.

This bears a connection to the implicit computational complexity
program, which has sought to develop syntactic means of developing
programming languages that capture some complexity class
\cite{hofmann-hab98,leivant-popl93,hofmann-ic03,kristiansen-tcs04}.
Although this community has focused on general purpose programming
languages---with only limited success in producing usable systems---it
seems that restricting the domain of interest to program analyzers may
be a fruitful line of work to investigate.

The \exptime\ construction of \autoref{sec-kcfa-exptime-hard} has a
conceptual basis in Datalog complexity research \cite{hkmv,gmsv}.
See \autoref{sec-rel-kcfa} for a discussion.

\section{Termination Analysis}

Termination analysis of higher-order programs \cite{jones-bohr-lmcs08,
  sereni-jones-aplas05, giesl-etal-rta06, sereni-icfp07} is inherently
tied to some underlying flow analysis.

Recent work by Sereni and Jones on the termination analysis of
higher-order languages has relied on an initial control flow analysis
of a program, the result of which becomes input to the termination
analyzer \cite{sereni-jones-aplas05,sereni-icfp07}.  Once a call-graph
is constructed, the so-called ``size-change'' principle\footnote{The
  size-change principle has enjoyed a complexity investigation in its
  own right \cite{lee-etal-popl01, ben-amram-etal-toplas07}.} can be
used to show that there is no infinite path of decreasing size through
through the program's control graph, and therefore the program
eventually produces an answer.  This work has noted the inadequacies
of 0CFA for producing precise enough graphs for proving most
interesting programs terminating.  Motivated by more powerful
termination analyses, these researchers have designed more powerful
(i.e., more precise) control flow analyses, dubbed $k$-limited CFA.
These analyses are parametrized by a fixed bound on the depth of
environments, like Shivers' $k$CFA. So for example, in 1-limited CFA,
each variable is mapped to the program point in which it is bound, but
no information is retained about this value's environment.  But unlike
$k$CFA, this ``limited'' analysis is not polyvariant
(context-sensitive) with respect to the most recent $k$ calling
contexts.

A lesson of our investigation into the complexity of $k$CFA is that it
is {\em not} the polyvariance that makes the analysis difficult to
compute, but rather the environments.  Sereni notes that the
$k$-limited CFA hierarchy ``present[s] different characteristics, in
particular in the aspects of precision and complexity''
\cite{sereni-icfp07}, however no complexity characterization is given.

\section{Type Inference and Quantifier Elimination}
\label{sec-quantifier-elim}

Earlier work on the complexity of compile-time type inference is a
precursor of the research insights described here, and naturally so,
since type inference is a kind of static analysis
\cite{mairson-popl90,henglein-unpub90,henglein-mairson-popl91,mairson-jfp04}.
The decidability of type inference depends on the making of
approximations, necessarily rejecting programs without type errors; in
simply-typed $\lambda$-calculus, for instance, all occurrences of a
variable must have the same type.  (The same is, in effect, also true
for ML, modulo the finite development implicit in {\tt let}-bindings.)
The type constraints on these multiple occurrences are solved by
first-order unification.

As a consequence, we can understand the inherent complexity of type
inference by analyzing the expressive power of {\em linear} terms,
where no such constraints exist, since linear terms are always
simply-typable.  In these cases, type inference is synonymous with
normalization.\footnote{An aberrant case of this phenomenon is
  examined by \citet{neergaard-mairson-icfp04}, which analyzed a type
  system where normalization and type inference are synonymous in {\em
    every} case.  The tractability of type inference thus implied a
  certain inexpressiveness of the language.}  This observation
motivates the analysis of type inference described by
\citet{mairson-popl90, mairson-jfp04}.

Compared to flow analysis, type reconstruction has enjoyed a much more
thorough complexity analysis.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

A key observation about the type inference problem for simply typed
$\lambda$-terms is that, when the term is linear (every bound variable
occurs exactly once), the most general type and normal form are
isomorphic
\cite{hindley-tcs89,hirokawa-tacs91,henglein-mairson-popl91,mairson-jfp04}. So
given a linear term in normal form, we can construct its most general
type (no surprise there), but conversely, when given a most general
type, we can construct the normal form of all terms with that type.

This insight becomes the key ingredient in proving the lower bound
complexity of simple-type inference---when the program is linear,
static analysis is effectively ``running'' the program.  Lower bounds,
then, can be obtained by simply hacking within the linear
$\lambda$-calculus.

\begin{quote}%
{\bf Aside:} 
The normal form of a linear program can be ``read back'' from its most
general type in the following way: given a type
$\sigma_1\rightarrow\sigma_2\rightarrow \dots \rightarrow \sigma_k
\rightarrow \alpha$, where $\alpha$ is a type variable, we can
conclude the normal form has the shape $\lambda x_1.\lambda x_2.\dots
\lambda x_k.e$.
%
Since the term is linear, and the type is most general, every type
variable occurs exactly twice: once positively and once negatively.
%
Furthermore, there exists a
unique $\sigma_i \equiv \tau_1\rightarrow\tau_2\rightarrow \dots
\rightarrow \tau_m \rightarrow \alpha$, so $x_i$ must be the head
variable of the normal form, i.e., we now know: $\lambda x_1.\lambda
x_2.\dots \lambda x_k.x_1e'$, and $x_i$ is applied to $m$ arguments,
each with type $\tau_1,\dots,\tau_m$, respectively. 
%
But now, by induction, we can recursively construct the normal forms
of the arguments.  The base case occurs when we get to a base type (a
type variable); here the term is just the occurrence of the
$\lambda$-bound variable that has this (unique) type.  In other words,
a negative type-variable occurrence marks a $\lambda$-binding, while
the corresponding positive type-variable occurrence marks the single
occurrence of the bound variable.  The rest of the term structure is
determined in a syntax-directed way by the arrow structure of the
type.
\end{quote}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


It has been known for a long time that type reconstruction for the
simply typed $\lambda$-calculus is decidable
\cite{curry-dialectica69,hindley-ams69}, i.e.~it is decidable whether
a term of the untyped $\lambda$-calculus is the image under
type-erasing of a term of the simply typed
$\lambda$-calculus.\footnote{See \citet{tiuryn-mfcs90} for a survey of
  type inference problems, cited in \citet{cardone-hindley-06}.}
\citet{wand-fi87} gave the first direct reduction to the unification
problem
\cite{herbrand,robinson-jacm65,dwork-et-al-jlp84,kanellakis-etal-robinson}.
%
\citet{henglein-fplca91,henglein92d} used unification to develop
efficient type inference for binding time analysis and flow analysis,
respectively.  This work directly inspired the widely influential
\citet{steensgaard-popl96} algorithm.\footnote{See
  \autoref{sec-pointer-analysis} for more on the relation of pointer
  analysis and flow analysis.}

A lower bound on the complexity of type inference can often be
leveraged by the combinatorial power behind a quantifier elimination
procedure \cite{mairson-jfp92}.  These procedures are syntactic
transformations that map programs into potentially larger programs
that can been typed in a simpler, quantifier-free setting.

As an example, consider the case of ML polymorphism.  The universal
quantification introduced by {\tt let}-bound values can be eliminated
by reducing all {\tt let}-redexes.  The residual program is
simply-typable if, and only if, the original program is ML-typable.

This is embodied in the following inference rule:\footnote{In the
  survey, {\em Type systems for programming languages},
  \citet{mitchell-volb} attributes this observation to Albert Meyer.
  [page~122] \citet{henglein-mairson-popl91} point out in a footnote that
  it also appears in the thesis of \citet{damas-phd}, and is the
  subject of a question on the 1985 postgraduate examination in
  computing at Edinburgh University.}
\begin{displaymath}
\inferrule{\Gamma \vdash M : \tau_0\\ \Gamma \vdash [M/x]N:\tau_1}
          {\Gamma \vdash \mbox{\tt{let} } x = M \mbox{ \tt{in} } N:\tau_1}
\end{displaymath}

The residual may be exponentially larger due to nested {\tt let}
expressions that must all be eliminated.  From a Curry-Howard
perspective, this can be seen as a form of cut-elimination.  From a
computational perspective, this can be seen as a bounded running of
the program at compile time.  From a software engineering perspective,
this can be seen as code-reuse---the ML-type inference problem has
been reduced to the simple-type inference problem, and thus to
first-order unification.  But the price is that an exponential amount
of work may now be required.

Full polymorphism is undecidable, but ML offers a limit form of
outermost universal quantification.  But this restriction relegates
polymorphic functions to a second-class citizenship, so in particular,
functions passed as arguments to functions (a staple of higher-order
programming) can only be used monomorphically.

Intersection types restore first-class polymorphism by offering a
finite form of explicit quantification over simple types.  The type
$\tau_1 \wedge \tau_2$ is used for a term that is typable as both
$\tau_1$ and $\tau_2$.  This can formalized as the following inference
rule for $\wedge$:\footnote{This presentation closely follows the
  informal presentation of intersection types in Chapter 4 of
  \citet{neergaard-phd}.}
\begin{displaymath}
\inferrule{\Gamma_1 \vdash M:\tau_1\\ \Gamma_2 \vdash M:\tau_2}
          {\Gamma_1 \wedge \Gamma_2 \vdash M:\tau_1\wedge\tau_2}
\end{displaymath}
where $\wedge$ is lifted to environments in a straightforward way.
Notice that this allows expressions such as,
\begin{displaymath}
(\lambda f.\lambda z.z(f\; 2)(f\; \mathbf{false}))\;(\lambda x.x),
\end{displaymath}
to be typed where $x$ has type $\mathbf{int} \wedge \mathbf{bool}$.

The inference rule, as stated, breaks syntax-directed inference.
\citet{vanbakel-tcs92} observed that by limiting the rule to the
arguments of function application, syntax-direction can be recovered
without changing the set of typable terms (although some terms will
have fewer typings).  Such systems are called {\em strict
  intersections} since the $\wedge$ can occur only on the left of a
function type.

The finite $\wedge$-quantifiers of strict intersections too have an
elimination procedure, which can be understood as a program
transformation that eliminates $\wedge$-quant\-ification by {\em rank}.
A type is rank $r$ if there are no occurrences of $\wedge$ to the left
of $r$ occurrences of an arrow.  The highest rank intersections
can be eliminated by performing a {\em minimal complete development}.

Every strongly normalizing term has an intersection type, so type
inference in general is undecidable.  However, decidable fragments can
be regained by a standard approach of applying a {\em
  rank} restriction, limiting the depth of $\wedge$ to the left of a
function type.  

By bounding the rank, inference becomes decidable; if the rank is
bound at $k$, $k$ developments suffice to eliminate all intersections.
The residual program is simply-typable if, and only if, the original
program is rank-$k$ intersection typable.  Since each development can
cause the program to grow by an exponential factor, iteratively
performing $k$-MCD's results in an elementary lower bound
\cite{kfoury-etal-icfp99,neergaard-mairson-icfp04}.

The special case of rank-2 intersection types have proved to be an
important case with applications to modular flow analysis, dead-code
elimination, and typing polymorphic recursion, local definitions,
conditionals and pattern matching \cite{damiani-prost-types96,
  damiani-toplas03, banerjee-jensen-mscs03, damiani-fi07}.

% ``Quadratic bound'' on ML-type reconstruction \cite{leivant-popl83}.

% ML: \citet{mitchell-89}.  \citet{kanellakis-mitchell-popl89} observed
% that {\tt let} can be used to compose functions an exponential number
% of times with a polynomial-length formula.  \cite{mairson-popl90}.
% \cite{kanellakis-mairson-mitchell-90}. \cite{henglein-unpub90}.
% \cite{henglein-mairson-popl91}.

System F, the polymorphic typed $\lambda$-calculus
\cite{reynolds-pcp74,girard-proofs-and-types}, has an undecidable
Curry-style inference problem \cite{wells-apal99}.  Partial inference
in a Church-style system is investigated by
\citet{boehm-sfcs85,pfenning-fi93} and Pfenning's result shows even
partial inference for a simple predicative fragment is undecidable.

The quantifier-elimination approach to proving lower bounds was
extended to System F$_\omega$ by \citet{henglein-mairson-popl91}.
They prove a sequence of lower bounds on recognizing the System
F$_k$-typable terms, where the bound for F$_{k+1}$ is exponentially
larger than that for F$_k$.  This is analogous to intersection
quantifier elimination via complete developments at the term level.
The essence of \citet{henglein-mairson-popl91} is to compute
developments at the kind level to shift from System F$_{k+1}$ to
System F$_k$ typability.  This technique led to lower bounds on
System F$_i$ and the non-elementary bound on System F$_\omega$
\cite{henglein-mairson-popl91}.  \citet{urzyczyn-mscs97} showed
Curry-style inference for System F$_\omega$ is undecidable.

There are some interesting open complexity problems in the realm of
type inference and quantifier elimination.  Bounded polymorphic
recursion has recently been investigated \cite{comini-etal-sas08}, and
is decidable but with unknown complexity bounds, nor quantifier
elimination procedures.
%
Typed Scheme \cite{tobin-hochstadt-felleisen-popl08}, uses explicit
annotations, but with partial inference and flow sensitivity.  It
includes intersection rules for function types.  Complexity bounds on
type checking and partial inference are unknown.

The simple algorithm of \citet{wand-fi87}, which generates constraints
for type reconstruction, can also be seen as compiler for the linear
$\lambda$-calculus.  It compiles a linear term into a ``machine
language'' of first-order constraints of the form $a = b$ and $c =
d\rightarrow e$.  This machine language is the computational analog of
logic's own low-level machine language for first-order propositional
logic, the machine-oriented logic of \citet{robinson-jacm65}.

Unifying these constraints effectively runs the machine language,
evaluating the original program, producing an answer in the guise of a
solved form of the type, which is isomorphic to the normal form of the
program.

Viewed from this perspective, this is an instance of
normal\-ization-by-eval\-uation for the linear $\lambda$-calculus.  A
linear term is mapped into the domain of first-order logic, where
unification is used to evaluate to a canonical solved form, which can
be mapped to the normal form of the term.  Constraint-based
formulations of monovariant flow analyses analogously can be seen as
instances of {\em weak} normal\-ization-by-eval\-uation functions for
the linear $\lambda$-calculus.


% It should be noted that all linear terms have types
% \cite{hindley-tcs89}, so this compiler is complete.

% More complexity type inference papers: \cite{hoang-mitchell-popl95}.