diff --git a/.beads/formulas/towers-of-hanoi.formula.toml b/.beads/formulas/towers-of-hanoi.formula.toml index 1f263df7..cd698cf0 100644 --- a/.beads/formulas/towers-of-hanoi.formula.toml +++ b/.beads/formulas/towers-of-hanoi.formula.toml @@ -1,5 +1,5 @@ description = """ -AGENT EXECUTION PROTOCOL - Towers of Hanoi ({disks} disks, {total_moves} steps) +AGENT EXECUTION PROTOCOL - Towers of Hanoi PURPOSE: This is a durability proof, not computation. Steps are pre-computed. Your job is to execute them mechanically, proving crash-recovery at scale. @@ -35,81 +35,71 @@ This proves Gas Town can execute arbitrarily long workflows with nondeterministic idempotence - different sessions, same outcome. """ formula = "towers-of-hanoi" -version = 1 - -[example_3_disk] - -[[example_3_disk.steps]] -description = "Move disk 1 from A to C" -id = "move-1" - -[[example_3_disk.steps]] -description = "Move disk 2 from A to B" -id = "move-2" -needs = ["move-1"] - -[[example_3_disk.steps]] -description = "Move disk 1 from C to B" -id = "move-3" -needs = ["move-2"] - -[[example_3_disk.steps]] -description = "Move disk 3 from A to C" -id = "move-4" -needs = ["move-3"] - -[[example_3_disk.steps]] -description = "Move disk 1 from B to A" -id = "move-5" -needs = ["move-4"] - -[[example_3_disk.steps]] -description = "Move disk 2 from B to C" -id = "move-6" -needs = ["move-5"] - -[[example_3_disk.steps]] -description = "Move disk 1 from A to C" -id = "move-7" -needs = ["move-6"] - -[generate] -[generate.for-each] -range = "1..2^{disks}" -var = "move_num" -[generate.step] -description = "Move {computed_disk} from {computed_source} to {computed_target}. This is move {move_num} of {total_moves}. Simply execute the move - no decision needed." -id = "move-{move_num}" -needs = ["move-{move_num - 1}"] -[generate.step.compute] -disk = "lowest_set_bit({move_num})" -source = "peg_for_disk({disk}, {move_num}, 'source')" -target = "peg_for_disk({disk}, {move_num}, 'target')" - -[[steps]] -description = "Verify initial state: {disks} disks stacked on peg {source_peg}. All disks in order (largest on bottom)." -id = "setup" - -[[steps]] -description = "Execute all {total_moves} moves to transfer tower from {source_peg} to {target_peg}." -id = "solve" -needs = ["setup"] - -[[steps]] -description = "Verify final state: all {disks} disks now on peg {target_peg}. Tower intact, all moves were legal." -id = "verify" -needs = ["solve"] +version = 2 [vars] -[vars.auxiliary_peg] -default = "B" -description = "Helper peg" -[vars.disks] -description = "Number of disks to solve" -required = true [vars.source_peg] default = "A" description = "Starting peg" [vars.target_peg] default = "C" description = "Target peg" +[vars.auxiliary_peg] +default = "B" +description = "Helper peg" + +# 3-disk solution: 7 moves (2^3 - 1) +# Each step is a simple acknowledgment - the agent just closes it. + +[[steps]] +id = "setup" +title = "Verify initial state" +description = "All 3 disks stacked on peg A. Largest on bottom." + +[[steps]] +id = "move-1" +title = "Move disk 1: A → C" +description = "Move the smallest disk from peg A to peg C." +needs = ["setup"] + +[[steps]] +id = "move-2" +title = "Move disk 2: A → B" +description = "Move disk 2 from peg A to peg B." +needs = ["move-1"] + +[[steps]] +id = "move-3" +title = "Move disk 1: C → B" +description = "Move disk 1 from peg C to peg B." +needs = ["move-2"] + +[[steps]] +id = "move-4" +title = "Move disk 3: A → C" +description = "Move the largest disk from peg A to peg C." +needs = ["move-3"] + +[[steps]] +id = "move-5" +title = "Move disk 1: B → A" +description = "Move disk 1 from peg B to peg A." +needs = ["move-4"] + +[[steps]] +id = "move-6" +title = "Move disk 2: B → C" +description = "Move disk 2 from peg B to peg C." +needs = ["move-5"] + +[[steps]] +id = "move-7" +title = "Move disk 1: A → C" +description = "Move disk 1 from peg A to peg C." +needs = ["move-6"] + +[[steps]] +id = "verify" +title = "Verify final state" +description = "All 3 disks now on peg C. Tower intact, all moves were legal." +needs = ["move-7"] diff --git a/.beads/formulas/towers-of-hanoi.formula.yaml b/.beads/formulas/towers-of-hanoi.formula.yaml index d94291ae..6e284483 100644 --- a/.beads/formulas/towers-of-hanoi.formula.yaml +++ b/.beads/formulas/towers-of-hanoi.formula.yaml @@ -10,16 +10,13 @@ # For n disks: 2^n - 1 moves # 20 disks = 1,048,575 moves (the "million step" problem) # -# The iterative algorithm (no recursion needed): -# For move k (1-indexed): -# - disk = largest power of 2 dividing k (disk 1 is smallest) -# - direction = computed from disk parity and move number -# -# This formula uses for-each to generate all moves at cook time. +# Currently hardcoded for 3 disks (7 moves) as proof of concept. +# For million-step version, need to implement range expansion in cook. formula: towers-of-hanoi +version: 2 description: | - AGENT EXECUTION PROTOCOL - Towers of Hanoi ({disks} disks, {total_moves} steps) + AGENT EXECUTION PROTOCOL - Towers of Hanoi PURPOSE: This is a durability proof, not computation. Steps are pre-computed. Your job is to execute them mechanically, proving crash-recovery at scale. @@ -53,80 +50,60 @@ description: | This proves Gas Town can execute arbitrarily long workflows with nondeterministic idempotence - different sessions, same outcome. -version: 1 vars: - disks: "{{disks}}" - source_peg: "A" - target_peg: "C" - auxiliary_peg: "B" - -# The magic: for-each over computed move sequence -# Each move is deterministic, computed from move number -generate: - # This is pseudo-syntax for the runtime expansion we'd need - for-each: - var: move_num - range: "1..2^{disks}" # 1 to 2^n - 1 - step: - id: "move-{move_num}" - description: > - Move {computed_disk} from {computed_source} to {computed_target}. - - This is move {move_num} of {total_moves}. - Simply execute the move - no decision needed. - needs: - - "move-{move_num - 1}" # Sequential dependency - compute: - # Disk to move: position of lowest set bit in move_num - disk: "lowest_set_bit({move_num})" - # Peg calculations based on disk parity and move number - source: "peg_for_disk({disk}, {move_num}, 'source')" - target: "peg_for_disk({disk}, {move_num}, 'target')" - -# Alternatively, simpler recursive template for smaller N: -# (This would need the recursive expansion operator) + source_peg: + default: "A" + description: "Starting peg" + target_peg: + default: "C" + description: "Target peg" + auxiliary_peg: + default: "B" + description: "Helper peg" +# 3-disk solution: 7 moves (2^3 - 1) steps: - id: setup - description: > - Verify initial state: {disks} disks stacked on peg {source_peg}. - All disks in order (largest on bottom). + title: "Verify initial state" + description: "All 3 disks stacked on peg A. Largest on bottom." - - id: solve - description: > - Execute all {total_moves} moves to transfer tower from - {source_peg} to {target_peg}. + - id: move-1 + title: "Move disk 1: A → C" + description: "Move the smallest disk from peg A to peg C." needs: [setup] - # This step would be expanded by the generate block above + + - id: move-2 + title: "Move disk 2: A → B" + description: "Move disk 2 from peg A to peg B." + needs: [move-1] + + - id: move-3 + title: "Move disk 1: C → B" + description: "Move disk 1 from peg C to peg B." + needs: [move-2] + + - id: move-4 + title: "Move disk 3: A → C" + description: "Move the largest disk from peg A to peg C." + needs: [move-3] + + - id: move-5 + title: "Move disk 1: B → A" + description: "Move disk 1 from peg B to peg A." + needs: [move-4] + + - id: move-6 + title: "Move disk 2: B → C" + description: "Move disk 2 from peg B to peg C." + needs: [move-5] + + - id: move-7 + title: "Move disk 1: A → C" + description: "Move disk 1 from peg A to peg C." + needs: [move-6] - id: verify - description: > - Verify final state: all {disks} disks now on peg {target_peg}. - Tower intact, all moves were legal. - needs: [solve] - -# For the prototype, let's show a 3-disk example (7 moves): -example_3_disk: - # Move sequence for 3 disks: A→C, A→B, C→B, A→C, B→A, B→C, A→C - steps: - - id: move-1 - description: "Move disk 1 from A to C" - - id: move-2 - description: "Move disk 2 from A to B" - needs: [move-1] - - id: move-3 - description: "Move disk 1 from C to B" - needs: [move-2] - - id: move-4 - description: "Move disk 3 from A to C" - needs: [move-3] - - id: move-5 - description: "Move disk 1 from B to A" - needs: [move-4] - - id: move-6 - description: "Move disk 2 from B to C" - needs: [move-5] - - id: move-7 - description: "Move disk 1 from A to C" - needs: [move-6] + title: "Verify final state" + description: "All 3 disks now on peg C. Tower intact, all moves were legal." + needs: [move-7]