Continue expanding on the map draft

Signed-off-by: Danila Fedorin <danila.fedorin@gmail.com>
This commit is contained in:
Danila Fedorin 2024-06-09 18:02:04 -07:00
parent 4c70e61a14
commit 7b03183e75

View File

@ -151,9 +151,10 @@ Let's start thinking about what sorts of lattices our maps will be.
The thing that [motivated our introduction]({{< relref "01_spa_agda_lattices#specificity" >}}) The thing that [motivated our introduction]({{< relref "01_spa_agda_lattices#specificity" >}})
of lattices was comparing them by "specificity", so let's try figure out how of lattices was comparing them by "specificity", so let's try figure out how
to compare maps. For that, we can begin small, by looking at singleton maps. to compare maps. For that, we can begin small, by looking at singleton maps.
If we have `{"x": +}` and `{"x": }`, which one of them is smaller? Well, wehave previously established that `+` is more specific (and thus less than) ``. Thus, it shouldn't be too much of a stretch If we have `{"x": +}` and `{"x": }`, which one of them is smaller? Well, we have
to say that for singleton maps of the same key, the one with the smaller previously established that `+` is more specific (and thus less than) ``. Thus,
value is smaller. it shouldn't be too much of a stretch to say that for singleton maps of the same
key, the one with the smaller value is smaller.
Now, what about a pair of singleton maps like `{"x": +}` and `{"y": }`? Among Now, what about a pair of singleton maps like `{"x": +}` and `{"y": }`? Among
these two, each contains some information that the other does not. Although the these two, each contains some information that the other does not. Although the
@ -163,4 +164,56 @@ these maps incompatible, then. More generally, if we have two maps and each one
has a key that the other doesn't, we can't compare them. has a key that the other doesn't, we can't compare them.
If only one map has a unique key, though, things are different. Take for If only one map has a unique key, though, things are different. Take for
instance `{"x": +}` and `{"x": +, "y": +}`. instance `{"x": +}` and `{"x": +, "y": +}`. Are they really incomparable?
The keys that the two maps do share can be compared (`+ <= +`, because they're
equal).
All of the above leads to the following conventional definition, which I find
easier to further motivate using \((\sqcup)\) and \((\sqcap)\)
(and [do so below]({{< relref "#union-as-or" >}})).
> A map `m1` is less than or equal to another map `m2` (`m1 <= m2`) if for
> every key `k` that has a value in `m1`, the key also has a value in `m2`, and
> `m1[k] <= m2[k]`.
That definitions matches our intuitions so far. The only key in `{"x": +}` is `x`;
this key is also in `{"x": }` (check) and `+ < ` (check). On the other hand,
both `{"x": +}` and `{"y": }` have a key that the other doesn't, so the
definition above is not satisfied. Finally, for `{"x": +}` and
`{"x": +, "y": +}`, the only key in the former is also present in the latter,
and `+ <= +`; the definition is satisfied.
Next, we need to define the \((\sqcup)\) and \((\sqcap)\) operators that match
our definition of "less than or equal". Let's start with \((\sqcup)\). For two
maps \(m_1\) and \(m_2\), the join of those two maps, \(m_1 \sqcup m_2\) should
be greater than or equal to both; in other words, both sub-maps should be less
than or equal to the join. Our newly-introduced condition for "less than or equal"
requires that each key in the smaller map be present in the larger one; as
a result, \(m_1 \sqcup m_2\) should contain all the keys in \(m_1\) __and__
all the keys in \(m_2\). So, we could just take the union of the two maps:
copy values from both into the result. Only, what happens if both \(m_1\)
and \(m_2\) have a value mapped to a particular key? The values in the two
maps could be distinct, and they might even be incomparable. This is where the
second part of the condition kicks in: the value in the combination of the
maps needs to be bigger than the value in either sub-map. We already know how
to get a value that's bigger than two other values: we use a join on the
values! Thus, define \(m_1 \sqcup m_2\) as a map that has all the keys
from \(m_1\) and \(m_2\), where the value at a particular key is given
as follows:
{{< latex >}}
(m_1 \sqcup m_2)[k] =
\begin{cases}
m_1[k] \sqcup m_2[k] & k \in m_1, k \in m_2 \\
m_1[k] & k \in m_1, k \notin m_2 \\
m_2[k] & k \notin m_1, k \in m_2
\end{cases}
{{< /latex >}}
{{< todo >}}
I started using 'join' but haven't introduced it before.
{{< /todo >}}
something something lub glub
{#union-as-or}