Trie comprehensions abstract the process of projecting one-or-more
tries against some patterns, binding the results to usable variables,
and iterating over the results.
Currently supports for-trie/fold, for-trie/list, for-trie/set, and
for-trie/patch, as well as the ability to easily create new trie
comprehension macros. Note that these comprehensions operate in the
style of `for*` rather than `for`.
The problem was that sometimes there'd be an assertion that `meta` had
asserted that *also* was asserted by some local process. Commit
de1dc5a introduced code that would drop the assertion in this case;
this commit changes it to only remove assertions from the set when
*only* `meta` is asserting them.
Previously, the timer driver caused the background thread to call
send-ground-message to indicate that a timer had expired. However,
this can lead to a race! In cases where a timer expires very soon, the
channel-put of the set-timer instruction leads shortly thereafter to a
send-ground-message which then races the establishment of the
metalevel-1 subscription to the timer-expired events that are coming
from the background thread.
The race cannot occur in the sequential implementation because the
network makes sure to enqueue the transition actions resulting from
the set-timer message delivery ahead of any enqueueing of the
timer-expired ground message, so that by the time the ground message
is processed, the relevant subscription always exists.
In a looser implementation, however, this level of synchronised
activity may not exist, and the ground message may overtake the
subscription establishment.
Therefore, I've changed the driver to instead use ground /assertions/
to signal expired timers. Upon processing of such an assertion, the
driver cleans it up. This is very similar to hardware interrupts,
where the driver has to "clear the interrupt" in order to let the
system continue properly.