Skip to main content

Expressions

Rules aren't limited to just pattern matching — you can compute values in the head and filter with comparisons in the body.

Arithmetic (rule heads)

Arithmetic expressions appear in rule heads to compute derived values.

Integer operators

These work on all integer types (int8 through int64, uint8 through uint64):

OperatorDescriptionExample
+Additionx + 1
-Subtractionx - y
*Multiplicationx * 2
/Integer divisionx / 3
%Modulox % 2

Heads up: expressions are parsed left-to-right without precedence. So x + y * z means (x + y) * z, not x + (y * z). When in doubt, use parentheses.

String concatenation

The cat operator glues two strings together:

OperatorDescriptionExample
catString concatenationx cat y

Examples

.decl Arc(src: int32, dst: int32, weight: int32)
.decl DoubleWeight(src: int32, dst: int32, w: int32)
.decl FullName(id: int32, full: string)
.decl Person(id: int32, first: string, last: string)

// Arithmetic in the head
DoubleWeight(x, y, w * 2) :- Arc(x, y, w).

// String concatenation in the head
FullName(id, first cat " " cat last) :- Person(id, first, last).

Comparisons (rule bodies)

Comparisons appear in rule bodies to filter tuples. They test a condition between two values:

OperatorDescriptionExample
=Equalx = y
!=Not equalx != y
>Greater thanx > 0
<Less thanx < 100
>=Greater or equalx >= y
<=Less or equalx <= y

Examples

// Filter: only keep arcs where weight exceeds 100
Heavy(x, y) :- Arc(x, y, w), w > 100.

// Same-generation query: pairs sharing a common ancestor, but not the same node
Sg(x, y) :- Arc(a, x), Arc(a, y), x != y.
Sg(x, y) :- Arc(a, x), Sg(a, b), Arc(b, y).