\section{Linear Logic and Static Analysis}
\label{chap:linear-logic}

If you want to understand exactly how and where static analysis is
computationally difficult, you need to know about linearity.
%
%% When I hear the word `Curry-Howard', I reach for my gun.
%
In this chapter, we develop an alternative, graphical representation
of programs that makes explicit both non-linearity and control, and is
suitable for static analysis.

This alternative representation offers the following benefits:

\begin{itemize}
\item It provides clear intuitions on the essence of 0CFA and forms
the basis for a transparent proof of the correspondence between 0CFA
and evaluation for linear programs.

\item As a consequence of symmetries in the notation, it is equally
well-suited for representing programs with first-class control.

\item It based on the technology of linear logic.  Insights gleaned
from linear logic, viewed through the lens of a Curry-Howard
correspondence, can inform program analysis and {\em vice versa}.

\item As an application of the above, a novel and efficient algorithm
for analyzing typed programs (\autoref{sec:eta}) is derived from
recent results on the efficient normalization of linear logic proofs.

\end{itemize}

We give a reformulation of 0CFA in this setting and then transparently
{\em reprove} the main result of \autoref{sec:linearity}: analysis and
evaluation are synonymous for linear programs.

%% \paragraph{Note to the reader:} 
%% \begin{quote}
%% So much recent research effort has been directed at the
%% effective communication of mathematical proofs to computers via the
%% mechanizing meta-theory program (and it may be that the technology of
%% sharing graphs can contribute to that program), but proofs (and
%% programs, naturally) are meant also to communicate ideas {\em between}
%% humans (cf. Frege's concept script). It is primarily for this reason
%% that we choose this representation: it is effective in communicating
%% the {\em ideas} of this research.

%% Simple proofs are hard to find in recent literature.  Rigor has lead
%% to rigor mortis.  Instead, simple proofs exist in an oral history
%% among researchers, proofs that can be (and often are) told at the
%% coffeehouse over napkins and a pen.  There is a place for 50,000 lines
%% of Coq code, but likewise there is a place for the napkin and the pen.

%% It has technical advantages as well, but these can be regarded as
%% icing on the cake (and are perhaps due to the conceptual clarity of
%% the setting). 

%% Come on in, the water is fine.
%% \end{quote}

\subsection{Sharing Graphs for Static Analysis}

In general, the sharing graph of a term will consist of a
distinguished {\em root} wire from which the rest of the term's graph
``hangs.''
\begin{displaymath}
\includegraphics{figure.13}
\end{displaymath}
At the bottom of the graph, the dangling wires represent
free variables and connect to occurrences of the free variable within
in term.

Graphs consist of ternary abstraction ($\lambda$), apply (@),
sharing ($\triangledown$) nodes, and unary weakening ($\odot$)
nodes.  Each node has a distinguished {\em principal} port.  For unary
nodes, this is the only port.  The ternary nodes have two {\em
auxiliary} ports, distinguished as the {\em white} and {\em black}
ports.

\begin{itemize}
\item A variable occurrence is represented simply as a wire from the
root to the free occurrence of the variable.
\begin{displaymath}
\includegraphics{figure.14}
\end{displaymath}

\item Given the graph for $M$, where $x$ occurs free,
\begin{displaymath}
\includegraphics{figure.15}
\end{displaymath}
the abstraction $\lambda x.M$ is formed as,
\begin{displaymath}
\includegraphics{figure.16}
\end{displaymath}

Supposing $x$ does not occur in $M$, the weakening node ($\odot$) is
used to ``plug'' the $\lambda$ variable wire.
\begin{displaymath}
\includegraphics{figure.17}
\end{displaymath}


\item Given graphs for $M$ and $N$,
\begin{displaymath}
\includegraphics{figure.12},
\end{displaymath}
the application $MN$ is formed as,
\begin{displaymath}
  \includegraphics{figure.11}.
\end{displaymath}
An application node is introduced.  The operator $M$ is connected to
the function port and the operand $N$ is connected to the argument
port.  The continuation wire becomes the root wire for the
application.  Free variables shared between both $M$ and $N$ are
fanned out with sharing nodes.
\end{itemize}

% \dvhnote{Explain the linear logic program.  What it sought to
% accomplish, where does it succeed, what does this have to do with
% static analysis?  See \citet{girard-proofs-and-types}.}

\subsection{Graphical 0CFA}

We now describe an algorithm for performing control flow analysis that
is based on the graph coding of terms.  The graphical formulation
consists of generating a set of {\em virtual paths} for a program
graph.  Virtual paths describe an approximation of the real paths that
will arise during program execution.

\begin{figure} 
  \centering 
  \input{fig/0cfa-rules.ps_t}
  \caption{CFA virtual wire propagation rules.} 
  \label{figure-cfa-rules} 
\end{figure}

\autoref{figure-cfa-rules} defines the virtual path propagation rules.
Note that a wire can be identified by its label or a variable
name.\footnote{We implicitly let $\ell$ range over both in the
  following definitions.}  The left hand rule states that a virtual
wire is added from the continuation wire to the body wire and from the
variable wire to the argument wire of each $\beta$-redex.  The right
hand rule states analogous wires are added to each {\em virtual
  $\beta$-redex}---an apply and lambda node connected by a virtual
path.  There is a {\em virtual path} between two wires $\ell$ and
$\ell'$, written $\ell \vp \ell'$ in a CFA-graph iff:
%% 1) $\ell \equiv \ell'$, 2) there is a
%% virtual wire from $\ell$ to $\ell'$, 3) $\ell$ connects to an
%% auxiliary port and $\ell'$ connects to the principal port of a sharing
%% node, or 4) $\ell\vp \ell''$ and $\ell''\vp \ell'$.
\begin{enumerate}
\item $\ell \equiv \ell'$.
\item There is a virtual wire from $\ell$ to $\ell'$.
\item $\ell$ connects to an auxiliary port and $\ell'$ connects to the root
port of a sharing node.
\item There is a virtual path from $\ell$ to $\ell''$ and from
$\ell''$ and $\ell'$.
\end{enumerate}

\paragraph{Reachability:} Some care must be taken to ensure leastness
when propagating virtual wires.  In particular, wires are added only
when there is a virtual path between a {\em reachable} apply and a
lambda node.  An apply node is reachable if it is on the spine of the
program, i.e., if $e=(\cdots((e_0e_1)^{\ell_1}e_2)^{\ell_2}\cdots
e_n)^{\ell_n}$ then the apply nodes with continuation wires labeled
$\ell_1,\dots,\ell_n$ are reachable, or it is on the spine of an
expression with a virtual path from a reachable apply node.

Reachability is usually explained as a known improvement to flow
analysis; precision is increased by avoiding parts of the program that
cannot be reached \cite{ayers-phd93, palsberg-schwarzbach-ic95,
  biswas-popl97, heintze-mcallester-icfp97, midtgaard-jensen-sas-08,
  midtgaard-jensen-icfp09}.

But reachability can also be understood as an analysis analog to weak
normalization.
%
Reachability says roughly: ``don't analyze under $\lambda$ until the
analysis determines it may be applied.''
%
On the other hand, weak normalization says: ``don't evaluate under
$\lambda$ until the evaluator determines it is applied.''
%
The analyzers of \autoref{chap:foundations} implicitly include
reachability since they are based on a evaluation function that
performs weak normalization.

% \citet{wand-02} investigates these issues (question posed by
% Palsberg).

% \citet{wand-02} introduces a very course view of observation. 

% Soundness: if $\cache \models t^\ell$ and $t^\ell \rightarrow
% t^{\ell'}$, then $\cache \models t^{\ell'}$, and $\cache(\ell')
% \subseteq \cache(\ell)$.

% Prediction: if $\cache \models t^\ell$ and $t^\ell \rightarrow^\star
% (\lambda x.e)^{\ell'}$, then


The graph-based analysis can now be performed in the following way:
construct the CFA graph according to the rules in
\autoref{figure-cfa-rules}, then define $\cache(\ell)$ as $\{ (\lambda
x.e)^{\ell'}\; |\; \ell\vp \ell' \}$ and $\aenv(x)$ as $\{ (\lambda
x.e)^{\ell}\; |\; x\vp \ell \}$.  It is easy to see that the
algorithm constructs answers that satisfy the acceptability relation
specifying the analysis.  Moreover, this algorithm constructs least
solutions according to the partial order given in \autoref{sec:ai}.

\begin{lemma}
  $\cache',\aenv'\models e$ implies $\cache,\aenv \sqsubseteq
  \cache',\aenv'$ for $\cache,\aenv$ constructed for $e$ as described
  above.
\end{lemma}

\begin{figure} 
  \centering \input{fig/0cfa-example.ps_t}
  \caption{Graph coding and CFA graph of $(\lambda f. ff(\lambda y.y)) (\lambda x.x)$.}
  \label{figure-cfa-example} 
\end{figure}

We now consider an example of use of the algorithm.  Consider the
labeled program: 
\begin{displaymath}
((\lambda f.((f^1 f^2)^3(\lambda y.y^4)^5)^6)^7 (\lambda
x.x^8)^9)^{10}
\end{displaymath}
\autoref{figure-cfa-example} shows the graph coding of the program and
the corresponding CFA graph.  The CFA graph is constructed by adding
virtual wires $10 \vp 6$ and $f\vp 9$, induced by the actual
$\beta$-redex on wire 7.  Adding the virtual path $f\vp 9$ to the
graph creates a virtual $\beta$-redex via the route $1\vp f$ (through
the sharing node), and $f\vp 9$ (through the virtual wire).  This
induces $3 \vp 8$ and $8\vp 2$.  There is now a virtual $\beta$-redex
via $3 \vp 8 \vp 2 \vp f \vp 9$, so wires $6 \vp 8$ and $8 \vp 5$ are
added.  This addition creates another virtual redex via $3 \vp 8 \vp 2
\vp 5$, which induces virtual wires $6 \vp 4$ and $4 \vp 5$.  No
further wires can be added, so the CFA graph is complete.  The
resulting abstract cache gives:
\begin{displaymath}
\begin{array}{l@{\:=\:}ll@{\:=\:}l}
\cache(1) & \{ \lambda x \} &
\cache(6) & \{ \lambda x, \lambda y \} \\
\cache(2) & \{ \lambda x \} &
\cache(7) & \{ \lambda f \} \\
\cache(3) & \{ \lambda x, \lambda y \} &
\cache(8) & \{ \lambda x, \lambda y \} \\
\cache(4) & \{ \lambda y \} &
\cache(9) & \{ \lambda x \} \\
\cache(5) & \{ \lambda y \} &
\cache(10)& \{ \lambda x, \lambda y \}
\end{array}
\begin{array}{l@{\:=\:}l}
\aenv(f) & \{ \lambda x \} \\
\aenv(x) & \{ \lambda x, \lambda y \}\\
\aenv(y) & \{ \lambda y \}
\end{array}
\end{displaymath}


\subsection{Multiplicative Linear Logic}

The Curry-Howard isomorphism states a correspondence between logical
systems and computational calculi \cite{howard}.  The fundamental idea
is that data types are theorems and typed programs are proofs of
theorems.
\begin{quote}%
It begins with the observation that an implication $A \rightarrow B$
corresponds to a type of functions from $A$ to $B$, because inferring
$B$ from $A\rightarrow B$ and $A$ can be seen as {\em applying} the
first assumption to the second one---just like a function from $A$ to
$B$ applied to an element of $A$ yields an element of $B$. [p.~v] \cite{sorensen-urzyczyn}
\end{quote}

For the functional programmer, the most immediate correspondence is
between proofs in propositional intuitionistic logic and simply typed
$\lambda$-terms.  But the correspondence extends considerably further.
\begin{quote}%
Virtually all proof-related concepts can be interpreted in terms of
computations, and virtually all syntactic features of various
lambda-calculi and similar systems can be formulated in the language
of proof theory.
\end{quote}


%% A {\em sequent} is an expression $\underline{A} \vdash \underline{B}$
%% where $A$ and $B$ are finite sequences of formulae $A_1,\dots,A_n$ and
%% $B_1,\dots,B_m$.  

%% Gentzen's original calculus was for {\em classical logic}.  It
%% consists of 1) structural rules for exchange, weakening and
%% contraction, 2) identity rules for axioms and cuts, and 3) logical
%% rules for negation, conjunction, disjunction and implication.

%% It enjoys a strong left/right symmetry. According to
%% \citet{girard-proofs-and-types}, the sequent calculus ``is the
%% pretties illustration of the symmetries of Logic.''

%% Intuitively, such an expression is understood as asserting the
%% conjunction of the formulae on the left of the turnstile implies the
%% disjunction of the formulae on the right.



%% \subsubsection{Simply typed $\lambda$-calculus and intuistionistic sequents}

%% Simply typed $\lambda$-calculus.  This should be familiar to any
%% functional programmer.
%% \begin{mathpar}
%% \inferrule*[left=Var]{ }{\Gamma,x : \tau \vdash x : \tau}
%% \and
%% \inferrule*[left=Abs]{\Gamma,x:\sigma \vdash M : \tau}{\Gamma \vdash \lambda x.M : \sigma \rightarrow \tau}
%% \and
%% \inferrule*[left=App]{\Gamma\vdash M:\sigma \rightarrow \tau\\ \Gamma\vdash N:\sigma}{\Gamma \vdash MN:\tau}
%% \end{mathpar}


%% \subsubsection{Linear $\lambda$-calculus and linear sequents}

%% Let us consider what happens when we restrict ourselves to the linear $\lambda$-calculus.
%% \begin{mathpar}
%% \inferrule*[left=Var]{ }{x : \tau \vdash x : \tau}
%% \and
%% \inferrule*[left=Abs]{\Gamma,x:\sigma \vdash M : \tau}{\Gamma \vdash \lambda x.M : \sigma \lolli \tau}
%% \and
%% \inferrule*[left=App]{\Gamma\vdash M:\sigma \lolli \tau\\ \Delta\vdash N:\sigma}{\Gamma,\Delta \vdash MN:\tau}
%% \end{mathpar}

%% Linear $\lambda$-calculus, symmetric form:
%% \begin{mathpar}
%% \inferrule*[left=Var]{ }{x : \tau^\perp, x : \tau}
%% \and
%% \inferrule*[left=Abs]{\Gamma,x:\sigma^\perp, M : \tau}{\Gamma,\lambda x.M : \sigma \lolli \tau}
%% \and
%% \inferrule*[left=App]{\Gamma, M:\sigma \lolli \tau\\ \Delta, N:\sigma}{\Gamma,\Delta, MN:\tau}
%% \end{mathpar}



%% \begin{mathpar}
%% \inferrule*{\Gamma,M:A^\perp\parr B\\
%%             \inferrule*{\Delta,N:A\\ \inferrule*{ }{k:B,k:B^\perp}}{\Delta,k:B,\langle N, k\rangle:A \tensor B^\perp}}
%%            {\Gamma,\Delta,k:B}          
%% \end{mathpar}


%% \dvhnote{Much of this follows \citet{lafont-proofs-and-types}, but
%% restricted to the MLL fragment.}

In this section we want to develop the ``proofs-as-programs''
correspondence for linear programs, an important class of programs to
consider for lower bounds on program analysis.  Because analysis and
evaluation are synonymous for linear programs, insights from proof
evaluation can guide new algorithms for program analysis.


The correspondence between simply typed (nonlinear) terms and
intuitionistic logic can be seen by looking at the familiar typing
rules:
\begin{mathpar}
\inferrule*[left=Var]{ }{\Gamma,x : A \vdash x : A}
\and
\inferrule*[left=Abs]{\Gamma,x:A \vdash M : B}{\Gamma \vdash \lambda x.M : A \rightarrow B}
\and
\inferrule*[left=App]{\Gamma\vdash M:A \rightarrow B\\ \Gamma\vdash N:A}{\Gamma \vdash MN:B}
\end{mathpar}

If you ignore the ``proof terms'' (i.e. the programs), you get intuitionsitic sequent calculus:
\begin{mathpar}
\inferrule*[left=Ax]{ }{\Gamma,A \vdash A}
\and
\inferrule*[left=$\rightarrow$I]{\Gamma,A \vdash B}{\Gamma \vdash A \rightarrow B}
\and
\inferrule*[left=$\rightarrow$E]{\Gamma\vdash A \rightarrow B\\ \Gamma\vdash A}{\Gamma \vdash B}
\end{mathpar}

Likewise, {\em linear programs} have their own logical avatar, namely
{\em multiplicative linear logic}.

\subsubsection{Proofs}

Each atomic formula is given in two forms: positive ($A$) and negative
($A^\perp$) and the {\em linear negation} of $A$ is $A^\perp$ and {\em
vice versa}.  Negation is extended to compound formulae via De
Morgan laws:
\begin{mathpar}
(A\tensor B)^\perp = A^\perp \parr B^\perp

(A\parr B)^\perp = A^\perp \tensor B^\perp
\end{mathpar}

A two sided sequent
\begin{mathpar}
A_1,\dots,A_n \vdash B_1,\dots,B_m
\end{mathpar}
is replaced by
\begin{mathpar}
\vdash A_1^\perp,\dots,A_n^\perp,B_1,\dots,B_m
\end{mathpar}

%% \dvhnote{This section should be flushed out.  See \citet{lafont-ll95}
%% and Harry's notes on that paper for more details.}

The interested reader is referred to \citet{girard-tcs87} for more
details on linear logic.

For each derivation in MLL, there is a proofnet, which abstracts away
much of the needless sequentialization of sequent derivations, ``like
the order of application of independent logical rules: for example,
there are many inessintailly different ways to obtain $\vdash A_1
\parr A_2,\dots A_{n-1} \parr A_n$ from $\vdash A_1,\dots A_n$, while
there is only one proof net representing all these derivations''
\cite{di-cosmo-etal-mscs03}.
%
There is strong connection with calculus of explicit substitutions
\citet{di-cosmo-etal-mscs03}.

The sequent rules of multiplicative linear logic (MLL) are given in
\autoref{fig-mll-sequents}.

\begin{figure}[h]
\begin{mathpar}
\inferrule*[left=Ax,rightskip=10pt]{ }{A,A^\perp}
\and
\inferrule*[left=Cut]{\Gamma,A \\ A^\perp,\Delta}{\Gamma,\Delta}
\and
\inferrule*[Left=$\parr$]{\Gamma,A,B}{\Gamma,A\parr B}
\and
\inferrule*[Left=$\tensor$]{\Gamma,A \\ \Delta,B}{\Gamma,\Delta,A\tensor B}
\end{mathpar}
\caption{MLL sequent rules.}
\label{fig-mll-sequents}
\end{figure}

\subsubsection{Programs}

These rules have an easy functional programming interpretation as the
types of a linear programming language (eg.~linear ML), following the
intuitions of the Curry-Howard correspondence
\cite{girard-proofs-and-types,sorensen-urzyczyn}.\footnote{For a more
detailed discussion of the C.-H.~correspondence between linear ML and
MLL, see \citet{mairson-jfp04}.}

(These are written in the more conventional (to functional programmers)
two-sided sequents, but just remember that $A^\perp$ on the left is
like $A$ on the right).

\begin{mathpar}
\inferrule*{ }{x:A\vdash x:A}
\and
\inferrule*{\Gamma \vdash M:A \\ \Delta \vdash N:B}{\Gamma,\Delta \vdash (M,N):A\tensor B}
\and
\inferrule*{\Gamma,x:A\vdash M:B}{\Gamma\vdash \lambda x.M : A\lolli B}
\and 
\inferrule*{\Gamma\vdash M:A\lolli B \\ \Delta\vdash N:A}{\Gamma,\Delta\vdash MN : B}
\and 
\inferrule*{\Gamma\vdash M:A\tensor B\\ \Delta, x:A,y:B \vdash N : C}
           {\Gamma,\Delta \vdash \mbox{let }\langle x,y\rangle = M\mbox{ in }N : C}
\end{mathpar}

The {\sc Axiom} rule says that a variable can be viewed simultaneously
as a continuation ($A^\perp$) or as an expression ($A$)---one man's
ceiling is another man's floor.  Thus we say ``input of type $A$'' and
``output of type $A^\perp$'' interchangeably, along with similar
dualisms.  We also regard $(A^\perp)^\perp$ synonymous with $A$: for
example, {\tt Int} is an integer, and ${\tt Int}^\perp$ is a request
(need) for an integer, and if you need to need an integer---$({\tt
  Int}^\perp)^\perp$---then you have an integer.

The {\sc Cut} rule says that if you have two computations, one with an
output of type $A$, another with an input of type $A$, you can plug
them together.  

The $\tensor$-rule is about pairing: it says that if you have separate
computations producing outputs of types $A$ and $B$ respectively, you
can combine the computations to produce a paired output of type
$A\tensor B$.  Alternatively, given two computations with $A$ an
output in one, and $B$ an input (equivalently, continuation $B^\perp$
an output) in the other, they get paired as a {\em call site}
``waiting'' for a function which produces an {\em output} of type $B$
with an {\em input} of type $A$.  Thus $\tensor$ is both {\tt cons}
and function call (@).

The $\parr$-rule is the linear unpairing of this $\tensor$-formation.
When a computation uses inputs of types $A$ and $B$, these can be
combined as a single input pair, e.g., {\tt let (x,y)=p in...}.
Alternatively, when a computation has an input of type $A$ (output of
continuation of type $A^\perp$) and an output of type $B$, these can
be combined to construct a function which inputs a call site pair, and
unpairs them appropriately.  Thus $\parr$ is both unpairing and $\lambda$.

\subsection{\texorpdfstring{$\eta$}{Eta}-Expansion and \logspace}
\label{sec:eta}
%% ICFP

\subsubsection{Atomic versus Non-Atomic Axioms}

The above {\sc Axiom} rule does not make clear whether the formula $A$
is an atomic type variable or a more complex type formula.  When a {\em
  linear} program only has atomic formulas in the ``axiom'' position,
then we can evaluate (normalize) it in logarithmic space.  When the
program is not linear, we can similarly compute a 0CFA analysis in
\logspace.  Moreover, these problems are complete for \logspace.

MLL proofs with non-atomic axioms can be easily converted to ones with
atomic axioms using the following transformation, analogous to
$\eta$-expansion:
\begin{mathpar}
\inferrule
{ }
{\alpha \otimes \beta, \alpha^\perp \parr \beta^\perp}
\and
\Rightarrow 
\and
\inferrule
{\inferrule
  {\inferrule{ }{\alpha,\alpha^\perp}\\ 
   \inferrule{ }{\beta,\beta^\perp}}
  {\alpha \otimes \beta, \alpha^\perp, \beta^\perp}}
{\alpha \otimes \beta, \alpha^\perp \parr \beta^\perp}
\end{mathpar}

\begin{figure} 
  \centering 
  \input{fig/expansion-narrow.ps_t}
  \caption{Expansion algorithm.}
  \label{figure-expansion}
\end{figure}
This transformation can increase the size of the proof.  For example,
in the circuit examples of the previous section (which are evidence
for \ptime-completeness), $\eta$-expansion causes an exponential
increase in the number of proof rules used.\footnote{It is linear in
  the formulas used, whose length increases exponentially (not so if
  the formulas are represented by directed acyclic graphs).}  A {\sc
  logspace} evaluation is then polynomial-time and -space in the
original circuit description.

The program transformation corresponding to the above proof expansion
is a version of $\eta$-expansion: see \autoref{figure-expansion}.  The
left hand expansion rule is simply $\eta$, dualized in the unusual
right hand rule. 
% The left rule applies to terms of the
% form $\lambda x . ee'$ where $ee':\sigma \rightarrow \sigma'$.  The
% right rule applies to terms of the form $\lambda x. C[ex]$ where $C$
% is an arbitrary program context and $x : \sigma \rightarrow \sigma'$.
The right rule is written with the @ above the $\lambda$ only to
emphasis its duality with the left rule.  Although not shown in the
graphs, but implied by the term rewriting rules, an axiom may pass
through any number of sharing nodes.

\subsubsection{Proof Normalization with Non-Atomic Axioms: \ptime}

A normalized {\em linear} program has no redexes. From the type of the
program, one can reconstruct---in a totally syntax-directed way---what
the structure of the term is \cite{mairson-jfp04}.  It is only the
position of the {\em axioms} that is not revealed.  For example, both
{\tt TT} and {\tt FF} from the above circuit example have type {\tt 'a
  * 'a -> 'a * 'a}.\footnote{The linear logic equivalent is
  $(\alpha^\perp\parr\alpha^\perp)\parr (\alpha\tensor\alpha)$.  The
  $\lambda$ is represented by the outer $\parr$, the unpairing by the
  inner $\parr$, and the {\tt cons}ing by the $\tensor$.}
%  $\alpha\tensor\alpha\lolli\alpha\tensor\alphs$}
From this type, we can see that the term is a $\lambda$-abstraction,
the parameter is unpaired---and then, are the two components of type
{\tt a} repaired as before, or ``twisted''?  To twist or not to twist
is what distinguishes {\tt TT} from {\tt FF}.

An MLL {\em proofnet} is a graphical analogue of an MLL proof, where
various sequentialization in the proof is ignored.  The proofnet
consists of axiom, cut, $\tensor$, and $\parr$ nodes with various
dangling edges corresponding to conclusions.  Rules for proofnet
formation (\autoref{fig-mll-proofnets}) follow the rules for sequent
formation (\autoref{fig-mll-sequents}) almost identically.

\begin{figure}[h]
\begin{displaymath}
\input{fig/proofnet.ps_t}
\end{displaymath}
\caption{MLL proofnets.}
\label{fig-mll-proofnets}
\end{figure}

A binary axiom node has two dangling edges, typed $A$ and $A^\perp$.
Given two disjoint proofnets with dangling edges (conclusions) typed
$\Gamma, A$ and $A^\perp,\Delta$, the edges typed $A,A^\perp$ can be
connected to a binary cut node, and the resulting connected proofnet
has dangling edges typed $\Gamma,\Delta$.  Given a connected proofnet
with dangling wires typed $\Gamma,A,B$, the edges typed $A,B$ can be
connected to the two auxiliary port of a $\parr$ node and the dangling
edge connected to the principal port will have type $A\parr B$.
Finally, given two disjoint proofnets with dangling edges typed
$\Gamma,A$ and $\Delta,B$, the edges typed $A,B$ can be connected to
the two auxiliary ports of a ternary $\tensor$ node; the principal
port then has a dangling wire of type $A\tensor B$.  The intuition is
that $\tensor$ is pairing and $\parr$ is linear unpairing.

The geometry of interaction \cite{girard-goi89,
  gonthier-abadi-levy-popl92}---the semantics of linear logic---and
the notion of paths provide a way to calculate normal forms, and may
be viewed as the logician's way of talking about static program
analysis.\footnote{See \citet{mairson-fsttcs02} for an introduction to
  context semantics and normalization by static analysis in the
  geometry of interaction.}  To understand how this analysis works, we
need to have a graphical picture of what a linear functional program
looks like.

Without loss of generality, such a program has a type $\phi$.  Nodes
in its graphical picture are either $\lambda$ or linear unpairing
($\parr$ in MLL), or application/call site or linear pairing
($\tensor$ in MLL).  We draw the graphical picture so that axioms are
on top, and cuts (redexes, either $\beta$-redexes or pair-unpair
redexes) are on the bottom as shown in \autoref{fig-mll-normal}.

\begin{figure}[h]
\begin{center}
\input{fig/mll-normal.ps_t}
\end{center}
\caption{MLL proofnet with atomic axioms.}
\label{fig-mll-normal}
\end{figure}

Because the axioms all have atomic type, the graph has the following
nice property:
\begin{lemma}
  Begin at an axiom $\alpha$ and ``descend'' to a cut-link, saving in
  an (initially empty) stack whether nodes are encountered on their
  left or right auxiliary port.  Once a cut is reached, ``ascend'' the
  accompanying structure, popping the stack and continuing left or
  right as specified by the stack token.  Then (1) the stack empties
  exactly when the next axiom $\alpha'$ is reached, and (2) if the
  $k$-th node from the start traversed is a $\tensor$, the $k$-th node
  from the end traversed is a $\parr$, and vice versa.
\end{lemma}
The path traced in the Lemma, using the stack, is
geometry of interaction (GoI), also known as static
analysis.  The correspondence between the $k$-th node from the start and
end of the traversal is precisely that between a {\em call site} ($\tensor$) and
a {\em called function} ($\parr$), or between a {\tt cons} ($\tensor$)
and a linear unpairing ($\parr$).

\subsubsection{Proof Normalization with Atomic Axioms: \logspace}

\noindent {\sf A sketch of the ``four finger'' normalization
  algorithm:} The stack height may be polynomial, but we do not need
the stack! Put fingers $\alpha,\beta$ on the axiom where the path begins, and
iterate over all possible choices of another two fingers $\alpha',\beta'$ at
another axiom.  Now move $\beta$ and $\beta'$ towards the cut link, where if
$\beta$ encounters a node on the left (right), then $\beta'$ must move left
(right) also.  If $\alpha',\beta'$ were correctly placed initially, then when
$\beta$ arrives at the cut link, it must be met by $\beta'$.  If $\beta'$ isn't
there, or got stuck somehow, then $\alpha',\beta'$ were incorrectly placed, and
we iterate to another placement and try again.

\begin{lemma}
  Any path from axiom $\alpha$ to axiom $\alpha'$ traced by the stack algorithm
  of the previous lemma is also traversed by the ``four finger''
  normalization algorithm.
\end{lemma}

Normalization by static analysis is synonymous with traversing these
paths.  Because these fingers can be stored in logarithmic space, we
conclude \cite{terui-ll2002,mairson-unpub06,mairson-geocal06}:

\begin{theorem}
  Normalization of linear, simply-typed, and fully $\eta$-expanded
  functional programs is contained in \logspace.
\end{theorem}

That 0CFA is then contained in \logspace\ is a casual byproduct of
this theorem, due to the following observation: if application site
$\chi$ calls function $\phi$, then the $\tensor$ and $\parr$
(synonymously, @ and $\lambda$) denoting call site and function are
in distinct trees connected by a {\sc Cut} link.  As a consequence the
0CFA computation is a subcase of the four-finger algorithm: traverse
the two paths from the nodes to the cut link, checking that the paths
are isomorphic, as described above.  The full 0CFA calculation then
iterates over all such pairs of nodes.
\begin{corollary}
  0CFA of linear, simply-typed, and fully $\eta$-expanded
  functional programs is contained in \logspace.
\end{corollary}

\subsubsection{0CFA in \logspace}

Now let us remove the linearity constraint, while continuing to insist
on full $\eta$-expansion as described above, and simple typing.  The
normalization problem is no longer contained in \logspace, but rather
non-elementary recursive, \cite{statman79,mairson92,asperti-mairson}.
However, 0CFA remains contained in \logspace, because it is now an
{\em approximation}.  This result follows from the following
observation:
\begin{lemma}
\label{lemma-iso-paths}
Suppose $(t^\ell\;e)$ occurs in a simply typed, fully $\eta$-expanded
program and $\lambda x.e \in \cache(\ell)$.  Then the corresponding
$\tensor$ and $\parr$ occur in adjacent trees connected at their roots
by a {\sc cut}-link and on dual, isomorphic paths modulo placement of
sharing nodes.
\end{lemma}
Here ``modulo placement'' means: follow the paths to the {\sc}
cut---then we encounter $\tensor$ (resp., $\parr$) on one path when we
encounter $\parr$ (resp., $\tensor$) on the other, on the same (left,
right) auxiliary ports.  We thus {\em ignore} traversal of sharing
nodes on each path in judging whether the paths are isomorphic.
(Without sharing nodes, the $\tensor$ and $\parr$ would
annihilate---i.e., a $\beta$-redex---during normalization.)

\begin{theorem}
0CFA of a simply-typed, fully $\eta$-expanded program is contained in
\logspace.
\end{theorem}

Observe that 0CFA defines an {\em approximate} form of normalization
which is suggested by simply {\em ignoring} where sharing occurs.
Thus we may define the {\em set} of $\lambda$-terms to which that a term
might evaluate.  Call this {\em 0CFA-normalization}. 
%% \dvhnote{It's not
%% really a set of normal forms... it's a single proofnet.}
\begin{theorem}
  For fully $\eta$-expanded, simply-typed terms, 0CFA-normalization
  can be computed in {\em nondeterministic} \logspace.
\end{theorem}
\begin{conjecture}
  For fully $\eta$-expanded, simply-typed terms, 0CFA-normalization is
  complete for {\em nondeterministic} \logspace.
\end{conjecture}
The proof of the above conjecture likely depends on a coding of
arbitrary directed graphs and the consideration of commensurate path
problems.
\begin{conjecture}
  An algorithm for 0CFA normalization can be realized by {\em optimal
  reduction}, where sharing nodes {\em always} duplicate, and never
  annihilate.
\end{conjecture}

%% \dvhnote{If we are going to talk about 0CFA ``normalization'' it seems
%% it should be introduced before the $\eta$ expansion section.}

\subsubsection{\logspace-hardness of Normalization and 0CFA:  linear,
  simply-typed, fully \texorpdfstring{$\eta$}{eta}-expanded programs}

That the normalization and 0CFA problem for this class of programs is
as hard as any \logspace\ problem follows from the {\sc
  logspace}-hardness of the {\em permutation problem}: given a
permutation $\pi$ on $1,\ldots, n$ and integer $1\le i\le n$, are $1$
and $i$ on the same cycle in $\pi$?  That is, is there a $k$ where
$1\le k\le n$ and $\pi^k(1)=i$?

Briefly, the \logspace-hardness of the permutation problem is as
follows.\footnote{This presentation closely follows
  \citet{mairson-geocal06}.}  Given an arbitrary \logspace\ Turing
machine $M$ and an input $x$ to it, visualize a graph where the nodes
are machine IDs, with directed edges connecting successive
configurations.  Assume that $M$ always accepts or rejects in unique
configurations.  Then the graph has two connected components: the
``accept'' component, and the ``reject'' component.  Each component is
a directed tree with edges pointing towards the root (final
configuration).  Take an Euler tour around each component (like
tracing the fingers on your hand) to derive two {\em cycles}, and thus
a {\em permutation} on machine IDs.  Each cycle is polynomial size,
because the configurations only take logarithmic space.  The
equivalent permutation problem is then: does the initial configuration
and the accept configuration sit on the same cycle?

The following linear ML code describes the ``target'' code of a
transformation of an instance of the permutation problem.  For a
permutation on $n$ letters, we take here an example where $n=3$.
Begin with a vector of length $n$ set to {\tt False}, and a
permutation on $n$ letters:
\begin{quote}
{\small
\begin{alltt}
- val V= (False,False,False);
val V = ((fn,fn),(fn,fn),(fn,fn))
  : (('a * 'a -> 'a * 'a) * ('a * 'a -> 'a * 'a))
  * (('a * 'a -> 'a * 'a) * ('a * 'a -> 'a * 'a))
  * (('a * 'a -> 'a * 'a) * ('a * 'a -> 'a * 'a))
\end{alltt}}
\end{quote}
Denote as $\nu$ the type of vector {\tt V}.  
\begin{quote}
{\small
\begin{alltt}
- fun Perm (P,Q,R)= (Q,R,P);
val Perm = fn : \ensuremath{\nu} -> \ensuremath{\nu}
\end{alltt}}
\end{quote}
The function {\tt Insert} {\em linearly} inserts {\tt True} in the
first vector component, using all input exactly once:
\begin{quote}
{\small
\begin{alltt}
- fun Insert ((p,p'),Q,R)= ((TT,Compose(p,p')),Q,R);
val Insert = fn : \ensuremath{\nu} -> \ensuremath{\nu}
\end{alltt}}
\end{quote}
The function {\tt Select} {\em linearly} selects the third vector
component:
\begin{quote}
{\small
\begin{alltt}
- fun Select (P,Q,(r,r'))= 
    (Compose (r,Compose (Compose P, Compose Q)),r');
val Select = fn
  : \ensuremath{\nu} -> (('a * 'a -> 'a * 'a) * ('a * 'a -> 'a * 'a))
\end{alltt}}
\end{quote}
Because {\tt Perm} and {\tt Insert} have the same flat type, they can
be composed iteratively in ML without changing the type.  (This
clearly is {\em not} true in our coding of circuits, where the size of
the type increases with the circuit.  A careful coding limits the type
size to be polynomial in the circuit size, regardless of circuit
depth.)
\begin{lemma}
Let $\pi$ be coded as permutation {\tt Perm}.  Define {\tt Foo} to be
\begin{center}
{\tt Compose(Insert,Perm)} 
\end{center}
composed with itself $n$ times.  Then 1 and
$i$ are on the same cycle of $\pi$ iff {\tt Select (Foo V)} normalizes
to {\tt True}.
\end{lemma}

Because 0CFA of a linear program is identical with normalization, we conclude:

\begin{theorem}
0CFA of a simply-typed, fully $\eta$-expanded program is complete for
\logspace.
\end{theorem}

% As a consequence of the hardness construction having a constant type,
% we may conclude the 0CFA of any bounded type program ($\eta$-expanded
% or not) is \logspace-hard:

% \begin{theorem}
% 0CFA of a bounded, simply-typed program is \logspace-hard.
% \end{theorem}

The usefulness of $\eta$-expansion has been noted in the context of
partial evaluation \cite{jones-et-al-93,danvy-et-al-toplas96}.  In
that setting, $\eta$-redexes serve to syntactically embed binding-time
coercions.  In our case, the type-based $\eta$-expansion does the
trick of placing the analysis in \logspace\ by embedding the type
structure into the syntax of the program.\footnote{Or, in slogan form:
  \logspace\ $=$ \ptime\ upto $\eta$.}

\subsection{Graphical Flow Analysis and Control}
%% ICFP
\citet{shivers-sigplan04} argues that ``CPS provide[s] a uniform
representation of control structure,'' allowing ``this machinery to be
employed to reason about context, as well,'' and that ``without CPS,
separate contextual analyses and transforms must be also
implemented---redundantly,'' in his view.  Although our formulation of
flow analysis is a ``direct-style'' formulation, a graph
representation enjoys the same benefits of a CPS representation,
namely that control structures are made explicit---in a graph a
continuation is simply a wire.  Control constructs such as
\verb|call/cc| can be expressed directly \cite{lawall-mairson-esop00}
and our graphical formulation of control flow analysis carries over
without modification.

\citet{lawall-mairson-esop00} derive graph representations of programs
with control operators such as \verb|call/cc| by first translating
programs into continuation passing style (CPS).  They observed that
when edges in the CPS graphs carrying answer values (of type $\bot$)
are eliminated, the original (direct-style) graph is regained, modulo
placement of boxes and croissants that control sharing.  Composing the
two transformations results in a direct-style graph coding for
languages with \verb|call/cc| (hereafter, $\lambda_\mathcal{K}$).  The
approach applies equally well to languages such as Filinski's
symmetric $\lambda$-calculus \shortcite{filinski-ctcs89}, Parigot's
$\lambda_\mu$ calculus \shortcite{parigot-lpar92}, and most any
language expressible in CPS.

Languages such as $\lambda_\xi$, which contains the ``delimited
control'' operators {\em shift} and {\em reset}
\cite{danvy-filinksi-lfp90}, are not immediately amenable to this
approach since the direct-style transformation requires all calls to
functions or continuations be in tail position.  Adapting this
approach to such languages constitutes an open area of research.

\newcommand\graph[1]{\ensuremath{#1}}
\begin{figure} 
  % \centering \scalebox{1.5}{\input{fig/callcc-cfa.ps_t}}
  \caption{Graph coding of {\tt call/cc} and example CFA graph.}
  \label{figure-callcc}
\end{figure}


The left side of \autoref{figure-callcc} shows the graph coding of
\verb|call/cc|.  Examining this graph, we can read of an
interpretation of \verb|call/cc|, namely: \verb|call/cc| is a function
that when applied, copies the current continuation ($\triangle$) and
applies the given function $f$ to a function ($\lambda v\dots$) that
when applied abandons the continuation at that point ($\odot$) and
gives its argument $v$ to a copy of the continuation where
\verb|call/cc| was applied.  If $f$ never applies the function it is
given, then control returns ``normally'' and the value $f$ returns is
given to the other copy of the continuation where \verb|call/cc| was
applied.

%% \dvhnote{I started to write about boxing and confluence but I'm not
%% sure they're relevant here.}

%% Of course, just as the graph coding of terms given in
%% \autoref{section-preliminaries} is insufficient for performing
%% reduction, so too is this graph coding of \verb|call/cc|.  What is
%% missing is a boxing strategy like that given in
%% \autoref{figure-red-graph}...

%% It is well-known that term reduction for $\lambda_\mathcal{K}$ is
%% non-confluent, however the graph reduction technology developed by
%% \citet{lawall-mairson-esop00} resolves this issue---confluence is
%% regained by program's giving multiple answers to a shared
%% continuation.

The right side of \autoref{figure-callcc} gives the CFA graph for the
program:
\begin{displaymath}
(\mbox{{\tt call/cc }} (\lambda k.(\lambda x.\overline{1})(k\overline{2})))^\ell
\end{displaymath}

From the CFA graph we see that $\cache(\ell) = \{ \overline{1},
\overline{2} \}$, reflecting the fact that the program will return
$\overline{1}$ under a call-by-name reduction strategy and
$\overline{2}$ under call-by-value.  Thus, the analysis is indifferent
to the reduction strategy.  Note that whereas before, approximation
was introduced through nonlinearity of bound variables, approximation
can now be introduced via nonlinear use of continuations, as seen in
the example.  In the same way that 0CFA considers all occurrences of a
bound variable ``the same'', 0CFA considers all continuations obtained
with each instance of \verb|call/cc| ``the same''.

Note that we can ask new kinds of interesting questions in this
analysis.  For example, in \autoref{figure-callcc}, we can compute
which continuations are potentially {\em discarded}, by computing
which continuations flow into the weakening node of the \verb|call/cc|
term.  (The answer is the continuation $((\lambda
x.\overline{1})[\;])$.)  Likewise, it is possible to ask which
continuations are potentially {\em copied}, by computing which
continuations flow into the principal port of the sharing node in the
\verb|call/cc| term (in this case, the top-level empty continuation
$[\;]$).  Because continuations are used linearly in
\verb|call/cc|-free programs, the questions were uninteresting
before---the answer is always {\em none}.

Our proofs for the \ptime-completeness of 0CFA for the untyped
$\lambda$-calculus
%% ---and likewise for the results on $k$CFA---
carry over without modification languages such as
$\lambda_\mathcal{K}$, $\lambda_\mu$ and the symmetric
$\lambda$-calculus.  In other words, first-class control operators
such as \verb|call/cc| increase the expressivity of the language,
%% in the sense of \citet{felleisen-esop90}, 
but add nothing to the computational complexity of control flow
analysis.  In the case of simply-typed, fully $\eta$-expanded
programs, the same can be said.  A suitable notion of ``simply-typed''
programs is needed, such as that provided by \citet{griffin-popl90}
for $\lambda_\mathcal{K}$.  The type-based expansion algorithm of
\autoref{figure-expansion} applies without modification and lemma
\autoref{lemma-iso-paths} holds,
%% the paths are simply ``modulo more sharing nodes,''
allowing 0CFA for this class of programs to be done in \logspace.
Linear logic provides a foundation for (classical) $\lambda$-calculi
with control; related logical insights allow control flow analysis in
this setting.

The graph coding of terms in our development is based on the
technology of {\em sharing graphs} in the untyped case, and {\em proof
  nets} in the typed case \cite{lafont-ll95}.  The technology of
proofnets have previously been extended to intersection types
\cite{regnier-phd,neergaard-phd}, which have a close connection to
flow analysis \cite{amtoft-turbak-esop00, palsberg-pavlopoulou-jfp01,
  wells-etal-jfp02, banerjee-jensen-mscs03}.
 
The graph codings, CFA graphs, and virtual wire propagation rules
share a strong resemblance to the ``pre-flow'' graphs, flow graphs,
and graph ``closing rules'', respectively, of
\citet{Mossin:97:FlowAnalysis}.  Casting the analysis in this light
leads to insights from linear logic and optimal reduction.  For
example, as [page 78] \citet{Mossin:97:FlowAnalysis} notes, the CFA
virtual paths computed by 0CFA are an approximation of the actual
run-time paths and correspond exactly to the ``well-balanced paths'' of
\citet{asperti-laneve-tcs95} as an approximation to ``legal paths''
\cite{levy-phd} and results on proof normalization in linear logic
\cite{DBLP:conf/ictcs/MairsonT03} informed the novel flow analysis algorithms
presented here.

%% \subsection{Flow analysis and optimal evaluation}
%% ICFP

