gqlrules is a lightweight proof-of-concept runner for the GQL Rules project. It:
- parses
.gqlrrule-program files (rule headers,MODE,BODY/HEADblocks), - does not parse the inner Cypher itself (wrapper-only design),
- concatenates
BODY + HEADinto executable Cypher statements, - runs rules iteratively until a fixpoint is reached (no further changes),
- writes execution metrics to JSON and, optionally, CSV.
This PoC is optimized for a locally running Neo4j instance available at:
- Neo4j Browser:
http://localhost:7474 - Bolt:
bolt://localhost:7687
Docker is intentionally not used in this artifact.
- The parser is wrapper-only: it understands the outer
.gqlrstructure, but it does not parse or validate the Cypher insideBODYandHEAD. - In v0.1, each rule is expected to end with:
RETURN <int> AS changes
This is required to detect whether a fixpoint has been reached.
- The artifact is intended for local Neo4j execution and research reproducibility, not as a production-grade rule engine.
- Python 3.10 or newer
- Neo4j (Desktop or Server) running locally
- Python package
neo4j(installed from the project dependencies) - (optional) APOC, if your rules call
apoc.*
-
Make sure Neo4j is running and the Browser is available at:
http://localhost:7474
-
Make sure Bolt is available at:
bolt://localhost:7687
-
Make sure you know:
- the username (usually
neo4j) - the password configured in Neo4j Desktop/Server
- the username (usually
If you use APOC, enable the relevant APOC settings in your Neo4j installation. In Neo4j Desktop this is usually handled through the Plugins panel.
Run the following commands from the implementation-PoC/ directory:
python3.10 -m venv .venv
source .venv/bin/activate
pip install -U pip
pip install -e .[dev]If you do not need the development extras, use:
pip install -e .The package installs the CLI entry point:
gqlr --helpIf you do not install the package, you can still run the CLI with:
PYTHONPATH=src python3 -m gqlrules.cli --helpIt is recommended to use environment variables instead of passing credentials on the command line:
export NEO4J_URI="bolt://localhost:7687"
export NEO4J_USER="neo4j"
export NEO4J_PASSWORD="YourPassword"
export NEO4J_DATABASE="neo4j"On Windows PowerShell:
$env:NEO4J_URI="bolt://localhost:7687"
$env:NEO4J_USER="neo4j"
$env:NEO4J_PASSWORD="YourPassword"
$env:NEO4J_DATABASE="neo4j"CLI defaults in the current PoC implementation are:
--uri bolt://localhost:7687--user neo4j--password domeldomel--database neo4j
The password default is only a convenience fallback in the research artifact. In any real setup, override it explicitly.
Minimal example:
RULE suspiciousTransfers MODE LOG {
BODY:
MATCH (a:Account)-[t:TRANSFER]->(b:Account)
WHERE t.amount > 10000
HEAD:
MERGE (t)-[:HAS_FLAG]->(:Flag {name:"SUSPICIOUS"})
RETURN count(*) AS changes
}
Important notes:
- the outer wrapper (
RULE,MODE,BODY,HEAD) is parsed by the PoC, - the Cypher inside
BODYandHEADis passed through as text, - each rule must end with
RETURN ... AS changes.
Print the parsed AST as JSON:
gqlr parse examples/banking/program.gqlrGenerate .cypher artifacts and a manifest:
gqlr compile examples/banking/program.gqlr --out out/Execute the program to fixpoint and write a report:
gqlr run examples/banking/program.gqlr --reports-dir reports/Optional useful flags:
--csvto also write a per-rule CSV report--max-rounds <N>to bound the fixpoint loop--shuffle --seed <N>to perturb rule order for determinism checks
If you do not use environment variables:
gqlr run examples/banking/program.gqlr \
--uri bolt://localhost:7687 \
--user neo4j \
--password "domeldomel" \
--database neo4jRun a bundled end-to-end scenario:
gqlr demo bankingDocumented demo scenarios:
banking- transfers, flagging rules, and defaultsfamily- derived family relations and transitive closurecompliance- high-value events, default metadata, and frequent-recipient patterns
Examples:
gqlr demo family
gqlr demo complianceWithout installing the package:
PYTHONPATH=src python3 -m gqlrules.cli demo bankingBy default, a demo run will:
- execute
examples/<demo>/constraints.cypherif present, - execute
examples/<demo>/load.cypherif present, - run the rules to fixpoint,
- execute
examples/<demo>/postconditions.cypherif present, - write reports under
reports/.
The examples/ directory contains:
banking/,family/,compliance/- main end-to-end demo scenariosminimal/- small parser/compiler examples, including invalid inputsmode_robustness/- examples forSTRICT,LOG, andIGNOREclosure_scale/- synthetic recursive-closure input used in evaluation
After run (and also after demo), the PoC writes:
reports/<run_id>.jsonreports/<run_id>.csvif--csvis enabled
Reports include, among other things:
- number of rounds,
- per-round timing,
- per-rule changes,
- termination status,
- errors or diagnostics reflected by the chosen
MODE.
The out/ and reports/ directories are generated locally and are intentionally excluded from version control.
IGNORE: rule errors do not stop execution; the failing rule contributeschanges=0LOG: same continuation behavior asIGNORE, but the report contains fuller error informationSTRICT: the first rule error aborts the whole run
This directory also contains the scripts used for the evaluation artifact described in the paper:
scripts/run_evaluation.pyscripts/run_large_scale_e5.py
They can be run without package installation via:
PYTHONPATH=src python3 scripts/run_evaluation.py --help
PYTHONPATH=src python3 scripts/run_large_scale_e5.py --helpFor the exact evaluation protocol, expected inputs, and generated artifacts, see Reproducibility.md.
Unit tests:
pytest -qIntegration tests require a live Neo4j instance and the following environment variables:
NEO4J_URINEO4J_USERNEO4J_PASSWORD- optionally
NEO4J_DATABASE
Example:
export NEO4J_URI="bolt://localhost:7687"
export NEO4J_USER="neo4j"
export NEO4J_PASSWORD="domeldomel"
export NEO4J_DATABASE="neo4j"
pytest -q -m integration- check that Neo4j is running,
- check that Browser works on port
7474, - check that Bolt works on port
7687, - check username, password, and database name.
Add:
RETURN ... AS changes
at the end of the rule head.
- enable the APOC plugin in Neo4j, or
- remove or rewrite the parts of your rules that call
apoc.*.
This is a research PoC / artifact with a deliberately simple execution model (wrapper-only). The next natural development step is manual stratification and, optionally, hybrid dependency analysis.