Skip to main content

DSL Quick Reference

One-line syntax for every construct. For full semantics, see the DSL Reference.

Patterns

pattern <name> {
...
}
pattern betrayal {
stage e1 {
e1.type = "betray"
}
}

Stages

A stage is an event slot. The anchor name (e1) becomes the source for clauses inside the block.

stage <anchor> {
<clauses>
}
stage e1 {
e1.type = "greet"
e1.actor -> ?who
}

Clauses

String match

source.label = "value"
e1.location = "throne_room"

Numeric match

source.label = <number>
e1.points = 100

Boolean match

source.label = true | false
e1.active = true

Variable binding

Bind a target node to a variable with ->. The same ?var in a later stage creates a join.

source.label -> ?var
e1.actor -> ?char

Node reference

Match a specific named node (no ? prefix).

source.label -> node_name
e1.actor -> alice

Cross-stage comparison

Compare a value against a previously bound variable. Operators: >, <, >=, <=, =.

source.label > ?var
source.label < ?var
source.label >= ?var
source.label <= ?var
source.label = ?var
e2.severity > ?level

Note: = ?var compares values. -> ?var binds/joins node references. They are not interchangeable.

Negated clause

Prefix with !. Works with literal values and node references only.

! source.label = "value"
! e1.status = "invited"

Negation Windows

Unless between

No matching event between two stages.

unless between <start> <end> {
<clauses>
}
unless between e1 e2 {
mid.type = "fulfill"
mid.actor -> ?char
}

Unless after

No matching event after a stage (open-ended).

unless after <start> {
<clauses>
}
unless after e2 {
end.type = "resolve"
end.actor -> ?char
}

Unless global

No matching event across the entire pattern span.

unless {
<clauses>
}
unless {
mid.type = "reconcile"
mid.actor -> ?char
}

Temporal Constraints

Allen relation (qualitative)

All 13 Allen relations: before, after, meets, met_by, overlaps, overlapped_by, during, contains, starts, started_by, finishes, finished_by, equals.

temporal <left> <relation> <right>
temporal e1 before e2

Metric gap

Add a bounded distance constraint to any Allen relation.

temporal <left> <relation> <right> gap <min>..<max>
temporal e1 before e2 gap 0..100

Other gap forms: ..10 (no min), 3.. (no max), 5 (exact).

Concurrent Groups

Stages inside concurrent { } can match in any order. All must match before the pattern advances past the group.

concurrent {
stage <a> { ... }
stage <b> { ... }
}
concurrent {
stage e2 {
e2.type = "temp_spike"
e2.sensor -> ?s
}
stage e3 {
e3.type = "pressure_drop"
e3.sensor -> ?s
}
}

Composition

Sequence

Concatenate two patterns. sharing(...) joins variables across them.

compose <name> = <a> >> <b> sharing(<var>, ...)
compose promise_kept = setup >> payoff sharing(char)

Choice

Exclusive choice -- when one alternative completes, siblings are killed.

compose <name> = <a> | <b> | <c>
compose crisis = war | famine | plague

Exact repeat

compose <name> = <pattern> * <count> sharing(<var>, ...)
compose three_strikes = offense * 3 sharing(offender)

Range repeat

Match N to M times. Also supports unbounded: * 3.. (3 or more).

compose <name> = <pattern> * <min>..<max> sharing(<var>, ...)
compose brute_force = login_fail * 5..10 sharing(acct)

Metadata

Attach key-value pairs to a pattern. Propagated to matches and events.

meta("<key>", "<value>")
meta("thread_type", "conflict")
meta("priority", "high")

Deadline

Expire partial matches after N ticks without completion.

deadline <ticks>
deadline 30

Graph (testing / playground)

Define a test graph with timestamped edges.

graph {
@<time> source.label = <value>
@<time> source.label -> <node>
@<start>..<end> source.label = <value>
now = <number>
}
graph {
@1 e1.type = "enter"
@1 e1.actor -> alice
@5..10 e2.type = "siege"
now = 15
}

Comments

// Line comments start with //
e1.type = "enter" // end-of-line comments too