Write up the "verified" portion of the forward analysis

Signed-off-by: Danila Fedorin <danila.fedorin@gmail.com>
This commit is contained in:
2024-12-25 19:03:51 -08:00
parent fa180ee24e
commit 3b9c2edcdd
4 changed files with 569 additions and 1 deletions

View File

@@ -10,7 +10,21 @@ draft: true
In the previous post, I showed that the Control Flow graphs we built of our
programs match how they are really executed. This means that we can rely
on these graphs to compute program information. In this post, we finally
get to compute that information. Let's jump right into it!
get to compute that information. Here's a quick bit paraphrasing from last time
that provides a summary of our approach:
1. We will construct a finite-height lattice. Every single element of this
lattice will contain information about each variable at each node in the
Control Flow Graph.
2. We will then define a monotonic function that update this information using
the structure encoded in the CFGs edges and nodes.
3. Then, using the fixed-point algorithm, we will find the least element of the
lattice, which will give us a precise description of all program variables at
all points in the program.
4. Because we have just validated our CFGs to be faithful to the languages
semantics, well be able to prove that our algorithm produces accurate results.
Let's jump right into it!
### Choosing a Lattice
A lot of this time, we have been [talking about lattices]({{< relref "01_spa_agda_lattices" >}}),
@@ -59,6 +73,7 @@ split our programs into sequences of statements that are guaranteed to execute
together --- basic blocks. For our analysis, we'll keep per-variable for
each basic block in the program. Since basic blocks are nodes in the Control Flow
Graph of our program, our whole lattice will be as follows:
{#whole-lattice}
{{< latex >}}
\text{Info} \triangleq \text{NodeId} \to (\text{Variable} \to \text{Sign})
@@ -112,6 +127,7 @@ exact values of `x`, `y`, and `z`, leaving only their signs). The exact details
of how this partial evaluation is done are analysis-specific; in general, we
simply require an analysis to provide an evaluator. We will define
[an evaluator for the sign lattice below](#instantiating-with-the-sign-lattice).
{#general-evaluator}
{{< codelines "agda" "agda-spa/Analysis/Forward.agda" 166 167 >}}
@@ -136,6 +152,7 @@ current block. Early on, we saw that [the \((\sqcup)\) operator models disjuncti
\((\sqcup)\) to the variable-sign maps of all predecessors. The
[reference _Static Program Analysis_ text](https://cs.au.dk/~amoeller/spa/)
calls this operation \(\text{JOIN}\):
{#join-preds}
{{< latex >}}
\textit{JOIN}(v) = \bigsqcup_{w \in \textit{pred}(v)} \llbracket w \rrbracket
@@ -272,6 +289,7 @@ Actually, we haven't yet seen that `updateVariablesFromStmt`. This is
a function that we can define using the user-provided abtract interpretation
`eval`. Specifically, it handles the job of updating the sign of a variable
once it has been assigned to (or doing nothing if the statement is a no-op).
{#define-updateVariablesFromStmt}
{{< codelines "agda" "agda-spa/Analysis/Forward.agda" 191 193 >}}