libpetri 5.1.0 → 6.0.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-BPGE7GZR.js → chunk-5LE2M5PW.js} +2 -2
- package/dist/{chunk-SXK2Z45Z.js → chunk-H2KAMPGN.js} +1 -1
- package/dist/chunk-H2KAMPGN.js.map +1 -0
- package/dist/{chunk-EL4E6LVO.js → chunk-MQZ6IM63.js} +3792 -711
- package/dist/chunk-MQZ6IM63.js.map +1 -0
- package/dist/debug/index.d.ts +2 -2
- package/dist/debug/index.js +1 -1
- package/dist/doclet/index.d.ts +1 -1
- package/dist/doclet/resources/petrinet-diagrams.js +1 -1
- package/dist/{event-store-CUyHiIH7.d.ts → event-store-D6i4u41W.d.ts} +7 -1
- package/dist/export/index.d.ts +1 -1
- package/dist/index.d.ts +43 -10
- package/dist/index.js +301 -2163
- package/dist/index.js.map +1 -1
- package/dist/{petri-net-6G5r1Wwb.d.ts → petri-net-34SkD5RT.d.ts} +27 -2
- package/dist/render-dom/index.js +1 -1
- package/dist/verification/index.d.ts +411 -5
- package/dist/verification/index.js +725 -1
- package/dist/verification/index.js.map +1 -1
- package/dist/viewer/index.js +1 -1
- package/dist/viewer/viewer.iife.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-EL4E6LVO.js.map +0 -1
- package/dist/chunk-SXK2Z45Z.js.map +0 -1
- /package/dist/{chunk-BPGE7GZR.js.map → chunk-5LE2M5PW.js.map} +0 -0
|
@@ -860,7 +860,7 @@ declare function ignore(): EnvironmentAnalysisMode;
|
|
|
860
860
|
* violates the property, Spacer finds a counterexample. If no violation
|
|
861
861
|
* is reachable, the property is proven.
|
|
862
862
|
*/
|
|
863
|
-
type SmtProperty = DeadlockFree | TerminatesAtSink | MutualExclusion | PlaceBound | Unreachable | BranchPlaceBound | JoinedOrDeadLettered;
|
|
863
|
+
type SmtProperty = DeadlockFree | TerminatesAtSink | MutualExclusion | PlaceBound | Unreachable | BranchPlaceBound | JoinedOrDeadLettered | QuiescentCount;
|
|
864
864
|
/**
|
|
865
865
|
* Deadlock-freedom: no reachable quiescent marking strands a token (VER-002).
|
|
866
866
|
*
|
|
@@ -926,6 +926,19 @@ interface JoinedOrDeadLettered {
|
|
|
926
926
|
readonly type: 'joined-or-dead-lettered';
|
|
927
927
|
readonly pending: Place<any>;
|
|
928
928
|
}
|
|
929
|
+
/**
|
|
930
|
+
* A token count at quiescence (VER-002): every reachable quiescent marking holds between
|
|
931
|
+
* `min` and `max` tokens across `places` (`max` may be `Infinity`). The lower bound is
|
|
932
|
+
* waived while any `waivedBy` place is marked, the upper never: a halted run ([VER-014])
|
|
933
|
+
* need not refund its budget, but never holds more than there is.
|
|
934
|
+
*/
|
|
935
|
+
interface QuiescentCount {
|
|
936
|
+
readonly type: 'quiescent-count';
|
|
937
|
+
readonly places: readonly Place<any>[];
|
|
938
|
+
readonly min: number;
|
|
939
|
+
readonly max: number;
|
|
940
|
+
readonly waivedBy: readonly Place<any>[];
|
|
941
|
+
}
|
|
929
942
|
declare function deadlockFree(): DeadlockFree;
|
|
930
943
|
/** Quiescence reaches a declared sink (VER-002). See {@link TerminatesAtSink}. */
|
|
931
944
|
declare function terminatesAtSink(): TerminatesAtSink;
|
|
@@ -936,6 +949,14 @@ declare function unreachable(places: ReadonlySet<Place<any>>): Unreachable;
|
|
|
936
949
|
declare function branchPlaceBound(place: Place<any>, bound: number): BranchPlaceBound;
|
|
937
950
|
/** Joined-or-dead-lettered at quiescence (NU-040). See {@link JoinedOrDeadLettered}. */
|
|
938
951
|
declare function joinedOrDeadLettered(pending: Place<any>): JoinedOrDeadLettered;
|
|
952
|
+
/**
|
|
953
|
+
* A token count at quiescence (VER-002). See {@link QuiescentCount}.
|
|
954
|
+
*
|
|
955
|
+
* ```ts
|
|
956
|
+
* quiescentCount([budget], k, k, [halt]) // the budget is back at k whenever the net comes to rest, unless it halted
|
|
957
|
+
* ```
|
|
958
|
+
*/
|
|
959
|
+
declare function quiescentCount(places: Iterable<Place<any>>, min: number, max: number, waivedBy?: Iterable<Place<any>>): QuiescentCount;
|
|
939
960
|
/** Human-readable description of a property. */
|
|
940
961
|
declare function propertyDescription(prop: SmtProperty): string;
|
|
941
962
|
|
|
@@ -962,6 +983,10 @@ declare class MarkingState {
|
|
|
962
983
|
totalTokens(): number;
|
|
963
984
|
/** Checks if no tokens exist anywhere. */
|
|
964
985
|
isEmpty(): boolean;
|
|
986
|
+
/**
|
|
987
|
+
* The marking as `{name:count, ...}`, places in code-point order of their names, so reports
|
|
988
|
+
* and witness traces print the same on every host ([VER-013], [VER-022]).
|
|
989
|
+
*/
|
|
965
990
|
toString(): string;
|
|
966
991
|
static empty(): MarkingState;
|
|
967
992
|
static builder(): MarkingStateBuilder;
|
|
@@ -1904,4 +1929,4 @@ declare class PetriNetBuilder {
|
|
|
1904
1929
|
private buildWithFusion;
|
|
1905
1930
|
}
|
|
1906
1931
|
|
|
1907
|
-
export { type VerificationHarness as $, type Arc as A, type Port as B, type Channel as C, type PortDirection as D, type EnvironmentPlace as E, FusionSet as F, SubnetDefBuilder as G, type SubnetInstance as H, type In as I, type Timing as J, type KeyFn as K, type LogFn as L, MAX_DURATION_MS as M, type NameId as N, type Out as O, PetriNet as P, type TimingDeadline as Q, type TimingDelayed as R, SubnetDef as S, type Token as T, type TimingExact as U, type TimingImmediate as V, type TimingWindow as W, TokenInput as X, TokenOutput as Y, type TransitionAction as Z, TransitionBuilder as _, type Place as a, type
|
|
1932
|
+
export { type VerificationHarness as $, type Arc as A, type Port as B, type Channel as C, type PortDirection as D, type EnvironmentPlace as E, FusionSet as F, SubnetDefBuilder as G, type SubnetInstance as H, type In as I, type Timing as J, type KeyFn as K, type LogFn as L, MAX_DURATION_MS as M, type NameId as N, type Out as O, PetriNet as P, type TimingDeadline as Q, type TimingDelayed as R, SubnetDef as S, type Token as T, type TimingExact as U, type TimingImmediate as V, type TimingWindow as W, TokenInput as X, TokenOutput as Y, type TransitionAction as Z, TransitionBuilder as _, type Place as a, type QuiescentCount as a$, type VerificationResult as a0, all as a1, allPlaces as a2, and as a3, andPlaces as a4, arcPlace as a5, atLeast as a6, consumptionCount as a7, deadline as a8, delayed as a9, requiredCount as aA, resetArc as aB, timeout as aC, timeoutPlace as aD, tokenAt as aE, tokenOf as aF, transform as aG, transformAsync as aH, transformFrom as aI, unitToken as aJ, window as aK, withTimeout as aL, xor as aM, xorPlaces as aN, type EnvironmentAnalysisMode as aO, type PInvariant as aP, MarkingState as aQ, type SmtProperty as aR, type Verdict as aS, MarkingStateBuilder as aT, type SmtVerificationResult as aU, type BranchPlaceBound as aV, type DeadlockFree as aW, type JoinedOrDeadLettered as aX, type MutualExclusion as aY, type PlaceBound as aZ, type Proven as a_, earliest as aa, enumerateBranches as ab, environmentPlace as ac, exact as ad, exactly as ae, fork as af, forwardInput as ag, hasDeadline as ah, immediate as ai, inhibitorArc as aj, inputArc as ak, isPassthrough as al, isUnit as am, keyForPlace as an, latest as ao, matchCorrelates as ap, matchKey as aq, matchSpec as ar, nameId as as, one as at, outPlace as au, outputArc as av, passthrough as aw, place as ax, produce as ay, readArc as az, Transition as b, type SmtStatistics as b0, type TerminatesAtSink as b1, type TokenSupplier as b2, type Unknown as b3, type Unreachable as b4, type VerificationRoute as b5, type Violated as b6, alwaysAvailable as b7, bounded as b8, ignore as b9, branchPlaceBound as ba, deadlockFree as bb, isProven as bc, isViolated as bd, joinedOrDeadLettered as be, mutualExclusion as bf, pInvariant as bg, pInvariantToString as bh, placeBound as bi, propertyDescription as bj, quiescentCount as bk, terminatesAtSink as bl, unreachable as bm, TransitionContext as c, type ArcInhibitor as d, type ArcInput as e, type ArcOutput as f, type ArcRead as g, type ArcReset as h, ComposeBindings as i, FusionSetBuilder as j, type InAll as k, type InAtLeast as l, type InExactly as m, type InOne as n, Instance as o, Interface as p, InterfaceBuilder as q, type MatchKey as r, type MatchSpec as s, type OutAnd as t, type OutForwardInput as u, type OutPlace as v, type OutTimeout as w, type OutXor as x, type OutputEntry as y, PetriNetBuilder as z };
|
package/dist/render-dom/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { b as Transition, a as Place, P as PetriNet, E as EnvironmentPlace, aO as EnvironmentAnalysisMode, aP as PInvariant, aQ as MarkingState, aR as SmtProperty, aS as Verdict, aT as MarkingStateBuilder, aU as SmtVerificationResult } from '../petri-net-
|
|
2
|
-
export { aV as BranchPlaceBound, aW as DeadlockFree, aX as JoinedOrDeadLettered, aY as MutualExclusion, aZ as PlaceBound, a_ as Proven, a$ as
|
|
1
|
+
import { b as Transition, a as Place, P as PetriNet, E as EnvironmentPlace, aO as EnvironmentAnalysisMode, aP as PInvariant, aQ as MarkingState, aR as SmtProperty, aS as Verdict, aT as MarkingStateBuilder, aU as SmtVerificationResult } from '../petri-net-34SkD5RT.js';
|
|
2
|
+
export { aV as BranchPlaceBound, aW as DeadlockFree, aX as JoinedOrDeadLettered, aY as MutualExclusion, aZ as PlaceBound, a_ as Proven, a$ as QuiescentCount, b0 as SmtStatistics, b1 as TerminatesAtSink, b2 as TokenSupplier, b3 as Unknown, b4 as Unreachable, $ as VerificationHarness, a0 as VerificationResult, b5 as VerificationRoute, b6 as Violated, b7 as alwaysAvailable, b7 as analysisAlwaysAvailable, b8 as analysisBounded, b9 as analysisIgnore, b8 as bounded, ba as branchPlaceBound, bb as deadlockFree, b9 as ignore, bc as isProven, bd as isViolated, be as joinedOrDeadLettered, bf as mutualExclusion, bg as pInvariant, bh as pInvariantToString, bi as placeBound, bj as propertyDescription, bk as quiescentCount, bl as terminatesAtSink, bm as unreachable } from '../petri-net-34SkD5RT.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* A flattened transition with pre/post vectors for SMT encoding.
|
|
@@ -115,7 +115,8 @@ declare class IncidenceMatrix {
|
|
|
115
115
|
* - `consumeAll[p]`: true for `all`/`at-least` inputs (consume everything)
|
|
116
116
|
* - Index arrays for inhibitor, read, and reset arcs
|
|
117
117
|
*
|
|
118
|
-
* Places are sorted by name for stable
|
|
118
|
+
* Places are sorted by name, in Unicode code-point order, for stable indexing across
|
|
119
|
+
* runs, hosts and implementations.
|
|
119
120
|
*/
|
|
120
121
|
|
|
121
122
|
/**
|
|
@@ -297,6 +298,11 @@ declare function strandingExcuses(flatNet: FlatNet, sinkPlaces: ReadonlySet<Plac
|
|
|
297
298
|
* permitted in `m`. The graph-route form of {@link strandingExcuses}.
|
|
298
299
|
*/
|
|
299
300
|
declare function strandsToken(m: MarkingState, sinkPlaces: ReadonlySet<Place<any>>, conditional: readonly ConditionalSinks[]): boolean;
|
|
301
|
+
/**
|
|
302
|
+
* The places of `m` holding a stranded token, in `m`'s own order: empty exactly when
|
|
303
|
+
* {@link strandsToken} is false. [VER-022] names them in its violations.
|
|
304
|
+
*/
|
|
305
|
+
declare function strandedPlaces(m: MarkingState, sinkPlaces: ReadonlySet<Place<any>>, conditional: readonly ConditionalSinks[]): Place<any>[];
|
|
300
306
|
/**
|
|
301
307
|
* The declarations as the report prints them after the property description:
|
|
302
308
|
* `sinks: a, b; when h: c, d; when p`, or `null` when nothing is declared.
|
|
@@ -678,6 +684,8 @@ declare class SmtVerifier {
|
|
|
678
684
|
private _semiflowInvariants;
|
|
679
685
|
private _stateEquation;
|
|
680
686
|
private _linearBound;
|
|
687
|
+
private _stateEquationPhase;
|
|
688
|
+
private _firingBound;
|
|
681
689
|
private _nuMaxClasses;
|
|
682
690
|
private _enumerationMaxClasses;
|
|
683
691
|
private _fragmentMode;
|
|
@@ -836,8 +844,45 @@ declare class SmtVerifier {
|
|
|
836
844
|
* as the equality laws), and the certificate check re-proves it against the raw
|
|
837
845
|
* step relation, whose only counter knowledge is the increment. Not applied to the
|
|
838
846
|
* name-coloured encoding or Route B, which the report says when it applies.
|
|
847
|
+
*
|
|
848
|
+
* Not {@link stateEquationPhase}, the VER-018 pre-phase (on by default) that can decide
|
|
849
|
+
* the property instead of the fixpoint query.
|
|
839
850
|
*/
|
|
840
851
|
stateEquation(enabled: boolean): this;
|
|
852
|
+
/**
|
|
853
|
+
* Enables/disables the state-equation phase (VER-018; default: enabled).
|
|
854
|
+
*
|
|
855
|
+
* Before the fixpoint query, one linear query asks whether a marking the marking
|
|
856
|
+
* equation (`M = M0 + C·n`, `n ≥ 0`, an upper bound on a cleared place) admits violates
|
|
857
|
+
* the property; `unsat` proves it. A `sat` candidate is settled cheapest first: a run
|
|
858
|
+
* within its firing counts that reaches a violation (the counterexample), an initially
|
|
859
|
+
* marked trap it empties, or an inequality `a·M ≤ b` kept by the exact step relation
|
|
860
|
+
* that excludes it. The refinement is added and the query asked again.
|
|
861
|
+
*
|
|
862
|
+
* The proof `SE ∧ refinements` passes the certificate check before it is reported, and
|
|
863
|
+
* the report prints each refinement, e.g. `Merge/hasdata <= Merge/ready_0 +
|
|
864
|
+
* Merge/ready_1` on a workflow join. When nothing settles a candidate, the pipeline
|
|
865
|
+
* continues unchanged. Flat path only: skipped for a ν-net and under `ignore` with
|
|
866
|
+
* environment places. Runs within the full {@link timeout}; the certificate check gets
|
|
867
|
+
* its own.
|
|
868
|
+
*
|
|
869
|
+
* Not {@link stateEquation}, which adds firing counters inside the fixpoint encoding.
|
|
870
|
+
*/
|
|
871
|
+
stateEquationPhase(enabled: boolean): this;
|
|
872
|
+
/**
|
|
873
|
+
* Enables/disables the firing-bound phase (VER-019; default: enabled).
|
|
874
|
+
*
|
|
875
|
+
* Weights `r ≥ 0` that every firing lowers by at least one bound every run by
|
|
876
|
+
* `K = r·M0` firings, so a bounded model check to depth `K` decides the property. The
|
|
877
|
+
* depth doubles from 8, which finds a short counterexample early. Without such weights
|
|
878
|
+
* the report names the transitions the marking equation lets repeat, and the fixpoint
|
|
879
|
+
* query runs.
|
|
880
|
+
*
|
|
881
|
+
* A proof carries no inductive invariant: the ranking is re-checked in exact integer
|
|
882
|
+
* arithmetic, and a counterexample is replayed. Runs after the state-equation phase, on
|
|
883
|
+
* the same nets, within half the {@link timeout}.
|
|
884
|
+
*/
|
|
885
|
+
firingBound(enabled: boolean): this;
|
|
841
886
|
/**
|
|
842
887
|
* Sets the class-count cap for the ν-aware state-class-graph analysis (NU-050,
|
|
843
888
|
* Route B). When the symbolic name-aware graph would exceed this, the analysis
|
|
@@ -936,6 +981,23 @@ declare class SmtVerifier {
|
|
|
936
981
|
* `null` hands over to the fixpoint query.
|
|
937
982
|
*/
|
|
938
983
|
private linearBoundProof;
|
|
984
|
+
/**
|
|
985
|
+
* Whether environment places are registered but not modelled ([VER-006] `ignore`). A
|
|
986
|
+
* proof over a frozen environment is vacuous, so every route that can return `proven`
|
|
987
|
+
* refuses it. See {@link IGNORE_MODE_VACUITY_REASON}.
|
|
988
|
+
*/
|
|
989
|
+
private get ignoresEnvironment();
|
|
990
|
+
/**
|
|
991
|
+
* Runs the state-equation phase (VER-018). Returns the final result when it decided
|
|
992
|
+
* the property — a `proven` only once the certificate check passed — and `null` when
|
|
993
|
+
* it stepped aside, with the reason in the report.
|
|
994
|
+
*/
|
|
995
|
+
private stateEquationDecision;
|
|
996
|
+
/**
|
|
997
|
+
* Runs the firing-bound phase (VER-019). Returns the final result when it decided the
|
|
998
|
+
* property and `null` when it stepped aside, with the reason in the report.
|
|
999
|
+
*/
|
|
1000
|
+
private firingBoundDecision;
|
|
939
1001
|
/**
|
|
940
1002
|
* ν-net soundness guard (NU-040, NU-050). Applied only when the net contains
|
|
941
1003
|
* match (ν-join) transitions, and only to a proven/violated verdict (an
|
|
@@ -970,6 +1032,12 @@ interface EncodedScripts {
|
|
|
970
1032
|
* no linear demand (the quiescence properties).
|
|
971
1033
|
*/
|
|
972
1034
|
readonly bound: string | null;
|
|
1035
|
+
/**
|
|
1036
|
+
* The first query of the state-equation phase (VER-018), before any refinement, or
|
|
1037
|
+
* `null` where the phase does not run (the name-coloured encoding, a ν-net, `ignore`
|
|
1038
|
+
* with environment places, or the phase disabled).
|
|
1039
|
+
*/
|
|
1040
|
+
readonly stateEquation: string | null;
|
|
973
1041
|
}
|
|
974
1042
|
/**
|
|
975
1043
|
* `(define-fun Reachable ((x!0 Int) …) Bool true)`: the certificate stand-in the
|
|
@@ -1413,6 +1481,15 @@ interface BranchEdge {
|
|
|
1413
1481
|
readonly branchIndex: number;
|
|
1414
1482
|
readonly target: StateClass;
|
|
1415
1483
|
}
|
|
1484
|
+
/** Options for {@link StateClassGraph.build}. */
|
|
1485
|
+
interface StateClassGraphOptions {
|
|
1486
|
+
/**
|
|
1487
|
+
* Explore the **untimed** reachable set ([VER-004]): every clock gets `immediate()`'s
|
|
1488
|
+
* `[0, ∞)`, so any enabled transition may fire next and the graph holds exactly the
|
|
1489
|
+
* markings the untimed encoders reason about. No effect on an all-immediate net.
|
|
1490
|
+
*/
|
|
1491
|
+
readonly untimed?: boolean;
|
|
1492
|
+
}
|
|
1416
1493
|
/**
|
|
1417
1494
|
* State Class Graph for Time Petri Net analysis.
|
|
1418
1495
|
*
|
|
@@ -1433,7 +1510,7 @@ declare class StateClassGraph {
|
|
|
1433
1510
|
*
|
|
1434
1511
|
* @throws Error if the net violates CORE-043 — analysis rejects the same nets execution rejects.
|
|
1435
1512
|
*/
|
|
1436
|
-
static build(net: PetriNet, initialMarking: MarkingState, maxClasses: number, environmentPlaces?: Set<EnvironmentPlace<any>>, environmentMode?: EnvironmentAnalysisMode): StateClassGraph;
|
|
1513
|
+
static build(net: PetriNet, initialMarking: MarkingState, maxClasses: number, environmentPlaces?: Set<EnvironmentPlace<any>>, environmentMode?: EnvironmentAnalysisMode, options?: StateClassGraphOptions): StateClassGraph;
|
|
1437
1514
|
stateClasses(): readonly StateClass[];
|
|
1438
1515
|
size(): number;
|
|
1439
1516
|
isComplete(): boolean;
|
|
@@ -1519,4 +1596,333 @@ declare class TimePetriNetAnalyzerBuilder {
|
|
|
1519
1596
|
build(): TimePetriNetAnalyzer;
|
|
1520
1597
|
}
|
|
1521
1598
|
|
|
1522
|
-
|
|
1599
|
+
/**
|
|
1600
|
+
* @module open-net/contract
|
|
1601
|
+
*
|
|
1602
|
+
* What a subnet promises when verified on its own, with its ports played by the environment
|
|
1603
|
+
* ([VER-022]).
|
|
1604
|
+
*
|
|
1605
|
+
* The **assumption**: the tokens the subnet holds before anything arrives, and arrival
|
|
1606
|
+
* groups, each delivering between `min` and `max` tokens onto its places at any point of the
|
|
1607
|
+
* run. Every bound is finite: a bound is both the runtime cap and the width of the claim.
|
|
1608
|
+
*
|
|
1609
|
+
* The **guarantee**: at every quiescent marking the count clauses hold, and tokens rest only
|
|
1610
|
+
* on clause, rest or environment places, or where a marked designed terminal excuses them;
|
|
1611
|
+
* every other place is internal and empty. Every run comes to rest unless
|
|
1612
|
+
* {@link OpenNetContractBuilder.requireTermination} is turned off.
|
|
1613
|
+
*/
|
|
1614
|
+
|
|
1615
|
+
/**
|
|
1616
|
+
* The environment delivers between `min` and `max` tokens in total, each onto one of
|
|
1617
|
+
* `places`, each at any point of the run.
|
|
1618
|
+
*/
|
|
1619
|
+
interface ArrivalGroup {
|
|
1620
|
+
readonly places: readonly Place<any>[];
|
|
1621
|
+
readonly min: number;
|
|
1622
|
+
readonly max: number;
|
|
1623
|
+
}
|
|
1624
|
+
/**
|
|
1625
|
+
* At every quiescent marking the tokens across `places` number between `min` and `max`
|
|
1626
|
+
* (`max` may be `Infinity`). A marked designed terminal waives `min`, never `max`: a halt
|
|
1627
|
+
* stops progress, it does not license a token too many.
|
|
1628
|
+
*/
|
|
1629
|
+
interface CountClause {
|
|
1630
|
+
readonly name: string;
|
|
1631
|
+
readonly places: readonly Place<any>[];
|
|
1632
|
+
readonly min: number;
|
|
1633
|
+
readonly max: number;
|
|
1634
|
+
}
|
|
1635
|
+
/**
|
|
1636
|
+
* While `marker` holds a token, the clauses' lower bounds are waived and tokens may rest on
|
|
1637
|
+
* `excused`: the places where the work the marker interrupted was delivered. The marker
|
|
1638
|
+
* itself may always rest, as a conditional-sink marker may ([VER-014]).
|
|
1639
|
+
*/
|
|
1640
|
+
interface DesignedTerminal {
|
|
1641
|
+
readonly marker: Place<any>;
|
|
1642
|
+
readonly excused: readonly Place<any>[];
|
|
1643
|
+
}
|
|
1644
|
+
/**
|
|
1645
|
+
* A subnet's contract: the environment it assumes and what it guarantees at quiescence
|
|
1646
|
+
* ([VER-022]). Build one with {@link OpenNetContract.builder}; check it with `verifyOpenNet`.
|
|
1647
|
+
*
|
|
1648
|
+
* ```ts
|
|
1649
|
+
* const contract = OpenNetContract.builder()
|
|
1650
|
+
* .initialMarking(m => m.tokens(idle, 1).tokens(budget, k))
|
|
1651
|
+
* .arrive(1, inData, inEmpty) // exactly one arrival on the input edge
|
|
1652
|
+
* .arriveAtMost(1, halt) // never or once
|
|
1653
|
+
* .expect('e3', 1, e3Data, e3Empty) // one of data / empty per outgoing edge, once it runs
|
|
1654
|
+
* .expect('idle', 1, idle)
|
|
1655
|
+
* .expect('budget', k, budget)
|
|
1656
|
+
* .expect('history', 1, done, skipped)
|
|
1657
|
+
* .terminal(halt, inData, inEmpty) // a halted run leaves the arrival where it was delivered
|
|
1658
|
+
* .terminal(skipped) // a skipped run writes no output edge at all
|
|
1659
|
+
* .build();
|
|
1660
|
+
* ```
|
|
1661
|
+
*
|
|
1662
|
+
* **A node that can skip needs its edge clauses conditional.** `expect('e3', 1, …)` alone
|
|
1663
|
+
* reports a node that rests having skipped the edge. Name the place that marks a skip as a
|
|
1664
|
+
* {@link OpenNetContractBuilder.terminal}: while it is marked the lower bounds are waived, and
|
|
1665
|
+
* the upper bounds still catch an edge written twice.
|
|
1666
|
+
*
|
|
1667
|
+
* **A subnet that asks something of its neighbours needs an environment.** Alone, a node that
|
|
1668
|
+
* sends a request and waits quiesces with the request outstanding. Give the contract the
|
|
1669
|
+
* transitions the neighbours fire; their own places are never counted as stranded.
|
|
1670
|
+
*
|
|
1671
|
+
* ```ts
|
|
1672
|
+
* // A node that runs again on every answer, against an environment that answers twice.
|
|
1673
|
+
* const again = Transition.builder('env/again').inputs(one(request), one(rounds))
|
|
1674
|
+
* .outputs(outPlace(reply)).build();
|
|
1675
|
+
* const end = Transition.builder('env/end').inputs(one(request)).outputs(outPlace(ended)).build();
|
|
1676
|
+
*
|
|
1677
|
+
* const agent = OpenNetContract.builder()
|
|
1678
|
+
* .initialMarking(m => m.tokens(rounds, 2)) // the environment's own budget
|
|
1679
|
+
* .arrive(1, inPlace)
|
|
1680
|
+
* .expectBetween('done', 0, 1, done) // it may end without finishing
|
|
1681
|
+
* .environment(again, end)
|
|
1682
|
+
* .build();
|
|
1683
|
+
* ```
|
|
1684
|
+
*
|
|
1685
|
+
* An environment transition is never executed, so it needs no action.
|
|
1686
|
+
*/
|
|
1687
|
+
declare class OpenNetContract {
|
|
1688
|
+
/** Tokens the subnet holds before anything arrives: its own resources and any shared pool it borrows from. */
|
|
1689
|
+
readonly initialMarking: MarkingState;
|
|
1690
|
+
readonly arrivals: readonly ArrivalGroup[];
|
|
1691
|
+
readonly clauses: readonly CountClause[];
|
|
1692
|
+
/** Places that may hold any number of tokens at quiescence. */
|
|
1693
|
+
readonly rest: readonly Place<any>[];
|
|
1694
|
+
readonly terminals: readonly DesignedTerminal[];
|
|
1695
|
+
/** Transitions the environment fires: neighbours that react to what the subnet sends. */
|
|
1696
|
+
readonly environment: readonly Transition[];
|
|
1697
|
+
/** Whether every run must come to rest. */
|
|
1698
|
+
readonly requiresTermination: boolean;
|
|
1699
|
+
/** @internal Use {@link OpenNetContract.builder}. */
|
|
1700
|
+
constructor(key: symbol, initialMarking: MarkingState, arrivals: readonly ArrivalGroup[], clauses: readonly CountClause[], rest: readonly Place<any>[], terminals: readonly DesignedTerminal[], environment: readonly Transition[], requiresTermination: boolean);
|
|
1701
|
+
static builder(): OpenNetContractBuilder;
|
|
1702
|
+
/**
|
|
1703
|
+
* Every place the initial marking, an arrival group, a clause, the rest set or a terminal
|
|
1704
|
+
* marker names, then every place an environment transition touches, in first-mention
|
|
1705
|
+
* order: the places a port trace reports. A terminal's excused places are not included;
|
|
1706
|
+
* `closeOpenNet` adds them to the closed net itself.
|
|
1707
|
+
*/
|
|
1708
|
+
places(): Place<any>[];
|
|
1709
|
+
/** The contract as the report prints it, one line per part. */
|
|
1710
|
+
describe(): string[];
|
|
1711
|
+
}
|
|
1712
|
+
declare class OpenNetContractBuilder {
|
|
1713
|
+
private _initialMarking;
|
|
1714
|
+
private readonly _arrivals;
|
|
1715
|
+
private readonly _clauses;
|
|
1716
|
+
private readonly _rest;
|
|
1717
|
+
private readonly _terminals;
|
|
1718
|
+
private readonly _environment;
|
|
1719
|
+
private _requiresTermination;
|
|
1720
|
+
/** Tokens the subnet holds before anything arrives. */
|
|
1721
|
+
initialMarking(marking: MarkingState): this;
|
|
1722
|
+
initialMarking(configurator: (builder: MarkingStateBuilder) => void): this;
|
|
1723
|
+
/** The environment delivers exactly `count` tokens, each onto one of `places`, at any point of the run. */
|
|
1724
|
+
arrive(count: number, ...places: Place<any>[]): this;
|
|
1725
|
+
/** The environment delivers at most `max` tokens, possibly none. `arriveAtMost(1, halt)` is "never or once". */
|
|
1726
|
+
arriveAtMost(max: number, ...places: Place<any>[]): this;
|
|
1727
|
+
/** The environment delivers between `min` and `max` tokens in total, each onto one of `places`, at any point of the run. */
|
|
1728
|
+
arriveBetween(min: number, max: number, ...places: Place<any>[]): this;
|
|
1729
|
+
/** At every quiescent marking, exactly `count` tokens across `places`. */
|
|
1730
|
+
expect(name: string, count: number, ...places: Place<any>[]): this;
|
|
1731
|
+
/** At every quiescent marking, between `min` and `max` tokens across `places`; `max` may be `Infinity`. */
|
|
1732
|
+
expectBetween(name: string, min: number, max: number, ...places: Place<any>[]): this;
|
|
1733
|
+
/** Places that may hold any number of tokens at quiescence. */
|
|
1734
|
+
rest(...places: Place<any>[]): this;
|
|
1735
|
+
/**
|
|
1736
|
+
* A designed terminal: while `marker` holds a token, lower bounds are waived and tokens may
|
|
1737
|
+
* rest on `excused`. Repeated calls for one marker accumulate.
|
|
1738
|
+
*/
|
|
1739
|
+
terminal(marker: Place<any>, ...excused: Place<any>[]): this;
|
|
1740
|
+
/**
|
|
1741
|
+
* Transitions the environment fires: a neighbour that reacts to what the subnet sends, such
|
|
1742
|
+
* as a tool answering a request. An arrival group cannot say that: its tokens do not wait
|
|
1743
|
+
* for a request.
|
|
1744
|
+
*
|
|
1745
|
+
* They join the closed net unchanged and are marked as environment steps in the port trace.
|
|
1746
|
+
* A place only they touch belongs to the environment and may hold tokens at quiescence; a
|
|
1747
|
+
* place they share with the subnet is a port, judged like any other. Their actions never
|
|
1748
|
+
* run, so one that declares outputs may keep `passthrough()`.
|
|
1749
|
+
*/
|
|
1750
|
+
environment(...transitions: Transition[]): this;
|
|
1751
|
+
/** Whether every run must come to rest (default `true`). */
|
|
1752
|
+
requireTermination(required: boolean): this;
|
|
1753
|
+
build(): OpenNetContract;
|
|
1754
|
+
}
|
|
1755
|
+
|
|
1756
|
+
/**
|
|
1757
|
+
* @module open-net/closure
|
|
1758
|
+
*
|
|
1759
|
+
* An open net closed by the environment its contract describes ([VER-022]).
|
|
1760
|
+
*
|
|
1761
|
+
* Each arrival group becomes a source place holding the tokens it must deliver, one
|
|
1762
|
+
* transition per target place moving a token across, and a second source for the optional
|
|
1763
|
+
* part whose tokens may also be declined. The contract's environment transitions join
|
|
1764
|
+
* unchanged. Every interleaving of environment steps with the subnet's firings is a run of
|
|
1765
|
+
* the closed net, which is quiescent only once the environment has delivered what it must
|
|
1766
|
+
* and decided about the rest. Every route then verifies a plain net.
|
|
1767
|
+
*
|
|
1768
|
+
* Ordinary places, not the environment places of [VER-006]: those never run dry, so a net
|
|
1769
|
+
* with one is never quiescent and every quiescence property would hold vacuously.
|
|
1770
|
+
*/
|
|
1771
|
+
|
|
1772
|
+
/** What an environment transition of the closure does, for the port trace. */
|
|
1773
|
+
type EnvironmentStep = {
|
|
1774
|
+
readonly kind: 'arrival';
|
|
1775
|
+
readonly group: number;
|
|
1776
|
+
readonly place: string;
|
|
1777
|
+
} | {
|
|
1778
|
+
readonly kind: 'decline';
|
|
1779
|
+
readonly group: number;
|
|
1780
|
+
}
|
|
1781
|
+
/** One of the contract's own environment transitions. */
|
|
1782
|
+
| {
|
|
1783
|
+
readonly kind: 'transition';
|
|
1784
|
+
};
|
|
1785
|
+
/** An open net and its environment, as one closed net. */
|
|
1786
|
+
interface ClosedNet {
|
|
1787
|
+
readonly net: PetriNet;
|
|
1788
|
+
readonly initialMarking: MarkingState;
|
|
1789
|
+
/** Each environment transition by name, with what it does. */
|
|
1790
|
+
readonly environment: ReadonlyMap<string, EnvironmentStep>;
|
|
1791
|
+
/**
|
|
1792
|
+
* Places only the contract's environment transitions touch: the environment's own state.
|
|
1793
|
+
* A token left on one at quiescence is never stranded.
|
|
1794
|
+
*/
|
|
1795
|
+
readonly environmentPlaces: readonly Place<any>[];
|
|
1796
|
+
/**
|
|
1797
|
+
* Places the contract names that no arc touches, in contract order. They join the closed
|
|
1798
|
+
* net as places of their own, so every route resolves them. A clause over a place nothing
|
|
1799
|
+
* writes then counts zero there, which is the finding, not an error.
|
|
1800
|
+
*/
|
|
1801
|
+
readonly undeclared: readonly string[];
|
|
1802
|
+
}
|
|
1803
|
+
/**
|
|
1804
|
+
* Closes `net` with the environment of `contract`: its environment transitions, and for
|
|
1805
|
+
* arrival group `i` a source `env:arrivals[i]` holding `min` tokens and a source
|
|
1806
|
+
* `env:optional[i]` holding `max − min`, with transitions `env:arrive[i]:<place>` /
|
|
1807
|
+
* `env:arrive?[i]:<place>` moving a token onto each of the group's places, and
|
|
1808
|
+
* `env:decline[i]` discarding an optional one.
|
|
1809
|
+
*
|
|
1810
|
+
* @throws when a name the closure would add is already taken in `net`
|
|
1811
|
+
*/
|
|
1812
|
+
declare function closeOpenNet(net: PetriNet, contract: OpenNetContract): ClosedNet;
|
|
1813
|
+
|
|
1814
|
+
/**
|
|
1815
|
+
* @module open-net/result
|
|
1816
|
+
*
|
|
1817
|
+
* What `verifyOpenNet` returns ([VER-022]), and how a witness becomes a port trace.
|
|
1818
|
+
*/
|
|
1819
|
+
|
|
1820
|
+
/** Which part of the contract a violation breaks. */
|
|
1821
|
+
type ContractViolationKind =
|
|
1822
|
+
/** A count clause: too few tokens across its places at quiescence with no terminal marked, or too many. */
|
|
1823
|
+
'clause'
|
|
1824
|
+
/** A token rests where the contract lets none rest: on an internal place, or on one only an unmarked terminal excuses. */
|
|
1825
|
+
| 'stranded'
|
|
1826
|
+
/** A run that never comes to rest: a reachable cycle. */
|
|
1827
|
+
| 'termination';
|
|
1828
|
+
/** A token-count change on one contract place. */
|
|
1829
|
+
interface PortChange {
|
|
1830
|
+
readonly place: string;
|
|
1831
|
+
readonly delta: number;
|
|
1832
|
+
}
|
|
1833
|
+
/** A firing that touches the subnet's boundary: an environment step, or a change on a contract place. */
|
|
1834
|
+
interface PortStep {
|
|
1835
|
+
/** The firing's position in {@link ContractViolation.transitions}, counting from 1. */
|
|
1836
|
+
readonly step: number;
|
|
1837
|
+
readonly transition: string;
|
|
1838
|
+
/**
|
|
1839
|
+
* Set when the environment fired it: `arrival` or `decline` for an arrival group,
|
|
1840
|
+
* `transition` for one of the contract's environment transitions. `null` for the subnet.
|
|
1841
|
+
*/
|
|
1842
|
+
readonly environment: EnvironmentStep['kind'] | null;
|
|
1843
|
+
/** Token changes on the contract's places, in the contract's order. */
|
|
1844
|
+
readonly changes: readonly PortChange[];
|
|
1845
|
+
}
|
|
1846
|
+
/** One broken part of the contract, with a firing sequence that breaks it. */
|
|
1847
|
+
interface ContractViolation {
|
|
1848
|
+
readonly kind: ContractViolationKind;
|
|
1849
|
+
/**
|
|
1850
|
+
* The clause's name, a stranded place's name, or `termination`. The SMT route reports one
|
|
1851
|
+
* stranding for the whole query, naming every stranded place comma-separated.
|
|
1852
|
+
*/
|
|
1853
|
+
readonly subject: string;
|
|
1854
|
+
/** What was found, in words. */
|
|
1855
|
+
readonly detail: string;
|
|
1856
|
+
/** The firing sequence from the initial marking, environment transitions included. */
|
|
1857
|
+
readonly transitions: readonly string[];
|
|
1858
|
+
/** The marking before the first firing and after each one, when the route has them in order. */
|
|
1859
|
+
readonly markings: readonly MarkingState[];
|
|
1860
|
+
/** For `termination`, the index into {@link transitions} where the repeating cycle starts. */
|
|
1861
|
+
readonly cycleStart: number | null;
|
|
1862
|
+
/** The firings of {@link transitions} that touch the boundary. */
|
|
1863
|
+
readonly portTrace: readonly PortStep[];
|
|
1864
|
+
/**
|
|
1865
|
+
* Whether {@link transitions} is a real firing sequence in order. Always on the graph
|
|
1866
|
+
* route; on the SMT route it is the counterexample replay's outcome ([VER-003]).
|
|
1867
|
+
*/
|
|
1868
|
+
readonly confirmed: boolean;
|
|
1869
|
+
}
|
|
1870
|
+
/** Which route decided the verdict. */
|
|
1871
|
+
type OpenNetRoute = 'enumeration' | 'smt';
|
|
1872
|
+
/** The outcome of `verifyOpenNet`. */
|
|
1873
|
+
interface OpenNetResult {
|
|
1874
|
+
/** `proven`, `violated` (see {@link violations}), or `unknown` with the reason. */
|
|
1875
|
+
readonly verdict: Verdict;
|
|
1876
|
+
/**
|
|
1877
|
+
* Every broken part found. The graph route lists clauses in contract order, then stranded
|
|
1878
|
+
* places by name, then termination; the SMT route asks for stranding first, so it lists
|
|
1879
|
+
* that, then clauses in contract order, then termination.
|
|
1880
|
+
*/
|
|
1881
|
+
readonly violations: readonly ContractViolation[];
|
|
1882
|
+
readonly route: OpenNetRoute;
|
|
1883
|
+
/** Classes the state-class graph explored; `0` when it was skipped. */
|
|
1884
|
+
readonly classCount: number;
|
|
1885
|
+
/** Whether the state-class graph closed within its budget. */
|
|
1886
|
+
readonly graphComplete: boolean;
|
|
1887
|
+
readonly report: string;
|
|
1888
|
+
/** The subnet closed by its environment: what every route verified. */
|
|
1889
|
+
readonly closedNet: PetriNet;
|
|
1890
|
+
readonly closedMarking: MarkingState;
|
|
1891
|
+
readonly elapsedMs: number;
|
|
1892
|
+
}
|
|
1893
|
+
|
|
1894
|
+
/**
|
|
1895
|
+
* @module open-net/verify-open-net
|
|
1896
|
+
*
|
|
1897
|
+
* A subnet verified on its own against a contract, with its ports played by the environment
|
|
1898
|
+
* ([VER-022]). The closed net's untimed state-class graph decides exactly when it closes; a
|
|
1899
|
+
* violation it finds stands either way, and otherwise the SMT pipeline gets the contract.
|
|
1900
|
+
* Composing the per-subnet proofs into a claim about a whole net is the caller's theorem.
|
|
1901
|
+
*/
|
|
1902
|
+
|
|
1903
|
+
/** Options for {@link verifyOpenNet}. */
|
|
1904
|
+
interface OpenNetOptions {
|
|
1905
|
+
/** Class budget for the state-class graph (default 50 000, as for [VER-017]). `0` skips the graph. */
|
|
1906
|
+
readonly maxClasses?: number;
|
|
1907
|
+
/** Whether to ask the SMT pipeline when the graph does not close (default `true`). */
|
|
1908
|
+
readonly smt?: boolean;
|
|
1909
|
+
/** Configures each `SmtVerifier` the SMT route builds, e.g. `v => v.timeout(120_000).stateEquation(true)`. */
|
|
1910
|
+
readonly configureSmt?: (verifier: SmtVerifier) => SmtVerifier;
|
|
1911
|
+
/** Time for the firing-bound query that decides termination on the SMT route (default 60 s). */
|
|
1912
|
+
readonly terminationTimeoutMs?: number;
|
|
1913
|
+
}
|
|
1914
|
+
/**
|
|
1915
|
+
* Verifies `net` in isolation against `contract` ([VER-022]).
|
|
1916
|
+
*
|
|
1917
|
+
* `proven` means that, in every run of the environment the contract assumes, every
|
|
1918
|
+
* quiescent marking meets the contract, and (unless termination is waived) every run comes
|
|
1919
|
+
* to rest. The claim is untimed, priority-blind and value-blind, like every route's
|
|
1920
|
+
* ([VER-004]). `violated` lists every broken part with a shortest witness, and
|
|
1921
|
+
* `unknown` says why neither route decided.
|
|
1922
|
+
*
|
|
1923
|
+
* @throws when the net violates CORE-043, as every verifier does, or when the closure's
|
|
1924
|
+
* names collide with the net's
|
|
1925
|
+
*/
|
|
1926
|
+
declare function verifyOpenNet(net: PetriNet, contract: OpenNetContract, options?: OpenNetOptions): Promise<OpenNetResult>;
|
|
1927
|
+
|
|
1928
|
+
export { type AbstractState, EnvironmentAnalysisMode as AnalysisEnvironmentMode, type ArrivalGroup, type BranchEdge, type CertificateCheckOutcome, type CertificateVc, type ClassView, type ClosedNet, type ConditionalSinks, type ContractViolation, type ContractViolationKind, type CountClause, DBM, DUMP_ENV, type DecodedTrace, type DesignedTerminal, type EncodeOptions, type EncodedScripts, EnvironmentAnalysisMode, type EnvironmentStep, type FlatNet, type FlatTransition, IncidenceMatrix, type LinearBound, type LivenessResult, MIN_Z3_VERSION, MarkingState, MarkingStateBuilder, NOTE_ENUMERATED, OpenNetContract, OpenNetContractBuilder, type OpenNetOptions, type OpenNetResult, type OpenNetRoute, PInvariant, type PortChange, type PortStep, type PrioritySemantics, type QueryProven, type QueryResult, type QueryUnknown, type QueryViolated, type ReplayOptions, type ReplayOutcome, type ReplayStep, type ScgOutcome, type SmtEncoding, SmtProperty, SmtVerificationResult, SmtVerifier, StateClass, StateClassGraph, type StateClassGraphOptions, type StructuralCheckResult, TimePetriNetAnalyzer, TimePetriNetAnalyzerBuilder, Verdict, type XorBranchAnalysis, type XorBranchInfo, type Z3Exit, Z3ProcessError, type Z3Reply, type Z3Solver, Z3Unavailable, type Z3Version, Z3_ENV, canonicalInvariantOrder, checkCertificate, checkLinearBoundExact, closeOpenNet, computePInvariants, computePSemiflows, computeSCCs, decideOverClasses, decode, decodeLinearBound, decodeStateSet, describeSinks, encode, encodeLinearBound, encodeNet, encodeStepRelationSmt2, findMaximalTrapIn, findMinimalSiphons, findTerminalSCCs, flatNetIndexOf, flatNetPlaceCount, flatNetTransitionCount, flatTransition, flatten, formatLinearBound, formatLinearDemand, formatZ3Version, isCoveredByInvariants, isUntimed, parseZ3Version, placeholderCertificate, replayCounterexample, resolveZ3, rethrowIfProgrammingError, runZ3Spacer, runZ3Text, strandedPlaces, strandingExcuses, strandsToken, strengthenWithSemiflows, structuralCheck, vcScript, verifyOpenNet, verifyViaStateClassGraph, violationDemand, z3Available, z3SolverAt };
|