Formalized finite-trace scene-flow monitoring in Lean 4.
This project encodes driving-scene safety properties as temporal formulas, evaluates them on finite traces, and includes mechanized metatheory in Lean. It also provides a data pipeline that converts RSV graph frames plus ego logs into a generated Lean trace and runs the monitor on real sample data.
This repository is a quick prototype to see Lean 4's capabilities for this domain. For the original work that inspired this, see the SGSM & SceneFlowLang projects:
- Lean specification and semantics in
SceneFlowSpec/*.lean - Example properties in
SceneFlowSpec/Examples.lean - Theorem proofs in
SceneFlowSpec/Theorems.lean - Data adapter/checker in
scripts/run_sceneflow_checks.py
The project is pinned by lean-toolchain to Lean v4.28.0.
Install Lean/Lake via elan if needed:
curl https://raw.githubusercontent.com/leanprover/elan/master/elan-init.sh -sSf | shThen in this repo:
lake update
lake buildRequired by the data adapter:
conda env create -f environment.yml
conda activate scene-flow-spec-leanBuild/check the Lean project:
lake buildRun evaluators embedded in example files:
lake env lean SceneFlowSpec/Examples.lean
lake env lean SceneFlowSpec/Theorems.leanFrom repo root:
python scripts/run_sceneflow_checks.pyThis command:
- Reads
sceneflow_sample/data/rsv/*.pklandsceneflow_sample/data/ego_logs.json. - Generates
SceneFlowSpec/GeneratedTrace.lean. - Runs
lake env leanon that generated file.
The generated run uses SceneFlowLang-style symbolic groundings: it discovers
vehicles, lanes, and junctions in the trace, then instantiates the current
property schemas for the concrete entity IDs instead of assuming ego is ID 1.
By default this checks all vehicle bindings, matching SceneFlowLang's all-vehicle
mode.
- intersection yielding
- following distance
- opposing-lane clearing while passing
Generate only (skip Lean execution):
python scripts/run_sceneflow_checks.py --no-runUse a different input dataset directory:
python scripts/run_sceneflow_checks.py --data-dir path/to/dataCheck only relationships grounded around the entity named ego:
python scripts/run_sceneflow_checks.py --ego-onlyWrite generated Lean to a custom output path:
python scripts/run_sceneflow_checks.py --output SceneFlowSpec/GeneratedTrace.lean