Index: doc/aaron_comp_II/comp_II.tex
===================================================================
--- doc/aaron_comp_II/comp_II.tex	(revision 3078643badaf4e6783038509fba874449f0d1ae6)
+++ doc/aaron_comp_II/comp_II.tex	(revision be0a9d8a687f930ea1282a53a5089a2db229863e)
@@ -37,4 +37,7 @@
 \setlength{\headsep}{0.25in}
 
+\usepackage{caption}
+\usepackage{subcaption}
+
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
@@ -62,5 +65,5 @@
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-\newcommand{\bigO}[1]{O\left( #1 \right)}
+\newcommand{\bigO}[1]{O\!\left( #1 \right)}
 
 \begin{document}
@@ -407,16 +410,36 @@
 
 \subsection{Argument-Parameter Matching}
-The first axis we consider is argument-parameter matching --- whether the type matching for a candidate function to a set of candidate arguments is directed by the argument types or the parameter types. 
-
-\subsubsection{Argument-directed (``Bottom-up'')}
-Baker's algorithm for expression resolution\cite{Baker82} pre-computes argument candidates, from the leaves of the expression tree up.
+The first axis for consideration is argument-parameter matching direction --- whether the type matching for a candidate function to a set of candidate arguments is directed by the argument types or the parameter types. 
+All expression resolution algorithms form a DAG of interpretations, some explicitly, some implicitly; in this DAG, arcs point from function-call interpretations to argument interpretations, as below:
+\begin{figure}[h]
+\centering
+\begin{subfigure}[h]{2in}
+\begin{lstlisting}
+int *p;  // $p_i$
+char *p; // $p_c$ 
+
+double *f(int*, int*); // $f_d$
+char *f(char*, char*); // $f_c$
+
+f( f( p, p ), p );
+\end{lstlisting}
+\end{subfigure}~\begin{subfigure}[h]{2in}
+\includegraphics{resolution_dag}
+\end{subfigure}
+\caption{Resolution DAG for a simple expression. Functions that do not have a valid argument matching are covered with an \textsf{X}.}\label{fig:res_dag}
+\end{figure}
+
+Note that some interpretations may be part of more than one super-interpretation, as with $p_i$ in the bottom row, while some valid subexpression interpretations, like $f_d$ in the middle row, are not used in any interpretation of their containing expression.
+
+\subsubsection{Argument-directed (Bottom-up)}
+Baker's algorithm for expression resolution~\cite{Baker82} pre-computes argument candidates, from the leaves of the expression tree up.
 For each candidate function, Baker attempts to match argument types to parameter types in sequence, failing if any parameter cannot be matched.
 
-Bilson\cite{Bilson03} similarly pre-computes argument candidates in the original \CFA compiler, but then explicitly enumerates all possible argument combinations for a multi-parameter function; these argument combinations are matched to the parameter types of the candidate function as a unit rather than individual arguments.
-This is less efficient than Baker's approach, as the same argument may be compared to the same parameter many times, but allows a more straightforward handling of polymorphic type binding and multiple return types.
-It is possible the efficiency losses here relative to Baker could be significantly reduced by application of memoization to the argument-parameter type comparisons.
-
-\subsubsection{Parameter-directed (``Top-down'')}
-Unlike Baker and Bilson, Cormack's algorithm\cite{Cormack81} requests argument candidates which match the type of each parameter of each candidate function, from the top-level expression down; memoization of these requests is presented as an optimization.
+Bilson~\cite{Bilson03} similarly pre-computes argument candidates in the original \CFA compiler, but then explicitly enumerates all possible argument combinations for a multi-parameter function; these argument combinations are matched to the parameter types of the candidate function as a unit rather than individual arguments.
+This approach is less efficient than Baker's approach, as the same argument may be compared to the same parameter many times, but allows a more straightforward handling of polymorphic type-binding and multiple return-types.
+It is possible the efficiency losses here relative to Baker could be significantly reduced by keeping a memoized cache of argument-parameter type comparisons and reading previously-seen argument-parameter matches from this cache rather than recomputing them.
+
+\subsubsection{Parameter-directed (Top-down)}
+Unlike Baker and Bilson, Cormack's algorithm~\cite{Cormack81} requests argument candidates that match the type of each parameter of each candidate function, from the top-level expression down; memoization of these requests is presented as an optimization.
 As presented, this algorithm requires the result of the expression to have a known type, though an algorithm based on Cormack's could reasonably request a candidate set of any return type, though such a set may be quite large.
 
@@ -436,4 +459,7 @@
 
 Deciding when to switch between bottom-up and top-down resolution in a hybrid algorithm is a necessarily heuristic process, and though finding good heuristics for it is an open question, one reasonable approach might be to switch from top-down to bottom-up when the number of candidate functions exceeds some threshold.
+
+\subsubsection{Common Subexpression Caching}
+With any of these argument-parameter approaches, it may be a useful optimization to cache the resolution results for common subexpressions; in Figure~\ref{fig:res_dag} this optimization would result in the list of interpretations $[p_c, p_i]$ for ©p© only being calculated once, and re-used for each of the three instances of ©p©.
 
 \subsection{Implicit Conversion Application}
