← Home
petri-net tutorial go-pflow simulation sim-pflow-xyz

Introducing sim.pflow.xyz

sim.pflow.xyz is where the models on this blog run. Each one is a Petri net stored as a small JSON document — places, transitions, arcs, rates — and every model in the catalog gets the same instruments: seeded scenarios, side-by-side comparison, diagnostics, structural checks and calibration against an event log. Nothing is written per model. The instruments read the document.

The question it is built around: what if the model was the app? The Model Is the App makes that argument at length. This post is the tour.

Three models, in order

The catalog has well over a hundred entries now. Three of them make a sensible path through it, each adding one idea to the last:

Model What it adds Open it
Tic-tac-toe Places, transitions, turn tokens; a game the engine can solve console · app
Café Weighted arcs, capped stock, a shared staff pool, customers who give up console
Vet clinic Many contending pools, read-arc gates, disruptions console

Every console is the same page, /whatif/?id={model}, pointed at a different id. The knobs it shows are the ones the model declares.

Tic-tac-toe: the foundation

Nine cells, two players, a turn token that passes back and forth, and win detectors that end the game. The stored model is 34 places and 35 transitions, including a move counter and a draw place so every game ends in an outcome you can count.

Because the model declares its players and an objective, the engine can play it. Ask sim_evaluate for exact search and you get minimax over the declared game — it blocks, takes wins, and shows O can always avoid losing. Ask for the incidence method and you get the closed-form strategic values: centre 2.0, corner 1.5, edge 1.0, the count of win lines through each cell. Same net, two readings. Tic-Tac-Toe Model has the full analysis, including where the plain ODE ranking falls short of search.

Café: resources and people

Three drinks, a pantry, two baristas. An espresso draws 20g of beans and a cup; a latte 15g of beans and 50ml of milk; a cappuccino 15g and 30ml. Stocks are capped and restock; customers who wait too long walk out.

The café is built from three separately written nets — counter, pantry, staff — fused so that starting a drink is one firing across all three: the order leaves the queue, the stock is drawn down and a barista is taken off the floor in the same step. The barista and the beans are marked kinetic: false: they permit a drink to start without making it start faster. Leave that out and a bigger pantry brews quicker, which no café does.

That structure is what makes "should I put a third barista on?" a question with an answer. Headcount is the initial marking on one place; change it and compare. Coffee Shop Model works through a larger five-drink net with the same pattern of recipes as arc weights.

Vet clinic: contention

38 places and 42 transitions: vets, techs, a receptionist, exam rooms, surgery and dental suites, radiology, recovery kennels, and walk-ins who leave if they wait too long. Every service seizes its staff and its room when it starts and releases them when it finishes, so how busy the vets are is a marking you can read.

Here the console's disruptions earn their keep — an emergency wave, a surgery day — and so does sim_diagnose, which ranks every knob by its measured effect on the objective. What-If Analysis and The Capacity Paradox are what came out of pointing it at this clinic and at models like it.

The same building blocks everywhere

Every model in the catalog uses the same vocabulary:

The first three are structure (what can happen). Tokens are state (what is the case now). Rates make it a simulation (what tends to happen). Declarations say what you are asking.

What you can ask of a model

The instruments are the same for every model, from the catalog or one you wrote five minutes ago:

Models are content-addressed and immutable: a change is a new model with its own id, so "which version did you run?" has a definite answer.

Why play first

Petri nets are visual and dynamic, and reading about tokens doesn't build the intuition that moving them does. Make a move in the tic-tac-toe app and watch a token leave one place, the transition fire, and a token land in another place. Add a barista to the café and watch the walkouts fall — or not. The concepts click in a way a diagram alone doesn't manage, and the console is honest about the second case: if a knob does nothing, the comparison shows it doing nothing.

The philosophy

Traditional development starts with code and describes it afterwards. Here the model comes first and stays the source of truth:

The bet is that a good enough model makes everything downstream of it — the analysis, the console, the app — a reading of the document rather than a separate program that can drift from it.

Getting started

  1. Open sim.pflow.xyz and pick a model from the catalog
  2. Start with tic-tac-toe, then the café
  3. Turn the knobs; compare two scenarios on the same seed
  4. Connect an MCP client and describe a process of your own:
claude mcp add --transport http sim https://sim.pflow.xyz/mcp

The public tools work without signing in; storing models you own asks you to sign in the first time. The help page and llms.txt cover the rest.

For the underlying library: go-pflow on GitHub

For the theory behind ODE analysis: Declarative Differential Models

For what-if scenario planning: Skip the Spreadsheet: What-If Analysis

See also Chapter 17: The Visual Editor in Petri Nets as a Universal Abstraction.

×

Follow on Mastodon