\def\code#1{\mathtt{#1}} \def\closure#1{\mathcal C_{#1}} \def\par#1{\left( {#1} \right)} \def\set#1{\left\{ {#1} \right\}} \def\union{\cup}
Closure analysis
fact n return: isZero n base recurse
base: return 1
recurse: sub n 1 step1
step1 m: fact m step2
step2 f: mul n f return
main return1: fact 5 m0
m0 f: print f m1
m1: return1
Take the exemplar line
\code{step1}\ \code{m}\ \code{return}\ \code{:}\ \code{isZero}\ \code{n}\ \code{base}\ \code{recurse}
Turn this into a equation where we take all indentifiers in the call. For each identifier that is a name, we add a the closure. For each identifier that is a parameter, we just add it plain. Then subtract the parameters of the declaration itself.
This creates a set of equations:
\begin{align} \closure{\code{fact}} &= \set{\code{n}} \union \closure{\code{base}} \union \closure{\code{recurse}} \setminus \set{\code{n}, \code{return}} \\ \closure{\code{base}} &= \set{\code{return}} \\ \closure{\code{recurse}} &= \set{\code{n}} \union \closure{\code{step1}} \\ \closure{\code{step1}} &= \set{\code{m}} \union \closure{\code{fact}} \union \closure{\code{step2}} \setminus \set{\code{m}} \\ \closure{\code{step2}} &= \set{\code{n}, \code{f}, \code{return}} \setminus \set{\code{f}} \\ \closure{\code{main}} &= \closure{\code{fact}} \union \closure{\code{m0}} \setminus \set{\code{return1}} \\ \closure{\code{m0}} &= \set{\code{f}} \union \closure{\code{m1}} \setminus \set{\code{f}} \\ \closure{\code{m1}} &= \set{\code{return1}} \end{align}
Let's try to solve these equations:
\begin{align} \closure{\code{fact}} &= \closure{\code{recurse}} \setminus \set{\code{n}, \code{return}} \\ \closure{\code{base}} &= \set{\code{return}} \\ \closure{\code{recurse}} &= \set{\code{n}} \union \closure{\code{step1}} \\ \closure{\code{step1}} &= \set{\code{n}, \code{return}} \union \closure{\code{fact}} \setminus \set{\code{m}} \\ \closure{\code{step2}} &= \set{\code{n}, \code{return}} \\ \closure{\code{main}} &= \closure{\code{fact}} \setminus \set{\code{return1}} \\ \closure{\code{m0}} &= \set{\code{return1}} \\ \closure{\code{m1}} &= \set{\code{return1}} \end{align}
The problem now is that we have a cycle around \closure{\code{fact}}.
\begin{align} \closure{\code{fact}} &= \closure{\code{recurse}} \setminus \set{\code{n}, \code{return}} \\ \closure{\code{recurse}} &= \set{\code{n}} \union \closure{\code{step1}} \\ \closure{\code{step1}} &= \set{\code{n}, \code{return}} \union \closure{\code{fact}} \setminus \set{\code{m}} \end{align}
Let's inline all expressions until we recurse:
\begin{align} \closure{\code{fact}} &= \set{\code{n}} \union \par{ \set{\code{n}, \code{return}} \union \closure{\code{fact}} \setminus \set{\code{m}} } \setminus \set{\code{n}, \code{return}} \end{align}
Alternatively, we could pick any of the others to inline. The results should be the same:
\begin{align} \closure{\code{recurse}} &= \set{\code{n}} \union \par{ \set{\code{n}, \code{return}} \union \par{ \closure{\code{recurse}} \setminus \set{\code{n}, \code{return}} } \setminus \set{\code{m}} } \end{align}
Solving for fact
\begin{align} \closure{\code{fact}} &= \set{\code{n}} \union \par{ \set{\code{n}, \code{return}} \union \closure{\code{fact}} \setminus \set{\code{m}} } \setminus \set{\code{n}, \code{return}} \\ \closure{\code{fact}} &= \par{ \set{\code{n}} \setminus \set{\code{n}, \code{return}} } \union \par{ \par{ \set{\code{n}, \code{return}} \union \closure{\code{fact}} \setminus \set{\code{m}} } \setminus \set{\code{n}, \code{return}} } \\ \closure{\code{fact}} &= \par{ \set{\code{n}} \setminus \set{\code{n}, \code{return}} } \union \par{ \par{ \set{\code{n}, \code{return}} \union \closure{\code{fact}} } \setminus \set{\code{m}, \code{n}, \code{return}} } \\ \closure{\code{fact}} &= \par{ \set{\code{n}, \code{return}} \setminus \set{\code{m}, \code{n}, \code{return}} } \union \par{ \closure{\code{fact}} \setminus \set{\code{m}, \code{n}, \code{return}} } \\ \closure{\code{fact}} &= \closure{\code{fact}} \setminus \set{\code{m}, \code{n}, \code{return}} \\ \closure{\code{fact}} &\in \mathcal{P} \par{ \set{\code{m}, \code{n}, \code{return}} ^\mathrm{C} } \end{align}
The smallest solution is \closure{\code{fact}} = \emptyset.
We can substitute this back to solve all equations. But let's instead look at a different recursive equation and see if we can solve it too:
Solving for recurse
\begin{align} \closure{\code{recurse}} &= \set{\code{n}} \union \par{ \set{\code{n}, \code{return}} \union \par{ \closure{\code{recurse}} \setminus \set{\code{n}, \code{return}} } \setminus \set{\code{m}} } \\ \closure{\code{recurse}} &= \set{\code{n}} \union \par{ \set{\code{n}, \code{return}} \setminus \set{\code{m}} } \union \par{ \closure{\code{recurse}} \setminus \set{\code{m}, \code{n}, \code{return}} } \\ \closure{\code{recurse}} &= \set{\code{n}, \code{return}} \union \par{ \closure{\code{recurse}} \setminus \set{\code{m}, \code{n}, \code{return}} } \end{align}
The smallest solution is \closure{\code{recurse}} = \set{\code{n}, \code{return}}.