[{"data":1,"prerenderedAt":4},["ShallowReactive",2],{"OAqjawrNJN":3},"# dLean\n\ndLean is a shallow embedding of [differential dynamic logic (dL)](https://doi.org/10.1007/978-3-319-63588-0) in Lean 4 for verifying cyber-physical systems. It represents hybrid programs—nondeterministic programs combining discrete and continuous dynamics—as ordinary monadic Lean programs that can be verified using Lean's `mvcgen` framework. This approach scales from scalar systems to vector-valued dynamics and QdL-style multi-agent models while reusing Lean and Mathlib's existing infrastructure. Because LLMs are effective at constructing Lean proofs, dLean proofs are also well suited to LLM-based automation at scale.\n\n## Hybrid programs\n\nA hybrid program combines discrete control with continuous physical evolution. \n\nAs an example from the [LFCPS book](https://doi.org/10.1007/978-3-319-63588-0), consider a bouncing ball with height `x` and vertical velocity `v`. Let `g > 0` denote gravitational constant, `c` is damping factor applied at each bounce, and `r ≥ 0` models air resistance. \n\nThe hybrid program is as follows: If the ball is on the ground `(x = 0)`, the controller reverses and scales its velocity by assigning `v := -c * v`. Between bounces, the ball follows one of two ODEs: `up` describes upward motion `(v ≥ 0)`, while `down` describes downward motion `(v ≤ 0)`.\n\nFirst, we define the upward ODE `{ x' = v, v' = -g - r*v^2 }` \nwith its domain constraint `(x >= 0 & v >= 0)`, and likewise the downward ODE\n`{ x' = v, v' = -g + r*v^2 }` with the domain `(x >= 0 & v \u003C= 0)`.\n\n```lean\ndef up (g r : ℝ) : ℝ × ℝ → ℝ × ℝ\n  | (_x, v) => (v, -g - r * v ^ 2)\n\ndef upDomain : ℝ × ℝ → Prop\n  | (x, v) => 0 ≤ x ∧ 0 ≤ v\n\ndef down (g r : ℝ) : ℝ × ℝ → ℝ × ℝ\n  | (_x, v) => (v, -g + r * v ^ 2)\n\ndef downDomain : ℝ × ℝ → Prop\n  | (x, v) => 0 ≤ x ∧ v ≤ 0\n```\n\nThe return type of the hybrid program that we will define will be `SetM ℝ`. It is an ordinary set of real numbers represented by its membership predicate. The `SetM` monad's bind operation provides sequential composition: every possible result of one program is passed to the next program, and all possible outputs are collected into a single set. The bouncing-ball hybrid program can therefore be written using Lean's `do` notation as follows:\n\n```lean\ndef prog (g c r x v : ℝ) : SetM ℝ := do\n  let mut (x, v) := (x, v)\n  let n ← choose ℕ\n  for _ in [:n] do\n    if x = 0 then\n      v := -c * v\n    (x, v) ← (evolve (up g r) upDomain ∪\n              evolve (down g r) downDomain) (x, v)\n  return x\n```\n\nThe program nondeterministically chooses an `n : ℕ` and executes the loop exactly `n` times. `evolve (up g r) upDomain ∪ evolve (down g r) downDomain` is a nondeterministic choice between upward and downward motion. In either branch, `evolve` follows any valid trajectory of the selected ODE from the current `(x, v)` for an arbitrary nonnegative duration, requires its domain condition to hold throughout, and returns the reached position and velocity pair.\n\nThe corresponding Lean safety statement says that every result position `x_res` of the ball is between the ground and the initial height bound is as follows:\n\n```lean\ntheorem aerodynamic_quantum_safe :\n    ∀ g H c r x v,\n      (x ≤ H ∧ v = 0 ∧ 0 ≤ x) ∧ (0 \u003C g ∧ c ≤ 1 ∧ 0 ≤ c ∧ 0 ≤ r) →\n        ∀ x_res ∈ SetM.run (prog g c r x v), 0 ≤ x_res ∧ x_res ≤ H := sorry\n```\n\nIt corresponds to the following dL formula:\n\n```text\n  (x\u003C=H & v=0 & x>=0) &\n  (g>0 & 1>=c&c>=0 & r>=0)\n ->\n  [\n    {\n      {?x=0; v:=-c*v;  ++  ?x!=0;}\n      {{x'=v,v'=-g-r*v^2&x>=0&v>=0} ++ {x'=v,v'=-g+r*v^2&x>=0&v\u003C=0}}\n    }*\n  ] (0\u003C=x&x\u003C=H)\n```\n\nQuantifying over every member of the resulting set corresponds to the box modality: the postcondition must hold after every possible execution.\n\nTo prove the safety theorem, a loop invariant can be supplied to `mvcgen`, which decomposes the monadic program and generates the required verification conditions. Continuous evolution is handled by applying theorems from the dLean library that represent the dL proof rules: `dI` proves differential invariants, `dC` introduces differential cuts, and `dW` derives consequences of the evolution domain.\n\nThe automatic differentiation tactics discharge the analytic side of these rules and the remaining arithmetic is proved using Lean and Mathlib.\n\nState spaces beyond real-valued variables require almost no additional machinery: vectors are supported directly by Mathlib, while QdL-style collections of objects are represented as ordinary Lean functions from object identifiers to their values. Look at the examples under `dLean/Examples`\n\n## Install and build\n\n```sh\ngit clone REPOSITORY_URL\ncd dLean\nlake update\nlake exe cache get\nlake build\n```\n\n## Proof automation\n\nThe benchmark harness in `agentic/prove.sh` prepares a sandbox workspace, runs Codex or Claude Code (only Codex has been tested), and checks the generated `Solution.lean` independently with Lean Comparator. Reference `Proof.lean` files are not copied into the workspace.\n\nThe repository includes a [dLean prover skill](agentic/skills/dlean-prover/SKILL.md). The harness copies it into each agent workspace and instructs the agent to read it before proving.\n\nJudging requires Lean Comparator and lean4export compatible with dLean's Lean toolchain, and Landrun on a Linux system that supports its sandbox. Clone [Comparator](https://github.com/leanprover/comparator) and build with:\n\n```sh\nlake build lean4export comparator\n```\n\nBack in the dLean repository, configure the executable locations:\n\n```sh\nexport COMPARATOR_ROOT=/absolute/path/to/comparator\nexport COMPARATOR_LANDRUN=/absolute/path/to/landrun\n```\n\nRun the complete workflow from the repository root (it creates the agent workspace under ./benchmark-results):\n\n```sh\nagentic/prove.sh run dLean/Examples/BouncingBall codex --model gpt-6-astra\n```\n\nThe stages can also be run separately:\n\n```sh\nagentic/prove.sh prepare dLean/Examples/BouncingBall ./BouncingBall-sandbox\nagentic/prove.sh agent codex ./BouncingBall-sandbox\nagentic/prove.sh judge dLean/Examples/BouncingBall ./BouncingBall-sandbox/Solution.lean\n```\n\nRun `agentic/prove.sh help` for more information.\n",1789154852419]