@fairfox/polly 0.15.6 → 0.15.7

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.
@@ -371,6 +371,8 @@ class TLAGenerator {
371
371
  temporalProperties = [];
372
372
  symmetrySets = [];
373
373
  resolvedActionNames = new Map;
374
+ tabSymmetryEnabled = false;
375
+ tabCount = 0;
374
376
  constructor(options) {
375
377
  this.options = options;
376
378
  }
@@ -531,6 +533,7 @@ class TLAGenerator {
531
533
  this.addExtends();
532
534
  this.addConstants(config);
533
535
  this.addMessageTypes(config, analysis);
536
+ this.addTabSymmetry(config);
534
537
  this.addStateType(config, analysis);
535
538
  this.addVariables();
536
539
  if (this.temporalProperties.length > 0) {
@@ -596,7 +599,11 @@ class TLAGenerator {
596
599
  lines.push(` MaxClients = ${messages.maxClients}`);
597
600
  hasProjectConstant = true;
598
601
  }
599
- if ("maxTabs" in messages && messages.maxTabs !== undefined) {
602
+ if (this.tabSymmetryEnabled) {
603
+ for (let i = 0;i < this.tabCount; i++) {
604
+ lines.push(` Tab${i} = Tab${i}`);
605
+ }
606
+ } else if ("maxTabs" in messages && messages.maxTabs !== undefined) {
600
607
  lines.push(` MaxTabId = ${messages.maxTabs}`);
601
608
  } else if (hasProjectConstant) {
602
609
  lines.push(" MaxTabId = 0");
@@ -930,6 +937,39 @@ class TLAGenerator {
930
937
  this.symmetrySets = ["Symmetry"];
931
938
  this.line("");
932
939
  }
940
+ addTabSymmetry(config) {
941
+ if (!config.messages.tabSymmetry) {
942
+ return;
943
+ }
944
+ const maxTabs = config.messages.maxTabs ?? 1;
945
+ this.tabCount = maxTabs + 1;
946
+ this.tabSymmetryEnabled = true;
947
+ this.line("\\* Tab symmetry constants for state space reduction (Tier 1 optimization)");
948
+ this.line("CONSTANTS");
949
+ this.indent++;
950
+ const tabConstants = [];
951
+ for (let i = 0;i <= maxTabs; i++) {
952
+ tabConstants.push(`Tab${i}`);
953
+ }
954
+ this.line(tabConstants.join(", "));
955
+ this.indent--;
956
+ this.line("");
957
+ this.line(`Tabs == {${tabConstants.join(", ")}}`);
958
+ this.line("");
959
+ this.line("TabSymmetry == Permutations(Tabs)");
960
+ this.line("");
961
+ const hasMessageSymmetry = this.symmetrySets.length > 0 && this.symmetrySets[0] === "Symmetry";
962
+ if (hasMessageSymmetry) {
963
+ this.line("\\* Combined symmetry: message types and tabs");
964
+ this.line("AllSymmetry == Symmetry \\cup TabSymmetry");
965
+ this.line("");
966
+ this.symmetrySets = ["AllSymmetry"];
967
+ console.log(`[INFO] [TLAGenerator] Combined symmetry: message symmetry + ${this.tabCount} tabs as model values`);
968
+ } else {
969
+ this.symmetrySets = ["TabSymmetry"];
970
+ console.log(`[INFO] [TLAGenerator] Tab symmetry enabled: ${this.tabCount} tabs as model values`);
971
+ }
972
+ }
933
973
  addVariables() {
934
974
  this.line("\\* Application state per context");
935
975
  this.line("VARIABLE contextStates");
@@ -1684,7 +1724,8 @@ class TLAGenerator {
1684
1724
  if (hasValidHandlers) {
1685
1725
  this.line("\\/ \\E c \\in Contexts : ConnectPort(c) /\\ UNCHANGED <<contextStates, payload>>");
1686
1726
  this.line("\\/ \\E c \\in Contexts : DisconnectPort(c) /\\ UNCHANGED <<contextStates, payload>>");
1687
- this.line("\\/ \\E src \\in Contexts : \\E targetSet \\in (SUBSET Contexts \\ {{}}) : \\E tab \\in 0..MaxTabId : \\E msgType \\in UserMessageTypes :");
1727
+ const tabSet = this.tabSymmetryEnabled ? "Tabs" : "0..MaxTabId";
1728
+ this.line(`\\/ \\E src \\in Contexts : \\E targetSet \\in (SUBSET Contexts \\ {{}}) : \\E tab \\in ${tabSet} : \\E msgType \\in UserMessageTypes :`);
1688
1729
  this.indent++;
1689
1730
  this.line("SendMessage(src, targetSet, tab, msgType) /\\ UNCHANGED <<contextStates, payload>>");
1690
1731
  this.indent--;
@@ -2111,9 +2152,12 @@ class DockerRunner {
2111
2152
  "tlc",
2112
2153
  "-workers",
2113
2154
  `${options?.workers || 1}`,
2114
- "-cleanup",
2115
- `${specName}.tla`
2155
+ "-cleanup"
2116
2156
  ];
2157
+ if (options?.maxDepth !== undefined && options.maxDepth > 0) {
2158
+ args.push("-depth", `${options.maxDepth}`);
2159
+ }
2160
+ args.push(`${specName}.tla`);
2117
2161
  const result = await this.runCommand("docker", args, {
2118
2162
  timeout: options?.timeout
2119
2163
  });
@@ -3037,6 +3081,26 @@ class ConfigValidator {
3037
3081
  }
3038
3082
  }
3039
3083
  }
3084
+ if (messages.tabSymmetry !== undefined) {
3085
+ if (typeof messages.tabSymmetry !== "boolean") {
3086
+ this.issues.push({
3087
+ type: "invalid_value",
3088
+ severity: "error",
3089
+ field: "messages.tabSymmetry",
3090
+ message: "tabSymmetry must be a boolean",
3091
+ suggestion: "Use true or false"
3092
+ });
3093
+ }
3094
+ if (messages.tabSymmetry && (messages.maxTabs === undefined || messages.maxTabs === null)) {
3095
+ this.issues.push({
3096
+ type: "invalid_value",
3097
+ severity: "warning",
3098
+ field: "messages.tabSymmetry",
3099
+ message: "tabSymmetry enabled but maxTabs not set",
3100
+ suggestion: "Set maxTabs to define the number of tabs for symmetry reduction"
3101
+ });
3102
+ }
3103
+ }
3040
3104
  }
3041
3105
  validateVerificationOptions(verification) {
3042
3106
  if (verification.timeout !== undefined) {
@@ -5920,6 +5984,12 @@ function getTimeout(config) {
5920
5984
  function getWorkers(config) {
5921
5985
  return config.verification?.workers ?? 1;
5922
5986
  }
5987
+ function getMaxDepth(config) {
5988
+ if ("tier2" in config && config.tier2?.boundedExploration?.maxDepth) {
5989
+ return config.tier2.boundedExploration.maxDepth;
5990
+ }
5991
+ return;
5992
+ }
5923
5993
  async function runFullVerification(configPath) {
5924
5994
  const config = await loadVerificationConfig(configPath);
5925
5995
  const analysis = await runCodebaseAnalysis();
@@ -5931,6 +6001,7 @@ async function runFullVerification(configPath) {
5931
6001
  const docker = await setupDocker();
5932
6002
  const timeoutSeconds = getTimeout(config);
5933
6003
  const workers = getWorkers(config);
6004
+ const maxDepth = getMaxDepth(config);
5934
6005
  console.log(color("⚙️ Running TLC model checker...", COLORS.blue));
5935
6006
  if (timeoutSeconds === 0) {
5936
6007
  console.log(color(" No timeout set - will run until completion", COLORS.gray));
@@ -5939,10 +6010,14 @@ async function runFullVerification(configPath) {
5939
6010
  const timeoutLabel = timeoutMinutes > 0 ? `${timeoutMinutes} minute${timeoutMinutes > 1 ? "s" : ""}` : `${timeoutSeconds} seconds`;
5940
6011
  console.log(color(` Timeout: ${timeoutLabel}`, COLORS.gray));
5941
6012
  }
6013
+ if (maxDepth !== undefined) {
6014
+ console.log(color(` Max depth: ${maxDepth}`, COLORS.gray));
6015
+ }
5942
6016
  console.log();
5943
6017
  const result = await docker.runTLC(specPath, {
5944
6018
  workers,
5945
- timeout: timeoutSeconds > 0 ? timeoutSeconds * 1000 : undefined
6019
+ timeout: timeoutSeconds > 0 ? timeoutSeconds * 1000 : undefined,
6020
+ maxDepth
5946
6021
  });
5947
6022
  displayVerificationResults(result, specDir);
5948
6023
  }
@@ -6159,4 +6234,4 @@ main().catch((error) => {
6159
6234
  process.exit(1);
6160
6235
  });
6161
6236
 
6162
- //# debugId=3EB612577B3C8CF564756E2164756E21
6237
+ //# debugId=A9938BA1A7CCD3B464756E2164756E21