libpetri 0.3.2
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.
- package/README.md +121 -0
- package/dist/chunk-FN773SSE.js +87 -0
- package/dist/chunk-FN773SSE.js.map +1 -0
- package/dist/chunk-VQ4XMJTD.js +107 -0
- package/dist/chunk-VQ4XMJTD.js.map +1 -0
- package/dist/export/index.d.ts +153 -0
- package/dist/export/index.js +411 -0
- package/dist/export/index.js.map +1 -0
- package/dist/index.d.ts +498 -0
- package/dist/index.js +1972 -0
- package/dist/index.js.map +1 -0
- package/dist/petri-net-C3Jy5HCt.d.ts +543 -0
- package/dist/verification/index.d.ts +505 -0
- package/dist/verification/index.js +1201 -0
- package/dist/verification/index.js.map +1 -0
- package/package.json +48 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,498 @@
|
|
|
1
|
+
import { P as Place, T as Token, a as PetriNet, b as Transition, E as EnvironmentPlace, c as TransitionContext, O as Out } from './petri-net-C3Jy5HCt.js';
|
|
2
|
+
export { A as Arc, d as ArcInhibitor, e as ArcInput, f as ArcOutput, g as ArcRead, h as ArcReset, I as In, i as InAll, j as InAtLeast, k as InExactly, l as InOne, L as LogFn, M as MAX_DURATION_MS, m as OutAnd, n as OutForwardInput, o as OutPlace, p as OutTimeout, q as OutXor, r as OutputEntry, s as PetriNetBuilder, t as Timing, u as TimingDeadline, v as TimingDelayed, w as TimingExact, x as TimingImmediate, y as TimingWindow, z as TokenInput, B as TokenOutput, C as TransitionAction, D as TransitionBuilder, F as all, G as allPlaces, H as and, J as andPlaces, K as arcPlace, N as atLeast, Q as consumptionCount, R as deadline, S as delayed, U as earliest, V as enumerateBranches, W as environmentPlace, X as exact, Y as exactly, Z as fork, _ as forwardInput, $ as hasDeadline, a0 as hasGuard, a1 as immediate, a2 as inhibitorArc, a3 as inputArc, a4 as isUnit, a5 as latest, a6 as matchesGuard, a7 as one, a8 as outPlace, a9 as outputArc, aa as passthrough, ab as place, ac as produce, ad as readArc, ae as requiredCount, af as resetArc, ag as timeout, ah as timeoutPlace, ai as tokenAt, aj as tokenOf, ak as transform, al as transformAsync, am as transformFrom, an as unitToken, ao as window, ap as withTimeout, aq as xor, ar as xorPlaces } from './petri-net-C3Jy5HCt.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @module marking
|
|
6
|
+
*
|
|
7
|
+
* Mutable token state (marking) of a running Petri net.
|
|
8
|
+
*
|
|
9
|
+
* Tokens per place are stored in FIFO arrays (push to end, shift from front).
|
|
10
|
+
* Not thread-safe — all mutation occurs from the single-threaded orchestrator.
|
|
11
|
+
*
|
|
12
|
+
* For typical nets (≤10 tokens per place), Array.shift() is faster than a deque
|
|
13
|
+
* due to cache locality. Only optimize if profiling shows a bottleneck.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/** Anything that carries a place reference and an optional guard predicate. */
|
|
17
|
+
interface GuardSpec<T = any> {
|
|
18
|
+
readonly place: Place<T>;
|
|
19
|
+
readonly guard?: (value: T) => boolean;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Mutable marking (token state) of a Petri Net during execution.
|
|
23
|
+
*
|
|
24
|
+
* Tokens in each place are maintained in FIFO order (array: push to end, shift from front).
|
|
25
|
+
* Not thread-safe — all access must be from the orchestrator.
|
|
26
|
+
*/
|
|
27
|
+
declare class Marking {
|
|
28
|
+
/** Place name -> FIFO queue of tokens. */
|
|
29
|
+
private readonly tokens;
|
|
30
|
+
/** Place name -> Place reference (for inspection). */
|
|
31
|
+
private readonly placeRefs;
|
|
32
|
+
static empty(): Marking;
|
|
33
|
+
static from(initial: Map<Place<any>, Token<any>[]>): Marking;
|
|
34
|
+
addToken<T>(place: Place<T>, token: Token<T>): void;
|
|
35
|
+
/** Removes and returns the oldest token. Returns null if empty. */
|
|
36
|
+
removeFirst<T>(place: Place<T>): Token<T> | null;
|
|
37
|
+
/** Removes and returns all tokens from a place. */
|
|
38
|
+
removeAll<T>(place: Place<T>): Token<T>[];
|
|
39
|
+
/**
|
|
40
|
+
* Removes and returns the first token whose value satisfies the guard predicate.
|
|
41
|
+
*
|
|
42
|
+
* Performs a linear scan of the place's FIFO queue. If no guard is provided,
|
|
43
|
+
* behaves like `removeFirst()`. If a guard is provided, skips non-matching
|
|
44
|
+
* tokens and splices the first match out of the queue (O(n) worst case).
|
|
45
|
+
*/
|
|
46
|
+
removeFirstMatching(spec: GuardSpec): Token<any> | null;
|
|
47
|
+
/** Check if any token matches a guard predicate. */
|
|
48
|
+
hasMatchingToken(spec: GuardSpec): boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Counts tokens in a place whose values satisfy the guard predicate.
|
|
51
|
+
*
|
|
52
|
+
* If no guard is provided, returns the total token count (O(1)).
|
|
53
|
+
* With a guard, performs a linear scan over all tokens (O(n)).
|
|
54
|
+
* Used by the executor for enablement checks on guarded `all`/`at-least` inputs.
|
|
55
|
+
*/
|
|
56
|
+
countMatching(spec: GuardSpec): number;
|
|
57
|
+
/**
|
|
58
|
+
* Returns tokens in a place. **Returns a live reference** to the internal
|
|
59
|
+
* array — callers must not mutate it. Copy with `[...peekTokens(p)]` if
|
|
60
|
+
* mutation or snapshot semantics are needed.
|
|
61
|
+
*/
|
|
62
|
+
peekTokens<T>(place: Place<T>): readonly Token<T>[];
|
|
63
|
+
/** Returns the oldest token without removing it. */
|
|
64
|
+
peekFirst<T>(place: Place<T>): Token<T> | null;
|
|
65
|
+
/** Checks if a place has any tokens. */
|
|
66
|
+
hasTokens(place: Place<any>): boolean;
|
|
67
|
+
/** Returns the number of tokens in a place. */
|
|
68
|
+
tokenCount(place: Place<any>): number;
|
|
69
|
+
toString(): string;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* @module compiled-net
|
|
74
|
+
*
|
|
75
|
+
* Integer-indexed, precomputed representation of a PetriNet for bitmap-based execution.
|
|
76
|
+
*
|
|
77
|
+
* **Precomputation strategy**: At compile time, all places and transitions are assigned
|
|
78
|
+
* stable integer IDs. Input/inhibitor arcs are converted to Uint32Array bitmasks (one per
|
|
79
|
+
* transition), enabling O(W) enablement checks via bitwise AND where W = ceil(numPlaces/32).
|
|
80
|
+
*
|
|
81
|
+
* **Why bitmaps**: JS bitwise operators work natively on 32-bit integers. Using Uint32Array
|
|
82
|
+
* with 32-bit words (WORD_SHIFT=5) avoids BigInt overhead while keeping enablement checks
|
|
83
|
+
* branch-free and cache-friendly. For a typical 50-place net, W=2 words per mask.
|
|
84
|
+
*
|
|
85
|
+
* **Reverse index**: A place-to-transitions mapping enables the dirty set pattern —
|
|
86
|
+
* when a place's marking changes, only affected transitions are re-evaluated.
|
|
87
|
+
*/
|
|
88
|
+
|
|
89
|
+
interface CardinalityCheck {
|
|
90
|
+
readonly placeIds: readonly number[];
|
|
91
|
+
readonly requiredCounts: readonly number[];
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Integer-indexed, precomputed representation of a PetriNet for bitmap-based execution.
|
|
95
|
+
*
|
|
96
|
+
* Uses Uint32Array masks with 32-bit words (JS bitwise ops work on 32-bit ints natively).
|
|
97
|
+
*/
|
|
98
|
+
declare class CompiledNet {
|
|
99
|
+
readonly net: PetriNet;
|
|
100
|
+
readonly placeCount: number;
|
|
101
|
+
readonly transitionCount: number;
|
|
102
|
+
readonly wordCount: number;
|
|
103
|
+
private readonly _placesById;
|
|
104
|
+
private readonly _transitionsById;
|
|
105
|
+
private readonly _placeIndex;
|
|
106
|
+
private readonly _transitionIndex;
|
|
107
|
+
private readonly _needsMask;
|
|
108
|
+
private readonly _inhibitorMask;
|
|
109
|
+
private readonly _placeToTransitions;
|
|
110
|
+
private readonly _consumptionPlaceIds;
|
|
111
|
+
private readonly _cardinalityChecks;
|
|
112
|
+
private readonly _hasGuards;
|
|
113
|
+
private constructor();
|
|
114
|
+
static compile(net: PetriNet): CompiledNet;
|
|
115
|
+
place(pid: number): Place<any>;
|
|
116
|
+
transition(tid: number): Transition;
|
|
117
|
+
placeId(place: Place<any>): number;
|
|
118
|
+
transitionId(t: Transition): number;
|
|
119
|
+
affectedTransitions(pid: number): readonly number[];
|
|
120
|
+
consumptionPlaceIds(tid: number): readonly number[];
|
|
121
|
+
cardinalityCheck(tid: number): CardinalityCheck | null;
|
|
122
|
+
hasGuards(tid: number): boolean;
|
|
123
|
+
/**
|
|
124
|
+
* Two-phase bitmap enablement check for a transition:
|
|
125
|
+
* 1. **Presence check**: verifies all required places (inputs + reads) have tokens
|
|
126
|
+
* via `containsAll(snapshot, needsMask)`.
|
|
127
|
+
* 2. **Inhibitor check**: verifies no inhibitor places have tokens
|
|
128
|
+
* via `!intersects(snapshot, inhibitorMask)`.
|
|
129
|
+
*
|
|
130
|
+
* This is a necessary but not sufficient condition — cardinality and guard checks
|
|
131
|
+
* are performed separately by the executor for transitions that pass this fast path.
|
|
132
|
+
*/
|
|
133
|
+
canEnableBitmap(tid: number, markingSnapshot: Uint32Array): boolean;
|
|
134
|
+
}
|
|
135
|
+
declare function setBit(arr: Uint32Array, bit: number): void;
|
|
136
|
+
declare function clearBit(arr: Uint32Array, bit: number): void;
|
|
137
|
+
declare function testBit(arr: Uint32Array, bit: number): boolean;
|
|
138
|
+
/** Checks if all bits in mask are set in snapshot. */
|
|
139
|
+
declare function containsAll(snapshot: Uint32Array, mask: Uint32Array): boolean;
|
|
140
|
+
/** Checks if any bit in mask is set in snapshot. */
|
|
141
|
+
declare function intersects(snapshot: Uint32Array, mask: Uint32Array): boolean;
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Events emitted during Petri Net execution.
|
|
145
|
+
* Discriminated union capturing all observable state changes.
|
|
146
|
+
*/
|
|
147
|
+
type NetEvent = ExecutionStarted | ExecutionCompleted | TransitionEnabled | TransitionClockRestarted | TransitionStarted | TransitionCompleted | TransitionFailed | TransitionTimedOut | ActionTimedOut | TokenAdded | TokenRemoved | LogMessage | MarkingSnapshot;
|
|
148
|
+
interface ExecutionStarted {
|
|
149
|
+
readonly type: 'execution-started';
|
|
150
|
+
readonly timestamp: number;
|
|
151
|
+
readonly netName: string;
|
|
152
|
+
readonly executionId: string;
|
|
153
|
+
}
|
|
154
|
+
interface ExecutionCompleted {
|
|
155
|
+
readonly type: 'execution-completed';
|
|
156
|
+
readonly timestamp: number;
|
|
157
|
+
readonly netName: string;
|
|
158
|
+
readonly executionId: string;
|
|
159
|
+
readonly totalDurationMs: number;
|
|
160
|
+
}
|
|
161
|
+
interface TransitionEnabled {
|
|
162
|
+
readonly type: 'transition-enabled';
|
|
163
|
+
readonly timestamp: number;
|
|
164
|
+
readonly transitionName: string;
|
|
165
|
+
}
|
|
166
|
+
interface TransitionClockRestarted {
|
|
167
|
+
readonly type: 'transition-clock-restarted';
|
|
168
|
+
readonly timestamp: number;
|
|
169
|
+
readonly transitionName: string;
|
|
170
|
+
}
|
|
171
|
+
interface TransitionStarted {
|
|
172
|
+
readonly type: 'transition-started';
|
|
173
|
+
readonly timestamp: number;
|
|
174
|
+
readonly transitionName: string;
|
|
175
|
+
readonly consumedTokens: readonly Token<unknown>[];
|
|
176
|
+
}
|
|
177
|
+
interface TransitionCompleted {
|
|
178
|
+
readonly type: 'transition-completed';
|
|
179
|
+
readonly timestamp: number;
|
|
180
|
+
readonly transitionName: string;
|
|
181
|
+
readonly producedTokens: readonly Token<unknown>[];
|
|
182
|
+
readonly durationMs: number;
|
|
183
|
+
}
|
|
184
|
+
interface TransitionFailed {
|
|
185
|
+
readonly type: 'transition-failed';
|
|
186
|
+
readonly timestamp: number;
|
|
187
|
+
readonly transitionName: string;
|
|
188
|
+
readonly errorMessage: string;
|
|
189
|
+
readonly exceptionType: string;
|
|
190
|
+
/** Original stack trace, if available. */
|
|
191
|
+
readonly stack?: string;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Emitted when a transition exceeds its deadline (upper time bound) without firing.
|
|
195
|
+
* Classical TPN semantics: transition is forcibly disabled by the executor in
|
|
196
|
+
* `updateDirtyTransitions()` when elapsed time exceeds `latest(timing)`.
|
|
197
|
+
*/
|
|
198
|
+
interface TransitionTimedOut {
|
|
199
|
+
readonly type: 'transition-timed-out';
|
|
200
|
+
readonly timestamp: number;
|
|
201
|
+
readonly transitionName: string;
|
|
202
|
+
/** The deadline that was exceeded, in milliseconds from enablement. */
|
|
203
|
+
readonly deadlineMs: number;
|
|
204
|
+
/** Actual time elapsed since enablement, in milliseconds. */
|
|
205
|
+
readonly actualDurationMs: number;
|
|
206
|
+
}
|
|
207
|
+
interface ActionTimedOut {
|
|
208
|
+
readonly type: 'action-timed-out';
|
|
209
|
+
readonly timestamp: number;
|
|
210
|
+
readonly transitionName: string;
|
|
211
|
+
readonly timeoutMs: number;
|
|
212
|
+
}
|
|
213
|
+
interface TokenAdded {
|
|
214
|
+
readonly type: 'token-added';
|
|
215
|
+
readonly timestamp: number;
|
|
216
|
+
readonly placeName: string;
|
|
217
|
+
readonly token: Token<unknown>;
|
|
218
|
+
}
|
|
219
|
+
interface TokenRemoved {
|
|
220
|
+
readonly type: 'token-removed';
|
|
221
|
+
readonly timestamp: number;
|
|
222
|
+
readonly placeName: string;
|
|
223
|
+
readonly token: Token<unknown>;
|
|
224
|
+
}
|
|
225
|
+
interface LogMessage {
|
|
226
|
+
readonly type: 'log-message';
|
|
227
|
+
readonly timestamp: number;
|
|
228
|
+
readonly transitionName: string;
|
|
229
|
+
readonly logger: string;
|
|
230
|
+
readonly level: string;
|
|
231
|
+
readonly message: string;
|
|
232
|
+
readonly error: string | null;
|
|
233
|
+
readonly errorMessage: string | null;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Snapshot of the full marking (token state) at a point in time.
|
|
237
|
+
* Emitted at two points during execution:
|
|
238
|
+
* 1. After initialization (before the main loop) — captures the initial marking
|
|
239
|
+
* 2. Before the execution-completed event — captures the final marking
|
|
240
|
+
*/
|
|
241
|
+
interface MarkingSnapshot {
|
|
242
|
+
readonly type: 'marking-snapshot';
|
|
243
|
+
readonly timestamp: number;
|
|
244
|
+
/** Place name -> tokens in that place at snapshot time. Only non-empty places are included. */
|
|
245
|
+
readonly marking: ReadonlyMap<string, readonly Token<unknown>[]>;
|
|
246
|
+
}
|
|
247
|
+
/** Extracts transition name from events that have one. Returns null otherwise. */
|
|
248
|
+
declare function eventTransitionName(event: NetEvent): string | null;
|
|
249
|
+
/** Checks if the event is a failure type. */
|
|
250
|
+
declare function isFailureEvent(event: NetEvent): boolean;
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Storage for events emitted during Petri net execution.
|
|
254
|
+
*/
|
|
255
|
+
interface EventStore {
|
|
256
|
+
/** Appends an event to the store. */
|
|
257
|
+
append(event: NetEvent): void;
|
|
258
|
+
/** Returns all events in chronological order. */
|
|
259
|
+
events(): readonly NetEvent[];
|
|
260
|
+
/** Whether this store is enabled (false = skip event creation). */
|
|
261
|
+
isEnabled(): boolean;
|
|
262
|
+
/** Number of events captured. */
|
|
263
|
+
size(): number;
|
|
264
|
+
/** Whether no events have been captured. */
|
|
265
|
+
isEmpty(): boolean;
|
|
266
|
+
}
|
|
267
|
+
/** Returns events matching a predicate. */
|
|
268
|
+
declare function filterEvents(store: EventStore, predicate: (e: NetEvent) => boolean): NetEvent[];
|
|
269
|
+
/** Returns events of a specific type. */
|
|
270
|
+
declare function eventsOfType<T extends NetEvent['type']>(store: EventStore, type: T): Extract<NetEvent, {
|
|
271
|
+
type: T;
|
|
272
|
+
}>[];
|
|
273
|
+
/** Returns all events for a specific transition. */
|
|
274
|
+
declare function transitionEvents(store: EventStore, transitionName: string): NetEvent[];
|
|
275
|
+
/** Returns all failure events. */
|
|
276
|
+
declare function failures(store: EventStore): NetEvent[];
|
|
277
|
+
declare class InMemoryEventStore implements EventStore {
|
|
278
|
+
private readonly _events;
|
|
279
|
+
append(event: NetEvent): void;
|
|
280
|
+
events(): readonly NetEvent[];
|
|
281
|
+
isEnabled(): boolean;
|
|
282
|
+
size(): number;
|
|
283
|
+
isEmpty(): boolean;
|
|
284
|
+
/** Clears all stored events. */
|
|
285
|
+
clear(): void;
|
|
286
|
+
}
|
|
287
|
+
/** Returns a no-op event store that discards all events. */
|
|
288
|
+
declare function noopEventStore(): EventStore;
|
|
289
|
+
/** Creates a new in-memory event store. */
|
|
290
|
+
declare function inMemoryEventStore(): InMemoryEventStore;
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Interface for Petri net executors.
|
|
294
|
+
*/
|
|
295
|
+
interface PetriNetExecutor {
|
|
296
|
+
/** Run the net until quiescence or timeout. */
|
|
297
|
+
run(timeoutMs?: number): Promise<Marking>;
|
|
298
|
+
/** Inject an external token. Returns true if accepted. */
|
|
299
|
+
inject<T>(place: EnvironmentPlace<T>, token: Token<T>): Promise<boolean>;
|
|
300
|
+
/** Shut down the executor. */
|
|
301
|
+
close(): void;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* @module bitmap-net-executor
|
|
306
|
+
*
|
|
307
|
+
* Async bitmap-based executor for Typed Coloured Time Petri Nets.
|
|
308
|
+
*
|
|
309
|
+
* **Execution loop phases** (per cycle):
|
|
310
|
+
* 1. Process completed transitions — collect outputs, validate against Out specs
|
|
311
|
+
* 2. Process external events — inject tokens from EnvironmentPlaces
|
|
312
|
+
* 3. Update dirty transitions — re-evaluate enablement for transitions whose
|
|
313
|
+
* input/inhibitor/read places changed (bitmap-based dirty set tracking)
|
|
314
|
+
* 4. Fire ready transitions — sorted by priority (desc) then FIFO enablement time
|
|
315
|
+
* 5. Await work — sleep until an action completes, a timer fires, or an external event arrives
|
|
316
|
+
*
|
|
317
|
+
* **Concurrency model**: Single-threaded JS event loop. No locks or CAS needed.
|
|
318
|
+
* Multiple transitions execute concurrently via Promises (actions return Promise<void>).
|
|
319
|
+
* Only the orchestrator mutates marking state — actions communicate via TokenOutput.
|
|
320
|
+
*
|
|
321
|
+
* **Bitmap strategy**: Places are tracked as bits in Uint32Array words. Enablement
|
|
322
|
+
* checks use bitwise AND/OR for O(W) where W = ceil(numPlaces/32). A dirty set
|
|
323
|
+
* bitmap tracks which transitions need re-evaluation, avoiding O(T) scans per cycle.
|
|
324
|
+
*
|
|
325
|
+
* @see CompiledNet for the precomputed bitmap masks and reverse indices
|
|
326
|
+
*/
|
|
327
|
+
|
|
328
|
+
interface BitmapNetExecutorOptions {
|
|
329
|
+
eventStore?: EventStore;
|
|
330
|
+
environmentPlaces?: Set<EnvironmentPlace<any>>;
|
|
331
|
+
longRunning?: boolean;
|
|
332
|
+
/** Provides execution context data for each transition firing. */
|
|
333
|
+
executionContextProvider?: (transitionName: string, consumed: Token<any>[]) => Map<string, unknown>;
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Async bitmap-based executor for Coloured Time Petri Nets.
|
|
337
|
+
*
|
|
338
|
+
* Single-threaded JS model: no CAS needed, direct array writes.
|
|
339
|
+
* Actions return Promise<void> — multiple in-flight actions are naturally concurrent.
|
|
340
|
+
*
|
|
341
|
+
* @remarks
|
|
342
|
+
* **Deadline enforcement**: Transitions with finite deadlines (`deadline`, `window`, `exact`)
|
|
343
|
+
* are checked in `enforceDeadlines()`, called from the main loop only when `hasAnyDeadlines`
|
|
344
|
+
* is true (precomputed at construction). If a transition has been enabled longer than
|
|
345
|
+
* `latest(timing)`, it is forcibly disabled and a `TransitionTimedOut` event is emitted.
|
|
346
|
+
* The `awaitWork()` timer also schedules wake-ups for approaching deadlines, not just
|
|
347
|
+
* earliest firing times.
|
|
348
|
+
*
|
|
349
|
+
* **Constructor precomputation**: `hasAnyDeadlines`, `allImmediate`/`allSamePriority`,
|
|
350
|
+
* and `eventStoreEnabled` are computed once to avoid per-cycle overhead. Safe because
|
|
351
|
+
* `isEnabled()` is constant and timing/priority are immutable on Transition.
|
|
352
|
+
*/
|
|
353
|
+
declare class BitmapNetExecutor implements PetriNetExecutor {
|
|
354
|
+
private readonly compiled;
|
|
355
|
+
private readonly marking;
|
|
356
|
+
private readonly eventStore;
|
|
357
|
+
private readonly environmentPlaces;
|
|
358
|
+
private readonly longRunning;
|
|
359
|
+
private readonly executionContextProvider?;
|
|
360
|
+
private readonly startMs;
|
|
361
|
+
private readonly hasAnyDeadlines;
|
|
362
|
+
private readonly allImmediate;
|
|
363
|
+
private readonly allSamePriority;
|
|
364
|
+
private readonly eventStoreEnabled;
|
|
365
|
+
private readonly markedPlaces;
|
|
366
|
+
private readonly dirtySet;
|
|
367
|
+
private readonly markingSnapBuffer;
|
|
368
|
+
private readonly dirtySnapBuffer;
|
|
369
|
+
private readonly firingSnapBuffer;
|
|
370
|
+
private readonly enabledAtMs;
|
|
371
|
+
private readonly inFlightFlags;
|
|
372
|
+
private readonly enabledFlags;
|
|
373
|
+
/** Precomputed: 1 if transition has a finite deadline, 0 otherwise. */
|
|
374
|
+
private readonly hasDeadlineFlags;
|
|
375
|
+
private enabledTransitionCount;
|
|
376
|
+
private readonly inFlight;
|
|
377
|
+
private readonly inFlightPromises;
|
|
378
|
+
private readonly awaitPromises;
|
|
379
|
+
private readonly completionQueue;
|
|
380
|
+
private readonly externalQueue;
|
|
381
|
+
private wakeUpResolve;
|
|
382
|
+
private readonly readyBuffer;
|
|
383
|
+
private readonly pendingResetPlaces;
|
|
384
|
+
private readonly transitionInputPlaceNames;
|
|
385
|
+
private running;
|
|
386
|
+
private closed;
|
|
387
|
+
constructor(net: PetriNet, initialTokens: Map<Place<any>, Token<any>[]>, options?: BitmapNetExecutorOptions);
|
|
388
|
+
run(timeoutMs?: number): Promise<Marking>;
|
|
389
|
+
private executeLoop;
|
|
390
|
+
inject<T>(envPlace: EnvironmentPlace<T>, token: Token<T>): Promise<boolean>;
|
|
391
|
+
/** Convenience: inject a raw value (creates token with current timestamp). */
|
|
392
|
+
injectValue<T>(envPlace: EnvironmentPlace<T>, value: T): Promise<boolean>;
|
|
393
|
+
private initializeMarkedBitmap;
|
|
394
|
+
private markAllDirty;
|
|
395
|
+
private shouldTerminate;
|
|
396
|
+
private updateDirtyTransitions;
|
|
397
|
+
/**
|
|
398
|
+
* Checks all enabled transitions with finite deadlines. If a transition has been
|
|
399
|
+
* enabled longer than `latest(timing)`, it is forcibly disabled and a
|
|
400
|
+
* `TransitionTimedOut` event is emitted. Classical TPN semantics require transitions
|
|
401
|
+
* to either fire within their window or become disabled.
|
|
402
|
+
*
|
|
403
|
+
* A 1ms tolerance is applied to account for timer jitter and microtask scheduling
|
|
404
|
+
* delays. Without this, exact-timed transitions (where earliest == latest) would
|
|
405
|
+
* almost always be disabled before they can fire.
|
|
406
|
+
*/
|
|
407
|
+
private enforceDeadlines;
|
|
408
|
+
private canEnable;
|
|
409
|
+
private hasInputFromResetPlace;
|
|
410
|
+
private fireReadyTransitions;
|
|
411
|
+
/**
|
|
412
|
+
* Fast path for nets where all transitions are immediate and same priority.
|
|
413
|
+
* Skips timing checks, sorting, and snapshot buffer — just scan and fire.
|
|
414
|
+
*
|
|
415
|
+
* Uses live `markedPlaces` instead of a snapshot. Safe because
|
|
416
|
+
* `updateBitmapAfterConsumption()` synchronously updates the bitmap before the next
|
|
417
|
+
* iteration. For equal-priority immediate transitions, tid scan order satisfies
|
|
418
|
+
* FIFO-by-enablement-time (all enabled in the same cycle).
|
|
419
|
+
*/
|
|
420
|
+
private fireReadyImmediate;
|
|
421
|
+
private fireReadyGeneral;
|
|
422
|
+
private fireTransition;
|
|
423
|
+
private updateBitmapAfterConsumption;
|
|
424
|
+
private processCompletedTransitions;
|
|
425
|
+
private processExternalEvents;
|
|
426
|
+
private drainPendingExternalEvents;
|
|
427
|
+
/**
|
|
428
|
+
* Suspends the executor until work is available. Composes up to 3 promise sources
|
|
429
|
+
* into a single Promise.race: (1) any in-flight action completing, (2) external
|
|
430
|
+
* event injection via wakeUp(), (3) timer for the next delayed transition's earliest
|
|
431
|
+
* firing time. This avoids busy-waiting while remaining responsive to all event types.
|
|
432
|
+
*
|
|
433
|
+
* **Microtask flush**: Before building Promise.race, yields via `await Promise.resolve()`
|
|
434
|
+
* to drain the microtask queue. Sync actions complete via `.then()` microtask; this
|
|
435
|
+
* yield lets those fire, avoiding ~5 allocations when work is already available.
|
|
436
|
+
* After the yield, re-checks queues and `this.closed` for close-during-yield safety.
|
|
437
|
+
*/
|
|
438
|
+
private awaitWork;
|
|
439
|
+
private millisUntilNextTimedTransition;
|
|
440
|
+
private wakeUp;
|
|
441
|
+
/** Returns true if any transition needs re-evaluation. O(W) where W = ceil(transitions/32). */
|
|
442
|
+
private hasDirtyBits;
|
|
443
|
+
private markDirty;
|
|
444
|
+
private markTransitionDirty;
|
|
445
|
+
getMarking(): Marking;
|
|
446
|
+
/** Builds a snapshot of the current marking for event emission. */
|
|
447
|
+
private snapshotMarking;
|
|
448
|
+
isQuiescent(): boolean;
|
|
449
|
+
executionId(): string;
|
|
450
|
+
close(): void;
|
|
451
|
+
private emitEvent;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* Error thrown when a transition's output doesn't satisfy its declared Out spec.
|
|
456
|
+
*/
|
|
457
|
+
declare class OutViolationError extends Error {
|
|
458
|
+
constructor(message: string);
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/**
|
|
462
|
+
* @module executor-support
|
|
463
|
+
*
|
|
464
|
+
* Output validation and timeout production for the Petri net executor.
|
|
465
|
+
*
|
|
466
|
+
* **Output validation algorithm**: Recursively walks the declared Out spec tree,
|
|
467
|
+
* checking that the action's produced tokens match the structure:
|
|
468
|
+
* - Place/ForwardInput: place must be in the produced set
|
|
469
|
+
* - AND: all children must be satisfied (conjunction)
|
|
470
|
+
* - XOR: exactly 1 child must be satisfied (throws OutViolationError for 0 or 2+)
|
|
471
|
+
* - Timeout: delegates to child spec
|
|
472
|
+
*
|
|
473
|
+
* Returns the set of "claimed" place names on success, or null if unsatisfied.
|
|
474
|
+
*
|
|
475
|
+
* **Timeout production**: When an action exceeds its timeout, produces default
|
|
476
|
+
* tokens to the timeout branch's output places, enabling the net to continue.
|
|
477
|
+
*/
|
|
478
|
+
|
|
479
|
+
/**
|
|
480
|
+
* Recursively validates that a transition's output satisfies its declared Out spec.
|
|
481
|
+
*
|
|
482
|
+
* @returns the set of claimed place names, or null if not satisfied
|
|
483
|
+
* @throws OutViolationError if a structural violation is detected (e.g. XOR with 0 or 2+ branches)
|
|
484
|
+
*/
|
|
485
|
+
declare function validateOutSpec(tName: string, spec: Out, producedPlaceNames: Set<string>): Set<string> | null;
|
|
486
|
+
/**
|
|
487
|
+
* Produces default tokens to the timeout branch's output places when an action
|
|
488
|
+
* exceeds its timeout. Walks the Out spec tree recursively:
|
|
489
|
+
*
|
|
490
|
+
* - **Place**: produces `null` (the timeout sentinel value).
|
|
491
|
+
* - **ForwardInput**: forwards the consumed input token to the output place.
|
|
492
|
+
* - **AND**: recurses into all children (all branches get tokens).
|
|
493
|
+
* - **XOR**: disallowed — timeout cannot choose a branch non-deterministically.
|
|
494
|
+
* - **Timeout**: disallowed — nested timeouts would create ambiguous recovery paths.
|
|
495
|
+
*/
|
|
496
|
+
declare function produceTimeoutOutput(context: TransitionContext, timeoutChild: Out): void;
|
|
497
|
+
|
|
498
|
+
export { type ActionTimedOut, BitmapNetExecutor, type BitmapNetExecutorOptions, type CardinalityCheck, CompiledNet, EnvironmentPlace, type EventStore, type ExecutionCompleted, type ExecutionStarted, type GuardSpec, InMemoryEventStore, type LogMessage, Marking, type MarkingSnapshot, type NetEvent, Out, OutViolationError, PetriNet, type PetriNetExecutor, Place, Token, type TokenAdded, type TokenRemoved, Transition, type TransitionClockRestarted, type TransitionCompleted, TransitionContext, type TransitionEnabled, type TransitionFailed, type TransitionStarted, type TransitionTimedOut, clearBit, containsAll, eventTransitionName, eventsOfType, failures, filterEvents, inMemoryEventStore, intersects, isFailureEvent, noopEventStore, produceTimeoutOutput, setBit, testBit, transitionEvents, validateOutSpec };
|