libpetri 4.0.0 → 4.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.
- package/dist/{chunk-WYCGGQAW.js → chunk-FD3S4TZM.js} +73 -32
- package/dist/chunk-FD3S4TZM.js.map +1 -0
- package/dist/{chunk-KO6TSB47.js → chunk-GJAHGHGT.js} +2 -2
- package/dist/debug/index.d.ts +2 -2
- package/dist/doclet/index.d.ts +1 -1
- package/dist/doclet/resources/petrinet-diagrams.js +1 -1
- package/dist/{event-store-2FOAeUyh.d.ts → event-store-B3ppVTpO.d.ts} +1 -1
- package/dist/export/index.d.ts +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/{petri-net-hduM6tJf.d.ts → petri-net-p0ONpSAO.d.ts} +32 -2
- package/dist/render-dom/index.js +1 -1
- package/dist/verification/index.d.ts +36 -47
- package/dist/verification/index.js +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-WYCGGQAW.js.map +0 -1
- /package/dist/{chunk-KO6TSB47.js.map → chunk-GJAHGHGT.js.map} +0 -0
|
@@ -3528,6 +3528,7 @@ function counterexamplePath(scg, target) {
|
|
|
3528
3528
|
}
|
|
3529
3529
|
|
|
3530
3530
|
// src/verification/smt-verifier.ts
|
|
3531
|
+
var IGNORE_MODE_VACUITY_REASON = "environment places present but not modeled (mode=ignore); a proof would be vacuous \u2014 use alwaysAvailable() or bounded(k) to model external injection";
|
|
3531
3532
|
var SmtVerifier = class _SmtVerifier {
|
|
3532
3533
|
constructor(net) {
|
|
3533
3534
|
this.net = net;
|
|
@@ -3636,13 +3637,26 @@ var SmtVerifier = class _SmtVerifier {
|
|
|
3636
3637
|
* into a chain whose other combinations avoid it (dropped by the H1 guard). On a
|
|
3637
3638
|
* net with a few reset arcs that can lose every law of the chains those arcs
|
|
3638
3639
|
* touch, and without them IC3 has to rediscover the conservation of each chain —
|
|
3639
|
-
* on a ~100-place net it does not within any practical budget.
|
|
3640
|
-
*
|
|
3640
|
+
* on a ~100-place net it does not within any practical budget.
|
|
3641
|
+
*
|
|
3642
|
+
* **Turn this on if the net has any `all()` / `atLeast(n)` or reset arc on a busy
|
|
3643
|
+
* place** — draining an input queue is the everyday case. Every basis row whose
|
|
3644
|
+
* support touches such a place fails the H1 guard and is dropped, so the encoders
|
|
3645
|
+
* run on a deficient invariant set and nothing in the report says a law is missing
|
|
3646
|
+
* beyond the `Dropped` lines.
|
|
3647
|
+
*
|
|
3648
|
+
* This reaches the **name-coloured** encoder (NU-050) as well as the flat one, and
|
|
3649
|
+
* it matters most there. On a 113-place ν-net, whole-net deadlock-freedom went from
|
|
3650
|
+
* `unknown` after 50 minutes to `proven` in about 15 seconds with this option as the
|
|
3651
|
+
* only change; on the flat path, reachability-safety queries that timed out at 120 s
|
|
3652
|
+
* close in about a second.
|
|
3641
3653
|
*
|
|
3642
3654
|
* Soundness is unchanged: the semiflows pass the same exact re-validation as the
|
|
3643
3655
|
* basis rows, the union is pure strengthening (`Semiflow.lean`,
|
|
3644
3656
|
* `semiflow_union_sound`), and the certificate check re-proves the strengthened
|
|
3645
|
-
* invariant
|
|
3657
|
+
* invariant — that check is flat-path only, so a coloured `proven` reports
|
|
3658
|
+
* `Certificate check: not applicable (name-coloured encoding)`. Off by default so
|
|
3659
|
+
* reports stay byte-equal.
|
|
3646
3660
|
*/
|
|
3647
3661
|
semiflowInvariants(enabled) {
|
|
3648
3662
|
this._semiflowInvariants = enabled;
|
|
@@ -3702,6 +3716,48 @@ var SmtVerifier = class _SmtVerifier {
|
|
|
3702
3716
|
this._prioritySemantics = semantics;
|
|
3703
3717
|
return this;
|
|
3704
3718
|
}
|
|
3719
|
+
/**
|
|
3720
|
+
* The name-coloured plan and its encoding, or a null plan when the net is outside
|
|
3721
|
+
* the fragment (NU-050) and a null encoding when the property names a place the net
|
|
3722
|
+
* does not resolve.
|
|
3723
|
+
*
|
|
3724
|
+
* {@link verify} and {@link encodeScripts} share this deliberately. They used to
|
|
3725
|
+
* invoke `buildColouredPlan` and `encodeColoured` separately, so handing the encoder
|
|
3726
|
+
* the wrong one of the two lists changed only one of them — and the script-parity
|
|
3727
|
+
* goldens are generated from `encodeScripts`. Unifying the invocation closes that. It
|
|
3728
|
+
* does not make the two paths identical: each still computes its own invariant and
|
|
3729
|
+
* semiflow lists, so they can still drift through the arguments rather than the call.
|
|
3730
|
+
*
|
|
3731
|
+
* `invariants` is what the encoder conjoins into every rule body (the null-space
|
|
3732
|
+
* basis, unioned with the semiflows when VER-007 is enabled); `semiflows` sets the
|
|
3733
|
+
* colour-slot bound k (NU-053). They are not the same list.
|
|
3734
|
+
*/
|
|
3735
|
+
colouredAttempt(flatNet, invariants, semiflows) {
|
|
3736
|
+
const hasMatch = [...this.net.transitions].some((t) => t.matchSpec !== null);
|
|
3737
|
+
const nuBounded = this._budgetPlaces.size > 0;
|
|
3738
|
+
if (!hasMatch || !nuBounded) return { plan: null, encoding: null };
|
|
3739
|
+
const plan = buildColouredPlan(
|
|
3740
|
+
this.net,
|
|
3741
|
+
flatNet,
|
|
3742
|
+
this._initialMarking,
|
|
3743
|
+
this._budgetPlaces,
|
|
3744
|
+
this._fragmentMode,
|
|
3745
|
+
this._carrierPlaces,
|
|
3746
|
+
semiflows
|
|
3747
|
+
);
|
|
3748
|
+
if (plan == null) return { plan: null, encoding: null };
|
|
3749
|
+
return {
|
|
3750
|
+
plan,
|
|
3751
|
+
encoding: encodeColoured(
|
|
3752
|
+
plan,
|
|
3753
|
+
flatNet,
|
|
3754
|
+
this._initialMarking,
|
|
3755
|
+
this._property,
|
|
3756
|
+
invariants,
|
|
3757
|
+
this._sinkPlaces
|
|
3758
|
+
)
|
|
3759
|
+
};
|
|
3760
|
+
}
|
|
3705
3761
|
/**
|
|
3706
3762
|
* The SMT-LIB2 scripts {@link verify} would send to z3 for this configuration,
|
|
3707
3763
|
* without running a solver (VER-013 AC1): the HORN query (flat, or name-coloured
|
|
@@ -3713,8 +3769,6 @@ var SmtVerifier = class _SmtVerifier {
|
|
|
3713
3769
|
*/
|
|
3714
3770
|
encodeScripts() {
|
|
3715
3771
|
requireOutputProducingActions(this.net);
|
|
3716
|
-
const hasMatch = [...this.net.transitions].some((t) => t.matchSpec !== null);
|
|
3717
|
-
const nuBounded = this._budgetPlaces.size > 0;
|
|
3718
3772
|
const flatNet = flatten(this.net, this._environmentPlaces, this._environmentMode);
|
|
3719
3773
|
const matrix = IncidenceMatrix.from(flatNet);
|
|
3720
3774
|
const { valid: basis } = validateInvariantsExact(
|
|
@@ -3732,20 +3786,9 @@ var SmtVerifier = class _SmtVerifier {
|
|
|
3732
3786
|
let invariants = basis;
|
|
3733
3787
|
if (this._semiflowInvariants) invariants = strengthenWithSemiflows(basis, semiflows).invariants;
|
|
3734
3788
|
invariants = canonicalInvariantOrder(invariants);
|
|
3735
|
-
|
|
3736
|
-
|
|
3737
|
-
|
|
3738
|
-
flatNet,
|
|
3739
|
-
this._initialMarking,
|
|
3740
|
-
this._budgetPlaces,
|
|
3741
|
-
this._fragmentMode,
|
|
3742
|
-
this._carrierPlaces,
|
|
3743
|
-
semiflows
|
|
3744
|
-
);
|
|
3745
|
-
if (plan != null) {
|
|
3746
|
-
const coloured = encodeColoured(plan, flatNet, this._initialMarking, this._property, invariants, this._sinkPlaces);
|
|
3747
|
-
if (coloured != null) return { horn: coloured.smt2, certificate: null, coloured: true };
|
|
3748
|
-
}
|
|
3789
|
+
const attempt = this.colouredAttempt(flatNet, invariants, semiflows);
|
|
3790
|
+
if (attempt.encoding != null) {
|
|
3791
|
+
return { horn: attempt.encoding.smt2, certificate: null, coloured: true };
|
|
3749
3792
|
}
|
|
3750
3793
|
const horn = encode(flatNet, this._initialMarking, this._property, invariants, this._sinkPlaces, this._counterexampleReplay).smt2;
|
|
3751
3794
|
const certificate = vcScript(
|
|
@@ -3796,8 +3839,13 @@ var SmtVerifier = class _SmtVerifier {
|
|
|
3796
3839
|
if (outcome.transitions.length > 0) {
|
|
3797
3840
|
report.push(` Counterexample trace: ${outcome.trace.length} states, ${outcome.transitions.length} transitions`);
|
|
3798
3841
|
}
|
|
3842
|
+
let routeBVerdict = outcome.verdict;
|
|
3843
|
+
if (routeBVerdict.type === "proven" && this._environmentPlaces.size > 0 && this._environmentMode.type === "ignore") {
|
|
3844
|
+
report.push(` Downgraded to UNKNOWN: ${IGNORE_MODE_VACUITY_REASON}`);
|
|
3845
|
+
routeBVerdict = { type: "unknown", reason: IGNORE_MODE_VACUITY_REASON };
|
|
3846
|
+
}
|
|
3799
3847
|
return buildResult(
|
|
3800
|
-
|
|
3848
|
+
routeBVerdict,
|
|
3801
3849
|
report.join("\n"),
|
|
3802
3850
|
[],
|
|
3803
3851
|
[],
|
|
@@ -3903,15 +3951,6 @@ var SmtVerifier = class _SmtVerifier {
|
|
|
3903
3951
|
}
|
|
3904
3952
|
report.push("");
|
|
3905
3953
|
report.push("Phase 4: IC3/PDR verification via Z3 Spacer...");
|
|
3906
|
-
const colouredPlan = hasMatch && nuBounded ? buildColouredPlan(
|
|
3907
|
-
this.net,
|
|
3908
|
-
flatNet,
|
|
3909
|
-
this._initialMarking,
|
|
3910
|
-
this._budgetPlaces,
|
|
3911
|
-
this._fragmentMode,
|
|
3912
|
-
this._carrierPlaces,
|
|
3913
|
-
semiflows
|
|
3914
|
-
) : null;
|
|
3915
3954
|
const stats = {
|
|
3916
3955
|
places: flatNet.places.length,
|
|
3917
3956
|
transitions: flatNet.transitions.length,
|
|
@@ -3932,12 +3971,14 @@ var SmtVerifier = class _SmtVerifier {
|
|
|
3932
3971
|
return buildResult({ type: "unknown", reason }, report.join("\n"), invariants, [], [], [], performance.now() - start, stats);
|
|
3933
3972
|
}
|
|
3934
3973
|
report.push(` Solver: z3 ${formatZ3Version(solver.version)}`);
|
|
3974
|
+
const colouredAttempt = this.colouredAttempt(flatNet, invariants, semiflows);
|
|
3975
|
+
const colouredPlan = colouredAttempt.plan;
|
|
3935
3976
|
let encoding;
|
|
3936
3977
|
if (colouredPlan != null) {
|
|
3937
3978
|
report.push(
|
|
3938
3979
|
` \u03BD-encoding: name-coloured (exact within budget k=${colouredPlan.k}; ${colouredPlan.coloured.length} coloured place(s))`
|
|
3939
3980
|
);
|
|
3940
|
-
const coloured =
|
|
3981
|
+
const coloured = colouredAttempt.encoding;
|
|
3941
3982
|
if (coloured == null) {
|
|
3942
3983
|
const reason = "property names a place that does not resolve in the net; refusing to certify (the encoding would be vacuously proven)";
|
|
3943
3984
|
report.push(" Status: UNKNOWN (unresolved property place)\n");
|
|
@@ -3966,7 +4007,7 @@ var SmtVerifier = class _SmtVerifier {
|
|
|
3966
4007
|
switch (queryResult.type) {
|
|
3967
4008
|
case "proven": {
|
|
3968
4009
|
if (this._environmentPlaces.size > 0 && this._environmentMode.type === "ignore") {
|
|
3969
|
-
const reason =
|
|
4010
|
+
const reason = IGNORE_MODE_VACUITY_REASON;
|
|
3970
4011
|
report.push(` Status: UNSAT, but vacuous under ignore mode
|
|
3971
4012
|
`);
|
|
3972
4013
|
report.push("=== RESULT ===\n");
|
|
@@ -4362,4 +4403,4 @@ export {
|
|
|
4362
4403
|
isProven,
|
|
4363
4404
|
isViolated
|
|
4364
4405
|
};
|
|
4365
|
-
//# sourceMappingURL=chunk-
|
|
4406
|
+
//# sourceMappingURL=chunk-FD3S4TZM.js.map
|