Skip to main content

Rule Syntax

Rules express temporal constraints using modal mu-calculus.

Submitting Rules

When adding a rule to a contract, you must include a model that witnesses satisfiability:

modal c commit \
--method rule \
--rule 'rule my_rule { formula { always (+predicate(...)) } }' \
--model 'model witness { initial s; s -> s [] }' \
--sign key.pem

The model proves the rule can be satisfied. Without a satisfying model, the rule commit is rejected. This prevents adding unsatisfiable rules that would deadlock the contract.

Basic Structure

rule <name> {
starting_at <commit_ref>
formula {
<modal_formula>
}
}

// Or as default export
export default rule {
starting_at $PARENT
formula {
<modal_formula>
}
}

Anchoring (starting_at)

starting_at $PARENT           // Parent of this commit
starting_at $ROOT // Genesis commit
starting_at abc123... // Specific commit hash
OperatorMeaning
[ACTION] φAfter ALL ACTION transitions, φ holds
<ACTION> φAfter SOME ACTION transition, φ holds
[-ACTION] φIf ACTION is refused/impossible, φ holds
[<+ACTION>] φCommitted: CAN do ACTION and CANNOT refuse

Temporal Operators (Syntactic Sugar)

always(φ)           // φ holds forever (invariant)
// = gfp(X, φ & []X)

eventually(φ) // φ holds now or sometime later
// = lfp(X, φ | <>X)

until(p, q) // p holds until q becomes true
// = lfp(X, q | (p & <>X))

Fixed Points

// Greatest fixed point (νX) - invariants, safety
gfp(X, property & []X)

// Least fixed point (μX) - reachability, liveness
lfp(X, target | <>X)

// Unicode alternatives
νX. (property & []X)
μX. (target | <>X)

Boolean Connectives

φ & ψ           // Conjunction (and)
φ | ψ // Disjunction (or)
!φ // Negation (not)
φ -> ψ // Implication
true // Always true
false // Always false