From 5ac68061418e830a35d04888a70e1031a0f26e22 Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Fri, 20 Jan 2023 09:33:23 -0500 Subject: [PATCH 01/70] Added manifest.json Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- manifest.json | 194 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 manifest.json diff --git a/manifest.json b/manifest.json new file mode 100644 index 00000000..68434e44 --- /dev/null +++ b/manifest.json @@ -0,0 +1,194 @@ +{ + "specifications": [ + { + "title": "The Coffee Can Black/White Bean Problem", + "description": "Math problem published by Dijkstra attributed to Carel Scholten", + "source": "https://stackoverflow.com/a/66304920/2852699", + "authors": ["Andrew Helwer"], + "tags": ["beginner"], + "modules": [ + { + "path": "specifications/CoffeeCan/CoffeeCan.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/CoffeeCan/100BeanCoffeeCan.cfg", + "runtime": "00:00:01", + "features": ["liveness"], + "result": "success" + }, + { + "path": "specifications/CoffeeCan/1000BeanCoffeeCan.cfg", + "runtime": "00:00:15", + "features": ["liveness"], + "result": "success" + }, + { + "path": "specifications/CoffeeCan/3000BeanCoffeeCan.cfg", + "runtime": "00:02:30", + "features": ["liveness"], + "result": "success" + } + ] + } + ] + }, + { + "title": "Key-Value Store with Snapshot Isolation", + "description": "A simple KVS implementing snapshot isolation", + "source": "https://ahelwer.ca", + "authors": ["Andrew Helwer"], + "tags": [], + "modules": [ + { + "path": "specifications/KeyValueStore/KeyValueStore.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/KeyValueStore/MCKeyValueStore.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/KeyValueStore/KVSSafetySmall.cfg", + "runtime": "00:00:40", + "features": [], + "result": "success" + }, + { + "path": "specifications/KeyValueStore/KVSSafetyMedium.cfg", + "runtime": "00:04:30", + "features": ["symmetry"], + "result": "success" + }, + { + "path": "specifications/KeyValueStore/KVSSafetyLarge.cfg", + "runtime": "07:16:00", + "features": ["symmetry"], + "result": "success" + } + ] + } + ] + }, + { + "title": "Multi-Car Elevator System", + "description": "A simple multi-car elevator system servicing a multi-floor building", + "source": "https://groups.google.com/g/tlaplus/c/5Xd8kv288jE/m/IrliJIatBwAJ", + "authors": ["Andrew Helwer"], + "tags": [], + "modules": [ + { + "path": "specifications/MultiCarElevator/Elevator.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/MultiCarElevator/ElevatorLivenessSmall.cfg", + "runtime": "00:00:05", + "features": ["liveness"], + "result": "success" + }, + { + "path": "specifications/MultiCarElevator/ElevatorSafetyMedium.cfg", + "runtime": "00:03:00", + "features": [], + "result": "success" + }, + { + "path": "specifications/MultiCarElevator/ElevatorSafetyLarge.cfg", + "runtime": "00:10:00", + "features": [], + "result": "success" + }, + { + "path": "specifications/MultiCarElevator/ElevatorLivenessLarge.cfg", + "runtime": "00:11:00", + "features": ["liveness"], + "result": "success" + } + ] + } + ] + }, + { + "title": "The Nano Blockchain Protocol", + "description": "A specification of the protocol originally used by the Nano blockchain", + "source": "https://docs.nano.org/whitepaper/english/", + "authors": ["Andrew Helwer"], + "tags": ["blockchain"], + "modules": [ + { + "path": "specifications/NanoBlockchain/Nano.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/NanoBlockchain/MCNano.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/NanoBlockchain/MCNanoSmall.cfg", + "runtime": "00:00:05", + "features": ["view"], + "result": "success" + }, + { + "path": "specifications/NanoBlockchain/MCNanoLarge.cfg", + "runtime": "00:20:00", + "features": ["view"], + "result": "success" + } + ] + } + ] + }, + { + "title": "The Slush Probabilistic Consensus Protocol", + "description": "An attempt to use TLA⁺ to analyze a probabilistic protocol in the Avalanche family", + "source": "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/ahelwer/avalanche-analysis", + "authors": ["Andrew Helwer"], + "tags": ["probability"], + "modules": [ + { + "path": "specifications/SlushProtocol/Slush.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": ["pluscal"], + "models": [ + { + "path": "specifications/SlushProtocol/SlushSmall.cfg", + "runtime": "00:00:08", + "features": [], + "result": "success" + }, + { + "path": "specifications/SlushProtocol/SlushMedium.cfg", + "runtime": "00:01:00", + "features": [], + "result": "success" + }, + { + "path": "specifications/SlushProtocol/SlushLarge.cfg", + "runtime": "00:50:00", + "features": [], + "result": "success" + } + ] + } + ] + } + ] +} + From 82a2ae5b5a51deb39cb7157bec343ef534f00c61 Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Fri, 20 Jan 2023 10:23:53 -0500 Subject: [PATCH 02/70] Defined JSON schema Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/workflows/manifest-schema.json | 58 ++++++++++++++++++++++++++ .gitignore | 23 ++++++---- 2 files changed, 73 insertions(+), 8 deletions(-) create mode 100644 .github/workflows/manifest-schema.json diff --git a/.github/workflows/manifest-schema.json b/.github/workflows/manifest-schema.json new file mode 100644 index 00000000..3b11031e --- /dev/null +++ b/.github/workflows/manifest-schema.json @@ -0,0 +1,58 @@ +{ + "type" : "object", + "properties" : { + "specifications" : { + "type": "array", + "items": { + "type": "object", + "properties": { + "title": {"type": "string"}, + "description": {"type": "string"}, + "source": {"type": "string"}, + "authors": { + "type": "array", + "items": {"type": "string"} + }, + "tags": { + "type": "array", + "items": {"enum": ["beginner", "blockchain", "probability"]} + }, + "modules": { + "type": "array", + "items": { + "type": "object", + "properties": { + "path": {"type": "string"}, + "communityDependencies": { + "type": "array", + "items": {"type": "string"} + }, + "tlaLanguageVersion": {"type": "number"}, + "features": { + "type": "array", + "items": {"enum": ["pluscal", "proof"]} + }, + "models": { + "type": "array", + "items": { + "type": "object", + "properties": { + "path": {"type": "string"}, + "runtime": {"type": "string"}, + "features": { + "type": "array", + "items": {"enum": ["liveness", "symmetry", "view"]} + }, + "result": {"enum": ["success", "safety failure", "liveness failure", "deadlock"]} + } + } + } + } + } + } + } + } + } + } +} + diff --git a/.gitignore b/.gitignore index f1d13c16..38f977dd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,27 +1,34 @@ -## Blacklist all files +## Ignore all files by default * -## Whitelist TLA+ files +## Don't ignore TLA+ files !*.tla -## Whitelist TLC model config and results +## Don't ignore TLC model config and results !*.cfg !*.out ## Usually .out files are small -## Whitelist Toolbox model metadata +## Don't ignore Toolbox model metadata !*.launch -## Whitelist Toolbox spec metadata +## Don't ignore Toolbox spec metadata !.project !*.prefs -## Whitelist PDFs +## Don't ignore PDFs !*.pdf -## Whitelist all folders +## Don't ignore all folders !*/ -## Blacklist TLAPS cache folder +## Ignore TLAPS cache folder ## See https://github.com/tlaplus/tlapm/issues/16 __tlacache__ .tlacache + +## Don't ignore CI files +!.github/** + +## Don't ignore READMEs +!*.md + From f771915c0c5900b9844c7fb6b376218e0481b5d8 Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Fri, 20 Jan 2023 10:52:13 -0500 Subject: [PATCH 03/70] Added py script to validate json schema Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/workflows/CI.yml | 39 +++++++++++++++++++ .../workflows/scripts/check-against-schema.py | 14 +++++++ .../{ => scripts}/manifest-schema.json | 0 .github/workflows/scripts/requirements.txt | 3 ++ 4 files changed, 56 insertions(+) create mode 100644 .github/workflows/CI.yml create mode 100644 .github/workflows/scripts/check-against-schema.py rename .github/workflows/{ => scripts}/manifest-schema.json (100%) create mode 100644 .github/workflows/scripts/requirements.txt diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml new file mode 100644 index 00000000..ee4c5670 --- /dev/null +++ b/.github/workflows/CI.yml @@ -0,0 +1,39 @@ +name: Metadata Validation +on: + push: + branches: + - master + pull_request: + branches: + - master +jobs: + validate-metadata: + runs-on: ubuntu-latest + env: + TSTLA_VERSION: 1.0.1 + steps: + - name: Clone repo + uses: actions/checkout@v2 + - name: Install python + uses: actions/setup-python@v4 + with: + python-version: '3.11' + - name: Install packages + working-directory: ./.github/workflows/scripts + run: pip install -r requirements.txt + - name: Get tree-sitter-tlaplus + working-directory: ./.github/workflows/scripts + run: | + wget https://github.com/tlaplus-community/tree-sitter-tlaplus/archive/refs/tags/v$TSTLA_VERSION.tar.gz + tar -xf v$TSTLA_VERSION.tar.gz + - name: Check manifest.json format + run: python check-against-schema.py + - name: Check manifest completeness + run: python check-manifest-completeness.py + - name: Check manifest feature flags + run: python check-manifest-feature-flags.py + - name: Check TLA⁺ specs parse + run: python check-specs-parse.py + - name: Check TLC models run + run: python check-models-run.py + diff --git a/.github/workflows/scripts/check-against-schema.py b/.github/workflows/scripts/check-against-schema.py new file mode 100644 index 00000000..54fdd738 --- /dev/null +++ b/.github/workflows/scripts/check-against-schema.py @@ -0,0 +1,14 @@ +import json +from jsonschema import validate + +schema_file = open('.github/workflows/scripts/manifest-schema.json', 'rt') +manifest_file = open('manifest.json', 'rt') +schema = json.load(schema_file) +manifest = json.load(manifest_file) +result = validate(instance=manifest, schema=schema) +if None == result: + exit(0) +else: + print(result) + exit(1) + diff --git a/.github/workflows/manifest-schema.json b/.github/workflows/scripts/manifest-schema.json similarity index 100% rename from .github/workflows/manifest-schema.json rename to .github/workflows/scripts/manifest-schema.json diff --git a/.github/workflows/scripts/requirements.txt b/.github/workflows/scripts/requirements.txt new file mode 100644 index 00000000..7dbb4656 --- /dev/null +++ b/.github/workflows/scripts/requirements.txt @@ -0,0 +1,3 @@ +jsonschema == 4.17.3 +tree-sitter==0.20.1 + From 518db846e510640f72466270f5fbe01a7e98d173 Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Fri, 20 Jan 2023 15:30:28 -0500 Subject: [PATCH 04/70] Added py script to check manifest file existence Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/workflows/CI.yml | 6 +-- .github/workflows/main.yml | 8 +++- .../workflows/scripts/check-against-schema.py | 2 + .../check-manifest-file-correspondence.py | 41 +++++++++++++++++++ 4 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/scripts/check-manifest-file-correspondence.py diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index ee4c5670..2da50eb1 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -27,9 +27,9 @@ jobs: wget https://github.com/tlaplus-community/tree-sitter-tlaplus/archive/refs/tags/v$TSTLA_VERSION.tar.gz tar -xf v$TSTLA_VERSION.tar.gz - name: Check manifest.json format - run: python check-against-schema.py - - name: Check manifest completeness - run: python check-manifest-completeness.py + run: python ./.github/workflows/scripts/check-against-schema.py + - name: Check manifest files + run: python ./.github/workflows/scripts/check-manifest-file-correspondence.py - name: Check manifest feature flags run: python check-manifest-feature-flags.py - name: Check TLA⁺ specs parse diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 171a9e70..a3a07ea0 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,6 +1,10 @@ name: CI - -on: [push, workflow_dispatch, workflow_call] +on: + push: + branches: + - master + workflow_dispatch: + workflow_call: jobs: build: diff --git a/.github/workflows/scripts/check-against-schema.py b/.github/workflows/scripts/check-against-schema.py index 54fdd738..9ffe3929 100644 --- a/.github/workflows/scripts/check-against-schema.py +++ b/.github/workflows/scripts/check-against-schema.py @@ -1,3 +1,5 @@ +# Checks to ensure manifest.json is valid according to schema + import json from jsonschema import validate diff --git a/.github/workflows/scripts/check-manifest-file-correspondence.py b/.github/workflows/scripts/check-manifest-file-correspondence.py new file mode 100644 index 00000000..8f8c500f --- /dev/null +++ b/.github/workflows/scripts/check-manifest-file-correspondence.py @@ -0,0 +1,41 @@ +# Checks to ensure all files in manifest.json exist, and that all .tla and +# .cfg files in repo are recorded in manifest.json + +import json +from os.path import exists, normpath +import glob + +manifest_file = open('manifest.json', 'rt') +manifest = json.load(manifest_file) + +module_lists = [spec["modules"] for spec in manifest["specifications"]] +modules = [module for module_list in module_lists for module in module_list] +module_paths = set([normpath(module["path"]) for module in modules]) +model_lists = [module["models"] for module in modules] +model_paths = set([normpath(model["path"]) for model_list in model_lists for model in model_list]) + +missing_module_files = [path for path in module_paths if not exists(path)] +missing_model_files = [path for path in model_paths if not exists(path)] + +any_missing = False +if any(missing_module_files): + any_missing = True + print('Module files not found:\n' + '\n'.join(missing_module_files)) +if any(missing_model_files): + any_missing = True + print('Model files not found:\n' + '\n'.join(missing_model_files)) + +tla_files = set([normpath(path) for path in glob.glob(f"./specifications/**/*.tla", recursive=True)]) +cfg_files = set([normpath(path) for path in glob.glob(f"./specifications/**/*.cfg", recursive=True)]) +missing_module_paths = tla_files - module_paths +missing_model_paths = cfg_files - model_paths + +if any(missing_module_paths): + any_missing = True + print('Module files not included in manifest:\n' + '\n'.join(missing_module_paths)) +if any(missing_model_paths): + any_missing = True + print('Model files not included in manifest:\n' + '\n'.join(missing_model_paths)) + +exit(1 if any_missing else 0) + From bcbc9666ae39324f6529617ca1160c9d65cb331b Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Sat, 21 Jan 2023 09:49:12 -0500 Subject: [PATCH 05/70] Added script to check feature flags with tree-sitter queries Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/workflows/CI.yml | 24 +++++------ .../workflows/scripts/check-against-schema.py | 12 ++++-- .../scripts/check-manifest-feature-flags.py | 42 +++++++++++++++++++ .../check-manifest-file-correspondence.py | 5 ++- .../workflows/scripts/manifest-schema.json | 14 ++++++- manifest.json | 15 +++++++ 6 files changed, 93 insertions(+), 19 deletions(-) create mode 100644 .github/workflows/scripts/check-manifest-feature-flags.py diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 2da50eb1..c154f956 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -1,4 +1,4 @@ -name: Metadata Validation +name: Check Specs & Metadata on: push: branches: @@ -11,6 +11,7 @@ jobs: runs-on: ubuntu-latest env: TSTLA_VERSION: 1.0.1 + SCRIPT_DIR: ./.github/workflows/scripts steps: - name: Clone repo uses: actions/checkout@v2 @@ -18,22 +19,21 @@ jobs: uses: actions/setup-python@v4 with: python-version: '3.11' - - name: Install packages - working-directory: ./.github/workflows/scripts - run: pip install -r requirements.txt + - name: Install python packages + run: pip install -r $SCRIPT_DIR/requirements.txt + - name: Check manifest.json format + run: python $SCRIPT_DIR/check-against-schema.py + - name: Check manifest files + run: python $SCRIPT_DIR/check-manifest-file-correspondence.py - name: Get tree-sitter-tlaplus - working-directory: ./.github/workflows/scripts run: | wget https://github.com/tlaplus-community/tree-sitter-tlaplus/archive/refs/tags/v$TSTLA_VERSION.tar.gz tar -xf v$TSTLA_VERSION.tar.gz - - name: Check manifest.json format - run: python ./.github/workflows/scripts/check-against-schema.py - - name: Check manifest files - run: python ./.github/workflows/scripts/check-manifest-file-correspondence.py + mv tree-sitter-tlaplus-$TSTLA_VERSION tree-sitter-tlaplus - name: Check manifest feature flags - run: python check-manifest-feature-flags.py + run: python $SCRIPT_DIR/check-manifest-feature-flags.py - name: Check TLA⁺ specs parse - run: python check-specs-parse.py + run: python $SCRIPT_DIR/check-specs-parse.py - name: Check TLC models run - run: python check-models-run.py + run: python $SCRIPT_DIR/check-models-run.py diff --git a/.github/workflows/scripts/check-against-schema.py b/.github/workflows/scripts/check-against-schema.py index 9ffe3929..78bbfff9 100644 --- a/.github/workflows/scripts/check-against-schema.py +++ b/.github/workflows/scripts/check-against-schema.py @@ -3,10 +3,14 @@ import json from jsonschema import validate -schema_file = open('.github/workflows/scripts/manifest-schema.json', 'rt') -manifest_file = open('manifest.json', 'rt') -schema = json.load(schema_file) -manifest = json.load(manifest_file) +schema = None +with open('.github/workflows/scripts/manifest-schema.json', 'rt') as schema_file: + schema = json.load(schema_file) + +manifest = None +with open('manifest.json', 'rt') as manifest_file: + manifest = json.load(manifest_file) + result = validate(instance=manifest, schema=schema) if None == result: exit(0) diff --git a/.github/workflows/scripts/check-manifest-feature-flags.py b/.github/workflows/scripts/check-manifest-feature-flags.py new file mode 100644 index 00000000..5c23225d --- /dev/null +++ b/.github/workflows/scripts/check-manifest-feature-flags.py @@ -0,0 +1,42 @@ +import json +from tree_sitter import Language, Parser + +Language.build_library( + 'build/tree-sitter-languages.so', + ['tree-sitter-tlaplus'] +) + +manifest = None +with open('manifest.json', 'rt') as manifest_file: + manifest = json.load(manifest_file) + +TLAPLUS_LANGUAGE = Language('build/tree-sitter-languages.so', 'tlaplus') +parser = Parser() +parser.set_language(TLAPLUS_LANGUAGE) + +pcal_name = 'pluscal' +proof_name = 'proof' +query = TLAPLUS_LANGUAGE.query( + f'(pcal_algorithm_start) @{pcal_name}' + + f'[(terminal_proof) (non_terminal_proof)] @{proof_name}' +) + +success = True +for spec in manifest['specifications']: + for module in spec['modules']: + module_text = None + with open(module['path'], 'rb') as module_file: + module_text = module_file.read() + tree = parser.parse(module_text) + captures = query.captures(tree.root_node) + expected_features = set([name for _, name in captures]) + actual_features = set(module['features']) + if expected_features != actual_features: + success = False + print( + f'Module {module["path"]} has incorrect features in manifest; ' + + f'expected {list(expected_features)}, actual {list(actual_features)}' + ) + +exit(0 if success else 1) + diff --git a/.github/workflows/scripts/check-manifest-file-correspondence.py b/.github/workflows/scripts/check-manifest-file-correspondence.py index 8f8c500f..2d1867b9 100644 --- a/.github/workflows/scripts/check-manifest-file-correspondence.py +++ b/.github/workflows/scripts/check-manifest-file-correspondence.py @@ -5,8 +5,9 @@ from os.path import exists, normpath import glob -manifest_file = open('manifest.json', 'rt') -manifest = json.load(manifest_file) +manifest = None +with open('manifest.json', 'rt') as manifest_file: + manifest = json.load(manifest_file) module_lists = [spec["modules"] for spec in manifest["specifications"]] modules = [module for module_list in module_lists for module in module_list] diff --git a/.github/workflows/scripts/manifest-schema.json b/.github/workflows/scripts/manifest-schema.json index 3b11031e..49fb240d 100644 --- a/.github/workflows/scripts/manifest-schema.json +++ b/.github/workflows/scripts/manifest-schema.json @@ -1,10 +1,14 @@ { "type" : "object", + "required": ["specifications"], + "additionalProperties": false, "properties" : { "specifications" : { "type": "array", "items": { "type": "object", + "required": ["title", "description", "source", "authors", "tags", "modules"], + "additionalProperties": false, "properties": { "title": {"type": "string"}, "description": {"type": "string"}, @@ -21,6 +25,8 @@ "type": "array", "items": { "type": "object", + "required": ["path", "communityDependencies", "tlaLanguageVersion", "features", "models"], + "additionalProperties": false, "properties": { "path": {"type": "string"}, "communityDependencies": { @@ -36,9 +42,15 @@ "type": "array", "items": { "type": "object", + "additionalProperties": false, + "required": ["path", "runtime", "size", "features", "result"], "properties": { "path": {"type": "string"}, - "runtime": {"type": "string"}, + "runtime": { + "type": "string", + "pattern": "^[0-9][0-9]:[0-9][0-9]:[0-9][0-9]$" + }, + "size": {"enum": ["small", "medium", "large"]}, "features": { "type": "array", "items": {"enum": ["liveness", "symmetry", "view"]} diff --git a/manifest.json b/manifest.json index 68434e44..751f6c42 100644 --- a/manifest.json +++ b/manifest.json @@ -16,18 +16,21 @@ { "path": "specifications/CoffeeCan/100BeanCoffeeCan.cfg", "runtime": "00:00:01", + "size": "small", "features": ["liveness"], "result": "success" }, { "path": "specifications/CoffeeCan/1000BeanCoffeeCan.cfg", "runtime": "00:00:15", + "size": "medium", "features": ["liveness"], "result": "success" }, { "path": "specifications/CoffeeCan/3000BeanCoffeeCan.cfg", "runtime": "00:02:30", + "size": "medium", "features": ["liveness"], "result": "success" } @@ -58,18 +61,21 @@ { "path": "specifications/KeyValueStore/KVSSafetySmall.cfg", "runtime": "00:00:40", + "size": "medium", "features": [], "result": "success" }, { "path": "specifications/KeyValueStore/KVSSafetyMedium.cfg", "runtime": "00:04:30", + "size": "medium", "features": ["symmetry"], "result": "success" }, { "path": "specifications/KeyValueStore/KVSSafetyLarge.cfg", "runtime": "07:16:00", + "size": "large", "features": ["symmetry"], "result": "success" } @@ -93,24 +99,28 @@ { "path": "specifications/MultiCarElevator/ElevatorLivenessSmall.cfg", "runtime": "00:00:05", + "size": "small", "features": ["liveness"], "result": "success" }, { "path": "specifications/MultiCarElevator/ElevatorSafetyMedium.cfg", "runtime": "00:03:00", + "size": "medium", "features": [], "result": "success" }, { "path": "specifications/MultiCarElevator/ElevatorSafetyLarge.cfg", "runtime": "00:10:00", + "size": "large", "features": [], "result": "success" }, { "path": "specifications/MultiCarElevator/ElevatorLivenessLarge.cfg", "runtime": "00:11:00", + "size": "large", "features": ["liveness"], "result": "success" } @@ -141,12 +151,14 @@ { "path": "specifications/NanoBlockchain/MCNanoSmall.cfg", "runtime": "00:00:05", + "size": "small", "features": ["view"], "result": "success" }, { "path": "specifications/NanoBlockchain/MCNanoLarge.cfg", "runtime": "00:20:00", + "size": "large", "features": ["view"], "result": "success" } @@ -170,18 +182,21 @@ { "path": "specifications/SlushProtocol/SlushSmall.cfg", "runtime": "00:00:08", + "size": "small", "features": [], "result": "success" }, { "path": "specifications/SlushProtocol/SlushMedium.cfg", "runtime": "00:01:00", + "size": "medium", "features": [], "result": "success" }, { "path": "specifications/SlushProtocol/SlushLarge.cfg", "runtime": "00:50:00", + "size": "large", "features": [], "result": "success" } From ec999d069577da7ee7974708859cfea4188ab2d5 Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Sat, 21 Jan 2023 16:17:32 -0500 Subject: [PATCH 06/70] Added a bunch of specs to manifest Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/workflows/CI.yml | 10 +- .../workflows/scripts/check-against-schema.py | 2 +- .../scripts/check-manifest-feature-flags.py | 9 +- ...nifest-schema.json => manifest-schema.json | 21 +- manifest.json | 379 ++++++++++++++++++ 5 files changed, 407 insertions(+), 14 deletions(-) rename .github/workflows/scripts/manifest-schema.json => manifest-schema.json (77%) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index c154f956..3cb1cced 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -32,8 +32,10 @@ jobs: mv tree-sitter-tlaplus-$TSTLA_VERSION tree-sitter-tlaplus - name: Check manifest feature flags run: python $SCRIPT_DIR/check-manifest-feature-flags.py - - name: Check TLA⁺ specs parse - run: python $SCRIPT_DIR/check-specs-parse.py - - name: Check TLC models run - run: python $SCRIPT_DIR/check-models-run.py +# - name: Get nightly TLA⁺ tools +# run: wget https://nightly.tlapl.us/dist/tla2tools.jar +# - name: Check TLA⁺ specs parse +# run: python $SCRIPT_DIR/check-specs-parse.py +# - name: Check TLC models run +# run: python $SCRIPT_DIR/check-models-run.py diff --git a/.github/workflows/scripts/check-against-schema.py b/.github/workflows/scripts/check-against-schema.py index 78bbfff9..fea57517 100644 --- a/.github/workflows/scripts/check-against-schema.py +++ b/.github/workflows/scripts/check-against-schema.py @@ -4,7 +4,7 @@ from jsonschema import validate schema = None -with open('.github/workflows/scripts/manifest-schema.json', 'rt') as schema_file: +with open('manifest-schema.json', 'rt') as schema_file: schema = json.load(schema_file) manifest = None diff --git a/.github/workflows/scripts/check-manifest-feature-flags.py b/.github/workflows/scripts/check-manifest-feature-flags.py index 5c23225d..b4c8025d 100644 --- a/.github/workflows/scripts/check-manifest-feature-flags.py +++ b/.github/workflows/scripts/check-manifest-feature-flags.py @@ -14,11 +14,9 @@ parser = Parser() parser.set_language(TLAPLUS_LANGUAGE) -pcal_name = 'pluscal' -proof_name = 'proof' query = TLAPLUS_LANGUAGE.query( - f'(pcal_algorithm_start) @{pcal_name}' - + f'[(terminal_proof) (non_terminal_proof)] @{proof_name}' + '(pcal_algorithm_start) @pluscal' + + '[(terminal_proof) (non_terminal_proof)] @proof' ) success = True @@ -28,6 +26,9 @@ with open(module['path'], 'rb') as module_file: module_text = module_file.read() tree = parser.parse(module_text) + if tree.root_node.has_error: + success = False + print(f'Module {module["path"]} contains syntax errors') captures = query.captures(tree.root_node) expected_features = set([name for _, name in captures]) actual_features = set(module['features']) diff --git a/.github/workflows/scripts/manifest-schema.json b/manifest-schema.json similarity index 77% rename from .github/workflows/scripts/manifest-schema.json rename to manifest-schema.json index 49fb240d..1919b06e 100644 --- a/.github/workflows/scripts/manifest-schema.json +++ b/manifest-schema.json @@ -31,7 +31,18 @@ "path": {"type": "string"}, "communityDependencies": { "type": "array", - "items": {"type": "string"} + "items": { + "type": "object", + "required": ["name", "version"], + "additionalProperties": false, + "properties": { + "name": {"type": "string"}, + "version": { + "type": "string", + "pattern": "^[0-9a-fA-F]{40}$" + } + } + } }, "tlaLanguageVersion": {"type": "number"}, "features": { @@ -48,14 +59,14 @@ "path": {"type": "string"}, "runtime": { "type": "string", - "pattern": "^[0-9][0-9]:[0-9][0-9]:[0-9][0-9]$" + "pattern": "^(([0-9][0-9]:[0-9][0-9]:[0-9][0-9])|unknown)$" }, - "size": {"enum": ["small", "medium", "large"]}, + "size": {"enum": ["small", "medium", "large", "unknown"]}, "features": { "type": "array", - "items": {"enum": ["liveness", "symmetry", "view"]} + "items": {"enum": ["liveness", "symmetry", "view", "alias", "state constraint"]} }, - "result": {"enum": ["success", "safety failure", "liveness failure", "deadlock"]} + "result": {"enum": ["success", "safety failure", "liveness failure", "deadlock", "unknown"]} } } } diff --git a/manifest.json b/manifest.json index 751f6c42..16934474 100644 --- a/manifest.json +++ b/manifest.json @@ -1,5 +1,166 @@ { "specifications": [ + { + "title": "", + "description": "", + "source": "", + "authors": [], + "tags": [], + "modules": [ + { + "path": "specifications/", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/", + "runtime": "unknown", + "size": "unknown", + "features": [], + "result": "unknown" + } + ] + } + ] + }, + { + "title": "The Boulangerie Algorithm", + "description": "Spec of a variant of the Bakery Algorithm", + "source": "https://doi.org/10.1007/978-3-319-25258-2_28", + "authors": [], + "tags": [], + "modules": [ + { + "path": "specifications/Bakery-Boulangerie/Bakery.tla", + "communityDependencies": ["Leslie Lamport", "Stephan Merz"], + "tlaLanguageVersion": 2, + "features": ["pluscal", "proof"], + "models": [] + }, + { + "path": "specifications/Bakery-Boulangerie/Boulanger.tla", + "communityDependencies": ["Leslie Lamport", "Stephan Merz"], + "tlaLanguageVersion": 2, + "features": ["pluscal", "proof"], + "models": [] + } + ] + }, + { + "title": "The Car Talk Puzzle", + "description": "Math puzzle involving a farmer, a stone, and a balance scale", + "source": "Car Talk radio program, 22 October 2011", + "authors": ["Leslie Lamport"], + "tags": ["beginner"], + "modules": [ + { + "path": "specifications/CarTalkPuzzle/CarTalkPuzzle.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [], + }, + { + "path": "specifications/CarTalkPuzzle/CarTalkPuzzle.toolbox/Model_1/CarTalkPuzzle.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [], + }, + { + "path": "specifications/CarTalkPuzzle/CarTalkPuzzle.toolbox/Model_1/MC.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/CarTalkPuzzle/CarTalkPuzzle.toolbox/Model_1/MC.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [], + "result": "unknown" + } + ], + }, + { + "path": "specifications/CarTalkPuzzle/CarTalkPuzzle.toolbox/Model_2/CarTalkPuzzle.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [], + }, + { + "path": "specifications/CarTalkPuzzle/CarTalkPuzzle.toolbox/Model_2/MC.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/CarTalkPuzzle/CarTalkPuzzle.toolbox/Model_2/MC.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [], + "result": "unknown" + } + ], + }, + { + "path": "specifications/CarTalkPuzzle/CarTalkPuzzle.toolbox/Model_3/CarTalkPuzzle.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [], + }, + { + "path": "specifications/CarTalkPuzzle/CarTalkPuzzle.toolbox/Model_3/MC.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/CarTalkPuzzle/CarTalkPuzzle.toolbox/Model_3/MC.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [], + "result": "unknown" + } + ], + }, + ] + }, + { + "title": "Chameneos, a Concurrency Game", + "description": "A concurrency game requiring concurrent & symmetric cooperation", + "source": "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/mryndzionek/tlaplus_specs#chameneostla", + "authors": ["Mariusz Ryndzionek"], + "tags": [], + "modules": [ + { + "path": "specifications/Chameneos/Chameneos.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + } + ] + }, + { + "title": "The Cigarette Smokers Problem", + "description": "A concurrency problem described in 1971 by Suhas Patil", + "source": "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/mryndzionek/tlaplus_specs#cigarettesmokerstla", + "authors": ["Mariusz Ryndzionek"], + "tags": [], + "modules": [ + { + "path": "specifications/Chameneos/Chameneos.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + } + ] + }, { "title": "The Coffee Can Black/White Bean Problem", "description": "Math problem published by Dijkstra attributed to Carel Scholten", @@ -38,6 +199,140 @@ } ] }, + { + "title": "The Die Hard Problem", + "description": "Obtain 4 gallons of water using only 3 and 5 gallon jugs", + "source": "https://en.wikipedia.org/wiki/Water_pouring_puzzle", + "authors": ["Leslie Lamport"], + "tags": ["beginner"], + "modules": [ + { + "path": "specifications/DieHard/DieHard.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/DieHard/DieHard.cfg", + "runtime": "00:00:01", + "size": "small", + "features": [], + "result": "safety failure" + } + ] + }, + { + "path": "specifications/DieHard/DieHarder.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/DieHard/MCDieHarder.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/DieHard/MCDieHarder.cfg", + "runtime": "00:00:01", + "size": "small", + "features": [], + "result": "safety failure" + } + ] + } + ] + }, + { + "title": "The Dining Philosophers Problem", + "description": "The Chandy-Misra solution to the Dining Philosophers concurrency problem", + "source": "https://en.wikipedia.org/wiki/Dining_philosophers_problem#Chandy/Misra_solution", + "authors": ["Jeff Hemphill"], + "tags": ["beginner"], + "modules": [ + { + "path": "specifications/DiningPhilosophers/DiningPhilosophers.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": ["pluscal"], + "models": [ + { + "path": "specifications/DiningPhilosophers/DiningPhilosophers.cfg", + "runtime": "unknown", + "size": "unknown", + "features": ["liveness"], + "result": "unknown" + } + ] + } + ] + }, + { + "title": "Einstein's Riddle", + "description": "Five houses, five people, various facts, who lives in what house?", + "source": "https://en.wikipedia.org/wiki/Zebra_Puzzle", + "authors": ["Isaac DeFrain"], + "tags": ["beginner"], + "modules": [ + { + "path": "specifications/EinsteinRiddle/Einstein.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/EinsteinRiddle/Einstein.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [], + "result": "safety failure" + } + ] + } + ] + }, + { + "title": "Conway's Game of Life", + "description": "The famous cellular automata simulation", + "source": "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/mryndzionek/tlaplus_specs#gameoflifetla", + "authors": ["Mariusz Ryndzionek"], + "tags": [], + "modules": [ + { + "path": "specifications/GameOfLife/GameOfLife.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + } + ] + }, + { + "title": "Huang's Algorithm", + "description": "An algorithm for detecting termination in a distributed system", + "source": "https://en.wikipedia.org/wiki/Huang%27s_algorithm", + "authors": ["Markus Kuppe"], + "tags": [], + "modules": [ + { + "path": "specifications/Huang/Huang.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/Huang/Huang.cfg", + "runtime": "unknown", + "size": "unknown", + "features": ["liveness", "state constraint", "alias"], + "result": "unknown" + } + ] + } + ] + }, { "title": "Key-Value Store with Snapshot Isolation", "description": "A simple KVS implementing snapshot isolation", @@ -83,6 +378,90 @@ } ] }, + { + "title": "The Knuth-Yao Method", + "description": "A method for simulating a fair 6-sided die using only coin flips", + "source": "https://old.reddit.com/r/tlaplus/comments/j06ohw/how_do_you_reason_about_a_probabilistic/g6owlxy/", + "authors": ["Ron Pressler", "Markus Kuppe"], + "tags": [], + "modules": [ + { + "path": "specifications/KnuthYao/KnuthYao.tla", + "communityDependencies": ["DyadicRationals"], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/KnuthYao/Prob.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/KnuthYao/SimKnuthYao.tla", + "communityDependencies": ["DyadicRationals", "Functions", "CSV", "TLCExt", "IOUtils", "Statistics"], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/KnuthYao/SimKnuthYao.cfg", + "runtime": "unknown", + "size": "unknown", + "features": ["state constraint"], + "result": "unknown" + } + ] + } + ] + }, + { + "title": "TLA⁺ Level Checking", + "description": "Level-checking of TLA⁺ formulas as described in Specifying Systems", + "source": "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/tlaplus/tlaplus/blob/6bc82f7746ccdfbdf49cdef24448666d11e5e218/tlatools/org.lamport.tlatools/src/tla2sany/semantic/LevelNode.java#L354-L2778", + "authors": ["Leslie Lamport"], + "tags": [], + "modules": [ + { + "path": "specifications/LevelChecking/LevelSpec.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + } + ] + }, + { + "title": "Loop Invariance", + "description": "Examples of finding and proving loop invariants in PlusCal", + "source": "http://lamport.azurewebsites.net/tla/proving-safety.pdf", + "authors": ["Leslie Lamport"], + "tags": [], + "modules": [ + { + "path": "specifications/LoopInvariance/BinarySearch.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": ["pluscal", "proof"], + "models": [] + }, + { + "path": "specifications/LoopInvariance/Quicksort.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": ["pluscal", "proof"], + "models": [] + }, + { + "path": "specifications/LoopInvariance/SumSequence.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": ["pluscal", "proof"], + "models": [] + } + ] + }, { "title": "Multi-Car Elevator System", "description": "A simple multi-car elevator system servicing a multi-floor building", From ea22f65802392779c3dc2b006a221e7da1a85005 Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Sat, 21 Jan 2023 17:58:52 -0500 Subject: [PATCH 07/70] Added some more specs to the manifest Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- manifest-schema.json | 2 +- manifest.json | 109 +++++++++++++++++++++++++++++-------------- 2 files changed, 76 insertions(+), 35 deletions(-) diff --git a/manifest-schema.json b/manifest-schema.json index 1919b06e..c2d3f21b 100644 --- a/manifest-schema.json +++ b/manifest-schema.json @@ -7,7 +7,7 @@ "type": "array", "items": { "type": "object", - "required": ["title", "description", "source", "authors", "tags", "modules"], + "required": ["title", "description", "authors", "tags", "modules"], "additionalProperties": false, "properties": { "title": {"type": "string"}, diff --git a/manifest.json b/manifest.json index 16934474..ed4c1a92 100644 --- a/manifest.json +++ b/manifest.json @@ -1,46 +1,21 @@ { "specifications": [ - { - "title": "", - "description": "", - "source": "", - "authors": [], - "tags": [], - "modules": [ - { - "path": "specifications/", - "communityDependencies": [], - "tlaLanguageVersion": 2, - "features": [], - "models": [ - { - "path": "specifications/", - "runtime": "unknown", - "size": "unknown", - "features": [], - "result": "unknown" - } - ] - } - ] - }, { "title": "The Boulangerie Algorithm", "description": "Spec of a variant of the Bakery Algorithm", - "source": "https://doi.org/10.1007/978-3-319-25258-2_28", - "authors": [], + "authors": ["Leslie Lamport", "Stephan Merz"], "tags": [], "modules": [ { "path": "specifications/Bakery-Boulangerie/Bakery.tla", - "communityDependencies": ["Leslie Lamport", "Stephan Merz"], + "communityDependencies": [], "tlaLanguageVersion": 2, "features": ["pluscal", "proof"], "models": [] }, { "path": "specifications/Bakery-Boulangerie/Boulanger.tla", - "communityDependencies": ["Leslie Lamport", "Stephan Merz"], + "communityDependencies": [], "tlaLanguageVersion": 2, "features": ["pluscal", "proof"], "models": [] @@ -50,7 +25,6 @@ { "title": "The Car Talk Puzzle", "description": "Math puzzle involving a farmer, a stone, and a balance scale", - "source": "Car Talk radio program, 22 October 2011", "authors": ["Leslie Lamport"], "tags": ["beginner"], "modules": [ @@ -202,7 +176,6 @@ { "title": "The Die Hard Problem", "description": "Obtain 4 gallons of water using only 3 and 5 gallon jugs", - "source": "https://en.wikipedia.org/wiki/Water_pouring_puzzle", "authors": ["Leslie Lamport"], "tags": ["beginner"], "modules": [ @@ -248,7 +221,6 @@ { "title": "The Dining Philosophers Problem", "description": "The Chandy-Misra solution to the Dining Philosophers concurrency problem", - "source": "https://en.wikipedia.org/wiki/Dining_philosophers_problem#Chandy/Misra_solution", "authors": ["Jeff Hemphill"], "tags": ["beginner"], "modules": [ @@ -272,7 +244,6 @@ { "title": "Einstein's Riddle", "description": "Five houses, five people, various facts, who lives in what house?", - "source": "https://en.wikipedia.org/wiki/Zebra_Puzzle", "authors": ["Isaac DeFrain"], "tags": ["beginner"], "modules": [ @@ -312,7 +283,6 @@ { "title": "Huang's Algorithm", "description": "An algorithm for detecting termination in a distributed system", - "source": "https://en.wikipedia.org/wiki/Huang%27s_algorithm", "authors": ["Markus Kuppe"], "tags": [], "modules": [ @@ -336,7 +306,6 @@ { "title": "Key-Value Store with Snapshot Isolation", "description": "A simple KVS implementing snapshot isolation", - "source": "https://ahelwer.ca", "authors": ["Andrew Helwer"], "tags": [], "modules": [ @@ -462,6 +431,78 @@ } ] }, + { + "title": "Misra Reachability Algorithm", + "description": "A sequential algorithm for computing the set of reachable nodes in a directed graph", + "authors": ["Leslie Lamport"], + "tags": [], + "modules": [ + { + "path": "specifications/MisraReachability/ParReach.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": ["pluscal"], + "models": [] + }, + { + "path": "specifications/MisraReachability/ParReachProofs.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": ["proof"], + "models": [] + }, + { + "path": "specifications/MisraReachability/Reachability.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/MisraReachability/ReachabilityProofs.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": ["proof"], + "models": [] + }, + { + "path": "specifications/MisraReachability/ReachabilityTest.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/MisraReachability/Reachable.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": ["pluscal"], + "models": [] + }, + { + "path": "specifications/MisraReachability/ReachableProofs.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": ["proof"], + "models": [] + } + ] + }, + { + "title": "Missionaries and Cannibals", + "description": "Spec of a river-crossing puzzle", + "authors": ["Leslie Lamport"], + "tags": ["beginner"], + "modules": [ + { + "path": "specifications/MissionariesAndCannibals/MissionariesAndCannibals.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [], + } + ] + }, { "title": "Multi-Car Elevator System", "description": "A simple multi-car elevator system servicing a multi-floor building", From 35dd45fb39c3b2c3e3b36aac0fc3e6f488eb4046 Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Mon, 23 Jan 2023 18:17:56 -0500 Subject: [PATCH 08/70] Wrote script to generate manifest Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/workflows/CI.yml | 6 +- .../scripts/check-manifest-feature-flags.py | 43 ------- .../check-manifest-file-correspondence.py | 42 ------- .../scripts/check_manifest_features.py | 54 ++++++++ .../workflows/scripts/check_manifest_files.py | 35 ++++++ ...nst-schema.py => check_manifest_schema.py} | 0 .../workflows/scripts/generate_manifest.py | 118 ++++++++++++++++++ .gitignore | 3 + manifest-schema.json | 15 +-- manifest.json | 43 ++++--- ...anCoffeeCan.cfg => CoffeeCan1000Beans.cfg} | 0 ...eanCoffeeCan.cfg => CoffeeCan100Beans.cfg} | 0 ...anCoffeeCan.cfg => CoffeeCan3000Beans.cfg} | 0 .../{MCKeyValueStore.tla => MCKVS.tla} | 2 +- ...VSSafetyLarge.cfg => MCKVSSafetyLarge.cfg} | 0 ...SafetyMedium.cfg => MCKVSSafetyMedium.cfg} | 0 ...VSSafetySmall.cfg => MCKVSSafetySmall.cfg} | 0 17 files changed, 242 insertions(+), 119 deletions(-) delete mode 100644 .github/workflows/scripts/check-manifest-feature-flags.py delete mode 100644 .github/workflows/scripts/check-manifest-file-correspondence.py create mode 100644 .github/workflows/scripts/check_manifest_features.py create mode 100644 .github/workflows/scripts/check_manifest_files.py rename .github/workflows/scripts/{check-against-schema.py => check_manifest_schema.py} (100%) create mode 100644 .github/workflows/scripts/generate_manifest.py rename specifications/CoffeeCan/{1000BeanCoffeeCan.cfg => CoffeeCan1000Beans.cfg} (100%) rename specifications/CoffeeCan/{100BeanCoffeeCan.cfg => CoffeeCan100Beans.cfg} (100%) rename specifications/CoffeeCan/{3000BeanCoffeeCan.cfg => CoffeeCan3000Beans.cfg} (100%) rename specifications/KeyValueStore/{MCKeyValueStore.tla => MCKVS.tla} (67%) rename specifications/KeyValueStore/{KVSSafetyLarge.cfg => MCKVSSafetyLarge.cfg} (100%) rename specifications/KeyValueStore/{KVSSafetyMedium.cfg => MCKVSSafetyMedium.cfg} (100%) rename specifications/KeyValueStore/{KVSSafetySmall.cfg => MCKVSSafetySmall.cfg} (100%) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 3cb1cced..03ba1692 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -22,16 +22,16 @@ jobs: - name: Install python packages run: pip install -r $SCRIPT_DIR/requirements.txt - name: Check manifest.json format - run: python $SCRIPT_DIR/check-against-schema.py + run: python $SCRIPT_DIR/check_manifest_schema.py - name: Check manifest files - run: python $SCRIPT_DIR/check-manifest-file-correspondence.py + run: python $SCRIPT_DIR/check_manifest_files.py - name: Get tree-sitter-tlaplus run: | wget https://github.com/tlaplus-community/tree-sitter-tlaplus/archive/refs/tags/v$TSTLA_VERSION.tar.gz tar -xf v$TSTLA_VERSION.tar.gz mv tree-sitter-tlaplus-$TSTLA_VERSION tree-sitter-tlaplus - name: Check manifest feature flags - run: python $SCRIPT_DIR/check-manifest-feature-flags.py + run: python $SCRIPT_DIR/check_manifest_features.py # - name: Get nightly TLA⁺ tools # run: wget https://nightly.tlapl.us/dist/tla2tools.jar # - name: Check TLA⁺ specs parse diff --git a/.github/workflows/scripts/check-manifest-feature-flags.py b/.github/workflows/scripts/check-manifest-feature-flags.py deleted file mode 100644 index b4c8025d..00000000 --- a/.github/workflows/scripts/check-manifest-feature-flags.py +++ /dev/null @@ -1,43 +0,0 @@ -import json -from tree_sitter import Language, Parser - -Language.build_library( - 'build/tree-sitter-languages.so', - ['tree-sitter-tlaplus'] -) - -manifest = None -with open('manifest.json', 'rt') as manifest_file: - manifest = json.load(manifest_file) - -TLAPLUS_LANGUAGE = Language('build/tree-sitter-languages.so', 'tlaplus') -parser = Parser() -parser.set_language(TLAPLUS_LANGUAGE) - -query = TLAPLUS_LANGUAGE.query( - '(pcal_algorithm_start) @pluscal' - + '[(terminal_proof) (non_terminal_proof)] @proof' -) - -success = True -for spec in manifest['specifications']: - for module in spec['modules']: - module_text = None - with open(module['path'], 'rb') as module_file: - module_text = module_file.read() - tree = parser.parse(module_text) - if tree.root_node.has_error: - success = False - print(f'Module {module["path"]} contains syntax errors') - captures = query.captures(tree.root_node) - expected_features = set([name for _, name in captures]) - actual_features = set(module['features']) - if expected_features != actual_features: - success = False - print( - f'Module {module["path"]} has incorrect features in manifest; ' - + f'expected {list(expected_features)}, actual {list(actual_features)}' - ) - -exit(0 if success else 1) - diff --git a/.github/workflows/scripts/check-manifest-file-correspondence.py b/.github/workflows/scripts/check-manifest-file-correspondence.py deleted file mode 100644 index 2d1867b9..00000000 --- a/.github/workflows/scripts/check-manifest-file-correspondence.py +++ /dev/null @@ -1,42 +0,0 @@ -# Checks to ensure all files in manifest.json exist, and that all .tla and -# .cfg files in repo are recorded in manifest.json - -import json -from os.path import exists, normpath -import glob - -manifest = None -with open('manifest.json', 'rt') as manifest_file: - manifest = json.load(manifest_file) - -module_lists = [spec["modules"] for spec in manifest["specifications"]] -modules = [module for module_list in module_lists for module in module_list] -module_paths = set([normpath(module["path"]) for module in modules]) -model_lists = [module["models"] for module in modules] -model_paths = set([normpath(model["path"]) for model_list in model_lists for model in model_list]) - -missing_module_files = [path for path in module_paths if not exists(path)] -missing_model_files = [path for path in model_paths if not exists(path)] - -any_missing = False -if any(missing_module_files): - any_missing = True - print('Module files not found:\n' + '\n'.join(missing_module_files)) -if any(missing_model_files): - any_missing = True - print('Model files not found:\n' + '\n'.join(missing_model_files)) - -tla_files = set([normpath(path) for path in glob.glob(f"./specifications/**/*.tla", recursive=True)]) -cfg_files = set([normpath(path) for path in glob.glob(f"./specifications/**/*.cfg", recursive=True)]) -missing_module_paths = tla_files - module_paths -missing_model_paths = cfg_files - model_paths - -if any(missing_module_paths): - any_missing = True - print('Module files not included in manifest:\n' + '\n'.join(missing_module_paths)) -if any(missing_model_paths): - any_missing = True - print('Model files not included in manifest:\n' + '\n'.join(missing_model_paths)) - -exit(1 if any_missing else 0) - diff --git a/.github/workflows/scripts/check_manifest_features.py b/.github/workflows/scripts/check_manifest_features.py new file mode 100644 index 00000000..beb70e7b --- /dev/null +++ b/.github/workflows/scripts/check_manifest_features.py @@ -0,0 +1,54 @@ +import json +from tree_sitter import Language, Parser + +Language.build_library( + 'build/tree-sitter-languages.so', + ['tree-sitter-tlaplus'] +) + +TLAPLUS_LANGUAGE = Language('build/tree-sitter-languages.so', 'tlaplus') +parser = Parser() +parser.set_language(TLAPLUS_LANGUAGE) + +query = TLAPLUS_LANGUAGE.query( + '(pcal_algorithm_start) @pluscal' + + '[(terminal_proof) (non_terminal_proof)] @proof' +) + +def parse_module(path): + module_text = None + with open(path, 'rb') as module_file: + module_text = module_file.read() + tree = parser.parse(module_text) + return (tree, tree.root_node.has_error) + +def get_tree_features(tree): + return set([name for _, name in query.captures(tree.root_node)]) + +def get_module_features(path): + tree, _ = parse_module(path) + return list(get_tree_features(tree)) + +if __name__ == '__main__': + manifest = None + with open('manifest.json', 'rt') as manifest_file: + manifest = json.load(manifest_file) + + success = True + for spec in manifest['specifications']: + for module in spec['modules']: + tree, parse_err = parse_module(module['path']) + if parse_err: + success = False + print(f'Module {module["path"]} contains syntax errors') + expected_features = get_tree_features(tree) + actual_features = set(module['features']) + if expected_features != actual_features: + success = False + print( + f'Module {module["path"]} has incorrect features in manifest; ' + + f'expected {list(expected_features)}, actual {list(actual_features)}' + ) + + exit(0 if success else 1) + diff --git a/.github/workflows/scripts/check_manifest_files.py b/.github/workflows/scripts/check_manifest_files.py new file mode 100644 index 00000000..af4c4829 --- /dev/null +++ b/.github/workflows/scripts/check_manifest_files.py @@ -0,0 +1,35 @@ +# Checks to ensure all files in manifest.json exist, and that all .tla and +# .cfg files in repo are recorded in manifest.json + +import json +from os.path import normpath +import glob + +manifest = None +with open('manifest.json', 'rt') as manifest_file: + manifest = json.load(manifest_file) + +module_lists = [spec["modules"] for spec in manifest["specifications"]] +modules = [module for module_list in module_lists for module in module_list] +model_lists = [module["models"] for module in modules] + +# All paths in the manifest +tla_mf_paths = set([normpath(module["path"]) for module in modules]) +cfg_mf_paths = set([normpath(model["path"]) for model_list in model_lists for model in model_list]) + +# All paths on the filesystem +tla_fs_paths = set([normpath(path) for path in glob.glob(f"./specifications/**/*.tla", recursive=True)]) +cfg_fs_paths = set([normpath(path) for path in glob.glob(f"./specifications/**/*.cfg", recursive=True)]) + +success = True +if tla_mf_paths != tla_fs_paths: + success = False + print('.tla files not recorded in manifest:\n' + '\n'.join(tla_fs_paths - tla_mf_paths)) + print('Manifest .tla files not found in specifications dir:\n' + '\n'.join(tla_mf_paths - tla_fs_paths)) +if cfg_mf_paths != tla_fs_paths: + success = False + print('.cfg files not recorded in manifest:\n' + '\n'.join(cfg_fs_paths - cfg_mf_paths)) + print('Manifest .cfg files not found in specifications dir:\n' + '\n'.join(cfg_mf_paths - cfg_fs_paths)) + +exit(0 if success else 1) + diff --git a/.github/workflows/scripts/check-against-schema.py b/.github/workflows/scripts/check_manifest_schema.py similarity index 100% rename from .github/workflows/scripts/check-against-schema.py rename to .github/workflows/scripts/check_manifest_schema.py diff --git a/.github/workflows/scripts/generate_manifest.py b/.github/workflows/scripts/generate_manifest.py new file mode 100644 index 00000000..2f0f1211 --- /dev/null +++ b/.github/workflows/scripts/generate_manifest.py @@ -0,0 +1,118 @@ +# Generates a best-effort manifest.json from files in the specifications dir + +from check_manifest_features import get_module_features +import json +import os +from os.path import basename, dirname, join, normpath, splitext +import glob + +def get_tla_files(dir): + return [normpath(path) for path in glob.glob(f'{dir.path}/**/*.tla', recursive=True)] + +def get_cfg_files(tla_path): + """Assume a .cfg file in the same directory as the .tla file and with the + same name is a model of that .tla file; also assume this of any .cfg + files where the .tla file name is only a prefix of the .cfg file name, + unless there are other .tla file names in the directory that exactly + match the .cfg file name. + """ + parent_dir = dirname(tla_path) + module_name, _ = splitext(basename(tla_path)) + other_module_names = set(filter( + lambda other_module_name: other_module_name != module_name, + [splitext(basename(path))[0] for path in glob.glob(f'{join(parent_dir, module_name)}*.tla')] + )) + return [ + normpath(path) for path in glob.glob(f'{join(parent_dir, module_name)}*.cfg') + if splitext(basename(path))[0] not in other_module_names + ] + +new_manifest = { + 'specifications': [ + { + 'title': dir.name, + 'description': '', + 'source': '', + 'authors': [], + 'tags': [], + 'modules': [ + { + 'path': tla_path, + 'communityDependencies': [], + 'tlaLanguageVersion': 2, + 'features': get_module_features(tla_path), + 'models': [ + { + 'path': normpath(cfg_path), + 'runtime': 'unknown', + 'size': 'unknown', + 'features': [], + 'result': 'unknown' + } + for cfg_path in sorted(get_cfg_files(tla_path)) + ] + } + for tla_path in sorted(get_tla_files(dir)) + ] + } + for dir in sorted( + os.scandir('specifications'), key=lambda d: d.name + ) if dir.is_dir() and any(get_tla_files(dir)) + ] +} + +def find_corresponding_spec(old_spec, new_manifest): + old_modules = old_spec['modules'] + old_module_paths = set([normpath(module['path']) for module in old_modules]) + return list(filter( + lambda spec: any(old_module_paths.intersection( + set([normpath(module['path']) for module in spec['modules']]) + )), + new_manifest['specifications'] + ))[0] + +def integrate_spec_info(old_spec, new_spec): + fields = ['title', 'description', 'source', 'authors', 'tags'] + for field in fields: + new_spec[field] = old_spec[field] + +def find_corresponding_module(old_module, new_spec): + return [ + module for module in new_spec['modules'] + if normpath(module['path']) == normpath(old_module['path']) + ][0] + +def integrate_module_info(old_module, new_module): + fields = ['communityDependencies', 'tlaLanguageVersion'] + for field in fields: + new_module[field] = old_module[field] + +def find_corresponding_model(old_model, new_module): + return [ + model for model in new_module['models'] + if normpath(model['path']) == normpath(old_model['path']) + ][0] + +def integrate_model_info(old_model, new_model): + fields = ['runtime', 'size', 'features', 'result'] + for field in fields: + new_model[field] = old_model[field] + +# Integrate human-readable info from existing manifest +old_manifest = None +with open('manifest.json', 'rt') as old_manifest_file: + old_manifest = json.load(old_manifest_file) + +for old_spec in old_manifest['specifications']: + new_spec = find_corresponding_spec(old_spec, new_manifest) + integrate_spec_info(old_spec, new_spec) + for old_module in old_spec['modules']: + new_module = find_corresponding_module(old_module, new_spec) + integrate_module_info(old_module, new_module) + for old_model in old_module['models']: + new_model = find_corresponding_model(old_model, new_module) + integrate_model_info(old_model, new_model) + +with open('new-manifest.json', 'w') as new_manifest_file: + json.dump(new_manifest, new_manifest_file, indent=2) + diff --git a/.gitignore b/.gitignore index 38f977dd..db4fc2bc 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,6 @@ __tlacache__ ## Don't ignore READMEs !*.md +## Ignore pycache +__pycache__ + diff --git a/manifest-schema.json b/manifest-schema.json index c2d3f21b..91fdfba9 100644 --- a/manifest-schema.json +++ b/manifest-schema.json @@ -7,7 +7,7 @@ "type": "array", "items": { "type": "object", - "required": ["title", "description", "authors", "tags", "modules"], + "required": ["title", "description", "source", "authors", "tags", "modules"], "additionalProperties": false, "properties": { "title": {"type": "string"}, @@ -31,18 +31,7 @@ "path": {"type": "string"}, "communityDependencies": { "type": "array", - "items": { - "type": "object", - "required": ["name", "version"], - "additionalProperties": false, - "properties": { - "name": {"type": "string"}, - "version": { - "type": "string", - "pattern": "^[0-9a-fA-F]{40}$" - } - } - } + "items": {"type": "string"} }, "tlaLanguageVersion": {"type": "number"}, "features": { diff --git a/manifest.json b/manifest.json index ed4c1a92..66c6b575 100644 --- a/manifest.json +++ b/manifest.json @@ -3,6 +3,7 @@ { "title": "The Boulangerie Algorithm", "description": "Spec of a variant of the Bakery Algorithm", + "source": "", "authors": ["Leslie Lamport", "Stephan Merz"], "tags": [], "modules": [ @@ -25,6 +26,7 @@ { "title": "The Car Talk Puzzle", "description": "Math puzzle involving a farmer, a stone, and a balance scale", + "source": "", "authors": ["Leslie Lamport"], "tags": ["beginner"], "modules": [ @@ -33,14 +35,14 @@ "communityDependencies": [], "tlaLanguageVersion": 2, "features": [], - "models": [], + "models": [] }, { "path": "specifications/CarTalkPuzzle/CarTalkPuzzle.toolbox/Model_1/CarTalkPuzzle.tla", "communityDependencies": [], "tlaLanguageVersion": 2, "features": [], - "models": [], + "models": [] }, { "path": "specifications/CarTalkPuzzle/CarTalkPuzzle.toolbox/Model_1/MC.tla", @@ -55,14 +57,14 @@ "features": [], "result": "unknown" } - ], + ] }, { "path": "specifications/CarTalkPuzzle/CarTalkPuzzle.toolbox/Model_2/CarTalkPuzzle.tla", "communityDependencies": [], "tlaLanguageVersion": 2, "features": [], - "models": [], + "models": [] }, { "path": "specifications/CarTalkPuzzle/CarTalkPuzzle.toolbox/Model_2/MC.tla", @@ -77,14 +79,14 @@ "features": [], "result": "unknown" } - ], + ] }, { "path": "specifications/CarTalkPuzzle/CarTalkPuzzle.toolbox/Model_3/CarTalkPuzzle.tla", "communityDependencies": [], "tlaLanguageVersion": 2, "features": [], - "models": [], + "models": [] }, { "path": "specifications/CarTalkPuzzle/CarTalkPuzzle.toolbox/Model_3/MC.tla", @@ -99,8 +101,8 @@ "features": [], "result": "unknown" } - ], - }, + ] + } ] }, { @@ -127,7 +129,7 @@ "tags": [], "modules": [ { - "path": "specifications/Chameneos/Chameneos.tla", + "path": "specifications/CigaretteSmokers/CigaretteSmokers.tla", "communityDependencies": [], "tlaLanguageVersion": 2, "features": [], @@ -149,21 +151,21 @@ "features": [], "models": [ { - "path": "specifications/CoffeeCan/100BeanCoffeeCan.cfg", + "path": "specifications/CoffeeCan/CoffeeCan100Beans.cfg", "runtime": "00:00:01", "size": "small", "features": ["liveness"], "result": "success" }, { - "path": "specifications/CoffeeCan/1000BeanCoffeeCan.cfg", + "path": "specifications/CoffeeCan/CoffeeCan1000Beans.cfg", "runtime": "00:00:15", "size": "medium", "features": ["liveness"], "result": "success" }, { - "path": "specifications/CoffeeCan/3000BeanCoffeeCan.cfg", + "path": "specifications/CoffeeCan/CoffeeCan3000Beans.cfg", "runtime": "00:02:30", "size": "medium", "features": ["liveness"], @@ -176,6 +178,7 @@ { "title": "The Die Hard Problem", "description": "Obtain 4 gallons of water using only 3 and 5 gallon jugs", + "source": "", "authors": ["Leslie Lamport"], "tags": ["beginner"], "modules": [ @@ -221,6 +224,7 @@ { "title": "The Dining Philosophers Problem", "description": "The Chandy-Misra solution to the Dining Philosophers concurrency problem", + "source": "", "authors": ["Jeff Hemphill"], "tags": ["beginner"], "modules": [ @@ -244,6 +248,7 @@ { "title": "Einstein's Riddle", "description": "Five houses, five people, various facts, who lives in what house?", + "source": "", "authors": ["Isaac DeFrain"], "tags": ["beginner"], "modules": [ @@ -283,6 +288,7 @@ { "title": "Huang's Algorithm", "description": "An algorithm for detecting termination in a distributed system", + "source": "", "authors": ["Markus Kuppe"], "tags": [], "modules": [ @@ -306,6 +312,7 @@ { "title": "Key-Value Store with Snapshot Isolation", "description": "A simple KVS implementing snapshot isolation", + "source": "", "authors": ["Andrew Helwer"], "tags": [], "modules": [ @@ -317,27 +324,27 @@ "models": [] }, { - "path": "specifications/KeyValueStore/MCKeyValueStore.tla", + "path": "specifications/KeyValueStore/MCKVS.tla", "communityDependencies": [], "tlaLanguageVersion": 2, "features": [], "models": [ { - "path": "specifications/KeyValueStore/KVSSafetySmall.cfg", + "path": "specifications/KeyValueStore/MCKVSSafetySmall.cfg", "runtime": "00:00:40", "size": "medium", "features": [], "result": "success" }, { - "path": "specifications/KeyValueStore/KVSSafetyMedium.cfg", + "path": "specifications/KeyValueStore/MCKVSSafetyMedium.cfg", "runtime": "00:04:30", "size": "medium", "features": ["symmetry"], "result": "success" }, { - "path": "specifications/KeyValueStore/KVSSafetyLarge.cfg", + "path": "specifications/KeyValueStore/MCKVSSafetyLarge.cfg", "runtime": "07:16:00", "size": "large", "features": ["symmetry"], @@ -434,6 +441,7 @@ { "title": "Misra Reachability Algorithm", "description": "A sequential algorithm for computing the set of reachable nodes in a directed graph", + "source": "", "authors": ["Leslie Lamport"], "tags": [], "modules": [ @@ -491,6 +499,7 @@ { "title": "Missionaries and Cannibals", "description": "Spec of a river-crossing puzzle", + "source": "", "authors": ["Leslie Lamport"], "tags": ["beginner"], "modules": [ @@ -499,7 +508,7 @@ "communityDependencies": [], "tlaLanguageVersion": 2, "features": [], - "models": [], + "models": [] } ] }, diff --git a/specifications/CoffeeCan/1000BeanCoffeeCan.cfg b/specifications/CoffeeCan/CoffeeCan1000Beans.cfg similarity index 100% rename from specifications/CoffeeCan/1000BeanCoffeeCan.cfg rename to specifications/CoffeeCan/CoffeeCan1000Beans.cfg diff --git a/specifications/CoffeeCan/100BeanCoffeeCan.cfg b/specifications/CoffeeCan/CoffeeCan100Beans.cfg similarity index 100% rename from specifications/CoffeeCan/100BeanCoffeeCan.cfg rename to specifications/CoffeeCan/CoffeeCan100Beans.cfg diff --git a/specifications/CoffeeCan/3000BeanCoffeeCan.cfg b/specifications/CoffeeCan/CoffeeCan3000Beans.cfg similarity index 100% rename from specifications/CoffeeCan/3000BeanCoffeeCan.cfg rename to specifications/CoffeeCan/CoffeeCan3000Beans.cfg diff --git a/specifications/KeyValueStore/MCKeyValueStore.tla b/specifications/KeyValueStore/MCKVS.tla similarity index 67% rename from specifications/KeyValueStore/MCKeyValueStore.tla rename to specifications/KeyValueStore/MCKVS.tla index 6d9e4996..09b326dc 100644 --- a/specifications/KeyValueStore/MCKeyValueStore.tla +++ b/specifications/KeyValueStore/MCKVS.tla @@ -1,4 +1,4 @@ ----- MODULE MCKeyValueStore ---- +---- MODULE MCKVS ---- EXTENDS KeyValueStore, TLC TxIdSymmetric == Permutations(TxId) ==== diff --git a/specifications/KeyValueStore/KVSSafetyLarge.cfg b/specifications/KeyValueStore/MCKVSSafetyLarge.cfg similarity index 100% rename from specifications/KeyValueStore/KVSSafetyLarge.cfg rename to specifications/KeyValueStore/MCKVSSafetyLarge.cfg diff --git a/specifications/KeyValueStore/KVSSafetyMedium.cfg b/specifications/KeyValueStore/MCKVSSafetyMedium.cfg similarity index 100% rename from specifications/KeyValueStore/KVSSafetyMedium.cfg rename to specifications/KeyValueStore/MCKVSSafetyMedium.cfg diff --git a/specifications/KeyValueStore/KVSSafetySmall.cfg b/specifications/KeyValueStore/MCKVSSafetySmall.cfg similarity index 100% rename from specifications/KeyValueStore/KVSSafetySmall.cfg rename to specifications/KeyValueStore/MCKVSSafetySmall.cfg From 07eba6db7a68d60311ca846cc3a919a5f836d5f6 Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Tue, 24 Jan 2023 14:11:32 -0500 Subject: [PATCH 09/70] Detect model features Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/workflows/CI.yml | 2 +- .../scripts/check_manifest_features.py | 34 +++++++++++++++++++ .../workflows/scripts/check_manifest_files.py | 27 ++++++++++++--- .../workflows/scripts/generate_manifest.py | 24 ++++++++----- manifest-schema.json | 3 +- 5 files changed, 75 insertions(+), 15 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 03ba1692..4af064d0 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -10,7 +10,7 @@ jobs: validate-metadata: runs-on: ubuntu-latest env: - TSTLA_VERSION: 1.0.1 + TSTLA_VERSION: 1.0.2 SCRIPT_DIR: ./.github/workflows/scripts steps: - name: Clone repo diff --git a/.github/workflows/scripts/check_manifest_features.py b/.github/workflows/scripts/check_manifest_features.py index beb70e7b..c3855ad8 100644 --- a/.github/workflows/scripts/check_manifest_features.py +++ b/.github/workflows/scripts/check_manifest_features.py @@ -29,6 +29,31 @@ def get_module_features(path): tree, _ = parse_module(path) return list(get_tree_features(tree)) +model_features = { + 'PROPERTY': 'liveness', + 'PROPERTIES': 'liveness', + 'SYMMETRY': 'symmetry', + 'ALIAS': 'alias', + 'VIEW': 'view', + 'CONSTRAINT': 'state constraint', + 'CONSTRAINTS': 'state constraint', +} + +def get_model_features(path): + """ + This will be a best-effort text search until a tree-sitter grammar is + created for .cfg files. + """ + features = [] + model_text = None + with open(path, 'rt') as model_file: + model_text = model_file.read() + for line in model_text.split('\n'): + tokens = line.split() + if len(tokens) > 0 and tokens[0] in model_features: + features.append(model_features[tokens[0]]) + return set(features) + if __name__ == '__main__': manifest = None with open('manifest.json', 'rt') as manifest_file: @@ -49,6 +74,15 @@ def get_module_features(path): f'Module {module["path"]} has incorrect features in manifest; ' + f'expected {list(expected_features)}, actual {list(actual_features)}' ) + for model in module['models']: + expected_features = get_model_features(model['path']) + actual_features = set(model['features']) + if expected_features != actual_features: + success = False + print( + f'Model {model["path"]} has incorrect features in manifest; ' + + f'expected {list(expected_features)}, actual {list(actual_features)}' + ) exit(0 if success else 1) diff --git a/.github/workflows/scripts/check_manifest_files.py b/.github/workflows/scripts/check_manifest_files.py index af4c4829..0c84d4d4 100644 --- a/.github/workflows/scripts/check_manifest_files.py +++ b/.github/workflows/scripts/check_manifest_files.py @@ -1,6 +1,7 @@ # Checks to ensure all files in manifest.json exist, and that all .tla and # .cfg files in repo are recorded in manifest.json +from collections import Counter import json from os.path import normpath import glob @@ -14,21 +15,39 @@ model_lists = [module["models"] for module in modules] # All paths in the manifest -tla_mf_paths = set([normpath(module["path"]) for module in modules]) -cfg_mf_paths = set([normpath(model["path"]) for model_list in model_lists for model in model_list]) +tla_mf_paths_cnt = Counter([normpath(module["path"]) for module in modules]) +tla_mf_paths = set(tla_mf_paths_cnt) +cfg_mf_paths_cnt = Counter([normpath(model["path"]) for model_list in model_lists for model in model_list]) +cfg_mf_paths = set(cfg_mf_paths_cnt) # All paths on the filesystem tla_fs_paths = set([normpath(path) for path in glob.glob(f"./specifications/**/*.tla", recursive=True)]) cfg_fs_paths = set([normpath(path) for path in glob.glob(f"./specifications/**/*.cfg", recursive=True)]) success = True -if tla_mf_paths != tla_fs_paths: + +# Check for duplicate paths in manifest +duplicate_tla_paths = [k for k, v in tla_mf_paths_cnt.items() if v > 1] +duplicate_cfg_paths = [k for k, v in cfg_mf_paths_cnt.items() if v > 1] +if any(duplicate_tla_paths): + success = False + print('.tla file paths duplicated in manifest:\n' + '\n'.join(duplicate_tla_paths)) +if any(duplicate_cfg_paths): + success = False + print('.cfg file paths duplicated in manifest:\n' + '\n'.join(duplicate_cfg_paths)) + +# Check paths in manifest match paths on filesystem +if tla_mf_paths < tla_fs_paths: success = False print('.tla files not recorded in manifest:\n' + '\n'.join(tla_fs_paths - tla_mf_paths)) +if tla_fs_paths < tla_mf_paths: + success = False print('Manifest .tla files not found in specifications dir:\n' + '\n'.join(tla_mf_paths - tla_fs_paths)) -if cfg_mf_paths != tla_fs_paths: +if cfg_mf_paths < cfg_fs_paths: success = False print('.cfg files not recorded in manifest:\n' + '\n'.join(cfg_fs_paths - cfg_mf_paths)) +if cfg_fs_paths < cfg_mf_paths: + success = False print('Manifest .cfg files not found in specifications dir:\n' + '\n'.join(cfg_mf_paths - cfg_fs_paths)) exit(0 if success else 1) diff --git a/.github/workflows/scripts/generate_manifest.py b/.github/workflows/scripts/generate_manifest.py index 2f0f1211..5f58d06b 100644 --- a/.github/workflows/scripts/generate_manifest.py +++ b/.github/workflows/scripts/generate_manifest.py @@ -1,11 +1,13 @@ -# Generates a best-effort manifest.json from files in the specifications dir +# Generates a best-effort manifest.json -from check_manifest_features import get_module_features +from check_manifest_features import get_module_features, get_model_features import json import os from os.path import basename, dirname, join, normpath, splitext import glob +# Generate new manifest drawing info from files in specifications dir + def get_tla_files(dir): return [normpath(path) for path in glob.glob(f'{dir.path}/**/*.tla', recursive=True)] @@ -30,6 +32,7 @@ def get_cfg_files(tla_path): new_manifest = { 'specifications': [ { + 'path': normpath(dir.path), 'title': dir.name, 'description': '', 'source': '', @@ -43,10 +46,10 @@ def get_cfg_files(tla_path): 'features': get_module_features(tla_path), 'models': [ { - 'path': normpath(cfg_path), + 'path': cfg_path, 'runtime': 'unknown', 'size': 'unknown', - 'features': [], + 'features': list(get_model_features(cfg_path)), 'result': 'unknown' } for cfg_path in sorted(get_cfg_files(tla_path)) @@ -61,13 +64,15 @@ def get_cfg_files(tla_path): ] } +# Integrate human-readable info from existing manifest + def find_corresponding_spec(old_spec, new_manifest): old_modules = old_spec['modules'] old_module_paths = set([normpath(module['path']) for module in old_modules]) return list(filter( - lambda spec: any(old_module_paths.intersection( - set([normpath(module['path']) for module in spec['modules']]) - )), + lambda new_spec: any( + [old_module_path.startswith(new_spec['path']) for old_module_path in old_module_paths] + ), new_manifest['specifications'] ))[0] @@ -94,11 +99,10 @@ def find_corresponding_model(old_model, new_module): ][0] def integrate_model_info(old_model, new_model): - fields = ['runtime', 'size', 'features', 'result'] + fields = ['runtime', 'size', 'result'] for field in fields: new_model[field] = old_model[field] -# Integrate human-readable info from existing manifest old_manifest = None with open('manifest.json', 'rt') as old_manifest_file: old_manifest = json.load(old_manifest_file) @@ -113,6 +117,8 @@ def integrate_model_info(old_model, new_model): new_model = find_corresponding_model(old_model, new_module) integrate_model_info(old_model, new_model) +# Writes generated manifest to file + with open('new-manifest.json', 'w') as new_manifest_file: json.dump(new_manifest, new_manifest_file, indent=2) diff --git a/manifest-schema.json b/manifest-schema.json index 91fdfba9..faa5a9d7 100644 --- a/manifest-schema.json +++ b/manifest-schema.json @@ -7,9 +7,10 @@ "type": "array", "items": { "type": "object", - "required": ["title", "description", "source", "authors", "tags", "modules"], + "required": ["title", "description", "source", "authors", "path", "tags", "modules"], "additionalProperties": false, "properties": { + "path": {"type": "string"}, "title": {"type": "string"}, "description": {"type": "string"}, "source": {"type": "string"}, From 26a87d0e8450c5669dbdf85a8cb4e778578731c1 Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Wed, 25 Jan 2023 21:13:06 -0500 Subject: [PATCH 10/70] Filled out human-readable parts of manifest Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .../workflows/scripts/generate_manifest.py | 6 +- manifest-schema.json | 2 +- manifest.json | 2620 ++++++++++++++++- 3 files changed, 2524 insertions(+), 104 deletions(-) diff --git a/.github/workflows/scripts/generate_manifest.py b/.github/workflows/scripts/generate_manifest.py index 5f58d06b..5d557471 100644 --- a/.github/workflows/scripts/generate_manifest.py +++ b/.github/workflows/scripts/generate_manifest.py @@ -104,7 +104,7 @@ def integrate_model_info(old_model, new_model): new_model[field] = old_model[field] old_manifest = None -with open('manifest.json', 'rt') as old_manifest_file: +with open('manifest.json', 'r') as old_manifest_file: old_manifest = json.load(old_manifest_file) for old_spec in old_manifest['specifications']: @@ -119,6 +119,6 @@ def integrate_model_info(old_model, new_model): # Writes generated manifest to file -with open('new-manifest.json', 'w') as new_manifest_file: - json.dump(new_manifest, new_manifest_file, indent=2) +with open('manifest.json', 'w') as new_manifest_file: + json.dump(new_manifest, new_manifest_file, indent=2, ensure_ascii=False) diff --git a/manifest-schema.json b/manifest-schema.json index faa5a9d7..71899966 100644 --- a/manifest-schema.json +++ b/manifest-schema.json @@ -20,7 +20,7 @@ }, "tags": { "type": "array", - "items": {"enum": ["beginner", "blockchain", "probability"]} + "items": {"enum": ["beginner"]} }, "modules": { "type": "array", diff --git a/manifest.json b/manifest.json index 66c6b575..1d458dec 100644 --- a/manifest.json +++ b/manifest.json @@ -1,33 +1,46 @@ { "specifications": [ { + "path": "specifications/Bakery-Boulangerie", "title": "The Boulangerie Algorithm", "description": "Spec of a variant of the Bakery Algorithm", "source": "", - "authors": ["Leslie Lamport", "Stephan Merz"], + "authors": [ + "Leslie Lamport", + "Stephan Merz" + ], "tags": [], "modules": [ { "path": "specifications/Bakery-Boulangerie/Bakery.tla", "communityDependencies": [], "tlaLanguageVersion": 2, - "features": ["pluscal", "proof"], + "features": [ + "pluscal", + "proof" + ], "models": [] }, { "path": "specifications/Bakery-Boulangerie/Boulanger.tla", "communityDependencies": [], "tlaLanguageVersion": 2, - "features": ["pluscal", "proof"], + "features": [ + "pluscal", + "proof" + ], "models": [] } ] }, { + "path": "specifications/CarTalkPuzzle", "title": "The Car Talk Puzzle", "description": "Math puzzle involving a farmer, a stone, and a balance scale", "source": "", - "authors": ["Leslie Lamport"], + "authors": [ + "Leslie Lamport" + ], "tags": ["beginner"], "modules": [ { @@ -106,10 +119,13 @@ ] }, { + "path": "specifications/Chameneos", "title": "Chameneos, a Concurrency Game", "description": "A concurrency game requiring concurrent & symmetric cooperation", "source": "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/mryndzionek/tlaplus_specs#chameneostla", - "authors": ["Mariusz Ryndzionek"], + "authors": [ + "Mariusz Ryndzionek" + ], "tags": [], "modules": [ { @@ -122,10 +138,13 @@ ] }, { + "path": "specifications/CigaretteSmokers", "title": "The Cigarette Smokers Problem", "description": "A concurrency problem described in 1971 by Suhas Patil", "source": "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/mryndzionek/tlaplus_specs#cigarettesmokerstla", - "authors": ["Mariusz Ryndzionek"], + "authors": [ + "Mariusz Ryndzionek" + ], "tags": [], "modules": [ { @@ -138,10 +157,13 @@ ] }, { + "path": "specifications/CoffeeCan", "title": "The Coffee Can Black/White Bean Problem", "description": "Math problem published by Dijkstra attributed to Carel Scholten", "source": "https://stackoverflow.com/a/66304920/2852699", - "authors": ["Andrew Helwer"], + "authors": [ + "Andrew Helwer" + ], "tags": ["beginner"], "modules": [ { @@ -150,25 +172,31 @@ "tlaLanguageVersion": 2, "features": [], "models": [ - { - "path": "specifications/CoffeeCan/CoffeeCan100Beans.cfg", - "runtime": "00:00:01", - "size": "small", - "features": ["liveness"], - "result": "success" - }, { "path": "specifications/CoffeeCan/CoffeeCan1000Beans.cfg", "runtime": "00:00:15", "size": "medium", - "features": ["liveness"], + "features": [ + "liveness" + ], + "result": "success" + }, + { + "path": "specifications/CoffeeCan/CoffeeCan100Beans.cfg", + "runtime": "00:00:01", + "size": "small", + "features": [ + "liveness" + ], "result": "success" }, { "path": "specifications/CoffeeCan/CoffeeCan3000Beans.cfg", "runtime": "00:02:30", "size": "medium", - "features": ["liveness"], + "features": [ + "liveness" + ], "result": "success" } ] @@ -176,10 +204,13 @@ ] }, { + "path": "specifications/DieHard", "title": "The Die Hard Problem", "description": "Obtain 4 gallons of water using only 3 and 5 gallon jugs", "source": "", - "authors": ["Leslie Lamport"], + "authors": [ + "Leslie Lamport" + ], "tags": ["beginner"], "modules": [ { @@ -222,23 +253,30 @@ ] }, { + "path": "specifications/DiningPhilosophers", "title": "The Dining Philosophers Problem", "description": "The Chandy-Misra solution to the Dining Philosophers concurrency problem", "source": "", - "authors": ["Jeff Hemphill"], + "authors": [ + "Jeff Hemphill" + ], "tags": ["beginner"], "modules": [ { "path": "specifications/DiningPhilosophers/DiningPhilosophers.tla", "communityDependencies": [], "tlaLanguageVersion": 2, - "features": ["pluscal"], + "features": [ + "pluscal" + ], "models": [ { "path": "specifications/DiningPhilosophers/DiningPhilosophers.cfg", "runtime": "unknown", "size": "unknown", - "features": ["liveness"], + "features": [ + "liveness" + ], "result": "unknown" } ] @@ -246,10 +284,13 @@ ] }, { + "path": "specifications/EinsteinRiddle", "title": "Einstein's Riddle", "description": "Five houses, five people, various facts, who lives in what house?", "source": "", - "authors": ["Isaac DeFrain"], + "authors": [ + "Isaac DeFrain" + ], "tags": ["beginner"], "modules": [ { @@ -270,10 +311,13 @@ ] }, { + "path": "specifications/GameOfLife", "title": "Conway's Game of Life", "description": "The famous cellular automata simulation", "source": "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/mryndzionek/tlaplus_specs#gameoflifetla", - "authors": ["Mariusz Ryndzionek"], + "authors": [ + "Mariusz Ryndzionek" + ], "tags": [], "modules": [ { @@ -286,10 +330,13 @@ ] }, { + "path": "specifications/Huang", "title": "Huang's Algorithm", "description": "An algorithm for detecting termination in a distributed system", "source": "", - "authors": ["Markus Kuppe"], + "authors": [ + "Markus Kuppe" + ], "tags": [], "modules": [ { @@ -302,7 +349,11 @@ "path": "specifications/Huang/Huang.cfg", "runtime": "unknown", "size": "unknown", - "features": ["liveness", "state constraint", "alias"], + "features": [ + "state constraint", + "liveness", + "alias" + ], "result": "unknown" } ] @@ -310,10 +361,13 @@ ] }, { + "path": "specifications/KeyValueStore", "title": "Key-Value Store with Snapshot Isolation", "description": "A simple KVS implementing snapshot isolation", "source": "", - "authors": ["Andrew Helwer"], + "authors": [ + "Andrew Helwer" + ], "tags": [], "modules": [ { @@ -330,24 +384,28 @@ "features": [], "models": [ { - "path": "specifications/KeyValueStore/MCKVSSafetySmall.cfg", - "runtime": "00:00:40", - "size": "medium", - "features": [], + "path": "specifications/KeyValueStore/MCKVSSafetyLarge.cfg", + "runtime": "07:16:00", + "size": "large", + "features": [ + "symmetry" + ], "result": "success" }, { "path": "specifications/KeyValueStore/MCKVSSafetyMedium.cfg", "runtime": "00:04:30", "size": "medium", - "features": ["symmetry"], + "features": [ + "symmetry" + ], "result": "success" }, { - "path": "specifications/KeyValueStore/MCKVSSafetyLarge.cfg", - "runtime": "07:16:00", - "size": "large", - "features": ["symmetry"], + "path": "specifications/KeyValueStore/MCKVSSafetySmall.cfg", + "runtime": "00:00:40", + "size": "medium", + "features": [], "result": "success" } ] @@ -355,15 +413,21 @@ ] }, { + "path": "specifications/KnuthYao", "title": "The Knuth-Yao Method", "description": "A method for simulating a fair 6-sided die using only coin flips", "source": "https://old.reddit.com/r/tlaplus/comments/j06ohw/how_do_you_reason_about_a_probabilistic/g6owlxy/", - "authors": ["Ron Pressler", "Markus Kuppe"], + "authors": [ + "Ron Pressler", + "Markus Kuppe" + ], "tags": [], "modules": [ { "path": "specifications/KnuthYao/KnuthYao.tla", - "communityDependencies": ["DyadicRationals"], + "communityDependencies": [ + "DyadicRationals" + ], "tlaLanguageVersion": 2, "features": [], "models": [] @@ -377,7 +441,14 @@ }, { "path": "specifications/KnuthYao/SimKnuthYao.tla", - "communityDependencies": ["DyadicRationals", "Functions", "CSV", "TLCExt", "IOUtils", "Statistics"], + "communityDependencies": [ + "DyadicRationals", + "Functions", + "CSV", + "TLCExt", + "IOUtils", + "Statistics" + ], "tlaLanguageVersion": 2, "features": [], "models": [ @@ -385,7 +456,9 @@ "path": "specifications/KnuthYao/SimKnuthYao.cfg", "runtime": "unknown", "size": "unknown", - "features": ["state constraint"], + "features": [ + "state constraint" + ], "result": "unknown" } ] @@ -393,10 +466,13 @@ ] }, { + "path": "specifications/LevelChecking", "title": "TLA⁺ Level Checking", "description": "Level-checking of TLA⁺ formulas as described in Specifying Systems", "source": "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/tlaplus/tlaplus/blob/6bc82f7746ccdfbdf49cdef24448666d11e5e218/tlatools/org.lamport.tlatools/src/tla2sany/semantic/LevelNode.java#L354-L2778", - "authors": ["Leslie Lamport"], + "authors": [ + "Leslie Lamport" + ], "tags": [], "modules": [ { @@ -409,54 +485,73 @@ ] }, { + "path": "specifications/LoopInvariance", "title": "Loop Invariance", "description": "Examples of finding and proving loop invariants in PlusCal", "source": "http://lamport.azurewebsites.net/tla/proving-safety.pdf", - "authors": ["Leslie Lamport"], + "authors": [ + "Leslie Lamport" + ], "tags": [], "modules": [ { "path": "specifications/LoopInvariance/BinarySearch.tla", "communityDependencies": [], "tlaLanguageVersion": 2, - "features": ["pluscal", "proof"], + "features": [ + "pluscal", + "proof" + ], "models": [] }, { "path": "specifications/LoopInvariance/Quicksort.tla", "communityDependencies": [], "tlaLanguageVersion": 2, - "features": ["pluscal", "proof"], + "features": [ + "pluscal", + "proof" + ], "models": [] }, { "path": "specifications/LoopInvariance/SumSequence.tla", "communityDependencies": [], "tlaLanguageVersion": 2, - "features": ["pluscal", "proof"], + "features": [ + "pluscal", + "proof" + ], "models": [] } ] }, { + "path": "specifications/MisraReachability", "title": "Misra Reachability Algorithm", "description": "A sequential algorithm for computing the set of reachable nodes in a directed graph", "source": "", - "authors": ["Leslie Lamport"], + "authors": [ + "Leslie Lamport" + ], "tags": [], "modules": [ { "path": "specifications/MisraReachability/ParReach.tla", "communityDependencies": [], "tlaLanguageVersion": 2, - "features": ["pluscal"], + "features": [ + "pluscal" + ], "models": [] }, { "path": "specifications/MisraReachability/ParReachProofs.tla", "communityDependencies": [], "tlaLanguageVersion": 2, - "features": ["proof"], + "features": [ + "proof" + ], "models": [] }, { @@ -470,7 +565,9 @@ "path": "specifications/MisraReachability/ReachabilityProofs.tla", "communityDependencies": [], "tlaLanguageVersion": 2, - "features": ["proof"], + "features": [ + "proof" + ], "models": [] }, { @@ -484,23 +581,30 @@ "path": "specifications/MisraReachability/Reachable.tla", "communityDependencies": [], "tlaLanguageVersion": 2, - "features": ["pluscal"], + "features": [ + "pluscal" + ], "models": [] }, { "path": "specifications/MisraReachability/ReachableProofs.tla", "communityDependencies": [], "tlaLanguageVersion": 2, - "features": ["proof"], + "features": [ + "proof" + ], "models": [] } ] }, { + "path": "specifications/MissionariesAndCannibals", "title": "Missionaries and Cannibals", "description": "Spec of a river-crossing puzzle", "source": "", - "authors": ["Leslie Lamport"], + "authors": [ + "Leslie Lamport" + ], "tags": ["beginner"], "modules": [ { @@ -513,10 +617,13 @@ ] }, { + "path": "specifications/MultiCarElevator", "title": "Multi-Car Elevator System", "description": "A simple multi-car elevator system servicing a multi-floor building", "source": "https://groups.google.com/g/tlaplus/c/5Xd8kv288jE/m/IrliJIatBwAJ", - "authors": ["Andrew Helwer"], + "authors": [ + "Andrew Helwer" + ], "tags": [], "modules": [ { @@ -526,17 +633,21 @@ "features": [], "models": [ { - "path": "specifications/MultiCarElevator/ElevatorLivenessSmall.cfg", - "runtime": "00:00:05", - "size": "small", - "features": ["liveness"], + "path": "specifications/MultiCarElevator/ElevatorLivenessLarge.cfg", + "runtime": "00:11:00", + "size": "large", + "features": [ + "liveness" + ], "result": "success" }, { - "path": "specifications/MultiCarElevator/ElevatorSafetyMedium.cfg", - "runtime": "00:03:00", - "size": "medium", - "features": [], + "path": "specifications/MultiCarElevator/ElevatorLivenessSmall.cfg", + "runtime": "00:00:05", + "size": "small", + "features": [ + "liveness" + ], "result": "success" }, { @@ -547,10 +658,10 @@ "result": "success" }, { - "path": "specifications/MultiCarElevator/ElevatorLivenessLarge.cfg", - "runtime": "00:11:00", - "size": "large", - "features": ["liveness"], + "path": "specifications/MultiCarElevator/ElevatorSafetyMedium.cfg", + "runtime": "00:03:00", + "size": "medium", + "features": [], "result": "success" } ] @@ -558,80 +669,2389 @@ ] }, { - "title": "The Nano Blockchain Protocol", - "description": "A specification of the protocol originally used by the Nano blockchain", - "source": "https://docs.nano.org/whitepaper/english/", - "authors": ["Andrew Helwer"], - "tags": ["blockchain"], + "path": "specifications/N-Queens", + "title": "The N-Queens Puzzle", + "description": "Place N queens on an NxN chess board such that no two queens threaten each other", + "source": "", + "authors": ["Stephan Merz"], + "tags": ["beginner"], "modules": [ { - "path": "specifications/NanoBlockchain/Nano.tla", + "path": "specifications/N-Queens/Queens.tla", "communityDependencies": [], "tlaLanguageVersion": 2, "features": [], "models": [] }, { - "path": "specifications/NanoBlockchain/MCNano.tla", + "path": "specifications/N-Queens/Queens.toolbox/FourQueens/MC.tla", "communityDependencies": [], "tlaLanguageVersion": 2, "features": [], "models": [ { - "path": "specifications/NanoBlockchain/MCNanoSmall.cfg", - "runtime": "00:00:05", - "size": "small", - "features": ["view"], - "result": "success" - }, + "path": "specifications/N-Queens/Queens.toolbox/FourQueens/MC.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [], + "result": "unknown" + } + ] + }, + { + "path": "specifications/N-Queens/Queens.toolbox/FourQueens/Queens.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/N-Queens/QueensPluscal.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [ + "pluscal" + ], + "models": [] + }, + { + "path": "specifications/N-Queens/QueensPluscal.toolbox/FourQueens/MC.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/N-Queens/QueensPluscal.toolbox/FourQueens/MC.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [ + "liveness" + ], + "result": "unknown" + } + ] + }, + { + "path": "specifications/N-Queens/QueensPluscal.toolbox/FourQueens/QueensPluscal.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [ + "pluscal" + ], + "models": [] + } + ] + }, + { + "path": "specifications/NanoBlockchain", + "title": "The Nano Blockchain Protocol", + "description": "A specification of the protocol originally used by the Nano blockchain", + "source": "", + "authors": [ + "Andrew Helwer" + ], + "tags": [], + "modules": [ + { + "path": "specifications/NanoBlockchain/MCNano.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ { "path": "specifications/NanoBlockchain/MCNanoLarge.cfg", "runtime": "00:20:00", "size": "large", - "features": ["view"], + "features": [ + "view" + ], + "result": "success" + }, + { + "path": "specifications/NanoBlockchain/MCNanoSmall.cfg", + "runtime": "00:00:05", + "size": "small", + "features": [ + "view" + ], "result": "success" } ] + }, + { + "path": "specifications/NanoBlockchain/Nano.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] } ] }, { - "title": "The Slush Probabilistic Consensus Protocol", - "description": "An attempt to use TLA⁺ to analyze a probabilistic protocol in the Avalanche family", - "source": "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/ahelwer/avalanche-analysis", - "authors": ["Andrew Helwer"], - "tags": ["probability"], + "path": "specifications/Paxos", + "title": "The Paxos Protocol", + "description": "A protocol for error-tolerant consensus", + "source": "", + "authors": ["Leslie Lamport"], + "tags": [], "modules": [ { - "path": "specifications/SlushProtocol/Slush.tla", + "path": "specifications/Paxos/Consensus.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [ + "proof" + ], + "models": [] + }, + { + "path": "specifications/Paxos/MCConsensus.tla", "communityDependencies": [], "tlaLanguageVersion": 2, - "features": ["pluscal"], + "features": [], "models": [ { - "path": "specifications/SlushProtocol/SlushSmall.cfg", - "runtime": "00:00:08", - "size": "small", + "path": "specifications/Paxos/MCConsensus.cfg", + "runtime": "unknown", + "size": "unknown", "features": [], - "result": "success" - }, + "result": "unknown" + } + ] + }, + { + "path": "specifications/Paxos/MCPaxos.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ { - "path": "specifications/SlushProtocol/SlushMedium.cfg", - "runtime": "00:01:00", - "size": "medium", - "features": [], - "result": "success" - }, + "path": "specifications/Paxos/MCPaxos.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [ + "liveness", + "symmetry" + ], + "result": "unknown" + } + ] + }, + { + "path": "specifications/Paxos/MCVoting.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ { - "path": "specifications/SlushProtocol/SlushLarge.cfg", - "runtime": "00:50:00", - "size": "large", - "features": [], - "result": "success" + "path": "specifications/Paxos/MCVoting.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [ + "liveness", + "symmetry" + ], + "result": "unknown" + } + ] + }, + { + "path": "specifications/Paxos/Paxos.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/Paxos/Voting.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [ + "proof" + ], + "models": [] + } + ] + }, + { + "path": "specifications/PaxosHowToWinATuringAward", + "title": "How to Win a Turing Award", + "description": "Exercises from the lecture The Paxos Algorithm - or How to Win a Turing Award", + "source": "https://www.youtube.com/watch?v=tw3gsBms-f8", + "authors": ["Leslie Lamport"], + "tags": [], + "modules": [ + { + "path": "specifications/PaxosHowToWinATuringAward/Consensus.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [ + "proof" + ], + "models": [] + }, + { + "path": "specifications/PaxosHowToWinATuringAward/Paxos.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/PaxosHowToWinATuringAward/Voting.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [ + "proof" + ], + "models": [] + } + ] + }, + { + "path": "specifications/Prisoners", + "title": "The Prisoners & Switches Puzzle", + "description": "Given a room containing two switches prisoners enter one by one, they must develop a strategy to free themselves", + "source": "", + "authors": ["Leslie Lamport"], + "tags": ["beginner"], + "modules": [ + { + "path": "specifications/Prisoners/MCPrisoners.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/Prisoners/Prisoners.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/Prisoners/Prisoners.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [ + "liveness" + ], + "result": "unknown" } ] } ] + }, + { + "path": "specifications/ReadersWriters", + "title": "The Readers-Writers Problem", + "description": "Controlling concurrent access to a resource", + "source": "", + "authors": ["Isaac DeFrain"], + "tags": [], + "modules": [ + { + "path": "specifications/ReadersWriters/MC.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/ReadersWriters/MC.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [ + "liveness" + ], + "result": "unknown" + } + ] + }, + { + "path": "specifications/ReadersWriters/ReadersWriters.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + } + ] + }, + { + "path": "specifications/SingleLaneBridge", + "title": "Single-Lane Bridge Problem", + "description": "Controlling cars moving over a single-lange bridge in opposite directions", + "source": "", + "authors": [], + "tags": [], + "modules": [ + { + "path": "specifications/SingleLaneBridge/MC.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/SingleLaneBridge/MC.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [ + "liveness" + ], + "result": "unknown" + } + ] + }, + { + "path": "specifications/SingleLaneBridge/SingleLaneBridge.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + } + ] + }, + { + "path": "specifications/SlidingPuzzles", + "title": "Sliding Block Puzzle", + "description": "A spec of the Klotski sliding block puzzle", + "source": "", + "authors": ["Mariusz Ryndzionek"], + "tags": ["beginner"], + "modules": [ + { + "path": "specifications/SlidingPuzzles/SlidingPuzzles.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + } + ] + }, + { + "path": "specifications/SlushProtocol", + "title": "The Slush Probabilistic Consensus Protocol", + "description": "An attempt to use TLA⁺ to analyze a probabilistic protocol in the Avalanche family", + "source": "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/ahelwer/avalanche-analysis", + "authors": [ + "Andrew Helwer" + ], + "tags": [], + "modules": [ + { + "path": "specifications/SlushProtocol/Slush.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [ + "pluscal" + ], + "models": [ + { + "path": "specifications/SlushProtocol/SlushLarge.cfg", + "runtime": "00:50:00", + "size": "large", + "features": [], + "result": "success" + }, + { + "path": "specifications/SlushProtocol/SlushMedium.cfg", + "runtime": "00:01:00", + "size": "medium", + "features": [], + "result": "success" + }, + { + "path": "specifications/SlushProtocol/SlushSmall.cfg", + "runtime": "00:00:08", + "size": "small", + "features": [], + "result": "success" + } + ] + } + ] + }, + { + "path": "specifications/SpanningTree", + "title": "Span Tree Exercise", + "description": "Simplified algorithm from the Lamport paper *An Assertional Correctness Proof of a Distributed Program*", + "source": "", + "authors": ["Leslie Lamport"], + "tags": [], + "modules": [ + { + "path": "specifications/SpanningTree/SpanTree.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpanningTree/SpanTreeRandom.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpanningTree/SpanTreeTest.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + } + ] + }, + { + "path": "specifications/SpecifyingSystems", + "title": "Specs from Specifying Systems", + "description": "All specs seen in the textbook Specifying Systems by Leslie Lamport", + "source": "http://lamport.azurewebsites.net/tla/book.html", + "authors": ["Leslie Lamport"], + "tags": [], + "modules": [ + { + "path": "specifications/SpecifyingSystems/AdvancedExamples/BNFGrammars.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/AdvancedExamples/DifferentialEquations.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/AdvancedExamples/Graphs.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/AdvancedExamples/InnerSequential.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/AdvancedExamples/InnerSerial.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/AdvancedExamples/MCInnerSequential.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/SpecifyingSystems/AdvancedExamples/MCInnerSequential.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [ + "state constraint", + "liveness" + ], + "result": "unknown" + } + ] + }, + { + "path": "specifications/SpecifyingSystems/AdvancedExamples/MCInnerSerial.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/SpecifyingSystems/AdvancedExamples/MCInnerSerial.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [ + "state constraint", + "liveness" + ], + "result": "unknown" + } + ] + }, + { + "path": "specifications/SpecifyingSystems/AdvancedExamples/RegisterInterface.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/AdvancedExamples/SerialMemory.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/AsynchronousInterface/AsynchInterface.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/SpecifyingSystems/AsynchronousInterface/AsynchInterface.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [], + "result": "unknown" + } + ] + }, + { + "path": "specifications/SpecifyingSystems/AsynchronousInterface/Channel.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/SpecifyingSystems/AsynchronousInterface/Channel.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [], + "result": "unknown" + } + ] + }, + { + "path": "specifications/SpecifyingSystems/AsynchronousInterface/PrintValues.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/SpecifyingSystems/AsynchronousInterface/PrintValues.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [], + "result": "unknown" + } + ] + }, + { + "path": "specifications/SpecifyingSystems/CachingMemory/InternalMemory.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/CachingMemory/MCInternalMemory.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/SpecifyingSystems/CachingMemory/MCInternalMemory.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [], + "result": "unknown" + } + ] + }, + { + "path": "specifications/SpecifyingSystems/CachingMemory/MCWriteThroughCache.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/SpecifyingSystems/CachingMemory/MCWriteThroughCache.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [ + "liveness" + ], + "result": "unknown" + } + ] + }, + { + "path": "specifications/SpecifyingSystems/CachingMemory/Memory.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/CachingMemory/MemoryInterface.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/CachingMemory/WriteThroughCache.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/CachingMemory/WriteThroughCacheInstanced.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/Composing/BinaryHourClock.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/Composing/Channel.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/Composing/ChannelRefinement.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/Composing/CompositeFIFO.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/Composing/HourClock.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/Composing/InternalMemory.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/Composing/JointActionMemory.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/Composing/MemoryInterface.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/FIFO/Channel.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/FIFO/FIFO.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/FIFO/InnerFIFO.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/FIFO/InnerFIFOInstanced.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/FIFO/MCInnerFIFO.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/SpecifyingSystems/FIFO/MCInnerFIFO.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [ + "state constraint" + ], + "result": "unknown" + } + ] + }, + { + "path": "specifications/SpecifyingSystems/HourClock/HourClock.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/SpecifyingSystems/HourClock/HourClock.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [], + "result": "unknown" + } + ] + }, + { + "path": "specifications/SpecifyingSystems/HourClock/HourClock2.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/SpecifyingSystems/HourClock/HourClock2.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [ + "liveness" + ], + "result": "unknown" + } + ] + }, + { + "path": "specifications/SpecifyingSystems/Liveness/HourClock.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/Liveness/InternalMemory.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/Liveness/LiveHourClock.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/SpecifyingSystems/Liveness/LiveHourClock.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [ + "liveness" + ], + "result": "unknown" + } + ] + }, + { + "path": "specifications/SpecifyingSystems/Liveness/LiveInternalMemory.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/Liveness/LiveWriteThroughCache.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/Liveness/MCInternalMemory.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/Liveness/MCLiveInternalMemory.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/SpecifyingSystems/Liveness/MCLiveInternalMemory.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [ + "liveness" + ], + "result": "unknown" + } + ] + }, + { + "path": "specifications/SpecifyingSystems/Liveness/MCLiveWriteThroughCache.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/SpecifyingSystems/Liveness/MCLiveWriteThroughCache.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [ + "liveness" + ], + "result": "unknown" + } + ] + }, + { + "path": "specifications/SpecifyingSystems/Liveness/Memory.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/Liveness/MemoryInterface.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/Liveness/WriteThroughCacheInstanced.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/RealTime/HourClock.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/RealTime/InternalMemory.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/RealTime/MCRealTime.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/RealTime/MCRealTimeHourClock.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/SpecifyingSystems/RealTime/MCRealTimeHourClock.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [ + "liveness" + ], + "result": "unknown" + } + ] + }, + { + "path": "specifications/SpecifyingSystems/RealTime/Memory.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/RealTime/MemoryInterface.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/RealTime/RTMemory.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/RealTime/RTWriteThroughCache.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/RealTime/RealTime.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/RealTime/RealTimeHourClock.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/RealTime/WriteThroughCache.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/SimpleMath/SimpleMath.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/SpecifyingSystems/SimpleMath/SimpleMath.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [], + "result": "unknown" + } + ] + }, + { + "path": "specifications/SpecifyingSystems/Standard/Bags.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/Standard/FiniteSets.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/Standard/Integers.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/Standard/Naturals.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/Standard/Peano.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/Standard/ProtoReals.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/Standard/Reals.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/Standard/Sequences.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/Syntax/BNFGrammars.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/Syntax/TLAPlusGrammar.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/TLC/ABCorrectness.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/SpecifyingSystems/TLC/ABCorrectness.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [], + "result": "unknown" + } + ] + }, + { + "path": "specifications/SpecifyingSystems/TLC/AlternatingBit.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/TLC/BNFGrammars.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/TLC/ConfigFileGrammar.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SpecifyingSystems/TLC/MCAlternatingBit.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/SpecifyingSystems/TLC/MCAlternatingBit.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [ + "state constraint", + "liveness" + ], + "result": "unknown" + } + ] + }, + { + "path": "specifications/SpecifyingSystems/TLC/TLC.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + } + ] + }, + { + "path": "specifications/Stones", + "title": "Stone Scale Puzzle", + "description": "Alternative implementation of the Car Talk Puzzle", + "source": "", + "authors": ["Leslie Lamport"], + "tags": [], + "modules": [ + { + "path": "specifications/Stones/Stones.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + } + ] + }, + { + "path": "specifications/TLC", + "title": "The TLC Safety Checking Algorithm", + "description": "Spec of the safety checking algorithm used by the TLC model-checker", + "source": "", + "authors": ["Markus Kuppe"], + "tags": [], + "modules": [ + { + "path": "specifications/TLC/TLCMC.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [ + "pluscal" + ], + "models": [] + }, + { + "path": "specifications/TLC/TestGraphs.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/TLC/TestGraphs.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [ + "liveness" + ], + "result": "unknown" + } + ] + } + ] + }, + { + "path": "specifications/TeachingConcurrency", + "title": "Teaching Concurrency", + "description": "Simple problem useful for teaching and learning about concurrency", + "source": "http://lamport.azurewebsites.net/pubs/teaching-concurrency.pdf", + "authors": [], + "tags": [], + "modules": [ + { + "path": "specifications/TeachingConcurrency/Simple.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [ + "pluscal", + "proof" + ], + "models": [] + }, + { + "path": "specifications/TeachingConcurrency/SimpleRegular.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [ + "pluscal", + "proof" + ], + "models": [] + } + ] + }, + { + "path": "specifications/TransitiveClosure", + "title": "Transitive Closure", + "description": "Spec defining the transitive closure of a relation", + "source": "", + "authors": [], + "tags": [], + "modules": [ + { + "path": "specifications/TransitiveClosure/TransitiveClosure.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/TransitiveClosure/TransitiveClosure.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [], + "result": "unknown" + } + ] + } + ] + }, + { + "path": "specifications/TwoPhase", + "title": "Two-Phase Handshaking", + "description": "Specification of a very simple hardware protocol called two-phase handshaking", + "source": "", + "authors": [ + "Leslie Lamport", + "Stephan Merz" + ], + "tags": [], + "modules": [ + { + "path": "specifications/TwoPhase/Alternate.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/TwoPhase/TLAPS.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [ + "proof" + ], + "models": [] + }, + { + "path": "specifications/TwoPhase/TwoPhase.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [ + "proof" + ], + "models": [] + } + ] + }, + { + "path": "specifications/aba-asyn-byz", + "title": "Asynchronous Byzantine Consensus", + "description": "Spec of the protocol from paper *Asynchronous Consensus and Broadcast Protocols* (1985)", + "source": "", + "authors": [ + "Thanh Hai Tran", + "Igor Konnov", + "Josef Widder" + ], + "tags": [], + "modules": [ + { + "path": "specifications/aba-asyn-byz/aba_asyn_byz.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + } + ] + }, + { + "path": "specifications/allocator", + "title": "Resource Allocator", + "description": "Specification of a resource allocator", + "source": "", + "authors": ["Stephan Merz"], + "tags": [], + "modules": [ + { + "path": "specifications/allocator/AllocatorImplementation.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/allocator/AllocatorImplementation.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [ + "liveness" + ], + "result": "unknown" + } + ] + }, + { + "path": "specifications/allocator/AllocatorRefinement.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/allocator/AllocatorRefinement.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [ + "liveness" + ], + "result": "unknown" + } + ] + }, + { + "path": "specifications/allocator/SchedulingAllocator.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/allocator/SchedulingAllocator.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [ + "liveness" + ], + "result": "unknown" + } + ] + }, + { + "path": "specifications/allocator/SimpleAllocator.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/allocator/SimpleAllocator.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [ + "liveness" + ], + "result": "unknown" + } + ] + } + ] + }, + { + "path": "specifications/bcastByz", + "title": "Asynchronous Reliable Broadcast", + "description": "Algorithm from paper *Simulating authenticated broadcasts to derive simple fault-tolerant algorithms* (1987)", + "source": "", + "authors": [ + "Thanh Hai Tran", + "Igor Konnov", + "Josef Widder" + ], + "tags": [], + "modules": [ + { + "path": "specifications/bcastByz/bcastByz.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [ + "proof" + ], + "models": [] + } + ] + }, + { + "path": "specifications/bcastFolklore", + "title": "Folklore Reliable Broadcast", + "description": "Algorithm from paper *Unreliable failure detectors for reliable distributed systems* (1996)", + "source": "", + "authors": [ + "Thanh Hai Tran", + "Igor Konnov", + "Josev Widder" + ], + "tags": [], + "modules": [ + { + "path": "specifications/bcastFolklore/bcastFolklore.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + } + ] + }, + { + "path": "specifications/bosco", + "title": "The Bosco Byzantine Consensus Algorithm", + "description": "Algorithm from paper *Bosco: One-step byzantine asynchronous consensus* (2008)", + "source": "", + "authors": [ + "Thanh Hai Tran", + "Igor Konnov", + "Josev Widder" + ], + "tags": [], + "modules": [ + { + "path": "specifications/bosco/bosco.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + } + ] + }, + { + "path": "specifications/c1cs", + "title": "Consensus in One Communication Step", + "description": "Algorithm from paper *Consensus in one communication step* (2001)", + "source": "", + "authors": [ + "Thanh Hai Tran", + "Igor Konnov", + "Josev Widder" + ], + "tags": [], + "modules": [ + { + "path": "specifications/c1cs/c1cs.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + } + ] + }, + { + "path": "specifications/cbc_max", + "title": "Condition-Based Consensus", + "description": "Algorithm from paper *Evaluating the condition-based approach to solve consensus* (2003)", + "source": "", + "authors": [ + "Thanh Hai Tran", + "Igor Konnov", + "Josev Widder" + ], + "tags": [], + "modules": [ + { + "path": "specifications/cbc_max/cbc_max.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + } + ] + }, + { + "path": "specifications/cf1s-folklore", + "title": "One-Step Consensus with Zero-Degradation", + "description": "Algorithm from paper *One-step Consensus with Zero-Degradation* (2006)", + "source": "", + "authors": [ + "Thanh Hai Tran", + "Igor Konnov", + "Josev Widder" + ], + "tags": [], + "modules": [ + { + "path": "specifications/cf1s-folklore/cf1s_folklore.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + } + ] + }, + { + "path": "specifications/chang_roberts", + "title": "Chang-Roberts Algorithm for Leader Election in a Ring", + "description": "Algorithm from paper *An improved algorithm for decentralized extrema-finding in circular configurations of processes* (1979)", + "source": "", + "authors": ["Stephan Merz"], + "tags": [], + "modules": [ + { + "path": "specifications/chang_roberts/ChangRoberts.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [ + "pluscal" + ], + "models": [] + } + ] + }, + { + "path": "specifications/detector_chan96", + "title": "Failure Detector", + "description": "Algorithm from paper *Unreliable failure detectors for reliable distributed systems* (1996)", + "source": "", + "authors": [ + "Thanh Hai Tran", + "Igor Konnov", + "Josev Widder" + ], + "tags": [], + "modules": [ + { + "path": "specifications/detector_chan96/Age_Channel.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/detector_chan96/EPFailureDetector.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/detector_chan96/EnvironmentController.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + } + ] + }, + { + "path": "specifications/dijkstra-mutex", + "title": "Dijkstra's Mutual Exclusion Algorithm", + "description": "Algorithm from paper *Solution of a Problem in Concurrent Programming Control* (1965)", + "source": "", + "authors": ["Leslie Lamport"], + "tags": [], + "modules": [ + { + "path": "specifications/dijkstra-mutex/DijkstraMutex.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [ + "pluscal" + ], + "models": [] + }, + { + "path": "specifications/dijkstra-mutex/DijkstraMutex.toolbox/LSpec-model/DijkstraMutex.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [ + "pluscal" + ], + "models": [] + }, + { + "path": "specifications/dijkstra-mutex/DijkstraMutex.toolbox/LSpec-model/MC.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/dijkstra-mutex/DijkstraMutex.toolbox/LSpec-model/MC.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [ + "liveness" + ], + "result": "unknown" + } + ] + }, + { + "path": "specifications/dijkstra-mutex/DijkstraMutex.toolbox/Safety-4-processors/DijkstraMutex.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [ + "pluscal" + ], + "models": [] + }, + { + "path": "specifications/dijkstra-mutex/DijkstraMutex.toolbox/Safety-4-processors/MC.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/dijkstra-mutex/DijkstraMutex.toolbox/Safety-4-processors/MC.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [], + "result": "unknown" + } + ] + } + ] + }, + { + "path": "specifications/diskpaxos", + "title": "diskpaxos", + "description": "A formalization of the SWMR-Shared-Memory Disk Paxos", + "source": "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/nano-o/MultiPaxos/blob/master/DiskPaxos.tla", + "authors": [ + "Leslie Lamport", + "Giuliano Losa" + ], + "tags": [], + "modules": [ + { + "path": "specifications/diskpaxos/DiskSynod.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/diskpaxos/HDiskSynod.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/diskpaxos/Synod.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + } + ] + }, + { + "path": "specifications/echo", + "title": "The Echo Algorithm", + "description": "Algorithm for constructing a spanning tree in an undirected graph", + "source": "", + "authors": ["Stephan Merz"], + "tags": [], + "modules": [ + { + "path": "specifications/echo/Echo.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [ + "pluscal" + ], + "models": [] + }, + { + "path": "specifications/echo/MCEcho.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/echo/MCEcho.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [], + "result": "unknown" + } + ] + }, + { + "path": "specifications/echo/Relation.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + } + ] + }, + { + "path": "specifications/ewd426", + "title": "Token Stabilization", + "description": "Dijkstra's classical stabilizing token ring algorithm: EWD426", + "source": "", + "authors": [ + "Murat Demirbas", + "Markus Kuppe" + ], + "tags": [], + "modules": [ + { + "path": "specifications/ewd426/SimTokenRing.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/ewd426/SimTokenRing.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [ + "state constraint" + ], + "result": "unknown" + } + ] + }, + { + "path": "specifications/ewd426/TokenRing.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/ewd426/TokenRing.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [ + "alias", + "liveness" + ], + "result": "unknown" + } + ] + } + ] + }, + { + "path": "specifications/ewd687a", + "title": "Detecting Termination in Distributed Computations", + "description": "Dijkstra's Termination Detection Algorithm", + "source": "", + "authors": [ + "Leslie Lamport", + "Markus Kuppe", + "Stephan Merz" + ], + "tags": [], + "modules": [ + { + "path": "specifications/ewd687a/EWD687a.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/ewd687a/EWD687aPlusCal.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [ + "pluscal" + ], + "models": [] + }, + { + "path": "specifications/ewd687a/EWD687a_anim.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/ewd687a/EWD687a_anim.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [ + "alias", + "liveness" + ], + "result": "unknown" + } + ] + }, + { + "path": "specifications/ewd687a/MCEWD687a.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/ewd687a/MCEWD687a.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [ + "state constraint", + "liveness" + ], + "result": "unknown" + } + ] + } + ] + }, + { + "path": "specifications/ewd840", + "title": "ewd840", + "description": "Termination Detection in a Ring", + "source": "Dijkstra's termination detection algorithm for ring topologies", + "authors": ["Stephan Merz"], + "tags": [], + "modules": [ + { + "path": "specifications/ewd840/EWD840.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/ewd840/EWD840.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [], + "result": "unknown" + } + ] + }, + { + "path": "specifications/ewd840/EWD840_anim.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/ewd840/EWD840_anim.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [ + "alias" + ], + "result": "unknown" + } + ] + }, + { + "path": "specifications/ewd840/EWD840_json.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/ewd840/EWD840_json.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [], + "result": "unknown" + } + ] + }, + { + "path": "specifications/ewd840/EWD840_proof.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [ + "proof" + ], + "models": [] + }, + { + "path": "specifications/ewd840/SyncTerminationDetection.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/ewd840/SyncTerminationDetection.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [ + "liveness" + ], + "result": "unknown" + } + ] + }, + { + "path": "specifications/ewd840/TLAPS.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [ + "proof" + ], + "models": [] + } + ] + }, + { + "path": "specifications/ewd998", + "title": "Termination Detection in a Ring with Asynchronous Message Delivery", + "description": "Variant of EWD 840 given my Shmuel Safra", + "source": "", + "authors": [ + "Markus Kuppe", + "Stephan Merz" + ], + "tags": [], + "modules": [ + { + "path": "specifications/ewd998/AsyncTerminationDetection.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/ewd998/AsyncTerminationDetection.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [ + "state constraint" + ], + "result": "unknown" + } + ] + }, + { + "path": "specifications/ewd998/AsyncTerminationDetection_proof.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [ + "proof" + ], + "models": [ + { + "path": "specifications/ewd998/AsyncTerminationDetection_proof.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [ + "state constraint", + "liveness" + ], + "result": "unknown" + } + ] + }, + { + "path": "specifications/ewd998/EWD998.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/ewd998/EWD998.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [ + "state constraint" + ], + "result": "unknown" + } + ] + }, + { + "path": "specifications/ewd998/EWD998Chan.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/ewd998/EWD998Chan.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [ + "state constraint", + "liveness" + ], + "result": "unknown" + } + ] + }, + { + "path": "specifications/ewd998/EWD998ChanID.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/ewd998/EWD998ChanID.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [ + "view", + "state constraint", + "liveness" + ], + "result": "unknown" + } + ] + }, + { + "path": "specifications/ewd998/EWD998ChanID_export.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/ewd998/EWD998ChanID_export.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [], + "result": "unknown" + } + ] + }, + { + "path": "specifications/ewd998/EWD998ChanID_shiviz.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/ewd998/EWD998ChanID_shiviz.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [ + "alias" + ], + "result": "unknown" + } + ] + }, + { + "path": "specifications/ewd998/EWD998Chan_opts.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/ewd998/EWD998_anim.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/ewd998/EWD998_opts.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/ewd998/EWD998_optsSC.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/ewd998/EWD998_proof.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [ + "proof" + ], + "models": [] + }, + { + "path": "specifications/ewd998/SmokeEWD998.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/ewd998/SmokeEWD998.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [ + "state constraint", + "liveness" + ], + "result": "unknown" + } + ] + }, + { + "path": "specifications/ewd998/SmokeEWD998_SC.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/ewd998/SmokeEWD998_SC.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [], + "result": "unknown" + } + ] + }, + { + "path": "specifications/ewd998/Utils.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + } + ] + }, + { + "path": "specifications/glowingRaccoon", + "title": "PCR Testing for Snippets of DNA", + "description": "Specification of a PCR test process", + "source": "", + "authors": ["Martin Harrison"], + "tags": [], + "modules": [ + { + "path": "specifications/glowingRaccoon/clean.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/glowingRaccoon/product.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/glowingRaccoon/stages.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + } + ] + }, + { + "path": "specifications/lamport_mutex", + "title": "Distributed Mutual Exclusion", + "description": "Specification of Lamport's distributed mutual exclusion algorithm", + "source": "", + "authors": ["Stephan Merz"], + "tags": [], + "modules": [ + { + "path": "specifications/lamport_mutex/Functions.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/lamport_mutex/LamportMutex.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/lamport_mutex/LamportMutex_proofs.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [ + "proof" + ], + "models": [] + }, + { + "path": "specifications/lamport_mutex/NaturalsInduction.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/lamport_mutex/SequenceTheorems.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/lamport_mutex/TLAPS.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [ + "proof" + ], + "models": [] + }, + { + "path": "specifications/lamport_mutex/WellFoundedInduction.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + } + ] + }, + { + "path": "specifications/nbacc_ray97", + "title": "Asynchronous Non-Blocking Atomic Commit", + "description": "Algorithm from paper *A case study of agreement problems in distributed systems: non-blocking atomic commitment* (1997)", + "source": "", + "authors": [ + "Thanh Hai Tran", + "Igor Konnov", + "Josef Widder" + ], + "tags": [], + "modules": [ + { + "path": "specifications/nbacc_ray97/nbacc_ray97.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + } + ] + }, + { + "path": "specifications/nbacg_guer01", + "title": "Asynchronous Non-Blocking Atomic Commitment with Failure Detectors", + "description": "Algorithm from paper *On the hardness of failure-sensitive agreement problems* (2001)", + "source": "", + "authors": [ + "Thanh Hai Tran", + "Igor Konnov", + "Josef Widder" + ], + "tags": [], + "modules": [ + { + "path": "specifications/nbacg_guer01/nbacg_guer01.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + } + ] + }, + { + "path": "specifications/spanning", + "title": "Spanning Tree Broadcast Algorithm", + "description": "A spanning tree broadcast algorithm", + "source": "", + "authors": [ + "Thanh Hai Tran", + "Igor Konnov", + "Josef Widder" + ], + "tags": [], + "modules": [ + { + "path": "specifications/spanning/spanning.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + } + ] + }, + { + "path": "specifications/sums_even", + "title": "Proof x+x is Even", + "description": "Two proofs that x+x is even for every natural number x", + "source": "", + "authors": ["Stephan Merz"], + "tags": [], + "modules": [ + { + "path": "specifications/sums_even/TLAPS.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [ + "proof" + ], + "models": [] + }, + { + "path": "specifications/sums_even/sums_even.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [ + "proof" + ], + "models": [] + } + ] + }, + { + "path": "specifications/tower_of_hanoi", + "title": "The Tower of Hanoi Puzzle", + "description": "Famous puzzle involving stacking disks on towers", + "source": "", + "authors": [ + "Alexander Niederbühl", + "Markus Kuppe" + ], + "tags": ["beginner"], + "modules": [ + { + "path": "specifications/tower_of_hanoi/Bits.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/tower_of_hanoi/Hanoi.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/tower_of_hanoi/Hanoi.toolbox/Model_1/Bits.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/tower_of_hanoi/Hanoi.toolbox/Model_1/Hanoi.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/tower_of_hanoi/Hanoi.toolbox/Model_1/MC.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/tower_of_hanoi/Hanoi.toolbox/Model_1/MC.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [], + "result": "unknown" + } + ] + }, + { + "path": "specifications/tower_of_hanoi/HanoiSeq.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + } + ] + }, + { + "path": "specifications/transaction_commit", + "title": "Transaction Commit Models", + "description": "Ordinary transaction commit, two-phase commit, and Paxos commit", + "source": "http://research.microsoft.com/en-us/um/people/lamport/pubs/pubs.html#paxos-commit", + "authors": [ + "Jim Gray", + "Leslie Lamport" + ], + "tags": [], + "modules": [ + { + "path": "specifications/transaction_commit/PaxosCommit.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/transaction_commit/TCommit.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/transaction_commit/TwoPhase.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + } + ] } ] } From 1ca18117af0a4793a9bb14fdb6e6271925812793 Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Wed, 25 Jan 2023 21:17:50 -0500 Subject: [PATCH 11/70] Test to ensure CI fails Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- manifest.json | 1 - 1 file changed, 1 deletion(-) diff --git a/manifest.json b/manifest.json index 1d458dec..c3cca686 100644 --- a/manifest.json +++ b/manifest.json @@ -2941,7 +2941,6 @@ "communityDependencies": [], "tlaLanguageVersion": 2, "features": [ - "proof" ], "models": [] }, From 62e02b35ad757b0fe2425dac665b56c8375b65da Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Wed, 25 Jan 2023 21:19:24 -0500 Subject: [PATCH 12/70] Confirmed CI will correctly fail Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/workflows/CI.yml | 6 ------ manifest.json | 1 + 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 4af064d0..6ff31767 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -32,10 +32,4 @@ jobs: mv tree-sitter-tlaplus-$TSTLA_VERSION tree-sitter-tlaplus - name: Check manifest feature flags run: python $SCRIPT_DIR/check_manifest_features.py -# - name: Get nightly TLA⁺ tools -# run: wget https://nightly.tlapl.us/dist/tla2tools.jar -# - name: Check TLA⁺ specs parse -# run: python $SCRIPT_DIR/check-specs-parse.py -# - name: Check TLC models run -# run: python $SCRIPT_DIR/check-models-run.py diff --git a/manifest.json b/manifest.json index c3cca686..1d458dec 100644 --- a/manifest.json +++ b/manifest.json @@ -2941,6 +2941,7 @@ "communityDependencies": [], "tlaLanguageVersion": 2, "features": [ + "proof" ], "models": [] }, From a66586ef4045ce60a1c399c349afff504b11a8ad Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Thu, 26 Jan 2023 10:34:12 -0500 Subject: [PATCH 13/70] Added community module import check Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .../scripts/check_manifest_features.py | 94 ++++++++++++++++++- .../workflows/scripts/generate_manifest.py | 11 +-- 2 files changed, 93 insertions(+), 12 deletions(-) diff --git a/.github/workflows/scripts/check_manifest_features.py b/.github/workflows/scripts/check_manifest_features.py index c3855ad8..c8b0c59c 100644 --- a/.github/workflows/scripts/check_manifest_features.py +++ b/.github/workflows/scripts/check_manifest_features.py @@ -1,4 +1,6 @@ +import glob import json +from os.path import basename, dirname, splitext from tree_sitter import Language, Parser Language.build_library( @@ -10,7 +12,7 @@ parser = Parser() parser.set_language(TLAPLUS_LANGUAGE) -query = TLAPLUS_LANGUAGE.query( +feature_query = TLAPLUS_LANGUAGE.query( '(pcal_algorithm_start) @pluscal' + '[(terminal_proof) (non_terminal_proof)] @proof' ) @@ -20,13 +22,13 @@ def parse_module(path): with open(path, 'rb') as module_file: module_text = module_file.read() tree = parser.parse(module_text) - return (tree, tree.root_node.has_error) + return (tree, module_text, tree.root_node.has_error) def get_tree_features(tree): - return set([name for _, name in query.captures(tree.root_node)]) + return set([name for _, name in feature_query.captures(tree.root_node)]) def get_module_features(path): - tree, _ = parse_module(path) + tree, _, _ = parse_module(path) return list(get_tree_features(tree)) model_features = { @@ -54,6 +56,80 @@ def get_model_features(path): features.append(model_features[tokens[0]]) return set(features) +import_query = TLAPLUS_LANGUAGE.query( + '(extends (identifier_ref) @extends)' + + '(instance (identifier_ref) @instance)' +) + +module_name_query = TLAPLUS_LANGUAGE.query( + '(module name: (identifier) @module_name)' +) + +tlc_modules = { + 'Bags', + 'FiniteSets', + 'Integers', + 'Json', + 'Naturals', + 'Randomization', + 'RealTime', + 'Reals', + 'Sequences', + 'TLC', + 'TLCExt', + 'Toolbox' +} + +tlaps_modules = { + 'BagsTheorems', + 'FiniteSetTheorems', + 'FunctionTheorems', + 'NaturalsInduction', + 'SequenceTheorems', + 'SequencesExtTheorems', + 'TLAPS', + 'WellFoundedInduction' +} + +tlaps_module_overloads = { + 'Bags', + 'FiniteSets', + 'Functions', + 'RealTime', + 'SequencesExt' +} + +def get_module_names_in_dir(dir): + return set([splitext(basename(path))[0] for path in glob.glob(f'{dir}/*.tla')]) + +def get_community_imports(tree, text, dir, has_proof): + imports = set( + [ + text[node.start_byte:node.end_byte].decode('utf-8') + for node, _ in import_query.captures(tree.root_node) + ] + ) + modules_in_file = set( + [ + text[node.start_byte:node.end_byte].decode('utf-8') + for node, _ in module_name_query.captures(tree.root_node) + ] + ) + imports = ( + imports + - modules_in_file + - tlc_modules + - tlaps_modules + - get_module_names_in_dir(dir) + ) + return imports - tlaps_module_overloads if has_proof else imports + +def get_community_module_imports(path): + tree, text, _ = parse_module(path) + dir = dirname(path) + has_proof = 'proof' in get_tree_features(tree) + return list(get_community_imports(tree, text, dir, has_proof)) + if __name__ == '__main__': manifest = None with open('manifest.json', 'rt') as manifest_file: @@ -62,7 +138,7 @@ def get_model_features(path): success = True for spec in manifest['specifications']: for module in spec['modules']: - tree, parse_err = parse_module(module['path']) + tree, text, parse_err = parse_module(module['path']) if parse_err: success = False print(f'Module {module["path"]} contains syntax errors') @@ -74,6 +150,14 @@ def get_model_features(path): f'Module {module["path"]} has incorrect features in manifest; ' + f'expected {list(expected_features)}, actual {list(actual_features)}' ) + expected_imports = get_community_imports(tree, text, dirname(module['path']), 'proof' in expected_features) + actual_imports = set(module['communityDependencies']) + if expected_imports != actual_imports: + success = False + print( + f'Module {module["path"]} has incorrect community dependencies in manifest; ' + + f'expected {list(expected_imports)}, actual {list(actual_imports)}' + ) for model in module['models']: expected_features = get_model_features(model['path']) actual_features = set(model['features']) diff --git a/.github/workflows/scripts/generate_manifest.py b/.github/workflows/scripts/generate_manifest.py index 5d557471..4c83cabe 100644 --- a/.github/workflows/scripts/generate_manifest.py +++ b/.github/workflows/scripts/generate_manifest.py @@ -1,6 +1,6 @@ # Generates a best-effort manifest.json -from check_manifest_features import get_module_features, get_model_features +from check_manifest_features import get_community_module_imports, get_module_features, get_module_names_in_dir, get_model_features import json import os from os.path import basename, dirname, join, normpath, splitext @@ -20,10 +20,7 @@ def get_cfg_files(tla_path): """ parent_dir = dirname(tla_path) module_name, _ = splitext(basename(tla_path)) - other_module_names = set(filter( - lambda other_module_name: other_module_name != module_name, - [splitext(basename(path))[0] for path in glob.glob(f'{join(parent_dir, module_name)}*.tla')] - )) + other_module_names = [other for other in get_module_names_in_dir(parent_dir) if other != module_name] return [ normpath(path) for path in glob.glob(f'{join(parent_dir, module_name)}*.cfg') if splitext(basename(path))[0] not in other_module_names @@ -41,7 +38,7 @@ def get_cfg_files(tla_path): 'modules': [ { 'path': tla_path, - 'communityDependencies': [], + 'communityDependencies': get_community_module_imports(tla_path), 'tlaLanguageVersion': 2, 'features': get_module_features(tla_path), 'models': [ @@ -88,7 +85,7 @@ def find_corresponding_module(old_module, new_spec): ][0] def integrate_module_info(old_module, new_module): - fields = ['communityDependencies', 'tlaLanguageVersion'] + fields = ['tlaLanguageVersion'] for field in fields: new_module[field] = old_module[field] From 765d31452c9c15a3dfaa1f0d5e75fa99b6206137 Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Thu, 26 Jan 2023 10:55:53 -0500 Subject: [PATCH 14/70] Added community module imports to manifest Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .../scripts/check_manifest_features.py | 13 +- .../workflows/scripts/generate_manifest.py | 21 +- manifest.json | 289 ++++++++++++------ 3 files changed, 214 insertions(+), 109 deletions(-) diff --git a/.github/workflows/scripts/check_manifest_features.py b/.github/workflows/scripts/check_manifest_features.py index c8b0c59c..3f2aca3a 100644 --- a/.github/workflows/scripts/check_manifest_features.py +++ b/.github/workflows/scripts/check_manifest_features.py @@ -29,7 +29,7 @@ def get_tree_features(tree): def get_module_features(path): tree, _, _ = parse_module(path) - return list(get_tree_features(tree)) + return get_tree_features(tree) model_features = { 'PROPERTY': 'liveness', @@ -128,7 +128,7 @@ def get_community_module_imports(path): tree, text, _ = parse_module(path) dir = dirname(path) has_proof = 'proof' in get_tree_features(tree) - return list(get_community_imports(tree, text, dir, has_proof)) + return get_community_imports(tree, text, dir, has_proof) if __name__ == '__main__': manifest = None @@ -137,6 +137,15 @@ def get_community_module_imports(path): success = True for spec in manifest['specifications']: + if spec['title'] == '': + success = False + print(f'Spec {spec["path"]} does not have a title') + if spec['description'] == '': + success = False + print(f'Spec {spec["path"]} does not have a description') + if not any(spec['authors']): + success = False + print(f'Spec {spec["path"]} does not have any listed authors') for module in spec['modules']: tree, text, parse_err = parse_module(module['path']) if parse_err: diff --git a/.github/workflows/scripts/generate_manifest.py b/.github/workflows/scripts/generate_manifest.py index 4c83cabe..ba88c564 100644 --- a/.github/workflows/scripts/generate_manifest.py +++ b/.github/workflows/scripts/generate_manifest.py @@ -38,15 +38,15 @@ def get_cfg_files(tla_path): 'modules': [ { 'path': tla_path, - 'communityDependencies': get_community_module_imports(tla_path), + 'communityDependencies': sorted(list(get_community_module_imports(tla_path))), 'tlaLanguageVersion': 2, - 'features': get_module_features(tla_path), + 'features': sorted(list(get_module_features(tla_path))), 'models': [ { 'path': cfg_path, 'runtime': 'unknown', 'size': 'unknown', - 'features': list(get_model_features(cfg_path)), + 'features': sorted(list(get_model_features(cfg_path))), 'result': 'unknown' } for cfg_path in sorted(get_cfg_files(tla_path)) @@ -64,19 +64,16 @@ def get_cfg_files(tla_path): # Integrate human-readable info from existing manifest def find_corresponding_spec(old_spec, new_manifest): - old_modules = old_spec['modules'] - old_module_paths = set([normpath(module['path']) for module in old_modules]) - return list(filter( - lambda new_spec: any( - [old_module_path.startswith(new_spec['path']) for old_module_path in old_module_paths] - ), - new_manifest['specifications'] - ))[0] + return [ + spec for spec in new_manifest['specifications'] + if normpath(spec['path']) == old_spec['path'] + ][0] def integrate_spec_info(old_spec, new_spec): - fields = ['title', 'description', 'source', 'authors', 'tags'] + fields = ['title', 'description', 'source', 'tags'] for field in fields: new_spec[field] = old_spec[field] + new_spec['authors'] = sorted(old_spec['authors']) def find_corresponding_module(old_module, new_spec): return [ diff --git a/manifest.json b/manifest.json index 1d458dec..962972a2 100644 --- a/manifest.json +++ b/manifest.json @@ -41,7 +41,9 @@ "authors": [ "Leslie Lamport" ], - "tags": ["beginner"], + "tags": [ + "beginner" + ], "modules": [ { "path": "specifications/CarTalkPuzzle/CarTalkPuzzle.tla", @@ -164,7 +166,9 @@ "authors": [ "Andrew Helwer" ], - "tags": ["beginner"], + "tags": [ + "beginner" + ], "modules": [ { "path": "specifications/CoffeeCan/CoffeeCan.tla", @@ -211,7 +215,9 @@ "authors": [ "Leslie Lamport" ], - "tags": ["beginner"], + "tags": [ + "beginner" + ], "modules": [ { "path": "specifications/DieHard/DieHard.tla", @@ -260,7 +266,9 @@ "authors": [ "Jeff Hemphill" ], - "tags": ["beginner"], + "tags": [ + "beginner" + ], "modules": [ { "path": "specifications/DiningPhilosophers/DiningPhilosophers.tla", @@ -291,7 +299,9 @@ "authors": [ "Isaac DeFrain" ], - "tags": ["beginner"], + "tags": [ + "beginner" + ], "modules": [ { "path": "specifications/EinsteinRiddle/Einstein.tla", @@ -341,7 +351,11 @@ "modules": [ { "path": "specifications/Huang/Huang.tla", - "communityDependencies": [], + "communityDependencies": [ + "DyadicRationals", + "Functions", + "SequencesExt" + ], "tlaLanguageVersion": 2, "features": [], "models": [ @@ -350,9 +364,9 @@ "runtime": "unknown", "size": "unknown", "features": [ - "state constraint", + "alias", "liveness", - "alias" + "state constraint" ], "result": "unknown" } @@ -418,8 +432,8 @@ "description": "A method for simulating a fair 6-sided die using only coin flips", "source": "https://old.reddit.com/r/tlaplus/comments/j06ohw/how_do_you_reason_about_a_probabilistic/g6owlxy/", "authors": [ - "Ron Pressler", - "Markus Kuppe" + "Markus Kuppe", + "Ron Pressler" ], "tags": [], "modules": [ @@ -442,10 +456,8 @@ { "path": "specifications/KnuthYao/SimKnuthYao.tla", "communityDependencies": [ - "DyadicRationals", - "Functions", "CSV", - "TLCExt", + "Functions", "IOUtils", "Statistics" ], @@ -605,7 +617,9 @@ "authors": [ "Leslie Lamport" ], - "tags": ["beginner"], + "tags": [ + "beginner" + ], "modules": [ { "path": "specifications/MissionariesAndCannibals/MissionariesAndCannibals.tla", @@ -673,8 +687,12 @@ "title": "The N-Queens Puzzle", "description": "Place N queens on an NxN chess board such that no two queens threaten each other", "source": "", - "authors": ["Stephan Merz"], - "tags": ["beginner"], + "authors": [ + "Stephan Merz" + ], + "tags": [ + "beginner" + ], "modules": [ { "path": "specifications/N-Queens/Queens.tla", @@ -792,7 +810,9 @@ "title": "The Paxos Protocol", "description": "A protocol for error-tolerant consensus", "source": "", - "authors": ["Leslie Lamport"], + "authors": [ + "Leslie Lamport" + ], "tags": [], "modules": [ { @@ -878,7 +898,9 @@ "title": "How to Win a Turing Award", "description": "Exercises from the lecture The Paxos Algorithm - or How to Win a Turing Award", "source": "https://www.youtube.com/watch?v=tw3gsBms-f8", - "authors": ["Leslie Lamport"], + "authors": [ + "Leslie Lamport" + ], "tags": [], "modules": [ { @@ -913,8 +935,12 @@ "title": "The Prisoners & Switches Puzzle", "description": "Given a room containing two switches prisoners enter one by one, they must develop a strategy to free themselves", "source": "", - "authors": ["Leslie Lamport"], - "tags": ["beginner"], + "authors": [ + "Leslie Lamport" + ], + "tags": [ + "beginner" + ], "modules": [ { "path": "specifications/Prisoners/MCPrisoners.tla", @@ -947,7 +973,9 @@ "title": "The Readers-Writers Problem", "description": "Controlling concurrent access to a resource", "source": "", - "authors": ["Isaac DeFrain"], + "authors": [ + "Isaac DeFrain" + ], "tags": [], "modules": [ { @@ -981,7 +1009,9 @@ "title": "Single-Lane Bridge Problem", "description": "Controlling cars moving over a single-lange bridge in opposite directions", "source": "", - "authors": [], + "authors": [ + "Younes Aka" + ], "tags": [], "modules": [ { @@ -1015,8 +1045,12 @@ "title": "Sliding Block Puzzle", "description": "A spec of the Klotski sliding block puzzle", "source": "", - "authors": ["Mariusz Ryndzionek"], - "tags": ["beginner"], + "authors": [ + "Mariusz Ryndzionek" + ], + "tags": [ + "beginner" + ], "modules": [ { "path": "specifications/SlidingPuzzles/SlidingPuzzles.tla", @@ -1075,7 +1109,9 @@ "title": "Span Tree Exercise", "description": "Simplified algorithm from the Lamport paper *An Assertional Correctness Proof of a Distributed Program*", "source": "", - "authors": ["Leslie Lamport"], + "authors": [ + "Leslie Lamport" + ], "tags": [], "modules": [ { @@ -1106,7 +1142,9 @@ "title": "Specs from Specifying Systems", "description": "All specs seen in the textbook Specifying Systems by Leslie Lamport", "source": "http://lamport.azurewebsites.net/tla/book.html", - "authors": ["Leslie Lamport"], + "authors": [ + "Leslie Lamport" + ], "tags": [], "modules": [ { @@ -1155,8 +1193,8 @@ "runtime": "unknown", "size": "unknown", "features": [ - "state constraint", - "liveness" + "liveness", + "state constraint" ], "result": "unknown" } @@ -1173,8 +1211,8 @@ "runtime": "unknown", "size": "unknown", "features": [ - "state constraint", - "liveness" + "liveness", + "state constraint" ], "result": "unknown" } @@ -1765,8 +1803,8 @@ "runtime": "unknown", "size": "unknown", "features": [ - "state constraint", - "liveness" + "liveness", + "state constraint" ], "result": "unknown" } @@ -1786,7 +1824,9 @@ "title": "Stone Scale Puzzle", "description": "Alternative implementation of the Car Talk Puzzle", "source": "", - "authors": ["Leslie Lamport"], + "authors": [ + "Leslie Lamport" + ], "tags": [], "modules": [ { @@ -1803,7 +1843,9 @@ "title": "The TLC Safety Checking Algorithm", "description": "Spec of the safety checking algorithm used by the TLC model-checker", "source": "", - "authors": ["Markus Kuppe"], + "authors": [ + "Markus Kuppe" + ], "tags": [], "modules": [ { @@ -1839,7 +1881,9 @@ "title": "Teaching Concurrency", "description": "Simple problem useful for teaching and learning about concurrency", "source": "http://lamport.azurewebsites.net/pubs/teaching-concurrency.pdf", - "authors": [], + "authors": [ + "Leslie Lamport" + ], "tags": [], "modules": [ { @@ -1869,7 +1913,9 @@ "title": "Transitive Closure", "description": "Spec defining the transitive closure of a relation", "source": "", - "authors": [], + "authors": [ + "Stephan Merz" + ], "tags": [], "modules": [ { @@ -1933,9 +1979,9 @@ "description": "Spec of the protocol from paper *Asynchronous Consensus and Broadcast Protocols* (1985)", "source": "", "authors": [ - "Thanh Hai Tran", "Igor Konnov", - "Josef Widder" + "Josef Widder", + "Thanh Hai Tran" ], "tags": [], "modules": [ @@ -1953,7 +1999,9 @@ "title": "Resource Allocator", "description": "Specification of a resource allocator", "source": "", - "authors": ["Stephan Merz"], + "authors": [ + "Stephan Merz" + ], "tags": [], "modules": [ { @@ -2032,9 +2080,9 @@ "description": "Algorithm from paper *Simulating authenticated broadcasts to derive simple fault-tolerant algorithms* (1987)", "source": "", "authors": [ - "Thanh Hai Tran", "Igor Konnov", - "Josef Widder" + "Josef Widder", + "Thanh Hai Tran" ], "tags": [], "modules": [ @@ -2055,9 +2103,9 @@ "description": "Algorithm from paper *Unreliable failure detectors for reliable distributed systems* (1996)", "source": "", "authors": [ - "Thanh Hai Tran", "Igor Konnov", - "Josev Widder" + "Josev Widder", + "Thanh Hai Tran" ], "tags": [], "modules": [ @@ -2076,9 +2124,9 @@ "description": "Algorithm from paper *Bosco: One-step byzantine asynchronous consensus* (2008)", "source": "", "authors": [ - "Thanh Hai Tran", "Igor Konnov", - "Josev Widder" + "Josev Widder", + "Thanh Hai Tran" ], "tags": [], "modules": [ @@ -2097,9 +2145,9 @@ "description": "Algorithm from paper *Consensus in one communication step* (2001)", "source": "", "authors": [ - "Thanh Hai Tran", "Igor Konnov", - "Josev Widder" + "Josev Widder", + "Thanh Hai Tran" ], "tags": [], "modules": [ @@ -2118,9 +2166,9 @@ "description": "Algorithm from paper *Evaluating the condition-based approach to solve consensus* (2003)", "source": "", "authors": [ - "Thanh Hai Tran", "Igor Konnov", - "Josev Widder" + "Josev Widder", + "Thanh Hai Tran" ], "tags": [], "modules": [ @@ -2139,9 +2187,9 @@ "description": "Algorithm from paper *One-step Consensus with Zero-Degradation* (2006)", "source": "", "authors": [ - "Thanh Hai Tran", "Igor Konnov", - "Josev Widder" + "Josev Widder", + "Thanh Hai Tran" ], "tags": [], "modules": [ @@ -2159,7 +2207,9 @@ "title": "Chang-Roberts Algorithm for Leader Election in a Ring", "description": "Algorithm from paper *An improved algorithm for decentralized extrema-finding in circular configurations of processes* (1979)", "source": "", - "authors": ["Stephan Merz"], + "authors": [ + "Stephan Merz" + ], "tags": [], "modules": [ { @@ -2179,9 +2229,9 @@ "description": "Algorithm from paper *Unreliable failure detectors for reliable distributed systems* (1996)", "source": "", "authors": [ - "Thanh Hai Tran", "Igor Konnov", - "Josev Widder" + "Josev Widder", + "Thanh Hai Tran" ], "tags": [], "modules": [ @@ -2213,7 +2263,9 @@ "title": "Dijkstra's Mutual Exclusion Algorithm", "description": "Algorithm from paper *Solution of a Problem in Concurrent Programming Control* (1965)", "source": "", - "authors": ["Leslie Lamport"], + "authors": [ + "Leslie Lamport" + ], "tags": [], "modules": [ { @@ -2283,8 +2335,8 @@ "description": "A formalization of the SWMR-Shared-Memory Disk Paxos", "source": "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/nano-o/MultiPaxos/blob/master/DiskPaxos.tla", "authors": [ - "Leslie Lamport", - "Giuliano Losa" + "Giuliano Losa", + "Leslie Lamport" ], "tags": [], "modules": [ @@ -2316,7 +2368,9 @@ "title": "The Echo Algorithm", "description": "Algorithm for constructing a spanning tree in an undirected graph", "source": "", - "authors": ["Stephan Merz"], + "authors": [ + "Stephan Merz" + ], "tags": [], "modules": [ { @@ -2358,14 +2412,17 @@ "description": "Dijkstra's classical stabilizing token ring algorithm: EWD426", "source": "", "authors": [ - "Murat Demirbas", - "Markus Kuppe" + "Markus Kuppe", + "Murat Demirbas" ], "tags": [], "modules": [ { "path": "specifications/ewd426/SimTokenRing.tla", - "communityDependencies": [], + "communityDependencies": [ + "CSV", + "IOUtils" + ], "tlaLanguageVersion": 2, "features": [], "models": [ @@ -2414,7 +2471,9 @@ "modules": [ { "path": "specifications/ewd687a/EWD687a.tla", - "communityDependencies": [], + "communityDependencies": [ + "Graphs" + ], "tlaLanguageVersion": 2, "features": [], "models": [] @@ -2430,7 +2489,10 @@ }, { "path": "specifications/ewd687a/EWD687a_anim.tla", - "communityDependencies": [], + "communityDependencies": [ + "IOUtils", + "SVG" + ], "tlaLanguageVersion": 2, "features": [], "models": [ @@ -2457,8 +2519,8 @@ "runtime": "unknown", "size": "unknown", "features": [ - "state constraint", - "liveness" + "liveness", + "state constraint" ], "result": "unknown" } @@ -2471,7 +2533,9 @@ "title": "ewd840", "description": "Termination Detection in a Ring", "source": "Dijkstra's termination detection algorithm for ring topologies", - "authors": ["Stephan Merz"], + "authors": [ + "Stephan Merz" + ], "tags": [], "modules": [ { @@ -2491,7 +2555,9 @@ }, { "path": "specifications/ewd840/EWD840_anim.tla", - "communityDependencies": [], + "communityDependencies": [ + "SVG" + ], "tlaLanguageVersion": 2, "features": [], "models": [ @@ -2599,8 +2665,8 @@ "runtime": "unknown", "size": "unknown", "features": [ - "state constraint", - "liveness" + "liveness", + "state constraint" ], "result": "unknown" } @@ -2608,7 +2674,10 @@ }, { "path": "specifications/ewd998/EWD998.tla", - "communityDependencies": [], + "communityDependencies": [ + "Functions", + "SequencesExt" + ], "tlaLanguageVersion": 2, "features": [], "models": [ @@ -2634,8 +2703,8 @@ "runtime": "unknown", "size": "unknown", "features": [ - "state constraint", - "liveness" + "liveness", + "state constraint" ], "result": "unknown" } @@ -2652,9 +2721,9 @@ "runtime": "unknown", "size": "unknown", "features": [ - "view", + "liveness", "state constraint", - "liveness" + "view" ], "result": "unknown" } @@ -2662,7 +2731,9 @@ }, { "path": "specifications/ewd998/EWD998ChanID_export.tla", - "communityDependencies": [], + "communityDependencies": [ + "IOUtils" + ], "tlaLanguageVersion": 2, "features": [], "models": [ @@ -2694,28 +2765,40 @@ }, { "path": "specifications/ewd998/EWD998Chan_opts.tla", - "communityDependencies": [], + "communityDependencies": [ + "CSV", + "IOUtils" + ], "tlaLanguageVersion": 2, "features": [], "models": [] }, { "path": "specifications/ewd998/EWD998_anim.tla", - "communityDependencies": [], + "communityDependencies": [ + "IOUtils", + "SVG" + ], "tlaLanguageVersion": 2, "features": [], "models": [] }, { "path": "specifications/ewd998/EWD998_opts.tla", - "communityDependencies": [], + "communityDependencies": [ + "CSV", + "IOUtils" + ], "tlaLanguageVersion": 2, "features": [], "models": [] }, { "path": "specifications/ewd998/EWD998_optsSC.tla", - "communityDependencies": [], + "communityDependencies": [ + "CSV", + "IOUtils" + ], "tlaLanguageVersion": 2, "features": [], "models": [] @@ -2731,7 +2814,10 @@ }, { "path": "specifications/ewd998/SmokeEWD998.tla", - "communityDependencies": [], + "communityDependencies": [ + "CSV", + "IOUtils" + ], "tlaLanguageVersion": 2, "features": [], "models": [ @@ -2740,8 +2826,8 @@ "runtime": "unknown", "size": "unknown", "features": [ - "state constraint", - "liveness" + "liveness", + "state constraint" ], "result": "unknown" } @@ -2749,7 +2835,10 @@ }, { "path": "specifications/ewd998/SmokeEWD998_SC.tla", - "communityDependencies": [], + "communityDependencies": [ + "CSV", + "IOUtils" + ], "tlaLanguageVersion": 2, "features": [], "models": [ @@ -2764,7 +2853,10 @@ }, { "path": "specifications/ewd998/Utils.tla", - "communityDependencies": [], + "communityDependencies": [ + "Functions", + "SequencesExt" + ], "tlaLanguageVersion": 2, "features": [], "models": [] @@ -2776,7 +2868,9 @@ "title": "PCR Testing for Snippets of DNA", "description": "Specification of a PCR test process", "source": "", - "authors": ["Martin Harrison"], + "authors": [ + "Martin Harrison" + ], "tags": [], "modules": [ { @@ -2807,7 +2901,9 @@ "title": "Distributed Mutual Exclusion", "description": "Specification of Lamport's distributed mutual exclusion algorithm", "source": "", - "authors": ["Stephan Merz"], + "authors": [ + "Stephan Merz" + ], "tags": [], "modules": [ { @@ -2871,9 +2967,9 @@ "description": "Algorithm from paper *A case study of agreement problems in distributed systems: non-blocking atomic commitment* (1997)", "source": "", "authors": [ - "Thanh Hai Tran", "Igor Konnov", - "Josef Widder" + "Josef Widder", + "Thanh Hai Tran" ], "tags": [], "modules": [ @@ -2892,9 +2988,9 @@ "description": "Algorithm from paper *On the hardness of failure-sensitive agreement problems* (2001)", "source": "", "authors": [ - "Thanh Hai Tran", "Igor Konnov", - "Josef Widder" + "Josef Widder", + "Thanh Hai Tran" ], "tags": [], "modules": [ @@ -2913,9 +3009,9 @@ "description": "A spanning tree broadcast algorithm", "source": "", "authors": [ - "Thanh Hai Tran", "Igor Konnov", - "Josef Widder" + "Josef Widder", + "Thanh Hai Tran" ], "tags": [], "modules": [ @@ -2933,7 +3029,9 @@ "title": "Proof x+x is Even", "description": "Two proofs that x+x is even for every natural number x", "source": "", - "authors": ["Stephan Merz"], + "authors": [ + "Stephan Merz" + ], "tags": [], "modules": [ { @@ -2965,7 +3063,9 @@ "Alexander Niederbühl", "Markus Kuppe" ], - "tags": ["beginner"], + "tags": [ + "beginner" + ], "modules": [ { "path": "specifications/tower_of_hanoi/Bits.tla", @@ -3055,4 +3155,3 @@ } ] } - From 398ed4594bcb8c1ed18b7e7f6ba8500f3281f780 Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Thu, 26 Jan 2023 11:35:52 -0500 Subject: [PATCH 15/70] Wrote documentation for python scripts Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .../scripts/check_manifest_features.py | 59 ++++++++++++++++--- .../workflows/scripts/check_manifest_files.py | 11 ++-- .../scripts/check_manifest_schema.py | 7 ++- .../workflows/scripts/generate_manifest.py | 23 +++++--- 4 files changed, 80 insertions(+), 20 deletions(-) diff --git a/.github/workflows/scripts/check_manifest_features.py b/.github/workflows/scripts/check_manifest_features.py index 3f2aca3a..a1e275b7 100644 --- a/.github/workflows/scripts/check_manifest_features.py +++ b/.github/workflows/scripts/check_manifest_features.py @@ -1,8 +1,18 @@ +""" +This script performs whatever validations are possible on the metadata in +the manifest.json file. Prominent checks include: + * .tla files containing pluscal or proofs are marked as such + * .tla files importing community modules have those modules listed + * .cfg files with certain features are marked as such + * Human-written fields are not empty +""" + import glob import json from os.path import basename, dirname, splitext from tree_sitter import Language, Parser +# Builds the tree-sitter-tlaplus grammar and constructs the parser Language.build_library( 'build/tree-sitter-languages.so', ['tree-sitter-tlaplus'] @@ -12,25 +22,44 @@ parser = Parser() parser.set_language(TLAPLUS_LANGUAGE) -feature_query = TLAPLUS_LANGUAGE.query( - '(pcal_algorithm_start) @pluscal' - + '[(terminal_proof) (non_terminal_proof)] @proof' -) - def parse_module(path): + """ + Parses a .tla file; returns the parse tree along with whether a parse + error was detected. + """ module_text = None with open(path, 'rb') as module_file: module_text = module_file.read() tree = parser.parse(module_text) return (tree, module_text, tree.root_node.has_error) +def get_module_names_in_dir(dir): + """ + Gets the module names of all .tla files in the given directory. + """ + return set([splitext(basename(path))[0] for path in glob.glob(f'{dir}/*.tla')]) + +# This query looks for pluscal and proof constructs +# It can be extended to look for other things if desired +feature_query = TLAPLUS_LANGUAGE.query( + '(pcal_algorithm_start) @pluscal' + + '[(terminal_proof) (non_terminal_proof)] @proof' +) + def get_tree_features(tree): + """ + Returns any notable features in the parse tree, such as pluscal or proofs + """ return set([name for _, name in feature_query.captures(tree.root_node)]) def get_module_features(path): + """ + Gets notable features for the .tla file at the given path + """ tree, _, _ = parse_module(path) return get_tree_features(tree) +# Keywords mapping to features for models model_features = { 'PROPERTY': 'liveness', 'PROPERTIES': 'liveness', @@ -43,6 +72,7 @@ def get_module_features(path): def get_model_features(path): """ + Finds features present in the given .cfg model file. This will be a best-effort text search until a tree-sitter grammar is created for .cfg files. """ @@ -56,15 +86,19 @@ def get_model_features(path): features.append(model_features[tokens[0]]) return set(features) +# Query finding all module imports in a .tla file import_query = TLAPLUS_LANGUAGE.query( '(extends (identifier_ref) @extends)' + '(instance (identifier_ref) @instance)' ) +# Query finding all defined module names in a .tla file +# Especially useful for finding nested module names module_name_query = TLAPLUS_LANGUAGE.query( '(module name: (identifier) @module_name)' ) +# All the standard modules available when using TLC tlc_modules = { 'Bags', 'FiniteSets', @@ -80,6 +114,7 @@ def get_model_features(path): 'Toolbox' } +# All the standard modules available when using TLAPS tlaps_modules = { 'BagsTheorems', 'FiniteSetTheorems', @@ -91,6 +126,8 @@ def get_model_features(path): 'WellFoundedInduction' } +# Modules overloaded by TLAPS; some of these are ordinarily imported as +# community modules. tlaps_module_overloads = { 'Bags', 'FiniteSets', @@ -99,10 +136,12 @@ def get_model_features(path): 'SequencesExt' } -def get_module_names_in_dir(dir): - return set([splitext(basename(path))[0] for path in glob.glob(f'{dir}/*.tla')]) - def get_community_imports(tree, text, dir, has_proof): + """ + Gets all modules imported by a given .tla file that are not standard + modules or modules in the same file or directory. Community module + imports are what's left. + """ imports = set( [ text[node.start_byte:node.end_byte].decode('utf-8') @@ -125,6 +164,9 @@ def get_community_imports(tree, text, dir, has_proof): return imports - tlaps_module_overloads if has_proof else imports def get_community_module_imports(path): + """ + Gets all community modules imported by the .tla file at the given path. + """ tree, text, _ = parse_module(path) dir = dirname(path) has_proof = 'proof' in get_tree_features(tree) @@ -135,6 +177,7 @@ def get_community_module_imports(path): with open('manifest.json', 'rt') as manifest_file: manifest = json.load(manifest_file) + # Validates every field of the manifest that can be validated. success = True for spec in manifest['specifications']: if spec['title'] == '': diff --git a/.github/workflows/scripts/check_manifest_files.py b/.github/workflows/scripts/check_manifest_files.py index 0c84d4d4..35ff8784 100644 --- a/.github/workflows/scripts/check_manifest_files.py +++ b/.github/workflows/scripts/check_manifest_files.py @@ -1,5 +1,8 @@ -# Checks to ensure all files in manifest.json exist, and that all .tla and -# .cfg files in repo are recorded in manifest.json +""" +Checks to ensure all files in manifest.json exist, that all .tla and .cfg +files in repo are recorded in manifest.json, and that no files are present +twice in the manifest. +""" from collections import Counter import json @@ -14,13 +17,13 @@ modules = [module for module_list in module_lists for module in module_list] model_lists = [module["models"] for module in modules] -# All paths in the manifest +# Get all .tla and .cfg paths from the manifest tla_mf_paths_cnt = Counter([normpath(module["path"]) for module in modules]) tla_mf_paths = set(tla_mf_paths_cnt) cfg_mf_paths_cnt = Counter([normpath(model["path"]) for model_list in model_lists for model in model_list]) cfg_mf_paths = set(cfg_mf_paths_cnt) -# All paths on the filesystem +# Get paths of all .tla and .cfg files in the specifications dir tla_fs_paths = set([normpath(path) for path in glob.glob(f"./specifications/**/*.tla", recursive=True)]) cfg_fs_paths = set([normpath(path) for path in glob.glob(f"./specifications/**/*.cfg", recursive=True)]) diff --git a/.github/workflows/scripts/check_manifest_schema.py b/.github/workflows/scripts/check_manifest_schema.py index fea57517..b6e9f664 100644 --- a/.github/workflows/scripts/check_manifest_schema.py +++ b/.github/workflows/scripts/check_manifest_schema.py @@ -1,4 +1,9 @@ -# Checks to ensure manifest.json is valid according to schema +""" +Checks to ensure manifest.json is valid according to schema; this can also +be done manually at https://www.jsonschemavalidator.net/ +Learn about the JSON schema format at +https://json-schema.org/understanding-json-schema/ +""" import json from jsonschema import validate diff --git a/.github/workflows/scripts/generate_manifest.py b/.github/workflows/scripts/generate_manifest.py index ba88c564..fc7e865e 100644 --- a/.github/workflows/scripts/generate_manifest.py +++ b/.github/workflows/scripts/generate_manifest.py @@ -1,4 +1,11 @@ -# Generates a best-effort manifest.json +""" +Generates a best-effort manifest.json file. This is done by scanning all +.tla and .cfg files in the specifications dir then attempting to sort them +into a spec/module/model hierarchy. Files are parsed to check for features +and imports. Human-written fields (title/description/source/authors for +specs, runtime/size/result for models) are either taken from any existing +manifest.json file or set as blank/unknown as appropriate. +""" from check_manifest_features import get_community_module_imports, get_module_features, get_module_names_in_dir, get_model_features import json @@ -6,13 +13,15 @@ from os.path import basename, dirname, join, normpath, splitext import glob -# Generate new manifest drawing info from files in specifications dir - def get_tla_files(dir): + """ + Gets paths of all .tla files in the given directory. + """ return [normpath(path) for path in glob.glob(f'{dir.path}/**/*.tla', recursive=True)] def get_cfg_files(tla_path): - """Assume a .cfg file in the same directory as the .tla file and with the + """ + Assume a .cfg file in the same directory as the .tla file and with the same name is a model of that .tla file; also assume this of any .cfg files where the .tla file name is only a prefix of the .cfg file name, unless there are other .tla file names in the directory that exactly @@ -26,6 +35,7 @@ def get_cfg_files(tla_path): if splitext(basename(path))[0] not in other_module_names ] +# Generate new base manifest.json from files in specifications dir new_manifest = { 'specifications': [ { @@ -61,7 +71,7 @@ def get_cfg_files(tla_path): ] } -# Integrate human-readable info from existing manifest +# Integrate human-written info from existing manifest.json def find_corresponding_spec(old_spec, new_manifest): return [ @@ -111,8 +121,7 @@ def integrate_model_info(old_model, new_model): new_model = find_corresponding_model(old_model, new_module) integrate_model_info(old_model, new_model) -# Writes generated manifest to file - +# Write generated manifest to file with open('manifest.json', 'w') as new_manifest_file: json.dump(new_manifest, new_manifest_file, indent=2, ensure_ascii=False) From d29e7fe875cc750d5c533b7f94b8a11b2acf11a5 Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Thu, 26 Jan 2023 15:35:54 -0500 Subject: [PATCH 16/70] Parse all modules with SANY Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> Fixed parse error Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> Fixed sany parse error detection Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> Reverted SumSequence.tla to normal Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> Parse all modules with SANY Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/workflows/CI.yml | 15 +++++ .github/workflows/scripts/parse_modules.py | 61 +++++++++++++++++++ .../RealTime/RTWriteThroughCache.tla | 2 +- specifications/glowingRaccoon/product.tla | 3 - 4 files changed, 77 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/scripts/parse_modules.py diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 6ff31767..26a36269 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -11,6 +11,8 @@ jobs: runs-on: ubuntu-latest env: TSTLA_VERSION: 1.0.2 + TLAPS_VERSION: 202210041448 + COMMUNITY_MODULES_VERSION: 202211012231 SCRIPT_DIR: ./.github/workflows/scripts steps: - name: Clone repo @@ -32,4 +34,17 @@ jobs: mv tree-sitter-tlaplus-$TSTLA_VERSION tree-sitter-tlaplus - name: Check manifest feature flags run: python $SCRIPT_DIR/check_manifest_features.py + - name: Get nightly TLA⁺ toolset, TLAPS, and community modules + run: | + wget https://nightly.tlapl.us/dist/tla2tools.jar + wget https://github.com/tlaplus/CommunityModules/archive/refs/tags/$COMMUNITY_MODULES_VERSION.tar.gz + tar -xf $COMMUNITY_MODULES_VERSION.tar.gz + rm $COMMUNITY_MODULES_VERSION.tar.gz + mv CommunityModules-$COMMUNITY_MODULES_VERSION CommunityModules + wget https://github.com/tlaplus/tlapm/archive/refs/tags/$TLAPS_VERSION.tar.gz + tar -xf $TLAPS_VERSION.tar.gz + rm $TLAPS_VERSION.tar.gz + mv tlapm-$TLAPS_VERSION tlapm + - name: Parse all modules + run: python $SCRIPT_DIR/parse_modules.py diff --git a/.github/workflows/scripts/parse_modules.py b/.github/workflows/scripts/parse_modules.py new file mode 100644 index 00000000..1cb934f5 --- /dev/null +++ b/.github/workflows/scripts/parse_modules.py @@ -0,0 +1,61 @@ +""" +Parse all modules in the manifest with SANY. +""" + +from concurrent.futures import ThreadPoolExecutor +import logging +import json +from os import cpu_count +from os.path import dirname +import subprocess + +tlaps_modules = 'tlapm/library' +community_modules = 'CommunityModules/modules' +logging.basicConfig(level=logging.INFO) + +def parse_module(module_tuple): + """ + Parse the given module using SANY. + """ + path, using_proofs = module_tuple + logging.info(path) + # If using proofs, TLAPS modules override community modules + search_paths = ':'.join( + [dirname(path)] + + ([tlaps_modules] if using_proofs else []) + + [community_modules] + ) + sany = subprocess.run([ + 'java', + f'-DTLA-Library={search_paths}', + '-cp', 'tla2tools.jar', + 'tla2sany.SANY', path, + ], capture_output=True) + sany_output = sany.stdout.decode('utf-8') + if sany.returncode != 0 or 'Error' in sany_output or 'error' in sany_output: + logging.error(sany_output) + return False + return True + +manifest = None +with open('manifest.json', 'rt') as manifest_file: + manifest = json.load(manifest_file) + +# Skip these specs and modules as they do not currently parse +skip_specs = ['specifications/ewd998'] +skip_modules = ['specifications/LoopInvariance/SumSequence.tla'] + +# List of all modules to parse and whether they should use TLAPS imports +modules = [ + (module['path'], any(['proof' in module['features'] for module in spec['modules']])) + for spec in manifest['specifications'] if spec['path'] not in skip_specs + for module in spec['modules'] if module['path'] not in skip_modules +] + +# Parse specs in parallel +thread_count = cpu_count() +logging.info(f'Parsing using {thread_count} threads') +with ThreadPoolExecutor(thread_count) as executor: + results = executor.map(parse_module, modules) + exit(0 if all(results) else 1) + diff --git a/specifications/SpecifyingSystems/RealTime/RTWriteThroughCache.tla b/specifications/SpecifyingSystems/RealTime/RTWriteThroughCache.tla index 41af4961..9d86170f 100644 --- a/specifications/SpecifyingSystems/RealTime/RTWriteThroughCache.tla +++ b/specifications/SpecifyingSystems/RealTime/RTWriteThroughCache.tla @@ -47,5 +47,5 @@ RTSpec == /\ RTInit /\ [][RTNext]_vars /\ RTnow(vars) ----------------------------------------------------------------------------- RTM == INSTANCE RTMemory -THEOREM RTSpec => RTM!Spec +THEOREM RTSpec => RTM!RTSpec ============================================================================= diff --git a/specifications/glowingRaccoon/product.tla b/specifications/glowingRaccoon/product.tla index c9e2d18b..3752c572 100644 --- a/specifications/glowingRaccoon/product.tla +++ b/specifications/glowingRaccoon/product.tla @@ -175,9 +175,6 @@ Spec == /\ Init TypeOK == /\ tee \in {"Warm", "Hot", "TooHot"} /\ primer \in Nat - /\ dna \in Nat - /\ template \in Nat - /\ hybrid \in Nat /\ stage \in {"init","ready","annealed","extended","denatured"} /\ cycle \in Nat /\ longTemplate \in Nat From 8ca574ae798ce3c163fb28c487a9f01cd4728eed Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Fri, 27 Jan 2023 09:08:27 -0500 Subject: [PATCH 17/70] Basic TLC script Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/workflows/CI.yml | 1 + .github/workflows/scripts/check_models.py | 43 +++++++++++++++++++++++ .gitignore | 8 +++++ 3 files changed, 52 insertions(+) create mode 100644 .github/workflows/scripts/check_models.py diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 26a36269..a7518872 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -37,6 +37,7 @@ jobs: - name: Get nightly TLA⁺ toolset, TLAPS, and community modules run: | wget https://nightly.tlapl.us/dist/tla2tools.jar + wget https://github.com/tlaplus/CommunityModules/releases/latest/download/CommunityModules-deps.jar wget https://github.com/tlaplus/CommunityModules/archive/refs/tags/$COMMUNITY_MODULES_VERSION.tar.gz tar -xf $COMMUNITY_MODULES_VERSION.tar.gz rm $COMMUNITY_MODULES_VERSION.tar.gz diff --git a/.github/workflows/scripts/check_models.py b/.github/workflows/scripts/check_models.py new file mode 100644 index 00000000..95354590 --- /dev/null +++ b/.github/workflows/scripts/check_models.py @@ -0,0 +1,43 @@ +""" +Check all models marked as size "small" in the manifest with TLC. Small +models should finish executing in less than ten seconds on the GitHub CI +machines. +""" + +import json +from os import cpu_count +from os.path import dirname +import subprocess + +manifest = None +with open('manifest.json', 'rt') as manifest_file: + manifest = json.load(manifest_file) + +small_models = [ + (module['path'], model['path'], model['result']) + for spec in manifest['specifications'] + for module in spec['modules'] + for model in module['models'] if model['size'] == 'small' +] + +for module_path, model_path, expected_result in small_models: + print(model_path) + tlc = subprocess.run([ + 'java', + '-Dtlc2.TLC.ide=Github', + '-Dutil.ExecutionStatisticsCollector.id=abcdef60f238424fa70d124d0c77ffff', + '-XX:+UseParallelGC', + '-cp', 'tla2tools.jar', + 'tlc2.TLC', + '-workers', str(cpu_count()), + '-lncheck', 'final', + #'-tool', + '-config', model_path, + module_path + ], capture_output=True) + tlc_output = tlc.stdout.decode('utf-8') + + print(tlc_output) + print(tlc.returncode) + + diff --git a/.gitignore b/.gitignore index db4fc2bc..6665df66 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,11 @@ __tlacache__ ## Ignore pycache __pycache__ +## Ignore directories used for local CI testing +CommunityModules/ +tlapm/ +tree-sitter-tlaplus/ + +# Ignore TTrace specs +*_TTrace_*.tla + From 53db7d439ef893b3637e241a8c61f7a877c8c839 Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Fri, 27 Jan 2023 09:24:36 -0500 Subject: [PATCH 18/70] Added SDP spec Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .../scripts/check_manifest_features.py | 0 .../scripts/check_manifest_files.py | 0 .../scripts/check_manifest_schema.py | 0 .../check_small_models.py} | 3 +- .../scripts/generate_manifest.py | 0 .../{workflows => }/scripts/parse_modules.py | 0 .../{workflows => }/scripts/requirements.txt | 0 .github/workflows/CI.yml | 6 +- manifest.json | 67 +++++++++++++++++++ 9 files changed, 72 insertions(+), 4 deletions(-) rename .github/{workflows => }/scripts/check_manifest_features.py (100%) rename .github/{workflows => }/scripts/check_manifest_files.py (100%) rename .github/{workflows => }/scripts/check_manifest_schema.py (100%) rename .github/{workflows/scripts/check_models.py => scripts/check_small_models.py} (96%) rename .github/{workflows => }/scripts/generate_manifest.py (100%) rename .github/{workflows => }/scripts/parse_modules.py (100%) rename .github/{workflows => }/scripts/requirements.txt (100%) diff --git a/.github/workflows/scripts/check_manifest_features.py b/.github/scripts/check_manifest_features.py similarity index 100% rename from .github/workflows/scripts/check_manifest_features.py rename to .github/scripts/check_manifest_features.py diff --git a/.github/workflows/scripts/check_manifest_files.py b/.github/scripts/check_manifest_files.py similarity index 100% rename from .github/workflows/scripts/check_manifest_files.py rename to .github/scripts/check_manifest_files.py diff --git a/.github/workflows/scripts/check_manifest_schema.py b/.github/scripts/check_manifest_schema.py similarity index 100% rename from .github/workflows/scripts/check_manifest_schema.py rename to .github/scripts/check_manifest_schema.py diff --git a/.github/workflows/scripts/check_models.py b/.github/scripts/check_small_models.py similarity index 96% rename from .github/workflows/scripts/check_models.py rename to .github/scripts/check_small_models.py index 95354590..8f3f2593 100644 --- a/.github/workflows/scripts/check_models.py +++ b/.github/scripts/check_small_models.py @@ -6,7 +6,6 @@ import json from os import cpu_count -from os.path import dirname import subprocess manifest = None @@ -31,7 +30,7 @@ 'tlc2.TLC', '-workers', str(cpu_count()), '-lncheck', 'final', - #'-tool', + '-tool', '-config', model_path, module_path ], capture_output=True) diff --git a/.github/workflows/scripts/generate_manifest.py b/.github/scripts/generate_manifest.py similarity index 100% rename from .github/workflows/scripts/generate_manifest.py rename to .github/scripts/generate_manifest.py diff --git a/.github/workflows/scripts/parse_modules.py b/.github/scripts/parse_modules.py similarity index 100% rename from .github/workflows/scripts/parse_modules.py rename to .github/scripts/parse_modules.py diff --git a/.github/workflows/scripts/requirements.txt b/.github/scripts/requirements.txt similarity index 100% rename from .github/workflows/scripts/requirements.txt rename to .github/scripts/requirements.txt diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index a7518872..22cb602f 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -13,7 +13,7 @@ jobs: TSTLA_VERSION: 1.0.2 TLAPS_VERSION: 202210041448 COMMUNITY_MODULES_VERSION: 202211012231 - SCRIPT_DIR: ./.github/workflows/scripts + SCRIPT_DIR: .github/scripts steps: - name: Clone repo uses: actions/checkout@v2 @@ -34,7 +34,7 @@ jobs: mv tree-sitter-tlaplus-$TSTLA_VERSION tree-sitter-tlaplus - name: Check manifest feature flags run: python $SCRIPT_DIR/check_manifest_features.py - - name: Get nightly TLA⁺ toolset, TLAPS, and community modules + - name: Get TLA⁺ toolset, TLAPS, and community modules run: | wget https://nightly.tlapl.us/dist/tla2tools.jar wget https://github.com/tlaplus/CommunityModules/releases/latest/download/CommunityModules-deps.jar @@ -48,4 +48,6 @@ jobs: mv tlapm-$TLAPS_VERSION tlapm - name: Parse all modules run: python $SCRIPT_DIR/parse_modules.py + - name: Check all small models + run: python $SCRIPT_DIR/check_small_models.py diff --git a/manifest.json b/manifest.json index 962972a2..0227d66b 100644 --- a/manifest.json +++ b/manifest.json @@ -1004,6 +1004,73 @@ } ] }, + { + "path": "specifications/SDP_Verification", + "title": "Software-Defined Perimeter", + "description": "Specifying and verifying SDP-protocol-based zero trust architecture", + "source": "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/10227694/SDP_Verification", + "authors": [ + "Luming Dong", + "Zhi Niu" + ], + "tags": [], + "modules": [ + { + "path": "specifications/SDP_Verification/SDP_Attack_New_Solution_Spec/MC.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/SDP_Verification/SDP_Attack_New_Solution_Spec/MC.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [ + "liveness" + ], + "result": "unknown" + } + ] + }, + { + "path": "specifications/SDP_Verification/SDP_Attack_New_Solution_Spec/SPA_Attack_New.tla", + "communityDependencies": [ + "Bitwise", + "Functions" + ], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SDP_Verification/SDP_Attack_Spec/MC.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [ + { + "path": "specifications/SDP_Verification/SDP_Attack_Spec/MC.cfg", + "runtime": "unknown", + "size": "unknown", + "features": [ + "liveness" + ], + "result": "unknown" + } + ] + }, + { + "path": "specifications/SDP_Verification/SDP_Attack_Spec/SPA_Attack.tla", + "communityDependencies": [ + "Bitwise", + "Functions" + ], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + } + ] + }, { "path": "specifications/SingleLaneBridge", "title": "Single-Lane Bridge Problem", From 505c7d7aa5ee43671d042e030bd276b31a43d9d6 Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Fri, 27 Jan 2023 09:36:01 -0500 Subject: [PATCH 19/70] SumSequence now parses Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/scripts/check_manifest_features.py | 3 ++- .github/scripts/parse_modules.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/scripts/check_manifest_features.py b/.github/scripts/check_manifest_features.py index a1e275b7..7e9dd15c 100644 --- a/.github/scripts/check_manifest_features.py +++ b/.github/scripts/check_manifest_features.py @@ -120,8 +120,9 @@ def get_model_features(path): 'FiniteSetTheorems', 'FunctionTheorems', 'NaturalsInduction', - 'SequenceTheorems', + 'SequencesExt', 'SequencesExtTheorems', + 'SequenceTheorems', 'TLAPS', 'WellFoundedInduction' } diff --git a/.github/scripts/parse_modules.py b/.github/scripts/parse_modules.py index 1cb934f5..573452a1 100644 --- a/.github/scripts/parse_modules.py +++ b/.github/scripts/parse_modules.py @@ -43,7 +43,7 @@ def parse_module(module_tuple): # Skip these specs and modules as they do not currently parse skip_specs = ['specifications/ewd998'] -skip_modules = ['specifications/LoopInvariance/SumSequence.tla'] +skip_modules = [] # List of all modules to parse and whether they should use TLAPS imports modules = [ From bab9bd3d39407041d422f586eb119f58a6881288 Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Fri, 27 Jan 2023 09:48:07 -0500 Subject: [PATCH 20/70] Tweaked small model sizes Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- manifest.json | 22 ++++++++++++++--- ...ssSmall.cfg => ElevatorLivenessMedium.cfg} | 0 .../MultiCarElevator/ElevatorSafetySmall.cfg | 12 ++++++++++ .../NanoBlockchain/MCNanoMedium.cfg | 24 +++++++++++++++++++ specifications/NanoBlockchain/MCNanoSmall.cfg | 2 +- specifications/SlushProtocol/SlushSmall.cfg | 2 +- 6 files changed, 57 insertions(+), 5 deletions(-) rename specifications/MultiCarElevator/{ElevatorLivenessSmall.cfg => ElevatorLivenessMedium.cfg} (100%) create mode 100644 specifications/MultiCarElevator/ElevatorSafetySmall.cfg create mode 100644 specifications/NanoBlockchain/MCNanoMedium.cfg diff --git a/manifest.json b/manifest.json index 0227d66b..06a2127c 100644 --- a/manifest.json +++ b/manifest.json @@ -656,9 +656,9 @@ "result": "success" }, { - "path": "specifications/MultiCarElevator/ElevatorLivenessSmall.cfg", - "runtime": "00:00:05", - "size": "small", + "path": "specifications/MultiCarElevator/ElevatorLivenessMedium.cfg", + "runtime": "00:00:30", + "size": "medium", "features": [ "liveness" ], @@ -677,6 +677,13 @@ "size": "medium", "features": [], "result": "success" + }, + { + "path": "specifications/MultiCarElevator/ElevatorSafetySmall.cfg", + "runtime": "00:00:10", + "size": "small", + "features": [], + "result": "success" } ] } @@ -785,6 +792,15 @@ ], "result": "success" }, + { + "path": "specifications/NanoBlockchain/MCNanoMedium.cfg", + "runtime": "00:00:30", + "size": "medium", + "features": [ + "view" + ], + "result": "success" + }, { "path": "specifications/NanoBlockchain/MCNanoSmall.cfg", "runtime": "00:00:05", diff --git a/specifications/MultiCarElevator/ElevatorLivenessSmall.cfg b/specifications/MultiCarElevator/ElevatorLivenessMedium.cfg similarity index 100% rename from specifications/MultiCarElevator/ElevatorLivenessSmall.cfg rename to specifications/MultiCarElevator/ElevatorLivenessMedium.cfg diff --git a/specifications/MultiCarElevator/ElevatorSafetySmall.cfg b/specifications/MultiCarElevator/ElevatorSafetySmall.cfg new file mode 100644 index 00000000..2a6dcaa7 --- /dev/null +++ b/specifications/MultiCarElevator/ElevatorSafetySmall.cfg @@ -0,0 +1,12 @@ +CONSTANTS + Person = {p1, p2} + Elevator = {e1, e2} + FloorCount = 2 + +SPECIFICATION + Spec + +INVARIANTS + TypeInvariant + SafetyInvariant + diff --git a/specifications/NanoBlockchain/MCNanoMedium.cfg b/specifications/NanoBlockchain/MCNanoMedium.cfg new file mode 100644 index 00000000..cd5dc8a0 --- /dev/null +++ b/specifications/NanoBlockchain/MCNanoMedium.cfg @@ -0,0 +1,24 @@ +CONSTANTS + CalculateHash <- CalculateHashImpl + Hash = {h1, h2, h3, h4} + NoHashVal = NoHashVal + PrivateKey = {prv1, prv2} + PublicKey = {pub1, pub2} + Node = {n1, n2} + GenesisBalance = 3 + NoBlockVal = NoBlockVal + +CONSTANTS + NoHash = [Nano]NoHashVal + NoBlock = [Nano]NoBlockVal + +VIEW + View + +SPECIFICATION + Spec + +INVARIANTS + TypeInvariant + SafetyInvariant + diff --git a/specifications/NanoBlockchain/MCNanoSmall.cfg b/specifications/NanoBlockchain/MCNanoSmall.cfg index cd5dc8a0..3aaef145 100644 --- a/specifications/NanoBlockchain/MCNanoSmall.cfg +++ b/specifications/NanoBlockchain/MCNanoSmall.cfg @@ -1,6 +1,6 @@ CONSTANTS CalculateHash <- CalculateHashImpl - Hash = {h1, h2, h3, h4} + Hash = {h1, h2, h3} NoHashVal = NoHashVal PrivateKey = {prv1, prv2} PublicKey = {pub1, pub2} diff --git a/specifications/SlushProtocol/SlushSmall.cfg b/specifications/SlushProtocol/SlushSmall.cfg index 004faa33..5bfa5422 100644 --- a/specifications/SlushProtocol/SlushSmall.cfg +++ b/specifications/SlushProtocol/SlushSmall.cfg @@ -3,7 +3,7 @@ CONSTANTS SlushLoopProcess = {l1, l2, l3} SlushQueryProcess = {q1, q2, q3} HostMapping = {{n1, l1, q1}, {n2, l2, q2}, {n3, l3, q3}} - SlushIterationCount = 2 + SlushIterationCount = 1 SampleSetSize = 2 PickFlipThreshold = 2 From 87cc0f4ade810117229453633d8c799f294992ab Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Fri, 27 Jan 2023 10:14:40 -0500 Subject: [PATCH 21/70] Fixed import logic Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/scripts/check_manifest_features.py | 1 - manifest.json | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/scripts/check_manifest_features.py b/.github/scripts/check_manifest_features.py index 7e9dd15c..0834d8c7 100644 --- a/.github/scripts/check_manifest_features.py +++ b/.github/scripts/check_manifest_features.py @@ -120,7 +120,6 @@ def get_model_features(path): 'FiniteSetTheorems', 'FunctionTheorems', 'NaturalsInduction', - 'SequencesExt', 'SequencesExtTheorems', 'SequenceTheorems', 'TLAPS', diff --git a/manifest.json b/manifest.json index 06a2127c..1fd73e1c 100644 --- a/manifest.json +++ b/manifest.json @@ -795,7 +795,7 @@ { "path": "specifications/NanoBlockchain/MCNanoMedium.cfg", "runtime": "00:00:30", - "size": "medium", + "size": "small", "features": [ "view" ], From 614eaf8c454b5a9fe8aa9eb92647a7431286d013 Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Fri, 27 Jan 2023 11:05:23 -0500 Subject: [PATCH 22/70] Added some more small models Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/workflows/CI.yml | 2 +- manifest.json | 76 +++++++++++-------- .../MissionariesAndCannibals.cfg | 11 +++ .../MissionariesAndCannibals.tla | 2 + .../QueensPluscal.toolbox/FourQueens/MC.cfg | 3 +- .../SlidingPuzzles/SlidingPuzzles.cfg | 5 ++ .../SlidingPuzzles/SlidingPuzzles.tla | 2 +- .../Hanoi.toolbox/Model_1/MC.cfg | 4 +- 8 files changed, 69 insertions(+), 36 deletions(-) create mode 100644 specifications/MissionariesAndCannibals/MissionariesAndCannibals.cfg create mode 100644 specifications/SlidingPuzzles/SlidingPuzzles.cfg diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 22cb602f..6276f626 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -48,6 +48,6 @@ jobs: mv tlapm-$TLAPS_VERSION tlapm - name: Parse all modules run: python $SCRIPT_DIR/parse_modules.py - - name: Check all small models + - name: Check small models run: python $SCRIPT_DIR/check_small_models.py diff --git a/manifest.json b/manifest.json index 1fd73e1c..2804927d 100644 --- a/manifest.json +++ b/manifest.json @@ -67,10 +67,10 @@ "models": [ { "path": "specifications/CarTalkPuzzle/CarTalkPuzzle.toolbox/Model_1/MC.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:01", + "size": "small", "features": [], - "result": "unknown" + "result": "success" } ] }, @@ -89,10 +89,10 @@ "models": [ { "path": "specifications/CarTalkPuzzle/CarTalkPuzzle.toolbox/Model_2/MC.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:01", + "size": "small", "features": [], - "result": "unknown" + "result": "success" } ] }, @@ -112,7 +112,7 @@ { "path": "specifications/CarTalkPuzzle/CarTalkPuzzle.toolbox/Model_3/MC.cfg", "runtime": "unknown", - "size": "unknown", + "size": "large", "features": [], "result": "unknown" } @@ -280,12 +280,12 @@ "models": [ { "path": "specifications/DiningPhilosophers/DiningPhilosophers.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:01", + "size": "small", "features": [ "liveness" ], - "result": "unknown" + "result": "success" } ] } @@ -299,9 +299,7 @@ "authors": [ "Isaac DeFrain" ], - "tags": [ - "beginner" - ], + "tags": [], "modules": [ { "path": "specifications/EinsteinRiddle/Einstein.tla", @@ -312,7 +310,7 @@ { "path": "specifications/EinsteinRiddle/Einstein.cfg", "runtime": "unknown", - "size": "unknown", + "size": "large", "features": [], "result": "safety failure" } @@ -626,7 +624,15 @@ "communityDependencies": [], "tlaLanguageVersion": 2, "features": [], - "models": [] + "models": [ + { + "path": "specifications/MissionariesAndCannibals/MissionariesAndCannibals.cfg", + "runtime": "00:00:01", + "size": "small", + "features": [], + "result": "safety failure" + } + ] } ] }, @@ -716,10 +722,10 @@ "models": [ { "path": "specifications/N-Queens/Queens.toolbox/FourQueens/MC.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:01", + "size": "small", "features": [], - "result": "unknown" + "result": "safety failure" } ] }, @@ -747,12 +753,12 @@ "models": [ { "path": "specifications/N-Queens/QueensPluscal.toolbox/FourQueens/MC.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:01", + "size": "small", "features": [ "liveness" ], - "result": "unknown" + "result": "safety failure" } ] }, @@ -795,7 +801,7 @@ { "path": "specifications/NanoBlockchain/MCNanoMedium.cfg", "runtime": "00:00:30", - "size": "small", + "size": "medium", "features": [ "view" ], @@ -973,12 +979,12 @@ "models": [ { "path": "specifications/Prisoners/Prisoners.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:01", + "size": "small", "features": [ "liveness" ], - "result": "unknown" + "result": "success" } ] } @@ -1131,16 +1137,22 @@ "authors": [ "Mariusz Ryndzionek" ], - "tags": [ - "beginner" - ], + "tags": [], "modules": [ { "path": "specifications/SlidingPuzzles/SlidingPuzzles.tla", "communityDependencies": [], "tlaLanguageVersion": 2, "features": [], - "models": [] + "models": [ + { + "path": "specifications/SlidingPuzzles/SlidingPuzzles.cfg", + "runtime": "00:00:01", + "size": "small", + "features": [], + "result": "safety failure" + } + ] } ] }, @@ -3186,10 +3198,10 @@ "models": [ { "path": "specifications/tower_of_hanoi/Hanoi.toolbox/Model_1/MC.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:01", + "size": "small", "features": [], - "result": "unknown" + "result": "safety failure" } ] }, diff --git a/specifications/MissionariesAndCannibals/MissionariesAndCannibals.cfg b/specifications/MissionariesAndCannibals/MissionariesAndCannibals.cfg new file mode 100644 index 00000000..aed7a6e3 --- /dev/null +++ b/specifications/MissionariesAndCannibals/MissionariesAndCannibals.cfg @@ -0,0 +1,11 @@ +CONSTANTS + Missionaries = {m1, m2, m3} + Cannibals = {c1, c2, c3} + +INIT Init +NEXT Next + +INVARIANTS + TypeOK + Solution + diff --git a/specifications/MissionariesAndCannibals/MissionariesAndCannibals.tla b/specifications/MissionariesAndCannibals/MissionariesAndCannibals.tla index 4faff7f6..5f3fbd8a 100644 --- a/specifications/MissionariesAndCannibals/MissionariesAndCannibals.tla +++ b/specifications/MissionariesAndCannibals/MissionariesAndCannibals.tla @@ -217,6 +217,8 @@ Next == \E S \in SUBSET who_is_on_bank[bank_of_boat] : (* This problem was proposed to me by Jay Misra, who then suggested *) (* improvements to my first version of the spec. *) (***************************************************************************) +Solution == who_is_on_bank["E"] /= {} + ============================================================================= \* Modification History \* Last modified Sat Dec 22 14:17:18 PST 2018 by lamport diff --git a/specifications/N-Queens/QueensPluscal.toolbox/FourQueens/MC.cfg b/specifications/N-Queens/QueensPluscal.toolbox/FourQueens/MC.cfg index d8e4aeae..fbc8ba12 100644 --- a/specifications/N-Queens/QueensPluscal.toolbox/FourQueens/MC.cfg +++ b/specifications/N-Queens/QueensPluscal.toolbox/FourQueens/MC.cfg @@ -11,4 +11,5 @@ inv_129269506136536000 \* PROPERTY definition PROPERTY prop_129269506137537000 -\* Generated at Sat Dec 18 18:57:41 CET 2010 \ No newline at end of file +\* Generated at Sat Dec 18 18:57:41 CET 2010 +INVARIANT NoSolutions diff --git a/specifications/SlidingPuzzles/SlidingPuzzles.cfg b/specifications/SlidingPuzzles/SlidingPuzzles.cfg new file mode 100644 index 00000000..9ff34234 --- /dev/null +++ b/specifications/SlidingPuzzles/SlidingPuzzles.cfg @@ -0,0 +1,5 @@ +INIT Init +NEXT Next +INVARIANTS + TypeOK + KlotskiGoal diff --git a/specifications/SlidingPuzzles/SlidingPuzzles.tla b/specifications/SlidingPuzzles/SlidingPuzzles.tla index 32372b3d..82b89599 100644 --- a/specifications/SlidingPuzzles/SlidingPuzzles.tla +++ b/specifications/SlidingPuzzles/SlidingPuzzles.tla @@ -13,7 +13,7 @@ Klotski == {{<<0, 0>>, <<0, 1>>}, {<<1, 2>>, <<2, 2>>},{<<3, 2>>, <<3, 3>>}, {<<1, 3>>}, {<<2, 3>>}, {<<0, 4>>}, {<<3, 4>>}} -KlotskiGoal == {<<1, 3>>, <<1, 4>>, <<2, 3>>, <<2, 4>>} \in board +KlotskiGoal == {<<1, 3>>, <<1, 4>>, <<2, 3>>, <<2, 4>>} \notin board ChooseOne(S, P(_)) == CHOOSE x \in S : P(x) /\ \A y \in S : P(y) => y = x diff --git a/specifications/tower_of_hanoi/Hanoi.toolbox/Model_1/MC.cfg b/specifications/tower_of_hanoi/Hanoi.toolbox/Model_1/MC.cfg index d46b97b8..f2dd92d1 100644 --- a/specifications/tower_of_hanoi/Hanoi.toolbox/Model_1/MC.cfg +++ b/specifications/tower_of_hanoi/Hanoi.toolbox/Model_1/MC.cfg @@ -7,4 +7,6 @@ N <- const_146427254082040000 \* SPECIFICATION definition SPECIFICATION spec_146427254083041000 -\* Generated on Thu May 26 16:22:20 CEST 2016 \ No newline at end of file +\* Generated on Thu May 26 16:22:20 CEST 2016 +INVARIANT NotSolved + From 5f2d507f1bd48cd0c03a2dac270d63f8305806c4 Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Fri, 27 Jan 2023 11:18:25 -0500 Subject: [PATCH 23/70] Check TLC result against expected result Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/scripts/check_small_models.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/scripts/check_small_models.py b/.github/scripts/check_small_models.py index 8f3f2593..adbeb016 100644 --- a/.github/scripts/check_small_models.py +++ b/.github/scripts/check_small_models.py @@ -19,6 +19,7 @@ for model in module['models'] if model['size'] == 'small' ] +success = True for module_path, model_path, expected_result in small_models: print(model_path) tlc = subprocess.run([ @@ -34,9 +35,10 @@ '-config', model_path, module_path ], capture_output=True) - tlc_output = tlc.stdout.decode('utf-8') - - print(tlc_output) - print(tlc.returncode) + if (tlc.returncode == 0 and expected_result != 'success') or (tlc.returncode != 0 and expected_result == 'success'): + success = False + print(f'Model {model_path} expected result {expected_result} but returned error code {tlc.returncode}') + print(tlc.stdout.decode('utf-8')) +exit(0 if success else 1) From 2934f8811d6dbadfc348cbcc9c0cb35bb891620e Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Fri, 27 Jan 2023 19:38:20 -0500 Subject: [PATCH 24/70] Categorized almost all models Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/scripts/check_small_models.py | 63 +++++-- .github/workflows/run.sh | 95 +--------- manifest-schema.json | 2 +- manifest.json | 242 +++++++++++++------------- 4 files changed, 169 insertions(+), 233 deletions(-) diff --git a/.github/scripts/check_small_models.py b/.github/scripts/check_small_models.py index adbeb016..32f37bb2 100644 --- a/.github/scripts/check_small_models.py +++ b/.github/scripts/check_small_models.py @@ -4,41 +4,66 @@ machines. """ +from concurrent.futures import ThreadPoolExecutor import json +import logging from os import cpu_count import subprocess +from timeit import default_timer as timer -manifest = None -with open('manifest.json', 'rt') as manifest_file: - manifest = json.load(manifest_file) +tlc_result = { + 0 : 'success', + 1 : 'stuttering failure', + 11 : 'deadlock failure', + 12 : 'safety failure', + 13 : 'liveness failure' +} -small_models = [ - (module['path'], model['path'], model['result']) - for spec in manifest['specifications'] - for module in spec['modules'] - for model in module['models'] if model['size'] == 'small' -] - -success = True -for module_path, model_path, expected_result in small_models: - print(model_path) +def check_model(model_tuple): + start_time = timer() + module_path, model_path, expected_result = model_tuple tlc = subprocess.run([ 'java', + '-Dtlc2.TLC.stopAfter=60', '-Dtlc2.TLC.ide=Github', '-Dutil.ExecutionStatisticsCollector.id=abcdef60f238424fa70d124d0c77ffff', '-XX:+UseParallelGC', '-cp', 'tla2tools.jar', 'tlc2.TLC', - '-workers', str(cpu_count()), + '-workers', '1', '-lncheck', 'final', '-tool', '-config', model_path, module_path ], capture_output=True) - if (tlc.returncode == 0 and expected_result != 'success') or (tlc.returncode != 0 and expected_result == 'success'): - success = False - print(f'Model {model_path} expected result {expected_result} but returned error code {tlc.returncode}') - print(tlc.stdout.decode('utf-8')) + end_time = timer() + logging.info(f'{model_path} in {end_time - start_time:.1f}s') + actual_result = tlc_result[tlc.returncode] if tlc.returncode in tlc_result else str(tlc.returncode) + if expected_result != actual_result or '687' in model_path: + logging.error(f'Model {model_path} expected result {expected_result} but got {actual_result}') + logging.error(tlc.stdout.decode('utf-8')) + return False + return True + +logging.basicConfig(level=logging.INFO) + +manifest = None +with open('manifest.json', 'rt') as manifest_file: + manifest = json.load(manifest_file) + +small_models = [ + (module['path'], model['path'], model['result']) + for spec in manifest['specifications'] + for module in spec['modules'] + for model in module['models'] if model['size'] == 'small' +] -exit(0 if success else 1) +# Since these models are small we parallelize by checking multiple files at +# once instead of parallelizing state computation and exploration for each +# individual model. +thread_count = cpu_count() +logging.info(f'Checking models using {thread_count} threads') +with ThreadPoolExecutor(thread_count) as executor: + results = executor.map(check_model, small_models) + exit(0 if all(results) else 1) diff --git a/.github/workflows/run.sh b/.github/workflows/run.sh index 5c0145d1..a9e4d594 100755 --- a/.github/workflows/run.sh +++ b/.github/workflows/run.sh @@ -2,108 +2,19 @@ TLC_COMMAND="java -Dtlc2.TLC.stopAfter=180 -Dtlc2.TLC.ide=Github -Dutil.ExecutionStatisticsCollector.id=abcdef60f238424fa70d124d0c77ffff -cp tla2tools.jar tlc2.TLC -workers auto -lncheck final -tool -deadlock" -echo Check EWD840 -$TLC_COMMAND specifications/ewd840/EWD840 -echo Check CarTalkPuzzle Model_1 -$TLC_COMMAND specifications/CarTalkPuzzle/CarTalkPuzzle.toolbox/Model_1/MC -echo Check CarTalkPuzzle Model_2 -$TLC_COMMAND specifications/CarTalkPuzzle/CarTalkPuzzle.toolbox/Model_2/MC -echo Check MCDieHarder -$TLC_COMMAND specifications/DieHard/MCDieHarder || (($? == 12)) ## Expect a safety violation -echo Check DieHard -$TLC_COMMAND specifications/DieHard/DieHard || (($? == 12)) ## Expect a safety violation -echo Check DiningPhilosophers -$TLC_COMMAND specifications/DiningPhilosophers/DiningPhilosophers -echo Check TransitiveClosure -$TLC_COMMAND specifications/TransitiveClosure/TransitiveClosure -echo Check Hanoi -java -Dtlc2.TLC.stopAfter=600 -Dtlc2.TLC.ide=Github -Dutil.ExecutionStatisticsCollector.id=abcdef60f238424fa70d124d0c77ffff -cp tla2tools.jar:specifications/tower_of_hanoi/Hanoi.toolbox/Model_1/MC tlc2.TLC -workers auto -lncheck final -tool -deadlock specifications/tower_of_hanoi/Hanoi.toolbox/Model_1/MC -echo Check MCEcho -$TLC_COMMAND specifications/echo/MCEcho -echo Check Prisoners -$TLC_COMMAND specifications/Prisoners/Prisoners -echo Check LSpec-model -$TLC_COMMAND specifications/dijkstra-mutex/DijkstraMutex.toolbox/LSpec-model/MC -echo Check Safety-4-processors -$TLC_COMMAND specifications/dijkstra-mutex/DijkstraMutex.toolbox/Safety-4-processors/MC ## This spec used to be accepted by Apalache, but since Apalache has started to require type annotations for all variables. ## https://github.com/tlaplus/Examples/pull/31#issuecomment-796354291 -#echo Check EinsteinRiddle -#$TLC_COMMAND specifications/EinsteinRiddle/Einstein -echo Check MCInnerSequential -$TLC_COMMAND specifications/SpecifyingSystems/AdvancedExamples/MCInnerSequential #echo Check MCInnerSerial #$TLC_COMMAND specifications/SpecifyingSystems/AdvancedExamples/MCInnerSerial -echo Check MCLiveWriteThroughCache -$TLC_COMMAND specifications/SpecifyingSystems/Liveness/MCLiveWriteThroughCache -echo Check LiveHourClock -$TLC_COMMAND specifications/SpecifyingSystems/Liveness/LiveHourClock -echo Check MCLiveInternalMemory -$TLC_COMMAND specifications/SpecifyingSystems/Liveness/MCLiveInternalMemory -echo Check SimpleMath -$TLC_COMMAND specifications/SpecifyingSystems/SimpleMath/SimpleMath -echo Check HourClock2 -$TLC_COMMAND specifications/SpecifyingSystems/HourClock/HourClock2 -echo Check HourClock -$TLC_COMMAND specifications/SpecifyingSystems/HourClock/HourClock -echo Check MCInternalMemory -$TLC_COMMAND specifications/SpecifyingSystems/CachingMemory/MCInternalMemory -echo Check MCWriteThroughCache -$TLC_COMMAND specifications/SpecifyingSystems/CachingMemory/MCWriteThroughCache -echo Check PrintValues -$TLC_COMMAND specifications/SpecifyingSystems/AsynchronousInterface/PrintValues -echo Check AsynchInterface -$TLC_COMMAND specifications/SpecifyingSystems/AsynchronousInterface/AsynchInterface -echo Check Channel -$TLC_COMMAND specifications/SpecifyingSystems/AsynchronousInterface/Channel -echo Check MCAlternatingBit -$TLC_COMMAND specifications/SpecifyingSystems/TLC/MCAlternatingBit -echo Check ABCorrectness -$TLC_COMMAND specifications/SpecifyingSystems/TLC/ABCorrectness -echo Check MCRealTimeHourClock -$TLC_COMMAND specifications/SpecifyingSystems/RealTime/MCRealTimeHourClock || (($? != 1)) ## Stuttering -echo Check MCInnerFIFO -$TLC_COMMAND specifications/SpecifyingSystems/FIFO/MCInnerFIFO echo Check EWD840_anim $TLC_COMMAND -simulate num=1 specifications/ewd840/EWD840_anim || (($? == 12)) ## Expect a safety violation -echo Check SyncTerminationDetection -$TLC_COMMAND specifications/ewd840/SyncTerminationDetection -echo Check EWD840 -$TLC_COMMAND specifications/ewd840/EWD840 echo Check EWD840_json sed -i '/^SendMsg/{n;d;}' specifications/ewd840/EWD840.tla ## Cause RealInv to be violated (see EWD840_json.tla) $TLC_COMMAND specifications/ewd840/EWD840_json -echo Check MCVoting -$TLC_COMMAND specifications/Paxos/MCVoting -echo Check MCConsensus -$TLC_COMMAND specifications/Paxos/MCConsensus -echo Check MCPaxos -$TLC_COMMAND specifications/Paxos/MCPaxos echo Check EWD998ChanID $TLC_COMMAND specifications/ewd998/EWD998ChanID -echo Check EWD998Chan -$TLC_COMMAND specifications/ewd998/EWD998Chan -echo Check EWD998 -$TLC_COMMAND specifications/ewd998/EWD998 -echo Check TestGraphs -$TLC_COMMAND specifications/TLC/TestGraphs -echo Check SchedulingAllocator -$TLC_COMMAND specifications/allocator/SchedulingAllocator -echo Check AllocatorRefinement -$TLC_COMMAND specifications/allocator/AllocatorRefinement -echo Check SimpleAllocator -$TLC_COMMAND specifications/allocator/SimpleAllocator -echo Check AllocatorImplementation -$TLC_COMMAND specifications/allocator/AllocatorImplementation -echo Check FourQueens -$TLC_COMMAND specifications/N-Queens/Queens.toolbox/FourQueens/MC -echo Check FourQueens PlusCal -$TLC_COMMAND specifications/N-Queens/QueensPluscal.toolbox/FourQueens/MC -echo Check ReadersWriters -$TLC_COMMAND specifications/ReadersWriters/MC -echo Check EWD687a -$TLC_COMMAND specifications/ewd687a/MCEWD687a echo Simulate EWD687a_anim $TLC_COMMAND -simulate num=100 -note specifications/ewd687a/EWD687a_anim || (($? == 12)) ## Expect a safety violation -echo Check Huang -$TLC_COMMAND specifications/Huang/Huang +echo Simulate KnuthYao +$TLC_COMMAND -generate specifications/KnuthYao/SimKnuthYao + diff --git a/manifest-schema.json b/manifest-schema.json index 71899966..f739a360 100644 --- a/manifest-schema.json +++ b/manifest-schema.json @@ -56,7 +56,7 @@ "type": "array", "items": {"enum": ["liveness", "symmetry", "view", "alias", "state constraint"]} }, - "result": {"enum": ["success", "safety failure", "liveness failure", "deadlock", "unknown"]} + "result": {"enum": ["success", "safety failure", "stuttering failure", "liveness failure", "deadlock failure", "unknown"]} } } } diff --git a/manifest.json b/manifest.json index 2804927d..19a8fb65 100644 --- a/manifest.json +++ b/manifest.json @@ -359,14 +359,14 @@ "models": [ { "path": "specifications/Huang/Huang.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:01", + "size": "small", "features": [ "alias", "liveness", "state constraint" ], - "result": "unknown" + "result": "deadlock failure" } ] } @@ -725,7 +725,7 @@ "runtime": "00:00:01", "size": "small", "features": [], - "result": "safety failure" + "result": "deadlock failure" } ] }, @@ -854,10 +854,10 @@ "models": [ { "path": "specifications/Paxos/MCConsensus.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:01", + "size": "small", "features": [], - "result": "unknown" + "result": "deadlock failure" } ] }, @@ -869,13 +869,13 @@ "models": [ { "path": "specifications/Paxos/MCPaxos.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:01", + "size": "small", "features": [ "liveness", "symmetry" ], - "result": "unknown" + "result": "success" } ] }, @@ -887,13 +887,13 @@ "models": [ { "path": "specifications/Paxos/MCVoting.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:01", + "size": "small", "features": [ "liveness", "symmetry" ], - "result": "unknown" + "result": "deadlock failure" } ] }, @@ -1008,12 +1008,12 @@ "models": [ { "path": "specifications/ReadersWriters/MC.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:05", + "size": "small", "features": [ "liveness" ], - "result": "unknown" + "result": "success" } ] }, @@ -1045,12 +1045,12 @@ "models": [ { "path": "specifications/SDP_Verification/SDP_Attack_New_Solution_Spec/MC.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:01", + "size": "small", "features": [ "liveness" ], - "result": "unknown" + "result": "deadlock failure" } ] }, @@ -1072,12 +1072,12 @@ "models": [ { "path": "specifications/SDP_Verification/SDP_Attack_Spec/MC.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:01", + "size": "small", "features": [ "liveness" ], - "result": "unknown" + "result": "deadlock failure" } ] }, @@ -1285,13 +1285,13 @@ "models": [ { "path": "specifications/SpecifyingSystems/AdvancedExamples/MCInnerSequential.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:01", + "size": "small", "features": [ "liveness", "state constraint" ], - "result": "unknown" + "result": "success" } ] }, @@ -1335,10 +1335,10 @@ "models": [ { "path": "specifications/SpecifyingSystems/AsynchronousInterface/AsynchInterface.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:01", + "size": "small", "features": [], - "result": "unknown" + "result": "success" } ] }, @@ -1350,10 +1350,10 @@ "models": [ { "path": "specifications/SpecifyingSystems/AsynchronousInterface/Channel.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:01", + "size": "small", "features": [], - "result": "unknown" + "result": "success" } ] }, @@ -1365,10 +1365,10 @@ "models": [ { "path": "specifications/SpecifyingSystems/AsynchronousInterface/PrintValues.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:01", + "size": "small", "features": [], - "result": "unknown" + "result": "success" } ] }, @@ -1387,10 +1387,10 @@ "models": [ { "path": "specifications/SpecifyingSystems/CachingMemory/MCInternalMemory.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:01", + "size": "small", "features": [], - "result": "unknown" + "result": "success" } ] }, @@ -1402,12 +1402,12 @@ "models": [ { "path": "specifications/SpecifyingSystems/CachingMemory/MCWriteThroughCache.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:01", + "size": "small", "features": [ "liveness" ], - "result": "unknown" + "result": "success" } ] }, @@ -1531,12 +1531,12 @@ "models": [ { "path": "specifications/SpecifyingSystems/FIFO/MCInnerFIFO.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:01", + "size": "small", "features": [ "state constraint" ], - "result": "unknown" + "result": "success" } ] }, @@ -1548,10 +1548,10 @@ "models": [ { "path": "specifications/SpecifyingSystems/HourClock/HourClock.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:01", + "size": "small", "features": [], - "result": "unknown" + "result": "success" } ] }, @@ -1563,12 +1563,12 @@ "models": [ { "path": "specifications/SpecifyingSystems/HourClock/HourClock2.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:01", + "size": "small", "features": [ "liveness" ], - "result": "unknown" + "result": "success" } ] }, @@ -1594,12 +1594,12 @@ "models": [ { "path": "specifications/SpecifyingSystems/Liveness/LiveHourClock.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:01", + "size": "small", "features": [ "liveness" ], - "result": "unknown" + "result": "success" } ] }, @@ -1632,12 +1632,12 @@ "models": [ { "path": "specifications/SpecifyingSystems/Liveness/MCLiveInternalMemory.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:01", + "size": "small", "features": [ "liveness" ], - "result": "unknown" + "result": "success" } ] }, @@ -1649,12 +1649,12 @@ "models": [ { "path": "specifications/SpecifyingSystems/Liveness/MCLiveWriteThroughCache.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:01", + "size": "small", "features": [ "liveness" ], - "result": "unknown" + "result": "success" } ] }, @@ -1708,12 +1708,12 @@ "models": [ { "path": "specifications/SpecifyingSystems/RealTime/MCRealTimeHourClock.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:01", + "size": "small", "features": [ "liveness" ], - "result": "unknown" + "result": "liveness failure" } ] }, @@ -1774,10 +1774,10 @@ "models": [ { "path": "specifications/SpecifyingSystems/SimpleMath/SimpleMath.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:01", + "size": "small", "features": [], - "result": "unknown" + "result": "success" } ] }, @@ -1859,10 +1859,10 @@ "models": [ { "path": "specifications/SpecifyingSystems/TLC/ABCorrectness.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:01", + "size": "small", "features": [], - "result": "unknown" + "result": "success" } ] }, @@ -1895,13 +1895,13 @@ "models": [ { "path": "specifications/SpecifyingSystems/TLC/MCAlternatingBit.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:01", + "size": "small", "features": [ "liveness", "state constraint" ], - "result": "unknown" + "result": "success" } ] }, @@ -1960,12 +1960,12 @@ "models": [ { "path": "specifications/TLC/TestGraphs.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:01", + "size": "small", "features": [ "liveness" ], - "result": "unknown" + "result": "success" } ] } @@ -2021,10 +2021,10 @@ "models": [ { "path": "specifications/TransitiveClosure/TransitiveClosure.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:01", + "size": "small", "features": [], - "result": "unknown" + "result": "success" } ] } @@ -2107,12 +2107,12 @@ "models": [ { "path": "specifications/allocator/AllocatorImplementation.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:10", + "size": "small", "features": [ "liveness" ], - "result": "unknown" + "result": "success" } ] }, @@ -2124,12 +2124,12 @@ "models": [ { "path": "specifications/allocator/AllocatorRefinement.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:01", + "size": "small", "features": [ "liveness" ], - "result": "unknown" + "result": "success" } ] }, @@ -2141,12 +2141,12 @@ "models": [ { "path": "specifications/allocator/SchedulingAllocator.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:01", + "size": "small", "features": [ "liveness" ], - "result": "unknown" + "result": "success" } ] }, @@ -2158,12 +2158,12 @@ "models": [ { "path": "specifications/allocator/SimpleAllocator.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:01", + "size": "small", "features": [ "liveness" ], - "result": "unknown" + "result": "success" } ] } @@ -2389,12 +2389,12 @@ "models": [ { "path": "specifications/dijkstra-mutex/DijkstraMutex.toolbox/LSpec-model/MC.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:30", + "size": "small", "features": [ "liveness" ], - "result": "unknown" + "result": "success" } ] }, @@ -2415,10 +2415,10 @@ "models": [ { "path": "specifications/dijkstra-mutex/DijkstraMutex.toolbox/Safety-4-processors/MC.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:02:00", + "size": "medium", "features": [], - "result": "unknown" + "result": "success" } ] } @@ -2485,10 +2485,10 @@ "models": [ { "path": "specifications/echo/MCEcho.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:01", + "size": "small", "features": [], - "result": "unknown" + "result": "success" } ] }, @@ -2594,12 +2594,12 @@ { "path": "specifications/ewd687a/EWD687a_anim.cfg", "runtime": "unknown", - "size": "unknown", + "size": "large", "features": [ "alias", "liveness" ], - "result": "unknown" + "result": "safety failure" } ] }, @@ -2611,13 +2611,13 @@ "models": [ { "path": "specifications/ewd687a/MCEWD687a.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:01:00", + "size": "medium", "features": [ "liveness", "state constraint" ], - "result": "unknown" + "result": "success" } ] } @@ -2641,10 +2641,10 @@ "models": [ { "path": "specifications/ewd840/EWD840.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:01", + "size": "small", "features": [], - "result": "unknown" + "result": "deadlock failure" } ] }, @@ -2699,12 +2699,12 @@ "models": [ { "path": "specifications/ewd840/SyncTerminationDetection.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:01", + "size": "small", "features": [ "liveness" ], - "result": "unknown" + "result": "success" } ] }, @@ -2722,7 +2722,7 @@ { "path": "specifications/ewd998", "title": "Termination Detection in a Ring with Asynchronous Message Delivery", - "description": "Variant of EWD 840 given my Shmuel Safra", + "description": "Variant of EWD 840 given by Shmuel Safra", "source": "", "authors": [ "Markus Kuppe", @@ -2738,12 +2738,12 @@ "models": [ { "path": "specifications/ewd998/AsyncTerminationDetection.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:01", + "size": "small", "features": [ "state constraint" ], - "result": "unknown" + "result": "success" } ] }, @@ -2778,12 +2778,12 @@ "models": [ { "path": "specifications/ewd998/EWD998.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:05", + "size": "small", "features": [ "state constraint" ], - "result": "unknown" + "result": "deadlock failure" } ] }, @@ -2795,13 +2795,13 @@ "models": [ { "path": "specifications/ewd998/EWD998Chan.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:05", + "size": "small", "features": [ "liveness", "state constraint" ], - "result": "unknown" + "result": "deadlock failure" } ] }, @@ -2814,7 +2814,7 @@ { "path": "specifications/ewd998/EWD998ChanID.cfg", "runtime": "unknown", - "size": "unknown", + "size": "large", "features": [ "liveness", "state constraint", @@ -2835,7 +2835,7 @@ { "path": "specifications/ewd998/EWD998ChanID_export.cfg", "runtime": "unknown", - "size": "unknown", + "size": "large", "features": [], "result": "unknown" } @@ -2850,7 +2850,7 @@ { "path": "specifications/ewd998/EWD998ChanID_shiviz.cfg", "runtime": "unknown", - "size": "unknown", + "size": "large", "features": [ "alias" ], From e68eb35eda42b4f95d594a929fcaf9b6641f8bda Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Sat, 28 Jan 2023 08:58:38 -0500 Subject: [PATCH 25/70] Updated model time estimates Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/scripts/check_small_models.py | 41 ++++++++++++++------------- .github/workflows/run.sh | 2 ++ manifest-schema.json | 6 +++- manifest.json | 24 ++++++++-------- 4 files changed, 40 insertions(+), 33 deletions(-) diff --git a/.github/scripts/check_small_models.py b/.github/scripts/check_small_models.py index 32f37bb2..13e41511 100644 --- a/.github/scripts/check_small_models.py +++ b/.github/scripts/check_small_models.py @@ -4,13 +4,16 @@ machines. """ -from concurrent.futures import ThreadPoolExecutor +from datetime import datetime import json import logging -from os import cpu_count import subprocess from timeit import default_timer as timer +def parse_timespan(unparsed): + pattern = '%H:%M:%S' + return datetime.strptime(unparsed, pattern) - datetime.strptime('00:00:00', pattern) + tlc_result = { 0 : 'success', 1 : 'stuttering failure', @@ -19,9 +22,8 @@ 13 : 'liveness failure' } -def check_model(model_tuple): +def check_model(module_path, model_path, expected_result, expected_runtime): start_time = timer() - module_path, model_path, expected_result = model_tuple tlc = subprocess.run([ 'java', '-Dtlc2.TLC.stopAfter=60', @@ -30,14 +32,14 @@ def check_model(model_tuple): '-XX:+UseParallelGC', '-cp', 'tla2tools.jar', 'tlc2.TLC', - '-workers', '1', + '-workers', 'auto', '-lncheck', 'final', '-tool', '-config', model_path, module_path ], capture_output=True) end_time = timer() - logging.info(f'{model_path} in {end_time - start_time:.1f}s') + logging.info(f'{model_path} in {end_time - start_time:.1f}s vs. {expected_runtime.seconds}s expected') actual_result = tlc_result[tlc.returncode] if tlc.returncode in tlc_result else str(tlc.returncode) if expected_result != actual_result or '687' in model_path: logging.error(f'Model {model_path} expected result {expected_result} but got {actual_result}') @@ -51,19 +53,18 @@ def check_model(model_tuple): with open('manifest.json', 'rt') as manifest_file: manifest = json.load(manifest_file) -small_models = [ - (module['path'], model['path'], model['result']) - for spec in manifest['specifications'] - for module in spec['modules'] - for model in module['models'] if model['size'] == 'small' -] +# Ensure longest-running modules go first +small_models = sorted( + [ + (module['path'], model['path'], model['result'], parse_timespan(model['runtime'])) + for spec in manifest['specifications'] + for module in spec['modules'] + for model in module['models'] if model['size'] == 'small' + ], + key = lambda m: m[3], + reverse=True +) -# Since these models are small we parallelize by checking multiple files at -# once instead of parallelizing state computation and exploration for each -# individual model. -thread_count = cpu_count() -logging.info(f'Checking models using {thread_count} threads') -with ThreadPoolExecutor(thread_count) as executor: - results = executor.map(check_model, small_models) - exit(0 if all(results) else 1) +success = all([check_model(*model) for model in small_models]) +exit(0 if success else 0) diff --git a/.github/workflows/run.sh b/.github/workflows/run.sh index a9e4d594..364eefee 100755 --- a/.github/workflows/run.sh +++ b/.github/workflows/run.sh @@ -17,4 +17,6 @@ echo Simulate EWD687a_anim $TLC_COMMAND -simulate num=100 -note specifications/ewd687a/EWD687a_anim || (($? == 12)) ## Expect a safety violation echo Simulate KnuthYao $TLC_COMMAND -generate specifications/KnuthYao/SimKnuthYao +echo Check Dijkstra Mutext +$TLC_COMMAND specifications/dijkstra-mutex/DijkstraMutex.toolbox/LSpec-model/MC diff --git a/manifest-schema.json b/manifest-schema.json index f739a360..75a78a64 100644 --- a/manifest-schema.json +++ b/manifest-schema.json @@ -44,7 +44,7 @@ "items": { "type": "object", "additionalProperties": false, - "required": ["path", "runtime", "size", "features", "result"], + "required": ["path", "runtime", "size", "config", "features", "result"], "properties": { "path": {"type": "string"}, "runtime": { @@ -52,6 +52,10 @@ "pattern": "^(([0-9][0-9]:[0-9][0-9]:[0-9][0-9])|unknown)$" }, "size": {"enum": ["small", "medium", "large", "unknown"]}, + "config": { + "type": "array", + "items": {"enum": ["ignore deadlock", "simulate", "generate"]} + }, "features": { "type": "array", "items": {"enum": ["liveness", "symmetry", "view", "alias", "state constraint"]} diff --git a/manifest.json b/manifest.json index 19a8fb65..6a6ac05e 100644 --- a/manifest.json +++ b/manifest.json @@ -187,7 +187,7 @@ }, { "path": "specifications/CoffeeCan/CoffeeCan100Beans.cfg", - "runtime": "00:00:01", + "runtime": "00:00:05", "size": "small", "features": [ "liveness" @@ -1147,7 +1147,7 @@ "models": [ { "path": "specifications/SlidingPuzzles/SlidingPuzzles.cfg", - "runtime": "00:00:01", + "runtime": "00:00:10", "size": "small", "features": [], "result": "safety failure" @@ -1190,7 +1190,7 @@ }, { "path": "specifications/SlushProtocol/SlushSmall.cfg", - "runtime": "00:00:08", + "runtime": "00:00:30", "size": "small", "features": [], "result": "success" @@ -1649,7 +1649,7 @@ "models": [ { "path": "specifications/SpecifyingSystems/Liveness/MCLiveWriteThroughCache.cfg", - "runtime": "00:00:01", + "runtime": "00:00:10", "size": "small", "features": [ "liveness" @@ -1960,7 +1960,7 @@ "models": [ { "path": "specifications/TLC/TestGraphs.cfg", - "runtime": "00:00:01", + "runtime": "00:00:05", "size": "small", "features": [ "liveness" @@ -2021,7 +2021,7 @@ "models": [ { "path": "specifications/TransitiveClosure/TransitiveClosure.cfg", - "runtime": "00:00:01", + "runtime": "00:00:05", "size": "small", "features": [], "result": "success" @@ -2107,7 +2107,7 @@ "models": [ { "path": "specifications/allocator/AllocatorImplementation.cfg", - "runtime": "00:00:10", + "runtime": "00:00:30", "size": "small", "features": [ "liveness" @@ -2124,7 +2124,7 @@ "models": [ { "path": "specifications/allocator/AllocatorRefinement.cfg", - "runtime": "00:00:01", + "runtime": "00:00:05", "size": "small", "features": [ "liveness" @@ -2141,7 +2141,7 @@ "models": [ { "path": "specifications/allocator/SchedulingAllocator.cfg", - "runtime": "00:00:01", + "runtime": "00:00:10", "size": "small", "features": [ "liveness" @@ -2158,7 +2158,7 @@ "models": [ { "path": "specifications/allocator/SimpleAllocator.cfg", - "runtime": "00:00:01", + "runtime": "00:00:05", "size": "small", "features": [ "liveness" @@ -2389,8 +2389,8 @@ "models": [ { "path": "specifications/dijkstra-mutex/DijkstraMutex.toolbox/LSpec-model/MC.cfg", - "runtime": "00:00:30", - "size": "small", + "runtime": "00:00:50", + "size": "medium", "features": [ "liveness" ], From d59084c192d8ff0988a4a10b31c279b16d527fdf Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Sat, 28 Jan 2023 11:34:09 -0500 Subject: [PATCH 26/70] Added simulation specs Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/scripts/check_small_models.py | 50 +++-- .github/scripts/generate_manifest.py | 3 +- .github/workflows/run.sh | 10 - manifest-schema.json | 25 ++- manifest.json | 209 ++++++++++++++++-- .../N-Queens/Queens.toolbox/FourQueens/MC.cfg | 4 +- specifications/ewd998/EWD998Small.cfg | 17 ++ 7 files changed, 265 insertions(+), 53 deletions(-) create mode 100644 specifications/ewd998/EWD998Small.cfg diff --git a/.github/scripts/check_small_models.py b/.github/scripts/check_small_models.py index 13e41511..5bae925a 100644 --- a/.github/scripts/check_small_models.py +++ b/.github/scripts/check_small_models.py @@ -14,34 +14,48 @@ def parse_timespan(unparsed): pattern = '%H:%M:%S' return datetime.strptime(unparsed, pattern) - datetime.strptime('00:00:00', pattern) +def is_simulate_config(config): + sim_options = [ + option for option in config + if type(option) is dict + and 'simulate' in option + ] + if any(sim_options): + return (True, sim_options[0]['simulate']['traceCount']) + else: + return (False, 0) + tlc_result = { 0 : 'success', - 1 : 'stuttering failure', 11 : 'deadlock failure', 12 : 'safety failure', 13 : 'liveness failure' } -def check_model(module_path, model_path, expected_result, expected_runtime): +def check_model(module_path, model_path, expected_result, expected_runtime, config): + is_simulate, trace_count = is_simulate_config(config) start_time = timer() - tlc = subprocess.run([ - 'java', - '-Dtlc2.TLC.stopAfter=60', - '-Dtlc2.TLC.ide=Github', - '-Dutil.ExecutionStatisticsCollector.id=abcdef60f238424fa70d124d0c77ffff', - '-XX:+UseParallelGC', - '-cp', 'tla2tools.jar', - 'tlc2.TLC', - '-workers', 'auto', - '-lncheck', 'final', - '-tool', - '-config', model_path, - module_path - ], capture_output=True) + tlc = subprocess.run( + [ + 'java', + '-Dtlc2.TLC.stopAfter=60', + '-Dtlc2.TLC.ide=Github', + '-Dutil.ExecutionStatisticsCollector.id=abcdef60f238424fa70d124d0c77ffff', + '-XX:+UseParallelGC', + '-cp', 'tla2tools.jar', + 'tlc2.TLC', + module_path, + '-config', model_path, + '-noGenerateSpecTE', # Remove when fixed: https://github.com/tlaplus/tlaplus/issues/785 + '-workers', 'auto', + '-lncheck', 'final' + ] + (['-deadlock'] if 'ignore deadlock' in config else []) + + (['-simulate', f'num={trace_count}'] if is_simulate else []), + capture_output=True) end_time = timer() logging.info(f'{model_path} in {end_time - start_time:.1f}s vs. {expected_runtime.seconds}s expected') actual_result = tlc_result[tlc.returncode] if tlc.returncode in tlc_result else str(tlc.returncode) - if expected_result != actual_result or '687' in model_path: + if expected_result != actual_result: logging.error(f'Model {model_path} expected result {expected_result} but got {actual_result}') logging.error(tlc.stdout.decode('utf-8')) return False @@ -56,7 +70,7 @@ def check_model(module_path, model_path, expected_result, expected_runtime): # Ensure longest-running modules go first small_models = sorted( [ - (module['path'], model['path'], model['result'], parse_timespan(model['runtime'])) + (module['path'], model['path'], model['result'], parse_timespan(model['runtime']), model['config']) for spec in manifest['specifications'] for module in spec['modules'] for model in module['models'] if model['size'] == 'small' diff --git a/.github/scripts/generate_manifest.py b/.github/scripts/generate_manifest.py index fc7e865e..dbafad33 100644 --- a/.github/scripts/generate_manifest.py +++ b/.github/scripts/generate_manifest.py @@ -56,6 +56,7 @@ def get_cfg_files(tla_path): 'path': cfg_path, 'runtime': 'unknown', 'size': 'unknown', + 'config': [], 'features': sorted(list(get_model_features(cfg_path))), 'result': 'unknown' } @@ -103,7 +104,7 @@ def find_corresponding_model(old_model, new_module): ][0] def integrate_model_info(old_model, new_model): - fields = ['runtime', 'size', 'result'] + fields = ['runtime', 'size', 'config', 'result'] for field in fields: new_model[field] = old_model[field] diff --git a/.github/workflows/run.sh b/.github/workflows/run.sh index 364eefee..0c279f71 100755 --- a/.github/workflows/run.sh +++ b/.github/workflows/run.sh @@ -6,17 +6,7 @@ TLC_COMMAND="java -Dtlc2.TLC.stopAfter=180 -Dtlc2.TLC.ide=Github -Dutil.Executio ## https://github.com/tlaplus/Examples/pull/31#issuecomment-796354291 #echo Check MCInnerSerial #$TLC_COMMAND specifications/SpecifyingSystems/AdvancedExamples/MCInnerSerial -echo Check EWD840_anim -$TLC_COMMAND -simulate num=1 specifications/ewd840/EWD840_anim || (($? == 12)) ## Expect a safety violation echo Check EWD840_json sed -i '/^SendMsg/{n;d;}' specifications/ewd840/EWD840.tla ## Cause RealInv to be violated (see EWD840_json.tla) $TLC_COMMAND specifications/ewd840/EWD840_json -echo Check EWD998ChanID -$TLC_COMMAND specifications/ewd998/EWD998ChanID -echo Simulate EWD687a_anim -$TLC_COMMAND -simulate num=100 -note specifications/ewd687a/EWD687a_anim || (($? == 12)) ## Expect a safety violation -echo Simulate KnuthYao -$TLC_COMMAND -generate specifications/KnuthYao/SimKnuthYao -echo Check Dijkstra Mutext -$TLC_COMMAND specifications/dijkstra-mutex/DijkstraMutex.toolbox/LSpec-model/MC diff --git a/manifest-schema.json b/manifest-schema.json index 75a78a64..e2a65ac9 100644 --- a/manifest-schema.json +++ b/manifest-schema.json @@ -54,13 +54,34 @@ "size": {"enum": ["small", "medium", "large", "unknown"]}, "config": { "type": "array", - "items": {"enum": ["ignore deadlock", "simulate", "generate"]} + "items": { + "oneOf": [ + { + "enum": ["ignore deadlock", "generate"] + }, + { + "type": "object", + "additionalProperties": false, + "required": ["simulate"], + "properties": { + "simulate": { + "type": "object", + "additionalProperties": false, + "required": ["traceCount"], + "properties": { + "traceCount": {"type": "number"} + } + } + } + } + ] + } }, "features": { "type": "array", "items": {"enum": ["liveness", "symmetry", "view", "alias", "state constraint"]} }, - "result": {"enum": ["success", "safety failure", "stuttering failure", "liveness failure", "deadlock failure", "unknown"]} + "result": {"enum": ["success", "safety failure", "liveness failure", "deadlock failure", "unknown"]} } } } diff --git a/manifest.json b/manifest.json index 6a6ac05e..9c5c662c 100644 --- a/manifest.json +++ b/manifest.json @@ -69,6 +69,7 @@ "path": "specifications/CarTalkPuzzle/CarTalkPuzzle.toolbox/Model_1/MC.cfg", "runtime": "00:00:01", "size": "small", + "config": [], "features": [], "result": "success" } @@ -91,6 +92,7 @@ "path": "specifications/CarTalkPuzzle/CarTalkPuzzle.toolbox/Model_2/MC.cfg", "runtime": "00:00:01", "size": "small", + "config": [], "features": [], "result": "success" } @@ -113,6 +115,7 @@ "path": "specifications/CarTalkPuzzle/CarTalkPuzzle.toolbox/Model_3/MC.cfg", "runtime": "unknown", "size": "large", + "config": [], "features": [], "result": "unknown" } @@ -180,6 +183,7 @@ "path": "specifications/CoffeeCan/CoffeeCan1000Beans.cfg", "runtime": "00:00:15", "size": "medium", + "config": [], "features": [ "liveness" ], @@ -189,6 +193,7 @@ "path": "specifications/CoffeeCan/CoffeeCan100Beans.cfg", "runtime": "00:00:05", "size": "small", + "config": [], "features": [ "liveness" ], @@ -198,6 +203,7 @@ "path": "specifications/CoffeeCan/CoffeeCan3000Beans.cfg", "runtime": "00:02:30", "size": "medium", + "config": [], "features": [ "liveness" ], @@ -229,6 +235,7 @@ "path": "specifications/DieHard/DieHard.cfg", "runtime": "00:00:01", "size": "small", + "config": [], "features": [], "result": "safety failure" } @@ -251,6 +258,7 @@ "path": "specifications/DieHard/MCDieHarder.cfg", "runtime": "00:00:01", "size": "small", + "config": [], "features": [], "result": "safety failure" } @@ -282,6 +290,7 @@ "path": "specifications/DiningPhilosophers/DiningPhilosophers.cfg", "runtime": "00:00:01", "size": "small", + "config": [], "features": [ "liveness" ], @@ -311,6 +320,7 @@ "path": "specifications/EinsteinRiddle/Einstein.cfg", "runtime": "unknown", "size": "large", + "config": [], "features": [], "result": "safety failure" } @@ -359,16 +369,31 @@ "models": [ { "path": "specifications/Huang/Huang.cfg", - "runtime": "00:00:01", + "runtime": "00:00:30", "size": "small", + "config": ["ignore deadlock"], "features": [ "alias", "liveness", "state constraint" ], - "result": "deadlock failure" + "result": "success" } ] + }, + { + "path": "specifications/Huang/Huang_TTrace_1674862545.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/Huang/Huang_TTrace_1674914150.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] } ] }, @@ -399,6 +424,7 @@ "path": "specifications/KeyValueStore/MCKVSSafetyLarge.cfg", "runtime": "07:16:00", "size": "large", + "config": [], "features": [ "symmetry" ], @@ -408,6 +434,7 @@ "path": "specifications/KeyValueStore/MCKVSSafetyMedium.cfg", "runtime": "00:04:30", "size": "medium", + "config": [], "features": [ "symmetry" ], @@ -417,6 +444,7 @@ "path": "specifications/KeyValueStore/MCKVSSafetySmall.cfg", "runtime": "00:00:40", "size": "medium", + "config": [], "features": [], "result": "success" } @@ -466,6 +494,7 @@ "path": "specifications/KnuthYao/SimKnuthYao.cfg", "runtime": "unknown", "size": "unknown", + "config": ["generate"], "features": [ "state constraint" ], @@ -629,6 +658,7 @@ "path": "specifications/MissionariesAndCannibals/MissionariesAndCannibals.cfg", "runtime": "00:00:01", "size": "small", + "config": [], "features": [], "result": "safety failure" } @@ -656,6 +686,7 @@ "path": "specifications/MultiCarElevator/ElevatorLivenessLarge.cfg", "runtime": "00:11:00", "size": "large", + "config": [], "features": [ "liveness" ], @@ -665,6 +696,7 @@ "path": "specifications/MultiCarElevator/ElevatorLivenessMedium.cfg", "runtime": "00:00:30", "size": "medium", + "config": [], "features": [ "liveness" ], @@ -674,6 +706,7 @@ "path": "specifications/MultiCarElevator/ElevatorSafetyLarge.cfg", "runtime": "00:10:00", "size": "large", + "config": [], "features": [], "result": "success" }, @@ -681,6 +714,7 @@ "path": "specifications/MultiCarElevator/ElevatorSafetyMedium.cfg", "runtime": "00:03:00", "size": "medium", + "config": [], "features": [], "result": "success" }, @@ -688,6 +722,7 @@ "path": "specifications/MultiCarElevator/ElevatorSafetySmall.cfg", "runtime": "00:00:10", "size": "small", + "config": [], "features": [], "result": "success" } @@ -724,8 +759,9 @@ "path": "specifications/N-Queens/Queens.toolbox/FourQueens/MC.cfg", "runtime": "00:00:01", "size": "small", + "config": ["ignore deadlock"], "features": [], - "result": "deadlock failure" + "result": "safety failure" } ] }, @@ -755,6 +791,7 @@ "path": "specifications/N-Queens/QueensPluscal.toolbox/FourQueens/MC.cfg", "runtime": "00:00:01", "size": "small", + "config": [], "features": [ "liveness" ], @@ -793,6 +830,7 @@ "path": "specifications/NanoBlockchain/MCNanoLarge.cfg", "runtime": "00:20:00", "size": "large", + "config": [], "features": [ "view" ], @@ -802,6 +840,7 @@ "path": "specifications/NanoBlockchain/MCNanoMedium.cfg", "runtime": "00:00:30", "size": "medium", + "config": [], "features": [ "view" ], @@ -811,6 +850,7 @@ "path": "specifications/NanoBlockchain/MCNanoSmall.cfg", "runtime": "00:00:05", "size": "small", + "config": [], "features": [ "view" ], @@ -856,8 +896,9 @@ "path": "specifications/Paxos/MCConsensus.cfg", "runtime": "00:00:01", "size": "small", + "config": ["ignore deadlock"], "features": [], - "result": "deadlock failure" + "result": "success" } ] }, @@ -871,6 +912,7 @@ "path": "specifications/Paxos/MCPaxos.cfg", "runtime": "00:00:01", "size": "small", + "config": [], "features": [ "liveness", "symmetry" @@ -889,11 +931,12 @@ "path": "specifications/Paxos/MCVoting.cfg", "runtime": "00:00:01", "size": "small", + "config": ["ignore deadlock"], "features": [ "liveness", "symmetry" ], - "result": "deadlock failure" + "result": "success" } ] }, @@ -981,6 +1024,7 @@ "path": "specifications/Prisoners/Prisoners.cfg", "runtime": "00:00:01", "size": "small", + "config": [], "features": [ "liveness" ], @@ -1010,6 +1054,7 @@ "path": "specifications/ReadersWriters/MC.cfg", "runtime": "00:00:05", "size": "small", + "config": [], "features": [ "liveness" ], @@ -1047,13 +1092,21 @@ "path": "specifications/SDP_Verification/SDP_Attack_New_Solution_Spec/MC.cfg", "runtime": "00:00:01", "size": "small", + "config": ["ignore deadlock"], "features": [ "liveness" ], - "result": "deadlock failure" + "result": "success" } ] }, + { + "path": "specifications/SDP_Verification/SDP_Attack_New_Solution_Spec/MC_TTrace_1674864840.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, { "path": "specifications/SDP_Verification/SDP_Attack_New_Solution_Spec/SPA_Attack_New.tla", "communityDependencies": [ @@ -1072,15 +1125,37 @@ "models": [ { "path": "specifications/SDP_Verification/SDP_Attack_Spec/MC.cfg", - "runtime": "00:00:01", + "runtime": "00:00:05", "size": "small", + "config": ["ignore deadlock"], "features": [ "liveness" ], - "result": "deadlock failure" + "result": "safety failure" } ] }, + { + "path": "specifications/SDP_Verification/SDP_Attack_Spec/MC_TTrace_1674864912.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SDP_Verification/SDP_Attack_Spec/MC_TTrace_1674864941.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/SDP_Verification/SDP_Attack_Spec/MC_TTrace_1674914119.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, { "path": "specifications/SDP_Verification/SDP_Attack_Spec/SPA_Attack.tla", "communityDependencies": [ @@ -1113,6 +1188,7 @@ "path": "specifications/SingleLaneBridge/MC.cfg", "runtime": "unknown", "size": "unknown", + "config": [], "features": [ "liveness" ], @@ -1149,6 +1225,7 @@ "path": "specifications/SlidingPuzzles/SlidingPuzzles.cfg", "runtime": "00:00:10", "size": "small", + "config": [], "features": [], "result": "safety failure" } @@ -1178,6 +1255,7 @@ "path": "specifications/SlushProtocol/SlushLarge.cfg", "runtime": "00:50:00", "size": "large", + "config": [], "features": [], "result": "success" }, @@ -1185,6 +1263,7 @@ "path": "specifications/SlushProtocol/SlushMedium.cfg", "runtime": "00:01:00", "size": "medium", + "config": [], "features": [], "result": "success" }, @@ -1192,6 +1271,7 @@ "path": "specifications/SlushProtocol/SlushSmall.cfg", "runtime": "00:00:30", "size": "small", + "config": [], "features": [], "result": "success" } @@ -1287,6 +1367,7 @@ "path": "specifications/SpecifyingSystems/AdvancedExamples/MCInnerSequential.cfg", "runtime": "00:00:01", "size": "small", + "config": [], "features": [ "liveness", "state constraint" @@ -1305,6 +1386,7 @@ "path": "specifications/SpecifyingSystems/AdvancedExamples/MCInnerSerial.cfg", "runtime": "unknown", "size": "unknown", + "config": [], "features": [ "liveness", "state constraint" @@ -1337,6 +1419,7 @@ "path": "specifications/SpecifyingSystems/AsynchronousInterface/AsynchInterface.cfg", "runtime": "00:00:01", "size": "small", + "config": [], "features": [], "result": "success" } @@ -1350,8 +1433,9 @@ "models": [ { "path": "specifications/SpecifyingSystems/AsynchronousInterface/Channel.cfg", - "runtime": "00:00:01", + "runtime": "00:00:10", "size": "small", + "config": [], "features": [], "result": "success" } @@ -1367,6 +1451,7 @@ "path": "specifications/SpecifyingSystems/AsynchronousInterface/PrintValues.cfg", "runtime": "00:00:01", "size": "small", + "config": [], "features": [], "result": "success" } @@ -1389,6 +1474,7 @@ "path": "specifications/SpecifyingSystems/CachingMemory/MCInternalMemory.cfg", "runtime": "00:00:01", "size": "small", + "config": [], "features": [], "result": "success" } @@ -1404,6 +1490,7 @@ "path": "specifications/SpecifyingSystems/CachingMemory/MCWriteThroughCache.cfg", "runtime": "00:00:01", "size": "small", + "config": [], "features": [ "liveness" ], @@ -1533,6 +1620,7 @@ "path": "specifications/SpecifyingSystems/FIFO/MCInnerFIFO.cfg", "runtime": "00:00:01", "size": "small", + "config": [], "features": [ "state constraint" ], @@ -1550,6 +1638,7 @@ "path": "specifications/SpecifyingSystems/HourClock/HourClock.cfg", "runtime": "00:00:01", "size": "small", + "config": [], "features": [], "result": "success" } @@ -1565,6 +1654,7 @@ "path": "specifications/SpecifyingSystems/HourClock/HourClock2.cfg", "runtime": "00:00:01", "size": "small", + "config": [], "features": [ "liveness" ], @@ -1596,6 +1686,7 @@ "path": "specifications/SpecifyingSystems/Liveness/LiveHourClock.cfg", "runtime": "00:00:01", "size": "small", + "config": [], "features": [ "liveness" ], @@ -1634,6 +1725,7 @@ "path": "specifications/SpecifyingSystems/Liveness/MCLiveInternalMemory.cfg", "runtime": "00:00:01", "size": "small", + "config": [], "features": [ "liveness" ], @@ -1651,6 +1743,7 @@ "path": "specifications/SpecifyingSystems/Liveness/MCLiveWriteThroughCache.cfg", "runtime": "00:00:10", "size": "small", + "config": [], "features": [ "liveness" ], @@ -1710,6 +1803,7 @@ "path": "specifications/SpecifyingSystems/RealTime/MCRealTimeHourClock.cfg", "runtime": "00:00:01", "size": "small", + "config": [], "features": [ "liveness" ], @@ -1776,6 +1870,7 @@ "path": "specifications/SpecifyingSystems/SimpleMath/SimpleMath.cfg", "runtime": "00:00:01", "size": "small", + "config": [], "features": [], "result": "success" } @@ -1861,6 +1956,7 @@ "path": "specifications/SpecifyingSystems/TLC/ABCorrectness.cfg", "runtime": "00:00:01", "size": "small", + "config": [], "features": [], "result": "success" } @@ -1897,6 +1993,7 @@ "path": "specifications/SpecifyingSystems/TLC/MCAlternatingBit.cfg", "runtime": "00:00:01", "size": "small", + "config": [], "features": [ "liveness", "state constraint" @@ -1962,6 +2059,7 @@ "path": "specifications/TLC/TestGraphs.cfg", "runtime": "00:00:05", "size": "small", + "config": [], "features": [ "liveness" ], @@ -2023,6 +2121,7 @@ "path": "specifications/TransitiveClosure/TransitiveClosure.cfg", "runtime": "00:00:05", "size": "small", + "config": [], "features": [], "result": "success" } @@ -2109,6 +2208,7 @@ "path": "specifications/allocator/AllocatorImplementation.cfg", "runtime": "00:00:30", "size": "small", + "config": [], "features": [ "liveness" ], @@ -2126,6 +2226,7 @@ "path": "specifications/allocator/AllocatorRefinement.cfg", "runtime": "00:00:05", "size": "small", + "config": [], "features": [ "liveness" ], @@ -2143,6 +2244,7 @@ "path": "specifications/allocator/SchedulingAllocator.cfg", "runtime": "00:00:10", "size": "small", + "config": [], "features": [ "liveness" ], @@ -2160,6 +2262,7 @@ "path": "specifications/allocator/SimpleAllocator.cfg", "runtime": "00:00:05", "size": "small", + "config": [], "features": [ "liveness" ], @@ -2391,6 +2494,7 @@ "path": "specifications/dijkstra-mutex/DijkstraMutex.toolbox/LSpec-model/MC.cfg", "runtime": "00:00:50", "size": "medium", + "config": [], "features": [ "liveness" ], @@ -2417,6 +2521,7 @@ "path": "specifications/dijkstra-mutex/DijkstraMutex.toolbox/Safety-4-processors/MC.cfg", "runtime": "00:02:00", "size": "medium", + "config": [], "features": [], "result": "success" } @@ -2487,6 +2592,7 @@ "path": "specifications/echo/MCEcho.cfg", "runtime": "00:00:01", "size": "small", + "config": [], "features": [], "result": "success" } @@ -2525,6 +2631,7 @@ "path": "specifications/ewd426/SimTokenRing.cfg", "runtime": "unknown", "size": "unknown", + "config": [], "features": [ "state constraint" ], @@ -2542,6 +2649,7 @@ "path": "specifications/ewd426/TokenRing.cfg", "runtime": "unknown", "size": "unknown", + "config": [], "features": [ "alias", "liveness" @@ -2593,8 +2701,15 @@ "models": [ { "path": "specifications/ewd687a/EWD687a_anim.cfg", - "runtime": "unknown", - "size": "large", + "runtime": "00:00:01", + "size": "small", + "config": [ + { + "simulate": { + "traceCount": 1 + } + } + ], "features": [ "alias", "liveness" @@ -2613,6 +2728,7 @@ "path": "specifications/ewd687a/MCEWD687a.cfg", "runtime": "00:01:00", "size": "medium", + "config": [], "features": [ "liveness", "state constraint" @@ -2643,8 +2759,9 @@ "path": "specifications/ewd840/EWD840.cfg", "runtime": "00:00:01", "size": "small", + "config": ["ignore deadlock"], "features": [], - "result": "deadlock failure" + "result": "success" } ] }, @@ -2658,12 +2775,19 @@ "models": [ { "path": "specifications/ewd840/EWD840_anim.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:01", + "size": "small", + "config": [ + { + "simulate": { + "traceCount": 100 + } + } + ], "features": [ "alias" ], - "result": "unknown" + "result": "safety failure" } ] }, @@ -2677,6 +2801,7 @@ "path": "specifications/ewd840/EWD840_json.cfg", "runtime": "unknown", "size": "unknown", + "config": [], "features": [], "result": "unknown" } @@ -2701,6 +2826,7 @@ "path": "specifications/ewd840/SyncTerminationDetection.cfg", "runtime": "00:00:01", "size": "small", + "config": [], "features": [ "liveness" ], @@ -2740,6 +2866,7 @@ "path": "specifications/ewd998/AsyncTerminationDetection.cfg", "runtime": "00:00:01", "size": "small", + "config": [], "features": [ "state constraint" ], @@ -2759,6 +2886,7 @@ "path": "specifications/ewd998/AsyncTerminationDetection_proof.cfg", "runtime": "unknown", "size": "unknown", + "config": [], "features": [ "liveness", "state constraint" @@ -2777,13 +2905,24 @@ "features": [], "models": [ { - "path": "specifications/ewd998/EWD998.cfg", - "runtime": "00:00:05", + "path": "specifications/ewd998/EWD998Small.cfg", + "runtime": "00:00:30", "size": "small", + "config": ["ignore deadlock"], + "features": [ + "state constraint" + ], + "result": "success" + }, + { + "path": "specifications/ewd998/EWD998.cfg", + "runtime": "00:50:00", + "size": "large", + "config": ["ignore deadlock"], "features": [ "state constraint" ], - "result": "deadlock failure" + "result": "success" } ] }, @@ -2795,13 +2934,14 @@ "models": [ { "path": "specifications/ewd998/EWD998Chan.cfg", - "runtime": "00:00:05", - "size": "small", + "runtime": "00:05:00", + "size": "medium", + "config": ["ignore deadlock"], "features": [ "liveness", "state constraint" ], - "result": "deadlock failure" + "result": "success" } ] }, @@ -2815,6 +2955,7 @@ "path": "specifications/ewd998/EWD998ChanID.cfg", "runtime": "unknown", "size": "large", + "config": [], "features": [ "liveness", "state constraint", @@ -2836,6 +2977,7 @@ "path": "specifications/ewd998/EWD998ChanID_export.cfg", "runtime": "unknown", "size": "large", + "config": [], "features": [], "result": "unknown" } @@ -2851,6 +2993,7 @@ "path": "specifications/ewd998/EWD998ChanID_shiviz.cfg", "runtime": "unknown", "size": "large", + "config": [], "features": [ "alias" ], @@ -2858,6 +3001,20 @@ } ] }, + { + "path": "specifications/ewd998/EWD998Chan_TTrace_1674863100.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, + { + "path": "specifications/ewd998/EWD998Chan_TTrace_1674863118.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, { "path": "specifications/ewd998/EWD998Chan_opts.tla", "communityDependencies": [ @@ -2868,6 +3025,13 @@ "features": [], "models": [] }, + { + "path": "specifications/ewd998/EWD998_TTrace_1674863819.tla", + "communityDependencies": [], + "tlaLanguageVersion": 2, + "features": [], + "models": [] + }, { "path": "specifications/ewd998/EWD998_anim.tla", "communityDependencies": [ @@ -2920,6 +3084,7 @@ "path": "specifications/ewd998/SmokeEWD998.cfg", "runtime": "unknown", "size": "unknown", + "config": [], "features": [ "liveness", "state constraint" @@ -2941,6 +3106,7 @@ "path": "specifications/ewd998/SmokeEWD998_SC.cfg", "runtime": "unknown", "size": "unknown", + "config": [], "features": [], "result": "unknown" } @@ -3200,6 +3366,7 @@ "path": "specifications/tower_of_hanoi/Hanoi.toolbox/Model_1/MC.cfg", "runtime": "00:00:01", "size": "small", + "config": [], "features": [], "result": "safety failure" } diff --git a/specifications/N-Queens/Queens.toolbox/FourQueens/MC.cfg b/specifications/N-Queens/Queens.toolbox/FourQueens/MC.cfg index 2e54e098..2b79a3d7 100644 --- a/specifications/N-Queens/Queens.toolbox/FourQueens/MC.cfg +++ b/specifications/N-Queens/Queens.toolbox/FourQueens/MC.cfg @@ -8,4 +8,6 @@ spec_129269484699017000 INVARIANT inv_129269484700018000 inv_129269484701019000 -\* Generated at Sat Dec 18 18:54:07 CET 2010 \ No newline at end of file +\* Generated at Sat Dec 18 18:54:07 CET 2010 +INVARIANT NoSolutions + diff --git a/specifications/ewd998/EWD998Small.cfg b/specifications/ewd998/EWD998Small.cfg new file mode 100644 index 00000000..57656f73 --- /dev/null +++ b/specifications/ewd998/EWD998Small.cfg @@ -0,0 +1,17 @@ +CONSTANTS + N = 3 + +CONSTRAINTS + StateConstraint + +SPECIFICATION + Spec + +INVARIANT + TerminationDetection + Inv + TypeOK + +\* PROPERTIES +\* \* Liveness +\* TDSpec From 28bb5dedc07265cc583559e1a3804d5dcb69c322 Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Mon, 30 Jan 2023 10:38:08 -0500 Subject: [PATCH 27/70] Removed TTrace specs from manifest Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/scripts/generate_manifest.py | 9 +++- manifest.json | 63 ---------------------------- 2 files changed, 7 insertions(+), 65 deletions(-) diff --git a/.github/scripts/generate_manifest.py b/.github/scripts/generate_manifest.py index dbafad33..e85efa12 100644 --- a/.github/scripts/generate_manifest.py +++ b/.github/scripts/generate_manifest.py @@ -15,9 +15,14 @@ def get_tla_files(dir): """ - Gets paths of all .tla files in the given directory. + Gets paths of all .tla files in the given directory, except for error + trace specs. """ - return [normpath(path) for path in glob.glob(f'{dir.path}/**/*.tla', recursive=True)] + return [ + normpath(path) + for path in glob.glob(f'{dir.path}/**/*.tla', recursive=True) + if '_TTrace_' not in path + ] def get_cfg_files(tla_path): """ diff --git a/manifest.json b/manifest.json index 9c5c662c..82969151 100644 --- a/manifest.json +++ b/manifest.json @@ -381,20 +381,6 @@ } ] }, - { - "path": "specifications/Huang/Huang_TTrace_1674862545.tla", - "communityDependencies": [], - "tlaLanguageVersion": 2, - "features": [], - "models": [] - }, - { - "path": "specifications/Huang/Huang_TTrace_1674914150.tla", - "communityDependencies": [], - "tlaLanguageVersion": 2, - "features": [], - "models": [] - } ] }, { @@ -1100,13 +1086,6 @@ } ] }, - { - "path": "specifications/SDP_Verification/SDP_Attack_New_Solution_Spec/MC_TTrace_1674864840.tla", - "communityDependencies": [], - "tlaLanguageVersion": 2, - "features": [], - "models": [] - }, { "path": "specifications/SDP_Verification/SDP_Attack_New_Solution_Spec/SPA_Attack_New.tla", "communityDependencies": [ @@ -1135,27 +1114,6 @@ } ] }, - { - "path": "specifications/SDP_Verification/SDP_Attack_Spec/MC_TTrace_1674864912.tla", - "communityDependencies": [], - "tlaLanguageVersion": 2, - "features": [], - "models": [] - }, - { - "path": "specifications/SDP_Verification/SDP_Attack_Spec/MC_TTrace_1674864941.tla", - "communityDependencies": [], - "tlaLanguageVersion": 2, - "features": [], - "models": [] - }, - { - "path": "specifications/SDP_Verification/SDP_Attack_Spec/MC_TTrace_1674914119.tla", - "communityDependencies": [], - "tlaLanguageVersion": 2, - "features": [], - "models": [] - }, { "path": "specifications/SDP_Verification/SDP_Attack_Spec/SPA_Attack.tla", "communityDependencies": [ @@ -3001,20 +2959,6 @@ } ] }, - { - "path": "specifications/ewd998/EWD998Chan_TTrace_1674863100.tla", - "communityDependencies": [], - "tlaLanguageVersion": 2, - "features": [], - "models": [] - }, - { - "path": "specifications/ewd998/EWD998Chan_TTrace_1674863118.tla", - "communityDependencies": [], - "tlaLanguageVersion": 2, - "features": [], - "models": [] - }, { "path": "specifications/ewd998/EWD998Chan_opts.tla", "communityDependencies": [ @@ -3025,13 +2969,6 @@ "features": [], "models": [] }, - { - "path": "specifications/ewd998/EWD998_TTrace_1674863819.tla", - "communityDependencies": [], - "tlaLanguageVersion": 2, - "features": [], - "models": [] - }, { "path": "specifications/ewd998/EWD998_anim.tla", "communityDependencies": [ From 31eea13cbc4bb6408b5b6e3a7c338b8da8f7346a Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Mon, 30 Jan 2023 12:32:22 -0500 Subject: [PATCH 28/70] Skip TE spec generation for some models Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/scripts/check_small_models.py | 7 ++- .github/workflows/CI.yml | 19 ++++---- manifest-schema.json | 2 +- manifest.json | 62 ++++++++++++++++++--------- 4 files changed, 58 insertions(+), 32 deletions(-) diff --git a/.github/scripts/check_small_models.py b/.github/scripts/check_small_models.py index 5bae925a..fdb66b3f 100644 --- a/.github/scripts/check_small_models.py +++ b/.github/scripts/check_small_models.py @@ -8,6 +8,7 @@ import json import logging import subprocess +import sys from timeit import default_timer as timer def parse_timespan(unparsed): @@ -46,10 +47,12 @@ def check_model(module_path, model_path, expected_result, expected_runtime, conf 'tlc2.TLC', module_path, '-config', model_path, - '-noGenerateSpecTE', # Remove when fixed: https://github.com/tlaplus/tlaplus/issues/785 '-workers', 'auto', - '-lncheck', 'final' + '-lncheck', 'final', + '-cleanup' ] + (['-deadlock'] if 'ignore deadlock' in config else []) + # Remove when fixed: https://github.com/tlaplus/tlaplus/issues/785 + + (['-noGenerateSpecTE'] if 'skip trace spec gen' in config else []) + (['-simulate', f'num={trace_count}'] if is_simulate else []), capture_output=True) end_time = timer() diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 6276f626..6476d1a5 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -10,9 +10,7 @@ jobs: validate-metadata: runs-on: ubuntu-latest env: - TSTLA_VERSION: 1.0.2 TLAPS_VERSION: 202210041448 - COMMUNITY_MODULES_VERSION: 202211012231 SCRIPT_DIR: .github/scripts steps: - name: Clone repo @@ -29,19 +27,20 @@ jobs: run: python $SCRIPT_DIR/check_manifest_files.py - name: Get tree-sitter-tlaplus run: | - wget https://github.com/tlaplus-community/tree-sitter-tlaplus/archive/refs/tags/v$TSTLA_VERSION.tar.gz - tar -xf v$TSTLA_VERSION.tar.gz - mv tree-sitter-tlaplus-$TSTLA_VERSION tree-sitter-tlaplus + wget https://github.com/tlaplus-community/tree-sitter-tlaplus/archive/main.tar.gz + tar -xf main.tar.gz + rm main.tar.gz + mv tree-sitter-tlaplus-main tree-sitter-tlaplus - name: Check manifest feature flags run: python $SCRIPT_DIR/check_manifest_features.py - name: Get TLA⁺ toolset, TLAPS, and community modules run: | wget https://nightly.tlapl.us/dist/tla2tools.jar wget https://github.com/tlaplus/CommunityModules/releases/latest/download/CommunityModules-deps.jar - wget https://github.com/tlaplus/CommunityModules/archive/refs/tags/$COMMUNITY_MODULES_VERSION.tar.gz - tar -xf $COMMUNITY_MODULES_VERSION.tar.gz - rm $COMMUNITY_MODULES_VERSION.tar.gz - mv CommunityModules-$COMMUNITY_MODULES_VERSION CommunityModules + wget https://github.com/tlaplus/CommunityModules/archive/master.tar.gz + tar -xf master.tar.gz + rm master.tar.gz + mv CommunityModules-master CommunityModules wget https://github.com/tlaplus/tlapm/archive/refs/tags/$TLAPS_VERSION.tar.gz tar -xf $TLAPS_VERSION.tar.gz rm $TLAPS_VERSION.tar.gz @@ -50,4 +49,6 @@ jobs: run: python $SCRIPT_DIR/parse_modules.py - name: Check small models run: python $SCRIPT_DIR/check_small_models.py + - name: Smoke test large models + run: python $SCRIPT_DIR/smoke_test_large_models.py diff --git a/manifest-schema.json b/manifest-schema.json index e2a65ac9..8f572305 100644 --- a/manifest-schema.json +++ b/manifest-schema.json @@ -57,7 +57,7 @@ "items": { "oneOf": [ { - "enum": ["ignore deadlock", "generate"] + "enum": ["ignore deadlock", "generate", "skip trace spec gen"] }, { "type": "object", diff --git a/manifest.json b/manifest.json index 82969151..2abb560d 100644 --- a/manifest.json +++ b/manifest.json @@ -371,7 +371,9 @@ "path": "specifications/Huang/Huang.cfg", "runtime": "00:00:30", "size": "small", - "config": ["ignore deadlock"], + "config": [ + "ignore deadlock" + ], "features": [ "alias", "liveness", @@ -380,7 +382,7 @@ "result": "success" } ] - }, + } ] }, { @@ -480,7 +482,9 @@ "path": "specifications/KnuthYao/SimKnuthYao.cfg", "runtime": "unknown", "size": "unknown", - "config": ["generate"], + "config": [ + "generate" + ], "features": [ "state constraint" ], @@ -745,7 +749,9 @@ "path": "specifications/N-Queens/Queens.toolbox/FourQueens/MC.cfg", "runtime": "00:00:01", "size": "small", - "config": ["ignore deadlock"], + "config": [ + "ignore deadlock" + ], "features": [], "result": "safety failure" } @@ -882,7 +888,9 @@ "path": "specifications/Paxos/MCConsensus.cfg", "runtime": "00:00:01", "size": "small", - "config": ["ignore deadlock"], + "config": [ + "ignore deadlock" + ], "features": [], "result": "success" } @@ -917,7 +925,9 @@ "path": "specifications/Paxos/MCVoting.cfg", "runtime": "00:00:01", "size": "small", - "config": ["ignore deadlock"], + "config": [ + "ignore deadlock" + ], "features": [ "liveness", "symmetry" @@ -1078,7 +1088,9 @@ "path": "specifications/SDP_Verification/SDP_Attack_New_Solution_Spec/MC.cfg", "runtime": "00:00:01", "size": "small", - "config": ["ignore deadlock"], + "config": [ + "ignore deadlock" + ], "features": [ "liveness" ], @@ -1106,7 +1118,9 @@ "path": "specifications/SDP_Verification/SDP_Attack_Spec/MC.cfg", "runtime": "00:00:05", "size": "small", - "config": ["ignore deadlock"], + "config": [ + "ignore deadlock" + ], "features": [ "liveness" ], @@ -1914,7 +1928,7 @@ "path": "specifications/SpecifyingSystems/TLC/ABCorrectness.cfg", "runtime": "00:00:01", "size": "small", - "config": [], + "config": ["skip trace spec gen"], "features": [], "result": "success" } @@ -1951,7 +1965,7 @@ "path": "specifications/SpecifyingSystems/TLC/MCAlternatingBit.cfg", "runtime": "00:00:01", "size": "small", - "config": [], + "config": ["skip trace spec gen"], "features": [ "liveness", "state constraint" @@ -2717,7 +2731,9 @@ "path": "specifications/ewd840/EWD840.cfg", "runtime": "00:00:01", "size": "small", - "config": ["ignore deadlock"], + "config": [ + "ignore deadlock" + ], "features": [], "result": "success" } @@ -2863,20 +2879,24 @@ "features": [], "models": [ { - "path": "specifications/ewd998/EWD998Small.cfg", - "runtime": "00:00:30", - "size": "small", - "config": ["ignore deadlock"], + "path": "specifications/ewd998/EWD998.cfg", + "runtime": "00:50:00", + "size": "large", + "config": [ + "ignore deadlock" + ], "features": [ "state constraint" ], "result": "success" }, { - "path": "specifications/ewd998/EWD998.cfg", - "runtime": "00:50:00", - "size": "large", - "config": ["ignore deadlock"], + "path": "specifications/ewd998/EWD998Small.cfg", + "runtime": "00:00:30", + "size": "small", + "config": [ + "ignore deadlock" + ], "features": [ "state constraint" ], @@ -2894,7 +2914,9 @@ "path": "specifications/ewd998/EWD998Chan.cfg", "runtime": "00:05:00", "size": "medium", - "config": ["ignore deadlock"], + "config": [ + "ignore deadlock" + ], "features": [ "liveness", "state constraint" From adae0506c4e0b5b34430f53d556a9b1b433d97ad Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Mon, 30 Jan 2023 13:50:52 -0500 Subject: [PATCH 29/70] Added smoke testing for large models Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/scripts/check_small_models.py | 29 +++--------- .github/scripts/smoke_test_large_models.py | 54 ++++++++++++++++++++++ .github/scripts/tla_utils.py | 41 ++++++++++++++++ .github/workflows/CI.yml | 2 +- manifest.json | 20 ++++---- 5 files changed, 112 insertions(+), 34 deletions(-) create mode 100644 .github/scripts/smoke_test_large_models.py create mode 100644 .github/scripts/tla_utils.py diff --git a/.github/scripts/check_small_models.py b/.github/scripts/check_small_models.py index fdb66b3f..a1fc5316 100644 --- a/.github/scripts/check_small_models.py +++ b/.github/scripts/check_small_models.py @@ -7,9 +7,8 @@ from datetime import datetime import json import logging -import subprocess -import sys from timeit import default_timer as timer +import tla_utils def parse_timespan(unparsed): pattern = '%H:%M:%S' @@ -34,28 +33,12 @@ def is_simulate_config(config): } def check_model(module_path, model_path, expected_result, expected_runtime, config): - is_simulate, trace_count = is_simulate_config(config) start_time = timer() - tlc = subprocess.run( - [ - 'java', - '-Dtlc2.TLC.stopAfter=60', - '-Dtlc2.TLC.ide=Github', - '-Dutil.ExecutionStatisticsCollector.id=abcdef60f238424fa70d124d0c77ffff', - '-XX:+UseParallelGC', - '-cp', 'tla2tools.jar', - 'tlc2.TLC', - module_path, - '-config', model_path, - '-workers', 'auto', - '-lncheck', 'final', - '-cleanup' - ] + (['-deadlock'] if 'ignore deadlock' in config else []) - # Remove when fixed: https://github.com/tlaplus/tlaplus/issues/785 - + (['-noGenerateSpecTE'] if 'skip trace spec gen' in config else []) - + (['-simulate', f'num={trace_count}'] if is_simulate else []), - capture_output=True) + tlc, timeout = tla_utils.check_model(module_path, model_path, config, 60, 70) end_time = timer() + if timeout: + logging.error(f'{model_path} hit hard timeout') + return False logging.info(f'{model_path} in {end_time - start_time:.1f}s vs. {expected_runtime.seconds}s expected') actual_result = tlc_result[tlc.returncode] if tlc.returncode in tlc_result else str(tlc.returncode) if expected_result != actual_result: @@ -83,5 +66,5 @@ def check_model(module_path, model_path, expected_result, expected_runtime, conf ) success = all([check_model(*model) for model in small_models]) -exit(0 if success else 0) +exit(0 if success else 1) diff --git a/.github/scripts/smoke_test_large_models.py b/.github/scripts/smoke_test_large_models.py new file mode 100644 index 00000000..eb025004 --- /dev/null +++ b/.github/scripts/smoke_test_large_models.py @@ -0,0 +1,54 @@ +""" +Smoke-test all models not marked as size "small" in the manifest. This +entails running them for five seconds to ensure they can actually start +and work with the spec they're supposed to be modeling. +""" + +import json +import logging +import tla_utils + +def check_model(module_path, model_path, config): + tlc, timeout = tla_utils.check_model(module_path, model_path, config, 5, 10) + if timeout: + # Return True here; see https://github.com/tlaplus/tlaplus/issues/788 + logging.info(f'{model_path} hit hard timeout') + return True + logging.info(model_path) + if 0 != tlc.returncode: + logging.error(f'Model {model_path} expected error code 0 but got {tlc.returncode}') + logging.error(tlc.stdout.decode('utf-8')) + return False + return True + +logging.basicConfig(level=logging.INFO) + +manifest = None +with open('manifest.json', 'rt') as manifest_file: + manifest = json.load(manifest_file) + +skip_models = [ + # SimKnuthYao requires certain number of states to have been generated + # before termination or else it fails. This makes it not amenable to + # smoke testing. + 'specifications/KnuthYao/SimKnuthYao.cfg', + # These should all work; it is a bug that they do not + 'specifications/SpecifyingSystems/AdvancedExamples/MCInnerSerial.cfg', + 'specifications/ewd426/SimTokenRing.cfg', + 'specifications/ewd840/EWD840_json.cfg', + 'specifications/ewd998/AsyncTerminationDetection_proof.cfg', + 'specifications/ewd998/SmokeEWD998.cfg' +] + +large_models = [ + (module['path'], model['path'], model['config']) + for spec in manifest['specifications'] + for module in spec['modules'] + for model in module['models'] + if model['size'] != 'small' + and model['path'] not in skip_models +] + +success = all([check_model(*model) for model in large_models]) +exit(0 if success else 1) + diff --git a/.github/scripts/tla_utils.py b/.github/scripts/tla_utils.py new file mode 100644 index 00000000..eeb7c9ce --- /dev/null +++ b/.github/scripts/tla_utils.py @@ -0,0 +1,41 @@ +import subprocess + +def is_simulate_config(config): + sim_options = [ + option for option in config + if type(option) is dict + and 'simulate' in option + ] + if any(sim_options): + return (True, sim_options[0]['simulate']['traceCount']) + else: + return (False, 0) + +def check_model(module_path, model_path, config, soft_timeout, hard_timeout): + is_simulate, trace_count = is_simulate_config(config) + try: + tlc = subprocess.run([ + 'java', + f'-Dtlc2.TLC.stopAfter={soft_timeout}', + '-Dtlc2.TLC.ide=Github', + '-Dutil.ExecutionStatisticsCollector.id=abcdef60f238424fa70d124d0c77ffff', + '-XX:+UseParallelGC', + '-cp', 'tla2tools.jar', + 'tlc2.TLC', + module_path, + '-config', model_path, + '-workers', 'auto', + '-lncheck', 'final', + '-cleanup' + ] + (['-deadlock'] if 'ignore deadlock' in config else []) + # Remove when fixed: https://github.com/tlaplus/tlaplus/issues/785 + + (['-noGenerateSpecTE'] if 'skip trace spec gen' in config else []) + + (['-generate'] if 'generate' in config else []) + + (['-simulate', f'num={trace_count}'] if is_simulate else []), + capture_output=True, + timeout=hard_timeout + ) + return (tlc, False) + except subprocess.TimeoutExpired: + return (None, True) + diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 6476d1a5..0ecafc22 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -49,6 +49,6 @@ jobs: run: python $SCRIPT_DIR/parse_modules.py - name: Check small models run: python $SCRIPT_DIR/check_small_models.py - - name: Smoke test large models + - name: Smoke-test large models run: python $SCRIPT_DIR/smoke_test_large_models.py diff --git a/manifest.json b/manifest.json index 2abb560d..da1c8a95 100644 --- a/manifest.json +++ b/manifest.json @@ -90,7 +90,7 @@ "models": [ { "path": "specifications/CarTalkPuzzle/CarTalkPuzzle.toolbox/Model_2/MC.cfg", - "runtime": "00:00:01", + "runtime": "00:00:05", "size": "small", "config": [], "features": [], @@ -369,8 +369,8 @@ "models": [ { "path": "specifications/Huang/Huang.cfg", - "runtime": "00:00:30", - "size": "small", + "runtime": "00:00:40", + "size": "medium", "config": [ "ignore deadlock" ], @@ -710,7 +710,7 @@ }, { "path": "specifications/MultiCarElevator/ElevatorSafetySmall.cfg", - "runtime": "00:00:10", + "runtime": "00:00:15", "size": "small", "config": [], "features": [], @@ -1195,7 +1195,7 @@ "models": [ { "path": "specifications/SlidingPuzzles/SlidingPuzzles.cfg", - "runtime": "00:00:10", + "runtime": "00:00:05", "size": "small", "config": [], "features": [], @@ -1241,7 +1241,7 @@ }, { "path": "specifications/SlushProtocol/SlushSmall.cfg", - "runtime": "00:00:30", + "runtime": "00:00:15", "size": "small", "config": [], "features": [], @@ -1405,7 +1405,7 @@ "models": [ { "path": "specifications/SpecifyingSystems/AsynchronousInterface/Channel.cfg", - "runtime": "00:00:10", + "runtime": "00:00:01", "size": "small", "config": [], "features": [], @@ -1713,7 +1713,7 @@ "models": [ { "path": "specifications/SpecifyingSystems/Liveness/MCLiveWriteThroughCache.cfg", - "runtime": "00:00:10", + "runtime": "00:00:05", "size": "small", "config": [], "features": [ @@ -2178,7 +2178,7 @@ "models": [ { "path": "specifications/allocator/AllocatorImplementation.cfg", - "runtime": "00:00:30", + "runtime": "00:00:15", "size": "small", "config": [], "features": [ @@ -2678,7 +2678,7 @@ "config": [ { "simulate": { - "traceCount": 1 + "traceCount": 100 } } ], From 1524b0fd93ac6fabfddca1b12fb98539c6207f4f Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Mon, 30 Jan 2023 13:55:23 -0500 Subject: [PATCH 30/70] Rebased, remove skip TE spec option Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/scripts/tla_utils.py | 2 -- manifest-schema.json | 2 +- manifest.json | 4 ++-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/scripts/tla_utils.py b/.github/scripts/tla_utils.py index eeb7c9ce..3f49336f 100644 --- a/.github/scripts/tla_utils.py +++ b/.github/scripts/tla_utils.py @@ -28,8 +28,6 @@ def check_model(module_path, model_path, config, soft_timeout, hard_timeout): '-lncheck', 'final', '-cleanup' ] + (['-deadlock'] if 'ignore deadlock' in config else []) - # Remove when fixed: https://github.com/tlaplus/tlaplus/issues/785 - + (['-noGenerateSpecTE'] if 'skip trace spec gen' in config else []) + (['-generate'] if 'generate' in config else []) + (['-simulate', f'num={trace_count}'] if is_simulate else []), capture_output=True, diff --git a/manifest-schema.json b/manifest-schema.json index 8f572305..e2a65ac9 100644 --- a/manifest-schema.json +++ b/manifest-schema.json @@ -57,7 +57,7 @@ "items": { "oneOf": [ { - "enum": ["ignore deadlock", "generate", "skip trace spec gen"] + "enum": ["ignore deadlock", "generate"] }, { "type": "object", diff --git a/manifest.json b/manifest.json index da1c8a95..21b024d4 100644 --- a/manifest.json +++ b/manifest.json @@ -1928,7 +1928,7 @@ "path": "specifications/SpecifyingSystems/TLC/ABCorrectness.cfg", "runtime": "00:00:01", "size": "small", - "config": ["skip trace spec gen"], + "config": [], "features": [], "result": "success" } @@ -1965,7 +1965,7 @@ "path": "specifications/SpecifyingSystems/TLC/MCAlternatingBit.cfg", "runtime": "00:00:01", "size": "small", - "config": ["skip trace spec gen"], + "config": [], "features": [ "liveness", "state constraint" From 7160df0344d5612866926c80b05af36dde7cf1df Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Mon, 30 Jan 2023 17:05:52 -0500 Subject: [PATCH 31/70] Fixed smoke tests Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/scripts/check_manifest_files.py | 9 +++++++-- .github/scripts/check_small_models.py | 6 +++--- .github/scripts/smoke_test_large_models.py | 17 ++++++++++------- .github/scripts/tla_utils.py | 7 +++---- manifest.json | 21 +++++++-------------- 5 files changed, 30 insertions(+), 30 deletions(-) diff --git a/.github/scripts/check_manifest_files.py b/.github/scripts/check_manifest_files.py index 35ff8784..7fcf64ab 100644 --- a/.github/scripts/check_manifest_files.py +++ b/.github/scripts/check_manifest_files.py @@ -24,8 +24,13 @@ cfg_mf_paths = set(cfg_mf_paths_cnt) # Get paths of all .tla and .cfg files in the specifications dir -tla_fs_paths = set([normpath(path) for path in glob.glob(f"./specifications/**/*.tla", recursive=True)]) -cfg_fs_paths = set([normpath(path) for path in glob.glob(f"./specifications/**/*.cfg", recursive=True)]) +tla_fs_paths = set([ + normpath(path) for path in glob.glob(f"./specifications/**/*.tla", recursive=True) + if '_TTrace_' not in path +]) +cfg_fs_paths = set([ + normpath(path) for path in glob.glob(f"./specifications/**/*.cfg", recursive=True) +]) success = True diff --git a/.github/scripts/check_small_models.py b/.github/scripts/check_small_models.py index a1fc5316..abc96e65 100644 --- a/.github/scripts/check_small_models.py +++ b/.github/scripts/check_small_models.py @@ -34,10 +34,10 @@ def is_simulate_config(config): def check_model(module_path, model_path, expected_result, expected_runtime, config): start_time = timer() - tlc, timeout = tla_utils.check_model(module_path, model_path, config, 60, 70) + tlc, hit_timeout = tla_utils.check_model('tla2tools.jar', module_path, model_path, config, 60) end_time = timer() - if timeout: - logging.error(f'{model_path} hit hard timeout') + if hit_timeout: + logging.error(f'{model_path} timed out') return False logging.info(f'{model_path} in {end_time - start_time:.1f}s vs. {expected_runtime.seconds}s expected') actual_result = tlc_result[tlc.returncode] if tlc.returncode in tlc_result else str(tlc.returncode) diff --git a/.github/scripts/smoke_test_large_models.py b/.github/scripts/smoke_test_large_models.py index eb025004..dc519f64 100644 --- a/.github/scripts/smoke_test_large_models.py +++ b/.github/scripts/smoke_test_large_models.py @@ -9,12 +9,10 @@ import tla_utils def check_model(module_path, model_path, config): - tlc, timeout = tla_utils.check_model(module_path, model_path, config, 5, 10) - if timeout: - # Return True here; see https://github.com/tlaplus/tlaplus/issues/788 - logging.info(f'{model_path} hit hard timeout') - return True logging.info(model_path) + tlc, hit_timeout = tla_utils.check_model('tla2tools.jar', module_path, model_path, config, 5) + if hit_timeout: + return True if 0 != tlc.returncode: logging.error(f'Model {model_path} expected error code 0 but got {tlc.returncode}') logging.error(tlc.stdout.decode('utf-8')) @@ -32,11 +30,16 @@ def check_model(module_path, model_path, config): # before termination or else it fails. This makes it not amenable to # smoke testing. 'specifications/KnuthYao/SimKnuthYao.cfg', - # These should all work; it is a bug that they do not + + # The following are bugs that should be fixed: + + # Attempted to access index 0 of tuple <<>> 'specifications/SpecifyingSystems/AdvancedExamples/MCInnerSerial.cfg', + # Attempted to select nonexistent field "traces" from record 'specifications/ewd426/SimTokenRing.cfg', - 'specifications/ewd840/EWD840_json.cfg', + # Cannot find TLAPS 'specifications/ewd998/AsyncTerminationDetection_proof.cfg', + # Property is violated by the initial state 'specifications/ewd998/SmokeEWD998.cfg' ] diff --git a/.github/scripts/tla_utils.py b/.github/scripts/tla_utils.py index 3f49336f..aab3d813 100644 --- a/.github/scripts/tla_utils.py +++ b/.github/scripts/tla_utils.py @@ -11,16 +11,15 @@ def is_simulate_config(config): else: return (False, 0) -def check_model(module_path, model_path, config, soft_timeout, hard_timeout): +def check_model(jar_path, module_path, model_path, config, timeout): is_simulate, trace_count = is_simulate_config(config) try: tlc = subprocess.run([ 'java', - f'-Dtlc2.TLC.stopAfter={soft_timeout}', '-Dtlc2.TLC.ide=Github', '-Dutil.ExecutionStatisticsCollector.id=abcdef60f238424fa70d124d0c77ffff', '-XX:+UseParallelGC', - '-cp', 'tla2tools.jar', + '-cp', jar_path, 'tlc2.TLC', module_path, '-config', model_path, @@ -31,7 +30,7 @@ def check_model(module_path, model_path, config, soft_timeout, hard_timeout): + (['-generate'] if 'generate' in config else []) + (['-simulate', f'num={trace_count}'] if is_simulate else []), capture_output=True, - timeout=hard_timeout + timeout=timeout ) return (tlc, False) except subprocess.TimeoutExpired: diff --git a/manifest.json b/manifest.json index 21b024d4..f0551448 100644 --- a/manifest.json +++ b/manifest.json @@ -1158,13 +1158,13 @@ "models": [ { "path": "specifications/SingleLaneBridge/MC.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:00:10", + "size": "small", "config": [], "features": [ "liveness" ], - "result": "unknown" + "result": "success" } ] }, @@ -1973,13 +1973,6 @@ "result": "success" } ] - }, - { - "path": "specifications/SpecifyingSystems/TLC/TLC.tla", - "communityDependencies": [], - "tlaLanguageVersion": 2, - "features": [], - "models": [] } ] }, @@ -2773,11 +2766,11 @@ "models": [ { "path": "specifications/ewd840/EWD840_json.cfg", - "runtime": "unknown", - "size": "unknown", - "config": [], + "runtime": "00:00:01", + "size": "small", + "config": ["ignore deadlock"], "features": [], - "result": "unknown" + "result": "success" } ] }, From b93595fb7fa353171f16bddbc4811933d731a092 Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Mon, 30 Jan 2023 17:16:51 -0500 Subject: [PATCH 32/70] Removed superseded old CI workflow Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/workflows/main.yml | 19 ------------------- .github/workflows/run.sh | 12 ------------ 2 files changed, 31 deletions(-) delete mode 100644 .github/workflows/main.yml delete mode 100755 .github/workflows/run.sh diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index a3a07ea0..00000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: CI -on: - push: - branches: - - master - workflow_dispatch: - workflow_call: - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Get (nightly) TLC - run: wget https://nightly.tlapl.us/dist/tla2tools.jar - - name: Get (nightly) CommunityModules - run: wget https://github.com/tlaplus/CommunityModules/releases/latest/download/CommunityModules-deps.jar - - name: Run - run: /bin/bash .github/workflows/run.sh diff --git a/.github/workflows/run.sh b/.github/workflows/run.sh deleted file mode 100755 index 0c279f71..00000000 --- a/.github/workflows/run.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash - -TLC_COMMAND="java -Dtlc2.TLC.stopAfter=180 -Dtlc2.TLC.ide=Github -Dutil.ExecutionStatisticsCollector.id=abcdef60f238424fa70d124d0c77ffff -cp tla2tools.jar tlc2.TLC -workers auto -lncheck final -tool -deadlock" - -## This spec used to be accepted by Apalache, but since Apalache has started to require type annotations for all variables. -## https://github.com/tlaplus/Examples/pull/31#issuecomment-796354291 -#echo Check MCInnerSerial -#$TLC_COMMAND specifications/SpecifyingSystems/AdvancedExamples/MCInnerSerial -echo Check EWD840_json -sed -i '/^SendMsg/{n;d;}' specifications/ewd840/EWD840.tla ## Cause RealInv to be violated (see EWD840_json.tla) -$TLC_COMMAND specifications/ewd840/EWD840_json - From a034ba6ea5f42535de558c316f1d76b156c2f52d Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Mon, 30 Jan 2023 17:21:58 -0500 Subject: [PATCH 33/70] Validate specs and models on all platforms Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/workflows/CI.yml | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 0ecafc22..5d9afa20 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -6,12 +6,14 @@ on: pull_request: branches: - master + +env: + SCRIPT_DIR: .github/scripts + jobs: + validate-metadata: runs-on: ubuntu-latest - env: - TLAPS_VERSION: 202210041448 - SCRIPT_DIR: .github/scripts steps: - name: Clone repo uses: actions/checkout@v2 @@ -33,6 +35,16 @@ jobs: mv tree-sitter-tlaplus-main tree-sitter-tlaplus - name: Check manifest feature flags run: python $SCRIPT_DIR/check_manifest_features.py + + validate-specs-and-models: + runs-on: ${{ matrix.os }} + env: + TLAPS_VERSION: 202210041448 + strategy: + matrix: + os: [windows-latest, ubuntu-latest, macos-latest] + fail-fast: false + steps: - name: Get TLA⁺ toolset, TLAPS, and community modules run: | wget https://nightly.tlapl.us/dist/tla2tools.jar From f24c5c0bd8f46c161bd8c0374ce1ab43c52873d5 Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Mon, 30 Jan 2023 17:23:56 -0500 Subject: [PATCH 34/70] Clone repo in CI Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/workflows/CI.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 5d9afa20..12b2fa00 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -45,6 +45,12 @@ jobs: os: [windows-latest, ubuntu-latest, macos-latest] fail-fast: false steps: + - name: Clone repo + uses: actions/checkout@v2 + - name: Install python + uses: actions/setup-python@v4 + with: + python-version: '3.11' - name: Get TLA⁺ toolset, TLAPS, and community modules run: | wget https://nightly.tlapl.us/dist/tla2tools.jar From 54be317a4a88a0438cf356336c3bbcbe3dd9d1a1 Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Mon, 30 Jan 2023 17:30:35 -0500 Subject: [PATCH 35/70] Add CI step to install Java Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/workflows/CI.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 12b2fa00..b8f1fdf1 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -47,11 +47,17 @@ jobs: steps: - name: Clone repo uses: actions/checkout@v2 - - name: Install python + - name: Install Python uses: actions/setup-python@v4 with: python-version: '3.11' + - name: Install Java + uses: actions/setup-java@v3 + with: + distribution: adopt + java-version: 17 - name: Get TLA⁺ toolset, TLAPS, and community modules + shell: bash run: | wget https://nightly.tlapl.us/dist/tla2tools.jar wget https://github.com/tlaplus/CommunityModules/releases/latest/download/CommunityModules-deps.jar From c5144bd47487073098835d2a86b6164520ef5e51 Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Mon, 30 Jan 2023 17:42:32 -0500 Subject: [PATCH 36/70] Use msys2 shell for windows Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/workflows/CI.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index b8f1fdf1..49c76925 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -42,7 +42,10 @@ jobs: TLAPS_VERSION: 202210041448 strategy: matrix: - os: [windows-latest, ubuntu-latest, macos-latest] + include: + - { os: windows-latest, shell: msys2 } + - { os: ubuntu-latest, shell: bash } + - { os: macos-latest, shell: bash } fail-fast: false steps: - name: Clone repo @@ -57,7 +60,7 @@ jobs: distribution: adopt java-version: 17 - name: Get TLA⁺ toolset, TLAPS, and community modules - shell: bash + shell: ${{ matrix.shell }} run: | wget https://nightly.tlapl.us/dist/tla2tools.jar wget https://github.com/tlaplus/CommunityModules/releases/latest/download/CommunityModules-deps.jar From b50e614d4cb2b508f59f6cc98890b1a94d0adba4 Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Mon, 30 Jan 2023 17:45:16 -0500 Subject: [PATCH 37/70] Trying this again Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/workflows/CI.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 49c76925..fea09169 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -47,6 +47,9 @@ jobs: - { os: ubuntu-latest, shell: bash } - { os: macos-latest, shell: bash } fail-fast: false + defaults: + run: + shell: ${{ matrix.shell }} steps: - name: Clone repo uses: actions/checkout@v2 @@ -60,7 +63,6 @@ jobs: distribution: adopt java-version: 17 - name: Get TLA⁺ toolset, TLAPS, and community modules - shell: ${{ matrix.shell }} run: | wget https://nightly.tlapl.us/dist/tla2tools.jar wget https://github.com/tlaplus/CommunityModules/releases/latest/download/CommunityModules-deps.jar From a89fdce05e7ed7747024b62dcb7f8ea0ebd2065a Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Mon, 30 Jan 2023 17:49:24 -0500 Subject: [PATCH 38/70] CI struggles Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/workflows/CI.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index fea09169..eb55e176 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -49,7 +49,7 @@ jobs: fail-fast: false defaults: run: - shell: ${{ matrix.shell }} + shell: ${{ matrix.shell }} {0} steps: - name: Clone repo uses: actions/checkout@v2 From 172a85024419c58210ae797c36a07cccd6555a45 Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Mon, 30 Jan 2023 17:56:48 -0500 Subject: [PATCH 39/70] Setup msys2 Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/workflows/CI.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index eb55e176..213e0192 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -13,6 +13,7 @@ env: jobs: validate-metadata: + name: Metadata Validation runs-on: ubuntu-latest steps: - name: Clone repo @@ -37,6 +38,7 @@ jobs: run: python $SCRIPT_DIR/check_manifest_features.py validate-specs-and-models: + name: Spec & Model Validation runs-on: ${{ matrix.os }} env: TLAPS_VERSION: 202210041448 @@ -62,6 +64,8 @@ jobs: with: distribution: adopt java-version: 17 + - uses: msys2/setup-msys2@v2 + if: matrix.os == 'windows-latest' - name: Get TLA⁺ toolset, TLAPS, and community modules run: | wget https://nightly.tlapl.us/dist/tla2tools.jar From 24e328b542bf475b78b49bfbf9aee294b7c616fe Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Mon, 30 Jan 2023 18:10:26 -0500 Subject: [PATCH 40/70] Don't use https for nightly.tlapl.us Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/scripts/smoke_test_large_models.py | 2 +- .github/workflows/CI.yml | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/scripts/smoke_test_large_models.py b/.github/scripts/smoke_test_large_models.py index dc519f64..c77072b4 100644 --- a/.github/scripts/smoke_test_large_models.py +++ b/.github/scripts/smoke_test_large_models.py @@ -37,7 +37,7 @@ def check_model(module_path, model_path, config): 'specifications/SpecifyingSystems/AdvancedExamples/MCInnerSerial.cfg', # Attempted to select nonexistent field "traces" from record 'specifications/ewd426/SimTokenRing.cfg', - # Cannot find TLAPS + # Initial error cannot find TLAPS; if fixed, cannot find property "Stable" 'specifications/ewd998/AsyncTerminationDetection_proof.cfg', # Property is violated by the initial state 'specifications/ewd998/SmokeEWD998.cfg' diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 213e0192..a015c456 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -39,6 +39,7 @@ jobs: validate-specs-and-models: name: Spec & Model Validation + needs: validate-metadata runs-on: ${{ matrix.os }} env: TLAPS_VERSION: 202210041448 @@ -64,11 +65,12 @@ jobs: with: distribution: adopt java-version: 17 - - uses: msys2/setup-msys2@v2 + - name: Install MSYS2 on Windows + uses: msys2/setup-msys2@v2 if: matrix.os == 'windows-latest' - name: Get TLA⁺ toolset, TLAPS, and community modules run: | - wget https://nightly.tlapl.us/dist/tla2tools.jar + wget http://nightly.tlapl.us/dist/tla2tools.jar wget https://github.com/tlaplus/CommunityModules/releases/latest/download/CommunityModules-deps.jar wget https://github.com/tlaplus/CommunityModules/archive/master.tar.gz tar -xf master.tar.gz From 318311711f94af8748add5e6377791e1dddc2630 Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Mon, 30 Jan 2023 18:18:52 -0500 Subject: [PATCH 41/70] Fix symbolic links in tar Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/scripts/parse_modules.py | 4 ++-- .github/workflows/CI.yml | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/scripts/parse_modules.py b/.github/scripts/parse_modules.py index 573452a1..6b106423 100644 --- a/.github/scripts/parse_modules.py +++ b/.github/scripts/parse_modules.py @@ -5,7 +5,7 @@ from concurrent.futures import ThreadPoolExecutor import logging import json -from os import cpu_count +from os import cpu_count, pathsep from os.path import dirname import subprocess @@ -20,7 +20,7 @@ def parse_module(module_tuple): path, using_proofs = module_tuple logging.info(path) # If using proofs, TLAPS modules override community modules - search_paths = ':'.join( + search_paths = pathsep.join( [dirname(path)] + ([tlaps_modules] if using_proofs else []) + [community_modules] diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index a015c456..2bde9aec 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -70,6 +70,7 @@ jobs: if: matrix.os == 'windows-latest' - name: Get TLA⁺ toolset, TLAPS, and community modules run: | + export MSYS=winsymlinks:lnk wget http://nightly.tlapl.us/dist/tla2tools.jar wget https://github.com/tlaplus/CommunityModules/releases/latest/download/CommunityModules-deps.jar wget https://github.com/tlaplus/CommunityModules/archive/master.tar.gz From 06248eeaa8c37e16ceba8d1598ccb8f18f79fcbe Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Mon, 30 Jan 2023 19:05:54 -0500 Subject: [PATCH 42/70] Only use MSYS2 to install tools Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/workflows/CI.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 2bde9aec..278b4c18 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -43,16 +43,17 @@ jobs: runs-on: ${{ matrix.os }} env: TLAPS_VERSION: 202210041448 + TOOL_INSTALL_SHELL: ${{ matrix.shell }} {0} strategy: matrix: include: - { os: windows-latest, shell: msys2 } - { os: ubuntu-latest, shell: bash } - { os: macos-latest, shell: bash } - fail-fast: false + fail-fast: true defaults: run: - shell: ${{ matrix.shell }} {0} + shell: bash steps: - name: Clone repo uses: actions/checkout@v2 @@ -69,7 +70,10 @@ jobs: uses: msys2/setup-msys2@v2 if: matrix.os == 'windows-latest' - name: Get TLA⁺ toolset, TLAPS, and community modules + shell: $TOOL_INSTALL_SHELL run: | + # Fix tar symbolic link issues on Windows; see: + # https://github.com/msys2/MSYS2-packages/issues/1216 export MSYS=winsymlinks:lnk wget http://nightly.tlapl.us/dist/tla2tools.jar wget https://github.com/tlaplus/CommunityModules/releases/latest/download/CommunityModules-deps.jar From 085800c8837fa1328ef85c84f857055beeefa1e3 Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Mon, 30 Jan 2023 19:12:53 -0500 Subject: [PATCH 43/70] Use -error-codes flag for SANY Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/scripts/parse_modules.py | 9 +++++---- .github/workflows/CI.yml | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/scripts/parse_modules.py b/.github/scripts/parse_modules.py index 6b106423..db805409 100644 --- a/.github/scripts/parse_modules.py +++ b/.github/scripts/parse_modules.py @@ -29,11 +29,12 @@ def parse_module(module_tuple): 'java', f'-DTLA-Library={search_paths}', '-cp', 'tla2tools.jar', - 'tla2sany.SANY', path, + 'tla2sany.SANY', + '-error-codes', + path ], capture_output=True) - sany_output = sany.stdout.decode('utf-8') - if sany.returncode != 0 or 'Error' in sany_output or 'error' in sany_output: - logging.error(sany_output) + if sany.returncode != 0: + logging.error(sany.stdout.decode('utf-8')) return False return True diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 278b4c18..e594f4e1 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -70,7 +70,7 @@ jobs: uses: msys2/setup-msys2@v2 if: matrix.os == 'windows-latest' - name: Get TLA⁺ toolset, TLAPS, and community modules - shell: $TOOL_INSTALL_SHELL + shell: ${{ env.TOOL_INSTALL_SHELL }} run: | # Fix tar symbolic link issues on Windows; see: # https://github.com/msys2/MSYS2-packages/issues/1216 From 3e5f74bce17da23ce11b587c9866f90c33fa35c7 Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Mon, 30 Jan 2023 19:16:39 -0500 Subject: [PATCH 44/70] CI strugs Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/workflows/CI.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index e594f4e1..a2dfd17b 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -43,17 +43,16 @@ jobs: runs-on: ${{ matrix.os }} env: TLAPS_VERSION: 202210041448 - TOOL_INSTALL_SHELL: ${{ matrix.shell }} {0} strategy: matrix: include: - { os: windows-latest, shell: msys2 } - { os: ubuntu-latest, shell: bash } - { os: macos-latest, shell: bash } - fail-fast: true + fail-fast: false defaults: run: - shell: bash + shell: ${{ matrix.shell }} {0} steps: - name: Clone repo uses: actions/checkout@v2 @@ -70,7 +69,6 @@ jobs: uses: msys2/setup-msys2@v2 if: matrix.os == 'windows-latest' - name: Get TLA⁺ toolset, TLAPS, and community modules - shell: ${{ env.TOOL_INSTALL_SHELL }} run: | # Fix tar symbolic link issues on Windows; see: # https://github.com/msys2/MSYS2-packages/issues/1216 @@ -86,9 +84,12 @@ jobs: rm $TLAPS_VERSION.tar.gz mv tlapm-$TLAPS_VERSION tlapm - name: Parse all modules + shell: bash run: python $SCRIPT_DIR/parse_modules.py - name: Check small models + shell: bash run: python $SCRIPT_DIR/check_small_models.py - name: Smoke-test large models + shell: bash run: python $SCRIPT_DIR/smoke_test_large_models.py From fc57fc2c792c13ef47594d614a50bfadd1aa8ea9 Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Mon, 30 Jan 2023 19:42:41 -0500 Subject: [PATCH 45/70] Try to fix unicode load issue on windows Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/scripts/check_manifest_features.py | 5 ++--- .github/scripts/check_manifest_files.py | 5 ++--- .github/scripts/check_manifest_schema.py | 10 +++------- .github/scripts/check_small_models.py | 5 +---- .github/scripts/generate_manifest.py | 5 ++--- .github/scripts/parse_modules.py | 6 ++---- .github/scripts/smoke_test_large_models.py | 5 +---- .github/scripts/tla_utils.py | 11 +++++++++++ 8 files changed, 24 insertions(+), 28 deletions(-) diff --git a/.github/scripts/check_manifest_features.py b/.github/scripts/check_manifest_features.py index 0834d8c7..06538bd8 100644 --- a/.github/scripts/check_manifest_features.py +++ b/.github/scripts/check_manifest_features.py @@ -10,6 +10,7 @@ import glob import json from os.path import basename, dirname, splitext +import tla_utils from tree_sitter import Language, Parser # Builds the tree-sitter-tlaplus grammar and constructs the parser @@ -173,9 +174,7 @@ def get_community_module_imports(path): return get_community_imports(tree, text, dir, has_proof) if __name__ == '__main__': - manifest = None - with open('manifest.json', 'rt') as manifest_file: - manifest = json.load(manifest_file) + manifest = tla_utils.load_manifest() # Validates every field of the manifest that can be validated. success = True diff --git a/.github/scripts/check_manifest_files.py b/.github/scripts/check_manifest_files.py index 7fcf64ab..ee532342 100644 --- a/.github/scripts/check_manifest_files.py +++ b/.github/scripts/check_manifest_files.py @@ -8,10 +8,9 @@ import json from os.path import normpath import glob +import tla_utils -manifest = None -with open('manifest.json', 'rt') as manifest_file: - manifest = json.load(manifest_file) +manifest = tla_utils.load_manifest() module_lists = [spec["modules"] for spec in manifest["specifications"]] modules = [module for module_list in module_lists for module in module_list] diff --git a/.github/scripts/check_manifest_schema.py b/.github/scripts/check_manifest_schema.py index b6e9f664..c1d22bef 100644 --- a/.github/scripts/check_manifest_schema.py +++ b/.github/scripts/check_manifest_schema.py @@ -7,14 +7,10 @@ import json from jsonschema import validate +import tla_utils -schema = None -with open('manifest-schema.json', 'rt') as schema_file: - schema = json.load(schema_file) - -manifest = None -with open('manifest.json', 'rt') as manifest_file: - manifest = json.load(manifest_file) +schema = tla_utils.load_schema() +manifest = tla_utils.load_manifest() result = validate(instance=manifest, schema=schema) if None == result: diff --git a/.github/scripts/check_small_models.py b/.github/scripts/check_small_models.py index abc96e65..d961d7ae 100644 --- a/.github/scripts/check_small_models.py +++ b/.github/scripts/check_small_models.py @@ -5,7 +5,6 @@ """ from datetime import datetime -import json import logging from timeit import default_timer as timer import tla_utils @@ -49,9 +48,7 @@ def check_model(module_path, model_path, expected_result, expected_runtime, conf logging.basicConfig(level=logging.INFO) -manifest = None -with open('manifest.json', 'rt') as manifest_file: - manifest = json.load(manifest_file) +manifest = tla_utils.load_manifest() # Ensure longest-running modules go first small_models = sorted( diff --git a/.github/scripts/generate_manifest.py b/.github/scripts/generate_manifest.py index e85efa12..e59d9ac4 100644 --- a/.github/scripts/generate_manifest.py +++ b/.github/scripts/generate_manifest.py @@ -12,6 +12,7 @@ import os from os.path import basename, dirname, join, normpath, splitext import glob +import tla_utils def get_tla_files(dir): """ @@ -113,9 +114,7 @@ def integrate_model_info(old_model, new_model): for field in fields: new_model[field] = old_model[field] -old_manifest = None -with open('manifest.json', 'r') as old_manifest_file: - old_manifest = json.load(old_manifest_file) +old_manifest = tla_utils.load_manifest() for old_spec in old_manifest['specifications']: new_spec = find_corresponding_spec(old_spec, new_manifest) diff --git a/.github/scripts/parse_modules.py b/.github/scripts/parse_modules.py index db805409..117133b3 100644 --- a/.github/scripts/parse_modules.py +++ b/.github/scripts/parse_modules.py @@ -4,10 +4,10 @@ from concurrent.futures import ThreadPoolExecutor import logging -import json from os import cpu_count, pathsep from os.path import dirname import subprocess +import tla_utils tlaps_modules = 'tlapm/library' community_modules = 'CommunityModules/modules' @@ -38,9 +38,7 @@ def parse_module(module_tuple): return False return True -manifest = None -with open('manifest.json', 'rt') as manifest_file: - manifest = json.load(manifest_file) +manifest = tla_utils.load_manifest() # Skip these specs and modules as they do not currently parse skip_specs = ['specifications/ewd998'] diff --git a/.github/scripts/smoke_test_large_models.py b/.github/scripts/smoke_test_large_models.py index c77072b4..a85426b5 100644 --- a/.github/scripts/smoke_test_large_models.py +++ b/.github/scripts/smoke_test_large_models.py @@ -4,7 +4,6 @@ and work with the spec they're supposed to be modeling. """ -import json import logging import tla_utils @@ -21,9 +20,7 @@ def check_model(module_path, model_path, config): logging.basicConfig(level=logging.INFO) -manifest = None -with open('manifest.json', 'rt') as manifest_file: - manifest = json.load(manifest_file) +manifest = tla_utils.load_manifest() skip_models = [ # SimKnuthYao requires certain number of states to have been generated diff --git a/.github/scripts/tla_utils.py b/.github/scripts/tla_utils.py index aab3d813..e0543a6d 100644 --- a/.github/scripts/tla_utils.py +++ b/.github/scripts/tla_utils.py @@ -1,5 +1,16 @@ +import json import subprocess +def load_json(path): + with open(path, 'r', encoding='utf8') as file: + return json.load(file) + +def load_manifest(): + return load_json('manifest.json') + +def load_schema(): + return load_json('manifest-schema.json') + def is_simulate_config(config): sim_options = [ option for option in config From 91fc03900bd026d30f83cea047154cb3e099ae6f Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Mon, 30 Jan 2023 19:50:17 -0500 Subject: [PATCH 46/70] Normalize paths Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/scripts/parse_modules.py | 8 ++++---- .github/scripts/tla_utils.py | 6 +++++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/.github/scripts/parse_modules.py b/.github/scripts/parse_modules.py index 117133b3..7ecb4fa5 100644 --- a/.github/scripts/parse_modules.py +++ b/.github/scripts/parse_modules.py @@ -5,12 +5,12 @@ from concurrent.futures import ThreadPoolExecutor import logging from os import cpu_count, pathsep -from os.path import dirname +from os.path import dirname, normpath import subprocess import tla_utils -tlaps_modules = 'tlapm/library' -community_modules = 'CommunityModules/modules' +tlaps_modules = normpath('tlapm/library') +community_modules = normpath('CommunityModules/modules') logging.basicConfig(level=logging.INFO) def parse_module(module_tuple): @@ -46,7 +46,7 @@ def parse_module(module_tuple): # List of all modules to parse and whether they should use TLAPS imports modules = [ - (module['path'], any(['proof' in module['features'] for module in spec['modules']])) + (normpath(module['path']), any(['proof' in module['features'] for module in spec['modules']])) for spec in manifest['specifications'] if spec['path'] not in skip_specs for module in spec['modules'] if module['path'] not in skip_modules ] diff --git a/.github/scripts/tla_utils.py b/.github/scripts/tla_utils.py index e0543a6d..a9bbaf2c 100644 --- a/.github/scripts/tla_utils.py +++ b/.github/scripts/tla_utils.py @@ -1,8 +1,9 @@ import json +from os.path import normpath import subprocess def load_json(path): - with open(path, 'r', encoding='utf8') as file: + with open(normpath(path), 'r', encoding='utf8') as file: return json.load(file) def load_manifest(): @@ -23,6 +24,9 @@ def is_simulate_config(config): return (False, 0) def check_model(jar_path, module_path, model_path, config, timeout): + jar_path = normpath(jar_path) + module_path = normpath(module_path) + model_path = normpath(model_path) is_simulate, trace_count = is_simulate_config(config) try: tlc = subprocess.run([ From cf2a8c78a6318a08a2f573047393cc85c2bbc8cf Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Tue, 31 Jan 2023 10:34:16 -0500 Subject: [PATCH 47/70] Use Posix paths in generate script on Windows Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/scripts/generate_manifest.py | 25 ++++++++++++++++--------- manifest.json | 6 ++++-- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/.github/scripts/generate_manifest.py b/.github/scripts/generate_manifest.py index e59d9ac4..1ba9ca3b 100644 --- a/.github/scripts/generate_manifest.py +++ b/.github/scripts/generate_manifest.py @@ -11,17 +11,24 @@ import json import os from os.path import basename, dirname, join, normpath, splitext +from pathlib import PureWindowsPath import glob import tla_utils +def to_posix(path): + """ + Converts paths to normalized Posix format. + https://stackoverflow.com/q/75291812/2852699 + """ + return PureWindowsPath(normpath(path)).as_posix() + def get_tla_files(dir): """ Gets paths of all .tla files in the given directory, except for error trace specs. """ return [ - normpath(path) - for path in glob.glob(f'{dir.path}/**/*.tla', recursive=True) + path for path in glob.glob(f'{dir.path}/**/*.tla', recursive=True) if '_TTrace_' not in path ] @@ -37,7 +44,7 @@ def get_cfg_files(tla_path): module_name, _ = splitext(basename(tla_path)) other_module_names = [other for other in get_module_names_in_dir(parent_dir) if other != module_name] return [ - normpath(path) for path in glob.glob(f'{join(parent_dir, module_name)}*.cfg') + path for path in glob.glob(f'{join(parent_dir, module_name)}*.cfg') if splitext(basename(path))[0] not in other_module_names ] @@ -45,7 +52,7 @@ def get_cfg_files(tla_path): new_manifest = { 'specifications': [ { - 'path': normpath(dir.path), + 'path': to_posix(dir.path), 'title': dir.name, 'description': '', 'source': '', @@ -53,13 +60,13 @@ def get_cfg_files(tla_path): 'tags': [], 'modules': [ { - 'path': tla_path, + 'path': to_posix(tla_path), 'communityDependencies': sorted(list(get_community_module_imports(tla_path))), 'tlaLanguageVersion': 2, 'features': sorted(list(get_module_features(tla_path))), 'models': [ { - 'path': cfg_path, + 'path': to_posix(cfg_path), 'runtime': 'unknown', 'size': 'unknown', 'config': [], @@ -83,7 +90,7 @@ def get_cfg_files(tla_path): def find_corresponding_spec(old_spec, new_manifest): return [ spec for spec in new_manifest['specifications'] - if normpath(spec['path']) == old_spec['path'] + if to_posix(spec['path']) == old_spec['path'] ][0] def integrate_spec_info(old_spec, new_spec): @@ -95,7 +102,7 @@ def integrate_spec_info(old_spec, new_spec): def find_corresponding_module(old_module, new_spec): return [ module for module in new_spec['modules'] - if normpath(module['path']) == normpath(old_module['path']) + if to_posix(module['path']) == to_posix(old_module['path']) ][0] def integrate_module_info(old_module, new_module): @@ -106,7 +113,7 @@ def integrate_module_info(old_module, new_module): def find_corresponding_model(old_model, new_module): return [ model for model in new_module['models'] - if normpath(model['path']) == normpath(old_model['path']) + if to_posix(model['path']) == to_posix(old_model['path']) ][0] def integrate_model_info(old_model, new_model): diff --git a/manifest.json b/manifest.json index f0551448..95a3a56b 100644 --- a/manifest.json +++ b/manifest.json @@ -2768,7 +2768,9 @@ "path": "specifications/ewd840/EWD840_json.cfg", "runtime": "00:00:01", "size": "small", - "config": ["ignore deadlock"], + "config": [ + "ignore deadlock" + ], "features": [], "result": "success" } @@ -3368,4 +3370,4 @@ ] } ] -} +} \ No newline at end of file From e2ae52ec29075347cd2838a537c29683d45a47fb Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Tue, 31 Jan 2023 10:41:50 -0500 Subject: [PATCH 48/70] Smoke-test generation script on windows Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/workflows/CI.yml | 65 ++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 36 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index a2dfd17b..94b6297f 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -7,42 +7,10 @@ on: branches: - master -env: - SCRIPT_DIR: .github/scripts - jobs: - - validate-metadata: - name: Metadata Validation - runs-on: ubuntu-latest - steps: - - name: Clone repo - uses: actions/checkout@v2 - - name: Install python - uses: actions/setup-python@v4 - with: - python-version: '3.11' - - name: Install python packages - run: pip install -r $SCRIPT_DIR/requirements.txt - - name: Check manifest.json format - run: python $SCRIPT_DIR/check_manifest_schema.py - - name: Check manifest files - run: python $SCRIPT_DIR/check_manifest_files.py - - name: Get tree-sitter-tlaplus - run: | - wget https://github.com/tlaplus-community/tree-sitter-tlaplus/archive/main.tar.gz - tar -xf main.tar.gz - rm main.tar.gz - mv tree-sitter-tlaplus-main tree-sitter-tlaplus - - name: Check manifest feature flags - run: python $SCRIPT_DIR/check_manifest_features.py - - validate-specs-and-models: - name: Spec & Model Validation - needs: validate-metadata + validate: + name: Validate Manifest, Specs, & Models runs-on: ${{ matrix.os }} - env: - TLAPS_VERSION: 202210041448 strategy: matrix: include: @@ -50,13 +18,16 @@ jobs: - { os: ubuntu-latest, shell: bash } - { os: macos-latest, shell: bash } fail-fast: false + env: + SCRIPT_DIR: .github/scripts + TLAPS_VERSION: 202210041448 defaults: run: shell: ${{ matrix.shell }} {0} steps: - name: Clone repo uses: actions/checkout@v2 - - name: Install Python + - name: Install python uses: actions/setup-python@v4 with: python-version: '3.11' @@ -68,10 +39,29 @@ jobs: - name: Install MSYS2 on Windows uses: msys2/setup-msys2@v2 if: matrix.os == 'windows-latest' - - name: Get TLA⁺ toolset, TLAPS, and community modules + - name: Install python packages + shell: bash + run: pip install -r $SCRIPT_DIR/requirements.txt + - name: Check manifest.json format + shell: bash + run: python $SCRIPT_DIR/check_manifest_schema.py + - name: Check manifest files + shell: bash + run: python $SCRIPT_DIR/check_manifest_files.py + - name: Get tree-sitter-tlaplus run: | # Fix tar symbolic link issues on Windows; see: # https://github.com/msys2/MSYS2-packages/issues/1216 + export MSYS=winsymlinks:lnk + wget https://github.com/tlaplus-community/tree-sitter-tlaplus/archive/main.tar.gz + tar -xf main.tar.gz + rm main.tar.gz + mv tree-sitter-tlaplus-main tree-sitter-tlaplus + - name: Check manifest feature flags + shell: bash + run: python $SCRIPT_DIR/check_manifest_features.py + - name: Get TLA⁺ toolset, TLAPS, and community modules + run: | export MSYS=winsymlinks:lnk wget http://nightly.tlapl.us/dist/tla2tools.jar wget https://github.com/tlaplus/CommunityModules/releases/latest/download/CommunityModules-deps.jar @@ -92,4 +82,7 @@ jobs: - name: Smoke-test large models shell: bash run: python $SCRIPT_DIR/smoke_test_large_models.py + - name: Smoke-test manifest generation script + shell: bash + run: python $SCRIPT_DIR/generate_manifest.py From d1462ad06d0b8353dd8b0a2bb9dc0c405a30f3e7 Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Tue, 31 Jan 2023 11:19:11 -0500 Subject: [PATCH 49/70] Separated model run mode from config Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/scripts/check_small_models.py | 31 +++--- .github/scripts/generate_manifest.py | 5 +- .github/scripts/smoke_test_large_models.py | 14 ++- .github/scripts/tla_utils.py | 34 ++++--- manifest-schema.json | 45 ++++----- manifest.json | 109 ++++++++++++++++++--- 6 files changed, 164 insertions(+), 74 deletions(-) diff --git a/.github/scripts/check_small_models.py b/.github/scripts/check_small_models.py index d961d7ae..b448b241 100644 --- a/.github/scripts/check_small_models.py +++ b/.github/scripts/check_small_models.py @@ -13,17 +13,6 @@ def parse_timespan(unparsed): pattern = '%H:%M:%S' return datetime.strptime(unparsed, pattern) - datetime.strptime('00:00:00', pattern) -def is_simulate_config(config): - sim_options = [ - option for option in config - if type(option) is dict - and 'simulate' in option - ] - if any(sim_options): - return (True, sim_options[0]['simulate']['traceCount']) - else: - return (False, 0) - tlc_result = { 0 : 'success', 11 : 'deadlock failure', @@ -31,9 +20,19 @@ def is_simulate_config(config): 13 : 'liveness failure' } -def check_model(module_path, model_path, expected_result, expected_runtime, config): +def check_model(module_path, model, expected_runtime): + model_path = model['path'] + logging.info(model_path) + expected_result = model['result'] start_time = timer() - tlc, hit_timeout = tla_utils.check_model('tla2tools.jar', module_path, model_path, config, 60) + tlc, hit_timeout = tla_utils.check_model( + 'tla2tools.jar', + module_path, + model_path, + model['mode'], + model['config'], + 60 + ) end_time = timer() if hit_timeout: logging.error(f'{model_path} timed out') @@ -53,13 +52,13 @@ def check_model(module_path, model_path, expected_result, expected_runtime, conf # Ensure longest-running modules go first small_models = sorted( [ - (module['path'], model['path'], model['result'], parse_timespan(model['runtime']), model['config']) + (module['path'], model, parse_timespan(model['runtime'])) for spec in manifest['specifications'] for module in spec['modules'] for model in module['models'] if model['size'] == 'small' ], - key = lambda m: m[3], - reverse=True + key = lambda m: m[2], + #reverse=True ) success = all([check_model(*model) for model in small_models]) diff --git a/.github/scripts/generate_manifest.py b/.github/scripts/generate_manifest.py index 1ba9ca3b..acb83f8f 100644 --- a/.github/scripts/generate_manifest.py +++ b/.github/scripts/generate_manifest.py @@ -69,6 +69,7 @@ def get_cfg_files(tla_path): 'path': to_posix(cfg_path), 'runtime': 'unknown', 'size': 'unknown', + 'mode': 'exhaustive search', 'config': [], 'features': sorted(list(get_model_features(cfg_path))), 'result': 'unknown' @@ -117,7 +118,7 @@ def find_corresponding_model(old_model, new_module): ][0] def integrate_model_info(old_model, new_model): - fields = ['runtime', 'size', 'config', 'result'] + fields = ['runtime', 'size', 'mode', 'config', 'result'] for field in fields: new_model[field] = old_model[field] @@ -134,6 +135,6 @@ def integrate_model_info(old_model, new_model): integrate_model_info(old_model, new_model) # Write generated manifest to file -with open('manifest.json', 'w') as new_manifest_file: +with open('manifest.json', 'w', encoding='utf8') as new_manifest_file: json.dump(new_manifest, new_manifest_file, indent=2, ensure_ascii=False) diff --git a/.github/scripts/smoke_test_large_models.py b/.github/scripts/smoke_test_large_models.py index a85426b5..359daca8 100644 --- a/.github/scripts/smoke_test_large_models.py +++ b/.github/scripts/smoke_test_large_models.py @@ -7,9 +7,17 @@ import logging import tla_utils -def check_model(module_path, model_path, config): +def check_model(module_path, model): + model_path = model['path'] logging.info(model_path) - tlc, hit_timeout = tla_utils.check_model('tla2tools.jar', module_path, model_path, config, 5) + tlc, hit_timeout = tla_utils.check_model( + 'tla2tools.jar', + module_path, + model_path, + model['mode'], + model['config'], + 5 + ) if hit_timeout: return True if 0 != tlc.returncode: @@ -41,7 +49,7 @@ def check_model(module_path, model_path, config): ] large_models = [ - (module['path'], model['path'], model['config']) + (module['path'], model) for spec in manifest['specifications'] for module in spec['modules'] for model in module['models'] diff --git a/.github/scripts/tla_utils.py b/.github/scripts/tla_utils.py index a9bbaf2c..13dd98cf 100644 --- a/.github/scripts/tla_utils.py +++ b/.github/scripts/tla_utils.py @@ -12,24 +12,30 @@ def load_manifest(): def load_schema(): return load_json('manifest-schema.json') -def is_simulate_config(config): - sim_options = [ - option for option in config - if type(option) is dict - and 'simulate' in option - ] - if any(sim_options): - return (True, sim_options[0]['simulate']['traceCount']) +def get_run_mode(mode): + if type(mode) is dict: + if 'simulate' in mode: + trace_count = mode['simulate']['traceCount'] + return ['-simulate', f'num={trace_count}'] + else: + raise NotImplementedError(f'Undefined model-check mode {mode}') + elif 'generate' == mode: + return ['-generate'] + elif 'exhaustive search' == mode: + return [] else: - return (False, 0) + raise NotImplementedError(f'Undefined model-check mode {mode}') -def check_model(jar_path, module_path, model_path, config, timeout): +def get_config(config): + return ['-deadlock'] if 'ignore deadlock' in config else [] + +def check_model(jar_path, module_path, model_path, mode, config, timeout): jar_path = normpath(jar_path) module_path = normpath(module_path) model_path = normpath(model_path) - is_simulate, trace_count = is_simulate_config(config) try: - tlc = subprocess.run([ + tlc = subprocess.run( + [ 'java', '-Dtlc2.TLC.ide=Github', '-Dutil.ExecutionStatisticsCollector.id=abcdef60f238424fa70d124d0c77ffff', @@ -41,9 +47,7 @@ def check_model(jar_path, module_path, model_path, config, timeout): '-workers', 'auto', '-lncheck', 'final', '-cleanup' - ] + (['-deadlock'] if 'ignore deadlock' in config else []) - + (['-generate'] if 'generate' in config else []) - + (['-simulate', f'num={trace_count}'] if is_simulate else []), + ] + get_config(config) + get_run_mode(mode), capture_output=True, timeout=timeout ) diff --git a/manifest-schema.json b/manifest-schema.json index e2a65ac9..f0906991 100644 --- a/manifest-schema.json +++ b/manifest-schema.json @@ -44,7 +44,7 @@ "items": { "type": "object", "additionalProperties": false, - "required": ["path", "runtime", "size", "config", "features", "result"], + "required": ["path", "runtime", "size", "mode", "config", "features", "result"], "properties": { "path": {"type": "string"}, "runtime": { @@ -52,30 +52,31 @@ "pattern": "^(([0-9][0-9]:[0-9][0-9]:[0-9][0-9])|unknown)$" }, "size": {"enum": ["small", "medium", "large", "unknown"]}, - "config": { - "type": "array", - "items": { - "oneOf": [ - { - "enum": ["ignore deadlock", "generate"] - }, - { - "type": "object", - "additionalProperties": false, - "required": ["simulate"], - "properties": { - "simulate": { - "type": "object", - "additionalProperties": false, - "required": ["traceCount"], - "properties": { - "traceCount": {"type": "number"} - } + "mode": { + "oneOf": [ + { + "enum": ["exhaustive search", "generate"] + }, + { + "type": "object", + "additionalProperties": false, + "required": ["simulate"], + "properties": { + "simulate": { + "type": "object", + "additionalProperties": false, + "required": ["traceCount"], + "properties": { + "traceCount": {"type": "number"} } } } - ] - } + } + ] + }, + "config": { + "type": "array", + "items": {"enum": ["ignore deadlock"]} }, "features": { "type": "array", diff --git a/manifest.json b/manifest.json index 95a3a56b..99dc59c8 100644 --- a/manifest.json +++ b/manifest.json @@ -69,6 +69,7 @@ "path": "specifications/CarTalkPuzzle/CarTalkPuzzle.toolbox/Model_1/MC.cfg", "runtime": "00:00:01", "size": "small", + "mode": "exhaustive search", "config": [], "features": [], "result": "success" @@ -92,6 +93,7 @@ "path": "specifications/CarTalkPuzzle/CarTalkPuzzle.toolbox/Model_2/MC.cfg", "runtime": "00:00:05", "size": "small", + "mode": "exhaustive search", "config": [], "features": [], "result": "success" @@ -115,6 +117,7 @@ "path": "specifications/CarTalkPuzzle/CarTalkPuzzle.toolbox/Model_3/MC.cfg", "runtime": "unknown", "size": "large", + "mode": "exhaustive search", "config": [], "features": [], "result": "unknown" @@ -183,6 +186,7 @@ "path": "specifications/CoffeeCan/CoffeeCan1000Beans.cfg", "runtime": "00:00:15", "size": "medium", + "mode": "exhaustive search", "config": [], "features": [ "liveness" @@ -193,6 +197,7 @@ "path": "specifications/CoffeeCan/CoffeeCan100Beans.cfg", "runtime": "00:00:05", "size": "small", + "mode": "exhaustive search", "config": [], "features": [ "liveness" @@ -203,6 +208,7 @@ "path": "specifications/CoffeeCan/CoffeeCan3000Beans.cfg", "runtime": "00:02:30", "size": "medium", + "mode": "exhaustive search", "config": [], "features": [ "liveness" @@ -235,6 +241,7 @@ "path": "specifications/DieHard/DieHard.cfg", "runtime": "00:00:01", "size": "small", + "mode": "exhaustive search", "config": [], "features": [], "result": "safety failure" @@ -258,6 +265,7 @@ "path": "specifications/DieHard/MCDieHarder.cfg", "runtime": "00:00:01", "size": "small", + "mode": "exhaustive search", "config": [], "features": [], "result": "safety failure" @@ -290,6 +298,7 @@ "path": "specifications/DiningPhilosophers/DiningPhilosophers.cfg", "runtime": "00:00:01", "size": "small", + "mode": "exhaustive search", "config": [], "features": [ "liveness" @@ -320,6 +329,7 @@ "path": "specifications/EinsteinRiddle/Einstein.cfg", "runtime": "unknown", "size": "large", + "mode": "exhaustive search", "config": [], "features": [], "result": "safety failure" @@ -371,6 +381,7 @@ "path": "specifications/Huang/Huang.cfg", "runtime": "00:00:40", "size": "medium", + "mode": "exhaustive search", "config": [ "ignore deadlock" ], @@ -412,6 +423,7 @@ "path": "specifications/KeyValueStore/MCKVSSafetyLarge.cfg", "runtime": "07:16:00", "size": "large", + "mode": "exhaustive search", "config": [], "features": [ "symmetry" @@ -422,6 +434,7 @@ "path": "specifications/KeyValueStore/MCKVSSafetyMedium.cfg", "runtime": "00:04:30", "size": "medium", + "mode": "exhaustive search", "config": [], "features": [ "symmetry" @@ -432,6 +445,7 @@ "path": "specifications/KeyValueStore/MCKVSSafetySmall.cfg", "runtime": "00:00:40", "size": "medium", + "mode": "exhaustive search", "config": [], "features": [], "result": "success" @@ -482,9 +496,8 @@ "path": "specifications/KnuthYao/SimKnuthYao.cfg", "runtime": "unknown", "size": "unknown", - "config": [ - "generate" - ], + "mode": "generate", + "config": [], "features": [ "state constraint" ], @@ -648,6 +661,7 @@ "path": "specifications/MissionariesAndCannibals/MissionariesAndCannibals.cfg", "runtime": "00:00:01", "size": "small", + "mode": "exhaustive search", "config": [], "features": [], "result": "safety failure" @@ -676,6 +690,7 @@ "path": "specifications/MultiCarElevator/ElevatorLivenessLarge.cfg", "runtime": "00:11:00", "size": "large", + "mode": "exhaustive search", "config": [], "features": [ "liveness" @@ -686,6 +701,7 @@ "path": "specifications/MultiCarElevator/ElevatorLivenessMedium.cfg", "runtime": "00:00:30", "size": "medium", + "mode": "exhaustive search", "config": [], "features": [ "liveness" @@ -696,6 +712,7 @@ "path": "specifications/MultiCarElevator/ElevatorSafetyLarge.cfg", "runtime": "00:10:00", "size": "large", + "mode": "exhaustive search", "config": [], "features": [], "result": "success" @@ -704,6 +721,7 @@ "path": "specifications/MultiCarElevator/ElevatorSafetyMedium.cfg", "runtime": "00:03:00", "size": "medium", + "mode": "exhaustive search", "config": [], "features": [], "result": "success" @@ -712,6 +730,7 @@ "path": "specifications/MultiCarElevator/ElevatorSafetySmall.cfg", "runtime": "00:00:15", "size": "small", + "mode": "exhaustive search", "config": [], "features": [], "result": "success" @@ -749,6 +768,7 @@ "path": "specifications/N-Queens/Queens.toolbox/FourQueens/MC.cfg", "runtime": "00:00:01", "size": "small", + "mode": "exhaustive search", "config": [ "ignore deadlock" ], @@ -783,6 +803,7 @@ "path": "specifications/N-Queens/QueensPluscal.toolbox/FourQueens/MC.cfg", "runtime": "00:00:01", "size": "small", + "mode": "exhaustive search", "config": [], "features": [ "liveness" @@ -822,6 +843,7 @@ "path": "specifications/NanoBlockchain/MCNanoLarge.cfg", "runtime": "00:20:00", "size": "large", + "mode": "exhaustive search", "config": [], "features": [ "view" @@ -832,6 +854,7 @@ "path": "specifications/NanoBlockchain/MCNanoMedium.cfg", "runtime": "00:00:30", "size": "medium", + "mode": "exhaustive search", "config": [], "features": [ "view" @@ -842,6 +865,7 @@ "path": "specifications/NanoBlockchain/MCNanoSmall.cfg", "runtime": "00:00:05", "size": "small", + "mode": "exhaustive search", "config": [], "features": [ "view" @@ -888,6 +912,7 @@ "path": "specifications/Paxos/MCConsensus.cfg", "runtime": "00:00:01", "size": "small", + "mode": "exhaustive search", "config": [ "ignore deadlock" ], @@ -906,6 +931,7 @@ "path": "specifications/Paxos/MCPaxos.cfg", "runtime": "00:00:01", "size": "small", + "mode": "exhaustive search", "config": [], "features": [ "liveness", @@ -925,6 +951,7 @@ "path": "specifications/Paxos/MCVoting.cfg", "runtime": "00:00:01", "size": "small", + "mode": "exhaustive search", "config": [ "ignore deadlock" ], @@ -1020,6 +1047,7 @@ "path": "specifications/Prisoners/Prisoners.cfg", "runtime": "00:00:01", "size": "small", + "mode": "exhaustive search", "config": [], "features": [ "liveness" @@ -1050,6 +1078,7 @@ "path": "specifications/ReadersWriters/MC.cfg", "runtime": "00:00:05", "size": "small", + "mode": "exhaustive search", "config": [], "features": [ "liveness" @@ -1088,6 +1117,7 @@ "path": "specifications/SDP_Verification/SDP_Attack_New_Solution_Spec/MC.cfg", "runtime": "00:00:01", "size": "small", + "mode": "exhaustive search", "config": [ "ignore deadlock" ], @@ -1118,6 +1148,7 @@ "path": "specifications/SDP_Verification/SDP_Attack_Spec/MC.cfg", "runtime": "00:00:05", "size": "small", + "mode": "exhaustive search", "config": [ "ignore deadlock" ], @@ -1160,6 +1191,7 @@ "path": "specifications/SingleLaneBridge/MC.cfg", "runtime": "00:00:10", "size": "small", + "mode": "exhaustive search", "config": [], "features": [ "liveness" @@ -1197,6 +1229,7 @@ "path": "specifications/SlidingPuzzles/SlidingPuzzles.cfg", "runtime": "00:00:05", "size": "small", + "mode": "exhaustive search", "config": [], "features": [], "result": "safety failure" @@ -1227,6 +1260,7 @@ "path": "specifications/SlushProtocol/SlushLarge.cfg", "runtime": "00:50:00", "size": "large", + "mode": "exhaustive search", "config": [], "features": [], "result": "success" @@ -1235,6 +1269,7 @@ "path": "specifications/SlushProtocol/SlushMedium.cfg", "runtime": "00:01:00", "size": "medium", + "mode": "exhaustive search", "config": [], "features": [], "result": "success" @@ -1243,6 +1278,7 @@ "path": "specifications/SlushProtocol/SlushSmall.cfg", "runtime": "00:00:15", "size": "small", + "mode": "exhaustive search", "config": [], "features": [], "result": "success" @@ -1339,6 +1375,7 @@ "path": "specifications/SpecifyingSystems/AdvancedExamples/MCInnerSequential.cfg", "runtime": "00:00:01", "size": "small", + "mode": "exhaustive search", "config": [], "features": [ "liveness", @@ -1358,6 +1395,7 @@ "path": "specifications/SpecifyingSystems/AdvancedExamples/MCInnerSerial.cfg", "runtime": "unknown", "size": "unknown", + "mode": "exhaustive search", "config": [], "features": [ "liveness", @@ -1391,6 +1429,7 @@ "path": "specifications/SpecifyingSystems/AsynchronousInterface/AsynchInterface.cfg", "runtime": "00:00:01", "size": "small", + "mode": "exhaustive search", "config": [], "features": [], "result": "success" @@ -1407,6 +1446,7 @@ "path": "specifications/SpecifyingSystems/AsynchronousInterface/Channel.cfg", "runtime": "00:00:01", "size": "small", + "mode": "exhaustive search", "config": [], "features": [], "result": "success" @@ -1423,6 +1463,7 @@ "path": "specifications/SpecifyingSystems/AsynchronousInterface/PrintValues.cfg", "runtime": "00:00:01", "size": "small", + "mode": "exhaustive search", "config": [], "features": [], "result": "success" @@ -1446,6 +1487,7 @@ "path": "specifications/SpecifyingSystems/CachingMemory/MCInternalMemory.cfg", "runtime": "00:00:01", "size": "small", + "mode": "exhaustive search", "config": [], "features": [], "result": "success" @@ -1462,6 +1504,7 @@ "path": "specifications/SpecifyingSystems/CachingMemory/MCWriteThroughCache.cfg", "runtime": "00:00:01", "size": "small", + "mode": "exhaustive search", "config": [], "features": [ "liveness" @@ -1592,6 +1635,7 @@ "path": "specifications/SpecifyingSystems/FIFO/MCInnerFIFO.cfg", "runtime": "00:00:01", "size": "small", + "mode": "exhaustive search", "config": [], "features": [ "state constraint" @@ -1610,6 +1654,7 @@ "path": "specifications/SpecifyingSystems/HourClock/HourClock.cfg", "runtime": "00:00:01", "size": "small", + "mode": "exhaustive search", "config": [], "features": [], "result": "success" @@ -1626,6 +1671,7 @@ "path": "specifications/SpecifyingSystems/HourClock/HourClock2.cfg", "runtime": "00:00:01", "size": "small", + "mode": "exhaustive search", "config": [], "features": [ "liveness" @@ -1658,6 +1704,7 @@ "path": "specifications/SpecifyingSystems/Liveness/LiveHourClock.cfg", "runtime": "00:00:01", "size": "small", + "mode": "exhaustive search", "config": [], "features": [ "liveness" @@ -1697,6 +1744,7 @@ "path": "specifications/SpecifyingSystems/Liveness/MCLiveInternalMemory.cfg", "runtime": "00:00:01", "size": "small", + "mode": "exhaustive search", "config": [], "features": [ "liveness" @@ -1715,6 +1763,7 @@ "path": "specifications/SpecifyingSystems/Liveness/MCLiveWriteThroughCache.cfg", "runtime": "00:00:05", "size": "small", + "mode": "exhaustive search", "config": [], "features": [ "liveness" @@ -1775,6 +1824,7 @@ "path": "specifications/SpecifyingSystems/RealTime/MCRealTimeHourClock.cfg", "runtime": "00:00:01", "size": "small", + "mode": "exhaustive search", "config": [], "features": [ "liveness" @@ -1842,6 +1892,7 @@ "path": "specifications/SpecifyingSystems/SimpleMath/SimpleMath.cfg", "runtime": "00:00:01", "size": "small", + "mode": "exhaustive search", "config": [], "features": [], "result": "success" @@ -1928,6 +1979,7 @@ "path": "specifications/SpecifyingSystems/TLC/ABCorrectness.cfg", "runtime": "00:00:01", "size": "small", + "mode": "exhaustive search", "config": [], "features": [], "result": "success" @@ -1965,6 +2017,7 @@ "path": "specifications/SpecifyingSystems/TLC/MCAlternatingBit.cfg", "runtime": "00:00:01", "size": "small", + "mode": "exhaustive search", "config": [], "features": [ "liveness", @@ -2024,6 +2077,7 @@ "path": "specifications/TLC/TestGraphs.cfg", "runtime": "00:00:05", "size": "small", + "mode": "exhaustive search", "config": [], "features": [ "liveness" @@ -2086,6 +2140,7 @@ "path": "specifications/TransitiveClosure/TransitiveClosure.cfg", "runtime": "00:00:05", "size": "small", + "mode": "exhaustive search", "config": [], "features": [], "result": "success" @@ -2173,6 +2228,7 @@ "path": "specifications/allocator/AllocatorImplementation.cfg", "runtime": "00:00:15", "size": "small", + "mode": "exhaustive search", "config": [], "features": [ "liveness" @@ -2191,6 +2247,7 @@ "path": "specifications/allocator/AllocatorRefinement.cfg", "runtime": "00:00:05", "size": "small", + "mode": "exhaustive search", "config": [], "features": [ "liveness" @@ -2209,6 +2266,7 @@ "path": "specifications/allocator/SchedulingAllocator.cfg", "runtime": "00:00:10", "size": "small", + "mode": "exhaustive search", "config": [], "features": [ "liveness" @@ -2227,6 +2285,7 @@ "path": "specifications/allocator/SimpleAllocator.cfg", "runtime": "00:00:05", "size": "small", + "mode": "exhaustive search", "config": [], "features": [ "liveness" @@ -2459,6 +2518,7 @@ "path": "specifications/dijkstra-mutex/DijkstraMutex.toolbox/LSpec-model/MC.cfg", "runtime": "00:00:50", "size": "medium", + "mode": "exhaustive search", "config": [], "features": [ "liveness" @@ -2486,6 +2546,7 @@ "path": "specifications/dijkstra-mutex/DijkstraMutex.toolbox/Safety-4-processors/MC.cfg", "runtime": "00:02:00", "size": "medium", + "mode": "exhaustive search", "config": [], "features": [], "result": "success" @@ -2557,6 +2618,7 @@ "path": "specifications/echo/MCEcho.cfg", "runtime": "00:00:01", "size": "small", + "mode": "exhaustive search", "config": [], "features": [], "result": "success" @@ -2596,6 +2658,7 @@ "path": "specifications/ewd426/SimTokenRing.cfg", "runtime": "unknown", "size": "unknown", + "mode": "exhaustive search", "config": [], "features": [ "state constraint" @@ -2614,6 +2677,7 @@ "path": "specifications/ewd426/TokenRing.cfg", "runtime": "unknown", "size": "unknown", + "mode": "exhaustive search", "config": [], "features": [ "alias", @@ -2668,13 +2732,12 @@ "path": "specifications/ewd687a/EWD687a_anim.cfg", "runtime": "00:00:01", "size": "small", - "config": [ - { - "simulate": { - "traceCount": 100 - } + "mode": { + "simulate": { + "traceCount": 100 } - ], + }, + "config": [], "features": [ "alias", "liveness" @@ -2693,6 +2756,7 @@ "path": "specifications/ewd687a/MCEWD687a.cfg", "runtime": "00:01:00", "size": "medium", + "mode": "exhaustive search", "config": [], "features": [ "liveness", @@ -2724,6 +2788,7 @@ "path": "specifications/ewd840/EWD840.cfg", "runtime": "00:00:01", "size": "small", + "mode": "exhaustive search", "config": [ "ignore deadlock" ], @@ -2744,13 +2809,12 @@ "path": "specifications/ewd840/EWD840_anim.cfg", "runtime": "00:00:01", "size": "small", - "config": [ - { - "simulate": { - "traceCount": 100 - } + "mode": { + "simulate": { + "traceCount": 100 } - ], + }, + "config": [], "features": [ "alias" ], @@ -2768,6 +2832,7 @@ "path": "specifications/ewd840/EWD840_json.cfg", "runtime": "00:00:01", "size": "small", + "mode": "exhaustive search", "config": [ "ignore deadlock" ], @@ -2795,6 +2860,7 @@ "path": "specifications/ewd840/SyncTerminationDetection.cfg", "runtime": "00:00:01", "size": "small", + "mode": "exhaustive search", "config": [], "features": [ "liveness" @@ -2835,6 +2901,7 @@ "path": "specifications/ewd998/AsyncTerminationDetection.cfg", "runtime": "00:00:01", "size": "small", + "mode": "exhaustive search", "config": [], "features": [ "state constraint" @@ -2855,6 +2922,7 @@ "path": "specifications/ewd998/AsyncTerminationDetection_proof.cfg", "runtime": "unknown", "size": "unknown", + "mode": "exhaustive search", "config": [], "features": [ "liveness", @@ -2877,6 +2945,7 @@ "path": "specifications/ewd998/EWD998.cfg", "runtime": "00:50:00", "size": "large", + "mode": "exhaustive search", "config": [ "ignore deadlock" ], @@ -2889,6 +2958,7 @@ "path": "specifications/ewd998/EWD998Small.cfg", "runtime": "00:00:30", "size": "small", + "mode": "exhaustive search", "config": [ "ignore deadlock" ], @@ -2909,6 +2979,7 @@ "path": "specifications/ewd998/EWD998Chan.cfg", "runtime": "00:05:00", "size": "medium", + "mode": "exhaustive search", "config": [ "ignore deadlock" ], @@ -2930,6 +3001,7 @@ "path": "specifications/ewd998/EWD998ChanID.cfg", "runtime": "unknown", "size": "large", + "mode": "exhaustive search", "config": [], "features": [ "liveness", @@ -2952,6 +3024,7 @@ "path": "specifications/ewd998/EWD998ChanID_export.cfg", "runtime": "unknown", "size": "large", + "mode": "exhaustive search", "config": [], "features": [], "result": "unknown" @@ -2968,6 +3041,7 @@ "path": "specifications/ewd998/EWD998ChanID_shiviz.cfg", "runtime": "unknown", "size": "large", + "mode": "exhaustive search", "config": [], "features": [ "alias" @@ -3038,6 +3112,7 @@ "path": "specifications/ewd998/SmokeEWD998.cfg", "runtime": "unknown", "size": "unknown", + "mode": "exhaustive search", "config": [], "features": [ "liveness", @@ -3060,6 +3135,7 @@ "path": "specifications/ewd998/SmokeEWD998_SC.cfg", "runtime": "unknown", "size": "unknown", + "mode": "exhaustive search", "config": [], "features": [], "result": "unknown" @@ -3320,6 +3396,7 @@ "path": "specifications/tower_of_hanoi/Hanoi.toolbox/Model_1/MC.cfg", "runtime": "00:00:01", "size": "small", + "mode": "exhaustive search", "config": [], "features": [], "result": "safety failure" @@ -3370,4 +3447,4 @@ ] } ] -} \ No newline at end of file +} From a067ee24b61a80308d03adea12f08221316e4d7d Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Tue, 31 Jan 2023 12:03:26 -0500 Subject: [PATCH 50/70] Try to fix windows unicode issue Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/scripts/generate_manifest.py | 2 +- .github/scripts/tla_utils.py | 2 +- .github/workflows/CI.yml | 22 ++++++++++++---------- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/.github/scripts/generate_manifest.py b/.github/scripts/generate_manifest.py index acb83f8f..d8c83197 100644 --- a/.github/scripts/generate_manifest.py +++ b/.github/scripts/generate_manifest.py @@ -135,6 +135,6 @@ def integrate_model_info(old_model, new_model): integrate_model_info(old_model, new_model) # Write generated manifest to file -with open('manifest.json', 'w', encoding='utf8') as new_manifest_file: +with open('manifest.json', 'w', encoding='utf-8') as new_manifest_file: json.dump(new_manifest, new_manifest_file, indent=2, ensure_ascii=False) diff --git a/.github/scripts/tla_utils.py b/.github/scripts/tla_utils.py index 13dd98cf..0cc69e31 100644 --- a/.github/scripts/tla_utils.py +++ b/.github/scripts/tla_utils.py @@ -3,7 +3,7 @@ import subprocess def load_json(path): - with open(normpath(path), 'r', encoding='utf8') as file: + with open(normpath(path), 'r', encoding='utf-8') as file: return json.load(file) def load_manifest(): diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 94b6297f..f9035f8d 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -17,7 +17,7 @@ jobs: - { os: windows-latest, shell: msys2 } - { os: ubuntu-latest, shell: bash } - { os: macos-latest, shell: bash } - fail-fast: false + fail-fast: true env: SCRIPT_DIR: .github/scripts TLAPS_VERSION: 202210041448 @@ -42,12 +42,6 @@ jobs: - name: Install python packages shell: bash run: pip install -r $SCRIPT_DIR/requirements.txt - - name: Check manifest.json format - shell: bash - run: python $SCRIPT_DIR/check_manifest_schema.py - - name: Check manifest files - shell: bash - run: python $SCRIPT_DIR/check_manifest_files.py - name: Get tree-sitter-tlaplus run: | # Fix tar symbolic link issues on Windows; see: @@ -57,6 +51,17 @@ jobs: tar -xf main.tar.gz rm main.tar.gz mv tree-sitter-tlaplus-main tree-sitter-tlaplus + - name: Smoke-test manifest generation script + shell: bash + run: | + python --version + python $SCRIPT_DIR/generate_manifest.py + - name: Check manifest.json format + shell: bash + run: python $SCRIPT_DIR/check_manifest_schema.py + - name: Check manifest files + shell: bash + run: python $SCRIPT_DIR/check_manifest_files.py - name: Check manifest feature flags shell: bash run: python $SCRIPT_DIR/check_manifest_features.py @@ -82,7 +87,4 @@ jobs: - name: Smoke-test large models shell: bash run: python $SCRIPT_DIR/smoke_test_large_models.py - - name: Smoke-test manifest generation script - shell: bash - run: python $SCRIPT_DIR/generate_manifest.py From 7ed6650ca384779dba7863e1166c26562409f48d Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Tue, 31 Jan 2023 12:10:42 -0500 Subject: [PATCH 51/70] Reorganized CI Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/workflows/CI.yml | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index f9035f8d..2a5862be 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -17,7 +17,7 @@ jobs: - { os: windows-latest, shell: msys2 } - { os: ubuntu-latest, shell: bash } - { os: macos-latest, shell: bash } - fail-fast: true + fail-fast: false env: SCRIPT_DIR: .github/scripts TLAPS_VERSION: 202210041448 @@ -42,42 +42,38 @@ jobs: - name: Install python packages shell: bash run: pip install -r $SCRIPT_DIR/requirements.txt - - name: Get tree-sitter-tlaplus + - name: Download TLA⁺ dependencies run: | # Fix tar symbolic link issues on Windows; see: # https://github.com/msys2/MSYS2-packages/issues/1216 export MSYS=winsymlinks:lnk + # Get tree-sitter-tlaplus wget https://github.com/tlaplus-community/tree-sitter-tlaplus/archive/main.tar.gz tar -xf main.tar.gz rm main.tar.gz mv tree-sitter-tlaplus-main tree-sitter-tlaplus - - name: Smoke-test manifest generation script - shell: bash - run: | - python --version - python $SCRIPT_DIR/generate_manifest.py - - name: Check manifest.json format - shell: bash - run: python $SCRIPT_DIR/check_manifest_schema.py - - name: Check manifest files - shell: bash - run: python $SCRIPT_DIR/check_manifest_files.py - - name: Check manifest feature flags - shell: bash - run: python $SCRIPT_DIR/check_manifest_features.py - - name: Get TLA⁺ toolset, TLAPS, and community modules - run: | - export MSYS=winsymlinks:lnk + # Get TLA⁺ tools wget http://nightly.tlapl.us/dist/tla2tools.jar + # Get TLA⁺ community modules wget https://github.com/tlaplus/CommunityModules/releases/latest/download/CommunityModules-deps.jar wget https://github.com/tlaplus/CommunityModules/archive/master.tar.gz tar -xf master.tar.gz rm master.tar.gz mv CommunityModules-master CommunityModules + # Get TLAPS wget https://github.com/tlaplus/tlapm/archive/refs/tags/$TLAPS_VERSION.tar.gz tar -xf $TLAPS_VERSION.tar.gz rm $TLAPS_VERSION.tar.gz mv tlapm-$TLAPS_VERSION tlapm + - name: Check manifest.json format + shell: bash + run: python $SCRIPT_DIR/check_manifest_schema.py + - name: Check manifest files + shell: bash + run: python $SCRIPT_DIR/check_manifest_files.py + - name: Check manifest feature flags + shell: bash + run: python $SCRIPT_DIR/check_manifest_features.py - name: Parse all modules shell: bash run: python $SCRIPT_DIR/parse_modules.py @@ -87,4 +83,9 @@ jobs: - name: Smoke-test large models shell: bash run: python $SCRIPT_DIR/smoke_test_large_models.py + - name: Smoke-test manifest generation script + shell: bash + run: | + python $SCRIPT_DIR/generate_manifest.py + git diff -a From 3dcd3c174f829076ae9ebf89f9ecaf2683c7347b Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Tue, 31 Jan 2023 13:13:46 -0500 Subject: [PATCH 52/70] Updated README instructions Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- README.md | 53 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 46 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index e971fba6..32b3dd0f 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,54 @@ -## Welcome to TLA+ Examples [![Gitpod ready-to-code](https://img.shields.io/badge/Gitpod-ready--to--spec-908a85?logo=gitpod)](https://gitpod.io/#https://github.com/tlaplus/examples/) +## Welcome to TLA+ Examples +[![Gitpod ready-to-code](https://img.shields.io/badge/Gitpod-ready--to--spec-908a85?logo=gitpod)](https://gitpod.io/#https://github.com/tlaplus/examples/) +[![Validate Specs & Models](https://github.com/tlaplus/examples/actions/workflows/ci.yml/badge.svg)](https://github.com/tlaplus/examples/actions/workflows/ci.yml) -The page **TLA+ Examples** is a library of TLA+ specifications for distributed algorithms. The webpage supplies the TLA+ community with: +This is a repository of TLA+ specifications and models covering applications in a variety of fields. +It serves as: +- a comprehensive example library demonstrating how to specify an algorithm in TLA+ +- a diverse corpus facilitating development & testing of TLA+ language tools +- a collection of case studies in the application of formal specification in TLA+ -- A comprehensive library of the TLA+ specifications that are available today, in order to provide an overview of how to specify an algorithm in TLA+. -- A comprehensive list of references and other interesting information for each problem. +## Contributing -Do you have your own case study that you like to share with the community? Send a pointer to us and we will include it in the repository. Your specifications will help the community in improving the tools for TLA+ analysis. +Do you have your own case study or TLA+ specification you'd like to share with the community? +Follow these instructions: +1. Ensure your spec is released under MIT or a similarly-permissive license +1. Fork this repository and create a new directory under `specifications` with the name of your spec +1. Place all TLA+ files in the directory, along with their `.cfg` model files (greatly encouraged) +1. Consider including a `README.md` explaining the significance of the spec with links to any relevant websites or publications, or integrate this info as comments in the spec itself +1. Add an entry to the below table in this top-level `README.md` summarizing your spec and its attributes +1. Update the `manifest.json` file with machine-readable records of your spec files, either manually or with a script as follows: + 1. Ensure you have Python 3.X installed + 1. Download & extract [tree-sitter-tlaplus](https://github.com/tlaplus-community/tree-sitter-tlaplus/archive/refs/heads/main.zip) to the root of the repository; ensure the extracted folder is named `tree-sitter-tlaplus` + 1. Run `pip install -r .github/scripts/requirements.txt` + 1. Run `python .github/scripts/generate_manifest.py` +1. Locate your spec's entry in the `manifest.json` file and ensure the following fields are filled out: + - Spec title: an appropriate title for your specification + - Spec description: a short description of your specification + - Spec source: if this spec was first published elsewhere, provide a link to this location + - Spec authors: a list of people who authored the spec + - Spec tags: currently only the `"beginner"` tag is supported for beginner-friendly specs + - Model runtime: the approximate runtime of the model on an ordinary workstation, in `"HH:MM:SS"` format + - Model size: + - `"small"` if the model can be executed in less than 10 seconds + - `"medium"` if the model can be executed in less than five minutes + - `"large"` if the model takes more than five minutes to execute + - Model mode: `"exhaustive search"` by default, but can also be `{"simulate": {"traceCount": N}}` or `"generate"` + - Model config: currently only `"ignore deadlock"` is supported + - Model result: + - `"success"` if the model completes successfully + - `"safety failure"` if the model violates an invariant + - `"liveness failure"` if the model fails to satisfy a liveness property + - `"deadlock failure"` if the model encounters deadlock + +The `manifest.json` file is checked for conformance to the repo's specs by a continuous integration script. +Its schema is found in the `manifest-schema.json` file. +All specs and models are also checked for parsing and execution by the CI script. ## List of Examples -| No | Name | Short description | Spec's authors | TLAPS Proof | TLC Check | Used modules | PlusCal | Apalache | -| :-: | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ | :---------: | :-----------------------------------------------------------------------------------------------------------: | --------------------------------------------------------------------- | -------- | -------- | +| # | Name | Description | Authors | TLAPS Proof | TLC Model | Module Dependencies | PlusCal | Apalache | +|:-:|------|-------------|---------|:-----------:|:---------:|---------------------|:--------:|:--------:| | 1 | 2PCwithBTM | A modified version of P2TCommit (Gray & Lamport, 2006) | Murat Demirbas | | ✔ | FinSet, Int, Seq | ✔ | | | 2 | 802.16 | IEEE 802.16 WiMAX Protocols | Prasad Narayana, Ruiming Chen, Yao Zhao, Yan Chen, Zhi (Judy) Fu, and Hai Zhou | | ✔ | Int, Seq, FinSet | | | | 3 | aba-asyn-byz | Asynchronous Byzantine agreement (Bracha & Toueg, 1985) | Thanh Hai Tran, Igor Konnov, Josef Widder | | ✔ | Nat | | | @@ -118,3 +156,4 @@ The repository is under the MIT license. However, we can upload your benchmarks ## Support or Contact Do you have any questions or comments? Please open an issue or send an email to the [TLA+ group](https://groups.google.com/g/tlaplus). + From f5e7ec547936500ad9b141f8286ff1c1484866ad Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Tue, 31 Jan 2023 13:31:15 -0500 Subject: [PATCH 53/70] Expanded README Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- README.md | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 32b3dd0f..a1f650ec 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -## Welcome to TLA+ Examples +# TLA+ Examples [![Gitpod ready-to-code](https://img.shields.io/badge/Gitpod-ready--to--spec-908a85?logo=gitpod)](https://gitpod.io/#https://github.com/tlaplus/examples/) [![Validate Specs & Models](https://github.com/tlaplus/examples/actions/workflows/ci.yml/badge.svg)](https://github.com/tlaplus/examples/actions/workflows/ci.yml) @@ -14,7 +14,7 @@ Do you have your own case study or TLA+ specification you'd like to s Follow these instructions: 1. Ensure your spec is released under MIT or a similarly-permissive license 1. Fork this repository and create a new directory under `specifications` with the name of your spec -1. Place all TLA+ files in the directory, along with their `.cfg` model files (greatly encouraged) +1. Place all TLA+ files in the directory, along with their `.cfg` model files; you are encouraged to include at least one model that completes execution in less than 10 seconds 1. Consider including a `README.md` explaining the significance of the spec with links to any relevant websites or publications, or integrate this info as comments in the spec itself 1. Add an entry to the below table in this top-level `README.md` summarizing your spec and its attributes 1. Update the `manifest.json` file with machine-readable records of your spec files, either manually or with a script as follows: @@ -27,22 +27,27 @@ Follow these instructions: - Spec description: a short description of your specification - Spec source: if this spec was first published elsewhere, provide a link to this location - Spec authors: a list of people who authored the spec - - Spec tags: currently only the `"beginner"` tag is supported for beginner-friendly specs - - Model runtime: the approximate runtime of the model on an ordinary workstation, in `"HH:MM:SS"` format + - Spec tags: + - `"beginner"` if your spec is appropriate for TLA+ newcomers + - Model runtime: approximate model runtime on an ordinary workstation, in `"HH:MM:SS"` format - Model size: - `"small"` if the model can be executed in less than 10 seconds - `"medium"` if the model can be executed in less than five minutes - `"large"` if the model takes more than five minutes to execute - - Model mode: `"exhaustive search"` by default, but can also be `{"simulate": {"traceCount": N}}` or `"generate"` - - Model config: currently only `"ignore deadlock"` is supported + - Model mode: + - `"exhaustive search"` by default + - `{"simulate": {"traceCount": N}}` for a simulation model + - `"generate"` for model trace generation + - Model config: + - `"ignore deadlock"` if your model should ignore deadlock - Model result: - `"success"` if the model completes successfully - `"safety failure"` if the model violates an invariant - `"liveness failure"` if the model fails to satisfy a liveness property - `"deadlock failure"` if the model encounters deadlock + - Other fields are auto-generated by the script; if you are adding an entry manually, ensure their values are present and correct (see other entries or the `manifest-schema.json` file) The `manifest.json` file is checked for conformance to the repo's specs by a continuous integration script. -Its schema is found in the `manifest-schema.json` file. All specs and models are also checked for parsing and execution by the CI script. ## List of Examples From e0d6a9d63f046bdf972ba9cf0de4543876dc6526 Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Tue, 31 Jan 2023 13:36:14 -0500 Subject: [PATCH 54/70] Final README changes Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a1f650ec..51452287 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,8 @@ It serves as: - a diverse corpus facilitating development & testing of TLA+ language tools - a collection of case studies in the application of formal specification in TLA+ +All TLA+ specs can be found in the `specifications` directory. + ## Contributing Do you have your own case study or TLA+ specification you'd like to share with the community? @@ -52,8 +54,8 @@ All specs and models are also checked for parsing and execution by the CI script ## List of Examples -| # | Name | Description | Authors | TLAPS Proof | TLC Model | Module Dependencies | PlusCal | Apalache | -|:-:|------|-------------|---------|:-----------:|:---------:|---------------------|:--------:|:--------:| +| # | Name | Description | Authors | TLAPS Proof? | TLC Model? | Module Dependencies | PlusCal? | Apalache? | +|:-:|------|-------------|---------|:------------:|:----------:|---------------------|:--------:|:---------:| | 1 | 2PCwithBTM | A modified version of P2TCommit (Gray & Lamport, 2006) | Murat Demirbas | | ✔ | FinSet, Int, Seq | ✔ | | | 2 | 802.16 | IEEE 802.16 WiMAX Protocols | Prasad Narayana, Ruiming Chen, Yao Zhao, Yan Chen, Zhi (Judy) Fu, and Hai Zhou | | ✔ | Int, Seq, FinSet | | | | 3 | aba-asyn-byz | Asynchronous Byzantine agreement (Bracha & Toueg, 1985) | Thanh Hai Tran, Igor Konnov, Josef Widder | | ✔ | Nat | | | @@ -160,5 +162,6 @@ The repository is under the MIT license. However, we can upload your benchmarks ## Support or Contact -Do you have any questions or comments? Please open an issue or send an email to the [TLA+ group](https://groups.google.com/g/tlaplus). +Do you have any questions or comments? +Please open an issue or send an email to the [TLA+ group](https://groups.google.com/g/tlaplus). From 1fced72548dc1fc1b058e10f0f6d4e227d315baa Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Tue, 31 Jan 2023 13:41:42 -0500 Subject: [PATCH 55/70] Ignore deadlock in simulation script Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest.json b/manifest.json index 99dc59c8..9db62d8f 100644 --- a/manifest.json +++ b/manifest.json @@ -2737,7 +2737,7 @@ "traceCount": 100 } }, - "config": [], + "config": ["ignore deadlock"], "features": [ "alias", "liveness" From 784cbe22b7b8034c29b884b3642635bb76d2430f Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Tue, 31 Jan 2023 13:42:33 -0500 Subject: [PATCH 56/70] Also ignore deadlock here Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest.json b/manifest.json index 9db62d8f..36b301a0 100644 --- a/manifest.json +++ b/manifest.json @@ -2814,7 +2814,7 @@ "traceCount": 100 } }, - "config": [], + "config": ["ignore deadlock"], "features": [ "alias" ], From 4271a6314203a7f0b5301490ab99d819d256b039 Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Tue, 31 Jan 2023 14:57:07 -0500 Subject: [PATCH 57/70] Added note about .cfg names Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 51452287..240c0d24 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ Follow these instructions: 1. Ensure your spec is released under MIT or a similarly-permissive license 1. Fork this repository and create a new directory under `specifications` with the name of your spec 1. Place all TLA+ files in the directory, along with their `.cfg` model files; you are encouraged to include at least one model that completes execution in less than 10 seconds +1. Ensure name of each `.cfg` file matches the `.tla` file it models, or has its name as a prefix; for example `SpecName.tla` can have the models `SpecName.cfg` and `SpecNameLiveness.cfg`, etc. 1. Consider including a `README.md` explaining the significance of the spec with links to any relevant websites or publications, or integrate this info as comments in the spec itself 1. Add an entry to the below table in this top-level `README.md` summarizing your spec and its attributes 1. Update the `manifest.json` file with machine-readable records of your spec files, either manually or with a script as follows: From b286b6517fa04c30b5ef5f079287caafac10241f Mon Sep 17 00:00:00 2001 From: Markus Alexander Kuppe Date: Thu, 2 Feb 2023 08:19:55 -0800 Subject: [PATCH 58/70] Models failing smoke testing #65 Addresses Github issue #65 https://github.com/tlaplus/Examples/issues/65 [Bug] Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- specifications/ewd426/SimTokenRing.tla | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/specifications/ewd426/SimTokenRing.tla b/specifications/ewd426/SimTokenRing.tla index a8096835..cb28700a 100644 --- a/specifications/ewd426/SimTokenRing.tla +++ b/specifications/ewd426/SimTokenRing.tla @@ -3,6 +3,10 @@ EXTENDS TokenRing, TLC, CSV, IOUtils (* Statistics collection *) +\* TCLGet("stats").traces is only defined when TLC runs in simulation or generation mode. +\* For this spec, users have to run TLC in generate mode to collect meaningful statistics. +ASSUME TLCGet("config").mode = "generate" + CSVFile == "SimTokenRing.csv" @@ -24,4 +28,4 @@ $ rm -rf states/ ; rm *.csv ; tlc SimTokenRing -note -generate -depth -1 $ alias tlc -tlc='java -cp /path/to/tla2tools.jar tlc2.TLC' \ No newline at end of file +tlc='java -cp /path/to/tla2tools.jar tlc2.TLC' From 69372ba8b4ec561afe417a6c25fc9f9a6d601537 Mon Sep 17 00:00:00 2001 From: Markus Alexander Kuppe Date: Thu, 2 Feb 2023 08:38:30 -0800 Subject: [PATCH 59/70] Models failing smoke testing #65 Addresses part of Github issue #65 https://github.com/tlaplus/Examples/issues/65 Also see comment https://github.com/tlaplus/Examples/issues/65#issuecomment-1414013004 [Doc] Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- specifications/ewd998/SmokeEWD998.tla | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/specifications/ewd998/SmokeEWD998.tla b/specifications/ewd998/SmokeEWD998.tla index ea996eed..25c9d431 100644 --- a/specifications/ewd998/SmokeEWD998.tla +++ b/specifications/ewd998/SmokeEWD998.tla @@ -1,6 +1,9 @@ ------------------------------- MODULE SmokeEWD998 ------------------------------- EXTENDS EWD998, TLC, Randomization, IOUtils, CSV, FiniteSets +\* In theory, TLC can check this spec exhaustively, but it is not feasible. +ASSUME TLCGet("config").mode \in {"generate", "simulate"} + k == 10 @@ -40,4 +43,4 @@ BF == PN == CHOOSE s \in (1..10) : ToString(s) = IOEnv.PN -=============================================================================== \ No newline at end of file +=============================================================================== From 201c7c69817a1be4355b028d73e69da7588654ae Mon Sep 17 00:00:00 2001 From: Markus Alexander Kuppe Date: Tue, 7 Feb 2023 01:56:25 +0000 Subject: [PATCH 60/70] Blacklist tools/ folder created by .devcontainer.json. Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 6665df66..04e7499e 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,6 @@ tree-sitter-tlaplus/ # Ignore TTrace specs *_TTrace_*.tla +## Blacklist tools/ folder created by .devcontainer.json +tools/ + From 9f659aab9acf0e4b72b098ad9f473060df154ccc Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Tue, 14 Feb 2023 10:48:38 -0500 Subject: [PATCH 61/70] Update smoke test after fixes Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/scripts/check_small_models.py | 2 +- .github/scripts/smoke_test_large_models.py | 11 --------- manifest.json | 28 ++++++++-------------- 3 files changed, 11 insertions(+), 30 deletions(-) diff --git a/.github/scripts/check_small_models.py b/.github/scripts/check_small_models.py index b448b241..bc6740eb 100644 --- a/.github/scripts/check_small_models.py +++ b/.github/scripts/check_small_models.py @@ -58,7 +58,7 @@ def check_model(module_path, model, expected_runtime): for model in module['models'] if model['size'] == 'small' ], key = lambda m: m[2], - #reverse=True + reverse=True ) success = all([check_model(*model) for model in small_models]) diff --git a/.github/scripts/smoke_test_large_models.py b/.github/scripts/smoke_test_large_models.py index 359daca8..cd36548a 100644 --- a/.github/scripts/smoke_test_large_models.py +++ b/.github/scripts/smoke_test_large_models.py @@ -35,17 +35,6 @@ def check_model(module_path, model): # before termination or else it fails. This makes it not amenable to # smoke testing. 'specifications/KnuthYao/SimKnuthYao.cfg', - - # The following are bugs that should be fixed: - - # Attempted to access index 0 of tuple <<>> - 'specifications/SpecifyingSystems/AdvancedExamples/MCInnerSerial.cfg', - # Attempted to select nonexistent field "traces" from record - 'specifications/ewd426/SimTokenRing.cfg', - # Initial error cannot find TLAPS; if fixed, cannot find property "Stable" - 'specifications/ewd998/AsyncTerminationDetection_proof.cfg', - # Property is violated by the initial state - 'specifications/ewd998/SmokeEWD998.cfg' ] large_models = [ diff --git a/manifest.json b/manifest.json index 36b301a0..e231d5dc 100644 --- a/manifest.json +++ b/manifest.json @@ -2657,8 +2657,8 @@ { "path": "specifications/ewd426/SimTokenRing.cfg", "runtime": "unknown", - "size": "unknown", - "mode": "exhaustive search", + "size": "large", + "mode": "generate", "config": [], "features": [ "state constraint" @@ -2904,6 +2904,7 @@ "mode": "exhaustive search", "config": [], "features": [ + "liveness", "state constraint" ], "result": "success" @@ -2917,20 +2918,7 @@ "features": [ "proof" ], - "models": [ - { - "path": "specifications/ewd998/AsyncTerminationDetection_proof.cfg", - "runtime": "unknown", - "size": "unknown", - "mode": "exhaustive search", - "config": [], - "features": [ - "liveness", - "state constraint" - ], - "result": "unknown" - } - ] + "models": [] }, { "path": "specifications/ewd998/EWD998.tla", @@ -3111,8 +3099,12 @@ { "path": "specifications/ewd998/SmokeEWD998.cfg", "runtime": "unknown", - "size": "unknown", - "mode": "exhaustive search", + "size": "large", + "mode": { + "simulate": { + "traceCount": 100 + } + }, "config": [], "features": [ "liveness", From 8955d41e2b7922666cb2cdb99640780706454e18 Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Tue, 14 Feb 2023 15:44:00 -0500 Subject: [PATCH 62/70] Ran MCInnerSerial, ignore SimTokenRing Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/scripts/smoke_test_large_models.py | 3 +++ manifest.json | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/scripts/smoke_test_large_models.py b/.github/scripts/smoke_test_large_models.py index cd36548a..aabc3641 100644 --- a/.github/scripts/smoke_test_large_models.py +++ b/.github/scripts/smoke_test_large_models.py @@ -35,6 +35,9 @@ def check_model(module_path, model): # before termination or else it fails. This makes it not amenable to # smoke testing. 'specifications/KnuthYao/SimKnuthYao.cfg', + # SimTokenRing does not work on Windows systems. It doesn't seem worth + # it to code special logic handling this case so we just won't check it. + 'specifications/ewd426/SimTokenRing.cfg', ] large_models = [ diff --git a/manifest.json b/manifest.json index e231d5dc..f5550968 100644 --- a/manifest.json +++ b/manifest.json @@ -1393,15 +1393,15 @@ "models": [ { "path": "specifications/SpecifyingSystems/AdvancedExamples/MCInnerSerial.cfg", - "runtime": "unknown", - "size": "unknown", + "runtime": "00:01:30", + "size": "medium", "mode": "exhaustive search", "config": [], "features": [ "liveness", "state constraint" ], - "result": "unknown" + "result": "success" } ] }, From fb8077700075a8f3f3dba437674e604020a83167 Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Tue, 14 Feb 2023 22:35:32 -0500 Subject: [PATCH 63/70] Implement .ciignore Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/scripts/check_manifest_files.py | 26 ++++++++++++++++---- .github/scripts/generate_manifest.py | 32 +++++++++++++++++++------ .github/scripts/tla_utils.py | 14 +++++++++++ 3 files changed, 61 insertions(+), 11 deletions(-) diff --git a/.github/scripts/check_manifest_files.py b/.github/scripts/check_manifest_files.py index ee532342..7581a5fc 100644 --- a/.github/scripts/check_manifest_files.py +++ b/.github/scripts/check_manifest_files.py @@ -1,7 +1,8 @@ """ Checks to ensure all files in manifest.json exist, that all .tla and .cfg -files in repo are recorded in manifest.json, and that no files are present -twice in the manifest. +files in repo are recorded in manifest.json (except for those in .ciignore), +and that no files are present twice in the manifest. Also checks to ensure +no files in .ciignore are in the manifest.json. """ from collections import Counter @@ -22,17 +23,34 @@ cfg_mf_paths_cnt = Counter([normpath(model["path"]) for model_list in model_lists for model in model_list]) cfg_mf_paths = set(cfg_mf_paths_cnt) -# Get paths of all .tla and .cfg files in the specifications dir +# Get ignored directories +ignored_dirs = tla_utils.get_ignored_dirs() +ignore = lambda path : tla_utils.ignore(ignored_dirs, path) + +# Get paths of all non-ignored .tla and .cfg files in the specifications dir tla_fs_paths = set([ normpath(path) for path in glob.glob(f"./specifications/**/*.tla", recursive=True) - if '_TTrace_' not in path + if '_TTrace_' not in path and not ignore(path) ]) cfg_fs_paths = set([ normpath(path) for path in glob.glob(f"./specifications/**/*.cfg", recursive=True) + if not ignore(path) ]) success = True +# Check whether manifest includes any ignored paths +ignored_tla_in_manifest = set(filter(ignore, tla_mf_paths)) +ignored_cfg_in_manifest = set(filter(ignore, cfg_mf_paths)) +if any(ignored_tla_in_manifest): + success = False + print('Ignored .tla paths present in manifest:\n' + '\n'.join(ignored_tla_in_manifest)) + tla_mf_paths = tla_mf_paths - ignored_tla_in_manifest +if any(ignored_cfg_in_manifest): + success = False + print('Ignored .cfg paths present in manifest:\n' + '\n'.join(ignored_cfg_in_manifest)) + cfg_mf_paths = cfg_mf_paths - ignored_cfg_in_manifest + # Check for duplicate paths in manifest duplicate_tla_paths = [k for k, v in tla_mf_paths_cnt.items() if v > 1] duplicate_cfg_paths = [k for k, v in cfg_mf_paths_cnt.items() if v > 1] diff --git a/.github/scripts/generate_manifest.py b/.github/scripts/generate_manifest.py index d8c83197..d2b42d60 100644 --- a/.github/scripts/generate_manifest.py +++ b/.github/scripts/generate_manifest.py @@ -14,6 +14,7 @@ from pathlib import PureWindowsPath import glob import tla_utils +from tree_sitter import Language, Parser def to_posix(path): """ @@ -48,6 +49,14 @@ def get_cfg_files(tla_path): if splitext(basename(path))[0] not in other_module_names ] +Language.build_library( + 'build/tree-sitter-languages.so', + ['tree-sitter-tlaplus'] +) + +ignored_dirs = tla_utils.get_ignored_dirs() +ignore = lambda path : tla_utils.ignore(ignored_dirs, path) + # Generate new base manifest.json from files in specifications dir new_manifest = { 'specifications': [ @@ -82,17 +91,18 @@ def get_cfg_files(tla_path): } for dir in sorted( os.scandir('specifications'), key=lambda d: d.name - ) if dir.is_dir() and any(get_tla_files(dir)) + ) if dir.is_dir() and any(get_tla_files(dir)) and not ignore(dir.path) ] } # Integrate human-written info from existing manifest.json def find_corresponding_spec(old_spec, new_manifest): - return [ + specs = [ spec for spec in new_manifest['specifications'] if to_posix(spec['path']) == old_spec['path'] - ][0] + ] + return specs[0] if any(specs) else None def integrate_spec_info(old_spec, new_spec): fields = ['title', 'description', 'source', 'tags'] @@ -101,10 +111,11 @@ def integrate_spec_info(old_spec, new_spec): new_spec['authors'] = sorted(old_spec['authors']) def find_corresponding_module(old_module, new_spec): - return [ + modules = [ module for module in new_spec['modules'] if to_posix(module['path']) == to_posix(old_module['path']) - ][0] + ] + return modules[0] if any(modules) else None def integrate_module_info(old_module, new_module): fields = ['tlaLanguageVersion'] @@ -112,10 +123,11 @@ def integrate_module_info(old_module, new_module): new_module[field] = old_module[field] def find_corresponding_model(old_model, new_module): - return [ + models = [ model for model in new_module['models'] if to_posix(model['path']) == to_posix(old_model['path']) - ][0] + ] + return models[0] if any(models) else None def integrate_model_info(old_model, new_model): fields = ['runtime', 'size', 'mode', 'config', 'result'] @@ -126,12 +138,18 @@ def integrate_model_info(old_model, new_model): for old_spec in old_manifest['specifications']: new_spec = find_corresponding_spec(old_spec, new_manifest) + if new_spec is None: + continue integrate_spec_info(old_spec, new_spec) for old_module in old_spec['modules']: new_module = find_corresponding_module(old_module, new_spec) + if new_module is None: + continue integrate_module_info(old_module, new_module) for old_model in old_module['models']: new_model = find_corresponding_model(old_model, new_module) + if new_model is None: + continue integrate_model_info(old_model, new_model) # Write generated manifest to file diff --git a/.github/scripts/tla_utils.py b/.github/scripts/tla_utils.py index 0cc69e31..807ad77e 100644 --- a/.github/scripts/tla_utils.py +++ b/.github/scripts/tla_utils.py @@ -2,6 +2,20 @@ from os.path import normpath import subprocess +def ignore(ignored_dirs, path): + return any([normpath(path).startswith(ignore_dir) for ignore_dir in ignored_dirs]) + +def is_blank(text): + all([c.isspace() for c in text]) + +def get_ignored_dirs(): + with open('.ciignore', 'r') as ignore_file: + return set([ + normpath(line.strip()) + for line in ignore_file.readlines() + if not line.startswith('#') and not is_blank(line) + ]) + def load_json(path): with open(normpath(path), 'r', encoding='utf-8') as file: return json.load(file) From a9a699dc632f510d3fc4ff8746abd119f3435eef Mon Sep 17 00:00:00 2001 From: merz Date: Fri, 10 Feb 2023 11:49:10 +0100 Subject: [PATCH 64/70] fixed TLC configuration file for AsyncTerminationDetection and removed spurious configuration file for AsyncTerminationDetection_proof Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- specifications/ewd998/AsyncTerminationDetection.cfg | 7 +++++-- specifications/ewd998/AsyncTerminationDetection_proof.cfg | 6 ------ 2 files changed, 5 insertions(+), 8 deletions(-) delete mode 100644 specifications/ewd998/AsyncTerminationDetection_proof.cfg diff --git a/specifications/ewd998/AsyncTerminationDetection.cfg b/specifications/ewd998/AsyncTerminationDetection.cfg index 18cb94cc..2f190c71 100644 --- a/specifications/ewd998/AsyncTerminationDetection.cfg +++ b/specifications/ewd998/AsyncTerminationDetection.cfg @@ -1,10 +1,13 @@ -INIT Init -NEXT Next +SPECIFICATION + Spec CONSTANT N = 4 INVARIANTS TypeOK Safe +PROPERTIES + Quiescence + Live CONSTRAINT StateConstraint diff --git a/specifications/ewd998/AsyncTerminationDetection_proof.cfg b/specifications/ewd998/AsyncTerminationDetection_proof.cfg deleted file mode 100644 index ba1922f4..00000000 --- a/specifications/ewd998/AsyncTerminationDetection_proof.cfg +++ /dev/null @@ -1,6 +0,0 @@ -CONSTANT N = 5 -SPECIFICATION Spec -CONSTRAINT StateConstraint -PROPERTY Stable -PROPERTY Live -PROPERTY STDSpec From 38161a92ae5f675a94c6c2fb0d1aecd597ad9841 Mon Sep 17 00:00:00 2001 From: merz Date: Sat, 11 Feb 2023 09:19:07 +0100 Subject: [PATCH 65/70] fixed two issues in specifications/SpecifyingSystems Signed-off-by: merz Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .../SpecifyingSystems/AdvancedExamples/MCInnerSerial.tla | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/specifications/SpecifyingSystems/AdvancedExamples/MCInnerSerial.tla b/specifications/SpecifyingSystems/AdvancedExamples/MCInnerSerial.tla index a0f91135..ed1230a4 100644 --- a/specifications/SpecifyingSystems/AdvancedExamples/MCInnerSerial.tla +++ b/specifications/SpecifyingSystems/AdvancedExamples/MCInnerSerial.tla @@ -41,5 +41,6 @@ AlwaysResponds == /\ \A p \in Proc, r \in Reg : (regFile[p][r].op # "Free") ~> (regFile[p][r].op = "Free") /\ \A oi \in [proc : Proc, idx : Nat] : - (oi \in opId) ~> (opIdQ(oi).reg = Done) + (oi \in opId) ~> (oi \in opId /\ opIdQ(oi).reg = Done) + ============================================================================= From 638dc01c04c3697c005f43ff300f5bdd204a1ad2 Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Tue, 14 Feb 2023 22:41:13 -0500 Subject: [PATCH 66/70] Add .ciignore Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .ciignore | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .ciignore diff --git a/.ciignore b/.ciignore new file mode 100644 index 00000000..8bfa598e --- /dev/null +++ b/.ciignore @@ -0,0 +1,7 @@ +# Every line starting with # is a comment line +# Every non-blank non-comment line lists a directory to ignore in the CI +# This will keep parse or model check failures from failing the CI workflow +# Example: +specifications/doesnotexist +specifications/ewd998 + From 056a066160a9bc5f44f822bc2e5c704af2c89e50 Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Tue, 14 Feb 2023 22:44:25 -0500 Subject: [PATCH 67/70] Fixed .ciignore Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .ciignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ciignore b/.ciignore index 8bfa598e..2887d259 100644 --- a/.ciignore +++ b/.ciignore @@ -1,7 +1,7 @@ # Every line starting with # is a comment line # Every non-blank non-comment line lists a directory to ignore in the CI # This will keep parse or model check failures from failing the CI workflow +# Note that directory names are case-sensitive # Example: specifications/doesnotexist -specifications/ewd998 From 4eabb2e1bdb2153c3bfdef9c77a6028b2d043234 Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Tue, 14 Feb 2023 23:03:19 -0500 Subject: [PATCH 68/70] Run model except on win Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- .github/scripts/smoke_test_large_models.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/scripts/smoke_test_large_models.py b/.github/scripts/smoke_test_large_models.py index aabc3641..5c51bcd0 100644 --- a/.github/scripts/smoke_test_large_models.py +++ b/.github/scripts/smoke_test_large_models.py @@ -5,6 +5,7 @@ """ import logging +import os import tla_utils def check_model(module_path, model): @@ -35,10 +36,8 @@ def check_model(module_path, model): # before termination or else it fails. This makes it not amenable to # smoke testing. 'specifications/KnuthYao/SimKnuthYao.cfg', - # SimTokenRing does not work on Windows systems. It doesn't seem worth - # it to code special logic handling this case so we just won't check it. - 'specifications/ewd426/SimTokenRing.cfg', -] + # SimTokenRing does not work on Windows systems. +] + (['specifications/ewd426/SimTokenRing.cfg'] if os.name == 'nt' else []) large_models = [ (module['path'], model) From 791a245d0f88343a96b188f3c9a6837e9d08bfc7 Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Tue, 14 Feb 2023 23:17:50 -0500 Subject: [PATCH 69/70] Update README instructions for .ciignore Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- README.md | 73 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index 240c0d24..9078a4f1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # TLA+ Examples [![Gitpod ready-to-code](https://img.shields.io/badge/Gitpod-ready--to--spec-908a85?logo=gitpod)](https://gitpod.io/#https://github.com/tlaplus/examples/) -[![Validate Specs & Models](https://github.com/tlaplus/examples/actions/workflows/ci.yml/badge.svg)](https://github.com/tlaplus/examples/actions/workflows/ci.yml) +[![Validate Specs & Models](https://github.com/tlaplus/Examples/actions/workflows/CI.yml/badge.svg)](https://github.com/tlaplus/Examples/actions/workflows/CI.yml) This is a repository of TLA+ specifications and models covering applications in a variety of fields. It serves as: @@ -9,6 +9,7 @@ It serves as: - a collection of case studies in the application of formal specification in TLA+ All TLA+ specs can be found in the `specifications` directory. +A central manifest of specs with descriptions and accounts of their various models and features can be found in the [`manifest.json`](manifest.json) file. ## Contributing @@ -18,40 +19,48 @@ Follow these instructions: 1. Fork this repository and create a new directory under `specifications` with the name of your spec 1. Place all TLA+ files in the directory, along with their `.cfg` model files; you are encouraged to include at least one model that completes execution in less than 10 seconds 1. Ensure name of each `.cfg` file matches the `.tla` file it models, or has its name as a prefix; for example `SpecName.tla` can have the models `SpecName.cfg` and `SpecNameLiveness.cfg`, etc. -1. Consider including a `README.md` explaining the significance of the spec with links to any relevant websites or publications, or integrate this info as comments in the spec itself +1. Consider including a `README.md` in the spec directory explaining the significance of the spec with links to any relevant websites or publications, or integrate this info as comments in the spec itself 1. Add an entry to the below table in this top-level `README.md` summarizing your spec and its attributes -1. Update the `manifest.json` file with machine-readable records of your spec files, either manually or with a script as follows: - 1. Ensure you have Python 3.X installed - 1. Download & extract [tree-sitter-tlaplus](https://github.com/tlaplus-community/tree-sitter-tlaplus/archive/refs/heads/main.zip) to the root of the repository; ensure the extracted folder is named `tree-sitter-tlaplus` - 1. Run `pip install -r .github/scripts/requirements.txt` - 1. Run `python .github/scripts/generate_manifest.py` + +## Adding Spec to Continuous Integration + +To combat bitrot, it is important to add your spec and model to the continuous integration system. +To do this, you'll have to update the `manifest.json` file with machine-readable records of your spec files. +If this process doesn't work for you, you can alternatively modify the [`.ciignore`](.ciignore) file to exclude your spec from validation. +Otherwise, follow these directions: + +1. Ensure you have Python 3.X installed +1. Download & extract tree-sitter-tlaplus ([zip](https://github.com/tlaplus-community/tree-sitter-tlaplus/archive/refs/heads/main.zip), [tar.gz](https://github.com/tlaplus-community/tree-sitter-tlaplus/archive/refs/heads/main.tar.gz)) to the root of the repository; ensure the extracted folder is named `tree-sitter-tlaplus` +1. Open a shell and navigate to the repo root; ensure a C++ compiler is installed and on your path + - On Windows, this might entail running the below script from the visual studio developer command prompt +1. Run `pip install -r .github/scripts/requirements.txt` +1. Run `python .github/scripts/generate_manifest.py` 1. Locate your spec's entry in the `manifest.json` file and ensure the following fields are filled out: - - Spec title: an appropriate title for your specification - - Spec description: a short description of your specification - - Spec source: if this spec was first published elsewhere, provide a link to this location - - Spec authors: a list of people who authored the spec - - Spec tags: - - `"beginner"` if your spec is appropriate for TLA+ newcomers - - Model runtime: approximate model runtime on an ordinary workstation, in `"HH:MM:SS"` format - - Model size: - - `"small"` if the model can be executed in less than 10 seconds - - `"medium"` if the model can be executed in less than five minutes - - `"large"` if the model takes more than five minutes to execute - - Model mode: - - `"exhaustive search"` by default - - `{"simulate": {"traceCount": N}}` for a simulation model - - `"generate"` for model trace generation - - Model config: - - `"ignore deadlock"` if your model should ignore deadlock - - Model result: - - `"success"` if the model completes successfully - - `"safety failure"` if the model violates an invariant - - `"liveness failure"` if the model fails to satisfy a liveness property - - `"deadlock failure"` if the model encounters deadlock - - Other fields are auto-generated by the script; if you are adding an entry manually, ensure their values are present and correct (see other entries or the `manifest-schema.json` file) + - Spec title: an appropriate title for your specification + - Spec description: a short description of your specification + - Spec source: if this spec was first published elsewhere, provide a link to this location + - Spec authors: a list of people who authored the spec + - Spec tags: + - `"beginner"` if your spec is appropriate for TLA+ newcomers + - Model runtime: approximate model runtime on an ordinary workstation, in `"HH:MM:SS"` format + - Model size: + - `"small"` if the model can be executed in less than 10 seconds + - `"medium"` if the model can be executed in less than five minutes + - `"large"` if the model takes more than five minutes to execute + - Model mode: + - `"exhaustive search"` by default + - `{"simulate": {"traceCount": N}}` for a simulation model + - `"generate"` for model trace generation + - Model config: + - `"ignore deadlock"` if your model should ignore deadlock + - Model result: + - `"success"` if the model completes successfully + - `"safety failure"` if the model violates an invariant + - `"liveness failure"` if the model fails to satisfy a liveness property + - `"deadlock failure"` if the model encounters deadlock + - Other fields are auto-generated by the script; if you are adding an entry manually, ensure their values are present and correct (see other entries or the `manifest-schema.json` file) -The `manifest.json` file is checked for conformance to the repo's specs by a continuous integration script. -All specs and models are also checked for parsing and execution by the CI script. +Before submitted your changes to run in the CI, you can quickly check your `manifest.json` for errors and also check it against [`manifest-schema.json`](manifest-schema.json) at https://www.jsonschemavalidator.net/. ## List of Examples From 20d48dd899926a7d223b5ce8c95b83e0ce0f8cee Mon Sep 17 00:00:00 2001 From: Andrew Helwer <2n8rn1w1f@mozmail.com> Date: Tue, 14 Feb 2023 23:33:21 -0500 Subject: [PATCH 70/70] Fixed bullets in readme Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com> --- README.md | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 9078a4f1..dec2fea2 100644 --- a/README.md +++ b/README.md @@ -36,29 +36,29 @@ Otherwise, follow these directions: 1. Run `pip install -r .github/scripts/requirements.txt` 1. Run `python .github/scripts/generate_manifest.py` 1. Locate your spec's entry in the `manifest.json` file and ensure the following fields are filled out: - - Spec title: an appropriate title for your specification - - Spec description: a short description of your specification - - Spec source: if this spec was first published elsewhere, provide a link to this location - - Spec authors: a list of people who authored the spec - - Spec tags: - - `"beginner"` if your spec is appropriate for TLA+ newcomers - - Model runtime: approximate model runtime on an ordinary workstation, in `"HH:MM:SS"` format - - Model size: - - `"small"` if the model can be executed in less than 10 seconds - - `"medium"` if the model can be executed in less than five minutes - - `"large"` if the model takes more than five minutes to execute - - Model mode: - - `"exhaustive search"` by default - - `{"simulate": {"traceCount": N}}` for a simulation model - - `"generate"` for model trace generation - - Model config: - - `"ignore deadlock"` if your model should ignore deadlock - - Model result: - - `"success"` if the model completes successfully - - `"safety failure"` if the model violates an invariant - - `"liveness failure"` if the model fails to satisfy a liveness property - - `"deadlock failure"` if the model encounters deadlock - - Other fields are auto-generated by the script; if you are adding an entry manually, ensure their values are present and correct (see other entries or the `manifest-schema.json` file) + - Spec title: an appropriate title for your specification + - Spec description: a short description of your specification + - Spec source: if this spec was first published elsewhere, provide a link to this location + - Spec authors: a list of people who authored the spec + - Spec tags: + - `"beginner"` if your spec is appropriate for TLA+ newcomers + - Model runtime: approximate model runtime on an ordinary workstation, in `"HH:MM:SS"` format + - Model size: + - `"small"` if the model can be executed in less than 10 seconds + - `"medium"` if the model can be executed in less than five minutes + - `"large"` if the model takes more than five minutes to execute + - Model mode: + - `"exhaustive search"` by default + - `{"simulate": {"traceCount": N}}` for a simulation model + - `"generate"` for model trace generation + - Model config: + - `"ignore deadlock"` if your model should ignore deadlock + - Model result: + - `"success"` if the model completes successfully + - `"safety failure"` if the model violates an invariant + - `"liveness failure"` if the model fails to satisfy a liveness property + - `"deadlock failure"` if the model encounters deadlock + - Other fields are auto-generated by the script; if you are adding an entry manually, ensure their values are present and correct (see other entries or the `manifest-schema.json` file) Before submitted your changes to run in the CI, you can quickly check your `manifest.json` for errors and also check it against [`manifest-schema.json`](manifest-schema.json) at https://www.jsonschemavalidator.net/.