stackdump

Things I learned while programming as a Petri-net maximalist.

The original web promised structured knowledge—but what we got was a mess of HTML, JavaScript hacks, and data silos. Schema.org tried to clean it up with shared vocabularies for Person, Event, Place, and more. But we rarely treat those vocabularies as more than a sprinkle of SEO dust.

What if we took them seriously? What if we modeled them compositionally?

Schema.org as a Category

Category theory gives us the tools. Think of schema.org like this:

  • Each @type is an object in a category.
  • Each property (location, memberOf, startDate) is a morphism.
  • Subclass relationships (MusicEvent → Event) are inclusion morphisms.
  • You can compose properties like functions:
  nginxCopyEditPerson → Organization → Place
  

Now your schema becomes a diagram, not just a dictionary. Your data becomes an instance of a presheaf over this category—structured, queryable, and introspectable.

Functors, Not Formats

This reframes structured data:

  • It’s not just JSON-LD or RDF.
  • It’s not about serialization.
  • It’s about mappings of meaning—functors from schema to sets.

You can validate with commutative diagrams. You can infer with composition. You can transform safely with categorical structure.

From Markup to Meaning

Once you go categorical:

  • Your templates become morphisms.
  • Your API responses are natural transformations.
  • Your app is a functor from semantic space to interaction space.

This isn’t hand-waving—it’s how we start modeling a semantic web that can compose.

Why Now?

Because we’re building decentralized systems. Because LLMs want structured prompts. Because web3 needs shared semantics. Because we finally care again about meaning.

And because we have the math.

Have you ever stared at your IDE and thought,

“This code needs more wedge-shaped clay.” No? Just me?

Well buckle up, dear reader, because today I’m going to half-jokingly argue that we should consider writing software in cuneiform. Yes, the Sumerian stuff. Clay tablets, styluses, pictographs, the whole Babylonian nine yards.

🧱 1. The Original Immutable Ledger

Before Ethereum, before Tendermint, before double-entry bookkeeping, there was cuneiform.

You wanted a smart contract in 2500 BCE? You literally baked it into a tablet.

Want to reverse a transaction? Sorry bro, it's been fired.

Imagine governance models where votes are kiln-hardened.

🔣 2. Symbol Tables? More Like Symbol Stones.

Cuneiform had its own tokenization system. A single symbol like 𒀀 (“a”) could mean “water” or “offspring” or “cry of anguish” depending on context. Just like in JavaScript!

Modern languages could learn from this polymorphic ambiguity. Imagine importing the 𒆜𒋼𒁍 (Petri net category) module into your codebase and letting meaning emerge from context. We’re talking real dynamic typing, baby.

🪨 3. Write Once, Read Never

Modern developers complain about unreadable code. But imagine shipping your production system in baked cuneiform:

  • No typos: you had one shot.
  • No refactoring: grab a chisel.
  • No infinite loops: fire takes time.

Unit tests? Just toss the tablet in the Euphrates. If it floats, your system was pure.

💧 4. “Hot Black Seed Water” DSL

Since cuneiform predates coffee and tea, we have to describe them compositionally:

  • Coffee = “black hot seed water” → 𒌓 𒉺 𒉡𒈬 𒀀
  • Tea = “hot leaf water” → 𒉺 𒄑 𒀀

This makes for an expressive declarative modeling system. Want to build a Kubernetes pod?

𒇻𒋼𒄑𒀀𒊒𒁀𒁲𒋾 “Hot replicating container leaf cycle fire sync”

Honestly, more readable than some Helm charts I’ve seen.

🧠 5. AI Alignment in a Pre-Modern Mode

If we truly want to align AGI with human values, why not start at the beginning? Before cybernetics. Before Turing. Before Python.

Let GPT-12 learn to parse 𒉺𒀀𒍣𒁍 (“hot water category”) and build programs like a temple scribe — slow, cautious, deliberate. No hallucinations. Just divine procedural clay.

🪔 Closing Thoughts

Look — I’m not seriously saying we should code in cuneiform. But also…

I am.

Why? Because it forces us to confront linguistic minimalismimmutabilitysemantic compression, and places an emphasis on symbolic execution.

And maybe that’s exactly what we need right now — Not another abstraction layer…

But a deus ex machina — emerging not from the cloud, but from the kiln.

The early web was meant to be a decentralized, user-owned hypertext system — a living web of information. Today, we've ended up with centralized silos where link previews, discovery, and even metadata are controlled by corporate platforms.

Gno.land gives us a chance to course-correct.

On Gno.land:

  • Metadata can be user-generated and stored directly in realms, without needing external servers or private APIs.
  • Previews can be computed deterministically from shared, verifiable code.
  • Users can own and fork content, making information remixable and participatory again — not just locked inside engagement farms.
  • Discovery can be peer-to-peer, with realms linking to each other openly, not filtered through black-box algorithms.

The goal isn’t just better previews. It’s restoring the editable, decentralized, user-sovereign spirit that the Web was supposed to have.

It starts simple: make the link structure public, verifiable, and open for everyone to extend.

Gno.land can be that foundation.

🚀 I’m working to build a Gno.land package: /p/pflow/metamodel ! (WIP on github)

  • Using Pflow means Gno developers can embed Petri nets directly inside their contracts without requiring external servers.
  • Petri net models are encoded in JSON or SVG, base64-encoded, and rendered inline using data URLs.

How This Works: Petri Nets in Gno

The p/pflow/metamodel package now includes a set of functions that allow Petri nets to be declared and then serialized as:

  1. JSON Data URLs (for programmatic consumption)

  2. SVG Data URLs (for direct visualization in Gno Markdown)

  3. Markdown Image Embeds (to display Petri nets inside contract descriptions)

  4. Markdown Hyperlinks (to share and interact with Petri nets on external viewers)

See an example of how to use this on my home realm: /r/stackdump/home

Declarative Differential Models (DDM) refer to a modeling approach where the entire system's behavior—states, transitions, constraints, and objectives—is described declaratively and encoded directly within a set of differential equations or differential-algebraic equations (DAEs).

Key Features of DDM:

  1. Declarative Nature:

    • The system is described by its rules and relationships, not step-by-step instructions.
    • These rules are translated into continuous or discrete dynamics that govern the system's evolution.
  2. Constraint Embedding:

    • Logical and physical constraints (e.g., conservation laws, capacity limits) are directly included in the model equations.
    • This ensures the system operates within valid bounds without requiring external enforcement.
  3. Dynamic and Adaptive Behavior:

    • DDMs can handle both deterministic and probabilistic transitions, making them suitable for hybrid systems (e.g., mixing continuous flows and discrete events).
  4. Optimization-Friendly:

    • DDMs naturally integrate with optimization techniques, allowing parameters (e.g., transition rates) to be learned or fine-tuned directly within the model.

Examples and Applications:

  • Petri Nets: Encoding resource flows, transitions, and state changes as ODEs.
  • Hybrid Systems: Combining discrete decision-making with continuous dynamics.
  • Physics-Inspired Machine Learning: Embedding physical constraints within Neural ODEs.
  • Optimal Control: Modeling decision problems directly in the dynamics for optimization.

Why Declarative?

The term “declarative” emphasizes that the model focuses on what the system does (rules and behaviors) rather than how it does it (procedural steps).

Use Case Example:

In a knapsack optimization problem:

  • States represent item availability, weight, and value.
  • Transitions represent decisions to include/exclude items.
  • Constraints (e.g., weight capacity) are encoded directly into the model dynamics, making the system solvable and interpretable.

See the python notebook

Continuous relaxation is a bridge between discrete and continuous domains, offering a powerful way to analyze complex problems by leveraging continuous mathematics. It is widely used across fields like optimization, physics, and systems modeling.

Using Continuous Relaxation with Petri Nets

Petri nets provide a robust framework for modeling the dynamics of Tic-Tac-Toe, extending beyond traditional game-tree analysis. By incorporating continuous relaxation, this approach transforms discrete moves and outcomes into a probabilistic system, making it possible to analyze strategic nuances using differential equations.

Modeling Tic-Tac-Toe as a Petri Net

In this model:

  • Places represent the grid's state, such as unclaimed cells (P00) and markers for Players X and O (e.g., X00 for Player X's mark in the top-left cell).
  • Transitions represent possible moves (e.g., Player X marking X00) and win conditions (e.g., X00_X01_X02 for a row win).
  • Tokens track the system's state, where a token in P00 indicates the top-left cell is unclaimed, while a token in X00 or O00 indicates it is marked by X or O.

Relaxing the System

Discrete moves are relaxed into continuous transitions, allowing the use of ODE solvers. For example:

  • A transition's firing rate represents the probability of a specific move, creating a probabilistic view of gameplay.
  • The win states (win_x, win_o) are modeled as accumulative probabilities derived from successful transition sequences.

Analyzing Strategies

By solving the ODEs, we can:

  1. Predict Win Probabilities: The probabilities of win_x and win_o over time show the likelihood of each player achieving victory.

  2. Evaluate Moves: The model ranks potential moves by their impact on the win probabilities, guiding optimal strategies.

  3. Visualize Dynamics: Plots of win probabilities provide insights into how the game evolves based on current states and potential player decisions.

Conclusion

This Petri-net-based continuous relaxation approach brings a novel lens to Tic-Tac-Toe analysis. By transitioning from discrete moves to probabilistic trajectories, we uncover richer strategic insights and establish a framework applicable to more complex games and systems.

Review the code from previous post where we apply this approach using Juila and Petri.jl

Optimization problems, like the knapsack problem, often invite varied approaches. At first glance, advanced methods might seem complex compared to classic algorithms. Surprisingly, this isn’t always true. In this post, we compare two methods:

  1. A continuous-time Petri net model using Ordinary Differential Equations (ODEs).

  2. A branch-and-bound algorithm, a traditional combinatorial optimization technique.

While the Petri net approach appears advanced, it’s often simpler to implement and interpret, especially for dynamic systems.

Approach 1: Petri Net with ODEs

The Petri net model uses Petri.jl to represent the knapsack problem as a dynamic system:

  • States (places): Represent the items, weight, value, and capacity.
  • Transitions: Define how items are added based on resource constraints.
  • ODEs: Govern the rate of change, allowing for continuous simulation of token flows.
Why It Works:
  • Simplicity in Design: Defining states and transitions requires fewer lines of code compared to implementing a full algorithm.
  • Ease of Visualization: ODE solvers and plotting libraries make it easy to track how the knapsack evolves over time.
  • Dynamic Exploration: Exclusions (removing certain items) can be simulated by setting specific transition rates to zero, requiring only minor code changes.

Approach 2: Branch-and-Bound Algorithm

Review the algorithm in the ipython notebook on github.

Branch-and-bound is a powerful yet more traditional approach that systematically explores all possible solutions:

  1. Tree Structure: Each node represents a decision (to include or exclude an item).

  2. Bounds: Calculates upper and lower bounds to prune branches.

  3. Iterative Exploration: Examines feasible solutions to maximize the knapsack's value.

Why It Works:
  • Proven Optimization: Guarantees an optimal solution by exhaustively exploring all branches.
  • Deterministic Results: No approximations or reliance on differential solvers.

Output from the branch-and-bound algorithm:

  • Maximal Value = 38

Which one to use?

  • For dynamic and exploratory analysis: The Petri net with ODEs is ideal. It offers a clear and flexible way to visualize how systems behave under various constraints.
  • For exact and guaranteed solutions: Branch-and-bound ensures optimality but comes with a higher implementation cost and less adaptability to dynamic changes.

Conclusion

While branch-and-bound excels in classic optimization, the Petri net approach proves that even advanced methods can be simpler and more intuitive in certain contexts. By leveraging tools like Petri.jl, we can tackle dynamic problems with ease, gaining insights without the overhead of intricate algorithms.

If you're diving into optimization or exploring Petri nets, try both methods and see which suits your needs. Continuous modeling might just surprise you with its simplicity and power.

Review the ipython notebook using Petri.jl w/ ODE solvers.

In our previous post, we demonstrated how Petri.jl can model Tic-Tac-Toe by translating its states and transitions into a dynamic Petri net framework. By embedding win conditions into Ordinary Differential Equations (ODEs), we quantified move heuristics to evaluate the value of each opening move.

Heuristics: Quantifying Strategy

We calculated heuristic scores for all possible opening moves by Player X. The results highlight the strategic significance of each position:

 -------- Scores -------
| 1.146 | 1.082 | 1.146 |
| 1.082 | 1.228 | 1.082 |
| 1.146 | 1.082 | 1.146 |

The center (P11) scores highest (1.228), confirming its importance. Corners follow, while edges lag behind.

Visualizing Probabilities

Simulations show how win probabilities evolve over time:

  • Center moves dominate quickly.
  • Corners remain competitive.
  • Edges grow slower, reflecting weaker strategic potential.

Broader Implications

This analysis validates Petri.jl as a robust tool for quantifying decision-making processes. Beyond games, it can model and optimize strategies in diverse domains.

Next Steps: Exploring Gossip Protocols

Having shown this technique works, we will now apply it to broader problems. Our next focus is modeling a simple gossip protocol to understand message propagation and consensus dynamics.

Stay tuned as we extend Petri.jl's capabilities to new frontiers of computational modeling!

Link to Notebook:

Some time ago, we explored modeling the classic game of Tic-Tac-Toe as a Petri net, demonstrating how this formalism could elegantly represent the interplay between game states and transitions. Today, we revisit this idea with fresh insights and a more advanced approach using Petri.jl, a Julia library that offers powerful tools for constructing and analyzing Petri nets.

From Concept to Visualization

Petri.jl allows us to model Tic-Tac-Toe in a way that's both expressive and computationally robust. Below is a visualization of the Petri net we constructed for Tic-Tac-Toe:

This graph showcases the game states as places and the player moves as transitions. Each directed arc represents the flow of tokens—analogous to moves advancing the game toward its conclusion.

Revisiting the Formalism

At its core, the Tic-Tac-Toe model encapsulates the following:

  1. Places: Represent the current state of the game (e.g., empty squares, player moves).

  2. Transitions: Represent the legal moves available to each player.

  3. Tokens: Indicate the state of play (e.g., which squares are occupied by X or O).

This approach highlights the game's structure, showing how states evolve as moves are made.

Analyzing Dynamics with ODEs

One of the most exciting possibilities opened up by Petri.jl is the ability to translate our Petri net into a system of Ordinary Differential Equations (ODEs). This enables a quantitative analysis of the game dynamics.

For

  • Each place corresponds to a variable representing the state of the board.
  • Transitions influence these variables based on player actions.
  • Solving the ODE system reveals trajectories of game progression.

Ensuring the Plot Matches the Game with Internal Win Conditions

The plots above appear to converge quickly to stable values, aligning with the game rules: the Next turn transition activates at t=1, and all moves settle to 0 starting at t=2. However, to confirm that this behavior accurately represents the game, we extended the Petri net model to include win conditions directly within the ODE system.

By embedding these conditions, we create a new ODEProblem that integrates both state dynamics and game logic. This approach ensures that the model can verify win outcomes internally, providing a stronger connection between the ODE-generated results and the expected behavior of Tic-Tac-Toe.

Model Checking X/O Win ratio

The extended model the Petri net to include places representing win conditions for each player. Each time a win condition was met, a token was deposited in the corresponding winx_ or wino_ place. After we solved and plotted the result, we measured this ratio at t=9.

Remarkably, the results showed only a 0.85% error compared to the expected statistical win ratios for Tic-Tac-Toe. This seems to demonst the model's accuracy in reflecting real-game dynamics.

Why This Matters

Revisiting our Tic-Tac-Toe model with modern tools like Petri.jl underscores how mathematical frameworks evolve alongside computational advancements. It also highlights the versatility of Petri nets in capturing not just static systems but also dynamic, strategy-driven games like Tic-Tac-Toe.

Next Steps

This approach is just the beginning. Future explorations could include:

  • Extending the model to other games with more complex rules.
  • Investigate how adding other Petri-net structures affect the dynamics of the ODE plots.

Python notebook with source code used in this post is available here

Pflow’s workflow implementation simplifies and extends WF-net ideas for practical, real-world systems by:

  1. Adding retry and reentry mechanisms (allow_reentry).

  2. Restricting state behaviors to enforce runtime constraints.

  3. Focusing on execution rather than pre-runtime verification.

WF-nets remain a formal and abstract framework for analyzing workflows, often requiring specialized tooling and theoretical grounding. Pflow’s workflow model aligns more with runtime task automation and system engineering.