Skip to content

Instantly share code, notes, and snippets.

@stackdump
Last active September 2, 2025 14:23
Show Gist options
  • Save stackdump/0f07da713a3bcfe9c06cebf3ec627133 to your computer and use it in GitHub Desktop.
Save stackdump/0f07da713a3bcfe9c06cebf3ec627133 to your computer and use it in GitHub Desktop.

Recipe For Coffee

pflow

{
  "modelType": "petriNet",
  "version": "v0",
  "places": {
    "Water": { "offset": 0, "initial": 1, "capacity": 1, "x": 35, "y": 166 },
    "BoiledWater": { "offset": 1, "capacity": 1, "x": 293, "y": 193 },
    "CoffeeBeans": { "offset": 2, "initial": 1, "capacity": 1, "x": 35, "y": 226 },
    "GroundCoffee": { "offset": 3, "capacity": 1, "x": 296, "y": 253 }
  },
  "transitions": {
    "BoilWater": { "x": 184, "y": 167 },
    "BrewCoffee": { "x": 183, "y": 291 },
    "GrindBeans": { "x": 180, "y": 228 }
  },
  "arcs": [
    { "source": "Water", "target": "BoilWater" },
    { "source": "BoilWater", "target": "BoiledWater" },
    { "source": "CoffeeBeans", "target": "GrindBeans" },
    { "source": "GrindBeans", "target": "GroundCoffee" },
    { "source": "BoiledWater", "target": "BrewCoffee" },
    { "source": "GroundCoffee", "target": "BrewCoffee" }
  ]
}

Full Coffee Process

pflow

{
  "modelType": "petriNet",
  "version": "v0",
  "places": {
    "Water": { "offset": 0, "initial": 1, "capacity": 1, "x": 35, "y": 166 },
    "BoiledWater": { "offset": 1, "capacity": 1, "x": 293, "y": 193 },
    "CoffeeBeans": { "offset": 2, "initial": 1, "capacity": 1, "x": 35, "y": 226 },
    "GroundCoffee": { "offset": 3, "capacity": 1, "x": 296, "y": 253 },
    "Filter": { "offset": 4, "initial": 1, "capacity": 1, "x": 35, "y": 290 },
    "CoffeeInPot": { "offset": 5, "capacity": 1, "x": 300, "y": 322 },
    "Cup": { "offset": 6, "initial": 1, "capacity": 1, "x": 35, "y": 349 },
    "Preparing": { "offset": 7, "capacity": 1, "x": 280, "y": 120 }
  },
  "transitions": {
    "BoilWater": { "x": 184, "y": 167 },
    "BrewCoffee": { "x": 183, "y": 291 },
    "GrindBeans": { "x": 180, "y": 228 },
    "PourCoffee": { "x": 183, "y": 352 }
  },
  "arcs": [
    { "source": "Water", "target": "BoilWater" },
    { "source": "BoilWater", "target": "BoiledWater" },
    { "source": "CoffeeBeans", "target": "GrindBeans" },
    { "source": "GrindBeans", "target": "GroundCoffee" },
    { "source": "BoiledWater", "target": "BrewCoffee" },
    { "source": "GroundCoffee", "target": "BrewCoffee" },
    { "source": "Filter", "target": "BrewCoffee" },
    { "source": "BrewCoffee", "target": "CoffeeInPot" },
    { "source": "CoffeeInPot", "target": "PourCoffee" },
    { "source": "Cup", "target": "PourCoffee" },
    { "source": "Preparing", "target": "BoilWater" }
  ]
}

Another Object: Payment

pflow

{
  "modelType": "petriNet",
  "version": "v0",
  "places": {
    "Water": { "offset": 0, "initial": 1, "capacity": 1, "x": 35, "y": 166 },
    "BoiledWater": { "offset": 1, "capacity": 1, "x": 293, "y": 193 },
    "CoffeeBeans": { "offset": 2, "initial": 1, "capacity": 1, "x": 35, "y": 226 },
    "GroundCoffee": { "offset": 3, "capacity": 1, "x": 296, "y": 253 },
    "Filter": { "offset": 4, "initial": 1, "capacity": 1, "x": 35, "y": 290 },
    "CoffeeInPot": { "offset": 5, "capacity": 1, "x": 300, "y": 322 },
    "Pending": { "offset": 6, "capacity": 1, "x": 518, "y": 168 },
    "Sent": { "offset": 7, "capacity": 1, "x": 524, "y": 258 },
    "Payment": { "offset": 8, "capacity": 1, "x": 528, "y": 346 },
    "Cup": { "offset": 9, "initial": 1, "capacity": 1, "x": 35, "y": 349 },
    "Preparing": { "offset": 10, "capacity": 1, "x": 280, "y": 120 }
  },
  "transitions": {
    "BoilWater": { "x": 184, "y": 167 },
    "BrewCoffee": { "x": 183, "y": 291 },
    "Credit": { "x": 393, "y": 288 },
    "GrindBeans": { "x": 180, "y": 228 },
    "PourCoffee": { "x": 183, "y": 352 },
    "Send": { "x": 392, "y": 211 }
  },
  "arcs": [
    { "source": "Water", "target": "BoilWater" },
    { "source": "BoilWater", "target": "BoiledWater" },
    { "source": "CoffeeBeans", "target": "GrindBeans" },
    { "source": "GrindBeans", "target": "GroundCoffee" },
    { "source": "BoiledWater", "target": "BrewCoffee" },
    { "source": "GroundCoffee", "target": "BrewCoffee" },
    { "source": "Filter", "target": "BrewCoffee" },
    { "source": "BrewCoffee", "target": "CoffeeInPot" },
    { "source": "CoffeeInPot", "target": "PourCoffee" },
    { "source": "Cup", "target": "PourCoffee" },
    { "source": "Pending", "target": "Send" },
    { "source": "Send", "target": "Sent" },
    { "source": "Sent", "target": "Credit" },
    { "source": "Credit", "target": "Payment" },
    { "source": "Preparing", "target": "BoilWater" }
  ]
}

Rule: Don't Pour before Payment

pflow

{
  "modelType": "petriNet",
  "version": "v0",
  "places": {
    "Water": { "offset": 0, "initial": 1, "capacity": 1, "x": 35, "y": 166 },
    "BoiledWater": { "offset": 1, "capacity": 1, "x": 293, "y": 193 },
    "CoffeeBeans": { "offset": 2, "initial": 1, "capacity": 1, "x": 35, "y": 226 },
    "GroundCoffee": { "offset": 3, "capacity": 1, "x": 296, "y": 253 },
    "Filter": { "offset": 4, "initial": 1, "capacity": 1, "x": 35, "y": 290 },
    "CoffeeInPot": { "offset": 5, "capacity": 1, "x": 300, "y": 322 },
    "Pending": { "offset": 6, "capacity": 1, "x": 518, "y": 168 },
    "Sent": { "offset": 7, "capacity": 1, "x": 524, "y": 258 },
    "Payment": { "offset": 8, "capacity": 1, "x": 528, "y": 346 },
    "Cup": { "offset": 9, "initial": 1, "capacity": 1, "x": 35, "y": 349 },
    "Preparing": { "offset": 10, "capacity": 1, "x": 280, "y": 120 }
  },
  "transitions": {
    "BoilWater": { "x": 184, "y": 167 },
    "BrewCoffee": { "x": 183, "y": 291 },
    "Credit": { "x": 393, "y": 288 },
    "GrindBeans": { "x": 180, "y": 228 },
    "PourCoffee": { "x": 183, "y": 352 },
    "Send": { "x": 392, "y": 211 }
  },
  "arcs": [
    { "source": "Water", "target": "BoilWater" },
    { "source": "BoilWater", "target": "BoiledWater" },
    { "source": "CoffeeBeans", "target": "GrindBeans" },
    { "source": "GrindBeans", "target": "GroundCoffee" },
    { "source": "BoiledWater", "target": "BrewCoffee" },
    { "source": "GroundCoffee", "target": "BrewCoffee" },
    { "source": "Filter", "target": "BrewCoffee" },
    { "source": "BrewCoffee", "target": "CoffeeInPot" },
    { "source": "CoffeeInPot", "target": "PourCoffee" },
    { "source": "Cup", "target": "PourCoffee" },
    { "source": "Pending", "target": "Send" },
    { "source": "Send", "target": "Sent" },
    { "source": "Sent", "target": "Credit" },
    { "source": "Credit", "target": "Payment" },
    { "source": "Preparing", "target": "BoilWater" },
    { "source": "PourCoffee", "target": "Payment", "inhibit": true }
  ]
}

Add Start and Exit

pflow

{
  "modelType": "petriNet",
  "version": "v0",
  "places": {
    "Water": { "offset": 0, "initial": 1, "capacity": 1, "x": 35, "y": 166 },
    "BoiledWater": { "offset": 1, "capacity": 1, "x": 293, "y": 193 },
    "CoffeeBeans": { "offset": 2, "initial": 1, "capacity": 1, "x": 35, "y": 226 },
    "GroundCoffee": { "offset": 3, "capacity": 1, "x": 296, "y": 253 },
    "Filter": { "offset": 4, "initial": 1, "capacity": 1, "x": 35, "y": 290 },
    "CoffeeInPot": { "offset": 5, "capacity": 1, "x": 300, "y": 322 },
    "Pending": { "offset": 6, "capacity": 1, "x": 518, "y": 168 },
    "Sent": { "offset": 7, "capacity": 1, "x": 524, "y": 258 },
    "Payment": { "offset": 8, "capacity": 1, "x": 528, "y": 346 },
    "Cup": { "offset": 9, "initial": 1, "capacity": 1, "x": 35, "y": 349 },
    "Preparing": { "offset": 10, "capacity": 1, "x": 280, "y": 120 },
    "Exit": { "offset": 11, "capacity": 1, "x": 280, "y": 400 },
    "Start": { "offset": 12, "initial": 1, "x": 33, "y": 98 }
  },
  "transitions": {
    "BoilWater": { "x": 184, "y": 167 },
    "BrewCoffee": { "x": 183, "y": 291 },
    "Credit": { "x": 393, "y": 288 },
    "GrindBeans": { "x": 180, "y": 228 },
    "PourCoffee": { "x": 183, "y": 352 },
    "Run": { "x": 180, "y": 120 },
    "Send": { "x": 392, "y": 211 }
  },
  "arcs": [
    { "source": "Water", "target": "BoilWater" },
    { "source": "BoilWater", "target": "BoiledWater" },
    { "source": "CoffeeBeans", "target": "GrindBeans" },
    { "source": "GrindBeans", "target": "GroundCoffee" },
    { "source": "BoiledWater", "target": "BrewCoffee" },
    { "source": "GroundCoffee", "target": "BrewCoffee" },
    { "source": "Filter", "target": "BrewCoffee" },
    { "source": "BrewCoffee", "target": "CoffeeInPot" },
    { "source": "CoffeeInPot", "target": "PourCoffee" },
    { "source": "Cup", "target": "PourCoffee" },
    { "source": "Pending", "target": "Send" },
    { "source": "Send", "target": "Sent" },
    { "source": "Sent", "target": "Credit" },
    { "source": "Credit", "target": "Payment" },
    { "source": "Preparing", "target": "BoilWater" },
    { "source": "PourCoffee", "target": "Exit" },
    { "source": "Run", "target": "Preparing" },
    { "source": "PourCoffee", "target": "Payment", "inhibit": true },
    { "source": "Run", "target": "Pending" },
    { "source": "Start", "target": "Run" }
  ]
}

Add additional pre-reqs

Grind Beans could technically happen 'before' Run - so we add an inhibitor to get correct behavior.

pflow

{
  "modelType": "petriNet",
  "version": "v0",
  "places": {
    "Water": { "offset": 0, "initial": 1, "capacity": 1, "x": 35, "y": 166 },
    "BoiledWater": { "offset": 1, "capacity": 1, "x": 293, "y": 193 },
    "CoffeeBeans": { "offset": 2, "initial": 1, "capacity": 1, "x": 35, "y": 226 },
    "GroundCoffee": { "offset": 3, "capacity": 1, "x": 296, "y": 253 },
    "Filter": { "offset": 4, "initial": 1, "capacity": 1, "x": 35, "y": 290 },
    "CoffeeInPot": { "offset": 5, "capacity": 1, "x": 300, "y": 322 },
    "Pending": { "offset": 6, "capacity": 1, "x": 518, "y": 168 },
    "Sent": { "offset": 7, "capacity": 1, "x": 524, "y": 258 },
    "Payment": { "offset": 8, "capacity": 1, "x": 528, "y": 346 },
    "Cup": { "offset": 9, "initial": 1, "capacity": 1, "x": 35, "y": 349 },
    "Preparing": { "offset": 10, "capacity": 1, "x": 280, "y": 120 },
    "Exit": { "offset": 11, "capacity": 1, "x": 280, "y": 400 },
    "Start": { "offset": 12, "initial": 1, "x": 33, "y": 98 }
  },
  "transitions": {
    "BoilWater": { "x": 184, "y": 167 },
    "BrewCoffee": { "x": 183, "y": 291 },
    "Credit": { "x": 393, "y": 288 },
    "GrindBeans": { "x": 180, "y": 228 },
    "PourCoffee": { "x": 183, "y": 352 },
    "Run": { "x": 180, "y": 120 },
    "Send": { "x": 392, "y": 211 }
  },
  "arcs": [
    { "source": "Water", "target": "BoilWater" },
    { "source": "BoilWater", "target": "BoiledWater" },
    { "source": "CoffeeBeans", "target": "GrindBeans" },
    { "source": "GrindBeans", "target": "GroundCoffee" },
    { "source": "BoiledWater", "target": "BrewCoffee" },
    { "source": "GroundCoffee", "target": "BrewCoffee" },
    { "source": "Filter", "target": "BrewCoffee" },
    { "source": "BrewCoffee", "target": "CoffeeInPot" },
    { "source": "CoffeeInPot", "target": "PourCoffee" },
    { "source": "Cup", "target": "PourCoffee" },
    { "source": "Pending", "target": "Send" },
    { "source": "Send", "target": "Sent" },
    { "source": "Sent", "target": "Credit" },
    { "source": "Credit", "target": "Payment" },
    { "source": "Preparing", "target": "BoilWater" },
    { "source": "PourCoffee", "target": "Exit" },
    { "source": "Run", "target": "Preparing" },
    { "source": "GrindBeans", "target": "BoiledWater", "inhibit": true },
    { "source": "PourCoffee", "target": "Payment", "inhibit": true },
    { "source": "Run", "target": "Pending" },
    { "source": "Start", "target": "Run" }
  ]
}

Completed Workflow Net

pflow

{
  "modelType": "petriNet",
  "version": "v0",
  "places": {
    "Water": { "offset": 0, "initial": 1, "capacity": 1, "x": 35, "y": 166 },
    "BoiledWater": { "offset": 1, "capacity": 1, "x": 293, "y": 193 },
    "CoffeeBeans": { "offset": 2, "initial": 1, "capacity": 1, "x": 35, "y": 226 },
    "GroundCoffee": { "offset": 3, "capacity": 1, "x": 296, "y": 253 },
    "Filter": { "offset": 4, "initial": 1, "capacity": 1, "x": 35, "y": 290 },
    "CoffeeInPot": { "offset": 5, "capacity": 1, "x": 300, "y": 322 },
    "Pending": { "offset": 6, "capacity": 1, "x": 518, "y": 168 },
    "Sent": { "offset": 7, "capacity": 1, "x": 524, "y": 258 },
    "Payment": { "offset": 8, "capacity": 1, "x": 528, "y": 346 },
    "Cup": { "offset": 9, "initial": 1, "capacity": 1, "x": 35, "y": 349 },
    "Preparing": { "offset": 10, "capacity": 1, "x": 280, "y": 120 },
    "Exit": { "offset": 11, "capacity": 1, "x": 280, "y": 400 },
    "Start": { "offset": 12, "initial": 1, "x": 33, "y": 98 }
  },
  "transitions": {
    "BoilWater": { "x": 184, "y": 167 },
    "BrewCoffee": { "x": 183, "y": 291 },
    "Credit": { "x": 393, "y": 288 },
    "GrindBeans": { "x": 180, "y": 228 },
    "Halt": { "x": 380, "y": 400 },
    "PourCoffee": { "x": 183, "y": 352 },
    "Run": { "x": 180, "y": 120 },
    "Send": { "x": 392, "y": 211 }
  },
  "arcs": [
    { "source": "Water", "target": "BoilWater" },
    { "source": "BoilWater", "target": "BoiledWater" },
    { "source": "CoffeeBeans", "target": "GrindBeans" },
    { "source": "GrindBeans", "target": "GroundCoffee" },
    { "source": "BoiledWater", "target": "BrewCoffee" },
    { "source": "GroundCoffee", "target": "BrewCoffee" },
    { "source": "Filter", "target": "BrewCoffee" },
    { "source": "BrewCoffee", "target": "CoffeeInPot" },
    { "source": "CoffeeInPot", "target": "PourCoffee" },
    { "source": "Cup", "target": "PourCoffee" },
    { "source": "Pending", "target": "Send" },
    { "source": "Send", "target": "Sent" },
    { "source": "Sent", "target": "Credit" },
    { "source": "Credit", "target": "Payment" },
    { "source": "Preparing", "target": "BoilWater" },
    { "source": "PourCoffee", "target": "Exit" },
    { "source": "Run", "target": "Preparing" },
    { "source": "Exit", "target": "Halt" },
    { "source": "GrindBeans", "target": "BoiledWater", "inhibit": true },
    { "source": "PourCoffee", "target": "Payment", "inhibit": true },
    { "source": "Run", "target": "Pending" },
    { "source": "Start", "target": "Run" }
  ]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment