libpetri 2.6.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- libpetri-2.6.0/PKG-INFO +140 -0
- libpetri-2.6.0/README.md +118 -0
- libpetri-2.6.0/libpetri/__init__.py +180 -0
- libpetri-2.6.0/libpetri/__init__.pyi +94 -0
- libpetri-2.6.0/libpetri/_libpetri.pyi +362 -0
- libpetri-2.6.0/libpetri/debug.py +88 -0
- libpetri-2.6.0/libpetri/debug.pyi +42 -0
- libpetri-2.6.0/libpetri/export.py +16 -0
- libpetri-2.6.0/libpetri/export.pyi +13 -0
- libpetri-2.6.0/libpetri/model.py +159 -0
- libpetri-2.6.0/libpetri/model.pyi +61 -0
- libpetri-2.6.0/libpetri/py.typed +0 -0
- libpetri-2.6.0/libpetri/runtime.py +196 -0
- libpetri-2.6.0/libpetri/runtime.pyi +83 -0
- libpetri-2.6.0/libpetri/verification.py +101 -0
- libpetri-2.6.0/libpetri/verification.pyi +42 -0
- libpetri-2.6.0/pyproject.toml +42 -0
- libpetri-2.6.0/rust/Cargo.lock +1351 -0
- libpetri-2.6.0/rust/Cargo.toml +32 -0
- libpetri-2.6.0/rust/libpetri/Cargo.toml +34 -0
- libpetri-2.6.0/rust/libpetri/README.md +268 -0
- libpetri-2.6.0/rust/libpetri/build.rs +229 -0
- libpetri-2.6.0/rust/libpetri/doc/showcase.svg +437 -0
- libpetri-2.6.0/rust/libpetri/examples/basic.rs +229 -0
- libpetri-2.6.0/rust/libpetri/src/lib.rs +113 -0
- libpetri-2.6.0/rust/libpetri/tests/auto_compose.rs +335 -0
- libpetri-2.6.0/rust/libpetri/tests/channel_composition.rs +174 -0
- libpetri-2.6.0/rust/libpetri/tests/compose_direct_e2e.rs +360 -0
- libpetri-2.6.0/rust/libpetri/tests/compose_e2e.rs +288 -0
- libpetri-2.6.0/rust/libpetri/tests/cross_lang_flat_dot.rs +56 -0
- libpetri-2.6.0/rust/libpetri/tests/cross_lang_inhibitor_read_dot.rs +66 -0
- libpetri-2.6.0/rust/libpetri/tests/cross_lang_junctions_dot.rs +98 -0
- libpetri-2.6.0/rust/libpetri/tests/cross_lang_pipeline_dot.rs +135 -0
- libpetri-2.6.0/rust/libpetri/tests/cross_lang_reset_output_dot.rs +53 -0
- libpetri-2.6.0/rust/libpetri/tests/fusion.rs +591 -0
- libpetri-2.6.0/rust/libpetri/tests/subnet_verify.rs +237 -0
- libpetri-2.6.0/rust/libpetri-core/Cargo.toml +17 -0
- libpetri-2.6.0/rust/libpetri-core/doc/arc_types.svg +79 -0
- libpetri-2.6.0/rust/libpetri-core/doc/timing_modes.svg +137 -0
- libpetri-2.6.0/rust/libpetri-core/src/action.rs +236 -0
- libpetri-2.6.0/rust/libpetri-core/src/arc.rs +40 -0
- libpetri-2.6.0/rust/libpetri-core/src/compose.rs +702 -0
- libpetri-2.6.0/rust/libpetri-core/src/context.rs +430 -0
- libpetri-2.6.0/rust/libpetri-core/src/fusion.rs +315 -0
- libpetri-2.6.0/rust/libpetri-core/src/input.rs +347 -0
- libpetri-2.6.0/rust/libpetri-core/src/instance.rs +388 -0
- libpetri-2.6.0/rust/libpetri-core/src/interface.rs +303 -0
- libpetri-2.6.0/rust/libpetri-core/src/lib.rs +86 -0
- libpetri-2.6.0/rust/libpetri-core/src/output.rs +292 -0
- libpetri-2.6.0/rust/libpetri-core/src/petri_net.rs +1183 -0
- libpetri-2.6.0/rust/libpetri-core/src/place.rs +157 -0
- libpetri-2.6.0/rust/libpetri-core/src/rewriter.rs +1358 -0
- libpetri-2.6.0/rust/libpetri-core/src/subnet.rs +166 -0
- libpetri-2.6.0/rust/libpetri-core/src/subnet_def.rs +772 -0
- libpetri-2.6.0/rust/libpetri-core/src/subnet_instance.rs +34 -0
- libpetri-2.6.0/rust/libpetri-core/src/timing.rs +155 -0
- libpetri-2.6.0/rust/libpetri-core/src/token.rs +173 -0
- libpetri-2.6.0/rust/libpetri-core/src/transition.rs +411 -0
- libpetri-2.6.0/rust/libpetri-core/tests/composition_properties.proptest-regressions +7 -0
- libpetri-2.6.0/rust/libpetri-core/tests/composition_properties.rs +401 -0
- libpetri-2.6.0/rust/libpetri-debug/Cargo.toml +22 -0
- libpetri-2.6.0/rust/libpetri-debug/src/archive/mod.rs +25 -0
- libpetri-2.6.0/rust/libpetri-debug/src/archive/session_archive.rs +234 -0
- libpetri-2.6.0/rust/libpetri-debug/src/archive/session_archive_reader.rs +871 -0
- libpetri-2.6.0/rust/libpetri-debug/src/archive/session_archive_storage.rs +30 -0
- libpetri-2.6.0/rust/libpetri-debug/src/archive/session_archive_writer.rs +288 -0
- libpetri-2.6.0/rust/libpetri-debug/src/archive/session_metadata.rs +228 -0
- libpetri-2.6.0/rust/libpetri-debug/src/debug_aware_event_store.rs +156 -0
- libpetri-2.6.0/rust/libpetri-debug/src/debug_command.rs +386 -0
- libpetri-2.6.0/rust/libpetri-debug/src/debug_event_store.rs +288 -0
- libpetri-2.6.0/rust/libpetri-debug/src/debug_protocol_handler.rs +1336 -0
- libpetri-2.6.0/rust/libpetri-debug/src/debug_response.rs +489 -0
- libpetri-2.6.0/rust/libpetri-debug/src/debug_session_registry.rs +1084 -0
- libpetri-2.6.0/rust/libpetri-debug/src/lib.rs +45 -0
- libpetri-2.6.0/rust/libpetri-debug/src/marking_cache.rs +324 -0
- libpetri-2.6.0/rust/libpetri-debug/src/net_event_converter.rs +359 -0
- libpetri-2.6.0/rust/libpetri-debug/src/place_analysis.rs +124 -0
- libpetri-2.6.0/rust/libpetri-debug/src/token_projector_registry.rs +166 -0
- libpetri-2.6.0/rust/libpetri-docgen/Cargo.toml +13 -0
- libpetri-2.6.0/rust/libpetri-docgen/resources/petrinet-diagrams.css +766 -0
- libpetri-2.6.0/rust/libpetri-docgen/resources/petrinet-diagrams.js +7245 -0
- libpetri-2.6.0/rust/libpetri-docgen/src/diagram_renderer.rs +263 -0
- libpetri-2.6.0/rust/libpetri-docgen/src/lib.rs +362 -0
- libpetri-2.6.0/rust/libpetri-docgen/src/subnet_dot_export.rs +367 -0
- libpetri-2.6.0/rust/libpetri-docgen/src/subnet_header.rs +187 -0
- libpetri-2.6.0/rust/libpetri-docgen/tests/subnet_diagrams.rs +232 -0
- libpetri-2.6.0/rust/libpetri-event/Cargo.toml +11 -0
- libpetri-2.6.0/rust/libpetri-event/src/event_store.rs +173 -0
- libpetri-2.6.0/rust/libpetri-event/src/lib.rs +41 -0
- libpetri-2.6.0/rust/libpetri-event/src/net_event.rs +240 -0
- libpetri-2.6.0/rust/libpetri-event/src/token_payload.rs +43 -0
- libpetri-2.6.0/rust/libpetri-export/Cargo.toml +12 -0
- libpetri-2.6.0/rust/libpetri-export/doc/export_example.svg +93 -0
- libpetri-2.6.0/rust/libpetri-export/src/cluster_builder.rs +630 -0
- libpetri-2.6.0/rust/libpetri-export/src/dot_exporter.rs +306 -0
- libpetri-2.6.0/rust/libpetri-export/src/dot_renderer.rs +505 -0
- libpetri-2.6.0/rust/libpetri-export/src/graph.rs +196 -0
- libpetri-2.6.0/rust/libpetri-export/src/lib.rs +78 -0
- libpetri-2.6.0/rust/libpetri-export/src/mapper.rs +1073 -0
- libpetri-2.6.0/rust/libpetri-export/src/styles.rs +167 -0
- libpetri-2.6.0/rust/libpetri-export/src/subnet_prefixes.rs +63 -0
- libpetri-2.6.0/rust/libpetri-py/Cargo.toml +29 -0
- libpetri-2.6.0/rust/libpetri-py/src/action.rs +391 -0
- libpetri-2.6.0/rust/libpetri-py/src/debug.rs +165 -0
- libpetri-2.6.0/rust/libpetri-py/src/error.rs +46 -0
- libpetri-2.6.0/rust/libpetri-py/src/executor.rs +229 -0
- libpetri-2.6.0/rust/libpetri-py/src/export.rs +122 -0
- libpetri-2.6.0/rust/libpetri-py/src/lib.rs +30 -0
- libpetri-2.6.0/rust/libpetri-py/src/model.rs +948 -0
- libpetri-2.6.0/rust/libpetri-py/src/value.rs +114 -0
- libpetri-2.6.0/rust/libpetri-py/src/verification.rs +325 -0
- libpetri-2.6.0/rust/libpetri-runtime/Cargo.toml +21 -0
- libpetri-2.6.0/rust/libpetri-runtime/build.rs +129 -0
- libpetri-2.6.0/rust/libpetri-runtime/src/bitmap.rs +232 -0
- libpetri-2.6.0/rust/libpetri-runtime/src/compiled_net.rs +368 -0
- libpetri-2.6.0/rust/libpetri-runtime/src/environment.rs +36 -0
- libpetri-2.6.0/rust/libpetri-runtime/src/executor.rs +3593 -0
- libpetri-2.6.0/rust/libpetri-runtime/src/executor_handle.rs +194 -0
- libpetri-2.6.0/rust/libpetri-runtime/src/lib.rs +73 -0
- libpetri-2.6.0/rust/libpetri-runtime/src/marking.rs +214 -0
- libpetri-2.6.0/rust/libpetri-runtime/src/owned_precompiled.rs +251 -0
- libpetri-2.6.0/rust/libpetri-runtime/src/precompiled_executor.rs +2635 -0
- libpetri-2.6.0/rust/libpetri-runtime/src/precompiled_net.rs +524 -0
- libpetri-2.6.0/rust/libpetri-verification/Cargo.toml +19 -0
- libpetri-2.6.0/rust/libpetri-verification/build.rs +61 -0
- libpetri-2.6.0/rust/libpetri-verification/src/analyzer.rs +745 -0
- libpetri-2.6.0/rust/libpetri-verification/src/counterexample.rs +160 -0
- libpetri-2.6.0/rust/libpetri-verification/src/dbm.rs +554 -0
- libpetri-2.6.0/rust/libpetri-verification/src/environment.rs +44 -0
- libpetri-2.6.0/rust/libpetri-verification/src/harness.rs +623 -0
- libpetri-2.6.0/rust/libpetri-verification/src/incidence_matrix.rs +117 -0
- libpetri-2.6.0/rust/libpetri-verification/src/lib.rs +68 -0
- libpetri-2.6.0/rust/libpetri-verification/src/marking_state.rs +177 -0
- libpetri-2.6.0/rust/libpetri-verification/src/net_flattener.rs +180 -0
- libpetri-2.6.0/rust/libpetri-verification/src/p_invariant.rs +249 -0
- libpetri-2.6.0/rust/libpetri-verification/src/property.rs +71 -0
- libpetri-2.6.0/rust/libpetri-verification/src/result.rs +63 -0
- libpetri-2.6.0/rust/libpetri-verification/src/scc.rs +163 -0
- libpetri-2.6.0/rust/libpetri-verification/src/smt_encoder.rs +447 -0
- libpetri-2.6.0/rust/libpetri-verification/src/smt_verifier.rs +453 -0
- libpetri-2.6.0/rust/libpetri-verification/src/state_class.rs +94 -0
- libpetri-2.6.0/rust/libpetri-verification/src/state_class_graph.rs +870 -0
- libpetri-2.6.0/rust/libpetri-verification/src/structural_check.rs +208 -0
libpetri-2.6.0/PKG-INFO
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: libpetri
|
|
3
|
+
Version: 2.6.0
|
|
4
|
+
Classifier: Development Status :: 4 - Beta
|
|
5
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
6
|
+
Classifier: Programming Language :: Python :: 3
|
|
7
|
+
Classifier: Programming Language :: Rust
|
|
8
|
+
Classifier: Typing :: Typed
|
|
9
|
+
Requires-Dist: maturin>=1.8,<2 ; extra == 'dev'
|
|
10
|
+
Requires-Dist: pytest>=8.3 ; extra == 'dev'
|
|
11
|
+
Requires-Dist: pytest-asyncio>=0.24 ; extra == 'dev'
|
|
12
|
+
Requires-Dist: pytest-benchmark>=5.0 ; extra == 'dev'
|
|
13
|
+
Provides-Extra: dev
|
|
14
|
+
Summary: Python bindings for libpetri
|
|
15
|
+
Keywords: petri-net,workflow,verification,graphviz,python
|
|
16
|
+
Home-Page: https://libpetri.org
|
|
17
|
+
Author: Dennis Berger
|
|
18
|
+
License: Apache-2.0
|
|
19
|
+
Requires-Python: >=3.11
|
|
20
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
21
|
+
|
|
22
|
+
# libpetri
|
|
23
|
+
|
|
24
|
+
[](https://pypi.org/project/libpetri/)
|
|
25
|
+
[](https://pypi.org/project/libpetri/)
|
|
26
|
+
[](https://github.com/libpetri/libpetri/blob/main/LICENSE)
|
|
27
|
+
|
|
28
|
+
**Python bindings for the libpetri Coloured Time Petri Net engine.**
|
|
29
|
+
|
|
30
|
+
Compose typed Petri nets in Python, run them on the Rust executor through PyO3.
|
|
31
|
+
Full surface parity with the Java, TypeScript, and Rust implementations — same
|
|
32
|
+
arc types, timing modes, composition primitives, formal-verification API,
|
|
33
|
+
debug protocol, and DOT export.
|
|
34
|
+
|
|
35
|
+
## Install
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pip install libpetri
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Wheels are published for CPython 3.11, 3.12, 3.13 on Linux / macOS / Windows
|
|
42
|
+
(x86-64 and arm64).
|
|
43
|
+
|
|
44
|
+
## Quick example
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
import libpetri as lp
|
|
48
|
+
|
|
49
|
+
request = lp.Place("Request")
|
|
50
|
+
response = lp.Place("Response")
|
|
51
|
+
|
|
52
|
+
def process(ctx: lp.TransitionContext) -> None:
|
|
53
|
+
req = ctx.input("Request")
|
|
54
|
+
ctx.output("Response", f"Processed: {req}")
|
|
55
|
+
|
|
56
|
+
net = (
|
|
57
|
+
lp.Net("Example")
|
|
58
|
+
.transition(
|
|
59
|
+
lp.Transition("Process")
|
|
60
|
+
.input(lp.one(request))
|
|
61
|
+
.output(lp.out(response))
|
|
62
|
+
.timing(lp.deadline(5000))
|
|
63
|
+
.action(process)
|
|
64
|
+
.build()
|
|
65
|
+
)
|
|
66
|
+
.build()
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
result = lp.run_sync(net, initial={request: ["hello"]})
|
|
70
|
+
print(result.first(response)) # → "Processed: hello"
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Async callbacks work the same way; `lp.run_async` drives `async def` actions
|
|
74
|
+
on tokio, releasing the GIL between awaits:
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
import asyncio, libpetri as lp
|
|
78
|
+
|
|
79
|
+
async def main() -> None:
|
|
80
|
+
incoming = lp.Place("incoming")
|
|
81
|
+
approved = lp.Place("approved")
|
|
82
|
+
|
|
83
|
+
async def approve(ctx: lp.TransitionContext) -> None:
|
|
84
|
+
order = ctx.input("incoming")
|
|
85
|
+
await asyncio.sleep(0) # any awaitable works
|
|
86
|
+
ctx.output("approved", {**order, "approved": True})
|
|
87
|
+
|
|
88
|
+
net = (
|
|
89
|
+
lp.Net("orders")
|
|
90
|
+
.transition(
|
|
91
|
+
lp.Transition("approve")
|
|
92
|
+
.input(lp.one(incoming))
|
|
93
|
+
.output(lp.out(approved))
|
|
94
|
+
.action(approve)
|
|
95
|
+
.build()
|
|
96
|
+
)
|
|
97
|
+
.build()
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
result = await lp.run_async(net, initial={incoming: [{"id": 1}]})
|
|
101
|
+
print(result.first(approved)) # → {'id': 1, 'approved': True}
|
|
102
|
+
|
|
103
|
+
asyncio.run(main())
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## What you get
|
|
107
|
+
|
|
108
|
+
- **Full runtime** — sync + async execution, environment-place injection, all
|
|
109
|
+
five arc kinds (input / output / inhibitor / read / reset), all five timing
|
|
110
|
+
modes, priority + FIFO scheduling.
|
|
111
|
+
- **Composition** — `SubnetDef` with typed ports + channels, `compose(...)`
|
|
112
|
+
via structural rewrite, port bindings, instance prefixes.
|
|
113
|
+
- **Formal verification** — SMT/IC3 properties (deadlock-free, mutual
|
|
114
|
+
exclusion, place bound, unreachable) through Z3 when the wheel ships with
|
|
115
|
+
the `z3` system library available.
|
|
116
|
+
- **Debug protocol** — same JSON wire format as the Java / TypeScript
|
|
117
|
+
implementations; pair with the libpetri debug-ui for live inspection.
|
|
118
|
+
- **DOT / Graphviz export** — `lp.dot_export(net)`.
|
|
119
|
+
- **Typed and IDE-friendly** — ships with `.pyi` stubs and `py.typed`; IDE
|
|
120
|
+
autocomplete and `mypy --strict` work out of the box.
|
|
121
|
+
|
|
122
|
+
## A note on token typing
|
|
123
|
+
|
|
124
|
+
The Java, TypeScript, and Rust implementations enforce `Place[T]` at compile
|
|
125
|
+
time. The Python binding stores tokens as `Py<PyAny>` across the FFI boundary
|
|
126
|
+
— net *structure* (arcs, transitions, composition) is still validated, but
|
|
127
|
+
token *runtime types* are not. A place named `"order"` will accept dicts,
|
|
128
|
+
integers, or strings interchangeably. This is intentional: Python has no
|
|
129
|
+
static generics across the FFI. Validate at your boundary (Pydantic,
|
|
130
|
+
dataclasses, `isinstance`) and only put validated values into markings.
|
|
131
|
+
|
|
132
|
+
## Links
|
|
133
|
+
|
|
134
|
+
- [Source / specification / sibling implementations](https://github.com/libpetri/libpetri)
|
|
135
|
+
- [Spec (183 requirements, 11 files)](https://github.com/libpetri/libpetri/tree/main/spec)
|
|
136
|
+
- [CHANGELOG](https://github.com/libpetri/libpetri/blob/main/CHANGELOG.md)
|
|
137
|
+
- [Benchmarks](https://github.com/libpetri/libpetri/tree/main/python/benches)
|
|
138
|
+
|
|
139
|
+
[Apache License 2.0](https://github.com/libpetri/libpetri/blob/main/LICENSE)
|
|
140
|
+
|
libpetri-2.6.0/README.md
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# libpetri
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/libpetri/)
|
|
4
|
+
[](https://pypi.org/project/libpetri/)
|
|
5
|
+
[](https://github.com/libpetri/libpetri/blob/main/LICENSE)
|
|
6
|
+
|
|
7
|
+
**Python bindings for the libpetri Coloured Time Petri Net engine.**
|
|
8
|
+
|
|
9
|
+
Compose typed Petri nets in Python, run them on the Rust executor through PyO3.
|
|
10
|
+
Full surface parity with the Java, TypeScript, and Rust implementations — same
|
|
11
|
+
arc types, timing modes, composition primitives, formal-verification API,
|
|
12
|
+
debug protocol, and DOT export.
|
|
13
|
+
|
|
14
|
+
## Install
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pip install libpetri
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Wheels are published for CPython 3.11, 3.12, 3.13 on Linux / macOS / Windows
|
|
21
|
+
(x86-64 and arm64).
|
|
22
|
+
|
|
23
|
+
## Quick example
|
|
24
|
+
|
|
25
|
+
```python
|
|
26
|
+
import libpetri as lp
|
|
27
|
+
|
|
28
|
+
request = lp.Place("Request")
|
|
29
|
+
response = lp.Place("Response")
|
|
30
|
+
|
|
31
|
+
def process(ctx: lp.TransitionContext) -> None:
|
|
32
|
+
req = ctx.input("Request")
|
|
33
|
+
ctx.output("Response", f"Processed: {req}")
|
|
34
|
+
|
|
35
|
+
net = (
|
|
36
|
+
lp.Net("Example")
|
|
37
|
+
.transition(
|
|
38
|
+
lp.Transition("Process")
|
|
39
|
+
.input(lp.one(request))
|
|
40
|
+
.output(lp.out(response))
|
|
41
|
+
.timing(lp.deadline(5000))
|
|
42
|
+
.action(process)
|
|
43
|
+
.build()
|
|
44
|
+
)
|
|
45
|
+
.build()
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
result = lp.run_sync(net, initial={request: ["hello"]})
|
|
49
|
+
print(result.first(response)) # → "Processed: hello"
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Async callbacks work the same way; `lp.run_async` drives `async def` actions
|
|
53
|
+
on tokio, releasing the GIL between awaits:
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
import asyncio, libpetri as lp
|
|
57
|
+
|
|
58
|
+
async def main() -> None:
|
|
59
|
+
incoming = lp.Place("incoming")
|
|
60
|
+
approved = lp.Place("approved")
|
|
61
|
+
|
|
62
|
+
async def approve(ctx: lp.TransitionContext) -> None:
|
|
63
|
+
order = ctx.input("incoming")
|
|
64
|
+
await asyncio.sleep(0) # any awaitable works
|
|
65
|
+
ctx.output("approved", {**order, "approved": True})
|
|
66
|
+
|
|
67
|
+
net = (
|
|
68
|
+
lp.Net("orders")
|
|
69
|
+
.transition(
|
|
70
|
+
lp.Transition("approve")
|
|
71
|
+
.input(lp.one(incoming))
|
|
72
|
+
.output(lp.out(approved))
|
|
73
|
+
.action(approve)
|
|
74
|
+
.build()
|
|
75
|
+
)
|
|
76
|
+
.build()
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
result = await lp.run_async(net, initial={incoming: [{"id": 1}]})
|
|
80
|
+
print(result.first(approved)) # → {'id': 1, 'approved': True}
|
|
81
|
+
|
|
82
|
+
asyncio.run(main())
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## What you get
|
|
86
|
+
|
|
87
|
+
- **Full runtime** — sync + async execution, environment-place injection, all
|
|
88
|
+
five arc kinds (input / output / inhibitor / read / reset), all five timing
|
|
89
|
+
modes, priority + FIFO scheduling.
|
|
90
|
+
- **Composition** — `SubnetDef` with typed ports + channels, `compose(...)`
|
|
91
|
+
via structural rewrite, port bindings, instance prefixes.
|
|
92
|
+
- **Formal verification** — SMT/IC3 properties (deadlock-free, mutual
|
|
93
|
+
exclusion, place bound, unreachable) through Z3 when the wheel ships with
|
|
94
|
+
the `z3` system library available.
|
|
95
|
+
- **Debug protocol** — same JSON wire format as the Java / TypeScript
|
|
96
|
+
implementations; pair with the libpetri debug-ui for live inspection.
|
|
97
|
+
- **DOT / Graphviz export** — `lp.dot_export(net)`.
|
|
98
|
+
- **Typed and IDE-friendly** — ships with `.pyi` stubs and `py.typed`; IDE
|
|
99
|
+
autocomplete and `mypy --strict` work out of the box.
|
|
100
|
+
|
|
101
|
+
## A note on token typing
|
|
102
|
+
|
|
103
|
+
The Java, TypeScript, and Rust implementations enforce `Place[T]` at compile
|
|
104
|
+
time. The Python binding stores tokens as `Py<PyAny>` across the FFI boundary
|
|
105
|
+
— net *structure* (arcs, transitions, composition) is still validated, but
|
|
106
|
+
token *runtime types* are not. A place named `"order"` will accept dicts,
|
|
107
|
+
integers, or strings interchangeably. This is intentional: Python has no
|
|
108
|
+
static generics across the FFI. Validate at your boundary (Pydantic,
|
|
109
|
+
dataclasses, `isinstance`) and only put validated values into markings.
|
|
110
|
+
|
|
111
|
+
## Links
|
|
112
|
+
|
|
113
|
+
- [Source / specification / sibling implementations](https://github.com/libpetri/libpetri)
|
|
114
|
+
- [Spec (183 requirements, 11 files)](https://github.com/libpetri/libpetri/tree/main/spec)
|
|
115
|
+
- [CHANGELOG](https://github.com/libpetri/libpetri/blob/main/CHANGELOG.md)
|
|
116
|
+
- [Benchmarks](https://github.com/libpetri/libpetri/tree/main/python/benches)
|
|
117
|
+
|
|
118
|
+
[Apache License 2.0](https://github.com/libpetri/libpetri/blob/main/LICENSE)
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
"""libpetri — Python bindings for the Rust Coloured Time Petri Net engine.
|
|
2
|
+
|
|
3
|
+
Note on token typing: the Java, TypeScript, and Rust implementations enforce
|
|
4
|
+
``Place[T]`` token types at compile time. The Python binding stores tokens as
|
|
5
|
+
``Py<PyAny>`` across the FFI boundary — net *structure* (arcs, transitions,
|
|
6
|
+
composition) is still validated, but token *runtime types* are not. A place
|
|
7
|
+
named ``"order"`` will accept dicts, integers, or strings interchangeably.
|
|
8
|
+
This is intentional: Python has no static generics across the FFI. If you need
|
|
9
|
+
type discipline, validate at your boundary (Pydantic, dataclasses, ``isinstance``)
|
|
10
|
+
and only put validated values into markings.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
16
|
+
|
|
17
|
+
from . import _libpetri
|
|
18
|
+
from .debug import DebugProtocolHandler, SessionSummary, require_debug
|
|
19
|
+
from .export import DotConfig, RankDir, dot_export
|
|
20
|
+
from .model import (
|
|
21
|
+
BuiltNet,
|
|
22
|
+
BuiltSubnetDef,
|
|
23
|
+
BuiltTransition,
|
|
24
|
+
BuiltinAction,
|
|
25
|
+
Channel,
|
|
26
|
+
fork,
|
|
27
|
+
passthrough,
|
|
28
|
+
InputSpec,
|
|
29
|
+
Instance,
|
|
30
|
+
InhibitorArc,
|
|
31
|
+
Net,
|
|
32
|
+
NetBuilder,
|
|
33
|
+
OutputSpec,
|
|
34
|
+
Place,
|
|
35
|
+
Port,
|
|
36
|
+
ReadArc,
|
|
37
|
+
ResetArc,
|
|
38
|
+
SubnetDef,
|
|
39
|
+
SubnetDefBuilder,
|
|
40
|
+
SubnetInstance,
|
|
41
|
+
Timing,
|
|
42
|
+
Transition,
|
|
43
|
+
TransitionBuilder,
|
|
44
|
+
TransitionContext,
|
|
45
|
+
all_tokens,
|
|
46
|
+
and_,
|
|
47
|
+
and_outputs,
|
|
48
|
+
at_least,
|
|
49
|
+
deadline,
|
|
50
|
+
delayed,
|
|
51
|
+
exact,
|
|
52
|
+
exactly,
|
|
53
|
+
forward_input,
|
|
54
|
+
immediate,
|
|
55
|
+
inhibitor,
|
|
56
|
+
one,
|
|
57
|
+
out,
|
|
58
|
+
out_place,
|
|
59
|
+
read,
|
|
60
|
+
reset,
|
|
61
|
+
timeout,
|
|
62
|
+
window,
|
|
63
|
+
xor,
|
|
64
|
+
xor_outputs,
|
|
65
|
+
)
|
|
66
|
+
from .runtime import (
|
|
67
|
+
CompiledNet,
|
|
68
|
+
ExecutorHandle,
|
|
69
|
+
ExecutorOptions,
|
|
70
|
+
MarkingView,
|
|
71
|
+
compile,
|
|
72
|
+
run_async,
|
|
73
|
+
run_sync,
|
|
74
|
+
start_async,
|
|
75
|
+
)
|
|
76
|
+
from .verification import (
|
|
77
|
+
PropertyResult,
|
|
78
|
+
SmtProperty,
|
|
79
|
+
SubnetVerificationResult,
|
|
80
|
+
VerificationHarness,
|
|
81
|
+
VerificationResult,
|
|
82
|
+
deadlock_free,
|
|
83
|
+
mutual_exclusion,
|
|
84
|
+
place_bound,
|
|
85
|
+
unreachable,
|
|
86
|
+
verify,
|
|
87
|
+
verify_subnet,
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
CallbackError = _libpetri.CallbackError
|
|
91
|
+
LibpetriError = _libpetri.LibpetriError
|
|
92
|
+
StructureError = _libpetri.StructureError
|
|
93
|
+
|
|
94
|
+
HAS_TOKIO = bool(_libpetri.HAS_TOKIO)
|
|
95
|
+
HAS_Z3 = bool(_libpetri.HAS_Z3)
|
|
96
|
+
HAS_DEBUG = bool(_libpetri.HAS_DEBUG)
|
|
97
|
+
|
|
98
|
+
try:
|
|
99
|
+
__version__ = version("libpetri")
|
|
100
|
+
except PackageNotFoundError:
|
|
101
|
+
__version__ = "0+local"
|
|
102
|
+
|
|
103
|
+
__all__ = [
|
|
104
|
+
"__version__",
|
|
105
|
+
"BuiltinAction",
|
|
106
|
+
"CallbackError",
|
|
107
|
+
"Channel",
|
|
108
|
+
"fork",
|
|
109
|
+
"passthrough",
|
|
110
|
+
"CompiledNet",
|
|
111
|
+
"DebugProtocolHandler",
|
|
112
|
+
"DotConfig",
|
|
113
|
+
"ExecutorHandle",
|
|
114
|
+
"ExecutorOptions",
|
|
115
|
+
"HAS_DEBUG",
|
|
116
|
+
"HAS_TOKIO",
|
|
117
|
+
"HAS_Z3",
|
|
118
|
+
"InputSpec",
|
|
119
|
+
"InhibitorArc",
|
|
120
|
+
"Instance",
|
|
121
|
+
"LibpetriError",
|
|
122
|
+
"MarkingView",
|
|
123
|
+
"Net",
|
|
124
|
+
"NetBuilder",
|
|
125
|
+
"OutputSpec",
|
|
126
|
+
"Place",
|
|
127
|
+
"Port",
|
|
128
|
+
"PropertyResult",
|
|
129
|
+
"RankDir",
|
|
130
|
+
"ReadArc",
|
|
131
|
+
"ResetArc",
|
|
132
|
+
"SessionSummary",
|
|
133
|
+
"SmtProperty",
|
|
134
|
+
"StructureError",
|
|
135
|
+
"SubnetDef",
|
|
136
|
+
"SubnetDefBuilder",
|
|
137
|
+
"SubnetInstance",
|
|
138
|
+
"SubnetVerificationResult",
|
|
139
|
+
"Timing",
|
|
140
|
+
"Transition",
|
|
141
|
+
"TransitionBuilder",
|
|
142
|
+
"TransitionContext",
|
|
143
|
+
"VerificationHarness",
|
|
144
|
+
"VerificationResult",
|
|
145
|
+
"all_tokens",
|
|
146
|
+
"and_",
|
|
147
|
+
"and_outputs",
|
|
148
|
+
"at_least",
|
|
149
|
+
"compile",
|
|
150
|
+
"deadlock_free",
|
|
151
|
+
"deadline",
|
|
152
|
+
"delayed",
|
|
153
|
+
"dot_export",
|
|
154
|
+
"exact",
|
|
155
|
+
"exactly",
|
|
156
|
+
"forward_input",
|
|
157
|
+
"immediate",
|
|
158
|
+
"inhibitor",
|
|
159
|
+
"mutual_exclusion",
|
|
160
|
+
"one",
|
|
161
|
+
"out",
|
|
162
|
+
"out_place",
|
|
163
|
+
"place_bound",
|
|
164
|
+
"read",
|
|
165
|
+
"require_debug",
|
|
166
|
+
"reset",
|
|
167
|
+
"run_async",
|
|
168
|
+
"run_sync",
|
|
169
|
+
"start_async",
|
|
170
|
+
"timeout",
|
|
171
|
+
"unreachable",
|
|
172
|
+
"verify",
|
|
173
|
+
"verify_subnet",
|
|
174
|
+
"window",
|
|
175
|
+
"xor",
|
|
176
|
+
"xor_outputs",
|
|
177
|
+
"BuiltNet",
|
|
178
|
+
"BuiltSubnetDef",
|
|
179
|
+
"BuiltTransition",
|
|
180
|
+
]
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"""Type stubs for the libpetri public surface."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from . import _libpetri
|
|
6
|
+
from .debug import (
|
|
7
|
+
DebugProtocolHandler as DebugProtocolHandler,
|
|
8
|
+
SessionSummary as SessionSummary,
|
|
9
|
+
require_debug as require_debug,
|
|
10
|
+
)
|
|
11
|
+
from .export import (
|
|
12
|
+
DotConfig as DotConfig,
|
|
13
|
+
RankDir as RankDir,
|
|
14
|
+
dot_export as dot_export,
|
|
15
|
+
)
|
|
16
|
+
from .model import (
|
|
17
|
+
BuiltNet as BuiltNet,
|
|
18
|
+
BuiltSubnetDef as BuiltSubnetDef,
|
|
19
|
+
BuiltTransition as BuiltTransition,
|
|
20
|
+
BuiltinAction as BuiltinAction,
|
|
21
|
+
Channel as Channel,
|
|
22
|
+
InhibitorArc as InhibitorArc,
|
|
23
|
+
InputSpec as InputSpec,
|
|
24
|
+
Instance as Instance,
|
|
25
|
+
Net as Net,
|
|
26
|
+
NetBuilder as NetBuilder,
|
|
27
|
+
OutputSpec as OutputSpec,
|
|
28
|
+
Place as Place,
|
|
29
|
+
PlaceLike as PlaceLike,
|
|
30
|
+
Port as Port,
|
|
31
|
+
ReadArc as ReadArc,
|
|
32
|
+
ResetArc as ResetArc,
|
|
33
|
+
SubnetDef as SubnetDef,
|
|
34
|
+
SubnetDefBuilder as SubnetDefBuilder,
|
|
35
|
+
SubnetInstance as SubnetInstance,
|
|
36
|
+
Timing as Timing,
|
|
37
|
+
Transition as Transition,
|
|
38
|
+
TransitionBuilder as TransitionBuilder,
|
|
39
|
+
TransitionContext as TransitionContext,
|
|
40
|
+
all_tokens as all_tokens,
|
|
41
|
+
and_ as and_,
|
|
42
|
+
and_outputs as and_outputs,
|
|
43
|
+
at_least as at_least,
|
|
44
|
+
deadline as deadline,
|
|
45
|
+
delayed as delayed,
|
|
46
|
+
exact as exact,
|
|
47
|
+
exactly as exactly,
|
|
48
|
+
fork as fork,
|
|
49
|
+
forward_input as forward_input,
|
|
50
|
+
immediate as immediate,
|
|
51
|
+
inhibitor as inhibitor,
|
|
52
|
+
one as one,
|
|
53
|
+
out as out,
|
|
54
|
+
out_place as out_place,
|
|
55
|
+
passthrough as passthrough,
|
|
56
|
+
read as read,
|
|
57
|
+
reset as reset,
|
|
58
|
+
timeout as timeout,
|
|
59
|
+
window as window,
|
|
60
|
+
xor as xor,
|
|
61
|
+
xor_outputs as xor_outputs,
|
|
62
|
+
)
|
|
63
|
+
from .runtime import (
|
|
64
|
+
CompiledNet as CompiledNet,
|
|
65
|
+
ExecutorHandle as ExecutorHandle,
|
|
66
|
+
ExecutorOptions as ExecutorOptions,
|
|
67
|
+
MarkingView as MarkingView,
|
|
68
|
+
compile as compile,
|
|
69
|
+
run_async as run_async,
|
|
70
|
+
run_sync as run_sync,
|
|
71
|
+
start_async as start_async,
|
|
72
|
+
)
|
|
73
|
+
from .verification import (
|
|
74
|
+
PropertyResult as PropertyResult,
|
|
75
|
+
SmtProperty as SmtProperty,
|
|
76
|
+
SubnetVerificationResult as SubnetVerificationResult,
|
|
77
|
+
VerificationHarness as VerificationHarness,
|
|
78
|
+
VerificationResult as VerificationResult,
|
|
79
|
+
deadlock_free as deadlock_free,
|
|
80
|
+
mutual_exclusion as mutual_exclusion,
|
|
81
|
+
place_bound as place_bound,
|
|
82
|
+
unreachable as unreachable,
|
|
83
|
+
verify as verify,
|
|
84
|
+
verify_subnet as verify_subnet,
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
CallbackError = _libpetri.CallbackError
|
|
88
|
+
LibpetriError = _libpetri.LibpetriError
|
|
89
|
+
StructureError = _libpetri.StructureError
|
|
90
|
+
|
|
91
|
+
HAS_TOKIO: bool
|
|
92
|
+
HAS_Z3: bool
|
|
93
|
+
HAS_DEBUG: bool
|
|
94
|
+
__version__: str
|