- Add docs/hanoi-demo.md with full execution instructions - Add scripts/gen_hanoi.py for generating larger formulas - Include pre-generated 7-disk formula (127 moves) - 9 and 10 disk formulas already committed Speed test results: 127 issues close in 14 sec (~109ms each) Expected 1K run time: ~2 minutes 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
104 lines
3.2 KiB
Python
104 lines
3.2 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Generate Towers of Hanoi formula with pre-computed moves.
|
|
|
|
Usage:
|
|
python3 gen_hanoi.py [n_disks] > formula.toml
|
|
|
|
Examples:
|
|
python3 gen_hanoi.py 7 # 127 moves (~19KB)
|
|
python3 gen_hanoi.py 10 # 1023 moves (~149KB)
|
|
python3 gen_hanoi.py 15 # 32767 moves (~4.7MB)
|
|
python3 gen_hanoi.py 20 # 1048575 moves (~163MB)
|
|
|
|
The generated formula creates a sequential workflow where each move
|
|
depends on the previous one. This tests Gas Town's ability to:
|
|
- Create large molecule hierarchies
|
|
- Execute sequential workflows across session boundaries
|
|
- Maintain state through crash recovery (idempotence)
|
|
"""
|
|
|
|
import sys
|
|
|
|
def hanoi_moves(n, source='A', target='C', auxiliary='B'):
|
|
"""Generate all moves for n-disk Hanoi using iterative algorithm."""
|
|
moves = []
|
|
def solve(n, src, tgt, aux):
|
|
if n == 1:
|
|
moves.append((1, src, tgt))
|
|
else:
|
|
solve(n - 1, src, aux, tgt)
|
|
moves.append((n, src, tgt))
|
|
solve(n - 1, aux, tgt, src)
|
|
solve(n, source, target, auxiliary)
|
|
return moves
|
|
|
|
def generate_formula(n_disks):
|
|
moves = hanoi_moves(n_disks)
|
|
total = len(moves)
|
|
|
|
print(f'''description = """
|
|
AGENT EXECUTION PROTOCOL - Towers of Hanoi ({n_disks} disks, {total} moves)
|
|
|
|
PURPOSE: This is a durability proof, not computation. Steps are pre-computed.
|
|
Your job is to execute them mechanically, proving crash-recovery at scale.
|
|
|
|
EXECUTION LOOP:
|
|
1. Find current state: bd mol current <mol-id>
|
|
2. Find the next ready (unblocked) step
|
|
3. Close it: bd close <step-id>
|
|
4. Repeat until no ready steps remain
|
|
|
|
ON RESUME (after crash/restart/handoff):
|
|
- Same as fresh start. The molecule IS the state.
|
|
- Query `bd mol current <mol-id>`, continue from there.
|
|
- No memory of previous session needed.
|
|
|
|
DO:
|
|
- Close steps as fast as possible (they're trivial mechanical moves)
|
|
- Use `gt handoff` when context fills (proactive cycling)
|
|
- Trust the pre-computed solution - every move is already correct
|
|
|
|
DO NOT:
|
|
- Try to solve Hanoi yourself - moves are already computed
|
|
- Mark steps in_progress - just close them directly
|
|
- Ask for permission - this is GUPP territory, just execute
|
|
- Stop for human input - run autonomously until complete
|
|
|
|
MONITORING:
|
|
- Progress: Count closed children of the molecule
|
|
- For mega-molecules: Use convoy dashboard when available
|
|
- Completion: All steps closed = molecule complete
|
|
|
|
This proves Gas Town can execute arbitrarily long workflows with
|
|
nondeterministic idempotence - different sessions, same outcome.
|
|
"""
|
|
formula = "towers-of-hanoi-{n_disks}"
|
|
version = 1
|
|
|
|
[[steps]]
|
|
id = "setup"
|
|
title = "Verify initial state"
|
|
description = "All {n_disks} disks stacked on peg A. Largest on bottom."
|
|
''')
|
|
|
|
for i, (disk, src, tgt) in enumerate(moves, 1):
|
|
prev = "setup" if i == 1 else f"move-{i-1}"
|
|
print(f'''
|
|
[[steps]]
|
|
id = "move-{i}"
|
|
title = "Move disk {disk}: {src} → {tgt}"
|
|
description = "Move disk {disk} from peg {src} to peg {tgt}. (Move {i}/{total})"
|
|
needs = ["{prev}"]''')
|
|
|
|
print(f'''
|
|
[[steps]]
|
|
id = "verify"
|
|
title = "Verify final state"
|
|
description = "All {n_disks} disks now on peg C. Tower intact, all moves were legal."
|
|
needs = ["move-{total}"]''')
|
|
|
|
if __name__ == "__main__":
|
|
n = int(sys.argv[1]) if len(sys.argv) > 1 else 10
|
|
generate_formula(n)
|