PPO on Lean-native GridWorld (Executable Example + Formal Model) #
This example complements torchlean ppo_cartpole:
torchlean ppo_cartpoleuses an external Python Gymnasium environment and checks every step against a Lean side trust-boundary contract (Runtime.RL.Boundary.Contract).- This example uses a Lean-native GridWorld and still runs the same PPO update in Lean.
Even though the environment is defined in Lean, we still validate every transition with the
boundary checker. That keeps the data model unified: downstream training code consumes
Spec.RL.ObservedTransition in a single format regardless of whether the source is a Lean-native
environment or an external sampler.
Formal hooks #
proofGridWorldhas an induced finite stochastic MDP (Spec.RL.FiniteStochastic.MDP) and a proof that it is well-formed (row-stochastic transition rows, $0\le\gamma<1$). That model uses the specification's sparse rewards; the training environment below uses shaped rewards.- The boundary checker can be turned into a Prop-level hypothesis via
Proofs.RL.Boundary.contractHolds_of_checkTransitionFin_eq_ok(seeNN/Proofs/RL/Boundary.lean), or you can use the proof-layer Gymnasium checked stepRuntime.RL.Gymnasium.Session.stepCheckedWithProof(NN/Proofs/RL/Gymnasium.lean) for external environments.
CLI flags #
--device cuda: run the Torch backend on CUDA (requires building with-K cuda=true).--updates <n>: number of PPO updates to run.--eval-every <n>: evaluate the greedy policy everynupdates.--eval-episodes <n>: number of evaluation episodes per checkpoint.--eval-max-steps <n>: maximum steps per evaluation episode.--log <path>,--policy <path>,--path <path>: override artifact output paths.
Run (from the repo root):
scripts/lake.sh -Kcuda=true build
scripts/lake.sh -Kcuda=true exe torchlean ppo_gridworld --device cuda \
--updates 1 --eval-every 1 \
--eval-episodes 1 --eval-max-steps 8
Artifacts:
- The executable writes widget-friendly JSON snapshots to
data/rl/by default:ppo_gridworld_trainlog.json,ppo_gridworld_policy.json,ppo_gridworld_path.json(override with--log,--policy,--path). - You can tune runtime cost with:
--updates,--eval-every,--eval-episodes,--eval-max-steps. - Visualize them in the editor via
NN/Examples/Models/RL/Views/PPOGridWorld.lean.
What this example does (and does not) guarantee #
- Because the environment dynamics are Lean code, you can reason about its properties directly (e.g. determinism, Markov property w.r.t. the explicit state, bounded rewards).
- The PPO/GAE update is implemented as Lean definitions and a TorchLean autograd program, so it is a natural target for formal proofs about the update equation.
- As in most practical PPO code, convergence and optimality are not guaranteed by this example; it is tuned for inspectability and type safety, not leaderboard performance.
References (primary):
- Schulman et al., "Proximal Policy Optimization Algorithms" (2017): https://arxiv.org/abs/1707.06347
- Schulman et al., "High-Dimensional Continuous Control Using Generalized Advantage Estimation" (2015): https://arxiv.org/abs/1506.02438
- Williams, "Simple statistical gradient-following algorithms for connectionist reinforcement learning" (REINFORCE, 1992): https://doi.org/10.1007/BF00992696
- Sutton and Barto, Reinforcement Learning: An Introduction (2nd ed., GridWorld examples): http://incompleteideas.net/book/the-book-2nd.html
- Puterman, Markov Decision Processes (finite discounted MDPs): https://doi.org/10.1002/9780470316887
Name of this executable target (used in CLI error messages and banners).
Instances For
Configuration #
Number of discrete actions (up/down/left/right).
Instances For
PPO rollout horizon (also the training batch size for this example).
Instances For
Discount factor used in returns / GAE.
Instances For
GAE(λ) parameter controlling the bias/variance tradeoff of advantage estimates.
Instances For
Adam learning rate used for the GridWorld actor-critic update.
Instances For
Number of PPO optimization epochs per collected rollout batch.
Instances For
Default maximum number of PPO updates (can be overridden by --updates).
Instances For
Default evaluation checkpoint interval (can be overridden by --eval-every).
Instances For
Default evaluation episodes per checkpoint (can be overridden by --eval-episodes).
Instances For
The observation tensor shape used by this example: [..., stateCount] one-hot vectors.
Instances For
Logits for a whole rollout: one row of action logits per timestep.
Instances For
Value estimates for a whole rollout, one per timestep.
Instances For
Action logits at a single timestep.
Instances For
A single value estimate, shaped [1] so it composes with the batched shapes above.
Instances For
Formal GridWorld model (spec/proof layer) #
We define a real-valued GridWorld model and record the proof that its stochastic-MDP view is valid.
The specification uses reward -1 before reaching the goal and 0 on arrival. The executable's
stepState below uses progress rewards and a goal reward of 1. This theorem concerns
proofGridWorld; it does not establish an equivalence with the shaped-reward training environment.
Start position (top-left cell).
Instances For
Goal position (bottom-right cell).
Instances For
A discount factor in [0,1) at the proof layer (ℝ) for the MDP instance.
Instances For
Proof-layer GridWorld instance over ℝ rewards/discounts.
Instances For
The induced finite stochastic MDP for proofGridWorld is well-formed
($0\le\gamma<1$, with row-stochastic transitions).
Lean-native runtime environment #
We implement a Gym-style environment (Spec.RL.Env) whose observations are one-hot vectors
over the flattened finite state space Fin stateCount.
The policy sees the same tensor shape as the Gymnasium-backed example and produces logits over a finite action set.
Start state encoded as Fin stateCount.
Instances For
Encode a discrete state as a one-hot observation.
Instances For
Manhattan distance to the goal.
Instances For
Deterministic GridWorld transition function with dense progress rewards.
Reaching the goal yields 1; other nonterminal moves yield the decrease in Manhattan distance
minus 0.05. The goal remains absorbing with reward 0. These shaped rewards differ from those
of proofGridWorld; no policy-equivalence theorem is claimed here.
Instances For
Lean-native environment packaged as a Spec.RL.Env for reuse with the generic RL runtime.
Instances For
Trust boundary contract #
Even though this environment is Lean-native, we keep a contract in play to exercise the “checked preconditions” workflow and to keep the interface identical to the external Gymnasium collector.
Model (Actor + Critic) #
Instances For
Construct the actor network as an MLP mapping one-hot observations to action logits.
Instances For
Construct the critic network as an MLP mapping one-hot observations to a scalar value estimate.
Instances For
Rollout collection (Lean-native environment) #
Collect a fixed-horizon PPO rollout from the Lean-native environment using a checked session.
This is an example-local rollout operation around rl.ppo.collect that packages:
- a
Spec.RL.Envas arl.session.CheckedSession, and - the (actor, critic) prediction functions at observation shape.
Instances For
Evaluation #
Evaluation APIs live in rl.eval.
Main Training Loop #
Entry point for scripts/lake.sh exe torchlean ppo_gridworld.
This executable:
- runs PPO updates against a Lean-native GridWorld environment,
- periodically evaluates the greedy policy and logs the average return,
- writes widget-friendly JSON artifacts (training curve, greedy policy snapshot, greedy path snapshot).