libpetri 4.1.0 → 5.1.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.
@@ -5,6 +5,7 @@ import {
5
5
  MIN_Z3_VERSION,
6
6
  MarkingState,
7
7
  MarkingStateBuilder,
8
+ NOTE_ENUMERATED,
8
9
  SmtVerifier,
9
10
  StateClass,
10
11
  StateClassGraph,
@@ -16,12 +17,18 @@ import {
16
17
  branchPlaceBound,
17
18
  canonicalInvariantOrder,
18
19
  checkCertificate,
20
+ checkLinearBoundExact,
19
21
  computePInvariants,
20
22
  computePSemiflows,
21
23
  deadlockFree,
24
+ decideOverClasses,
22
25
  decode,
26
+ decodeLinearBound,
23
27
  decodeStateSet,
28
+ describeSinks,
24
29
  encode,
30
+ encodeLinearBound,
31
+ encodeNet,
25
32
  encodeStepRelationSmt2,
26
33
  enumerateBranches,
27
34
  findMaximalTrapIn,
@@ -31,10 +38,13 @@ import {
31
38
  flatNetTransitionCount,
32
39
  flatTransition,
33
40
  flatten,
41
+ formatLinearBound,
42
+ formatLinearDemand,
34
43
  formatZ3Version,
35
44
  ignore,
36
45
  isCoveredByInvariants,
37
46
  isProven,
47
+ isUntimed,
38
48
  isViolated,
39
49
  joinedOrDeadLettered,
40
50
  mutualExclusion,
@@ -46,15 +56,21 @@ import {
46
56
  propertyDescription,
47
57
  replayCounterexample,
48
58
  resolveZ3,
59
+ rethrowIfProgrammingError,
49
60
  runZ3Spacer,
50
61
  runZ3Text,
62
+ strandingExcuses,
63
+ strandsToken,
51
64
  strengthenWithSemiflows,
52
65
  structuralCheck,
66
+ terminatesAtSink,
53
67
  unreachable,
54
68
  vcScript,
69
+ verifyViaStateClassGraph,
70
+ violationDemand,
55
71
  z3Available,
56
72
  z3SolverAt
57
- } from "../chunk-FD3S4TZM.js";
73
+ } from "../chunk-EL4E6LVO.js";
58
74
  import "../chunk-ATT7U5H5.js";
59
75
 
60
76
  // src/verification/analysis/scc-analyzer.ts
@@ -411,6 +427,7 @@ export {
411
427
  MIN_Z3_VERSION,
412
428
  MarkingState,
413
429
  MarkingStateBuilder,
430
+ NOTE_ENUMERATED,
414
431
  SmtVerifier,
415
432
  StateClass,
416
433
  StateClassGraph,
@@ -427,13 +444,19 @@ export {
427
444
  branchPlaceBound,
428
445
  canonicalInvariantOrder,
429
446
  checkCertificate,
447
+ checkLinearBoundExact,
430
448
  computePInvariants,
431
449
  computePSemiflows,
432
450
  computeSCCs,
433
451
  deadlockFree,
452
+ decideOverClasses,
434
453
  decode,
454
+ decodeLinearBound,
435
455
  decodeStateSet,
456
+ describeSinks,
436
457
  encode,
458
+ encodeLinearBound,
459
+ encodeNet,
437
460
  encodeStepRelationSmt2,
438
461
  findMaximalTrapIn,
439
462
  findMinimalSiphons,
@@ -443,10 +466,13 @@ export {
443
466
  flatNetTransitionCount,
444
467
  flatTransition,
445
468
  flatten,
469
+ formatLinearBound,
470
+ formatLinearDemand,
446
471
  formatZ3Version,
447
472
  ignore,
448
473
  isCoveredByInvariants,
449
474
  isProven,
475
+ isUntimed,
450
476
  isViolated,
451
477
  joinedOrDeadLettered,
452
478
  mutualExclusion,
@@ -458,12 +484,18 @@ export {
458
484
  propertyDescription,
459
485
  replayCounterexample,
460
486
  resolveZ3,
487
+ rethrowIfProgrammingError,
461
488
  runZ3Spacer,
462
489
  runZ3Text,
490
+ strandingExcuses,
491
+ strandsToken,
463
492
  strengthenWithSemiflows,
464
493
  structuralCheck,
494
+ terminatesAtSink,
465
495
  unreachable,
466
496
  vcScript,
497
+ verifyViaStateClassGraph,
498
+ violationDemand,
467
499
  z3Available,
468
500
  z3SolverAt
469
501
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/verification/analysis/scc-analyzer.ts","../../src/verification/analysis/time-petri-net-analyzer.ts"],"sourcesContent":["/**\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 { 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":[]}
1
+ {"version":3,"sources":["../../src/verification/analysis/scc-analyzer.ts","../../src/verification/analysis/time-petri-net-analyzer.ts"],"sourcesContent":["/**\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 { 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":[]}
@@ -5,7 +5,7 @@ import {
5
5
  colorForPrefix,
6
6
  discoverClusters,
7
7
  mount
8
- } from "../chunk-GJAHGHGT.js";
8
+ } from "../chunk-BPGE7GZR.js";
9
9
  export {
10
10
  DEFAULT_PANZOOM_OPTS,
11
11
  VERSION,