libpetri 2.5.0 → 2.6.0
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/dist/{chunk-FN773SSE.js → chunk-ATT7U5H5.js} +1 -1
- package/dist/chunk-ATT7U5H5.js.map +1 -0
- package/dist/{chunk-H62Z76FY.js → chunk-ETNHEAS6.js} +130 -18
- package/dist/chunk-ETNHEAS6.js.map +1 -0
- package/dist/{chunk-2GAZLDH3.js → chunk-ULX3OG6H.js} +2 -2
- package/dist/debug/index.d.ts +2 -2
- package/dist/debug/index.js +2 -2
- package/dist/doclet/index.d.ts +1 -1
- package/dist/doclet/index.js +3 -3
- package/dist/dot-exporter-TYC6FUAD.js +8 -0
- package/dist/{event-store-z30VMn0T.d.ts → event-store-E_ahsEc9.d.ts} +1 -1
- package/dist/export/index.d.ts +1 -1
- package/dist/export/index.js +2 -2
- package/dist/index.d.ts +29 -4
- package/dist/index.js +30 -6
- package/dist/index.js.map +1 -1
- package/dist/{petri-net-DXdpd0r5.d.ts → petri-net-C3asscb4.d.ts} +8 -1
- package/dist/verification/index.d.ts +39 -34
- package/dist/verification/index.js +7 -17
- package/dist/verification/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-FN773SSE.js.map +0 -1
- package/dist/chunk-H62Z76FY.js.map +0 -1
- package/dist/dot-exporter-7YDFCBKC.js +0 -8
- /package/dist/{chunk-2GAZLDH3.js.map → chunk-ULX3OG6H.js.map} +0 -0
- /package/dist/{dot-exporter-7YDFCBKC.js.map → dot-exporter-TYC6FUAD.js.map} +0 -0
|
@@ -274,7 +274,14 @@ declare function deadline(byMs: number): TimingDeadline;
|
|
|
274
274
|
declare function delayed(afterMs: number): TimingDelayed;
|
|
275
275
|
/** Time window: can fire within [earliest, latest]. */
|
|
276
276
|
declare function window(earliestMs: number, latestMs: number): TimingWindow;
|
|
277
|
-
/**
|
|
277
|
+
/**
|
|
278
|
+
* Exact timing: targets the specified time (interval `[at, at]`).
|
|
279
|
+
*
|
|
280
|
+
* The zero-width interval is precise for verification/simulation. Under wall-clock execution it
|
|
281
|
+
* is enforced *softly* — the transition fires at the first opportunity at or after `atMs` (like
|
|
282
|
+
* {@link delayed}) and is never force-disabled for being observed late (TIME-006). Prefer
|
|
283
|
+
* {@link delayed} for a plain lower bound, or {@link window} for a hard bounded window.
|
|
284
|
+
*/
|
|
278
285
|
declare function exact(atMs: number): TimingExact;
|
|
279
286
|
/** Returns the earliest time (ms) the transition can fire after enabling. */
|
|
280
287
|
declare function earliest(timing: Timing): number;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { b as Transition, a as Place, P as PetriNet, E as EnvironmentPlace, aG as MarkingState, aH as PInvariant, aI as MarkingStateBuilder, aJ as SmtProperty, aK as SmtVerificationResult } from '../petri-net-
|
|
2
|
-
export { aL as DeadlockFree, aM as MutualExclusion, aN as PlaceBound, aO as Proven, aP as SmtStatistics, aQ as TokenSupplier, aR as Unknown, aS as Unreachable, aT as Verdict, X as VerificationHarness, Y as VerificationResult, aU as Violated, aV as deadlockFree, aW as isProven, aX as isViolated, aY as mutualExclusion, aZ as pInvariant, a_ as pInvariantToString, a$ as placeBound, b0 as propertyDescription, b1 as unreachable } from '../petri-net-
|
|
1
|
+
import { b as Transition, a as Place, P as PetriNet, E as EnvironmentPlace, aG as MarkingState, aH as PInvariant, aI as MarkingStateBuilder, aJ as SmtProperty, aK as SmtVerificationResult } from '../petri-net-C3asscb4.js';
|
|
2
|
+
export { aL as DeadlockFree, aM as MutualExclusion, aN as PlaceBound, aO as Proven, aP as SmtStatistics, aQ as TokenSupplier, aR as Unknown, aS as Unreachable, aT as Verdict, X as VerificationHarness, Y as VerificationResult, aU as Violated, aV as deadlockFree, aW as isProven, aX as isViolated, aY as mutualExclusion, aZ as pInvariant, a_ as pInvariantToString, a$ as placeBound, b0 as propertyDescription, b1 as unreachable } from '../petri-net-C3asscb4.js';
|
|
3
3
|
import { Expr, init, Bool, FuncDecl } from 'z3-solver';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -44,6 +44,15 @@ interface FlatNet {
|
|
|
44
44
|
readonly transitions: readonly FlatTransition[];
|
|
45
45
|
/** For bounded environment places: place name -> max tokens. */
|
|
46
46
|
readonly environmentBounds: ReadonlyMap<string, number>;
|
|
47
|
+
/**
|
|
48
|
+
* Environment places whose tokens the analysis MODELS as externally injected
|
|
49
|
+
* (VER-006). Maps env place name -> injection bound: a number caps injection
|
|
50
|
+
* (`Bounded(k)`), `null` means unbounded (`AlwaysAvailable`). Absent entries
|
|
51
|
+
* (incl. `Ignore` mode) are not injected. The encoder emits one injection CHC
|
|
52
|
+
* rule per entry and the incidence matrix gains one injector column per entry
|
|
53
|
+
* so closed-net P-invariants over these places are correctly discarded.
|
|
54
|
+
*/
|
|
55
|
+
readonly environmentInjection: ReadonlyMap<string, number | null>;
|
|
47
56
|
}
|
|
48
57
|
declare function flatNetPlaceCount(net: FlatNet): number;
|
|
49
58
|
declare function flatNetTransitionCount(net: FlatNet): number;
|
|
@@ -67,6 +76,13 @@ declare class IncidenceMatrix {
|
|
|
67
76
|
private constructor();
|
|
68
77
|
/**
|
|
69
78
|
* Computes the incidence matrix from a FlatNet.
|
|
79
|
+
*
|
|
80
|
+
* Environment-injected places (VER-006) each contribute one extra **injector
|
|
81
|
+
* column** (a virtual transition that produces one token into that place and
|
|
82
|
+
* consumes nothing). This makes P-invariant computation env-aware: a valid
|
|
83
|
+
* invariant `y` must satisfy `y^T·C = 0` for the injector column too, forcing
|
|
84
|
+
* `y[envPlace] = 0` and thereby discarding closed-net conservation laws (e.g.
|
|
85
|
+
* `IN + OUT = const`) that would otherwise vacuously bound an injectable place.
|
|
70
86
|
*/
|
|
71
87
|
static from(flatNet: FlatNet): IncidenceMatrix;
|
|
72
88
|
/**
|
|
@@ -84,6 +100,24 @@ declare class IncidenceMatrix {
|
|
|
84
100
|
numPlaces(): number;
|
|
85
101
|
}
|
|
86
102
|
|
|
103
|
+
/**
|
|
104
|
+
* Analysis mode for environment places in state class graph construction.
|
|
105
|
+
*/
|
|
106
|
+
type EnvironmentAnalysisMode = {
|
|
107
|
+
readonly type: 'always-available';
|
|
108
|
+
} | {
|
|
109
|
+
readonly type: 'bounded';
|
|
110
|
+
readonly maxTokens: number;
|
|
111
|
+
} | {
|
|
112
|
+
readonly type: 'ignore';
|
|
113
|
+
};
|
|
114
|
+
/** Assumes environment places always have sufficient tokens. */
|
|
115
|
+
declare function alwaysAvailable(): EnvironmentAnalysisMode;
|
|
116
|
+
/** Analyzes with a bounded number of tokens in environment places. */
|
|
117
|
+
declare function bounded(maxTokens: number): EnvironmentAnalysisMode;
|
|
118
|
+
/** Treats environment places as regular places (default). */
|
|
119
|
+
declare function ignore(): EnvironmentAnalysisMode;
|
|
120
|
+
|
|
87
121
|
/**
|
|
88
122
|
* @module net-flattener
|
|
89
123
|
*
|
|
@@ -103,17 +137,6 @@ declare class IncidenceMatrix {
|
|
|
103
137
|
* Places are sorted by name for stable, deterministic indexing across runs.
|
|
104
138
|
*/
|
|
105
139
|
|
|
106
|
-
/**
|
|
107
|
-
* How to treat environment places during analysis.
|
|
108
|
-
*/
|
|
109
|
-
type EnvironmentAnalysisMode$1 = {
|
|
110
|
-
readonly type: 'unbounded';
|
|
111
|
-
} | {
|
|
112
|
-
readonly type: 'bounded';
|
|
113
|
-
readonly maxTokens: number;
|
|
114
|
-
};
|
|
115
|
-
declare function unbounded(): EnvironmentAnalysisMode$1;
|
|
116
|
-
declare function bounded$1(maxTokens: number): EnvironmentAnalysisMode$1;
|
|
117
140
|
/**
|
|
118
141
|
* Flattens a PetriNet into a FlatNet suitable for SMT encoding.
|
|
119
142
|
*
|
|
@@ -124,7 +147,7 @@ declare function bounded$1(maxTokens: number): EnvironmentAnalysisMode$1;
|
|
|
124
147
|
* 4. Recording inhibitor, read, and reset arcs
|
|
125
148
|
* 5. Setting environment bounds for bounded analysis mode
|
|
126
149
|
*/
|
|
127
|
-
declare function flatten(net: PetriNet, environmentPlaces?: Set<EnvironmentPlace<any>>, environmentMode?: EnvironmentAnalysisMode
|
|
150
|
+
declare function flatten(net: PetriNet, environmentPlaces?: Set<EnvironmentPlace<any>>, environmentMode?: EnvironmentAnalysisMode): FlatNet;
|
|
128
151
|
|
|
129
152
|
/**
|
|
130
153
|
* @module p-invariant-computer
|
|
@@ -260,7 +283,7 @@ declare class SmtVerifier {
|
|
|
260
283
|
initialMarking(configurator: (builder: MarkingStateBuilder) => void): this;
|
|
261
284
|
property(property: SmtProperty): this;
|
|
262
285
|
environmentPlaces(...places: EnvironmentPlace<any>[]): this;
|
|
263
|
-
environmentMode(mode: EnvironmentAnalysisMode
|
|
286
|
+
environmentMode(mode: EnvironmentAnalysisMode): this;
|
|
264
287
|
/**
|
|
265
288
|
* Declares expected sink (terminal) places for deadlock-freedom analysis.
|
|
266
289
|
* Markings where any sink place has a token are not considered deadlocks.
|
|
@@ -436,24 +459,6 @@ declare function computeSCCs<T>(nodes: Iterable<T>, successors: (node: T) => Ite
|
|
|
436
459
|
/** Finds terminal (bottom) SCCs — SCCs with no outgoing edges to other SCCs. */
|
|
437
460
|
declare function findTerminalSCCs<T>(nodes: Iterable<T>, successors: (node: T) => Iterable<T>): Set<T>[];
|
|
438
461
|
|
|
439
|
-
/**
|
|
440
|
-
* Analysis mode for environment places in state class graph construction.
|
|
441
|
-
*/
|
|
442
|
-
type EnvironmentAnalysisMode = {
|
|
443
|
-
readonly type: 'always-available';
|
|
444
|
-
} | {
|
|
445
|
-
readonly type: 'bounded';
|
|
446
|
-
readonly maxTokens: number;
|
|
447
|
-
} | {
|
|
448
|
-
readonly type: 'ignore';
|
|
449
|
-
};
|
|
450
|
-
/** Assumes environment places always have sufficient tokens. */
|
|
451
|
-
declare function alwaysAvailable(): EnvironmentAnalysisMode;
|
|
452
|
-
/** Analyzes with a bounded number of tokens in environment places. */
|
|
453
|
-
declare function bounded(maxTokens: number): EnvironmentAnalysisMode;
|
|
454
|
-
/** Treats environment places as regular places (default). */
|
|
455
|
-
declare function ignore(): EnvironmentAnalysisMode;
|
|
456
|
-
|
|
457
462
|
/** Edge that tracks which XOR branch was taken. */
|
|
458
463
|
interface BranchEdge {
|
|
459
464
|
readonly branchIndex: number;
|
|
@@ -561,4 +566,4 @@ declare class TimePetriNetAnalyzerBuilder {
|
|
|
561
566
|
build(): TimePetriNetAnalyzer;
|
|
562
567
|
}
|
|
563
568
|
|
|
564
|
-
export { type EnvironmentAnalysisMode as AnalysisEnvironmentMode, type BranchEdge, DBM, type DecodedTrace, type EncodingResult, type EnvironmentAnalysisMode
|
|
569
|
+
export { type EnvironmentAnalysisMode as AnalysisEnvironmentMode, type BranchEdge, DBM, type DecodedTrace, type EncodingResult, type EnvironmentAnalysisMode, type FlatNet, type FlatTransition, IncidenceMatrix, type LivenessResult, MarkingState, MarkingStateBuilder, PInvariant, type QueryProven, type QueryResult, type QueryUnknown, type QueryViolated, SmtProperty, SmtVerificationResult, SmtVerifier, type SpacerContext, StateClass, StateClassGraph, type StructuralCheckResult, TimePetriNetAnalyzer, TimePetriNetAnalyzerBuilder, type XorBranchAnalysis, type XorBranchInfo, alwaysAvailable, alwaysAvailable as analysisAlwaysAvailable, bounded as analysisBounded, ignore as analysisIgnore, bounded, computePInvariants, computeSCCs, createSpacerRunner, decode, encode, findMaximalTrapIn, findMinimalSiphons, findTerminalSCCs, flatNetIndexOf, flatNetPlaceCount, flatNetTransitionCount, flatTransition, flatten, ignore, isCoveredByInvariants, structuralCheck };
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
MarkingState,
|
|
4
4
|
MarkingStateBuilder,
|
|
5
5
|
SmtVerifier,
|
|
6
|
+
alwaysAvailable,
|
|
6
7
|
bounded,
|
|
7
8
|
computePInvariants,
|
|
8
9
|
createSpacerRunner,
|
|
@@ -17,6 +18,7 @@ import {
|
|
|
17
18
|
flatNetTransitionCount,
|
|
18
19
|
flatTransition,
|
|
19
20
|
flatten,
|
|
21
|
+
ignore,
|
|
20
22
|
isCoveredByInvariants,
|
|
21
23
|
isProven,
|
|
22
24
|
isViolated,
|
|
@@ -26,13 +28,12 @@ import {
|
|
|
26
28
|
placeBound,
|
|
27
29
|
propertyDescription,
|
|
28
30
|
structuralCheck,
|
|
29
|
-
unbounded,
|
|
30
31
|
unreachable
|
|
31
|
-
} from "../chunk-
|
|
32
|
+
} from "../chunk-ETNHEAS6.js";
|
|
32
33
|
import {
|
|
33
34
|
earliest,
|
|
34
35
|
latest
|
|
35
|
-
} from "../chunk-
|
|
36
|
+
} from "../chunk-ATT7U5H5.js";
|
|
36
37
|
|
|
37
38
|
// src/verification/analysis/dbm.ts
|
|
38
39
|
var EPSILON = 1e-9;
|
|
@@ -307,18 +308,6 @@ function findTerminalSCCs(nodes, successors) {
|
|
|
307
308
|
return terminal;
|
|
308
309
|
}
|
|
309
310
|
|
|
310
|
-
// src/verification/analysis/environment-analysis-mode.ts
|
|
311
|
-
function alwaysAvailable() {
|
|
312
|
-
return { type: "always-available" };
|
|
313
|
-
}
|
|
314
|
-
function bounded2(maxTokens) {
|
|
315
|
-
if (maxTokens < 0) throw new Error("maxTokens must be non-negative");
|
|
316
|
-
return { type: "bounded", maxTokens };
|
|
317
|
-
}
|
|
318
|
-
function ignore() {
|
|
319
|
-
return { type: "ignore" };
|
|
320
|
-
}
|
|
321
|
-
|
|
322
311
|
// src/verification/analysis/state-class-graph.ts
|
|
323
312
|
var StateClassGraph = class _StateClassGraph {
|
|
324
313
|
net;
|
|
@@ -906,8 +895,9 @@ export {
|
|
|
906
895
|
StateClassGraph,
|
|
907
896
|
TimePetriNetAnalyzer,
|
|
908
897
|
TimePetriNetAnalyzerBuilder,
|
|
898
|
+
alwaysAvailable,
|
|
909
899
|
alwaysAvailable as analysisAlwaysAvailable,
|
|
910
|
-
|
|
900
|
+
bounded as analysisBounded,
|
|
911
901
|
ignore as analysisIgnore,
|
|
912
902
|
bounded,
|
|
913
903
|
computePInvariants,
|
|
@@ -924,6 +914,7 @@ export {
|
|
|
924
914
|
flatNetTransitionCount,
|
|
925
915
|
flatTransition,
|
|
926
916
|
flatten,
|
|
917
|
+
ignore,
|
|
927
918
|
isCoveredByInvariants,
|
|
928
919
|
isProven,
|
|
929
920
|
isViolated,
|
|
@@ -933,7 +924,6 @@ export {
|
|
|
933
924
|
placeBound,
|
|
934
925
|
propertyDescription,
|
|
935
926
|
structuralCheck,
|
|
936
|
-
unbounded,
|
|
937
927
|
unreachable
|
|
938
928
|
};
|
|
939
929
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/verification/analysis/dbm.ts","../../src/verification/analysis/state-class.ts","../../src/verification/analysis/scc-analyzer.ts","../../src/verification/analysis/environment-analysis-mode.ts","../../src/verification/analysis/state-class-graph.ts","../../src/verification/analysis/time-petri-net-analyzer.ts"],"sourcesContent":["const EPSILON = 1e-9;\n\n/**\n * Difference Bound Matrix (DBM) for Time Petri Net state class analysis.\n *\n * Implements the Berthomieu-Diaz (1991) algorithm for computing firing domains\n * and their successors. Matrix bounds[i][j] = upper bound on (xi - xj).\n * Index 0 is the reference clock; index i+1 is the clock for transition i.\n */\nexport class DBM {\n private readonly bounds: Float64Array;\n private readonly dim: number;\n readonly clockNames: readonly string[];\n private readonly _empty: boolean;\n\n private constructor(bounds: Float64Array, dim: number, clockNames: readonly string[], empty: boolean) {\n this.bounds = bounds;\n this.dim = dim;\n this.clockNames = clockNames;\n this._empty = empty;\n }\n\n /** Creates an initial firing domain for enabled transitions. */\n static create(clockNames: readonly string[], lowerBounds: number[], upperBounds: number[]): DBM {\n const n = clockNames.length;\n const dim = n + 1;\n const bounds = makeMatrix(dim, Infinity);\n\n for (let i = 0; i < n; i++) {\n bounds[(0) * dim + (i + 1)] = -lowerBounds[i]!;\n bounds[(i + 1) * dim + (0)] = upperBounds[i]!;\n }\n\n return new DBM(bounds, dim, clockNames, false).canonicalize();\n }\n\n /** Creates an empty (unsatisfiable) zone. */\n static empty(clockNames: readonly string[]): DBM {\n const b = new Float64Array(1);\n b[0] = 0;\n return new DBM(b, 1, clockNames, true);\n }\n\n isEmpty(): boolean {\n return this._empty;\n }\n\n clockCount(): number {\n return this.clockNames.length;\n }\n\n private get(i: number, j: number): number {\n return this.bounds[i * this.dim + j]!;\n }\n\n /** Gets the lower bound (earliest firing time) for clock i. */\n getLowerBound(clockIndex: number): number {\n if (this._empty || clockIndex < 0 || clockIndex >= this.clockNames.length) return 0;\n const val = -this.get(0, clockIndex + 1);\n return val === 0 ? 0 : val; // normalize -0 to 0\n }\n\n /** Gets the upper bound (latest firing time / deadline) for clock i. */\n getUpperBound(clockIndex: number): number {\n if (this._empty || clockIndex < 0 || clockIndex >= this.clockNames.length) return Infinity;\n return this.get(clockIndex + 1, 0);\n }\n\n /** Checks if transition can fire (lower bound <= 0 after time passage). */\n canFire(clockIndex: number): boolean {\n return !this._empty && this.getLowerBound(clockIndex) <= EPSILON;\n }\n\n /**\n * Computes the successor firing domain after firing transition t_f.\n * Implements the 5-step Berthomieu-Diaz successor formula.\n */\n fireTransition(\n firedClock: number,\n newClockNames: readonly string[],\n newLowerBounds: number[],\n newUpperBounds: number[],\n persistentClocks: number[],\n ): DBM {\n if (this._empty) return this;\n\n const n = this.clockNames.length;\n if (firedClock < 0 || firedClock >= n) {\n throw new Error(`Invalid fired clock index: ${firedClock}`);\n }\n\n // Step 1: Intersect with \"t_f fires first\" constraint\n const constrained = new Float64Array(this.bounds);\n const dim = this.dim;\n const f = firedClock + 1;\n\n for (let i = 0; i < n; i++) {\n if (i !== firedClock) {\n const idx = i + 1;\n const pos = f * dim + idx;\n constrained[pos] = Math.min(constrained[pos]!, 0);\n }\n }\n\n // Step 2: Canonicalize\n if (!canonicalizeInPlace(constrained, dim)) {\n return DBM.empty([]);\n }\n\n // Steps 3 & 4: Substitution and Elimination\n const newN = persistentClocks.length + newClockNames.length;\n const newDim = newN + 1;\n const newBounds = makeMatrix(newDim, Infinity);\n\n // Copy persistent clocks with transformed bounds\n for (let pi = 0; pi < persistentClocks.length; pi++) {\n const oldIdx = persistentClocks[pi]! + 1;\n const newIdx = pi + 1;\n\n const upper = constrained[oldIdx * dim + f]!;\n const lower = Math.max(0, -constrained[f * dim + oldIdx]!);\n\n newBounds[0 * newDim + newIdx] = -lower;\n newBounds[newIdx * newDim + 0] = upper;\n\n // Inter-clock constraints between persistent transitions (preserved)\n for (let pj = 0; pj < persistentClocks.length; pj++) {\n const oldJ = persistentClocks[pj]! + 1;\n const newJ = pj + 1;\n newBounds[newIdx * newDim + newJ] = constrained[oldIdx * dim + oldJ]!;\n }\n }\n\n // Step 5: Add fresh intervals for newly enabled transitions\n const offset = persistentClocks.length;\n for (let k = 0; k < newClockNames.length; k++) {\n const idx = offset + k + 1;\n newBounds[0 * newDim + idx] = -newLowerBounds[k]!;\n newBounds[idx * newDim + 0] = newUpperBounds[k]!;\n }\n\n // Build new clock names\n const allNames: string[] = [];\n for (const idx of persistentClocks) {\n allNames.push(this.clockNames[idx]!);\n }\n allNames.push(...newClockNames);\n\n // Step 6: Final canonicalization\n return new DBM(newBounds, newDim, allNames, false).canonicalize();\n }\n\n /** Lets time pass: set all lower bounds to 0. */\n letTimePass(): DBM {\n if (this._empty) return this;\n\n const newBounds = new Float64Array(this.bounds);\n for (let i = 1; i < this.dim; i++) {\n newBounds[0 * this.dim + i] = 0;\n }\n\n return new DBM(newBounds, this.dim, this.clockNames, false).canonicalize();\n }\n\n private canonicalize(): DBM {\n if (this._empty) return this;\n\n const canon = new Float64Array(this.bounds);\n if (!canonicalizeInPlace(canon, this.dim)) {\n return DBM.empty(this.clockNames);\n }\n return new DBM(canon, this.dim, this.clockNames, false);\n }\n\n equals(other: DBM): boolean {\n if (this === other) return true;\n if (this._empty && other._empty) return true;\n if (this._empty || other._empty) return false;\n if (this.clockNames.length !== other.clockNames.length) return false;\n for (let i = 0; i < this.clockNames.length; i++) {\n if (this.clockNames[i] !== other.clockNames[i]) return false;\n }\n if (this.bounds.length !== other.bounds.length) return false;\n for (let i = 0; i < this.bounds.length; i++) {\n if (Math.abs(this.bounds[i]! - other.bounds[i]!) > EPSILON) return false;\n }\n return true;\n }\n\n toString(): string {\n if (this._empty) return 'DBM[empty]';\n const parts: string[] = [];\n for (let i = 0; i < this.clockNames.length; i++) {\n const lo = formatBound(this.getLowerBound(i));\n const hi = formatBound(this.getUpperBound(i));\n parts.push(`${this.clockNames[i]}:[${lo},${hi}]`);\n }\n return `DBM{${parts.join(', ')}}`;\n }\n}\n\nfunction makeMatrix(dim: number, fill: number): Float64Array {\n const m = new Float64Array(dim * dim).fill(fill);\n for (let i = 0; i < dim; i++) {\n m[i * dim + i] = 0;\n }\n return m;\n}\n\nfunction canonicalizeInPlace(dbm: Float64Array, dim: number): boolean {\n for (let k = 0; k < dim; k++) {\n for (let i = 0; i < dim; i++) {\n for (let j = 0; j < dim; j++) {\n const ik = dbm[i * dim + k]!;\n const kj = dbm[k * dim + j]!;\n if (ik < Infinity && kj < Infinity) {\n const via = ik + kj;\n if (via < dbm[i * dim + j]!) {\n dbm[i * dim + j] = via;\n }\n }\n }\n }\n }\n for (let i = 0; i < dim; i++) {\n if (dbm[i * dim + i]! < -EPSILON) return false;\n }\n return true;\n}\n\nfunction formatBound(b: number): string {\n if (b >= Infinity / 2) return '\\u221e';\n if (b === Math.trunc(b)) return String(b);\n return b.toFixed(3);\n}\n","import type { Transition } from '../../core/transition.js';\nimport type { MarkingState } from '../marking-state.js';\nimport type { DBM } from './dbm.js';\n\n/**\n * A State Class in Time Petri Net analysis.\n *\n * A state class is a pair (M, D) where M is a marking and D is a firing domain (DBM).\n * State classes provide a finite abstraction of the infinite state space of Time Petri Nets.\n */\nexport class StateClass {\n readonly marking: MarkingState;\n readonly firingDomain: DBM;\n readonly enabledTransitions: readonly Transition[];\n\n constructor(marking: MarkingState, firingDomain: DBM, enabledTransitions: readonly Transition[]) {\n this.marking = marking;\n this.firingDomain = firingDomain;\n this.enabledTransitions = [...enabledTransitions];\n }\n\n isEmpty(): boolean {\n return this.firingDomain.isEmpty();\n }\n\n canFire(transition: Transition): boolean {\n const idx = this.enabledTransitions.indexOf(transition);\n if (idx < 0) return false;\n return this.firingDomain.getUpperBound(idx) >= 0;\n }\n\n transitionIndex(transition: Transition): number {\n return this.enabledTransitions.indexOf(transition);\n }\n\n equals(other: StateClass): boolean {\n if (this === other) return true;\n return this.marking.toString() === other.marking.toString()\n && this.firingDomain.equals(other.firingDomain);\n }\n\n toString(): string {\n return `StateClass{${this.marking}, ${this.firingDomain}}`;\n }\n}\n","/**\n * Strongly Connected Component analysis using Tarjan's algorithm.\n * Generic over node type T. Uses a key function for Map-based lookups.\n */\n\n/** Computes all SCCs in a graph. O(V + E) via Tarjan's algorithm. */\nexport function computeSCCs<T>(\n nodes: Iterable<T>,\n successors: (node: T) => Iterable<T>,\n): Set<T>[] {\n const nodeArray = [...nodes];\n const indexMap = new Map<T, number>();\n const lowlink = new Map<T, number>();\n const onStack = new Set<T>();\n const stack: T[] = [];\n const sccs: Set<T>[] = [];\n let index = 0;\n\n function strongConnect(v: T): void {\n indexMap.set(v, index);\n lowlink.set(v, index);\n index++;\n stack.push(v);\n onStack.add(v);\n\n for (const w of successors(v)) {\n if (!indexMap.has(w)) {\n strongConnect(w);\n lowlink.set(v, Math.min(lowlink.get(v)!, lowlink.get(w)!));\n } else if (onStack.has(w)) {\n lowlink.set(v, Math.min(lowlink.get(v)!, indexMap.get(w)!));\n }\n }\n\n if (lowlink.get(v) === indexMap.get(v)) {\n const scc = new Set<T>();\n let w: T;\n do {\n w = stack.pop()!;\n onStack.delete(w);\n scc.add(w);\n } while (w !== v);\n sccs.push(scc);\n }\n }\n\n for (const node of nodeArray) {\n if (!indexMap.has(node)) {\n strongConnect(node);\n }\n }\n\n return sccs;\n}\n\n/** Finds terminal (bottom) SCCs — SCCs with no outgoing edges to other SCCs. */\nexport function findTerminalSCCs<T>(\n nodes: Iterable<T>,\n successors: (node: T) => Iterable<T>,\n): Set<T>[] {\n const allSCCs = computeSCCs(nodes, successors);\n\n const terminal: Set<T>[] = [];\n for (const scc of allSCCs) {\n let isTerminal = true;\n for (const node of scc) {\n for (const succ of successors(node)) {\n if (!scc.has(succ)) {\n isTerminal = false;\n break;\n }\n }\n if (!isTerminal) break;\n }\n if (isTerminal) {\n terminal.push(scc);\n }\n }\n\n return terminal;\n}\n","/**\n * Analysis mode for environment places in state class graph construction.\n */\nexport type EnvironmentAnalysisMode =\n | { readonly type: 'always-available' }\n | { readonly type: 'bounded'; readonly maxTokens: number }\n | { readonly type: 'ignore' };\n\n/** Assumes environment places always have sufficient tokens. */\nexport function alwaysAvailable(): EnvironmentAnalysisMode {\n return { type: 'always-available' };\n}\n\n/** Analyzes with a bounded number of tokens in environment places. */\nexport function bounded(maxTokens: number): EnvironmentAnalysisMode {\n if (maxTokens < 0) throw new Error('maxTokens must be non-negative');\n return { type: 'bounded', maxTokens };\n}\n\n/** Treats environment places as regular places (default). */\nexport function ignore(): EnvironmentAnalysisMode {\n return { type: 'ignore' };\n}\n","import type { Place } from '../../core/place.js';\nimport type { EnvironmentPlace } from '../../core/place.js';\nimport type { In } from '../../core/in.js';\nimport type { Transition } from '../../core/transition.js';\nimport type { PetriNet } from '../../core/petri-net.js';\nimport { earliest, latest } from '../../core/timing.js';\nimport { enumerateBranches } from '../../core/out.js';\nimport { MarkingState } from '../marking-state.js';\nimport { DBM } from './dbm.js';\nimport { StateClass } from './state-class.js';\nimport type { EnvironmentAnalysisMode } from './environment-analysis-mode.js';\nimport { ignore } from './environment-analysis-mode.js';\n\n/** Edge that tracks which XOR branch was taken. */\nexport interface BranchEdge {\n readonly branchIndex: number;\n readonly target: StateClass;\n}\n\ninterface VirtualTransition {\n readonly transition: Transition;\n readonly branchIndex: number;\n readonly outputPlaces: ReadonlySet<Place<any>>;\n}\n\n/**\n * State Class Graph for Time Petri Net analysis.\n *\n * Implements the Berthomieu-Diaz (1991) algorithm for computing the state class\n * graph of a bounded Time Petri Net.\n */\nexport class StateClassGraph {\n readonly net: PetriNet;\n readonly initialClass: StateClass;\n private readonly _stateClasses: StateClass[];\n private readonly _transitions: Map<StateClass, Map<Transition, BranchEdge[]>>;\n private readonly _successors: Map<StateClass, Set<StateClass>>;\n private readonly _predecessors: Map<StateClass, Set<StateClass>>;\n private readonly _complete: boolean;\n\n private constructor(\n net: PetriNet,\n initialClass: StateClass,\n stateClasses: StateClass[],\n transitions: Map<StateClass, Map<Transition, BranchEdge[]>>,\n complete: boolean,\n ) {\n this.net = net;\n this.initialClass = initialClass;\n this._stateClasses = stateClasses;\n this._transitions = transitions;\n this._complete = complete;\n\n // Build successor/predecessor maps\n this._successors = new Map();\n this._predecessors = new Map();\n for (const sc of stateClasses) {\n this._successors.set(sc, new Set());\n this._predecessors.set(sc, new Set());\n }\n for (const [from, tMap] of transitions) {\n for (const edges of tMap.values()) {\n for (const edge of edges) {\n this._successors.get(from)!.add(edge.target);\n this._predecessors.get(edge.target)!.add(from);\n }\n }\n }\n }\n\n /** Builds the state class graph for a Time Petri Net. */\n static build(\n net: PetriNet,\n initialMarking: MarkingState,\n maxClasses: number,\n environmentPlaces?: Set<EnvironmentPlace<any>>,\n environmentMode?: EnvironmentAnalysisMode,\n ): StateClassGraph {\n const envMode = environmentMode ?? ignore();\n const envPlaces = new Set<Place<any>>();\n if (environmentPlaces) {\n for (const ep of environmentPlaces) {\n envPlaces.add(ep.place);\n }\n }\n\n const enabledTransitions = findEnabledTransitions(net, initialMarking, envPlaces, envMode);\n const clockNames = enabledTransitions.map(t => t.name);\n const lowerBounds = enabledTransitions.map(t => earliest(t.timing) / 1000);\n const upperBounds = enabledTransitions.map(t => latest(t.timing) / 1000);\n\n let initialDBM = DBM.create(clockNames, lowerBounds, upperBounds);\n initialDBM = initialDBM.letTimePass();\n const initialClass = new StateClass(initialMarking, initialDBM, enabledTransitions);\n\n // BFS exploration\n const stateClasses: StateClass[] = [initialClass];\n const stateClassSet = new Set<string>([classKey(initialClass)]);\n const classMap = new Map<string, StateClass>([[classKey(initialClass), initialClass]]);\n const transitionMap = new Map<StateClass, Map<Transition, BranchEdge[]>>();\n transitionMap.set(initialClass, new Map());\n const queue: StateClass[] = [initialClass];\n let complete = true;\n\n while (queue.length > 0) {\n if (stateClasses.length >= maxClasses) {\n complete = false;\n break;\n }\n\n const current = queue.shift()!;\n\n for (const transition of current.enabledTransitions) {\n const virtualTransitions = expandTransition(transition);\n\n for (const vt of virtualTransitions) {\n const successor = computeSuccessor(net, current, vt, envPlaces, envMode);\n if (successor === null || successor.isEmpty()) continue;\n\n // Add edge with branch index\n const tEdges = transitionMap.get(current)!;\n if (!tEdges.has(transition)) tEdges.set(transition, []);\n tEdges.get(transition)!.push({ branchIndex: vt.branchIndex, target: successor });\n\n // Dedup state classes by key\n const key = classKey(successor);\n if (!stateClassSet.has(key)) {\n stateClassSet.add(key);\n classMap.set(key, successor);\n stateClasses.push(successor);\n transitionMap.set(successor, new Map());\n queue.push(successor);\n } else {\n // Rewrite edge target to existing canonical instance\n const canonical = classMap.get(key)!;\n if (canonical !== successor) {\n const edges = tEdges.get(transition)!;\n edges[edges.length - 1] = { branchIndex: vt.branchIndex, target: canonical };\n }\n }\n }\n }\n }\n\n return new StateClassGraph(net, initialClass, stateClasses, transitionMap, complete);\n }\n\n stateClasses(): readonly StateClass[] {\n return this._stateClasses;\n }\n\n size(): number {\n return this._stateClasses.length;\n }\n\n isComplete(): boolean {\n return this._complete;\n }\n\n successors(sc: StateClass): Set<StateClass> {\n return this._successors.get(sc) ?? new Set();\n }\n\n predecessors(sc: StateClass): Set<StateClass> {\n return this._predecessors.get(sc) ?? new Set();\n }\n\n /** Returns all outgoing transitions with their branch edges. */\n outgoingBranchEdges(sc: StateClass): Map<Transition, BranchEdge[]> {\n return this._transitions.get(sc) ?? new Map();\n }\n\n /** Returns the branch edges for a specific transition from a state class. */\n branchEdges(sc: StateClass, transition: Transition): BranchEdge[] {\n const map = this._transitions.get(sc);\n if (!map) return [];\n return map.get(transition) ?? [];\n }\n\n /** Returns all transitions that are enabled from a state class. */\n enabledTransitions(sc: StateClass): Set<Transition> {\n const map = this._transitions.get(sc);\n if (!map) return new Set();\n return new Set(map.keys());\n }\n\n /** Finds all state classes with a given marking. */\n classesWithMarking(marking: MarkingState): StateClass[] {\n const key = marking.toString();\n return this._stateClasses.filter(sc => sc.marking.toString() === key);\n }\n\n /** Checks if a marking is reachable. */\n isReachable(marking: MarkingState): boolean {\n const key = marking.toString();\n return this._stateClasses.some(sc => sc.marking.toString() === key);\n }\n\n /** Gets all reachable markings. */\n reachableMarkings(): Set<string> {\n const markings = new Set<string>();\n for (const sc of this._stateClasses) {\n markings.add(sc.marking.toString());\n }\n return markings;\n }\n\n /** Counts edges in the graph (each branch edge counts separately). */\n edgeCount(): number {\n let count = 0;\n for (const map of this._transitions.values()) {\n for (const edges of map.values()) {\n count += edges.length;\n }\n }\n return count;\n }\n\n toString(): string {\n return `StateClassGraph[classes=${this.size()}, edges=${this.edgeCount()}, complete=${this._complete}]`;\n }\n}\n\nfunction classKey(sc: StateClass): string {\n return `${sc.marking.toString()}|${sc.firingDomain.toString()}`;\n}\n\nfunction expandTransition(t: Transition): VirtualTransition[] {\n let branches: ReadonlyArray<ReadonlySet<Place<any>>>;\n\n if (t.outputSpec !== null) {\n branches = enumerateBranches(t.outputSpec);\n } else {\n branches = [new Set()];\n }\n\n return branches.map((outputPlaces, i) => ({\n transition: t,\n branchIndex: i,\n outputPlaces: outputPlaces as ReadonlySet<Place<any>>,\n }));\n}\n\nfunction computeSuccessor(\n net: PetriNet,\n current: StateClass,\n fired: VirtualTransition,\n environmentPlaces: Set<Place<any>>,\n environmentMode: EnvironmentAnalysisMode,\n): StateClass | null {\n const transition = fired.transition;\n\n // 1. Compute new marking\n const newMarking = fireTransition(current.marking, transition, fired.outputPlaces, environmentPlaces, environmentMode);\n\n // 2. Determine persistent and newly enabled transitions\n const newEnabledAll = findEnabledTransitions(net, newMarking, environmentPlaces, environmentMode);\n\n const persistent: Transition[] = [];\n const persistentIndices: number[] = [];\n for (let i = 0; i < current.enabledTransitions.length; i++) {\n const t = current.enabledTransitions[i]!;\n if (t !== transition && newEnabledAll.includes(t)) {\n persistent.push(t);\n persistentIndices.push(i);\n }\n }\n\n const newlyEnabled: Transition[] = [];\n for (const t of newEnabledAll) {\n if (!persistent.includes(t)) {\n newlyEnabled.push(t);\n }\n }\n\n // 3. Compute successor DBM\n const firedIdx = current.transitionIndex(transition);\n const newClockNames = newlyEnabled.map(t => t.name);\n const newLowerBounds = newlyEnabled.map(t => earliest(t.timing) / 1000);\n const newUpperBounds = newlyEnabled.map(t => latest(t.timing) / 1000);\n\n let newDBM = current.firingDomain.fireTransition(\n firedIdx,\n newClockNames,\n newLowerBounds,\n newUpperBounds,\n persistentIndices,\n );\n\n newDBM = newDBM.letTimePass();\n\n const allEnabled = [...persistent, ...newlyEnabled];\n return new StateClass(newMarking, newDBM, allEnabled);\n}\n\nfunction findEnabledTransitions(\n net: PetriNet,\n marking: MarkingState,\n environmentPlaces: Set<Place<any>>,\n environmentMode: EnvironmentAnalysisMode,\n): Transition[] {\n const enabled: Transition[] = [];\n for (const transition of net.transitions) {\n if (isEnabled(transition, marking, environmentPlaces, environmentMode)) {\n enabled.push(transition);\n }\n }\n return enabled;\n}\n\nfunction isEnabled(\n transition: Transition,\n marking: MarkingState,\n environmentPlaces: Set<Place<any>>,\n environmentMode: EnvironmentAnalysisMode,\n): boolean {\n for (const spec of transition.inputSpecs) {\n const required = inputRequiredCount(spec);\n if (!checkPlaceEnabled(spec.place, required, marking, environmentPlaces, environmentMode)) {\n return false;\n }\n }\n\n for (const arc of transition.reads) {\n if (!checkPlaceEnabled(arc.place, 1, marking, environmentPlaces, environmentMode)) {\n return false;\n }\n }\n\n for (const arc of transition.inhibitors) {\n if (marking.hasTokens(arc.place)) {\n return false;\n }\n }\n\n return true;\n}\n\nfunction inputRequiredCount(spec: In): number {\n switch (spec.type) {\n case 'one': return 1;\n case 'exactly': return spec.count;\n case 'all': return 1;\n case 'at-least': return spec.minimum;\n }\n}\n\nfunction inputConsumeCount(spec: In): number {\n switch (spec.type) {\n case 'one': return 1;\n case 'exactly': return spec.count;\n case 'all': return 1; // Analysis: consume minimum (1 token)\n case 'at-least': return spec.minimum;\n }\n}\n\nfunction checkPlaceEnabled(\n place: Place<any>,\n required: number,\n marking: MarkingState,\n environmentPlaces: Set<Place<any>>,\n environmentMode: EnvironmentAnalysisMode,\n): boolean {\n if (!environmentPlaces.has(place)) {\n return marking.tokens(place) >= required;\n }\n\n switch (environmentMode.type) {\n case 'always-available': return true;\n case 'bounded': return required <= environmentMode.maxTokens;\n case 'ignore': return marking.tokens(place) >= required;\n }\n}\n\nfunction fireTransition(\n marking: MarkingState,\n transition: Transition,\n outputPlaces: ReadonlySet<Place<any>>,\n environmentPlaces: Set<Place<any>>,\n environmentMode: EnvironmentAnalysisMode,\n): MarkingState {\n const builder = MarkingState.builder().copyFrom(marking);\n\n // Consume from inputs\n for (const spec of transition.inputSpecs) {\n const toConsume = inputConsumeCount(spec);\n consumeFromPlace(builder, spec.place, toConsume, environmentPlaces, environmentMode);\n }\n\n // Reset places\n for (const arc of transition.resets) {\n const current = marking.tokens(arc.place);\n if (current > 0) {\n builder.removeTokens(arc.place, current);\n }\n }\n\n // Produce to outputs\n for (const place of outputPlaces) {\n builder.addTokens(place, 1);\n }\n\n return builder.build();\n}\n\nfunction consumeFromPlace(\n builder: ReturnType<typeof MarkingState.builder>,\n place: Place<any>,\n count: number,\n environmentPlaces: Set<Place<any>>,\n environmentMode: EnvironmentAnalysisMode,\n): void {\n if (!environmentPlaces.has(place)) {\n builder.removeTokens(place, count);\n return;\n }\n if (environmentMode.type === 'ignore') {\n builder.removeTokens(place, count);\n }\n}\n","import type { Place } from '../../core/place.js';\nimport type { EnvironmentPlace } from '../../core/place.js';\nimport type { Transition } from '../../core/transition.js';\nimport type { PetriNet } from '../../core/petri-net.js';\nimport { enumerateBranches } from '../../core/out.js';\nimport { MarkingState } from '../marking-state.js';\nimport { StateClassGraph } from './state-class-graph.js';\nimport type { StateClass } from './state-class.js';\nimport { computeSCCs, findTerminalSCCs } from './scc-analyzer.js';\nimport type { EnvironmentAnalysisMode } from './environment-analysis-mode.js';\nimport { ignore } from './environment-analysis-mode.js';\n\n/** Result of liveness analysis. */\nexport interface LivenessResult {\n readonly stateClassGraph: StateClassGraph;\n readonly allSCCs: Set<StateClass>[];\n readonly terminalSCCs: Set<StateClass>[];\n readonly goalClasses: Set<StateClass>;\n readonly canReachGoal: Set<StateClass>;\n readonly isGoalLive: boolean;\n readonly isL4Live: boolean;\n readonly isComplete: boolean;\n readonly report: string;\n}\n\n/** Information about XOR branch coverage for a single transition. */\nexport interface XorBranchInfo {\n readonly totalBranches: number;\n readonly takenBranches: Set<number>;\n readonly untakenBranches: Set<number>;\n readonly branchOutputs: ReadonlyArray<ReadonlySet<Place<any>>>;\n}\n\n/** Result of XOR branch analysis. */\nexport interface XorBranchAnalysis {\n readonly transitionBranches: Map<Transition, XorBranchInfo>;\n unreachableBranches(): Map<Transition, Set<number>>;\n isXorComplete(): boolean;\n report(): string;\n}\n\n/**\n * Formal analyzer for Time Petri Nets using the State Class Graph method.\n * Implements Berthomieu-Diaz (1991) analysis.\n */\nexport class TimePetriNetAnalyzer {\n private readonly net: PetriNet;\n private readonly initialMarking: MarkingState;\n private readonly goalPlaces: Set<Place<any>>;\n private readonly maxClasses: number;\n private readonly environmentPlaces: Set<EnvironmentPlace<any>>;\n private readonly environmentMode: EnvironmentAnalysisMode;\n\n /** @internal Called by builder — use `TimePetriNetAnalyzer.forNet()` instead. */\n static create(\n net: PetriNet,\n initialMarking: MarkingState,\n goalPlaces: Set<Place<any>>,\n maxClasses: number,\n environmentPlaces: Set<EnvironmentPlace<any>>,\n environmentMode: EnvironmentAnalysisMode,\n ): TimePetriNetAnalyzer {\n return new TimePetriNetAnalyzer(net, initialMarking, goalPlaces, maxClasses, environmentPlaces, environmentMode);\n }\n\n private constructor(\n net: PetriNet,\n initialMarking: MarkingState,\n goalPlaces: Set<Place<any>>,\n maxClasses: number,\n environmentPlaces: Set<EnvironmentPlace<any>>,\n environmentMode: EnvironmentAnalysisMode,\n ) {\n this.net = net;\n this.initialMarking = initialMarking;\n this.goalPlaces = goalPlaces;\n this.maxClasses = maxClasses;\n this.environmentPlaces = environmentPlaces;\n this.environmentMode = environmentMode;\n }\n\n static forNet(net: PetriNet): TimePetriNetAnalyzerBuilder {\n return new TimePetriNetAnalyzerBuilder(net);\n }\n\n /** Performs formal liveness analysis. */\n analyze(): LivenessResult {\n const report: string[] = [];\n report.push('=== TIME PETRI NET FORMAL ANALYSIS ===\\n');\n report.push(`Method: State Class Graph (Berthomieu-Diaz 1991)`);\n report.push(`Net: ${this.net.name}`);\n report.push(`Places: ${this.net.places.size}`);\n report.push(`Transitions: ${this.net.transitions.size}`);\n report.push(`Goal places: [${[...this.goalPlaces].map(p => p.name).join(', ')}]\\n`);\n\n // Phase 1: Build State Class Graph\n report.push('Phase 1: Building State Class Graph...');\n if (this.environmentPlaces.size > 0) {\n report.push(` Environment places: ${this.environmentPlaces.size}`);\n report.push(` Environment mode: ${this.environmentMode.type}`);\n }\n const scg = StateClassGraph.build(this.net, this.initialMarking, this.maxClasses, this.environmentPlaces, this.environmentMode);\n report.push(` State classes: ${scg.size()}`);\n report.push(` Edges: ${scg.edgeCount()}`);\n report.push(` Complete: ${scg.isComplete() ? 'YES' : 'NO (truncated)'}`);\n\n if (!scg.isComplete()) {\n report.push(` WARNING: State class graph truncated at ${this.maxClasses} classes. Analysis may be incomplete.`);\n }\n report.push('');\n\n // Phase 2: Identify goal state classes\n report.push('Phase 2: Identifying goal state classes...');\n const goalClasses = new Set<StateClass>();\n for (const sc of scg.stateClasses()) {\n if (sc.marking.hasTokensInAny(this.goalPlaces)) {\n goalClasses.add(sc);\n }\n }\n report.push(` Goal state classes: ${goalClasses.size}\\n`);\n\n // Phase 3: Compute SCCs\n report.push('Phase 3: Computing Strongly Connected Components...');\n const successorFn = (sc: StateClass) => scg.successors(sc);\n const allSCCs = computeSCCs(scg.stateClasses(), successorFn);\n const terminalSCCs = findTerminalSCCs(scg.stateClasses(), successorFn);\n\n report.push(` Total SCCs: ${allSCCs.length}`);\n report.push(` Terminal SCCs: ${terminalSCCs.length}\\n`);\n\n // Phase 4: Check goal liveness\n report.push('Phase 4: Verifying Goal Liveness...');\n report.push(' Property: From every reachable state, a goal state is reachable');\n\n const terminalSCCsWithGoal: Set<StateClass>[] = [];\n const terminalSCCsWithoutGoal: Set<StateClass>[] = [];\n\n for (const scc of terminalSCCs) {\n let hasGoal = false;\n for (const sc of scc) {\n if (goalClasses.has(sc)) { hasGoal = true; break; }\n }\n (hasGoal ? terminalSCCsWithGoal : terminalSCCsWithoutGoal).push(scc);\n }\n\n report.push(` Terminal SCCs with goal: ${terminalSCCsWithGoal.length}`);\n report.push(` Terminal SCCs without goal: ${terminalSCCsWithoutGoal.length}`);\n\n const canReachGoal = computeBackwardReachability(scg, goalClasses);\n const statesNotReachingGoal = scg.size() - canReachGoal.size;\n\n report.push(` States that can reach goal: ${canReachGoal.size}/${scg.size()}\\n`);\n\n const isGoalLive = terminalSCCsWithoutGoal.length === 0 && statesNotReachingGoal === 0;\n\n // Phase 5: Check classical liveness (L4)\n report.push('Phase 5: Verifying Classical Liveness (L4)...');\n report.push(' Property: Every transition can fire from every reachable marking');\n\n const allTransitions = new Set(this.net.transitions);\n const terminalSCCsMissingTransitions: Set<StateClass>[] = [];\n\n for (const scc of terminalSCCs) {\n const transitionsInSCC = new Set<Transition>();\n for (const sc of scc) {\n for (const t of scg.enabledTransitions(sc)) {\n const edges = scg.branchEdges(sc, t);\n for (const edge of edges) {\n if (scc.has(edge.target)) {\n transitionsInSCC.add(t);\n }\n }\n }\n }\n let missingAny = false;\n for (const t of allTransitions) {\n if (!transitionsInSCC.has(t)) { missingAny = true; break; }\n }\n if (missingAny) {\n terminalSCCsMissingTransitions.push(scc);\n const missing = [...allTransitions].filter(t => !transitionsInSCC.has(t));\n report.push(` Terminal SCC missing transitions: [${missing.map(t => t.name).join(', ')}]`);\n }\n }\n\n const isL4Live = terminalSCCsMissingTransitions.length === 0 && scg.isComplete();\n\n // Summary\n report.push('\\n=== ANALYSIS RESULT ===\\n');\n\n if (isGoalLive && scg.isComplete()) {\n report.push('GOAL LIVENESS VERIFIED');\n report.push(' From every reachable state class, a goal marking is reachable.');\n } else if (isGoalLive && !scg.isComplete()) {\n report.push('GOAL LIVENESS LIKELY (incomplete proof)');\n } else {\n report.push('GOAL LIVENESS VIOLATION');\n if (terminalSCCsWithoutGoal.length > 0) {\n report.push(` ${terminalSCCsWithoutGoal.length} terminal SCC(s) have no goal state.`);\n }\n if (statesNotReachingGoal > 0) {\n report.push(` ${statesNotReachingGoal} state class(es) cannot reach goal.`);\n }\n }\n\n report.push('');\n\n if (isL4Live) {\n report.push('CLASSICAL LIVENESS (L4) VERIFIED');\n } else {\n report.push('CLASSICAL LIVENESS (L4) NOT VERIFIED');\n if (terminalSCCsMissingTransitions.length > 0) {\n report.push(\" Some terminal SCCs don't contain all transitions.\");\n }\n if (!scg.isComplete()) {\n report.push(' (State class graph incomplete - cannot prove L4)');\n }\n }\n\n return {\n stateClassGraph: scg,\n allSCCs,\n terminalSCCs,\n goalClasses,\n canReachGoal,\n isGoalLive,\n isL4Live,\n isComplete: scg.isComplete(),\n report: report.join('\\n'),\n };\n }\n\n /** Analyzes XOR branch coverage for a built state class graph. */\n static analyzeXorBranches(scg: StateClassGraph): XorBranchAnalysis {\n const result = new Map<Transition, XorBranchInfo>();\n\n for (const transition of scg.net.transitions) {\n if (transition.outputSpec === null) continue;\n\n const allBranches = enumerateBranches(transition.outputSpec);\n if (allBranches.length <= 1) continue;\n\n const takenBranches = new Set<number>();\n for (const sc of scg.stateClasses()) {\n const edges = scg.branchEdges(sc, transition);\n for (const edge of edges) {\n takenBranches.add(edge.branchIndex);\n }\n }\n\n const untakenBranches = new Set<number>();\n for (let i = 0; i < allBranches.length; i++) {\n if (!takenBranches.has(i)) untakenBranches.add(i);\n }\n\n result.set(transition, {\n totalBranches: allBranches.length,\n takenBranches,\n untakenBranches,\n branchOutputs: allBranches,\n });\n }\n\n return createXorBranchAnalysis(result);\n }\n}\n\nfunction createXorBranchAnalysis(transitionBranches: Map<Transition, XorBranchInfo>): XorBranchAnalysis {\n return {\n transitionBranches,\n unreachableBranches(): Map<Transition, Set<number>> {\n const result = new Map<Transition, Set<number>>();\n for (const [t, info] of transitionBranches) {\n if (info.untakenBranches.size > 0) {\n result.set(t, info.untakenBranches);\n }\n }\n return result;\n },\n isXorComplete(): boolean {\n for (const info of transitionBranches.values()) {\n if (info.untakenBranches.size > 0) return false;\n }\n return true;\n },\n report(): string {\n if (transitionBranches.size === 0) return 'No XOR transitions in net.';\n\n const lines: string[] = [];\n lines.push('XOR Branch Coverage Analysis');\n lines.push('============================\\n');\n\n for (const [t, info] of transitionBranches) {\n lines.push(`Transition: ${t.name}`);\n lines.push(` Branches: ${info.totalBranches}`);\n lines.push(` Taken: [${[...info.takenBranches].join(', ')}]`);\n\n if (info.untakenBranches.size > 0) {\n lines.push(` UNREACHABLE: [${[...info.untakenBranches].join(', ')}]`);\n for (const idx of info.untakenBranches) {\n const places = [...info.branchOutputs[idx]!].map(p => p.name).join(', ');\n lines.push(` Branch ${idx} outputs: [${places}]`);\n }\n } else {\n lines.push(' All branches reachable');\n }\n lines.push('');\n }\n\n if (this.isXorComplete()) {\n lines.push('RESULT: All XOR branches are reachable.');\n } else {\n lines.push('RESULT: Some XOR branches are unreachable!');\n }\n\n return lines.join('\\n');\n },\n };\n}\n\nfunction computeBackwardReachability(scg: StateClassGraph, goals: Set<StateClass>): Set<StateClass> {\n const reachable = new Set(goals);\n const queue = [...goals];\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n for (const pred of scg.predecessors(current)) {\n if (!reachable.has(pred)) {\n reachable.add(pred);\n queue.push(pred);\n }\n }\n }\n\n return reachable;\n}\n\n/** Builder for TimePetriNetAnalyzer. */\nexport class TimePetriNetAnalyzerBuilder {\n private readonly net: PetriNet;\n private _initialMarking: MarkingState = MarkingState.empty();\n private readonly _goalPlaces = new Set<Place<any>>();\n private _maxClasses = 100_000;\n private readonly _environmentPlaces = new Set<EnvironmentPlace<any>>();\n private _environmentMode: EnvironmentAnalysisMode = ignore();\n\n constructor(net: PetriNet) {\n this.net = net;\n }\n\n initialMarking(marking: MarkingState): this {\n this._initialMarking = marking;\n return this;\n }\n\n goalPlaces(...places: Place<any>[]): this {\n for (const p of places) this._goalPlaces.add(p);\n return this;\n }\n\n maxClasses(max: number): this {\n this._maxClasses = max;\n return this;\n }\n\n environmentPlaces(...places: EnvironmentPlace<any>[]): this {\n for (const ep of places) this._environmentPlaces.add(ep);\n return this;\n }\n\n environmentMode(mode: EnvironmentAnalysisMode): this {\n this._environmentMode = mode;\n return this;\n }\n\n build(): TimePetriNetAnalyzer {\n if (this._goalPlaces.size === 0) {\n throw new Error('At least one goal place must be specified');\n }\n return TimePetriNetAnalyzer.create(\n this.net,\n this._initialMarking,\n this._goalPlaces,\n this._maxClasses,\n this._environmentPlaces,\n this._environmentMode,\n );\n }\n}\n"],"mappings":"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","names":["bounded"]}
|
|
1
|
+
{"version":3,"sources":["../../src/verification/analysis/dbm.ts","../../src/verification/analysis/state-class.ts","../../src/verification/analysis/scc-analyzer.ts","../../src/verification/analysis/state-class-graph.ts","../../src/verification/analysis/time-petri-net-analyzer.ts"],"sourcesContent":["const EPSILON = 1e-9;\n\n/**\n * Difference Bound Matrix (DBM) for Time Petri Net state class analysis.\n *\n * Implements the Berthomieu-Diaz (1991) algorithm for computing firing domains\n * and their successors. Matrix bounds[i][j] = upper bound on (xi - xj).\n * Index 0 is the reference clock; index i+1 is the clock for transition i.\n */\nexport class DBM {\n private readonly bounds: Float64Array;\n private readonly dim: number;\n readonly clockNames: readonly string[];\n private readonly _empty: boolean;\n\n private constructor(bounds: Float64Array, dim: number, clockNames: readonly string[], empty: boolean) {\n this.bounds = bounds;\n this.dim = dim;\n this.clockNames = clockNames;\n this._empty = empty;\n }\n\n /** Creates an initial firing domain for enabled transitions. */\n static create(clockNames: readonly string[], lowerBounds: number[], upperBounds: number[]): DBM {\n const n = clockNames.length;\n const dim = n + 1;\n const bounds = makeMatrix(dim, Infinity);\n\n for (let i = 0; i < n; i++) {\n bounds[(0) * dim + (i + 1)] = -lowerBounds[i]!;\n bounds[(i + 1) * dim + (0)] = upperBounds[i]!;\n }\n\n return new DBM(bounds, dim, clockNames, false).canonicalize();\n }\n\n /** Creates an empty (unsatisfiable) zone. */\n static empty(clockNames: readonly string[]): DBM {\n const b = new Float64Array(1);\n b[0] = 0;\n return new DBM(b, 1, clockNames, true);\n }\n\n isEmpty(): boolean {\n return this._empty;\n }\n\n clockCount(): number {\n return this.clockNames.length;\n }\n\n private get(i: number, j: number): number {\n return this.bounds[i * this.dim + j]!;\n }\n\n /** Gets the lower bound (earliest firing time) for clock i. */\n getLowerBound(clockIndex: number): number {\n if (this._empty || clockIndex < 0 || clockIndex >= this.clockNames.length) return 0;\n const val = -this.get(0, clockIndex + 1);\n return val === 0 ? 0 : val; // normalize -0 to 0\n }\n\n /** Gets the upper bound (latest firing time / deadline) for clock i. */\n getUpperBound(clockIndex: number): number {\n if (this._empty || clockIndex < 0 || clockIndex >= this.clockNames.length) return Infinity;\n return this.get(clockIndex + 1, 0);\n }\n\n /** Checks if transition can fire (lower bound <= 0 after time passage). */\n canFire(clockIndex: number): boolean {\n return !this._empty && this.getLowerBound(clockIndex) <= EPSILON;\n }\n\n /**\n * Computes the successor firing domain after firing transition t_f.\n * Implements the 5-step Berthomieu-Diaz successor formula.\n */\n fireTransition(\n firedClock: number,\n newClockNames: readonly string[],\n newLowerBounds: number[],\n newUpperBounds: number[],\n persistentClocks: number[],\n ): DBM {\n if (this._empty) return this;\n\n const n = this.clockNames.length;\n if (firedClock < 0 || firedClock >= n) {\n throw new Error(`Invalid fired clock index: ${firedClock}`);\n }\n\n // Step 1: Intersect with \"t_f fires first\" constraint\n const constrained = new Float64Array(this.bounds);\n const dim = this.dim;\n const f = firedClock + 1;\n\n for (let i = 0; i < n; i++) {\n if (i !== firedClock) {\n const idx = i + 1;\n const pos = f * dim + idx;\n constrained[pos] = Math.min(constrained[pos]!, 0);\n }\n }\n\n // Step 2: Canonicalize\n if (!canonicalizeInPlace(constrained, dim)) {\n return DBM.empty([]);\n }\n\n // Steps 3 & 4: Substitution and Elimination\n const newN = persistentClocks.length + newClockNames.length;\n const newDim = newN + 1;\n const newBounds = makeMatrix(newDim, Infinity);\n\n // Copy persistent clocks with transformed bounds\n for (let pi = 0; pi < persistentClocks.length; pi++) {\n const oldIdx = persistentClocks[pi]! + 1;\n const newIdx = pi + 1;\n\n const upper = constrained[oldIdx * dim + f]!;\n const lower = Math.max(0, -constrained[f * dim + oldIdx]!);\n\n newBounds[0 * newDim + newIdx] = -lower;\n newBounds[newIdx * newDim + 0] = upper;\n\n // Inter-clock constraints between persistent transitions (preserved)\n for (let pj = 0; pj < persistentClocks.length; pj++) {\n const oldJ = persistentClocks[pj]! + 1;\n const newJ = pj + 1;\n newBounds[newIdx * newDim + newJ] = constrained[oldIdx * dim + oldJ]!;\n }\n }\n\n // Step 5: Add fresh intervals for newly enabled transitions\n const offset = persistentClocks.length;\n for (let k = 0; k < newClockNames.length; k++) {\n const idx = offset + k + 1;\n newBounds[0 * newDim + idx] = -newLowerBounds[k]!;\n newBounds[idx * newDim + 0] = newUpperBounds[k]!;\n }\n\n // Build new clock names\n const allNames: string[] = [];\n for (const idx of persistentClocks) {\n allNames.push(this.clockNames[idx]!);\n }\n allNames.push(...newClockNames);\n\n // Step 6: Final canonicalization\n return new DBM(newBounds, newDim, allNames, false).canonicalize();\n }\n\n /** Lets time pass: set all lower bounds to 0. */\n letTimePass(): DBM {\n if (this._empty) return this;\n\n const newBounds = new Float64Array(this.bounds);\n for (let i = 1; i < this.dim; i++) {\n newBounds[0 * this.dim + i] = 0;\n }\n\n return new DBM(newBounds, this.dim, this.clockNames, false).canonicalize();\n }\n\n private canonicalize(): DBM {\n if (this._empty) return this;\n\n const canon = new Float64Array(this.bounds);\n if (!canonicalizeInPlace(canon, this.dim)) {\n return DBM.empty(this.clockNames);\n }\n return new DBM(canon, this.dim, this.clockNames, false);\n }\n\n equals(other: DBM): boolean {\n if (this === other) return true;\n if (this._empty && other._empty) return true;\n if (this._empty || other._empty) return false;\n if (this.clockNames.length !== other.clockNames.length) return false;\n for (let i = 0; i < this.clockNames.length; i++) {\n if (this.clockNames[i] !== other.clockNames[i]) return false;\n }\n if (this.bounds.length !== other.bounds.length) return false;\n for (let i = 0; i < this.bounds.length; i++) {\n if (Math.abs(this.bounds[i]! - other.bounds[i]!) > EPSILON) return false;\n }\n return true;\n }\n\n toString(): string {\n if (this._empty) return 'DBM[empty]';\n const parts: string[] = [];\n for (let i = 0; i < this.clockNames.length; i++) {\n const lo = formatBound(this.getLowerBound(i));\n const hi = formatBound(this.getUpperBound(i));\n parts.push(`${this.clockNames[i]}:[${lo},${hi}]`);\n }\n return `DBM{${parts.join(', ')}}`;\n }\n}\n\nfunction makeMatrix(dim: number, fill: number): Float64Array {\n const m = new Float64Array(dim * dim).fill(fill);\n for (let i = 0; i < dim; i++) {\n m[i * dim + i] = 0;\n }\n return m;\n}\n\nfunction canonicalizeInPlace(dbm: Float64Array, dim: number): boolean {\n for (let k = 0; k < dim; k++) {\n for (let i = 0; i < dim; i++) {\n for (let j = 0; j < dim; j++) {\n const ik = dbm[i * dim + k]!;\n const kj = dbm[k * dim + j]!;\n if (ik < Infinity && kj < Infinity) {\n const via = ik + kj;\n if (via < dbm[i * dim + j]!) {\n dbm[i * dim + j] = via;\n }\n }\n }\n }\n }\n for (let i = 0; i < dim; i++) {\n if (dbm[i * dim + i]! < -EPSILON) return false;\n }\n return true;\n}\n\nfunction formatBound(b: number): string {\n if (b >= Infinity / 2) return '\\u221e';\n if (b === Math.trunc(b)) return String(b);\n return b.toFixed(3);\n}\n","import type { Transition } from '../../core/transition.js';\nimport type { MarkingState } from '../marking-state.js';\nimport type { DBM } from './dbm.js';\n\n/**\n * A State Class in Time Petri Net analysis.\n *\n * A state class is a pair (M, D) where M is a marking and D is a firing domain (DBM).\n * State classes provide a finite abstraction of the infinite state space of Time Petri Nets.\n */\nexport class StateClass {\n readonly marking: MarkingState;\n readonly firingDomain: DBM;\n readonly enabledTransitions: readonly Transition[];\n\n constructor(marking: MarkingState, firingDomain: DBM, enabledTransitions: readonly Transition[]) {\n this.marking = marking;\n this.firingDomain = firingDomain;\n this.enabledTransitions = [...enabledTransitions];\n }\n\n isEmpty(): boolean {\n return this.firingDomain.isEmpty();\n }\n\n canFire(transition: Transition): boolean {\n const idx = this.enabledTransitions.indexOf(transition);\n if (idx < 0) return false;\n return this.firingDomain.getUpperBound(idx) >= 0;\n }\n\n transitionIndex(transition: Transition): number {\n return this.enabledTransitions.indexOf(transition);\n }\n\n equals(other: StateClass): boolean {\n if (this === other) return true;\n return this.marking.toString() === other.marking.toString()\n && this.firingDomain.equals(other.firingDomain);\n }\n\n toString(): string {\n return `StateClass{${this.marking}, ${this.firingDomain}}`;\n }\n}\n","/**\n * Strongly Connected Component analysis using Tarjan's algorithm.\n * Generic over node type T. Uses a key function for Map-based lookups.\n */\n\n/** Computes all SCCs in a graph. O(V + E) via Tarjan's algorithm. */\nexport function computeSCCs<T>(\n nodes: Iterable<T>,\n successors: (node: T) => Iterable<T>,\n): Set<T>[] {\n const nodeArray = [...nodes];\n const indexMap = new Map<T, number>();\n const lowlink = new Map<T, number>();\n const onStack = new Set<T>();\n const stack: T[] = [];\n const sccs: Set<T>[] = [];\n let index = 0;\n\n function strongConnect(v: T): void {\n indexMap.set(v, index);\n lowlink.set(v, index);\n index++;\n stack.push(v);\n onStack.add(v);\n\n for (const w of successors(v)) {\n if (!indexMap.has(w)) {\n strongConnect(w);\n lowlink.set(v, Math.min(lowlink.get(v)!, lowlink.get(w)!));\n } else if (onStack.has(w)) {\n lowlink.set(v, Math.min(lowlink.get(v)!, indexMap.get(w)!));\n }\n }\n\n if (lowlink.get(v) === indexMap.get(v)) {\n const scc = new Set<T>();\n let w: T;\n do {\n w = stack.pop()!;\n onStack.delete(w);\n scc.add(w);\n } while (w !== v);\n sccs.push(scc);\n }\n }\n\n for (const node of nodeArray) {\n if (!indexMap.has(node)) {\n strongConnect(node);\n }\n }\n\n return sccs;\n}\n\n/** Finds terminal (bottom) SCCs — SCCs with no outgoing edges to other SCCs. */\nexport function findTerminalSCCs<T>(\n nodes: Iterable<T>,\n successors: (node: T) => Iterable<T>,\n): Set<T>[] {\n const allSCCs = computeSCCs(nodes, successors);\n\n const terminal: Set<T>[] = [];\n for (const scc of allSCCs) {\n let isTerminal = true;\n for (const node of scc) {\n for (const succ of successors(node)) {\n if (!scc.has(succ)) {\n isTerminal = false;\n break;\n }\n }\n if (!isTerminal) break;\n }\n if (isTerminal) {\n terminal.push(scc);\n }\n }\n\n return terminal;\n}\n","import type { Place } from '../../core/place.js';\nimport type { EnvironmentPlace } from '../../core/place.js';\nimport type { In } from '../../core/in.js';\nimport type { Transition } from '../../core/transition.js';\nimport type { PetriNet } from '../../core/petri-net.js';\nimport { earliest, latest } from '../../core/timing.js';\nimport { enumerateBranches } from '../../core/out.js';\nimport { MarkingState } from '../marking-state.js';\nimport { DBM } from './dbm.js';\nimport { StateClass } from './state-class.js';\nimport type { EnvironmentAnalysisMode } from './environment-analysis-mode.js';\nimport { ignore } from './environment-analysis-mode.js';\n\n/** Edge that tracks which XOR branch was taken. */\nexport interface BranchEdge {\n readonly branchIndex: number;\n readonly target: StateClass;\n}\n\ninterface VirtualTransition {\n readonly transition: Transition;\n readonly branchIndex: number;\n readonly outputPlaces: ReadonlySet<Place<any>>;\n}\n\n/**\n * State Class Graph for Time Petri Net analysis.\n *\n * Implements the Berthomieu-Diaz (1991) algorithm for computing the state class\n * graph of a bounded Time Petri Net.\n */\nexport class StateClassGraph {\n readonly net: PetriNet;\n readonly initialClass: StateClass;\n private readonly _stateClasses: StateClass[];\n private readonly _transitions: Map<StateClass, Map<Transition, BranchEdge[]>>;\n private readonly _successors: Map<StateClass, Set<StateClass>>;\n private readonly _predecessors: Map<StateClass, Set<StateClass>>;\n private readonly _complete: boolean;\n\n private constructor(\n net: PetriNet,\n initialClass: StateClass,\n stateClasses: StateClass[],\n transitions: Map<StateClass, Map<Transition, BranchEdge[]>>,\n complete: boolean,\n ) {\n this.net = net;\n this.initialClass = initialClass;\n this._stateClasses = stateClasses;\n this._transitions = transitions;\n this._complete = complete;\n\n // Build successor/predecessor maps\n this._successors = new Map();\n this._predecessors = new Map();\n for (const sc of stateClasses) {\n this._successors.set(sc, new Set());\n this._predecessors.set(sc, new Set());\n }\n for (const [from, tMap] of transitions) {\n for (const edges of tMap.values()) {\n for (const edge of edges) {\n this._successors.get(from)!.add(edge.target);\n this._predecessors.get(edge.target)!.add(from);\n }\n }\n }\n }\n\n /** Builds the state class graph for a Time Petri Net. */\n static build(\n net: PetriNet,\n initialMarking: MarkingState,\n maxClasses: number,\n environmentPlaces?: Set<EnvironmentPlace<any>>,\n environmentMode?: EnvironmentAnalysisMode,\n ): StateClassGraph {\n const envMode = environmentMode ?? ignore();\n const envPlaces = new Set<Place<any>>();\n if (environmentPlaces) {\n for (const ep of environmentPlaces) {\n envPlaces.add(ep.place);\n }\n }\n\n const enabledTransitions = findEnabledTransitions(net, initialMarking, envPlaces, envMode);\n const clockNames = enabledTransitions.map(t => t.name);\n const lowerBounds = enabledTransitions.map(t => earliest(t.timing) / 1000);\n const upperBounds = enabledTransitions.map(t => latest(t.timing) / 1000);\n\n let initialDBM = DBM.create(clockNames, lowerBounds, upperBounds);\n initialDBM = initialDBM.letTimePass();\n const initialClass = new StateClass(initialMarking, initialDBM, enabledTransitions);\n\n // BFS exploration\n const stateClasses: StateClass[] = [initialClass];\n const stateClassSet = new Set<string>([classKey(initialClass)]);\n const classMap = new Map<string, StateClass>([[classKey(initialClass), initialClass]]);\n const transitionMap = new Map<StateClass, Map<Transition, BranchEdge[]>>();\n transitionMap.set(initialClass, new Map());\n const queue: StateClass[] = [initialClass];\n let complete = true;\n\n while (queue.length > 0) {\n if (stateClasses.length >= maxClasses) {\n complete = false;\n break;\n }\n\n const current = queue.shift()!;\n\n for (const transition of current.enabledTransitions) {\n const virtualTransitions = expandTransition(transition);\n\n for (const vt of virtualTransitions) {\n const successor = computeSuccessor(net, current, vt, envPlaces, envMode);\n if (successor === null || successor.isEmpty()) continue;\n\n // Add edge with branch index\n const tEdges = transitionMap.get(current)!;\n if (!tEdges.has(transition)) tEdges.set(transition, []);\n tEdges.get(transition)!.push({ branchIndex: vt.branchIndex, target: successor });\n\n // Dedup state classes by key\n const key = classKey(successor);\n if (!stateClassSet.has(key)) {\n stateClassSet.add(key);\n classMap.set(key, successor);\n stateClasses.push(successor);\n transitionMap.set(successor, new Map());\n queue.push(successor);\n } else {\n // Rewrite edge target to existing canonical instance\n const canonical = classMap.get(key)!;\n if (canonical !== successor) {\n const edges = tEdges.get(transition)!;\n edges[edges.length - 1] = { branchIndex: vt.branchIndex, target: canonical };\n }\n }\n }\n }\n }\n\n return new StateClassGraph(net, initialClass, stateClasses, transitionMap, complete);\n }\n\n stateClasses(): readonly StateClass[] {\n return this._stateClasses;\n }\n\n size(): number {\n return this._stateClasses.length;\n }\n\n isComplete(): boolean {\n return this._complete;\n }\n\n successors(sc: StateClass): Set<StateClass> {\n return this._successors.get(sc) ?? new Set();\n }\n\n predecessors(sc: StateClass): Set<StateClass> {\n return this._predecessors.get(sc) ?? new Set();\n }\n\n /** Returns all outgoing transitions with their branch edges. */\n outgoingBranchEdges(sc: StateClass): Map<Transition, BranchEdge[]> {\n return this._transitions.get(sc) ?? new Map();\n }\n\n /** Returns the branch edges for a specific transition from a state class. */\n branchEdges(sc: StateClass, transition: Transition): BranchEdge[] {\n const map = this._transitions.get(sc);\n if (!map) return [];\n return map.get(transition) ?? [];\n }\n\n /** Returns all transitions that are enabled from a state class. */\n enabledTransitions(sc: StateClass): Set<Transition> {\n const map = this._transitions.get(sc);\n if (!map) return new Set();\n return new Set(map.keys());\n }\n\n /** Finds all state classes with a given marking. */\n classesWithMarking(marking: MarkingState): StateClass[] {\n const key = marking.toString();\n return this._stateClasses.filter(sc => sc.marking.toString() === key);\n }\n\n /** Checks if a marking is reachable. */\n isReachable(marking: MarkingState): boolean {\n const key = marking.toString();\n return this._stateClasses.some(sc => sc.marking.toString() === key);\n }\n\n /** Gets all reachable markings. */\n reachableMarkings(): Set<string> {\n const markings = new Set<string>();\n for (const sc of this._stateClasses) {\n markings.add(sc.marking.toString());\n }\n return markings;\n }\n\n /** Counts edges in the graph (each branch edge counts separately). */\n edgeCount(): number {\n let count = 0;\n for (const map of this._transitions.values()) {\n for (const edges of map.values()) {\n count += edges.length;\n }\n }\n return count;\n }\n\n toString(): string {\n return `StateClassGraph[classes=${this.size()}, edges=${this.edgeCount()}, complete=${this._complete}]`;\n }\n}\n\nfunction classKey(sc: StateClass): string {\n return `${sc.marking.toString()}|${sc.firingDomain.toString()}`;\n}\n\nfunction expandTransition(t: Transition): VirtualTransition[] {\n let branches: ReadonlyArray<ReadonlySet<Place<any>>>;\n\n if (t.outputSpec !== null) {\n branches = enumerateBranches(t.outputSpec);\n } else {\n branches = [new Set()];\n }\n\n return branches.map((outputPlaces, i) => ({\n transition: t,\n branchIndex: i,\n outputPlaces: outputPlaces as ReadonlySet<Place<any>>,\n }));\n}\n\nfunction computeSuccessor(\n net: PetriNet,\n current: StateClass,\n fired: VirtualTransition,\n environmentPlaces: Set<Place<any>>,\n environmentMode: EnvironmentAnalysisMode,\n): StateClass | null {\n const transition = fired.transition;\n\n // 1. Compute new marking\n const newMarking = fireTransition(current.marking, transition, fired.outputPlaces, environmentPlaces, environmentMode);\n\n // 2. Determine persistent and newly enabled transitions\n const newEnabledAll = findEnabledTransitions(net, newMarking, environmentPlaces, environmentMode);\n\n const persistent: Transition[] = [];\n const persistentIndices: number[] = [];\n for (let i = 0; i < current.enabledTransitions.length; i++) {\n const t = current.enabledTransitions[i]!;\n if (t !== transition && newEnabledAll.includes(t)) {\n persistent.push(t);\n persistentIndices.push(i);\n }\n }\n\n const newlyEnabled: Transition[] = [];\n for (const t of newEnabledAll) {\n if (!persistent.includes(t)) {\n newlyEnabled.push(t);\n }\n }\n\n // 3. Compute successor DBM\n const firedIdx = current.transitionIndex(transition);\n const newClockNames = newlyEnabled.map(t => t.name);\n const newLowerBounds = newlyEnabled.map(t => earliest(t.timing) / 1000);\n const newUpperBounds = newlyEnabled.map(t => latest(t.timing) / 1000);\n\n let newDBM = current.firingDomain.fireTransition(\n firedIdx,\n newClockNames,\n newLowerBounds,\n newUpperBounds,\n persistentIndices,\n );\n\n newDBM = newDBM.letTimePass();\n\n const allEnabled = [...persistent, ...newlyEnabled];\n return new StateClass(newMarking, newDBM, allEnabled);\n}\n\nfunction findEnabledTransitions(\n net: PetriNet,\n marking: MarkingState,\n environmentPlaces: Set<Place<any>>,\n environmentMode: EnvironmentAnalysisMode,\n): Transition[] {\n const enabled: Transition[] = [];\n for (const transition of net.transitions) {\n if (isEnabled(transition, marking, environmentPlaces, environmentMode)) {\n enabled.push(transition);\n }\n }\n return enabled;\n}\n\nfunction isEnabled(\n transition: Transition,\n marking: MarkingState,\n environmentPlaces: Set<Place<any>>,\n environmentMode: EnvironmentAnalysisMode,\n): boolean {\n for (const spec of transition.inputSpecs) {\n const required = inputRequiredCount(spec);\n if (!checkPlaceEnabled(spec.place, required, marking, environmentPlaces, environmentMode)) {\n return false;\n }\n }\n\n for (const arc of transition.reads) {\n if (!checkPlaceEnabled(arc.place, 1, marking, environmentPlaces, environmentMode)) {\n return false;\n }\n }\n\n for (const arc of transition.inhibitors) {\n if (marking.hasTokens(arc.place)) {\n return false;\n }\n }\n\n return true;\n}\n\nfunction inputRequiredCount(spec: In): number {\n switch (spec.type) {\n case 'one': return 1;\n case 'exactly': return spec.count;\n case 'all': return 1;\n case 'at-least': return spec.minimum;\n }\n}\n\nfunction inputConsumeCount(spec: In): number {\n switch (spec.type) {\n case 'one': return 1;\n case 'exactly': return spec.count;\n case 'all': return 1; // Analysis: consume minimum (1 token)\n case 'at-least': return spec.minimum;\n }\n}\n\nfunction checkPlaceEnabled(\n place: Place<any>,\n required: number,\n marking: MarkingState,\n environmentPlaces: Set<Place<any>>,\n environmentMode: EnvironmentAnalysisMode,\n): boolean {\n if (!environmentPlaces.has(place)) {\n return marking.tokens(place) >= required;\n }\n\n switch (environmentMode.type) {\n case 'always-available': return true;\n case 'bounded': return required <= environmentMode.maxTokens;\n case 'ignore': return marking.tokens(place) >= required;\n }\n}\n\nfunction fireTransition(\n marking: MarkingState,\n transition: Transition,\n outputPlaces: ReadonlySet<Place<any>>,\n environmentPlaces: Set<Place<any>>,\n environmentMode: EnvironmentAnalysisMode,\n): MarkingState {\n const builder = MarkingState.builder().copyFrom(marking);\n\n // Consume from inputs\n for (const spec of transition.inputSpecs) {\n const toConsume = inputConsumeCount(spec);\n consumeFromPlace(builder, spec.place, toConsume, environmentPlaces, environmentMode);\n }\n\n // Reset places\n for (const arc of transition.resets) {\n const current = marking.tokens(arc.place);\n if (current > 0) {\n builder.removeTokens(arc.place, current);\n }\n }\n\n // Produce to outputs\n for (const place of outputPlaces) {\n builder.addTokens(place, 1);\n }\n\n return builder.build();\n}\n\nfunction consumeFromPlace(\n builder: ReturnType<typeof MarkingState.builder>,\n place: Place<any>,\n count: number,\n environmentPlaces: Set<Place<any>>,\n environmentMode: EnvironmentAnalysisMode,\n): void {\n if (!environmentPlaces.has(place)) {\n builder.removeTokens(place, count);\n return;\n }\n if (environmentMode.type === 'ignore') {\n builder.removeTokens(place, count);\n }\n}\n","import type { Place } from '../../core/place.js';\nimport type { EnvironmentPlace } from '../../core/place.js';\nimport type { Transition } from '../../core/transition.js';\nimport type { PetriNet } from '../../core/petri-net.js';\nimport { enumerateBranches } from '../../core/out.js';\nimport { MarkingState } from '../marking-state.js';\nimport { StateClassGraph } from './state-class-graph.js';\nimport type { StateClass } from './state-class.js';\nimport { computeSCCs, findTerminalSCCs } from './scc-analyzer.js';\nimport type { EnvironmentAnalysisMode } from './environment-analysis-mode.js';\nimport { ignore } from './environment-analysis-mode.js';\n\n/** Result of liveness analysis. */\nexport interface LivenessResult {\n readonly stateClassGraph: StateClassGraph;\n readonly allSCCs: Set<StateClass>[];\n readonly terminalSCCs: Set<StateClass>[];\n readonly goalClasses: Set<StateClass>;\n readonly canReachGoal: Set<StateClass>;\n readonly isGoalLive: boolean;\n readonly isL4Live: boolean;\n readonly isComplete: boolean;\n readonly report: string;\n}\n\n/** Information about XOR branch coverage for a single transition. */\nexport interface XorBranchInfo {\n readonly totalBranches: number;\n readonly takenBranches: Set<number>;\n readonly untakenBranches: Set<number>;\n readonly branchOutputs: ReadonlyArray<ReadonlySet<Place<any>>>;\n}\n\n/** Result of XOR branch analysis. */\nexport interface XorBranchAnalysis {\n readonly transitionBranches: Map<Transition, XorBranchInfo>;\n unreachableBranches(): Map<Transition, Set<number>>;\n isXorComplete(): boolean;\n report(): string;\n}\n\n/**\n * Formal analyzer for Time Petri Nets using the State Class Graph method.\n * Implements Berthomieu-Diaz (1991) analysis.\n */\nexport class TimePetriNetAnalyzer {\n private readonly net: PetriNet;\n private readonly initialMarking: MarkingState;\n private readonly goalPlaces: Set<Place<any>>;\n private readonly maxClasses: number;\n private readonly environmentPlaces: Set<EnvironmentPlace<any>>;\n private readonly environmentMode: EnvironmentAnalysisMode;\n\n /** @internal Called by builder — use `TimePetriNetAnalyzer.forNet()` instead. */\n static create(\n net: PetriNet,\n initialMarking: MarkingState,\n goalPlaces: Set<Place<any>>,\n maxClasses: number,\n environmentPlaces: Set<EnvironmentPlace<any>>,\n environmentMode: EnvironmentAnalysisMode,\n ): TimePetriNetAnalyzer {\n return new TimePetriNetAnalyzer(net, initialMarking, goalPlaces, maxClasses, environmentPlaces, environmentMode);\n }\n\n private constructor(\n net: PetriNet,\n initialMarking: MarkingState,\n goalPlaces: Set<Place<any>>,\n maxClasses: number,\n environmentPlaces: Set<EnvironmentPlace<any>>,\n environmentMode: EnvironmentAnalysisMode,\n ) {\n this.net = net;\n this.initialMarking = initialMarking;\n this.goalPlaces = goalPlaces;\n this.maxClasses = maxClasses;\n this.environmentPlaces = environmentPlaces;\n this.environmentMode = environmentMode;\n }\n\n static forNet(net: PetriNet): TimePetriNetAnalyzerBuilder {\n return new TimePetriNetAnalyzerBuilder(net);\n }\n\n /** Performs formal liveness analysis. */\n analyze(): LivenessResult {\n const report: string[] = [];\n report.push('=== TIME PETRI NET FORMAL ANALYSIS ===\\n');\n report.push(`Method: State Class Graph (Berthomieu-Diaz 1991)`);\n report.push(`Net: ${this.net.name}`);\n report.push(`Places: ${this.net.places.size}`);\n report.push(`Transitions: ${this.net.transitions.size}`);\n report.push(`Goal places: [${[...this.goalPlaces].map(p => p.name).join(', ')}]\\n`);\n\n // Phase 1: Build State Class Graph\n report.push('Phase 1: Building State Class Graph...');\n if (this.environmentPlaces.size > 0) {\n report.push(` Environment places: ${this.environmentPlaces.size}`);\n report.push(` Environment mode: ${this.environmentMode.type}`);\n }\n const scg = StateClassGraph.build(this.net, this.initialMarking, this.maxClasses, this.environmentPlaces, this.environmentMode);\n report.push(` State classes: ${scg.size()}`);\n report.push(` Edges: ${scg.edgeCount()}`);\n report.push(` Complete: ${scg.isComplete() ? 'YES' : 'NO (truncated)'}`);\n\n if (!scg.isComplete()) {\n report.push(` WARNING: State class graph truncated at ${this.maxClasses} classes. Analysis may be incomplete.`);\n }\n report.push('');\n\n // Phase 2: Identify goal state classes\n report.push('Phase 2: Identifying goal state classes...');\n const goalClasses = new Set<StateClass>();\n for (const sc of scg.stateClasses()) {\n if (sc.marking.hasTokensInAny(this.goalPlaces)) {\n goalClasses.add(sc);\n }\n }\n report.push(` Goal state classes: ${goalClasses.size}\\n`);\n\n // Phase 3: Compute SCCs\n report.push('Phase 3: Computing Strongly Connected Components...');\n const successorFn = (sc: StateClass) => scg.successors(sc);\n const allSCCs = computeSCCs(scg.stateClasses(), successorFn);\n const terminalSCCs = findTerminalSCCs(scg.stateClasses(), successorFn);\n\n report.push(` Total SCCs: ${allSCCs.length}`);\n report.push(` Terminal SCCs: ${terminalSCCs.length}\\n`);\n\n // Phase 4: Check goal liveness\n report.push('Phase 4: Verifying Goal Liveness...');\n report.push(' Property: From every reachable state, a goal state is reachable');\n\n const terminalSCCsWithGoal: Set<StateClass>[] = [];\n const terminalSCCsWithoutGoal: Set<StateClass>[] = [];\n\n for (const scc of terminalSCCs) {\n let hasGoal = false;\n for (const sc of scc) {\n if (goalClasses.has(sc)) { hasGoal = true; break; }\n }\n (hasGoal ? terminalSCCsWithGoal : terminalSCCsWithoutGoal).push(scc);\n }\n\n report.push(` Terminal SCCs with goal: ${terminalSCCsWithGoal.length}`);\n report.push(` Terminal SCCs without goal: ${terminalSCCsWithoutGoal.length}`);\n\n const canReachGoal = computeBackwardReachability(scg, goalClasses);\n const statesNotReachingGoal = scg.size() - canReachGoal.size;\n\n report.push(` States that can reach goal: ${canReachGoal.size}/${scg.size()}\\n`);\n\n const isGoalLive = terminalSCCsWithoutGoal.length === 0 && statesNotReachingGoal === 0;\n\n // Phase 5: Check classical liveness (L4)\n report.push('Phase 5: Verifying Classical Liveness (L4)...');\n report.push(' Property: Every transition can fire from every reachable marking');\n\n const allTransitions = new Set(this.net.transitions);\n const terminalSCCsMissingTransitions: Set<StateClass>[] = [];\n\n for (const scc of terminalSCCs) {\n const transitionsInSCC = new Set<Transition>();\n for (const sc of scc) {\n for (const t of scg.enabledTransitions(sc)) {\n const edges = scg.branchEdges(sc, t);\n for (const edge of edges) {\n if (scc.has(edge.target)) {\n transitionsInSCC.add(t);\n }\n }\n }\n }\n let missingAny = false;\n for (const t of allTransitions) {\n if (!transitionsInSCC.has(t)) { missingAny = true; break; }\n }\n if (missingAny) {\n terminalSCCsMissingTransitions.push(scc);\n const missing = [...allTransitions].filter(t => !transitionsInSCC.has(t));\n report.push(` Terminal SCC missing transitions: [${missing.map(t => t.name).join(', ')}]`);\n }\n }\n\n const isL4Live = terminalSCCsMissingTransitions.length === 0 && scg.isComplete();\n\n // Summary\n report.push('\\n=== ANALYSIS RESULT ===\\n');\n\n if (isGoalLive && scg.isComplete()) {\n report.push('GOAL LIVENESS VERIFIED');\n report.push(' From every reachable state class, a goal marking is reachable.');\n } else if (isGoalLive && !scg.isComplete()) {\n report.push('GOAL LIVENESS LIKELY (incomplete proof)');\n } else {\n report.push('GOAL LIVENESS VIOLATION');\n if (terminalSCCsWithoutGoal.length > 0) {\n report.push(` ${terminalSCCsWithoutGoal.length} terminal SCC(s) have no goal state.`);\n }\n if (statesNotReachingGoal > 0) {\n report.push(` ${statesNotReachingGoal} state class(es) cannot reach goal.`);\n }\n }\n\n report.push('');\n\n if (isL4Live) {\n report.push('CLASSICAL LIVENESS (L4) VERIFIED');\n } else {\n report.push('CLASSICAL LIVENESS (L4) NOT VERIFIED');\n if (terminalSCCsMissingTransitions.length > 0) {\n report.push(\" Some terminal SCCs don't contain all transitions.\");\n }\n if (!scg.isComplete()) {\n report.push(' (State class graph incomplete - cannot prove L4)');\n }\n }\n\n return {\n stateClassGraph: scg,\n allSCCs,\n terminalSCCs,\n goalClasses,\n canReachGoal,\n isGoalLive,\n isL4Live,\n isComplete: scg.isComplete(),\n report: report.join('\\n'),\n };\n }\n\n /** Analyzes XOR branch coverage for a built state class graph. */\n static analyzeXorBranches(scg: StateClassGraph): XorBranchAnalysis {\n const result = new Map<Transition, XorBranchInfo>();\n\n for (const transition of scg.net.transitions) {\n if (transition.outputSpec === null) continue;\n\n const allBranches = enumerateBranches(transition.outputSpec);\n if (allBranches.length <= 1) continue;\n\n const takenBranches = new Set<number>();\n for (const sc of scg.stateClasses()) {\n const edges = scg.branchEdges(sc, transition);\n for (const edge of edges) {\n takenBranches.add(edge.branchIndex);\n }\n }\n\n const untakenBranches = new Set<number>();\n for (let i = 0; i < allBranches.length; i++) {\n if (!takenBranches.has(i)) untakenBranches.add(i);\n }\n\n result.set(transition, {\n totalBranches: allBranches.length,\n takenBranches,\n untakenBranches,\n branchOutputs: allBranches,\n });\n }\n\n return createXorBranchAnalysis(result);\n }\n}\n\nfunction createXorBranchAnalysis(transitionBranches: Map<Transition, XorBranchInfo>): XorBranchAnalysis {\n return {\n transitionBranches,\n unreachableBranches(): Map<Transition, Set<number>> {\n const result = new Map<Transition, Set<number>>();\n for (const [t, info] of transitionBranches) {\n if (info.untakenBranches.size > 0) {\n result.set(t, info.untakenBranches);\n }\n }\n return result;\n },\n isXorComplete(): boolean {\n for (const info of transitionBranches.values()) {\n if (info.untakenBranches.size > 0) return false;\n }\n return true;\n },\n report(): string {\n if (transitionBranches.size === 0) return 'No XOR transitions in net.';\n\n const lines: string[] = [];\n lines.push('XOR Branch Coverage Analysis');\n lines.push('============================\\n');\n\n for (const [t, info] of transitionBranches) {\n lines.push(`Transition: ${t.name}`);\n lines.push(` Branches: ${info.totalBranches}`);\n lines.push(` Taken: [${[...info.takenBranches].join(', ')}]`);\n\n if (info.untakenBranches.size > 0) {\n lines.push(` UNREACHABLE: [${[...info.untakenBranches].join(', ')}]`);\n for (const idx of info.untakenBranches) {\n const places = [...info.branchOutputs[idx]!].map(p => p.name).join(', ');\n lines.push(` Branch ${idx} outputs: [${places}]`);\n }\n } else {\n lines.push(' All branches reachable');\n }\n lines.push('');\n }\n\n if (this.isXorComplete()) {\n lines.push('RESULT: All XOR branches are reachable.');\n } else {\n lines.push('RESULT: Some XOR branches are unreachable!');\n }\n\n return lines.join('\\n');\n },\n };\n}\n\nfunction computeBackwardReachability(scg: StateClassGraph, goals: Set<StateClass>): Set<StateClass> {\n const reachable = new Set(goals);\n const queue = [...goals];\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n for (const pred of scg.predecessors(current)) {\n if (!reachable.has(pred)) {\n reachable.add(pred);\n queue.push(pred);\n }\n }\n }\n\n return reachable;\n}\n\n/** Builder for TimePetriNetAnalyzer. */\nexport class TimePetriNetAnalyzerBuilder {\n private readonly net: PetriNet;\n private _initialMarking: MarkingState = MarkingState.empty();\n private readonly _goalPlaces = new Set<Place<any>>();\n private _maxClasses = 100_000;\n private readonly _environmentPlaces = new Set<EnvironmentPlace<any>>();\n private _environmentMode: EnvironmentAnalysisMode = ignore();\n\n constructor(net: PetriNet) {\n this.net = net;\n }\n\n initialMarking(marking: MarkingState): this {\n this._initialMarking = marking;\n return this;\n }\n\n goalPlaces(...places: Place<any>[]): this {\n for (const p of places) this._goalPlaces.add(p);\n return this;\n }\n\n maxClasses(max: number): this {\n this._maxClasses = max;\n return this;\n }\n\n environmentPlaces(...places: EnvironmentPlace<any>[]): this {\n for (const ep of places) this._environmentPlaces.add(ep);\n return this;\n }\n\n environmentMode(mode: EnvironmentAnalysisMode): this {\n this._environmentMode = mode;\n return this;\n }\n\n build(): TimePetriNetAnalyzer {\n if (this._goalPlaces.size === 0) {\n throw new Error('At least one goal place must be specified');\n }\n return TimePetriNetAnalyzer.create(\n this.net,\n this._initialMarking,\n this._goalPlaces,\n this._maxClasses,\n this._environmentPlaces,\n this._environmentMode,\n );\n }\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/timing.ts"],"sourcesContent":["/**\n * Firing timing specification for transitions.\n *\n * Based on classical Time Petri Net (TPN) semantics:\n * - Transition CANNOT fire before earliest time (lower bound)\n * - Transition MUST fire by deadline OR become disabled (upper bound)\n *\n * All durations are in milliseconds.\n */\nexport type Timing = TimingImmediate | TimingDeadline | TimingDelayed | TimingWindow | TimingExact;\n\nexport interface TimingImmediate {\n readonly type: 'immediate';\n}\n\nexport interface TimingDeadline {\n readonly type: 'deadline';\n /** Deadline in milliseconds. Must be positive. */\n readonly byMs: number;\n}\n\nexport interface TimingDelayed {\n readonly type: 'delayed';\n /** Minimum delay in milliseconds. Must be non-negative. */\n readonly afterMs: number;\n}\n\nexport interface TimingWindow {\n readonly type: 'window';\n /** Earliest firing time in milliseconds. Must be non-negative. */\n readonly earliestMs: number;\n /** Latest firing time in milliseconds. Must be >= earliestMs. */\n readonly latestMs: number;\n}\n\nexport interface TimingExact {\n readonly type: 'exact';\n /** Exact firing time in milliseconds. Must be non-negative. */\n readonly atMs: number;\n}\n\n/** ~100 years in milliseconds, used for \"unconstrained\" intervals. */\nexport const MAX_DURATION_MS = 365 * 100 * 24 * 60 * 60 * 1000;\n\n// ==================== Factory Functions ====================\n\n/** Immediate firing: can fire as soon as enabled, no deadline. [0, inf) */\nexport function immediate(): TimingImmediate {\n return { type: 'immediate' };\n}\n\n/** Immediate with deadline: can fire immediately, must fire by deadline. [0, by] */\nexport function deadline(byMs: number): TimingDeadline {\n if (byMs <= 0) {\n throw new Error(`Deadline must be positive: ${byMs}`);\n }\n return { type: 'deadline', byMs };\n}\n\n/** Delayed firing: must wait, then can fire anytime. [after, inf) */\nexport function delayed(afterMs: number): TimingDelayed {\n if (afterMs < 0) {\n throw new Error(`Delay must be non-negative: ${afterMs}`);\n }\n return { type: 'delayed', afterMs };\n}\n\n/** Time window: can fire within [earliest, latest]. */\nexport function window(earliestMs: number, latestMs: number): TimingWindow {\n if (earliestMs < 0) {\n throw new Error(`Earliest must be non-negative: ${earliestMs}`);\n }\n if (latestMs < earliestMs) {\n throw new Error(`Latest (${latestMs}) must be >= earliest (${earliestMs})`);\n }\n return { type: 'window', earliestMs, latestMs };\n}\n\n/** Exact timing: fires at precisely the specified time. [at, at] */\nexport function exact(atMs: number): TimingExact {\n if (atMs < 0) {\n throw new Error(`Exact time must be non-negative: ${atMs}`);\n }\n return { type: 'exact', atMs };\n}\n\n// ==================== Query Functions ====================\n\n/** Returns the earliest time (ms) the transition can fire after enabling. */\nexport function earliest(timing: Timing): number {\n switch (timing.type) {\n case 'immediate': return 0;\n case 'deadline': return 0;\n case 'delayed': return timing.afterMs;\n case 'window': return timing.earliestMs;\n case 'exact': return timing.atMs;\n }\n}\n\n/** Returns the latest time (ms) by which the transition must fire. */\nexport function latest(timing: Timing): number {\n switch (timing.type) {\n case 'immediate': return MAX_DURATION_MS;\n case 'deadline': return timing.byMs;\n case 'delayed': return MAX_DURATION_MS;\n case 'window': return timing.latestMs;\n case 'exact': return timing.atMs;\n }\n}\n\n/** Returns true if this timing has a finite deadline. */\nexport function hasDeadline(timing: Timing): boolean {\n switch (timing.type) {\n case 'immediate': return false;\n case 'deadline': return true;\n case 'delayed': return false;\n case 'window': return true;\n case 'exact': return true;\n }\n}\n"],"mappings":";AA0CO,IAAM,kBAAkB,MAAM,MAAM,KAAK,KAAK,KAAK;AAKnD,SAAS,YAA6B;AAC3C,SAAO,EAAE,MAAM,YAAY;AAC7B;AAGO,SAAS,SAAS,MAA8B;AACrD,MAAI,QAAQ,GAAG;AACb,UAAM,IAAI,MAAM,8BAA8B,IAAI,EAAE;AAAA,EACtD;AACA,SAAO,EAAE,MAAM,YAAY,KAAK;AAClC;AAGO,SAAS,QAAQ,SAAgC;AACtD,MAAI,UAAU,GAAG;AACf,UAAM,IAAI,MAAM,+BAA+B,OAAO,EAAE;AAAA,EAC1D;AACA,SAAO,EAAE,MAAM,WAAW,QAAQ;AACpC;AAGO,SAAS,OAAO,YAAoB,UAAgC;AACzE,MAAI,aAAa,GAAG;AAClB,UAAM,IAAI,MAAM,kCAAkC,UAAU,EAAE;AAAA,EAChE;AACA,MAAI,WAAW,YAAY;AACzB,UAAM,IAAI,MAAM,WAAW,QAAQ,0BAA0B,UAAU,GAAG;AAAA,EAC5E;AACA,SAAO,EAAE,MAAM,UAAU,YAAY,SAAS;AAChD;AAGO,SAAS,MAAM,MAA2B;AAC/C,MAAI,OAAO,GAAG;AACZ,UAAM,IAAI,MAAM,oCAAoC,IAAI,EAAE;AAAA,EAC5D;AACA,SAAO,EAAE,MAAM,SAAS,KAAK;AAC/B;AAKO,SAAS,SAAS,QAAwB;AAC/C,UAAQ,OAAO,MAAM;AAAA,IACnB,KAAK;AAAa,aAAO;AAAA,IACzB,KAAK;AAAY,aAAO;AAAA,IACxB,KAAK;AAAW,aAAO,OAAO;AAAA,IAC9B,KAAK;AAAU,aAAO,OAAO;AAAA,IAC7B,KAAK;AAAS,aAAO,OAAO;AAAA,EAC9B;AACF;AAGO,SAAS,OAAO,QAAwB;AAC7C,UAAQ,OAAO,MAAM;AAAA,IACnB,KAAK;AAAa,aAAO;AAAA,IACzB,KAAK;AAAY,aAAO,OAAO;AAAA,IAC/B,KAAK;AAAW,aAAO;AAAA,IACvB,KAAK;AAAU,aAAO,OAAO;AAAA,IAC7B,KAAK;AAAS,aAAO,OAAO;AAAA,EAC9B;AACF;AAGO,SAAS,YAAY,QAAyB;AACnD,UAAQ,OAAO,MAAM;AAAA,IACnB,KAAK;AAAa,aAAO;AAAA,IACzB,KAAK;AAAY,aAAO;AAAA,IACxB,KAAK;AAAW,aAAO;AAAA,IACvB,KAAK;AAAU,aAAO;AAAA,IACtB,KAAK;AAAS,aAAO;AAAA,EACvB;AACF;","names":[]}
|