Markov Labs

Documentation

Chain DSL

Updated September 1, 2026

The chain generator accepts a line-oriented text format for declaring a graph, positioning its states, and assigning transition probabilities. Paste a complete definition into the text editor on the chain generator, then click Apply.

Complete example

This directed Cartesian chain has two states and four transitions.

directed
cartesian

node Sunny -1 0
node Rainy 1 0

edge Sunny Sunny 3/4
edge Sunny Rainy 1/4
edge Rainy Sunny 0.4
edge Rainy Rainy 0.6

Each nonempty line is one declaration. Blank lines are ignored. The graph mode and coordinate mode must appear before every node or edge.

Applying changes

Document structure

A chain definition begins with one graph mode and one coordinate mode, in either order. Nodes and edges follow both declarations.

directed | undirected
cartesian | polar <interval-count>
param <single-letter-name> [=] <value>
node <name> <coordinate-1> <coordinate-2> [uniform]
edge <from> <to> [weight] [straight]

Graph mode

directed

Edges have an arrow from the source state to the destination state. Each ordered pair may be declared at most once.

undirected

The graph displays connected states without arrowheads, but transition probabilities remain directional. If an edge is declared in only one direction, the parser creates the missing reverse edge. Its weight is 0, unless the reverse source node is uniform. Declare both directions when they need distinct nonzero probabilities.

Routing is shared by the two directional records of an undirected connection. Adding straight to either direction applies the preference to both.

undirected
cartesian
node A 0 0
node B 2 0
edge A B 1

Applying this definition produces both A → B with weight 1 and B → A with weight 0.

Coordinate mode

cartesian

Cartesian nodes use integer x and y coordinates. Coordinates may be negative, and no node is required at the origin.

cartesian
node Left -2 0
node UpperRight 2 3

polar <interval-count>

Polar nodes use an integer radius followed by an integer interval index. The interval count must be at least 3. Index 0 lies on the positive x-axis, and indices advance counterclockwise.

polar 12
node Origin 0 0
node Top 2 3
node Left 2 6

Parameters

param <single-letter-name> [=] <value>

A parameter gives a reusable transition probability a single-letter name. Its value may be an exact constant expression whose result is from 0 through 1, inclusive. Parameter names are case-sensitive and may not be repeated.

directed
cartesian
param p 1/3
node A 0 0
node B 2 0
edge A A p
edge A B 1-p

Constant expressions support decimal and integer literals, addition, subtraction, multiplication, division, parentheses or braces, and integer powers. LaTeX fractions and the multiplication commands \cdot and \times are also accepted. Expressions are evaluated exactly; for example, 1 / 2^5 has value 1/32. Negative exponents may be written as 2^-5, 2^(-5), or 2^{-5}. Exponents must be integers. Nested powers, implicit multiplication, variables, and percentages are not accepted as constant expressions.

Edges may use the parameter directly, such as p, or its complement, such as 1-p. Other arithmetic expressions are not accepted. The optional equals sign in param p = 1/3 is accepted, but canonical text omits it.

After parameterized text is applied, the chain generator exposes temporary live controls for its parameters. A live value changes the current visualization and calculations without changing the canonical text or saved chain. The editable value accepts the same exact constant expressions as a parameter declaration; its slider remains a hundredth-granularity approximation of that exact value.

Nodes

node <name> <coordinate-1> <coordinate-2> [uniform]

A node name identifies the state in later edge declarations. Names and positions must be unique.

Uniform outgoing probabilities

Add uniform to divide probability equally across every edge leaving the node. Edges from a uniform node must not include weight tokens.

directed
cartesian
node Start 0 0 uniform
node Heads 2 1
node Tails 2 -1
edge Start Heads
edge Start Tails

Here each outgoing edge from Start has effective probability 1/2. Adding or removing an outgoing edge changes the uniform probability automatically.

Edges and weights

edge <from> <to> [weight] [straight]

Both endpoints must match declared node names. Self-loops are allowed. Each directional source-destination pair may appear only once.

A non-uniform edge weight may be an exact constant expression whose result is from 0 through 1, inclusive, using the same constant grammar as parameter values. It may also be a declared single-letter parameter or that parameter's complement in the exact form 1-p. Expressions involving parameters, such as p^2 or p/2, are not accepted. If the weight is omitted, it defaults to 0.

edge A A 1 / 2^5
edge A B 0.5
edge A C

Individual weights are range-checked when the text is applied. The Probability Checker separately determines whether all outgoing weights from each state sum to exactly 1.

Straight routing preference

Add straight after the optional weight to prefer a straight path. Automatic routing is used when the option is absent. If another node obstructs the straight segment, the preference is retained while the edge temporarily uses automatic routing; the straight path returns when the obstruction clears. Self-loops cannot use straight.

edge A B straight
edge A C 1/2 straight

Names and comments

Names containing whitespace or # should be enclosed in double quotes. The canonical serializer leaves names containing only letters, numbers, underscores, periods, and hyphens unquoted; it adds double quotes around other names.

node A_1 0 0
node "Waiting Room" 2 0
edge A_1 "Waiting Room" 1

Inside a quoted name, write \" for a literal double quote and \\ for a literal backslash.

A # outside double quotes begins a comment. Full-line and trailing comments are both accepted.

# Two-state absorbing chain
node Active 0 0
node Absorbed 2 0 # terminal state
edge Absorbed Absorbed 1

Validation and canonical output

The parser rejects a definition when it contains:

The editor uses the same shared parser and serializer as saved chains and embedded chain diagrams. After a definition is applied, the text editor may rewrite it into canonical form: declarations are normalized, names are quoted when required, consecutive expression whitespace is collapsed to one space, entered constant expressions are preserved, and generated reverse edges in undirected graphs are made explicit.