Skip to content

13. Derived labels and relationships — DERIVE rules

A rule set defines a derived label: a label that exists on no stored node, whose membership is CONCLUDED from data by rules — including rules that refer to the label they are defining. A rule set may equally define a derived relationship — an edge whose existence is a conclusion (§13.4); everything in this section reads the same for both, with membership a node for a label and an ordered pair for a relationship. That self-reference is the point: it expresses propagation no single query can — ownership chains, phoenix succession, status that feeds back into further status. Where a view (§8) saves one query, a rule set is many unordered clauses of one definition, evaluated to a least fixpoint. A view cannot reference itself; a rule may.

# rules/phoenix-succession.yml — one rule set per file (shipped by realm-gov-uk)
name: gov-uk/phoenix-succession
derives: PhoenixSuccessor
description: >-
An appointment that follows the same officer's appointment at a company the register now
records as dissolved; phoenixDepth counts dissolved predecessors in the chain.
rules:
- derive: "(b:PhoenixSuccessor)"
from: |
MATCH (a:UkAppointment {companyStatus: 'dissolved'}), (b:UkAppointment)
WHERE b.officerId = a.officerId AND b.companyNumber <> a.companyNumber
AND a.appointedOn IS NOT NULL AND b.appointedOn IS NOT NULL
AND b.appointedOn > a.appointedOn
- derive: "(c:PhoenixSuccessor {phoenixDepth: d})"
from: |
MATCH (b:PhoenixSuccessor), (c:UkAppointment)
WHERE c.officerId = b.officerId AND c.companyNumber <> b.companyNumber
AND b.companyStatus = 'dissolved'
AND b.appointedOn IS NOT NULL AND c.appointedOn IS NOT NULL
AND c.appointedOn > b.appointedOn
WITH c, max(coalesce(b.phoenixDepth, 1) + 1) AS d

Each rule is a head and a body — read it as an implication:

  • derive is a node pattern — or, for a derived relationship, a relationship pattern (§13.4) — naming what the rule concludes: which body variable becomes a member, and (optionally) derived properties computed from body bindings. Its one label (or relationship type) must be the rule set’s derives. Quote it: property maps contain : , which YAML would otherwise read as a nested mapping.
  • from is ordinary read-only Virtual Cypher that BINDS variables and stops — no RETURN. The head is the projection; the host constructs the runnable query from the parsed head, and both productions are parsed by the real Cypher parser (the same §8.1 stance: no new grammar in queries, definition is metadata).

Semantics in one sentence: a node carries the label — a pair of nodes carries the relationship — if and only if some rule concludes it. Rules are unordered clauses — reordering them cannot change the result — and evaluation runs to a fixpoint, so a member concluded by one rule can satisfy another rule’s body; the second rule above chains through its own conclusions, which is how a depth-unbounded pattern is expressed in two clauses. Two rule sets may derive the same label: that is the union of their clauses, not a conflict. The classic worked case is the OFAC 50 Percent Rule — blocked if listed, or if blocked parties in AGGREGATE own ≥ 50%, recursively — where the entity that matters is on no list and no fixed-depth query can be correct for all data.