pub struct Edge {
pub guard: Option<LeafId>,
pub label: Transition,
pub target: ThreadStateId,
}Expand description
One edge out of a ThreadStateId in a compiled Automaton: the
condition/action it carries (Transition) plus the state it leads to.
T9 (docs/superpowers/plans/2026-10-03-sva.md) adds this type (and
State/Automaton below) – T4’s own skeleton defined
Transition’s five label shapes but, by its own module doc comment
(“no lowering yet”), never wired a target state onto any of them, so
there was no way yet to connect two states into an actual graph. T9 is
the first task that builds a real automaton, so it is the one that
completes the IR with the missing graph structure.
guard, a deliberate, documented addition beyond the plan’s literal
text. Plan §1.2 says a Boolean leaf (16.6) is evaluated by the engine
and “the automaton engine calls these compiled leaves” – but it never
says which edge a leaf’s truth value gates, and Transition itself
has no LeafId field on its Delay/Epsilon/Match variants (only
Abort/LocalVarWrite carry one, and for a different purpose: an abort
condition and a match-item’s write value, neither of which is “the
per-tick Boolean this edge requires to be taken”). Without a place to put
that leaf reference, nothing in the IR could represent even the simplest
legal sequence, a (16.9.1: a lone Boolean expression as a sequence
matches over exactly one tick, true -> match, false -> no match) –
there is no way to say “this edge may be taken on a tick only if a
evaluates true” using Transition alone. Edge::guard closes that gap
at the EDGE level (not a sixth Transition variant, preserving T4’s own
“every LRM operator is built from these five shapes… not a sixth”
design intent): guard = Some(leaf) means this edge is eligible only on
a tick where leaf evaluates true; guard = None means the edge’s own
label is the only eligibility condition (a pure elapsed-tick window for
Delay, or unconditional for Epsilon/Match).
Two combinations matter in practice (both built by
vj-codegen::sva::build, T9):
guard = Some(leaf)+label = Epsilon: 16.9.1’s Boolean-leaf point-sample – “this tick,leafmust evaluate true”, costing zero ADDITIONAL elapsed ticks beyond the one it is sampled on (the thing that advances a sequence’s clock is a##/repetition operator between samples, never a sample’s own evaluation – confirmed against the well-known identitya[*3]spans exactly 2 ticks, i to i+2, not 3, which only holds if a bare leaf’s own cost is zero).guard = None+label = Delay { min, max }: the elapsed-tick window a##min:maxcycle delay (16.7) or an inter-repetition link (16.9.2’s implicit##1between consecutive repeats, or a wider search window for[->]/[=]’s nonconsecutive/goto repeats) imposes between two samples.
A guard has no polarity of its own: the gap of a goto/nonconsecutive
repetition (16.9.2, b[->n] == (!b[*0:$] ##1 b)[*n]) is guarded by a
SEPARATE leaf standing for the expression !b, which the builder marks
negated in its leaf table (LeafTable::is_negated). The negation must live
in the leaf, not on the edge, because it is a 4-state operator: !x is x,
which a Boolean context collapses to false, so !b holds only where b is
KNOWN false – not wherever b fails to hold, which an edge flag over a
leaf already collapsed to a bool could not tell apart.
Fields§
§guard: Option<LeafId>§label: Transition§target: ThreadStateIdTrait Implementations§
impl Eq for Edge
impl StructuralPartialEq for Edge
Auto Trait Implementations§
impl Freeze for Edge
impl RefUnwindSafe for Edge
impl Send for Edge
impl Sync for Edge
impl Unpin for Edge
impl UnsafeUnpin for Edge
impl UnwindSafe for Edge
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.