Locy Syntax Cheatsheet¶
Rule¶
CREATE RULE name [PRIORITY n] AS
MATCH ...
[WHERE ...] // pre-aggregation filter
[ALONG x = expr]
[FOLD agg = aggregate(expr)]
[WHERE agg_condition] // post-FOLD filter (HAVING)
[BEST BY expr ASC|DESC]
YIELD KEY a, value AS alias, prob_expr AS PROB
// OR, for graph mutation rules (edge/node props are inline maps, no SET):
DERIVE (src)-[:TYPE {prop: expr}]->(dst)
The second WHERE (after FOLD) filters on aggregated values — equivalent to SQL's HAVING. It can reference FOLD output columns and KEY columns.
FOLD Aggregators¶
| Operator | Semantics | Use In Recursion? |
|---|---|---|
COUNT(*) / COUNT(expr) |
Row count | Safe (unbounded) |
SUM(expr) |
Arithmetic sum | Non-recursive only |
AVG(expr) |
Arithmetic mean | Non-recursive only |
MIN(expr) |
Minimum value | Safe in recursion |
MAX(expr) |
Maximum value | Safe in recursion |
COLLECT(expr) |
Collect into list | Safe (unbounded) |
MSUM(expr) |
Monotonic sum (non-decreasing) | Safe (unbounded) |
MMAX(expr) |
Monotonic maximum | Safe in recursion |
MMIN(expr) |
Monotonic minimum | Safe in recursion |
MCOUNT(expr) |
Monotonic count | Safe (unbounded) |
MNOR(expr) |
Noisy-OR probability: 1 − ∏(1 − pᵢ) |
Safe in recursion |
MPROD(expr) |
Product probability: ∏ pᵢ |
Safe in recursion |
Recursion safety comes from the aggregate's registered semilattice (monotone_join), not from an M prefix; the compiler falls back to the six built-in M* names only when the aggregate registry has no entry. SUM and AVG are non-monotone and are rejected inside a recursive stratum.
The aggregates marked unbounded are monotone but have no top element, so a recursive fold over one can iterate until max_iterations rather than converging — the iteration cap is the backstop. The exception is COLLECT, which is assembled after the fixpoint rather than tracked inside it, so it does not itself keep the loop iterating.
Goal Query¶
Derive Command¶
Explain¶
Assume¶
Abduce¶
Neural Predicates¶
CREATE MODEL name AS
INPUT (binding [: Label])
[FEATURES feature_expr (, feature_expr)*]
[FEATURES (subject, column) FROM source_rule]
OUTPUT (PROB | SCORE | LABEL | VECTOR) result_name
USING xervo('provider_alias' [, embedder = 'embed_alias'])
[CALIBRATION (platt_scaling | isotonic_regression | temperature_scaling | beta_calibration | dirichlet | conformal | conformal(alpha) | none)]
[VERSION 'string']
CALIBRATE model_name ON MATCH pattern [WHERE expr] TARGET expr METHOD calibration_method [HOLDOUT n]
VALIDATE model_name ON MATCH pattern [WHERE expr] TARGET expr METRICS metric (, metric)*
metric ∈ brier_score | ece | debiased_ece | accuracy | log_loss | auc. The classifier-registry key is the CREATE MODEL <name>, not the USING xervo('alias') provider hint. The feature dict the callable receives is keyed by the INPUT binding name; values are the evaluated argument expressions at the call site. See Neural Predicates.