🍳 Foodlang

Robot Planning

Foodlang turns a recipe into structures a robot planner can consume: a robot action graph, an illustrative PDDL domain + problem, and a FOON functional-object-oriented network.

Robot action graph

foodlang compile examples/simple-latte.food.yaml --target robot-action-graph
{
  "task": "Simple Latte",
  "actions": [
    { "id": "grind", "action": "grind", "inputs": ["coffee grounds"], "outputs": ["coffee grounds"] },
    { "id": "brew", "action": "brew_espresso", "depends_on": ["grind"],
      "inputs": ["coffee grounds", "water"], "outputs": ["espresso"] }
  ]
}

The graph is a DAG: depends_on encodes ordering so independent actions (brew vs. steam) can run in parallel. If you don't author one, Foodlang derives a linear graph from your transformations.

PDDL

foodlang compile examples/simple-latte.food.yaml --target pddl
(define (domain simple_latte)
  (:requirements :strips)
  (:predicates (available ?x))

  (:action extract_espresso
    :parameters ()
    :precondition (and (available coffee_grounds) (available water))
    :effect (and (available espresso))
  )
  ...
)

Each transformation becomes an action with available pre- and post-conditions. This is illustrative — it shows Foodlang can become planner-compatible, not that it is a verified planning instance.

FOON

foodlang compile examples/simple-latte.food.yaml --target foon
{
  "functional_units": [
    {
      "input_nodes": [{ "object": "milk", "state": "cold" }],
      "motion_node": { "action": "thermal_foaming" },
      "output_nodes": [
        { "object": "steamed milk", "state": "steamed" },
        { "object": "microfoam", "state": "foamed" }
      ]
    }
  ]
}

One functional unit per transformation: input object-state nodes → a motion node → output object-state nodes. This is the academic representation used in robotic manipulation research.