Minor edits to 'lattices 2'
Signed-off-by: Danila Fedorin <danila.fedorin@gmail.com>
This commit is contained in:
parent
711b01175d
commit
04f12b545d
|
@ -16,7 +16,7 @@ of variables in a program.
|
||||||
|
|
||||||
At the end of that post, I introduced a source of complexity: the "full"
|
At the end of that post, I introduced a source of complexity: the "full"
|
||||||
lattices that we want to use for the program analysis aren't signs or numbers,
|
lattices that we want to use for the program analysis aren't signs or numbers,
|
||||||
but maps of states and variables to lattices-based states. The full lattice
|
but maps of states and variables to lattice-based descriptions. The full lattice
|
||||||
for sign analysis might something in the form:
|
for sign analysis might something in the form:
|
||||||
|
|
||||||
{{< latex >}}
|
{{< latex >}}
|
||||||
|
@ -25,12 +25,12 @@ for sign analysis might something in the form:
|
||||||
|
|
||||||
Thus, we have to compare and find least upper bounds (e.g.) of not just
|
Thus, we have to compare and find least upper bounds (e.g.) of not just
|
||||||
signs, but maps! Proving the various lattice laws for signs was not too
|
signs, but maps! Proving the various lattice laws for signs was not too
|
||||||
challenging, but for for a two-level map like \(\text{info}\) above, we'd
|
challenging, but for for a two-level map like \(\text{Info}\) above, we'd
|
||||||
need to do a lot more work. We need tools to build up such complicated lattices!
|
need to do a lot more work. We need tools to build up such complicated lattices.
|
||||||
|
|
||||||
The way to do this, it turns out, is by using simpler lattices as building blocks.
|
The way to do this, it turns out, is by using simpler lattices as building blocks.
|
||||||
To start with, let's take a look at a very simple way of combining lattices:
|
To start with, let's take a look at a very simple way of combining lattices:
|
||||||
taking the Cartesian product.
|
taking the [Cartesian product](https://mathworld.wolfram.com/CartesianProduct.html).
|
||||||
|
|
||||||
### The Cartesian Product Lattice
|
### The Cartesian Product Lattice
|
||||||
|
|
||||||
|
@ -39,12 +39,13 @@ post, each lattice comes equipped with a "least upper bound" operator \((\sqcup)
|
||||||
and a "greatest lower bound" operator \((\sqcap)\). Since we now have two lattices,
|
and a "greatest lower bound" operator \((\sqcap)\). Since we now have two lattices,
|
||||||
let's use numerical suffixes to disambiguate between the operators
|
let's use numerical suffixes to disambiguate between the operators
|
||||||
of the first and second lattice: \((\sqcup_1)\) will be the LUB operator of
|
of the first and second lattice: \((\sqcup_1)\) will be the LUB operator of
|
||||||
the first lattice \(L_1\), and \((\sqcup_2)\) of the second lattice \(L_2\).
|
the first lattice \(L_1\), and \((\sqcup_2)\) of the second lattice \(L_2\),
|
||||||
|
and so on.
|
||||||
|
|
||||||
Then, let's take the Cartesian product of the elements of \(L_1\) and \(L_2\);
|
Then, let's take the Cartesian product of the elements of \(L_1\) and \(L_2\);
|
||||||
mathematically, we'll write this as \(L_1 \times L_2\), and in Agda, we can
|
mathematically, we'll write this as \(L_1 \times L_2\), and in Agda, we can
|
||||||
just use the standard [`Data.Product`](https://agda.github.io/agda-stdlib/master/Data.Product.html)
|
just use the standard [`Data.Product`](https://agda.github.io/agda-stdlib/master/Data.Product.html)
|
||||||
module. In Agda, I'll define the lattice as another [parameterized module](https://agda.readthedocs.io/en/latest/language/module-system.html#parameterised-modules). Since both \(L_1\) and \(L_2\)
|
module. Then, I'll define the lattice as another [parameterized module](https://agda.readthedocs.io/en/latest/language/module-system.html#parameterised-modules). Since both \(L_1\) and \(L_2\)
|
||||||
are lattices, this parameterized module will require `IsLattice` instances
|
are lattices, this parameterized module will require `IsLattice` instances
|
||||||
for both types:
|
for both types:
|
||||||
|
|
||||||
|
@ -52,7 +53,7 @@ for both types:
|
||||||
|
|
||||||
Elements of \(L_1 \times L_2\) are in the form \((l_1, l_2)\), where
|
Elements of \(L_1 \times L_2\) are in the form \((l_1, l_2)\), where
|
||||||
\(l_1 \in L_1\) and \(l_2 \in L_2\). The first thing we can get out of the
|
\(l_1 \in L_1\) and \(l_2 \in L_2\). The first thing we can get out of the
|
||||||
way is define what it means for two such elements to be equal. Recall that
|
way is defining what it means for two such elements to be equal. Recall that
|
||||||
we opted for a [custom equivalence relation]({{< relref "01_spa_agda_lattices#definitional-equality" >}})
|
we opted for a [custom equivalence relation]({{< relref "01_spa_agda_lattices#definitional-equality" >}})
|
||||||
instead of definitional equality to allow similar elements to be considered
|
instead of definitional equality to allow similar elements to be considered
|
||||||
equal; we'll have to define a similar relation for our new product lattice.
|
equal; we'll have to define a similar relation for our new product lattice.
|
||||||
|
@ -75,7 +76,7 @@ relations.
|
||||||
|
|
||||||
{{< codelines "Agda" "agda-spa/Lattice/Prod.agda" 42 48 >}}
|
{{< codelines "Agda" "agda-spa/Lattice/Prod.agda" 42 48 >}}
|
||||||
|
|
||||||
In fact, defining \((\sqcup)\) and \((\sqcap)\) by simply applying the
|
Defining \((\sqcup)\) and \((\sqcap)\) by simply applying the
|
||||||
corresponding operators from \(L_1\) and \(L_2\) seems quite natural as well.
|
corresponding operators from \(L_1\) and \(L_2\) seems quite natural as well.
|
||||||
|
|
||||||
{{< latex >}}
|
{{< latex >}}
|
||||||
|
@ -88,8 +89,8 @@ In Agda:
|
||||||
{{< codelines "Agda" "agda-spa/Lattice/Prod.agda" 50 54 >}}
|
{{< codelines "Agda" "agda-spa/Lattice/Prod.agda" 50 54 >}}
|
||||||
|
|
||||||
All that's left is to prove the various (semi)lattice properties. Intuitively,
|
All that's left is to prove the various (semi)lattice properties. Intuitively,
|
||||||
we can see that since the "combined" operator `_≈_` just independently applies
|
we can see that since the "combined" operator `_⊔_` just independently applies
|
||||||
the element operators `_≈₁_` and `_≈₂_`, as long as they are idempotent,
|
the element operators `_⊔₁_` and `_⊔₂_`, as long as they are idempotent,
|
||||||
commutative, and associative, so is the "combined" operator itself.
|
commutative, and associative, so is the "combined" operator itself.
|
||||||
Moreover, the proofs that `_⊔_` and `_⊓_` form semilattices are identical
|
Moreover, the proofs that `_⊔_` and `_⊓_` form semilattices are identical
|
||||||
up to replacing \((\sqcup)\) with \((\sqcap)\). Thus, in Agda, we can write
|
up to replacing \((\sqcup)\) with \((\sqcap)\). Thus, in Agda, we can write
|
||||||
|
@ -98,8 +99,9 @@ that these operators obey the semilattice laws).
|
||||||
|
|
||||||
{{< codelines "Agda" "agda-spa/Lattice/Prod.agda" 56 82 >}}
|
{{< codelines "Agda" "agda-spa/Lattice/Prod.agda" 56 82 >}}
|
||||||
|
|
||||||
Similarly to the semilattice properties, proving lattice properties boils
|
Above, I used `f₁` to stand for "either `_⊔₁_` or `_⊓₁_`", and similarly
|
||||||
down to applying the lattice properties of \(L_1\) and \(L_2\) to
|
`f₂` for "either `_⊔₂_` or `_⊓₂_`". Much like the semilattice properties,
|
||||||
individual components.
|
proving lattice properties boils down to applying the lattice properties of
|
||||||
|
\(L_1\) and \(L_2\) to individual components.
|
||||||
|
|
||||||
{{< codelines "Agda" "agda-spa/Lattice/Prod.agda" 84 96 >}}
|
{{< codelines "Agda" "agda-spa/Lattice/Prod.agda" 84 96 >}}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user