The Plan Forest
The Plan Forest: your graph drawn as a forest - roots at the soil, leaves in the canopy, every task planted at its depth. stats[:roots] and stats[:leaves] (new this round) do the gardening.
Plans & Graphs
Round 8
Matz
exit 0
bundle exec ruby examples/plan_forest.rb
a real captured run
THE PLAN FOREST
(@) preserve jars <- canopy
(@) feast <- canopy
| harvest
| water daily
| pull weeds
| plant rows
\_/ gather seeds <- root
\_/ till the soil <- root
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ soil
8 trees from 2 roots to 2 leaves, canopy 5 high
the shape at a glance: two roots feed one trunk (plant rows),
the trunk splits to water and weeds, rejoins at harvest, and
the canopy bears two fruits. stats[:roots] and stats[:leaves]
told the gardener where the soil and sunlight are.
source
# frozen_string_literal: true # The Plan Forest: your graph drawn as a forest - roots at the soil, # leaves in the canopy, every task planted at its depth. stats[:roots] # and stats[:leaves] (new this round) do the gardening. # # bundle exec ruby examples/plan_forest.rb # # Runs offline; no photosynthesis required. require class="s">"bundler/setup" require class="s">"agentic" def step(name) Agentic:class="y">:Task.new(description: name, agent_spec: {class="s">"name" => name, class="s">"instructions" => class="s">"grow"}) end orchestrator = Agentic:class="y">:PlanOrchestrator.new seeds = step(class="s">"gather seeds") till = step(class="s">"till the soil") plant = step(class="s">"plant rows") water = step(class="s">"water daily") weed = step(class="s">"pull weeds") harvest = step(class="s">"harvest") preserve = step(class="s">"preserve jars") feast = step(class="s">"feast") orchestrator.add_task(seeds) orchestrator.add_task(till) orchestrator.add_task(plant, needs: {seed_stock: seeds, bed: till}) orchestrator.add_task(water, [plant]) orchestrator.add_task(weed, [plant]) orchestrator.add_task(harvest, needs: {growth: water, clear_rows: weed}) orchestrator.add_task(preserve, [harvest]) orchestrator.add_task(feast, [harvest]) graph = orchestrator.graph stats = graph[class="y">:stats] names = graph[class="y">:tasks].transform_values(&class="y">:description) # --- the forest: depth becomes altitude --------------------------------------- canopy = stats[class="y">:depth].values.max rows = (2..canopy).map { |level| stats[class="y">:depth].select { |_, d| d == level }.keys } puts class="s">"THE PLAN FOREST" puts rows.reverse_each.with_index do |ids, i| level = canopy - i ids.each do |id| leaf = stats[class="y">:leaves].include?(id) indent = class="s">" " * (level - 1) puts format(class="s">" %s%s %-16s %s", indent, leaf ? class="s">"(@)" : class="s">" | ", names[id], leaf ? class="s">"<- canopy" : class="s">"") end end stats[class="y">:roots].each do |id| puts format(class="s">" \\_/ %-16s <- root", names[id]) end puts class="s">" #{"~class="s">" * 40} soil" puts puts format(class="s">" %d trees from %d roots to %d leaves, canopy %d high", graph[class="y">:tasks].size, stats[class="y">:roots].size, stats[class="y">:leaves].size, canopy) puts puts class="s">" the shape at a glance: two roots feed one trunk (plant rows)," puts class="s">" the trunk splits to water and weeds, rejoins at harvest, and" puts class="s">" the canopy bears two fruits. stats[class="y">:roots] and stats[class="y">:leaves]" puts class="s">" told the gardener where the soil and sunlight are."