3 releases (breaking)
0.3.0 | Sep 22, 2024 |
---|---|
0.2.0 | Sep 14, 2024 |
0.1.2 | Mar 9, 2024 |
0.1.1 |
|
0.1.0 |
|
#20 in #role
94KB
1.5K
SLoC
metamodel
Declarative Petri-nets using a rust DSL.
lib.rs
:
Metamodel - A Rust Library for Abstract State Machine Modeling
See the code below for an example of how to create a Petri-net model using the pflow_metamodel
library.
Also see: Macro pflow_metamodel::pflow_dsl for creating models using an internal rust DSL rather than json.
use pflow_metamodel::*;
let model: Model = pflow_json!{{
"modelType": "petriNet",
"version": "v0",
"places": {
"place0": { "offset": 0, "capacity": 3, "x": 100, "y": 180 }
},
"transitions": {
"txn0": { "role": "role0", "x": 20, "y": 100 },
"txn1": { "role": "role0", "x": 180, "y": 100 },
"txn2": { "role": "role0", "x": 20, "y": 260 },
"txn3": { "role": "role0", "x": 180, "y": 260 }
},
"arcs": [
{ "source": "txn0", "target": "place0" },
{ "source": "place0", "target": "txn1", "weight": 3 },
{ "source": "txn2", "target": "place0", "weight": 3, "inhibit": true },
{ "source": "place0", "target": "txn3", "inhibit": true }
]
}};
let state = model.vm.initial_vector();
assert_eq!(state, vec![0]);
let res = model.vm.transform(&state, "txn0", 1);
assert!(res.ok);
assert_eq!(state, vec![0]); // input state is _not_ mutated
assert_eq!(res.output, vec![1]);
let t = model.net.transitions.get("txn0");
assert!(t.is_some());
- Provides a DSL-driven framework for modeling and simulating Petri-nets, wf-nets, and DFAs.
- State machine data types are executed as a Vector Addition State Machine (VASM).
- Data models are viewable / shareable in browsers by using https://pflow.dev JSON format.
- Models can be compressed and shared as base64 encoded blobs.
- Models can be consistently hashed and shared as CIDs.
Dining Philosophers Example
The following example demonstrates the dining philosophers problem using the PetriNet
struct.
- read more about the dining philosophers problem.
- interact with the model dining philosophers model
use pflow_metamodel::*;
let model = pflow_json!{{
"modelType": "petriNet",
"version": "v0",
"places": {
"chopstick0": { "offset": 0, "initial": 1, "x": 403, "y": 340 },
"chopstick1": { "offset": 1, "initial": 1, "x": 534, "y": 345 },
"chopstick2": { "offset": 2, "initial": 1, "x": 358, "y": 467 },
"chopstick3": { "offset": 3, "initial": 1, "x": 547, "y": 461 },
"chopstick4": { "offset": 4, "initial": 1, "x": 451, "y": 536 },
"0right": { "offset": 5, "x": 415, "y": 181 },
"0left": { "offset": 6, "x": 545, "y": 177 },
"1right": { "offset": 7, "x": 719, "y": 288 },
"1left": { "offset": 8, "x": 769, "y": 404 },
"2left": { "offset": 9, "x": 686, "y": 584 },
"2right": { "offset": 10, "x": 594, "y": 678 },
"3left": { "offset": 11, "x": 315, "y": 679 },
"3right": { "offset": 12, "x": 216, "y": 608 },
"4right": { "offset": 13, "x": 148, "y": 397 },
"4left": { "offset": 14, "x": 183, "y": 289 }
},
"transitions": {
"0think": { "x": 478, "y": 106 },
"0eat": { "x": 473, "y": 247 },
"1eat": { "x": 654, "y": 396 },
"2eat": { "x": 574, "y": 573 },
"3eat": { "x": 333, "y": 556 },
"4eat": { "x": 267, "y": 370 },
"1think": { "x": 842, "y": 304 },
"4think": { "x": 72, "y": 314 },
"3think": { "x": 200, "y": 726 },
"2think": { "x": 740, "y": 699 }
},
"arcs": [
{ "source": "chopstick0", "target": "0eat" },
{ "source": "chopstick1", "target": "0eat" },
{ "source": "chopstick0", "target": "4eat" },
{ "source": "chopstick2", "target": "4eat" },
{ "source": "chopstick1", "target": "1eat" },
{ "source": "chopstick3", "target": "1eat" },
{ "source": "chopstick2", "target": "3eat" },
{ "source": "chopstick4", "target": "3eat" },
{ "source": "chopstick4", "target": "2eat" },
{ "source": "chopstick3", "target": "2eat" },
{ "source": "0eat", "target": "0right" },
{ "source": "0eat", "target": "0left" },
{ "source": "1eat", "target": "1right" },
{ "source": "1eat", "target": "1left" },
{ "source": "2eat", "target": "2left" },
{ "source": "2eat", "target": "2right" },
{ "source": "3eat", "target": "3right" },
{ "source": "3eat", "target": "3left" },
{ "source": "4eat", "target": "4right" },
{ "source": "4eat", "target": "4left" },
{ "source": "0right", "target": "0think" },
{ "source": "0left", "target": "0think" },
{ "source": "1right", "target": "1think" },
{ "source": "1left", "target": "1think" },
{ "source": "2left", "target": "2think" },
{ "source": "2right", "target": "2think" },
{ "source": "4left", "target": "4think" },
{ "source": "4right", "target": "4think" },
{ "source": "3right", "target": "3think" },
{ "source": "3left", "target": "3think" },
{ "source": "4think", "target": "chopstick0" },
{ "source": "4think", "target": "chopstick2" },
{ "source": "0think", "target": "chopstick0" },
{ "source": "0think", "target": "chopstick1" },
{ "source": "1think", "target": "chopstick1" },
{ "source": "1think", "target": "chopstick3" },
{ "source": "2think", "target": "chopstick3" },
{ "source": "2think", "target": "chopstick4" },
{ "source": "3think", "target": "chopstick2" },
{ "source": "3think", "target": "chopstick4" }
]
}};
Dependencies
~9MB
~316K SLoC