diff options
author | Kristóf Marussy <marussy@mit.bme.hu> | 2023-12-25 13:57:04 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-25 13:57:04 +0100 |
commit | fa25d614455dd0872bfa6ff88c5be3ecfc33a6af (patch) | |
tree | 84aba7f8ce90ff5aea38c912b3999ec7810f6f44 | |
parent | chore: upgrade to Eclipse 2023-12 (diff) | |
parent | refactor(generator): scope overrides (diff) | |
download | refinery-fa25d614455dd0872bfa6ff88c5be3ecfc33a6af.tar.gz refinery-fa25d614455dd0872bfa6ff88c5be3ecfc33a6af.tar.zst refinery-fa25d614455dd0872bfa6ff88c5be3ecfc33a6af.zip |
Merge pull request #50 from kris7t/generator-roundtrip
Round-trip model serialization and command line application
50 files changed, 2055 insertions, 531 deletions
diff --git a/.yarnrc.yml b/.yarnrc.yml index cf12e2d9..305b9b6a 100644 --- a/.yarnrc.yml +++ b/.yarnrc.yml | |||
@@ -4,7 +4,7 @@ enableTelemetry: false | |||
4 | 4 | ||
5 | logFilters: | 5 | logFilters: |
6 | - level: discard | 6 | - level: discard |
7 | text: "prettier is listed by your project with version 3.1.0, which doesn't satisfy what @xstate/cli (p708d6) and other dependencies request (^2.0.0)." | 7 | text: "prettier is listed by your project with version 3.1.1, which doesn't satisfy what @xstate/cli (p072c3) and other dependencies request (^2.0.0)." |
8 | 8 | ||
9 | nodeLinker: pnp | 9 | nodeLinker: pnp |
10 | 10 | ||
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 06b76786..e65ffc03 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | [versions] | 5 | [versions] |
6 | eclipseCollections = "12.0.0.M3" | 6 | eclipseCollections = "12.0.0.M3" |
7 | jetty = "12.0.3" | 7 | jetty = "12.0.5" |
8 | jmh = "1.37" | 8 | jmh = "1.37" |
9 | junit = "5.10.1" | 9 | junit = "5.10.1" |
10 | mockito = "5.8.0" | 10 | mockito = "5.8.0" |
@@ -23,6 +23,7 @@ gradlePlugin-shadow = { group = "com.github.johnrengelman", name = "shadow", ver | |||
23 | gradlePlugin-sonarqube = { group = "org.sonarsource.scanner.gradle", name = "sonarqube-gradle-plugin", version = "4.4.1.3373" } | 23 | gradlePlugin-sonarqube = { group = "org.sonarsource.scanner.gradle", name = "sonarqube-gradle-plugin", version = "4.4.1.3373" } |
24 | gson = { group = "com.google.code.gson", name = "gson", version = "2.10.1" } | 24 | gson = { group = "com.google.code.gson", name = "gson", version = "2.10.1" } |
25 | hamcrest = { group = "org.hamcrest", name = "hamcrest", version = "2.2" } | 25 | hamcrest = { group = "org.hamcrest", name = "hamcrest", version = "2.2" } |
26 | jcommander = { group = "org.jcommander", name = "jcommander", version = "1.83" } | ||
26 | jetbrainsAnnotations = { group = "org.jetbrains", name = "annotations", version = "24.1.0" } | 27 | jetbrainsAnnotations = { group = "org.jetbrains", name = "annotations", version = "24.1.0" } |
27 | jetty-server = { group = "org.eclipse.jetty", name = "jetty-server", version.ref = "jetty" } | 28 | jetty-server = { group = "org.eclipse.jetty", name = "jetty-server", version.ref = "jetty" } |
28 | jetty-servlet = { group = "org.eclipse.jetty.ee10", name = "jetty-ee10-servlet", version.ref = "jetty" } | 29 | jetty-servlet = { group = "org.eclipse.jetty.ee10", name = "jetty-ee10-servlet", version.ref = "jetty" } |
diff --git a/package.json b/package.json index 6dbe66ad..a61c71d4 100644 --- a/package.json +++ b/package.json | |||
@@ -25,8 +25,8 @@ | |||
25 | }, | 25 | }, |
26 | "packageManager": "yarn@4.0.2", | 26 | "packageManager": "yarn@4.0.2", |
27 | "devDependencies": { | 27 | "devDependencies": { |
28 | "eslint": "^8.55.0", | 28 | "eslint": "^8.56.0", |
29 | "typescript": "5.3.2" | 29 | "typescript": "5.3.3" |
30 | }, | 30 | }, |
31 | "resolutions": { | 31 | "resolutions": { |
32 | "d3-zoom@npm:^3.0.0": "patch:d3-zoom@npm%3A3.0.0#~/.yarn/patches/d3-zoom-npm-3.0.0-18f706a421.patch", | 32 | "d3-zoom@npm:^3.0.0": "patch:d3-zoom@npm%3A3.0.0#~/.yarn/patches/d3-zoom-npm-3.0.0-18f706a421.patch", |
diff --git a/settings.gradle.kts b/settings.gradle.kts index 40df30ff..6e5a72e9 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts | |||
@@ -9,6 +9,7 @@ rootProject.name = "refinery" | |||
9 | include( | 9 | include( |
10 | "frontend", | 10 | "frontend", |
11 | "generator", | 11 | "generator", |
12 | "generator-cli", | ||
12 | "interpreter", | 13 | "interpreter", |
13 | "interpreter-localsearch", | 14 | "interpreter-localsearch", |
14 | "interpreter-rete", | 15 | "interpreter-rete", |
diff --git a/subprojects/frontend/config/graphvizUMDVitePlugin.ts b/subprojects/frontend/config/graphvizUMDVitePlugin.ts index ab726e4f..0c3c9aa0 100644 --- a/subprojects/frontend/config/graphvizUMDVitePlugin.ts +++ b/subprojects/frontend/config/graphvizUMDVitePlugin.ts | |||
@@ -27,13 +27,15 @@ export default function graphvizUMDVitePlugin(): PluginOption { | |||
27 | async buildStart() { | 27 | async buildStart() { |
28 | const issuer = | 28 | const issuer = |
29 | root === undefined ? issuerFileName : path.join(root, issuerFileName); | 29 | root === undefined ? issuerFileName : path.join(root, issuerFileName); |
30 | const resolvedPath = pnpapi.resolveRequest( | 30 | // Since https://github.com/hpcc-systems/hpcc-js-wasm/commit/15e1ace5edae7f94714e547a3ac20e0e17cd6b0c, |
31 | '@hpcc-js/wasm/graphviz', | 31 | // hpcc-js has both a `.cjs` and a `.umd.js` build. PnPAPI will find the former, but we need the latter. |
32 | issuer, | 32 | const resolvedPath = pnpapi |
33 | ); | 33 | .resolveRequest('@hpcc-js/wasm/graphviz', issuer) |
34 | if (resolvedPath === null) { | 34 | ?.replace(/\.cjs$/, '.umd.js'); |
35 | if (resolvedPath === undefined) { | ||
35 | return; | 36 | return; |
36 | } | 37 | } |
38 | console.log(resolvedPath); | ||
37 | if (command === 'serve') { | 39 | if (command === 'serve') { |
38 | url = `/@fs/${resolvedPath}`; | 40 | url = `/@fs/${resolvedPath}`; |
39 | } else { | 41 | } else { |
diff --git a/subprojects/frontend/package.json b/subprojects/frontend/package.json index f55093ce..9dec8b32 100644 --- a/subprojects/frontend/package.json +++ b/subprojects/frontend/package.json | |||
@@ -33,23 +33,23 @@ | |||
33 | "@codemirror/language": "^6.9.3", | 33 | "@codemirror/language": "^6.9.3", |
34 | "@codemirror/lint": "^6.4.2", | 34 | "@codemirror/lint": "^6.4.2", |
35 | "@codemirror/search": "^6.5.5", | 35 | "@codemirror/search": "^6.5.5", |
36 | "@codemirror/state": "^6.3.2", | 36 | "@codemirror/state": "^6.3.3", |
37 | "@codemirror/view": "^6.22.1", | 37 | "@codemirror/view": "^6.22.3", |
38 | "@emotion/react": "^11.11.1", | 38 | "@emotion/react": "^11.11.3", |
39 | "@emotion/styled": "^11.11.0", | 39 | "@emotion/styled": "^11.11.0", |
40 | "@fontsource-variable/jetbrains-mono": "^5.0.18", | 40 | "@fontsource-variable/jetbrains-mono": "^5.0.19", |
41 | "@fontsource-variable/open-sans": "^5.0.18", | 41 | "@fontsource-variable/open-sans": "^5.0.21", |
42 | "@hpcc-js/wasm": "^2.15.0", | 42 | "@hpcc-js/wasm": "^2.15.3", |
43 | "@lezer/common": "^1.1.1", | 43 | "@lezer/common": "^1.1.2", |
44 | "@lezer/highlight": "^1.2.0", | 44 | "@lezer/highlight": "^1.2.0", |
45 | "@lezer/lr": "^1.3.14", | 45 | "@lezer/lr": "^1.3.14", |
46 | "@material-icons/svg": "^1.0.33", | 46 | "@material-icons/svg": "^1.0.33", |
47 | "@mui/icons-material": "5.14.19", | 47 | "@mui/icons-material": "^5.15.1", |
48 | "@mui/material": "5.14.19", | 48 | "@mui/material": "^5.15.1", |
49 | "@mui/system": "^5.14.19", | 49 | "@mui/system": "^5.15.1", |
50 | "@mui/x-data-grid": "^6.18.2", | 50 | "@mui/x-data-grid": "^6.18.6", |
51 | "ansi-styles": "^6.2.1", | 51 | "ansi-styles": "^6.2.1", |
52 | "csstype": "^3.1.2", | 52 | "csstype": "^3.1.3", |
53 | "d3": "^7.8.5", | 53 | "d3": "^7.8.5", |
54 | "d3-graphviz": "patch:d3-graphviz@npm%3A5.2.0#~/.yarn/patches/d3-graphviz-npm-5.2.0-161b1fbad4.patch", | 54 | "d3-graphviz": "patch:d3-graphviz@npm%3A5.2.0#~/.yarn/patches/d3-graphviz-npm-5.2.0-161b1fbad4.patch", |
55 | "d3-selection": "^3.0.0", | 55 | "d3-selection": "^3.0.0", |
@@ -65,7 +65,7 @@ | |||
65 | "notistack": "^3.0.1", | 65 | "notistack": "^3.0.1", |
66 | "react": "^18.2.0", | 66 | "react": "^18.2.0", |
67 | "react-dom": "^18.2.0", | 67 | "react-dom": "^18.2.0", |
68 | "react-resize-detector": "^9.1.0", | 68 | "react-resize-detector": "^9.1.1", |
69 | "xstate": "^4.38.3", | 69 | "xstate": "^4.38.3", |
70 | "zod": "^3.22.4" | 70 | "zod": "^3.22.4" |
71 | }, | 71 | }, |
@@ -75,38 +75,38 @@ | |||
75 | "@types/d3-graphviz": "^2.6.10", | 75 | "@types/d3-graphviz": "^2.6.10", |
76 | "@types/d3-selection": "^3.0.10", | 76 | "@types/d3-selection": "^3.0.10", |
77 | "@types/d3-zoom": "^3.0.8", | 77 | "@types/d3-zoom": "^3.0.8", |
78 | "@types/eslint": "^8.44.8", | 78 | "@types/eslint": "^8.56.0", |
79 | "@types/html-minifier-terser": "^7.0.2", | 79 | "@types/html-minifier-terser": "^7.0.2", |
80 | "@types/lodash-es": "^4.17.12", | 80 | "@types/lodash-es": "^4.17.12", |
81 | "@types/micromatch": "^4.0.6", | 81 | "@types/micromatch": "^4.0.6", |
82 | "@types/ms": "^0.7.34", | 82 | "@types/ms": "^0.7.34", |
83 | "@types/node": "^20.10.2", | 83 | "@types/node": "^20.10.5", |
84 | "@types/pnpapi": "^0.0.5", | 84 | "@types/pnpapi": "^0.0.5", |
85 | "@types/react": "^18.2.41", | 85 | "@types/react": "^18.2.45", |
86 | "@types/react-dom": "^18.2.17", | 86 | "@types/react-dom": "^18.2.18", |
87 | "@typescript-eslint/eslint-plugin": "^6.13.1", | 87 | "@typescript-eslint/eslint-plugin": "^6.15.0", |
88 | "@typescript-eslint/parser": "^6.13.1", | 88 | "@typescript-eslint/parser": "^6.15.0", |
89 | "@vitejs/plugin-react-swc": "^3.5.0", | 89 | "@vitejs/plugin-react-swc": "^3.5.0", |
90 | "@xstate/cli": "^0.5.11", | 90 | "@xstate/cli": "^0.5.15", |
91 | "cross-env": "^7.0.3", | 91 | "cross-env": "^7.0.3", |
92 | "eslint": "^8.55.0", | 92 | "eslint": "^8.56.0", |
93 | "eslint-config-airbnb": "^19.0.4", | 93 | "eslint-config-airbnb": "^19.0.4", |
94 | "eslint-config-airbnb-typescript": "^17.1.0", | 94 | "eslint-config-airbnb-typescript": "^17.1.0", |
95 | "eslint-config-prettier": "^9.1.0", | 95 | "eslint-config-prettier": "^9.1.0", |
96 | "eslint-import-resolver-typescript": "^3.6.1", | 96 | "eslint-import-resolver-typescript": "^3.6.1", |
97 | "eslint-plugin-import": "^2.29.0", | 97 | "eslint-plugin-import": "^2.29.1", |
98 | "eslint-plugin-jsx-a11y": "^6.8.0", | 98 | "eslint-plugin-jsx-a11y": "^6.8.0", |
99 | "eslint-plugin-mobx": "^0.0.9", | 99 | "eslint-plugin-mobx": "^0.0.9", |
100 | "eslint-plugin-prettier": "^5.0.1", | 100 | "eslint-plugin-prettier": "^5.1.1", |
101 | "eslint-plugin-react": "^7.33.2", | 101 | "eslint-plugin-react": "^7.33.2", |
102 | "eslint-plugin-react-hooks": "^4.6.0", | 102 | "eslint-plugin-react-hooks": "^4.6.0", |
103 | "html-minifier-terser": "^7.2.0", | 103 | "html-minifier-terser": "^7.2.0", |
104 | "micromatch": "^4.0.5", | 104 | "micromatch": "^4.0.5", |
105 | "pnpapi": "^0.0.0", | 105 | "pnpapi": "^0.0.0", |
106 | "prettier": "^3.1.0", | 106 | "prettier": "^3.1.1", |
107 | "typescript": "5.3.2", | 107 | "typescript": "5.3.3", |
108 | "vite": "^5.0.4", | 108 | "vite": "^5.0.10", |
109 | "vite-plugin-pwa": "^0.17.2", | 109 | "vite-plugin-pwa": "^0.17.4", |
110 | "workbox-window": "^7.0.0" | 110 | "workbox-window": "^7.0.0" |
111 | } | 111 | } |
112 | } | 112 | } |
diff --git a/subprojects/generator-cli/build.gradle.kts b/subprojects/generator-cli/build.gradle.kts new file mode 100644 index 00000000..6c681222 --- /dev/null +++ b/subprojects/generator-cli/build.gradle.kts | |||
@@ -0,0 +1,24 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | |||
7 | plugins { | ||
8 | id("tools.refinery.gradle.java-application") | ||
9 | } | ||
10 | |||
11 | dependencies { | ||
12 | implementation(project(":refinery-generator")) | ||
13 | implementation(libs.jcommander) | ||
14 | implementation(libs.slf4j.api) | ||
15 | } | ||
16 | |||
17 | application { | ||
18 | mainClass.set("tools.refinery.generator.cli.RefineryCli") | ||
19 | } | ||
20 | |||
21 | tasks.shadowJar { | ||
22 | // Silence Xtext warning. | ||
23 | append("plugin.properties") | ||
24 | } | ||
diff --git a/subprojects/generator-cli/src/main/java/tools/refinery/generator/cli/RefineryCli.java b/subprojects/generator-cli/src/main/java/tools/refinery/generator/cli/RefineryCli.java new file mode 100644 index 00000000..5de579e6 --- /dev/null +++ b/subprojects/generator-cli/src/main/java/tools/refinery/generator/cli/RefineryCli.java | |||
@@ -0,0 +1,64 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.generator.cli; | ||
7 | |||
8 | import com.beust.jcommander.JCommander; | ||
9 | import com.beust.jcommander.ParameterException; | ||
10 | import com.google.inject.Inject; | ||
11 | import tools.refinery.generator.cli.commands.GenerateCommand; | ||
12 | import tools.refinery.generator.standalone.StandaloneRefinery; | ||
13 | |||
14 | import java.io.IOException; | ||
15 | |||
16 | public class RefineryCli { | ||
17 | private static final String GENERATE_COMMAND = "generate"; | ||
18 | |||
19 | @Inject | ||
20 | private GenerateCommand generateCommand; | ||
21 | |||
22 | private JCommander jCommander; | ||
23 | |||
24 | public String parseArguments(String... args) { | ||
25 | var jc = getJCommander(); | ||
26 | jc.parse(args); | ||
27 | return jc.getParsedCommand(); | ||
28 | } | ||
29 | |||
30 | public void run(String command) throws IOException { | ||
31 | switch (command) { | ||
32 | case GENERATE_COMMAND -> generateCommand.run(); | ||
33 | case null, default -> showUsageAndExit(); | ||
34 | } | ||
35 | } | ||
36 | |||
37 | public void showUsageAndExit() { | ||
38 | getJCommander().usage(); | ||
39 | System.exit(1); | ||
40 | } | ||
41 | |||
42 | private JCommander getJCommander() { | ||
43 | if (jCommander == null) { | ||
44 | jCommander = JCommander.newBuilder() | ||
45 | .programName("refinery") | ||
46 | .addObject(this) | ||
47 | .addCommand(GENERATE_COMMAND, generateCommand) | ||
48 | .build(); | ||
49 | } | ||
50 | return jCommander; | ||
51 | } | ||
52 | |||
53 | public static void main(String[] args) throws IOException { | ||
54 | var cli = StandaloneRefinery.getInjector().getInstance(RefineryCli.class); | ||
55 | String command = null; | ||
56 | try { | ||
57 | command = cli.parseArguments(args); | ||
58 | } catch (ParameterException e) { | ||
59 | System.err.println(e.getMessage()); | ||
60 | cli.showUsageAndExit(); | ||
61 | } | ||
62 | cli.run(command); | ||
63 | } | ||
64 | } | ||
diff --git a/subprojects/generator-cli/src/main/java/tools/refinery/generator/cli/commands/GenerateCommand.java b/subprojects/generator-cli/src/main/java/tools/refinery/generator/cli/commands/GenerateCommand.java new file mode 100644 index 00000000..b33fce23 --- /dev/null +++ b/subprojects/generator-cli/src/main/java/tools/refinery/generator/cli/commands/GenerateCommand.java | |||
@@ -0,0 +1,87 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.generator.cli.commands; | ||
7 | |||
8 | import com.beust.jcommander.Parameter; | ||
9 | import com.beust.jcommander.Parameters; | ||
10 | import com.google.inject.Inject; | ||
11 | import org.eclipse.emf.ecore.resource.Resource; | ||
12 | import tools.refinery.generator.ModelGeneratorFactory; | ||
13 | import tools.refinery.generator.ProblemLoader; | ||
14 | |||
15 | import java.io.FileOutputStream; | ||
16 | import java.io.IOException; | ||
17 | import java.util.ArrayList; | ||
18 | import java.util.List; | ||
19 | import java.util.Map; | ||
20 | |||
21 | @Parameters(commandDescription = "Generate a model from a partial model") | ||
22 | public class GenerateCommand { | ||
23 | @Inject | ||
24 | private ProblemLoader loader; | ||
25 | |||
26 | @Inject | ||
27 | private ModelGeneratorFactory generatorFactory; | ||
28 | |||
29 | private String inputPath; | ||
30 | private String outputPath = "-"; | ||
31 | private List<String> scopes = new ArrayList<>(); | ||
32 | private List<String> overrideScopes = new ArrayList<>(); | ||
33 | private long randomSeed = 1; | ||
34 | |||
35 | @Parameter(description = "input path", required = true) | ||
36 | public void setInputPath(String inputPath) { | ||
37 | this.inputPath = inputPath; | ||
38 | } | ||
39 | |||
40 | @Parameter(names = {"-output", "-o"}, description = "Output path") | ||
41 | public void setOutputPath(String outputPath) { | ||
42 | this.outputPath = outputPath; | ||
43 | } | ||
44 | |||
45 | @Parameter(names = {"-scope", "-s"}, description = "Extra scope constraints") | ||
46 | public void setScopes(List<String> scopes) { | ||
47 | this.scopes = scopes; | ||
48 | } | ||
49 | |||
50 | @Parameter(names = {"-scope-override", "-S"}, description = "Override scope constraints") | ||
51 | public void setOverrideScopes(List<String> overrideScopes) { | ||
52 | this.overrideScopes = overrideScopes; | ||
53 | } | ||
54 | |||
55 | @Parameter(names = {"-random-seed", "-r"}, description = "Random seed") | ||
56 | public void setRandomSeed(long randomSeed) { | ||
57 | this.randomSeed = randomSeed; | ||
58 | } | ||
59 | |||
60 | public void run() throws IOException { | ||
61 | var problem = isStandardStream(inputPath) ? loader.loadStream(System.in) : loader.loadFile(inputPath); | ||
62 | problem = loader.loadScopeConstraints(problem, scopes, overrideScopes); | ||
63 | var generator = generatorFactory.createGenerator(problem); | ||
64 | generator.setRandomSeed(randomSeed); | ||
65 | generator.generate(); | ||
66 | var solution = generator.serializeSolution(); | ||
67 | var solutionResource = solution.eResource(); | ||
68 | var saveOptions = Map.of(); | ||
69 | if (isStandardStream(outputPath)) { | ||
70 | printSolution(solutionResource, saveOptions); | ||
71 | } else { | ||
72 | try (var outputStream = new FileOutputStream(outputPath)) { | ||
73 | solutionResource.save(outputStream, saveOptions); | ||
74 | } | ||
75 | } | ||
76 | } | ||
77 | |||
78 | private boolean isStandardStream(String path) { | ||
79 | return path == null || path.equals("-"); | ||
80 | } | ||
81 | |||
82 | // We deliberately write to the standard output if no output path is specified. | ||
83 | @SuppressWarnings("squid:S106") | ||
84 | private void printSolution(Resource solutionResource, Map<?, ?> saveOptions) throws IOException { | ||
85 | solutionResource.save(System.out, saveOptions); | ||
86 | } | ||
87 | } | ||
diff --git a/subprojects/generator/build.gradle.kts b/subprojects/generator/build.gradle.kts index d87ce6de..f78fee4d 100644 --- a/subprojects/generator/build.gradle.kts +++ b/subprojects/generator/build.gradle.kts | |||
@@ -12,4 +12,5 @@ dependencies { | |||
12 | api(project(":refinery-language-semantics")) | 12 | api(project(":refinery-language-semantics")) |
13 | api(libs.eclipseCollections.api) | 13 | api(libs.eclipseCollections.api) |
14 | implementation(project(":refinery-store-query-interpreter")) | 14 | implementation(project(":refinery-store-query-interpreter")) |
15 | testImplementation(testFixtures(project(":refinery-language"))) | ||
15 | } | 16 | } |
diff --git a/subprojects/generator/src/main/java/tools/refinery/generator/ModelGenerator.java b/subprojects/generator/src/main/java/tools/refinery/generator/ModelGenerator.java index 5b44c10a..1515dceb 100644 --- a/subprojects/generator/src/main/java/tools/refinery/generator/ModelGenerator.java +++ b/subprojects/generator/src/main/java/tools/refinery/generator/ModelGenerator.java | |||
@@ -5,7 +5,10 @@ | |||
5 | */ | 5 | */ |
6 | package tools.refinery.generator; | 6 | package tools.refinery.generator; |
7 | 7 | ||
8 | import com.google.inject.Provider; | ||
9 | import tools.refinery.language.model.problem.Problem; | ||
8 | import tools.refinery.language.semantics.ProblemTrace; | 10 | import tools.refinery.language.semantics.ProblemTrace; |
11 | import tools.refinery.language.semantics.SolutionSerializer; | ||
9 | import tools.refinery.store.dse.strategy.BestFirstStoreManager; | 12 | import tools.refinery.store.dse.strategy.BestFirstStoreManager; |
10 | import tools.refinery.store.map.Version; | 13 | import tools.refinery.store.map.Version; |
11 | import tools.refinery.store.model.ModelStore; | 14 | import tools.refinery.store.model.ModelStore; |
@@ -16,21 +19,22 @@ import tools.refinery.store.reasoning.seed.ModelSeed; | |||
16 | 19 | ||
17 | public class ModelGenerator extends ModelFacade { | 20 | public class ModelGenerator extends ModelFacade { |
18 | private final Version initialVersion; | 21 | private final Version initialVersion; |
19 | 22 | private final Provider<SolutionSerializer> solutionSerializerProvider; | |
20 | private int randomSeed = 0; | 23 | private long randomSeed = 1; |
21 | |||
22 | private boolean lastGenerationSuccessful; | 24 | private boolean lastGenerationSuccessful; |
23 | 25 | ||
24 | public ModelGenerator(ProblemTrace problemTrace, ModelStore store, ModelSeed modelSeed) { | 26 | ModelGenerator(ProblemTrace problemTrace, ModelStore store, ModelSeed modelSeed, |
27 | Provider<SolutionSerializer> solutionSerializerProvider) { | ||
25 | super(problemTrace, store, modelSeed, Concreteness.CANDIDATE); | 28 | super(problemTrace, store, modelSeed, Concreteness.CANDIDATE); |
29 | this.solutionSerializerProvider = solutionSerializerProvider; | ||
26 | initialVersion = getModel().commit(); | 30 | initialVersion = getModel().commit(); |
27 | } | 31 | } |
28 | 32 | ||
29 | public int getRandomSeed() { | 33 | public long getRandomSeed() { |
30 | return randomSeed; | 34 | return randomSeed; |
31 | } | 35 | } |
32 | 36 | ||
33 | public void setRandomSeed(int randomSeed) { | 37 | public void setRandomSeed(long randomSeed) { |
34 | this.randomSeed = randomSeed; | 38 | this.randomSeed = randomSeed; |
35 | this.lastGenerationSuccessful = false; | 39 | this.lastGenerationSuccessful = false; |
36 | } | 40 | } |
@@ -50,7 +54,7 @@ public class ModelGenerator extends ModelFacade { | |||
50 | if (solutions.isEmpty()) { | 54 | if (solutions.isEmpty()) { |
51 | return false; | 55 | return false; |
52 | } | 56 | } |
53 | getModel().restore(solutions.get(0).version()); | 57 | getModel().restore(solutions.getFirst().version()); |
54 | lastGenerationSuccessful = true; | 58 | lastGenerationSuccessful = true; |
55 | return true; | 59 | return true; |
56 | } | 60 | } |
@@ -63,9 +67,19 @@ public class ModelGenerator extends ModelFacade { | |||
63 | 67 | ||
64 | @Override | 68 | @Override |
65 | public <A, C> PartialInterpretation<A, C> getPartialInterpretation(PartialSymbol<A, C> partialSymbol) { | 69 | public <A, C> PartialInterpretation<A, C> getPartialInterpretation(PartialSymbol<A, C> partialSymbol) { |
70 | checkSuccessfulGeneration(); | ||
71 | return super.getPartialInterpretation(partialSymbol); | ||
72 | } | ||
73 | |||
74 | public Problem serializeSolution() { | ||
75 | checkSuccessfulGeneration(); | ||
76 | var serializer = solutionSerializerProvider.get(); | ||
77 | return serializer.serializeSolution(getProblemTrace(), getModel()); | ||
78 | } | ||
79 | |||
80 | private void checkSuccessfulGeneration() { | ||
66 | if (!lastGenerationSuccessful) { | 81 | if (!lastGenerationSuccessful) { |
67 | throw new IllegalStateException("No generated model is available"); | 82 | throw new IllegalStateException("No generated model is available"); |
68 | } | 83 | } |
69 | return super.getPartialInterpretation(partialSymbol); | ||
70 | } | 84 | } |
71 | } | 85 | } |
diff --git a/subprojects/generator/src/main/java/tools/refinery/generator/ModelGeneratorFactory.java b/subprojects/generator/src/main/java/tools/refinery/generator/ModelGeneratorFactory.java index 6642d591..587601f2 100644 --- a/subprojects/generator/src/main/java/tools/refinery/generator/ModelGeneratorFactory.java +++ b/subprojects/generator/src/main/java/tools/refinery/generator/ModelGeneratorFactory.java | |||
@@ -9,6 +9,7 @@ import com.google.inject.Inject; | |||
9 | import com.google.inject.Provider; | 9 | import com.google.inject.Provider; |
10 | import tools.refinery.language.model.problem.Problem; | 10 | import tools.refinery.language.model.problem.Problem; |
11 | import tools.refinery.language.semantics.ModelInitializer; | 11 | import tools.refinery.language.semantics.ModelInitializer; |
12 | import tools.refinery.language.semantics.SolutionSerializer; | ||
12 | import tools.refinery.store.dse.propagation.PropagationAdapter; | 13 | import tools.refinery.store.dse.propagation.PropagationAdapter; |
13 | import tools.refinery.store.dse.transition.DesignSpaceExplorationAdapter; | 14 | import tools.refinery.store.dse.transition.DesignSpaceExplorationAdapter; |
14 | import tools.refinery.store.model.ModelStore; | 15 | import tools.refinery.store.model.ModelStore; |
@@ -25,6 +26,9 @@ public final class ModelGeneratorFactory { | |||
25 | @Inject | 26 | @Inject |
26 | private Provider<ModelInitializer> initializerProvider; | 27 | private Provider<ModelInitializer> initializerProvider; |
27 | 28 | ||
29 | @Inject | ||
30 | private Provider<SolutionSerializer> solutionSerializerProvider; | ||
31 | |||
28 | private CancellationToken cancellationToken = CancellationToken.NONE; | 32 | private CancellationToken cancellationToken = CancellationToken.NONE; |
29 | 33 | ||
30 | private boolean debugPartialInterpretations; | 34 | private boolean debugPartialInterpretations; |
@@ -53,7 +57,8 @@ public final class ModelGeneratorFactory { | |||
53 | .requiredInterpretations(getRequiredInterpretations())); | 57 | .requiredInterpretations(getRequiredInterpretations())); |
54 | initializer.configureStoreBuilder(storeBuilder); | 58 | initializer.configureStoreBuilder(storeBuilder); |
55 | var store = storeBuilder.build(); | 59 | var store = storeBuilder.build(); |
56 | return new ModelGenerator(initializer.getProblemTrace(), store, initializer.getModelSeed()); | 60 | return new ModelGenerator(initializer.getProblemTrace(), store, initializer.getModelSeed(), |
61 | solutionSerializerProvider); | ||
57 | } | 62 | } |
58 | 63 | ||
59 | private Collection<Concreteness> getRequiredInterpretations() { | 64 | private Collection<Concreteness> getRequiredInterpretations() { |
diff --git a/subprojects/generator/src/main/java/tools/refinery/generator/ModelSemantics.java b/subprojects/generator/src/main/java/tools/refinery/generator/ModelSemantics.java index bc02c887..7207a509 100644 --- a/subprojects/generator/src/main/java/tools/refinery/generator/ModelSemantics.java +++ b/subprojects/generator/src/main/java/tools/refinery/generator/ModelSemantics.java | |||
@@ -11,7 +11,7 @@ import tools.refinery.store.reasoning.literal.Concreteness; | |||
11 | import tools.refinery.store.reasoning.seed.ModelSeed; | 11 | import tools.refinery.store.reasoning.seed.ModelSeed; |
12 | 12 | ||
13 | public class ModelSemantics extends ModelFacade { | 13 | public class ModelSemantics extends ModelFacade { |
14 | public ModelSemantics(ProblemTrace problemTrace, ModelStore store, ModelSeed modelSeed) { | 14 | ModelSemantics(ProblemTrace problemTrace, ModelStore store, ModelSeed modelSeed) { |
15 | super(problemTrace, store, modelSeed, Concreteness.PARTIAL); | 15 | super(problemTrace, store, modelSeed, Concreteness.PARTIAL); |
16 | } | 16 | } |
17 | } | 17 | } |
diff --git a/subprojects/generator/src/main/java/tools/refinery/generator/ProblemLoader.java b/subprojects/generator/src/main/java/tools/refinery/generator/ProblemLoader.java index 29f80714..20ea8132 100644 --- a/subprojects/generator/src/main/java/tools/refinery/generator/ProblemLoader.java +++ b/subprojects/generator/src/main/java/tools/refinery/generator/ProblemLoader.java | |||
@@ -10,20 +10,30 @@ import com.google.inject.Provider; | |||
10 | import org.eclipse.emf.common.util.URI; | 10 | import org.eclipse.emf.common.util.URI; |
11 | import org.eclipse.emf.ecore.resource.Resource; | 11 | import org.eclipse.emf.ecore.resource.Resource; |
12 | import org.eclipse.xtext.diagnostics.Severity; | 12 | import org.eclipse.xtext.diagnostics.Severity; |
13 | import org.eclipse.xtext.resource.FileExtensionProvider; | ||
13 | import org.eclipse.xtext.resource.IResourceFactory; | 14 | import org.eclipse.xtext.resource.IResourceFactory; |
14 | import org.eclipse.xtext.resource.XtextResourceSet; | 15 | import org.eclipse.xtext.resource.XtextResourceSet; |
15 | import org.eclipse.xtext.util.LazyStringInputStream; | 16 | import org.eclipse.xtext.util.LazyStringInputStream; |
16 | import org.eclipse.xtext.validation.CheckMode; | 17 | import org.eclipse.xtext.validation.CheckMode; |
17 | import org.eclipse.xtext.validation.IResourceValidator; | 18 | import org.eclipse.xtext.validation.IResourceValidator; |
18 | import tools.refinery.language.model.problem.Problem; | 19 | import tools.refinery.language.model.problem.Problem; |
20 | import tools.refinery.language.model.problem.Relation; | ||
21 | import tools.refinery.language.model.problem.ScopeDeclaration; | ||
19 | import tools.refinery.store.util.CancellationToken; | 22 | import tools.refinery.store.util.CancellationToken; |
20 | 23 | ||
24 | import java.io.ByteArrayOutputStream; | ||
21 | import java.io.File; | 25 | import java.io.File; |
22 | import java.io.IOException; | 26 | import java.io.IOException; |
23 | import java.io.InputStream; | 27 | import java.io.InputStream; |
28 | import java.nio.charset.StandardCharsets; | ||
29 | import java.util.ArrayList; | ||
30 | import java.util.HashSet; | ||
31 | import java.util.List; | ||
24 | import java.util.Map; | 32 | import java.util.Map; |
25 | 33 | ||
26 | public class ProblemLoader { | 34 | public class ProblemLoader { |
35 | private String fileExtension; | ||
36 | |||
27 | @Inject | 37 | @Inject |
28 | private Provider<XtextResourceSet> resourceSetProvider; | 38 | private Provider<XtextResourceSet> resourceSetProvider; |
29 | 39 | ||
@@ -35,25 +45,39 @@ public class ProblemLoader { | |||
35 | 45 | ||
36 | private CancellationToken cancellationToken = CancellationToken.NONE; | 46 | private CancellationToken cancellationToken = CancellationToken.NONE; |
37 | 47 | ||
48 | @Inject | ||
49 | public void setFileExtensionProvider(FileExtensionProvider fileExtensionProvider) { | ||
50 | this.fileExtension = fileExtensionProvider.getPrimaryFileExtension(); | ||
51 | } | ||
52 | |||
38 | public ProblemLoader cancellationToken(CancellationToken cancellationToken) { | 53 | public ProblemLoader cancellationToken(CancellationToken cancellationToken) { |
39 | this.cancellationToken = cancellationToken; | 54 | this.cancellationToken = cancellationToken; |
40 | return this; | 55 | return this; |
41 | } | 56 | } |
42 | 57 | ||
43 | public Problem loadString(String problemString) throws IOException { | 58 | public Problem loadString(String problemString, URI uri) throws IOException { |
44 | try (var stream = new LazyStringInputStream(problemString)) { | 59 | try (var stream = new LazyStringInputStream(problemString)) { |
45 | return loadStream(stream); | 60 | return loadStream(stream, uri); |
46 | } | 61 | } |
47 | } | 62 | } |
48 | 63 | ||
49 | public Problem loadStream(InputStream inputStream) throws IOException { | 64 | public Problem loadString(String problemString) throws IOException { |
65 | return loadString(problemString, null); | ||
66 | } | ||
67 | |||
68 | public Problem loadStream(InputStream inputStream, URI uri) throws IOException { | ||
50 | var resourceSet = resourceSetProvider.get(); | 69 | var resourceSet = resourceSetProvider.get(); |
51 | var resource = resourceFactory.createResource(URI.createFileURI("__synthetic.problem")); | 70 | var resourceUri = uri == null ? URI.createFileURI("__synthetic." + fileExtension) : uri; |
71 | var resource = resourceFactory.createResource(resourceUri); | ||
52 | resourceSet.getResources().add(resource); | 72 | resourceSet.getResources().add(resource); |
53 | resource.load(inputStream, Map.of()); | 73 | resource.load(inputStream, Map.of()); |
54 | return loadResource(resource); | 74 | return loadResource(resource); |
55 | } | 75 | } |
56 | 76 | ||
77 | public Problem loadStream(InputStream inputStream) throws IOException { | ||
78 | return loadStream(inputStream, null); | ||
79 | } | ||
80 | |||
57 | public Problem loadFile(File file) throws IOException { | 81 | public Problem loadFile(File file) throws IOException { |
58 | return loadFile(file.getAbsolutePath()); | 82 | return loadFile(file.getAbsolutePath()); |
59 | } | 83 | } |
@@ -82,9 +106,63 @@ public class ProblemLoader { | |||
82 | if (!errors.isEmpty()) { | 106 | if (!errors.isEmpty()) { |
83 | throw new ValidationErrorsException(resource.getURI(), errors); | 107 | throw new ValidationErrorsException(resource.getURI(), errors); |
84 | } | 108 | } |
85 | if (resource.getContents().isEmpty() || !(resource.getContents().get(0) instanceof Problem problem)) { | 109 | if (resource.getContents().isEmpty() || !(resource.getContents().getFirst() instanceof Problem problem)) { |
86 | throw new IllegalArgumentException("Model generation problem not found in resource " + resource.getURI()); | 110 | throw new IllegalArgumentException("Model generation problem not found in resource " + resource.getURI()); |
87 | } | 111 | } |
88 | return problem; | 112 | return problem; |
89 | } | 113 | } |
114 | |||
115 | public Problem loadScopeConstraints(Problem problem, List<String> extraScopes, | ||
116 | List<String> overrideScopes) throws IOException { | ||
117 | var allScopes = new ArrayList<>(extraScopes); | ||
118 | allScopes.addAll(overrideScopes); | ||
119 | if (allScopes.isEmpty()) { | ||
120 | return problem; | ||
121 | } | ||
122 | int originalStatementCount = problem.getStatements().size(); | ||
123 | var builder = new StringBuilder(); | ||
124 | var problemResource = problem.eResource(); | ||
125 | try (var outputStream = new ByteArrayOutputStream()) { | ||
126 | problemResource.save(outputStream, Map.of()); | ||
127 | builder.append(outputStream.toString(StandardCharsets.UTF_8)); | ||
128 | } | ||
129 | builder.append('\n'); | ||
130 | for (var scope : allScopes) { | ||
131 | builder.append("scope ").append(scope).append(".\n"); | ||
132 | } | ||
133 | var modifiedProblem = loadString(builder.toString(), problemResource.getURI()); | ||
134 | var modifiedStatements = modifiedProblem.getStatements(); | ||
135 | int modifiedStatementCount = modifiedStatements.size(); | ||
136 | if (modifiedStatementCount != originalStatementCount + allScopes.size()) { | ||
137 | throw new IllegalArgumentException("Failed to parse scope constraints"); | ||
138 | } | ||
139 | // Override scopes remove any scope constraint from the original problem with the same target type. | ||
140 | var overriddenScopes = new HashSet<Relation>(); | ||
141 | for (int i = modifiedStatementCount - overrideScopes.size(); i < modifiedStatementCount; i++) { | ||
142 | var statement = modifiedStatements.get(i); | ||
143 | if (!(statement instanceof ScopeDeclaration scopeDeclaration)) { | ||
144 | throw new IllegalStateException("Invalid scope constraint: " + statement); | ||
145 | } | ||
146 | for (var typeScope : scopeDeclaration.getTypeScopes()) { | ||
147 | overriddenScopes.add(typeScope.getTargetType()); | ||
148 | } | ||
149 | } | ||
150 | int statementIndex = 0; | ||
151 | var iterator = modifiedStatements.iterator(); | ||
152 | // Scope overrides only affect type scopes from the original problem and leave type scopes added on the | ||
153 | // command line intact. | ||
154 | while (statementIndex < originalStatementCount && iterator.hasNext()) { | ||
155 | var statement = iterator.next(); | ||
156 | if (statement instanceof ScopeDeclaration scopeDeclaration) { | ||
157 | var typeScopes = scopeDeclaration.getTypeScopes(); | ||
158 | typeScopes.removeIf(typeScope -> overriddenScopes.contains(typeScope.getTargetType())); | ||
159 | // Scope declarations with no type scopes are invalid, so we have to remove them. | ||
160 | if (typeScopes.isEmpty()) { | ||
161 | iterator.remove(); | ||
162 | } | ||
163 | } | ||
164 | statementIndex++; | ||
165 | } | ||
166 | return modifiedProblem; | ||
167 | } | ||
90 | } | 168 | } |
diff --git a/subprojects/generator/src/test/java/tools/refinery/generator/ProblemLoaderTest.java b/subprojects/generator/src/test/java/tools/refinery/generator/ProblemLoaderTest.java new file mode 100644 index 00000000..0c0db105 --- /dev/null +++ b/subprojects/generator/src/test/java/tools/refinery/generator/ProblemLoaderTest.java | |||
@@ -0,0 +1,129 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.generator; | ||
7 | |||
8 | |||
9 | import com.google.inject.Inject; | ||
10 | import org.eclipse.xtext.testing.InjectWith; | ||
11 | import org.eclipse.xtext.testing.extensions.InjectionExtension; | ||
12 | import org.junit.jupiter.api.extension.ExtendWith; | ||
13 | import org.junit.jupiter.params.ParameterizedTest; | ||
14 | import org.junit.jupiter.params.provider.Arguments; | ||
15 | import org.junit.jupiter.params.provider.MethodSource; | ||
16 | import tools.refinery.language.tests.ProblemInjectorProvider; | ||
17 | |||
18 | import java.io.ByteArrayOutputStream; | ||
19 | import java.io.IOException; | ||
20 | import java.nio.charset.StandardCharsets; | ||
21 | import java.util.List; | ||
22 | import java.util.Map; | ||
23 | import java.util.stream.Stream; | ||
24 | |||
25 | import static org.hamcrest.MatcherAssert.assertThat; | ||
26 | import static org.hamcrest.Matchers.is; | ||
27 | |||
28 | @ExtendWith(InjectionExtension.class) | ||
29 | @InjectWith(ProblemInjectorProvider.class) | ||
30 | class ProblemLoaderTest { | ||
31 | private static final String PREFIX = """ | ||
32 | class Foo. | ||
33 | class Bar. | ||
34 | """; | ||
35 | |||
36 | @Inject | ||
37 | private ProblemLoader loader; | ||
38 | |||
39 | @ParameterizedTest | ||
40 | @MethodSource | ||
41 | void loadScopeConstraintsTest(String originalScopes, List<String> scopes, List<String> overrideScopes, | ||
42 | String expectedScopes) throws IOException { | ||
43 | var problem = loader.loadString(PREFIX + originalScopes); | ||
44 | var modifiedProblem = loader.loadScopeConstraints(problem, scopes, overrideScopes); | ||
45 | String serializedProblem; | ||
46 | try (var outputStream = new ByteArrayOutputStream()) { | ||
47 | modifiedProblem.eResource().save(outputStream, Map.of()); | ||
48 | serializedProblem = outputStream.toString(StandardCharsets.UTF_8); | ||
49 | } | ||
50 | assertThat(serializedProblem, is(PREFIX + expectedScopes)); | ||
51 | } | ||
52 | |||
53 | static Stream<Arguments> loadScopeConstraintsTest() { | ||
54 | return Stream.of(Arguments.of("", | ||
55 | List.of(), | ||
56 | List.of(), | ||
57 | ""), Arguments.of("", | ||
58 | List.of("node=5..10"), | ||
59 | List.of(), """ | ||
60 | |||
61 | scope node=5..10. | ||
62 | """), Arguments.of("", | ||
63 | List.of("Foo=2", "Bar=3"), | ||
64 | List.of(), """ | ||
65 | |||
66 | scope Foo=2. | ||
67 | scope Bar=3. | ||
68 | """), Arguments.of(""" | ||
69 | scope Foo = 1, Bar = 1. | ||
70 | """, | ||
71 | List.of("node=5..10"), | ||
72 | List.of(), """ | ||
73 | scope Foo = 1, Bar = 1. | ||
74 | |||
75 | scope node=5..10. | ||
76 | """), Arguments.of(""" | ||
77 | scope Foo = 0..10, Bar = 1. | ||
78 | """, | ||
79 | List.of("Foo = 5"), | ||
80 | List.of(), """ | ||
81 | scope Foo = 0..10, Bar = 1. | ||
82 | |||
83 | scope Foo = 5. | ||
84 | """), Arguments.of(""" | ||
85 | scope Foo = 1, Bar = 1. | ||
86 | """, | ||
87 | List.of(), | ||
88 | List.of("node=5..10"), """ | ||
89 | scope Foo = 1, Bar = 1. | ||
90 | |||
91 | scope node=5..10. | ||
92 | """), Arguments.of(""" | ||
93 | scope Foo = 1, Bar = 1. | ||
94 | """, | ||
95 | List.of(), | ||
96 | List.of("Foo=3..4"), """ | ||
97 | scope Bar = 1. | ||
98 | |||
99 | scope Foo=3..4. | ||
100 | """), Arguments.of(""" | ||
101 | scope Foo = 1, Bar = 1. | ||
102 | """, | ||
103 | List.of("Foo=2"), | ||
104 | List.of("Foo=3..4"), """ | ||
105 | scope Bar = 1. | ||
106 | |||
107 | scope Foo=2. | ||
108 | scope Foo=3..4. | ||
109 | """), Arguments.of(""" | ||
110 | scope Foo = 1. | ||
111 | scope Bar = 1. | ||
112 | """, | ||
113 | List.of(), | ||
114 | List.of("Bar=3..4"), """ | ||
115 | scope Foo = 1. | ||
116 | |||
117 | |||
118 | scope Bar=3..4. | ||
119 | """), Arguments.of(""" | ||
120 | scope Foo = 1, Bar = 1. | ||
121 | """, | ||
122 | List.of(), | ||
123 | List.of("Foo=3..4", "Bar=4..5"), """ | ||
124 | |||
125 | scope Foo=3..4. | ||
126 | scope Bar=4..5. | ||
127 | """)); | ||
128 | } | ||
129 | } | ||
diff --git a/subprojects/language-model/src/main/resources/model/problem.ecore b/subprojects/language-model/src/main/resources/model/problem.ecore index 204f922c..74229a89 100644 --- a/subprojects/language-model/src/main/resources/model/problem.ecore +++ b/subprojects/language-model/src/main/resources/model/problem.ecore | |||
@@ -23,7 +23,7 @@ | |||
23 | <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//ReferenceKind"/> | 23 | <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//ReferenceKind"/> |
24 | <eStructuralFeatures xsi:type="ecore:EReference" name="referenceType" eType="#//Relation"/> | 24 | <eStructuralFeatures xsi:type="ecore:EReference" name="referenceType" eType="#//Relation"/> |
25 | <eStructuralFeatures xsi:type="ecore:EReference" name="invalidMultiplicity" eType="#//Relation" | 25 | <eStructuralFeatures xsi:type="ecore:EReference" name="invalidMultiplicity" eType="#//Relation" |
26 | containment="true"/> | 26 | transient="true" containment="true"/> |
27 | </eClassifiers> | 27 | </eClassifiers> |
28 | <eClassifiers xsi:type="ecore:EClass" name="NamedElement" abstract="true"> | 28 | <eClassifiers xsi:type="ecore:EClass" name="NamedElement" abstract="true"> |
29 | <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> | 29 | <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> |
diff --git a/subprojects/language-semantics/build.gradle.kts b/subprojects/language-semantics/build.gradle.kts index 689f621e..777ef993 100644 --- a/subprojects/language-semantics/build.gradle.kts +++ b/subprojects/language-semantics/build.gradle.kts | |||
@@ -16,6 +16,7 @@ dependencies { | |||
16 | api(project(":refinery-store-reasoning")) | 16 | api(project(":refinery-store-reasoning")) |
17 | implementation(project(":refinery-store-reasoning-scope")) | 17 | implementation(project(":refinery-store-reasoning-scope")) |
18 | runtimeOnly(libs.eclipseCollections) | 18 | runtimeOnly(libs.eclipseCollections) |
19 | testImplementation(project(":refinery-generator")) | ||
19 | testImplementation(project(":refinery-store-dse-visualization")) | 20 | testImplementation(project(":refinery-store-dse-visualization")) |
20 | testImplementation(project(":refinery-store-query-interpreter")) | 21 | testImplementation(project(":refinery-store-query-interpreter")) |
21 | testImplementation(testFixtures(project(":refinery-language"))) | 22 | testImplementation(testFixtures(project(":refinery-language"))) |
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/ModelInitializer.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/ModelInitializer.java index ecaa7e0d..38bf5a61 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/ModelInitializer.java +++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/ModelInitializer.java | |||
@@ -27,9 +27,7 @@ import tools.refinery.store.reasoning.seed.ModelSeed; | |||
27 | import tools.refinery.store.reasoning.seed.Seed; | 27 | import tools.refinery.store.reasoning.seed.Seed; |
28 | import tools.refinery.store.reasoning.translator.TranslationException; | 28 | import tools.refinery.store.reasoning.translator.TranslationException; |
29 | import tools.refinery.store.reasoning.translator.containment.ContainmentHierarchyTranslator; | 29 | import tools.refinery.store.reasoning.translator.containment.ContainmentHierarchyTranslator; |
30 | import tools.refinery.store.reasoning.translator.metamodel.Metamodel; | 30 | import tools.refinery.store.reasoning.translator.metamodel.*; |
31 | import tools.refinery.store.reasoning.translator.metamodel.MetamodelBuilder; | ||
32 | import tools.refinery.store.reasoning.translator.metamodel.MetamodelTranslator; | ||
33 | import tools.refinery.store.reasoning.translator.multiobject.MultiObjectTranslator; | 31 | import tools.refinery.store.reasoning.translator.multiobject.MultiObjectTranslator; |
34 | import tools.refinery.store.reasoning.translator.multiplicity.ConstrainedMultiplicity; | 32 | import tools.refinery.store.reasoning.translator.multiplicity.ConstrainedMultiplicity; |
35 | import tools.refinery.store.reasoning.translator.multiplicity.Multiplicity; | 33 | import tools.refinery.store.reasoning.translator.multiplicity.Multiplicity; |
@@ -73,6 +71,10 @@ public class ModelInitializer { | |||
73 | 71 | ||
74 | private ScopePropagator scopePropagator; | 72 | private ScopePropagator scopePropagator; |
75 | 73 | ||
74 | private int nodeCount; | ||
75 | |||
76 | private ModelSeed.Builder modelSeedBuilder; | ||
77 | |||
76 | private ModelSeed modelSeed; | 78 | private ModelSeed modelSeed; |
77 | 79 | ||
78 | public void readProblem(Problem problem) { | 80 | public void readProblem(Problem problem) { |
@@ -101,13 +103,17 @@ public class ModelInitializer { | |||
101 | TruthValue.FALSE)); | 103 | TruthValue.FALSE)); |
102 | collectNodes(); | 104 | collectNodes(); |
103 | collectPartialSymbols(); | 105 | collectPartialSymbols(); |
106 | nodeCount = problemTrace.getNodeTrace().size(); | ||
107 | modelSeedBuilder = ModelSeed.builder(nodeCount); | ||
108 | collectAssertions(); | ||
104 | collectMetamodel(); | 109 | collectMetamodel(); |
105 | metamodel = metamodelBuilder.build(); | 110 | metamodel = metamodelBuilder.build(); |
106 | problemTrace.setMetamodel(metamodel); | 111 | problemTrace.setMetamodel(metamodel); |
107 | collectAssertions(); | 112 | fixClassDeclarationAssertions(); |
108 | int nodeCount = problemTrace.getNodeTrace().size(); | ||
109 | var modelSeedBuilder = ModelSeed.builder(nodeCount); | ||
110 | for (var entry : relationInfoMap.entrySet()) { | 113 | for (var entry : relationInfoMap.entrySet()) { |
114 | if (entry.getKey() instanceof ReferenceDeclaration) { | ||
115 | continue; | ||
116 | } | ||
111 | var info = entry.getValue(); | 117 | var info = entry.getValue(); |
112 | var partialRelation = info.partialRelation(); | 118 | var partialRelation = info.partialRelation(); |
113 | modelSeedBuilder.seed(partialRelation, info.toSeed(nodeCount)); | 119 | modelSeedBuilder.seed(partialRelation, info.toSeed(nodeCount)); |
@@ -296,7 +302,20 @@ public class ModelInitializer { | |||
296 | } | 302 | } |
297 | var multiplicity = getMultiplicityConstraint(referenceDeclaration); | 303 | var multiplicity = getMultiplicityConstraint(referenceDeclaration); |
298 | try { | 304 | try { |
299 | metamodelBuilder.reference(relation, source, containment, multiplicity, target, oppositeRelation); | 305 | var seed = relationInfoMap.get(referenceDeclaration).toSeed(nodeCount); |
306 | var defaultValue = seed.majorityValue(); | ||
307 | if (defaultValue.must()) { | ||
308 | defaultValue = TruthValue.FALSE; | ||
309 | } | ||
310 | modelSeedBuilder.seed(relation, seed); | ||
311 | metamodelBuilder.reference(relation, ReferenceInfo.builder() | ||
312 | .containment(containment) | ||
313 | .source(source) | ||
314 | .multiplicity(multiplicity) | ||
315 | .target(target) | ||
316 | .opposite(oppositeRelation) | ||
317 | .defaultValue(defaultValue) | ||
318 | .build()); | ||
300 | } catch (RuntimeException e) { | 319 | } catch (RuntimeException e) { |
301 | throw TracedException.addTrace(classDeclaration, e); | 320 | throw TracedException.addTrace(classDeclaration, e); |
302 | } | 321 | } |
@@ -355,10 +374,6 @@ public class ModelInitializer { | |||
355 | collectCardinalityAssertions(newNodeId, TruthValue.UNKNOWN); | 374 | collectCardinalityAssertions(newNodeId, TruthValue.UNKNOWN); |
356 | var tuple = Tuple.of(newNodeId); | 375 | var tuple = Tuple.of(newNodeId); |
357 | mergeValue(classDeclaration, tuple, TruthValue.TRUE); | 376 | mergeValue(classDeclaration, tuple, TruthValue.TRUE); |
358 | var typeInfo = metamodel.typeHierarchy().getAnalysisResult(getPartialRelation(classDeclaration)); | ||
359 | for (var subType : typeInfo.getDirectSubtypes()) { | ||
360 | partialRelationInfoMap.get(subType).assertions().mergeValue(tuple, TruthValue.FALSE); | ||
361 | } | ||
362 | } | 377 | } |
363 | 378 | ||
364 | private void collectEnumAssertions(EnumDeclaration enumDeclaration) { | 379 | private void collectEnumAssertions(EnumDeclaration enumDeclaration) { |
@@ -399,6 +414,27 @@ public class ModelInitializer { | |||
399 | } | 414 | } |
400 | } | 415 | } |
401 | 416 | ||
417 | private void fixClassDeclarationAssertions() { | ||
418 | for (var statement : problem.getStatements()) { | ||
419 | if (statement instanceof ClassDeclaration classDeclaration) { | ||
420 | fixClassDeclarationAssertions(classDeclaration); | ||
421 | } | ||
422 | } | ||
423 | } | ||
424 | |||
425 | private void fixClassDeclarationAssertions(ClassDeclaration classDeclaration) { | ||
426 | var newNode = classDeclaration.getNewNode(); | ||
427 | if (newNode == null) { | ||
428 | return; | ||
429 | } | ||
430 | var newNodeId = getNodeId(newNode); | ||
431 | var tuple = Tuple.of(newNodeId); | ||
432 | var typeInfo = metamodel.typeHierarchy().getAnalysisResult(getPartialRelation(classDeclaration)); | ||
433 | for (var subType : typeInfo.getDirectSubtypes()) { | ||
434 | partialRelationInfoMap.get(subType).assertions().mergeValue(tuple, TruthValue.FALSE); | ||
435 | } | ||
436 | } | ||
437 | |||
402 | private void mergeValue(Relation relation, Tuple key, TruthValue value) { | 438 | private void mergeValue(Relation relation, Tuple key, TruthValue value) { |
403 | getRelationInfo(relation).assertions().mergeValue(key, value); | 439 | getRelationInfo(relation).assertions().mergeValue(key, value); |
404 | } | 440 | } |
@@ -482,7 +518,7 @@ public class ModelInitializer { | |||
482 | defaultValue = TruthValue.FALSE; | 518 | defaultValue = TruthValue.FALSE; |
483 | } else { | 519 | } else { |
484 | var seed = modelSeed.getSeed(partialRelation); | 520 | var seed = modelSeed.getSeed(partialRelation); |
485 | defaultValue = seed.reducedValue() == TruthValue.FALSE ? TruthValue.FALSE : TruthValue.UNKNOWN; | 521 | defaultValue = seed.majorityValue() == TruthValue.FALSE ? TruthValue.FALSE : TruthValue.UNKNOWN; |
486 | var cursor = seed.getCursor(defaultValue, problemTrace.getNodeTrace().size()); | 522 | var cursor = seed.getCursor(defaultValue, problemTrace.getNodeTrace().size()); |
487 | // The symbol should be mutable if there is at least one non-default entry in the seed. | 523 | // The symbol should be mutable if there is at least one non-default entry in the seed. |
488 | mutable = mutable || cursor.move(); | 524 | mutable = mutable || cursor.move(); |
@@ -495,7 +531,7 @@ public class ModelInitializer { | |||
495 | var problemParameters = predicateDefinition.getParameters(); | 531 | var problemParameters = predicateDefinition.getParameters(); |
496 | int arity = problemParameters.size(); | 532 | int arity = problemParameters.size(); |
497 | var parameters = new NodeVariable[arity]; | 533 | var parameters = new NodeVariable[arity]; |
498 | var parameterMap = new HashMap<tools.refinery.language.model.problem.Variable, Variable>(arity); | 534 | var parameterMap = HashMap.<tools.refinery.language.model.problem.Variable, Variable>newHashMap(arity); |
499 | var commonLiterals = new ArrayList<Literal>(); | 535 | var commonLiterals = new ArrayList<Literal>(); |
500 | for (int i = 0; i < arity; i++) { | 536 | for (int i = 0; i < arity; i++) { |
501 | var problemParameter = problemParameters.get(i); | 537 | var problemParameter = problemParameters.get(i); |
@@ -532,7 +568,7 @@ public class ModelInitializer { | |||
532 | return existing; | 568 | return existing; |
533 | } | 569 | } |
534 | int localScopeSize = existing.size() + newVariables.size(); | 570 | int localScopeSize = existing.size() + newVariables.size(); |
535 | var localScope = new HashMap<tools.refinery.language.model.problem.Variable, Variable>(localScopeSize); | 571 | var localScope = HashMap.<tools.refinery.language.model.problem.Variable, Variable>newHashMap(localScopeSize); |
536 | localScope.putAll(existing); | 572 | localScope.putAll(existing); |
537 | for (var newVariable : newVariables) { | 573 | for (var newVariable : newVariables) { |
538 | localScope.put(newVariable, Variable.of(newVariable.getName())); | 574 | localScope.put(newVariable, Variable.of(newVariable.getName())); |
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/ProblemTraceImpl.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/ProblemTraceImpl.java index cc634949..f686e980 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/ProblemTraceImpl.java +++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/ProblemTraceImpl.java | |||
@@ -9,7 +9,6 @@ import com.google.inject.Inject; | |||
9 | import org.eclipse.collections.api.factory.primitive.ObjectIntMaps; | 9 | import org.eclipse.collections.api.factory.primitive.ObjectIntMaps; |
10 | import org.eclipse.collections.api.map.primitive.MutableObjectIntMap; | 10 | import org.eclipse.collections.api.map.primitive.MutableObjectIntMap; |
11 | import org.eclipse.collections.api.map.primitive.ObjectIntMap; | 11 | import org.eclipse.collections.api.map.primitive.ObjectIntMap; |
12 | import org.eclipse.emf.ecore.util.EcoreUtil; | ||
13 | import org.eclipse.xtext.naming.IQualifiedNameConverter; | 12 | import org.eclipse.xtext.naming.IQualifiedNameConverter; |
14 | import org.eclipse.xtext.naming.QualifiedName; | 13 | import org.eclipse.xtext.naming.QualifiedName; |
15 | import org.eclipse.xtext.scoping.IScope; | 14 | import org.eclipse.xtext.scoping.IScope; |
@@ -28,7 +27,7 @@ import java.util.HashMap; | |||
28 | import java.util.LinkedHashMap; | 27 | import java.util.LinkedHashMap; |
29 | import java.util.Map; | 28 | import java.util.Map; |
30 | 29 | ||
31 | public class ProblemTraceImpl implements ProblemTrace { | 30 | class ProblemTraceImpl implements ProblemTrace { |
32 | @Inject | 31 | @Inject |
33 | private IQualifiedNameConverter qualifiedNameConverter; | 32 | private IQualifiedNameConverter qualifiedNameConverter; |
34 | 33 | ||
@@ -164,24 +163,6 @@ public class ProblemTraceImpl implements ProblemTrace { | |||
164 | } | 163 | } |
165 | 164 | ||
166 | private <T> T getElement(IScope scope, QualifiedName qualifiedName, Class<T> type) { | 165 | private <T> T getElement(IScope scope, QualifiedName qualifiedName, Class<T> type) { |
167 | var iterator = scope.getElements(qualifiedName).iterator(); | 166 | return semanticsUtils.getElement(problem, scope, qualifiedName, type); |
168 | if (!iterator.hasNext()) { | ||
169 | var qualifiedNameString = qualifiedNameConverter.toString(qualifiedName); | ||
170 | throw new IllegalArgumentException("No such %s: %s" | ||
171 | .formatted(type.getName(), qualifiedNameString)); | ||
172 | } | ||
173 | var eObjectDescription = iterator.next(); | ||
174 | if (iterator.hasNext()) { | ||
175 | var qualifiedNameString = qualifiedNameConverter.toString(qualifiedName); | ||
176 | throw new IllegalArgumentException("Ambiguous %s: %s" | ||
177 | .formatted(type.getName(), qualifiedNameString)); | ||
178 | } | ||
179 | var eObject = EcoreUtil.resolve(eObjectDescription.getEObjectOrProxy(), getProblem()); | ||
180 | if (!type.isInstance(eObject)) { | ||
181 | var qualifiedNameString = qualifiedNameConverter.toString(qualifiedName); | ||
182 | throw new IllegalArgumentException("Not a %s: %s" | ||
183 | .formatted(type.getName(), qualifiedNameString)); | ||
184 | } | ||
185 | return type.cast(eObject); | ||
186 | } | 167 | } |
187 | } | 168 | } |
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/SemanticsUtils.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/SemanticsUtils.java index b195a8e7..b72ba697 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/SemanticsUtils.java +++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/SemanticsUtils.java | |||
@@ -8,8 +8,14 @@ package tools.refinery.language.semantics; | |||
8 | import com.google.inject.Inject; | 8 | import com.google.inject.Inject; |
9 | import com.google.inject.Singleton; | 9 | import com.google.inject.Singleton; |
10 | import org.eclipse.emf.ecore.EObject; | 10 | import org.eclipse.emf.ecore.EObject; |
11 | import org.eclipse.emf.ecore.util.EcoreUtil; | ||
11 | import org.eclipse.xtext.naming.IQualifiedNameConverter; | 12 | import org.eclipse.xtext.naming.IQualifiedNameConverter; |
12 | import org.eclipse.xtext.naming.IQualifiedNameProvider; | 13 | import org.eclipse.xtext.naming.IQualifiedNameProvider; |
14 | import org.eclipse.xtext.naming.QualifiedName; | ||
15 | import org.eclipse.xtext.scoping.IScope; | ||
16 | import org.jetbrains.annotations.NotNull; | ||
17 | import org.jetbrains.annotations.Nullable; | ||
18 | import tools.refinery.language.model.problem.Problem; | ||
13 | 19 | ||
14 | import java.util.Optional; | 20 | import java.util.Optional; |
15 | 21 | ||
@@ -28,4 +34,39 @@ public class SemanticsUtils { | |||
28 | } | 34 | } |
29 | return Optional.of(qualifiedNameConverter.toString(qualifiedName)); | 35 | return Optional.of(qualifiedNameConverter.toString(qualifiedName)); |
30 | } | 36 | } |
37 | |||
38 | @Nullable | ||
39 | public <T> T maybeGetElement(Problem problem, IScope scope, QualifiedName qualifiedName, Class<T> type) { | ||
40 | if (qualifiedName == null) { | ||
41 | throw new IllegalArgumentException("Element name must not be null"); | ||
42 | } | ||
43 | var iterator = scope.getElements(qualifiedName).iterator(); | ||
44 | if (!iterator.hasNext()) { | ||
45 | return null; | ||
46 | } | ||
47 | var eObjectDescription = iterator.next(); | ||
48 | if (iterator.hasNext()) { | ||
49 | var qualifiedNameString = qualifiedNameConverter.toString(qualifiedName); | ||
50 | throw new IllegalArgumentException("Ambiguous %s: %s" | ||
51 | .formatted(type.getName(), qualifiedNameString)); | ||
52 | } | ||
53 | var eObject = EcoreUtil.resolve(eObjectDescription.getEObjectOrProxy(), problem); | ||
54 | if (!type.isInstance(eObject)) { | ||
55 | var qualifiedNameString = qualifiedNameConverter.toString(qualifiedName); | ||
56 | throw new IllegalArgumentException("Not a %s: %s" | ||
57 | .formatted(type.getName(), qualifiedNameString)); | ||
58 | } | ||
59 | return type.cast(eObject); | ||
60 | } | ||
61 | |||
62 | @NotNull | ||
63 | public <T> T getElement(Problem problem, IScope scope, QualifiedName qualifiedName, Class<T> type) { | ||
64 | var element = maybeGetElement(problem, scope, qualifiedName, type); | ||
65 | if (element == null) { | ||
66 | var qualifiedNameString = qualifiedNameConverter.toString(qualifiedName); | ||
67 | throw new IllegalArgumentException("No such %s: %s" | ||
68 | .formatted(type.getName(), qualifiedNameString)); | ||
69 | } | ||
70 | return element; | ||
71 | } | ||
31 | } | 72 | } |
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/SolutionSerializer.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/SolutionSerializer.java new file mode 100644 index 00000000..57af599e --- /dev/null +++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/SolutionSerializer.java | |||
@@ -0,0 +1,335 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.language.semantics; | ||
7 | |||
8 | import com.google.inject.Inject; | ||
9 | import com.google.inject.Provider; | ||
10 | import org.eclipse.collections.api.factory.primitive.IntObjectMaps; | ||
11 | import org.eclipse.collections.api.factory.primitive.ObjectIntMaps; | ||
12 | import org.eclipse.collections.api.map.primitive.MutableIntObjectMap; | ||
13 | import org.eclipse.collections.api.map.primitive.MutableObjectIntMap; | ||
14 | import org.eclipse.emf.common.util.URI; | ||
15 | import org.eclipse.emf.ecore.util.EcoreUtil; | ||
16 | import org.eclipse.xtext.naming.IQualifiedNameConverter; | ||
17 | import org.eclipse.xtext.naming.IQualifiedNameProvider; | ||
18 | import org.eclipse.xtext.naming.QualifiedName; | ||
19 | import org.eclipse.xtext.resource.FileExtensionProvider; | ||
20 | import org.eclipse.xtext.resource.IResourceFactory; | ||
21 | import org.eclipse.xtext.resource.XtextResource; | ||
22 | import org.eclipse.xtext.resource.XtextResourceSet; | ||
23 | import org.eclipse.xtext.scoping.IScopeProvider; | ||
24 | import tools.refinery.language.model.problem.*; | ||
25 | import tools.refinery.language.utils.ProblemDesugarer; | ||
26 | import tools.refinery.language.utils.ProblemUtil; | ||
27 | import tools.refinery.store.model.Model; | ||
28 | import tools.refinery.store.reasoning.ReasoningAdapter; | ||
29 | import tools.refinery.store.reasoning.interpretation.PartialInterpretation; | ||
30 | import tools.refinery.store.reasoning.literal.Concreteness; | ||
31 | import tools.refinery.store.reasoning.representation.PartialRelation; | ||
32 | import tools.refinery.store.reasoning.translator.typehierarchy.InferredType; | ||
33 | import tools.refinery.store.reasoning.translator.typehierarchy.TypeHierarchyTranslator; | ||
34 | import tools.refinery.store.representation.TruthValue; | ||
35 | import tools.refinery.store.tuple.Tuple; | ||
36 | |||
37 | import java.io.ByteArrayInputStream; | ||
38 | import java.io.ByteArrayOutputStream; | ||
39 | import java.io.IOException; | ||
40 | import java.util.Locale; | ||
41 | import java.util.Map; | ||
42 | import java.util.TreeMap; | ||
43 | import java.util.TreeSet; | ||
44 | import java.util.function.Function; | ||
45 | import java.util.stream.Collectors; | ||
46 | |||
47 | public class SolutionSerializer { | ||
48 | private String fileExtension; | ||
49 | |||
50 | @Inject | ||
51 | private Provider<XtextResourceSet> resourceSetProvider; | ||
52 | |||
53 | @Inject | ||
54 | private IResourceFactory resourceFactory; | ||
55 | |||
56 | @Inject | ||
57 | private IQualifiedNameProvider qualifiedNameProvider; | ||
58 | |||
59 | @Inject | ||
60 | private IQualifiedNameConverter qualifiedNameConverter; | ||
61 | |||
62 | @Inject | ||
63 | private SemanticsUtils semanticsUtils; | ||
64 | |||
65 | @Inject | ||
66 | private IScopeProvider scopeProvider; | ||
67 | |||
68 | @Inject | ||
69 | private ProblemDesugarer desugarer; | ||
70 | |||
71 | private ProblemTrace trace; | ||
72 | private Model model; | ||
73 | private ReasoningAdapter reasoningAdapter; | ||
74 | private PartialInterpretation<TruthValue, Boolean> existsInterpretation; | ||
75 | private Problem problem; | ||
76 | private final MutableIntObjectMap<Node> nodes = IntObjectMaps.mutable.empty(); | ||
77 | |||
78 | @Inject | ||
79 | public void setFileExtensionProvider(FileExtensionProvider fileExtensionProvider) { | ||
80 | this.fileExtension = fileExtensionProvider.getPrimaryFileExtension(); | ||
81 | } | ||
82 | |||
83 | public Problem serializeSolution(ProblemTrace trace, Model model) { | ||
84 | var uri = URI.createFileURI("__synthetic" + fileExtension); | ||
85 | return serializeSolution(trace, model, uri); | ||
86 | } | ||
87 | |||
88 | public Problem serializeSolution(ProblemTrace trace, Model model, URI uri) { | ||
89 | this.trace = trace; | ||
90 | this.model = model; | ||
91 | reasoningAdapter = model.getAdapter(ReasoningAdapter.class); | ||
92 | existsInterpretation = reasoningAdapter.getPartialInterpretation(Concreteness.CANDIDATE, | ||
93 | ReasoningAdapter.EXISTS_SYMBOL); | ||
94 | var originalProblem = trace.getProblem(); | ||
95 | problem = copyProblem(originalProblem, uri); | ||
96 | problem.getStatements().removeIf(SolutionSerializer::shouldRemoveStatement); | ||
97 | problem.getNodes().removeIf(this::shouldRemoveNode); | ||
98 | addExistsAssertions(); | ||
99 | addClassAssertions(); | ||
100 | addReferenceAssertions(); | ||
101 | return problem; | ||
102 | } | ||
103 | |||
104 | private static boolean shouldRemoveStatement(Statement statement) { | ||
105 | return statement instanceof Assertion || statement instanceof ScopeDeclaration; | ||
106 | } | ||
107 | |||
108 | private boolean shouldRemoveNode(Node newNode) { | ||
109 | var qualifiedName = qualifiedNameProvider.getFullyQualifiedName(newNode); | ||
110 | var scope = scopeProvider.getScope(trace.getProblem(), ProblemPackage.Literals.ASSERTION__RELATION); | ||
111 | var originalNode = semanticsUtils.maybeGetElement(problem, scope, qualifiedName, Node.class); | ||
112 | if (originalNode == null) { | ||
113 | return false; | ||
114 | } | ||
115 | int nodeId = trace.getNodeId(originalNode); | ||
116 | return !isExistingNode(nodeId); | ||
117 | } | ||
118 | |||
119 | private boolean isExistingNode(int nodeId) { | ||
120 | var exists = existsInterpretation.get(Tuple.of(nodeId)); | ||
121 | if (!exists.isConcrete()) { | ||
122 | throw new IllegalStateException("Invalid EXISTS %s for node %d".formatted(exists, nodeId)); | ||
123 | } | ||
124 | return exists.may(); | ||
125 | } | ||
126 | |||
127 | private Problem copyProblem(Problem originalProblem, URI uri) { | ||
128 | var newResourceSet = resourceSetProvider.get(); | ||
129 | if (!fileExtension.equals(uri.fileExtension())) { | ||
130 | uri = uri.appendFileExtension(fileExtension); | ||
131 | } | ||
132 | var newResource = resourceFactory.createResource(uri); | ||
133 | newResourceSet.getResources().add(newResource); | ||
134 | var originalResource = originalProblem.eResource(); | ||
135 | if (originalResource instanceof XtextResource) { | ||
136 | byte[] bytes; | ||
137 | try { | ||
138 | try (var outputStream = new ByteArrayOutputStream()) { | ||
139 | originalResource.save(outputStream, Map.of()); | ||
140 | bytes = outputStream.toByteArray(); | ||
141 | } | ||
142 | try (var inputStream = new ByteArrayInputStream(bytes)) { | ||
143 | newResource.load(inputStream, Map.of()); | ||
144 | } | ||
145 | } catch (IOException e) { | ||
146 | throw new IllegalStateException("Failed to copy problem", e); | ||
147 | } | ||
148 | var contents = newResource.getContents(); | ||
149 | if (!contents.isEmpty() && contents.getFirst() instanceof Problem newProblem) { | ||
150 | return newProblem; | ||
151 | } | ||
152 | throw new IllegalStateException("Invalid contents of copied problem"); | ||
153 | } else { | ||
154 | var newProblem = EcoreUtil.copy(originalProblem); | ||
155 | newResource.getContents().add(newProblem); | ||
156 | return newProblem; | ||
157 | } | ||
158 | } | ||
159 | |||
160 | private Relation findRelation(Relation originalRelation) { | ||
161 | var qualifiedName = qualifiedNameProvider.getFullyQualifiedName(originalRelation); | ||
162 | var scope = scopeProvider.getScope(problem, ProblemPackage.Literals.ASSERTION__RELATION); | ||
163 | return semanticsUtils.getElement(problem, scope, qualifiedName, Relation.class); | ||
164 | } | ||
165 | |||
166 | private Relation findPartialRelation(PartialRelation partialRelation) { | ||
167 | return findRelation(trace.getRelation(partialRelation)); | ||
168 | } | ||
169 | |||
170 | private Node findNode(Node originalNode) { | ||
171 | var qualifiedName = qualifiedNameProvider.getFullyQualifiedName(originalNode); | ||
172 | return findNode(qualifiedName); | ||
173 | } | ||
174 | |||
175 | private Node findNode(String name) { | ||
176 | var qualifiedName = qualifiedNameConverter.toQualifiedName(name); | ||
177 | return findNode(qualifiedName); | ||
178 | } | ||
179 | |||
180 | private Node findNode(QualifiedName qualifiedName) { | ||
181 | var scope = scopeProvider.getScope(problem, ProblemPackage.Literals.NODE_ASSERTION_ARGUMENT__NODE); | ||
182 | return semanticsUtils.maybeGetElement(problem, scope, qualifiedName, Node.class); | ||
183 | } | ||
184 | |||
185 | private void addAssertion(Relation relation, LogicValue value, Node... arguments) { | ||
186 | var assertion = ProblemFactory.eINSTANCE.createAssertion(); | ||
187 | assertion.setRelation(relation); | ||
188 | for (var node : arguments) { | ||
189 | var argument = ProblemFactory.eINSTANCE.createNodeAssertionArgument(); | ||
190 | argument.setNode(node); | ||
191 | assertion.getArguments().add(argument); | ||
192 | } | ||
193 | var logicConstant = ProblemFactory.eINSTANCE.createLogicConstant(); | ||
194 | logicConstant.setLogicValue(value); | ||
195 | assertion.setValue(logicConstant); | ||
196 | problem.getStatements().add(assertion); | ||
197 | } | ||
198 | |||
199 | private void addExistsAssertions() { | ||
200 | var builtinSymbols = desugarer.getBuiltinSymbols(problem) | ||
201 | .orElseThrow(() -> new IllegalStateException("No builtin library in copied problem")); | ||
202 | // Make sure to output exists assertions in a deterministic order. | ||
203 | var sortedNewNodes = new TreeMap<Integer, Node>(); | ||
204 | for (var pair : trace.getNodeTrace().keyValuesView()) { | ||
205 | var originalNode = pair.getOne(); | ||
206 | int nodeId = pair.getTwo(); | ||
207 | var newNode = findNode(originalNode); | ||
208 | // Since all implicit nodes that do not exist has already been remove in serializeSolution, | ||
209 | // we only need to add !exists assertions to ::new nodes (nodes marked as an individual must always exist). | ||
210 | if (ProblemUtil.isNewNode(originalNode)) { | ||
211 | sortedNewNodes.put(nodeId, newNode); | ||
212 | } else { | ||
213 | nodes.put(nodeId, newNode); | ||
214 | } | ||
215 | } | ||
216 | for (var newNode : sortedNewNodes.values()) { | ||
217 | // If a node is a new node of the class, we should replace it with a normal node. | ||
218 | addAssertion(builtinSymbols.exists(), LogicValue.FALSE, newNode); | ||
219 | } | ||
220 | } | ||
221 | |||
222 | private void addClassAssertions() { | ||
223 | var types = trace.getMetamodel().typeHierarchy().getPreservedTypes().keySet().stream() | ||
224 | .collect(Collectors.toMap(Function.identity(), this::findPartialRelation)); | ||
225 | var indexMap = ObjectIntMaps.mutable.empty(); | ||
226 | var cursor = model.getInterpretation(TypeHierarchyTranslator.TYPE_SYMBOL).getAll(); | ||
227 | while (cursor.move()) { | ||
228 | var key = cursor.getKey(); | ||
229 | var nodeId = key.get(0); | ||
230 | if (isExistingNode(nodeId)) { | ||
231 | createNodeAndAssertType(nodeId, cursor.getValue(), types, indexMap); | ||
232 | } | ||
233 | } | ||
234 | } | ||
235 | |||
236 | private void createNodeAndAssertType(int nodeId, InferredType inferredType, Map<PartialRelation, Relation> types, | ||
237 | MutableObjectIntMap<Object> indexMap) { | ||
238 | var candidateTypeSymbol = inferredType.candidateType(); | ||
239 | var candidateRelation = types.get(candidateTypeSymbol); | ||
240 | if (candidateRelation instanceof EnumDeclaration) { | ||
241 | // Type assertions for enum literals are added implicitly. | ||
242 | return; | ||
243 | } | ||
244 | Node node = nodes.get(nodeId); | ||
245 | if (node == null) { | ||
246 | String typeName = candidateRelation.getName(); | ||
247 | if (typeName == null || typeName.isEmpty()) { | ||
248 | typeName = "node"; | ||
249 | } else { | ||
250 | typeName = typeName.substring(0, 1).toLowerCase(Locale.ROOT) + typeName.substring(1); | ||
251 | } | ||
252 | int index = indexMap.getIfAbsent(typeName, 0); | ||
253 | String nodeName; | ||
254 | do { | ||
255 | index++; | ||
256 | nodeName = typeName + index; | ||
257 | } while (findNode(nodeName) != null); | ||
258 | node = ProblemFactory.eINSTANCE.createNode(); | ||
259 | node.setName(nodeName); | ||
260 | problem.getNodes().add(node); | ||
261 | nodes.put(nodeId, node); | ||
262 | } | ||
263 | addAssertion(candidateRelation, LogicValue.TRUE, node); | ||
264 | var typeAnalysisResult = trace.getMetamodel().typeHierarchy().getPreservedTypes().get(candidateTypeSymbol); | ||
265 | for (var subtype : typeAnalysisResult.getDirectSubtypes()) { | ||
266 | var subtypeRelation = types.get(subtype); | ||
267 | addAssertion(subtypeRelation, LogicValue.FALSE, node); | ||
268 | } | ||
269 | } | ||
270 | |||
271 | private void addReferenceAssertions() { | ||
272 | var metamodel = trace.getMetamodel(); | ||
273 | for (var partialRelation : metamodel.containmentHierarchy().keySet()) { | ||
274 | // No need to add a default value, because in a concrete model, each contained node has only a single | ||
275 | // container. | ||
276 | addAssertions(partialRelation); | ||
277 | } | ||
278 | for (var partialRelation : metamodel.directedCrossReferences().keySet()) { | ||
279 | addDefaultAssertion(partialRelation); | ||
280 | addAssertions(partialRelation); | ||
281 | } | ||
282 | // No need to add directed opposite references, because their default value is {@code unknown} and their | ||
283 | // actual value will always be computed from the value of the directed forward reference. | ||
284 | // However, undirected cross-references have to be serialized in both directions due to the default value of | ||
285 | // {@code false}. | ||
286 | for (var partialRelation : metamodel.undirectedCrossReferences().keySet()) { | ||
287 | addDefaultAssertion(partialRelation); | ||
288 | addAssertions(partialRelation); | ||
289 | } | ||
290 | } | ||
291 | |||
292 | private void addAssertions(PartialRelation partialRelation) { | ||
293 | var relation = findPartialRelation(partialRelation); | ||
294 | var cursor = reasoningAdapter.getPartialInterpretation(Concreteness.CANDIDATE, partialRelation).getAll(); | ||
295 | // Make sure to output assertions in a deterministic order. | ||
296 | var sortedTuples = new TreeSet<Tuple>(); | ||
297 | while (cursor.move()) { | ||
298 | var tuple = cursor.getKey(); | ||
299 | var from = nodes.get(tuple.get(0)); | ||
300 | var to = nodes.get(tuple.get(1)); | ||
301 | if (from == null || to == null) { | ||
302 | // One of the endpoints does not exist in the candidate model. | ||
303 | continue; | ||
304 | } | ||
305 | var value = cursor.getValue(); | ||
306 | if (!value.isConcrete()) { | ||
307 | throw new IllegalStateException("Invalid %s %s for tuple %s".formatted(partialRelation, value, tuple)); | ||
308 | } | ||
309 | if (value.may()) { | ||
310 | sortedTuples.add(tuple); | ||
311 | } | ||
312 | } | ||
313 | for (var tuple : sortedTuples) { | ||
314 | var from = nodes.get(tuple.get(0)); | ||
315 | var to = nodes.get(tuple.get(1)); | ||
316 | addAssertion(relation, LogicValue.TRUE, from, to); | ||
317 | } | ||
318 | } | ||
319 | |||
320 | private void addDefaultAssertion(PartialRelation partialRelation) { | ||
321 | var relation = findPartialRelation(partialRelation); | ||
322 | var assertion = ProblemFactory.eINSTANCE.createAssertion(); | ||
323 | assertion.setDefault(true); | ||
324 | assertion.setRelation(relation); | ||
325 | int arity = ProblemUtil.getArity(relation); | ||
326 | for (int i = 0; i < arity; i++) { | ||
327 | var argument = ProblemFactory.eINSTANCE.createWildcardAssertionArgument(); | ||
328 | assertion.getArguments().add(argument); | ||
329 | } | ||
330 | var logicConstant = ProblemFactory.eINSTANCE.createLogicConstant(); | ||
331 | logicConstant.setLogicValue(LogicValue.FALSE); | ||
332 | assertion.setValue(logicConstant); | ||
333 | problem.getStatements().add(assertion); | ||
334 | } | ||
335 | } | ||
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTree.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTree.java index c732f784..5d25f148 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTree.java +++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTree.java | |||
@@ -40,8 +40,8 @@ class DecisionTree implements MutableSeed<TruthValue> { | |||
40 | } | 40 | } |
41 | 41 | ||
42 | @Override | 42 | @Override |
43 | public TruthValue reducedValue() { | 43 | public TruthValue majorityValue() { |
44 | return root.getOtherwiseReducedValue().getTruthValue(); | 44 | return root.getMajorityValue().getTruthValueOrElse(TruthValue.FALSE); |
45 | } | 45 | } |
46 | 46 | ||
47 | @Override | 47 | @Override |
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTreeNode.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTreeNode.java index ebca2634..31d6fc78 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTreeNode.java +++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTreeNode.java | |||
@@ -100,6 +100,8 @@ abstract class DecisionTreeNode { | |||
100 | 100 | ||
101 | protected abstract LazyIntIterable getChildKeys(); | 101 | protected abstract LazyIntIterable getChildKeys(); |
102 | 102 | ||
103 | public abstract DecisionTreeValue getMajorityValue(); | ||
104 | |||
103 | protected abstract boolean moveNextSparse(int level, DecisionTreeCursor cursor, int startIndex, | 105 | protected abstract boolean moveNextSparse(int level, DecisionTreeCursor cursor, int startIndex, |
104 | int[] sortedChildren); | 106 | int[] sortedChildren); |
105 | 107 | ||
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/IntermediateNode.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/IntermediateNode.java index 0e2f5d18..2ad216ce 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/IntermediateNode.java +++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/IntermediateNode.java | |||
@@ -130,6 +130,11 @@ final class IntermediateNode extends DecisionTreeNode { | |||
130 | return children.keysView(); | 130 | return children.keysView(); |
131 | } | 131 | } |
132 | 132 | ||
133 | @Override | ||
134 | public DecisionTreeValue getMajorityValue() { | ||
135 | return otherwise.getMajorityValue(); | ||
136 | } | ||
137 | |||
133 | protected boolean moveNextSparse(int level, DecisionTreeCursor cursor, int startIndex, int[] sortedChildren) { | 138 | protected boolean moveNextSparse(int level, DecisionTreeCursor cursor, int startIndex, int[] sortedChildren) { |
134 | for (int i = startIndex; i < sortedChildren.length; i++) { | 139 | for (int i = startIndex; i < sortedChildren.length; i++) { |
135 | var key = sortedChildren[i]; | 140 | var key = sortedChildren[i]; |
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/NullaryMutableSeed.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/NullaryMutableSeed.java index 7a72c656..f100c5a6 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/NullaryMutableSeed.java +++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/NullaryMutableSeed.java | |||
@@ -29,14 +29,14 @@ class NullaryMutableSeed implements MutableSeed<TruthValue> { | |||
29 | } | 29 | } |
30 | 30 | ||
31 | @Override | 31 | @Override |
32 | public TruthValue reducedValue() { | 32 | public TruthValue majorityValue() { |
33 | return value.getTruthValue(); | 33 | return value.getTruthValue(); |
34 | } | 34 | } |
35 | 35 | ||
36 | @Override | 36 | @Override |
37 | public TruthValue get(Tuple key) { | 37 | public TruthValue get(Tuple key) { |
38 | validateKey(key); | 38 | validateKey(key); |
39 | return reducedValue(); | 39 | return majorityValue(); |
40 | } | 40 | } |
41 | 41 | ||
42 | private static void validateKey(Tuple key) { | 42 | private static void validateKey(Tuple key) { |
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/TerminalNode.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/TerminalNode.java index d3dd757c..dc501479 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/TerminalNode.java +++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/TerminalNode.java | |||
@@ -115,7 +115,7 @@ class TerminalNode extends DecisionTreeNode { | |||
115 | 115 | ||
116 | @Override | 116 | @Override |
117 | protected DecisionTreeValue getOtherwiseReducedValue() { | 117 | protected DecisionTreeValue getOtherwiseReducedValue() { |
118 | return otherwise; | 118 | return getMajorityValue(); |
119 | } | 119 | } |
120 | 120 | ||
121 | @Override | 121 | @Override |
@@ -124,6 +124,11 @@ class TerminalNode extends DecisionTreeNode { | |||
124 | } | 124 | } |
125 | 125 | ||
126 | @Override | 126 | @Override |
127 | public DecisionTreeValue getMajorityValue() { | ||
128 | return otherwise; | ||
129 | } | ||
130 | |||
131 | @Override | ||
127 | protected boolean moveNextSparse(int level, DecisionTreeCursor cursor, int startIndex, int[] sortedChildren) { | 132 | protected boolean moveNextSparse(int level, DecisionTreeCursor cursor, int startIndex, int[] sortedChildren) { |
128 | if (startIndex >= sortedChildren.length) { | 133 | if (startIndex >= sortedChildren.length) { |
129 | return false; | 134 | return false; |
diff --git a/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/SolutionSerializerTest.java b/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/SolutionSerializerTest.java new file mode 100644 index 00000000..2d759c86 --- /dev/null +++ b/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/SolutionSerializerTest.java | |||
@@ -0,0 +1,164 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.language.semantics; | ||
7 | |||
8 | import com.google.inject.Inject; | ||
9 | import org.eclipse.xtext.testing.InjectWith; | ||
10 | import org.eclipse.xtext.testing.extensions.InjectionExtension; | ||
11 | import org.junit.jupiter.api.extension.ExtendWith; | ||
12 | import org.junit.jupiter.params.ParameterizedTest; | ||
13 | import org.junit.jupiter.params.provider.Arguments; | ||
14 | import org.junit.jupiter.params.provider.MethodSource; | ||
15 | import tools.refinery.generator.ModelGeneratorFactory; | ||
16 | import tools.refinery.generator.ProblemLoader; | ||
17 | import tools.refinery.language.tests.ProblemInjectorProvider; | ||
18 | |||
19 | import java.io.ByteArrayOutputStream; | ||
20 | import java.io.IOException; | ||
21 | import java.util.Map; | ||
22 | import java.util.stream.Stream; | ||
23 | |||
24 | import static org.hamcrest.MatcherAssert.assertThat; | ||
25 | import static org.hamcrest.Matchers.is; | ||
26 | |||
27 | @ExtendWith(InjectionExtension.class) | ||
28 | @InjectWith(ProblemInjectorProvider.class) | ||
29 | class SolutionSerializerTest { | ||
30 | @Inject | ||
31 | ProblemLoader loader; | ||
32 | |||
33 | @Inject | ||
34 | ModelGeneratorFactory generatorFactory; | ||
35 | |||
36 | @Inject | ||
37 | SolutionSerializer serializer; | ||
38 | |||
39 | @ParameterizedTest | ||
40 | @MethodSource | ||
41 | void solutionSerializerTest(String prefix, String input, String expectedOutput) throws IOException { | ||
42 | var problem = loader.loadString(prefix + "\n" + input); | ||
43 | var generator = generatorFactory.createGenerator(problem); | ||
44 | generator.generate(); | ||
45 | var solution = serializer.serializeSolution(generator.getProblemTrace(), generator.getModel()); | ||
46 | String actualOutput; | ||
47 | try (var outputStream = new ByteArrayOutputStream()) { | ||
48 | solution.eResource().save(outputStream, Map.of()); | ||
49 | actualOutput = outputStream.toString(); | ||
50 | } | ||
51 | assertThat(actualOutput, is(prefix + "\n" + expectedOutput)); | ||
52 | } | ||
53 | |||
54 | static Stream<Arguments> solutionSerializerTest() { | ||
55 | return Stream.of(Arguments.of(""" | ||
56 | class Foo. | ||
57 | """, """ | ||
58 | scope Foo = 3. | ||
59 | """, """ | ||
60 | !exists(Foo::new). | ||
61 | Foo(foo1). | ||
62 | Foo(foo2). | ||
63 | Foo(foo3). | ||
64 | """), Arguments.of(""" | ||
65 | class Foo { | ||
66 | contains Bar[2] bars | ||
67 | } | ||
68 | |||
69 | class Bar. | ||
70 | """, """ | ||
71 | scope Foo = 1. | ||
72 | """, """ | ||
73 | !exists(Foo::new). | ||
74 | !exists(Bar::new). | ||
75 | Foo(foo1). | ||
76 | Bar(bar1). | ||
77 | Bar(bar2). | ||
78 | bars(foo1, bar1). | ||
79 | bars(foo1, bar2). | ||
80 | """), Arguments.of(""" | ||
81 | class Foo { | ||
82 | Bar[2] bars opposite foo | ||
83 | } | ||
84 | |||
85 | class Bar { | ||
86 | Foo[1] foo opposite bars | ||
87 | } | ||
88 | """, """ | ||
89 | scope Foo = 1, Bar = 2. | ||
90 | """, """ | ||
91 | !exists(Foo::new). | ||
92 | !exists(Bar::new). | ||
93 | Foo(foo1). | ||
94 | Bar(bar1). | ||
95 | Bar(bar2). | ||
96 | default !bars(*, *). | ||
97 | bars(foo1, bar1). | ||
98 | bars(foo1, bar2). | ||
99 | """), Arguments.of(""" | ||
100 | class Person { | ||
101 | Person[2] friend opposite friend | ||
102 | } | ||
103 | """, """ | ||
104 | friend(a, b). | ||
105 | friend(a, c). | ||
106 | friend(b, c). | ||
107 | |||
108 | scope Person += 0. | ||
109 | """, """ | ||
110 | !exists(Person::new). | ||
111 | Person(a). | ||
112 | Person(b). | ||
113 | Person(c). | ||
114 | default !friend(*, *). | ||
115 | friend(a, b). | ||
116 | friend(a, c). | ||
117 | friend(b, a). | ||
118 | friend(b, c). | ||
119 | friend(c, a). | ||
120 | friend(c, b). | ||
121 | """), Arguments.of(""" | ||
122 | class Foo { | ||
123 | Bar bar | ||
124 | } | ||
125 | |||
126 | enum Bar { | ||
127 | BAR_A, | ||
128 | BAR_B | ||
129 | } | ||
130 | """, """ | ||
131 | bar(foo, BAR_A). | ||
132 | |||
133 | scope Foo += 0. | ||
134 | """, """ | ||
135 | !exists(Foo::new). | ||
136 | Foo(foo). | ||
137 | default !bar(*, *). | ||
138 | bar(foo, BAR_A). | ||
139 | """), Arguments.of(""" | ||
140 | class Foo. | ||
141 | class Bar extends Foo. | ||
142 | """, """ | ||
143 | scope Foo = 1, Bar = 0. | ||
144 | """, """ | ||
145 | !exists(Foo::new). | ||
146 | !exists(Bar::new). | ||
147 | Foo(foo1). | ||
148 | !Bar(foo1). | ||
149 | """), Arguments.of(""" | ||
150 | class Foo { | ||
151 | Foo[] ref | ||
152 | } | ||
153 | """, """ | ||
154 | ref(a, b). | ||
155 | !exists(b). | ||
156 | |||
157 | scope Foo += 0. | ||
158 | """, """ | ||
159 | !exists(Foo::new). | ||
160 | Foo(a). | ||
161 | default !ref(*, *). | ||
162 | """)); | ||
163 | } | ||
164 | } | ||
diff --git a/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/internal/DecisionTreeTests.java b/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/internal/DecisionTreeTests.java index 2320de2c..61ce850f 100644 --- a/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/internal/DecisionTreeTests.java +++ b/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/internal/DecisionTreeTests.java | |||
@@ -276,6 +276,16 @@ class DecisionTreeTests { | |||
276 | assertThat(sut.getReducedValue(), is(TruthValue.TRUE)); | 276 | assertThat(sut.getReducedValue(), is(TruthValue.TRUE)); |
277 | } | 277 | } |
278 | 278 | ||
279 | @Test | ||
280 | void overwriteWildcardAllTest() { | ||
281 | var first = new DecisionTree(2, TruthValue.UNKNOWN); | ||
282 | first.mergeValue(Tuple.of(-1, -1), TruthValue.FALSE); | ||
283 | var second = new DecisionTree(2, null); | ||
284 | second.mergeValue(Tuple.of(1, -1), TruthValue.TRUE); | ||
285 | first.overwriteValues(second); | ||
286 | assertThat(first.majorityValue(), is(TruthValue.FALSE)); | ||
287 | } | ||
288 | |||
279 | private Map<Tuple, TruthValue> iterateAll(DecisionTree sut, TruthValue defaultValue, int nodeCount) { | 289 | private Map<Tuple, TruthValue> iterateAll(DecisionTree sut, TruthValue defaultValue, int nodeCount) { |
280 | var cursor = sut.getCursor(defaultValue, nodeCount); | 290 | var cursor = sut.getCursor(defaultValue, nodeCount); |
281 | var map = new LinkedHashMap<Tuple, TruthValue>(); | 291 | var map = new LinkedHashMap<Tuple, TruthValue>(); |
diff --git a/subprojects/language/src/main/java/tools/refinery/language/ProblemRuntimeModule.java b/subprojects/language/src/main/java/tools/refinery/language/ProblemRuntimeModule.java index 0a5cb3c2..00dd3de3 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/ProblemRuntimeModule.java +++ b/subprojects/language/src/main/java/tools/refinery/language/ProblemRuntimeModule.java | |||
@@ -20,6 +20,7 @@ import org.eclipse.xtext.scoping.IGlobalScopeProvider; | |||
20 | import org.eclipse.xtext.scoping.IScopeProvider; | 20 | import org.eclipse.xtext.scoping.IScopeProvider; |
21 | import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider; | 21 | import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider; |
22 | import org.eclipse.xtext.serializer.sequencer.ISemanticSequencer; | 22 | import org.eclipse.xtext.serializer.sequencer.ISemanticSequencer; |
23 | import org.eclipse.xtext.serializer.tokens.ICrossReferenceSerializer; | ||
23 | import org.eclipse.xtext.validation.IDiagnosticConverter; | 24 | import org.eclipse.xtext.validation.IDiagnosticConverter; |
24 | import org.eclipse.xtext.validation.IResourceValidator; | 25 | import org.eclipse.xtext.validation.IResourceValidator; |
25 | import org.eclipse.xtext.xbase.annotations.validation.DerivedStateAwareResourceValidator; | 26 | import org.eclipse.xtext.xbase.annotations.validation.DerivedStateAwareResourceValidator; |
@@ -34,12 +35,15 @@ import tools.refinery.language.resource.ProblemResourceDescriptionStrategy; | |||
34 | import tools.refinery.language.scoping.ProblemGlobalScopeProvider; | 35 | import tools.refinery.language.scoping.ProblemGlobalScopeProvider; |
35 | import tools.refinery.language.scoping.ProblemLocalScopeProvider; | 36 | import tools.refinery.language.scoping.ProblemLocalScopeProvider; |
36 | import tools.refinery.language.serializer.PreferShortAssertionsProblemSemanticSequencer; | 37 | import tools.refinery.language.serializer.PreferShortAssertionsProblemSemanticSequencer; |
38 | import tools.refinery.language.serializer.ProblemCrossReferenceSerializer; | ||
37 | import tools.refinery.language.validation.ProblemDiagnosticConverter; | 39 | import tools.refinery.language.validation.ProblemDiagnosticConverter; |
38 | 40 | ||
39 | /** | 41 | /** |
40 | * Use this class to register components to be used at runtime / without the | 42 | * Use this class to register components to be used at runtime / without the |
41 | * Equinox extension registry. | 43 | * Equinox extension registry. |
42 | */ | 44 | */ |
45 | // Unused methods in this class are called by reflection to configure the Xtext Injector. | ||
46 | @SuppressWarnings("unused") | ||
43 | public class ProblemRuntimeModule extends AbstractProblemRuntimeModule { | 47 | public class ProblemRuntimeModule extends AbstractProblemRuntimeModule { |
44 | @Override | 48 | @Override |
45 | public Class<? extends IParser> bindIParser() { | 49 | public Class<? extends IParser> bindIParser() { |
@@ -104,6 +108,10 @@ public class ProblemRuntimeModule extends AbstractProblemRuntimeModule { | |||
104 | return PreferShortAssertionsProblemSemanticSequencer.class; | 108 | return PreferShortAssertionsProblemSemanticSequencer.class; |
105 | } | 109 | } |
106 | 110 | ||
111 | public Class<? extends ICrossReferenceSerializer> bindICrossReferenceSerializer() { | ||
112 | return ProblemCrossReferenceSerializer.class; | ||
113 | } | ||
114 | |||
107 | public Class<? extends IDiagnosticConverter> bindIDiagnosticConverter() { | 115 | public Class<? extends IDiagnosticConverter> bindIDiagnosticConverter() { |
108 | return ProblemDiagnosticConverter.class; | 116 | return ProblemDiagnosticConverter.class; |
109 | } | 117 | } |
diff --git a/subprojects/language/src/main/java/tools/refinery/language/formatting2/ProblemFormatter.java b/subprojects/language/src/main/java/tools/refinery/language/formatting2/ProblemFormatter.java index 55a5ac20..0f3bd3ee 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/formatting2/ProblemFormatter.java +++ b/subprojects/language/src/main/java/tools/refinery/language/formatting2/ProblemFormatter.java | |||
@@ -69,12 +69,24 @@ public class ProblemFormatter extends AbstractJavaFormatter { | |||
69 | doc.prepend(region.keyword("{"), this::oneSpace); | 69 | doc.prepend(region.keyword("{"), this::oneSpace); |
70 | doc.append(region.keyword("{"), it -> it.setNewLines(1, 1, 2)); | 70 | doc.append(region.keyword("{"), it -> it.setNewLines(1, 1, 2)); |
71 | doc.prepend(region.keyword("}"), it -> it.setNewLines(1, 1, 2)); | 71 | doc.prepend(region.keyword("}"), it -> it.setNewLines(1, 1, 2)); |
72 | doc.interior(region.keyword("{"), region.keyword("}"), IHiddenRegionFormatter::indent); | ||
72 | doc.prepend(region.keyword("."), this::noSpace); | 73 | doc.prepend(region.keyword("."), this::noSpace); |
73 | for (var featureDeclaration : classDeclaration.getFeatureDeclarations()) { | 74 | for (var featureDeclaration : classDeclaration.getFeatureDeclarations()) { |
74 | doc.format(featureDeclaration); | 75 | doc.format(featureDeclaration); |
75 | } | 76 | } |
76 | } | 77 | } |
77 | 78 | ||
79 | protected void format(EnumDeclaration enumDeclaration, IFormattableDocument doc) { | ||
80 | surroundNewLines(doc, enumDeclaration, this::twoNewLines); | ||
81 | var region = regionFor(enumDeclaration); | ||
82 | doc.append(region.keyword("enum"), this::oneSpace); | ||
83 | doc.prepend(region.keyword("{"), this::oneSpace); | ||
84 | doc.append(region.keyword("{"), it -> it.setNewLines(1, 1, 2)); | ||
85 | doc.prepend(region.keyword("}"), it -> it.setNewLines(1, 1, 2)); | ||
86 | doc.interior(region.keyword("{"), region.keyword("}"), IHiddenRegionFormatter::indent); | ||
87 | doc.prepend(region.keyword("."), this::noSpace); | ||
88 | } | ||
89 | |||
78 | protected void format(PredicateDefinition predicateDefinition, IFormattableDocument doc) { | 90 | protected void format(PredicateDefinition predicateDefinition, IFormattableDocument doc) { |
79 | surroundNewLines(doc, predicateDefinition, this::twoNewLines); | 91 | surroundNewLines(doc, predicateDefinition, this::twoNewLines); |
80 | var region = regionFor(predicateDefinition); | 92 | var region = regionFor(predicateDefinition); |
@@ -151,14 +163,14 @@ public class ProblemFormatter extends AbstractJavaFormatter { | |||
151 | } | 163 | } |
152 | 164 | ||
153 | protected void surroundNewLines(IFormattableDocument doc, EObject eObject, | 165 | protected void surroundNewLines(IFormattableDocument doc, EObject eObject, |
154 | Procedure1<? super IHiddenRegionFormatter> init) { | 166 | Procedure1<? super IHiddenRegionFormatter> init) { |
155 | var region = doc.getRequest().getTextRegionAccess().regionForEObject(eObject); | 167 | var region = doc.getRequest().getTextRegionAccess().regionForEObject(eObject); |
156 | preprendNewLines(doc, region, init); | 168 | preprendNewLines(doc, region, init); |
157 | appendNewLines(doc, region, init); | 169 | appendNewLines(doc, region, init); |
158 | } | 170 | } |
159 | 171 | ||
160 | protected void preprendNewLines(IFormattableDocument doc, ISequentialRegion region, | 172 | protected void preprendNewLines(IFormattableDocument doc, ISequentialRegion region, |
161 | Procedure1<? super IHiddenRegionFormatter> init) { | 173 | Procedure1<? super IHiddenRegionFormatter> init) { |
162 | if (region == null) { | 174 | if (region == null) { |
163 | return; | 175 | return; |
164 | } | 176 | } |
@@ -174,7 +186,7 @@ public class ProblemFormatter extends AbstractJavaFormatter { | |||
174 | } | 186 | } |
175 | 187 | ||
176 | protected void appendNewLines(IFormattableDocument doc, ISequentialRegion region, | 188 | protected void appendNewLines(IFormattableDocument doc, ISequentialRegion region, |
177 | Procedure1<? super IHiddenRegionFormatter> init) { | 189 | Procedure1<? super IHiddenRegionFormatter> init) { |
178 | if (region == null) { | 190 | if (region == null) { |
179 | return; | 191 | return; |
180 | } | 192 | } |
diff --git a/subprojects/language/src/main/java/tools/refinery/language/serializer/PreferShortAssertionsProblemSemanticSequencer.java b/subprojects/language/src/main/java/tools/refinery/language/serializer/PreferShortAssertionsProblemSemanticSequencer.java index b9cafbc2..3432b2d8 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/serializer/PreferShortAssertionsProblemSemanticSequencer.java +++ b/subprojects/language/src/main/java/tools/refinery/language/serializer/PreferShortAssertionsProblemSemanticSequencer.java | |||
@@ -21,8 +21,7 @@ public class PreferShortAssertionsProblemSemanticSequencer extends ProblemSemant | |||
21 | 21 | ||
22 | @Override | 22 | @Override |
23 | protected void sequence_Assertion(ISerializationContext context, Assertion semanticObject) { | 23 | protected void sequence_Assertion(ISerializationContext context, Assertion semanticObject) { |
24 | if (semanticObject.isDefault() || | 24 | if (!(semanticObject.getValue() instanceof LogicConstant logicConstant) || |
25 | !(semanticObject.getValue() instanceof LogicConstant logicConstant) || | ||
26 | logicConstant.getLogicValue() == LogicValue.ERROR) { | 25 | logicConstant.getLogicValue() == LogicValue.ERROR) { |
27 | super.sequence_Assertion(context, semanticObject); | 26 | super.sequence_Assertion(context, semanticObject); |
28 | return; | 27 | return; |
@@ -39,6 +38,9 @@ public class PreferShortAssertionsProblemSemanticSequencer extends ProblemSemant | |||
39 | } | 38 | } |
40 | var feeder = createSequencerFeeder(context, semanticObject); | 39 | var feeder = createSequencerFeeder(context, semanticObject); |
41 | var access = grammarAccess.getAssertionAccess(); | 40 | var access = grammarAccess.getAssertionAccess(); |
41 | if (semanticObject.isDefault()) { | ||
42 | feeder.accept(access.getDefaultDefaultKeyword_0_0()); | ||
43 | } | ||
42 | feeder.accept(access.getValueShortLogicConstantParserRuleCall_1_1_0_0(), logicConstant); | 44 | feeder.accept(access.getValueShortLogicConstantParserRuleCall_1_1_0_0(), logicConstant); |
43 | feeder.accept(access.getRelationRelationQualifiedNameParserRuleCall_1_1_1_0_1(), semanticObject.getRelation()); | 45 | feeder.accept(access.getRelationRelationQualifiedNameParserRuleCall_1_1_1_0_1(), semanticObject.getRelation()); |
44 | var iterator = semanticObject.getArguments().iterator(); | 46 | var iterator = semanticObject.getArguments().iterator(); |
diff --git a/subprojects/language/src/main/java/tools/refinery/language/serializer/ProblemCrossReferenceSerializer.java b/subprojects/language/src/main/java/tools/refinery/language/serializer/ProblemCrossReferenceSerializer.java new file mode 100644 index 00000000..42950e61 --- /dev/null +++ b/subprojects/language/src/main/java/tools/refinery/language/serializer/ProblemCrossReferenceSerializer.java | |||
@@ -0,0 +1,167 @@ | |||
1 | /******************************************************************************* | ||
2 | * Copyright (c) 2008, 2018 itemis AG (http://www.itemis.eu) and others. | ||
3 | * Copyright (c) 2023 The Refinery Authors <https://refinery.tools/> | ||
4 | * This program and the accompanying materials are made available under the | ||
5 | * terms of the Eclipse Public License 2.0 which is available at | ||
6 | * http://www.eclipse.org/legal/epl-2.0. | ||
7 | * SPDX-License-Identifier: EPL-2.0 | ||
8 | *******************************************************************************/ | ||
9 | package tools.refinery.language.serializer; | ||
10 | |||
11 | import com.google.common.collect.Lists; | ||
12 | import com.google.inject.Inject; | ||
13 | import org.eclipse.emf.common.util.URI; | ||
14 | import org.eclipse.emf.ecore.EObject; | ||
15 | import org.eclipse.emf.ecore.EReference; | ||
16 | import org.eclipse.xtext.CrossReference; | ||
17 | import org.eclipse.xtext.EcoreUtil2; | ||
18 | import org.eclipse.xtext.GrammarUtil; | ||
19 | import org.eclipse.xtext.IGrammarAccess; | ||
20 | import org.eclipse.xtext.conversion.IValueConverterService; | ||
21 | import org.eclipse.xtext.conversion.ValueConverterException; | ||
22 | import org.eclipse.xtext.linking.impl.LinkingHelper; | ||
23 | import org.eclipse.xtext.naming.IQualifiedNameConverter; | ||
24 | import org.eclipse.xtext.naming.QualifiedName; | ||
25 | import org.eclipse.xtext.nodemodel.INode; | ||
26 | import org.eclipse.xtext.scoping.IScope; | ||
27 | import org.eclipse.xtext.scoping.IScopeProvider; | ||
28 | import org.eclipse.xtext.serializer.diagnostic.ISerializationDiagnostic; | ||
29 | import org.eclipse.xtext.serializer.diagnostic.SerializationDiagnostic; | ||
30 | import org.eclipse.xtext.serializer.tokens.CrossReferenceSerializer; | ||
31 | import org.eclipse.xtext.serializer.tokens.SerializerScopeProviderBinding; | ||
32 | import org.eclipse.xtext.util.EmfFormatter; | ||
33 | |||
34 | import java.util.List; | ||
35 | |||
36 | public class ProblemCrossReferenceSerializer extends CrossReferenceSerializer { | ||
37 | public static final String AMBIGUOUS_REFERENCE_DIAGNOSTIC = "tools.refinery.language.serializer" + | ||
38 | ".ProblemCrossReferenceSerializer.AMBIGUOUS_REFERENCE"; | ||
39 | |||
40 | @Inject | ||
41 | private LinkingHelper linkingHelper; | ||
42 | |||
43 | @Inject | ||
44 | private IQualifiedNameConverter qualifiedNameConverter; | ||
45 | |||
46 | @Inject | ||
47 | @SerializerScopeProviderBinding | ||
48 | private IScopeProvider scopeProvider; | ||
49 | |||
50 | @Inject | ||
51 | private IValueConverterService valueConverter; | ||
52 | |||
53 | @Inject | ||
54 | private IGrammarAccess grammarAccess; | ||
55 | |||
56 | @Override | ||
57 | public String serializeCrossRef(EObject semanticObject, CrossReference crossref, EObject target, INode node, | ||
58 | ISerializationDiagnostic.Acceptor errors) { | ||
59 | if ((target == null || target.eIsProxy()) && node != null) { | ||
60 | return tokenUtil.serializeNode(node); | ||
61 | } | ||
62 | |||
63 | final EReference ref = GrammarUtil.getReference(crossref, semanticObject.eClass()); | ||
64 | final IScope scope = scopeProvider.getScope(semanticObject, ref); | ||
65 | if (scope == null) { | ||
66 | if (errors != null) { | ||
67 | errors.accept(diagnostics.getNoScopeFoundDiagnostic(semanticObject, crossref, target)); | ||
68 | } | ||
69 | return null; | ||
70 | } | ||
71 | |||
72 | if (target != null && target.eIsProxy()) { | ||
73 | target = handleProxy(target, semanticObject, ref); | ||
74 | } | ||
75 | |||
76 | if (target != null && node != null) { | ||
77 | String text = linkingHelper.getCrossRefNodeAsString(node, true); | ||
78 | QualifiedName qualifiedName = qualifiedNameConverter.toQualifiedName(text); | ||
79 | URI targetUri = EcoreUtil2.getPlatformResourceOrNormalizedURI(target); | ||
80 | if (isUniqueInScope(scope, qualifiedName, targetUri)) { | ||
81 | return tokenUtil.serializeNode(node); | ||
82 | } | ||
83 | } | ||
84 | |||
85 | return getCrossReferenceNameFromScope(semanticObject, crossref, target, scope, errors); | ||
86 | } | ||
87 | |||
88 | private boolean isUniqueInScope(IScope scope, QualifiedName qualifiedName, URI targetUri) { | ||
89 | var iterator = scope.getElements(qualifiedName).iterator(); | ||
90 | if (!iterator.hasNext()) { | ||
91 | return false; | ||
92 | } | ||
93 | var description = iterator.next(); | ||
94 | return targetUri.equals(description.getEObjectURI()) && !iterator.hasNext(); | ||
95 | } | ||
96 | |||
97 | @Override | ||
98 | protected String getCrossReferenceNameFromScope(EObject semanticObject, CrossReference crossref, EObject target, | ||
99 | IScope scope, ISerializationDiagnostic.Acceptor errors) { | ||
100 | var ruleName = linkingHelper.getRuleNameFrom(crossref); | ||
101 | var targetUri = EcoreUtil2.getPlatformResourceOrNormalizedURI(target); | ||
102 | FoundName foundName = FoundName.NONE; | ||
103 | int shortestNameLength = Integer.MAX_VALUE; | ||
104 | String shortestName = null; | ||
105 | List<ISerializationDiagnostic> recordedErrors = null; | ||
106 | for (var description : scope.getElements(target)) { | ||
107 | var qualifiedName = description.getName(); | ||
108 | var segmentCount = qualifiedName.getSegmentCount(); | ||
109 | if (shortestName != null && segmentCount >= shortestNameLength) { | ||
110 | continue; | ||
111 | } | ||
112 | if (isUniqueInScope(scope, qualifiedName, targetUri)) { | ||
113 | var unconverted = qualifiedNameConverter.toString(qualifiedName); | ||
114 | try { | ||
115 | shortestName = valueConverter.toString(unconverted, ruleName); | ||
116 | shortestNameLength = segmentCount; | ||
117 | foundName = FoundName.VALID; | ||
118 | } catch (ValueConverterException e) { | ||
119 | if (recordedErrors == null) { | ||
120 | recordedErrors = Lists.newArrayList(); | ||
121 | } | ||
122 | recordedErrors.add(diagnostics.getValueConversionExceptionDiagnostic(semanticObject, crossref, | ||
123 | unconverted, e)); | ||
124 | } | ||
125 | } else if (foundName == FoundName.NONE) { | ||
126 | foundName = FoundName.AMBIGUOUS; | ||
127 | } | ||
128 | } | ||
129 | handleErrors(semanticObject, crossref, target, scope, errors, recordedErrors, foundName); | ||
130 | return shortestName; | ||
131 | } | ||
132 | |||
133 | private void handleErrors( | ||
134 | EObject semanticObject, CrossReference crossref, EObject target, IScope scope, | ||
135 | ISerializationDiagnostic.Acceptor errors, List<ISerializationDiagnostic> recordedErrors, | ||
136 | FoundName foundName) { | ||
137 | if (errors == null) { | ||
138 | return; | ||
139 | } | ||
140 | if (recordedErrors != null) { | ||
141 | recordedErrors.forEach(errors::accept); | ||
142 | } | ||
143 | if (foundName == FoundName.NONE) { | ||
144 | errors.accept(diagnostics.getNoEObjectDescriptionFoundDiagnostic(semanticObject, crossref, target, | ||
145 | scope)); | ||
146 | } else if (foundName == FoundName.AMBIGUOUS) { | ||
147 | // Computation of reference name copied from | ||
148 | // {@link org.eclipse.xtext.serializer.diagnostic.TokenDiagnosticProvider#getFullReferenceName}. | ||
149 | var ref = GrammarUtil.getReference(crossref); | ||
150 | var clazz = semanticObject.eClass().getName(); | ||
151 | if (ref.getEContainingClass() != semanticObject.eClass()) { | ||
152 | clazz = ref.getEContainingClass().getName() + "(" + clazz + ")"; | ||
153 | } | ||
154 | var message = "No unambiguous name could be found in scope %s.%s for %s" | ||
155 | .formatted(clazz, ref.getName(), EmfFormatter.objPath(target)); | ||
156 | var diagnostic = new SerializationDiagnostic(AMBIGUOUS_REFERENCE_DIAGNOSTIC, semanticObject, crossref, | ||
157 | grammarAccess.getGrammar(), message); | ||
158 | errors.accept(diagnostic); | ||
159 | } | ||
160 | } | ||
161 | |||
162 | private enum FoundName { | ||
163 | NONE, | ||
164 | AMBIGUOUS, | ||
165 | VALID | ||
166 | } | ||
167 | } | ||
diff --git a/subprojects/language/src/test/java/tools/refinery/language/tests/serializer/ProblemSerializerTest.java b/subprojects/language/src/test/java/tools/refinery/language/tests/serializer/ProblemSerializerTest.java index 9f4f2bbf..65675b6b 100644 --- a/subprojects/language/src/test/java/tools/refinery/language/tests/serializer/ProblemSerializerTest.java +++ b/subprojects/language/src/test/java/tools/refinery/language/tests/serializer/ProblemSerializerTest.java | |||
@@ -74,8 +74,8 @@ class ProblemSerializerTest { | |||
74 | } | 74 | } |
75 | 75 | ||
76 | @ParameterizedTest | 76 | @ParameterizedTest |
77 | @MethodSource | 77 | @MethodSource("assertionTest") |
78 | void defaultAssertionTest(LogicValue value, String valueAsString) { | 78 | void defaultAssertionTest(LogicValue value, String serializedAssertion) { |
79 | var pred = createPred(); | 79 | var pred = createPred(); |
80 | var node = ProblemFactory.eINSTANCE.createNode(); | 80 | var node = ProblemFactory.eINSTANCE.createNode(); |
81 | node.setName("a"); | 81 | node.setName("a"); |
@@ -88,12 +88,7 @@ class ProblemSerializerTest { | |||
88 | pred foo(node p). | 88 | pred foo(node p). |
89 | 89 | ||
90 | indiv a. | 90 | indiv a. |
91 | default foo(a):\040""" + valueAsString + ".\n"); | 91 | default\040""" + serializedAssertion + "\n"); |
92 | } | ||
93 | |||
94 | static Stream<Arguments> defaultAssertionTest() { | ||
95 | return Stream.of(Arguments.of(LogicValue.TRUE, "true"), Arguments.of(LogicValue.FALSE, "false"), | ||
96 | Arguments.of(LogicValue.UNKNOWN, "unknown"), Arguments.of(LogicValue.ERROR, "error")); | ||
97 | } | 92 | } |
98 | 93 | ||
99 | @Test | 94 | @Test |
@@ -161,6 +156,7 @@ class ProblemSerializerTest { | |||
161 | problem.getStatements().add(assertion); | 156 | problem.getStatements().add(assertion); |
162 | } | 157 | } |
163 | 158 | ||
159 | |||
164 | @Test | 160 | @Test |
165 | void implicitVariableTest() { | 161 | void implicitVariableTest() { |
166 | var pred = ProblemFactory.eINSTANCE.createPredicateDefinition(); | 162 | var pred = ProblemFactory.eINSTANCE.createPredicateDefinition(); |
@@ -232,20 +228,77 @@ class ProblemSerializerTest { | |||
232 | """); | 228 | """); |
233 | } | 229 | } |
234 | 230 | ||
231 | @Test | ||
232 | void unambiguousNameTest() { | ||
233 | createClassAndAssertion("Foo", "foo"); | ||
234 | |||
235 | assertSerializedResult(""" | ||
236 | class Foo { | ||
237 | Foo ref | ||
238 | } | ||
239 | |||
240 | ref(foo, foo). | ||
241 | """); | ||
242 | } | ||
243 | |||
244 | @Test | ||
245 | void ambiguousNameTest() { | ||
246 | createClassAndAssertion("Foo", "foo"); | ||
247 | createClassAndAssertion("Bar", "bar"); | ||
248 | |||
249 | assertSerializedResult(""" | ||
250 | class Foo { | ||
251 | Foo ref | ||
252 | } | ||
253 | |||
254 | Foo::ref(foo, foo). | ||
255 | |||
256 | class Bar { | ||
257 | Bar ref | ||
258 | } | ||
259 | |||
260 | Bar::ref(bar, bar). | ||
261 | """); | ||
262 | } | ||
263 | |||
264 | private void createClassAndAssertion(String className, String nodeName) { | ||
265 | var classDeclaration = ProblemFactory.eINSTANCE.createClassDeclaration(); | ||
266 | classDeclaration.setName(className); | ||
267 | var referenceDeclaration = ProblemFactory.eINSTANCE.createReferenceDeclaration(); | ||
268 | referenceDeclaration.setReferenceType(classDeclaration); | ||
269 | referenceDeclaration.setName("ref"); | ||
270 | classDeclaration.getFeatureDeclarations().add(referenceDeclaration); | ||
271 | problem.getStatements().add(classDeclaration); | ||
272 | var node = ProblemFactory.eINSTANCE.createNode(); | ||
273 | node.setName(nodeName); | ||
274 | problem.getNodes().add(node); | ||
275 | createBinaryAssertion(referenceDeclaration, node, node); | ||
276 | } | ||
277 | |||
278 | private void createBinaryAssertion(Relation relation, Node from, Node to) { | ||
279 | var assertion = ProblemFactory.eINSTANCE.createAssertion(); | ||
280 | assertion.setRelation(relation); | ||
281 | var fromArgument = ProblemFactory.eINSTANCE.createNodeAssertionArgument(); | ||
282 | fromArgument.setNode(from); | ||
283 | assertion.getArguments().add(fromArgument); | ||
284 | var toArgument = ProblemFactory.eINSTANCE.createNodeAssertionArgument(); | ||
285 | toArgument.setNode(to); | ||
286 | assertion.getArguments().add(toArgument); | ||
287 | var value = ProblemFactory.eINSTANCE.createLogicConstant(); | ||
288 | value.setLogicValue(LogicValue.TRUE); | ||
289 | assertion.setValue(value); | ||
290 | problem.getStatements().add(assertion); | ||
291 | } | ||
292 | |||
235 | private void assertSerializedResult(String expected) { | 293 | private void assertSerializedResult(String expected) { |
236 | var outputStream = new ByteArrayOutputStream(); | 294 | String problemString; |
237 | try { | 295 | try (var outputStream = new ByteArrayOutputStream()) { |
238 | resource.save(outputStream, Map.of()); | 296 | resource.save(outputStream, Map.of()); |
297 | problemString = outputStream.toString(); | ||
239 | } catch (IOException e) { | 298 | } catch (IOException e) { |
240 | throw new AssertionError("Failed to serialize problem", e); | 299 | throw new AssertionError("Failed to serialize problem", e); |
241 | } finally { | ||
242 | try { | ||
243 | outputStream.close(); | ||
244 | } catch (IOException e) { | ||
245 | // Nothing to handle in a test. | ||
246 | } | ||
247 | } | 300 | } |
248 | var problemString = outputStream.toString(); | 301 | // Nothing to handle in a test. |
249 | 302 | ||
250 | assertThat(problemString.replace("\r\n", "\n"), equalTo(expected.replace("\r\n", "\n"))); | 303 | assertThat(problemString.replace("\r\n", "\n"), equalTo(expected.replace("\r\n", "\n"))); |
251 | } | 304 | } |
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstExplorer.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstExplorer.java index ce3efb21..22f38ca9 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstExplorer.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstExplorer.java | |||
@@ -10,10 +10,10 @@ import tools.refinery.store.model.Model; | |||
10 | import java.util.Random; | 10 | import java.util.Random; |
11 | 11 | ||
12 | public class BestFirstExplorer extends BestFirstWorker { | 12 | public class BestFirstExplorer extends BestFirstWorker { |
13 | final int id; | 13 | final long id; |
14 | Random random; | 14 | Random random; |
15 | 15 | ||
16 | public BestFirstExplorer(BestFirstStoreManager storeManager, Model model, int id) { | 16 | public BestFirstExplorer(BestFirstStoreManager storeManager, Model model, long id) { |
17 | super(storeManager, model); | 17 | super(storeManager, model); |
18 | this.id = id; | 18 | this.id = id; |
19 | // The use of a non-cryptographic random generator is safe here, because we only use it to direct the state | 19 | // The use of a non-cryptographic random generator is safe here, because we only use it to direct the state |
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstStoreManager.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstStoreManager.java index 3d32f84c..c20ab9a0 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstStoreManager.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstStoreManager.java | |||
@@ -79,7 +79,7 @@ public class BestFirstStoreManager { | |||
79 | startExploration(initial, 1); | 79 | startExploration(initial, 1); |
80 | } | 80 | } |
81 | 81 | ||
82 | public void startExploration(Version initial, int randomSeed) { | 82 | public void startExploration(Version initial, long randomSeed) { |
83 | BestFirstExplorer bestFirstExplorer = new BestFirstExplorer(this, modelStore.createModelForState(initial), | 83 | BestFirstExplorer bestFirstExplorer = new BestFirstExplorer(this, modelStore.createModelForState(initial), |
84 | randomSeed); | 84 | randomSeed); |
85 | bestFirstExplorer.explore(); | 85 | bestFirstExplorer.explore(); |
diff --git a/subprojects/store-reasoning-scope/src/test/java/tools/refinery/store/reasoning/scope/PredicateScopeTest.java b/subprojects/store-reasoning-scope/src/test/java/tools/refinery/store/reasoning/scope/PredicateScopeTest.java index a2c56a6b..5ee97ce1 100644 --- a/subprojects/store-reasoning-scope/src/test/java/tools/refinery/store/reasoning/scope/PredicateScopeTest.java +++ b/subprojects/store-reasoning-scope/src/test/java/tools/refinery/store/reasoning/scope/PredicateScopeTest.java | |||
@@ -27,7 +27,6 @@ import tools.refinery.store.reasoning.translator.containment.ContainmentHierarch | |||
27 | import tools.refinery.store.reasoning.translator.metamodel.Metamodel; | 27 | import tools.refinery.store.reasoning.translator.metamodel.Metamodel; |
28 | import tools.refinery.store.reasoning.translator.metamodel.MetamodelTranslator; | 28 | import tools.refinery.store.reasoning.translator.metamodel.MetamodelTranslator; |
29 | import tools.refinery.store.reasoning.translator.multiobject.MultiObjectTranslator; | 29 | import tools.refinery.store.reasoning.translator.multiobject.MultiObjectTranslator; |
30 | import tools.refinery.store.reasoning.translator.multiplicity.ConstrainedMultiplicity; | ||
31 | import tools.refinery.store.representation.TruthValue; | 30 | import tools.refinery.store.representation.TruthValue; |
32 | import tools.refinery.store.representation.cardinality.CardinalityIntervals; | 31 | import tools.refinery.store.representation.cardinality.CardinalityIntervals; |
33 | import tools.refinery.store.statecoding.StateCoderAdapter; | 32 | import tools.refinery.store.statecoding.StateCoderAdapter; |
@@ -109,10 +108,16 @@ class PredicateScopeTest { | |||
109 | private ModelStore createStore() { | 108 | private ModelStore createStore() { |
110 | var metamodel = Metamodel.builder() | 109 | var metamodel = Metamodel.builder() |
111 | .type(index) | 110 | .type(index) |
112 | .reference(next, index, false, | 111 | .reference(next, builder -> builder |
113 | ConstrainedMultiplicity.of(CardinalityIntervals.LONE, nextInvalidMultiplicity), index, prev) | 112 | .source(index) |
114 | .reference(prev, index, false, | 113 | .target(index) |
115 | ConstrainedMultiplicity.of(CardinalityIntervals.LONE, prevInvalidMultiplicity), index, next) | 114 | .multiplicity(CardinalityIntervals.LONE, nextInvalidMultiplicity) |
115 | .opposite(prev)) | ||
116 | .reference(prev, builder -> builder | ||
117 | .source(index) | ||
118 | .target(index) | ||
119 | .multiplicity(CardinalityIntervals.LONE, prevInvalidMultiplicity) | ||
120 | .opposite(next)) | ||
116 | .build(); | 121 | .build(); |
117 | return ModelStore.builder() | 122 | return ModelStore.builder() |
118 | .with(QueryInterpreterAdapter.builder()) | 123 | .with(QueryInterpreterAdapter.builder()) |
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/seed/MapBasedSeed.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/seed/MapBasedSeed.java index 8b1c3bb3..3b78db02 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/seed/MapBasedSeed.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/seed/MapBasedSeed.java | |||
@@ -12,19 +12,19 @@ import tools.refinery.store.tuple.Tuple; | |||
12 | import java.util.Map; | 12 | import java.util.Map; |
13 | import java.util.Objects; | 13 | import java.util.Objects; |
14 | 14 | ||
15 | record MapBasedSeed<T>(int arity, Class<T> valueType, T reducedValue, Map<Tuple, T> map) implements Seed<T> { | 15 | record MapBasedSeed<T>(int arity, Class<T> valueType, T majorityValue, Map<Tuple, T> map) implements Seed<T> { |
16 | @Override | 16 | @Override |
17 | public T get(Tuple key) { | 17 | public T get(Tuple key) { |
18 | var value = map.get(key); | 18 | var value = map.get(key); |
19 | return value == null ? reducedValue : value; | 19 | return value == null ? majorityValue : value; |
20 | } | 20 | } |
21 | 21 | ||
22 | @Override | 22 | @Override |
23 | public Cursor<Tuple, T> getCursor(T defaultValue, int nodeCount) { | 23 | public Cursor<Tuple, T> getCursor(T defaultValue, int nodeCount) { |
24 | if (Objects.equals(defaultValue, reducedValue)) { | 24 | if (Objects.equals(defaultValue, majorityValue)) { |
25 | return Cursors.of(map); | 25 | return Cursors.of(map); |
26 | } | 26 | } |
27 | return new CartesianProductCursor<>(arity, nodeCount, reducedValue, defaultValue, map); | 27 | return new CartesianProductCursor<>(arity, nodeCount, majorityValue, defaultValue, map); |
28 | } | 28 | } |
29 | 29 | ||
30 | private static class CartesianProductCursor<T> implements Cursor<Tuple, T> { | 30 | private static class CartesianProductCursor<T> implements Cursor<Tuple, T> { |
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/seed/Seed.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/seed/Seed.java index 732efbcc..d9bad866 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/seed/Seed.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/seed/Seed.java | |||
@@ -19,7 +19,7 @@ public interface Seed<T> { | |||
19 | 19 | ||
20 | Class<T> valueType(); | 20 | Class<T> valueType(); |
21 | 21 | ||
22 | T reducedValue(); | 22 | T majorityValue(); |
23 | 23 | ||
24 | T get(Tuple key); | 24 | T get(Tuple key); |
25 | 25 | ||
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/DirectedCrossReferenceInfo.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/DirectedCrossReferenceInfo.java index d8c6a5ea..7241b032 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/DirectedCrossReferenceInfo.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/DirectedCrossReferenceInfo.java | |||
@@ -7,9 +7,11 @@ package tools.refinery.store.reasoning.translator.crossreference; | |||
7 | 7 | ||
8 | import tools.refinery.store.reasoning.representation.PartialRelation; | 8 | import tools.refinery.store.reasoning.representation.PartialRelation; |
9 | import tools.refinery.store.reasoning.translator.multiplicity.Multiplicity; | 9 | import tools.refinery.store.reasoning.translator.multiplicity.Multiplicity; |
10 | import tools.refinery.store.representation.TruthValue; | ||
10 | 11 | ||
11 | public record DirectedCrossReferenceInfo(PartialRelation sourceType, Multiplicity sourceMultiplicity, | 12 | public record DirectedCrossReferenceInfo(PartialRelation sourceType, Multiplicity sourceMultiplicity, |
12 | PartialRelation targetType, Multiplicity targetMultiplicity) { | 13 | PartialRelation targetType, Multiplicity targetMultiplicity, |
14 | TruthValue defaultValue) { | ||
13 | public boolean isConstrained() { | 15 | public boolean isConstrained() { |
14 | return sourceMultiplicity.isConstrained() || targetMultiplicity.isConstrained(); | 16 | return sourceMultiplicity.isConstrained() || targetMultiplicity.isConstrained(); |
15 | } | 17 | } |
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/DirectedCrossReferenceInitializer.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/DirectedCrossReferenceInitializer.java new file mode 100644 index 00000000..9347e91e --- /dev/null +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/DirectedCrossReferenceInitializer.java | |||
@@ -0,0 +1,52 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.reasoning.translator.crossreference; | ||
7 | |||
8 | import tools.refinery.store.model.Model; | ||
9 | import tools.refinery.store.reasoning.ReasoningAdapter; | ||
10 | import tools.refinery.store.reasoning.refinement.PartialModelInitializer; | ||
11 | import tools.refinery.store.reasoning.representation.PartialRelation; | ||
12 | import tools.refinery.store.reasoning.seed.ModelSeed; | ||
13 | import tools.refinery.store.representation.Symbol; | ||
14 | import tools.refinery.store.representation.TruthValue; | ||
15 | import tools.refinery.store.tuple.Tuple; | ||
16 | |||
17 | class DirectedCrossReferenceInitializer implements PartialModelInitializer { | ||
18 | private final PartialRelation linkType; | ||
19 | private final PartialRelation sourceType; | ||
20 | private final PartialRelation targetType; | ||
21 | private final Symbol<TruthValue> symbol; | ||
22 | |||
23 | public DirectedCrossReferenceInitializer(PartialRelation linkType, PartialRelation sourceType, | ||
24 | PartialRelation targetType, Symbol<TruthValue> symbol) { | ||
25 | this.linkType = linkType; | ||
26 | this.sourceType = sourceType; | ||
27 | this.targetType = targetType; | ||
28 | this.symbol = symbol; | ||
29 | } | ||
30 | |||
31 | @Override | ||
32 | public void initialize(Model model, ModelSeed modelSeed) { | ||
33 | var reasoningAdapter = model.getAdapter(ReasoningAdapter.class); | ||
34 | var sourceRefiner = reasoningAdapter.getRefiner(sourceType); | ||
35 | var targetRefiner = reasoningAdapter.getRefiner(targetType); | ||
36 | var interpretation = model.getInterpretation(symbol); | ||
37 | var cursor = modelSeed.getCursor(linkType, symbol.defaultValue()); | ||
38 | while (cursor.move()) { | ||
39 | var key = cursor.getKey(); | ||
40 | var value = cursor.getValue(); | ||
41 | interpretation.put(key, value); | ||
42 | if (value.must()) { | ||
43 | boolean merged = sourceRefiner.merge(Tuple.of(key.get(0)), TruthValue.TRUE) && | ||
44 | targetRefiner.merge(Tuple.of(key.get(1)), TruthValue.TRUE); | ||
45 | if (!merged) { | ||
46 | throw new IllegalArgumentException("Failed to merge end types of reference %s for key %s" | ||
47 | .formatted(linkType, key)); | ||
48 | } | ||
49 | } | ||
50 | } | ||
51 | } | ||
52 | } | ||
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/DirectedCrossReferenceTranslator.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/DirectedCrossReferenceTranslator.java index 9028337c..fc7477f1 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/DirectedCrossReferenceTranslator.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/DirectedCrossReferenceTranslator.java | |||
@@ -5,6 +5,7 @@ | |||
5 | */ | 5 | */ |
6 | package tools.refinery.store.reasoning.translator.crossreference; | 6 | package tools.refinery.store.reasoning.translator.crossreference; |
7 | 7 | ||
8 | import tools.refinery.store.dse.propagation.PropagationBuilder; | ||
8 | import tools.refinery.store.dse.transition.Rule; | 9 | import tools.refinery.store.dse.transition.Rule; |
9 | import tools.refinery.store.model.ModelStoreBuilder; | 10 | import tools.refinery.store.model.ModelStoreBuilder; |
10 | import tools.refinery.store.model.ModelStoreConfiguration; | 11 | import tools.refinery.store.model.ModelStoreConfiguration; |
@@ -14,9 +15,9 @@ import tools.refinery.store.query.view.ForbiddenView; | |||
14 | import tools.refinery.store.reasoning.lifting.DnfLifter; | 15 | import tools.refinery.store.reasoning.lifting.DnfLifter; |
15 | import tools.refinery.store.reasoning.literal.Concreteness; | 16 | import tools.refinery.store.reasoning.literal.Concreteness; |
16 | import tools.refinery.store.reasoning.literal.Modality; | 17 | import tools.refinery.store.reasoning.literal.Modality; |
17 | import tools.refinery.store.reasoning.refinement.RefinementBasedInitializer; | ||
18 | import tools.refinery.store.reasoning.representation.PartialRelation; | 18 | import tools.refinery.store.reasoning.representation.PartialRelation; |
19 | import tools.refinery.store.reasoning.translator.PartialRelationTranslator; | 19 | import tools.refinery.store.reasoning.translator.PartialRelationTranslator; |
20 | import tools.refinery.store.reasoning.translator.TranslationException; | ||
20 | import tools.refinery.store.reasoning.translator.multiplicity.InvalidMultiplicityErrorTranslator; | 21 | import tools.refinery.store.reasoning.translator.multiplicity.InvalidMultiplicityErrorTranslator; |
21 | import tools.refinery.store.reasoning.translator.multiplicity.Multiplicity; | 22 | import tools.refinery.store.reasoning.translator.multiplicity.Multiplicity; |
22 | import tools.refinery.store.representation.Symbol; | 23 | import tools.refinery.store.representation.Symbol; |
@@ -24,6 +25,7 @@ import tools.refinery.store.representation.TruthValue; | |||
24 | 25 | ||
25 | import static tools.refinery.store.query.literal.Literals.not; | 26 | import static tools.refinery.store.query.literal.Literals.not; |
26 | import static tools.refinery.store.reasoning.actions.PartialActionLiterals.add; | 27 | import static tools.refinery.store.reasoning.actions.PartialActionLiterals.add; |
28 | import static tools.refinery.store.reasoning.actions.PartialActionLiterals.merge; | ||
27 | import static tools.refinery.store.reasoning.literal.PartialLiterals.*; | 29 | import static tools.refinery.store.reasoning.literal.PartialLiterals.*; |
28 | import static tools.refinery.store.reasoning.translator.multiobject.MultiObjectTranslator.MULTI_VIEW; | 30 | import static tools.refinery.store.reasoning.translator.multiobject.MultiObjectTranslator.MULTI_VIEW; |
29 | 31 | ||
@@ -35,7 +37,7 @@ public class DirectedCrossReferenceTranslator implements ModelStoreConfiguration | |||
35 | public DirectedCrossReferenceTranslator(PartialRelation linkType, DirectedCrossReferenceInfo info) { | 37 | public DirectedCrossReferenceTranslator(PartialRelation linkType, DirectedCrossReferenceInfo info) { |
36 | this.linkType = linkType; | 38 | this.linkType = linkType; |
37 | this.info = info; | 39 | this.info = info; |
38 | symbol = Symbol.of(linkType.name(), 2, TruthValue.class, TruthValue.UNKNOWN); | 40 | symbol = Symbol.of(linkType.name(), 2, TruthValue.class, info.defaultValue()); |
39 | } | 41 | } |
40 | 42 | ||
41 | @Override | 43 | @Override |
@@ -45,41 +47,77 @@ public class DirectedCrossReferenceTranslator implements ModelStoreConfiguration | |||
45 | var targetType = info.targetType(); | 47 | var targetType = info.targetType(); |
46 | var mayNewSource = createMayHelper(sourceType, info.sourceMultiplicity(), false); | 48 | var mayNewSource = createMayHelper(sourceType, info.sourceMultiplicity(), false); |
47 | var mayNewTarget = createMayHelper(targetType, info.targetMultiplicity(), true); | 49 | var mayNewTarget = createMayHelper(targetType, info.targetMultiplicity(), true); |
48 | var forbiddenView = new ForbiddenView(symbol); | ||
49 | var mayName = DnfLifter.decorateName(name, Modality.MAY, Concreteness.PARTIAL); | 50 | var mayName = DnfLifter.decorateName(name, Modality.MAY, Concreteness.PARTIAL); |
50 | 51 | ||
51 | storeBuilder.with(PartialRelationTranslator.of(linkType) | 52 | var defaultValue = info.defaultValue(); |
52 | .symbol(symbol) | 53 | if (defaultValue.must()) { |
53 | .may(Query.of(mayName, (builder, source, target) -> { | 54 | throw new TranslationException(linkType, "Unsupported default value %s for directed cross references %s" |
55 | .formatted(defaultValue, linkType)); | ||
56 | } | ||
57 | |||
58 | var translator = PartialRelationTranslator.of(linkType); | ||
59 | translator.symbol(symbol); | ||
60 | if (defaultValue.may()) { | ||
61 | var forbiddenView = new ForbiddenView(symbol); | ||
62 | translator.may(Query.of(mayName, (builder, source, target) -> { | ||
63 | builder.clause( | ||
64 | mayNewSource.call(source), | ||
65 | mayNewTarget.call(target), | ||
66 | not(forbiddenView.call(source, target)) | ||
67 | ); | ||
68 | if (info.isConstrained()) { | ||
69 | // Violation of monotonicity: | ||
70 | // Edges violating upper multiplicity will not be marked as {@code ERROR}, but the | ||
71 | // corresponding error pattern will already mark the node as invalid. | ||
72 | builder.clause( | ||
73 | must(linkType.call(source, target)), | ||
74 | not(forbiddenView.call(source, target)), | ||
75 | may(sourceType.call(source)), | ||
76 | may(targetType.call(target)) | ||
77 | ); | ||
78 | } | ||
79 | })); | ||
80 | } else { | ||
81 | var propagationBuilder = storeBuilder.getAdapter(PropagationBuilder.class); | ||
82 | propagationBuilder.rule(Rule.of(name + "#invalidLink", (builder, p1, p2) -> { | ||
83 | builder.clause( | ||
84 | may(linkType.call(p1, p2)), | ||
85 | not(may(sourceType.call(p1))) | ||
86 | ); | ||
87 | builder.clause( | ||
88 | may(linkType.call(p1, p2)), | ||
89 | not(may(targetType.call(p2))) | ||
90 | ); | ||
91 | if (info.isConstrained()) { | ||
92 | builder.clause( | ||
93 | may(linkType.call(p1, p2)), | ||
94 | not(must(linkType.call(p1, p2))), | ||
95 | not(mayNewSource.call(p1)) | ||
96 | ); | ||
54 | builder.clause( | 97 | builder.clause( |
55 | mayNewSource.call(source), | 98 | may(linkType.call(p1, p2)), |
56 | mayNewTarget.call(target), | 99 | not(must(linkType.call(p1, p2))), |
57 | not(forbiddenView.call(source, target)) | 100 | not(mayNewTarget.call(p2)) |
58 | ); | 101 | ); |
59 | if (info.isConstrained()) { | 102 | } |
60 | // Violation of monotonicity: | 103 | builder.action( |
61 | // Edges violating upper multiplicity will not be marked as {@code ERROR}, but the | 104 | merge(linkType, TruthValue.FALSE, p1, p2) |
62 | // corresponding error pattern will already mark the node as invalid. | 105 | ); |
63 | builder.clause( | 106 | })); |
64 | must(linkType.call(source, target)), | 107 | } |
65 | not(forbiddenView.call(source, target)), | 108 | translator.refiner(DirectedCrossReferenceRefiner.of(symbol, sourceType, targetType)); |
66 | may(sourceType.call(source)), | 109 | translator.initializer(new DirectedCrossReferenceInitializer(linkType, sourceType, targetType, symbol)); |
67 | may(targetType.call(target)) | 110 | translator.decision(Rule.of(linkType.name(), (builder, source, target) -> builder |
68 | ); | 111 | .clause( |
69 | } | 112 | may(linkType.call(source, target)), |
70 | })) | 113 | not(candidateMust(linkType.call(source, target))), |
71 | .refiner(DirectedCrossReferenceRefiner.of(symbol, sourceType, targetType)) | 114 | not(MULTI_VIEW.call(source)), |
72 | .initializer(new RefinementBasedInitializer<>(linkType)) | 115 | not(MULTI_VIEW.call(target)) |
73 | .decision(Rule.of(linkType.name(), (builder, source, target) -> builder | 116 | ) |
74 | .clause( | 117 | .action( |
75 | may(linkType.call(source, target)), | 118 | add(linkType, source, target) |
76 | not(candidateMust(linkType.call(source, target))), | 119 | ))); |
77 | not(MULTI_VIEW.call(source)), | 120 | storeBuilder.with(translator); |
78 | not(MULTI_VIEW.call(target)) | ||
79 | ) | ||
80 | .action( | ||
81 | add(linkType, source, target) | ||
82 | )))); | ||
83 | 121 | ||
84 | storeBuilder.with(new InvalidMultiplicityErrorTranslator(sourceType, linkType, false, | 122 | storeBuilder.with(new InvalidMultiplicityErrorTranslator(sourceType, linkType, false, |
85 | info.sourceMultiplicity())); | 123 | info.sourceMultiplicity())); |
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/UndirectedCrossReferenceInfo.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/UndirectedCrossReferenceInfo.java index fe99bc54..34e9032a 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/UndirectedCrossReferenceInfo.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/UndirectedCrossReferenceInfo.java | |||
@@ -7,8 +7,9 @@ package tools.refinery.store.reasoning.translator.crossreference; | |||
7 | 7 | ||
8 | import tools.refinery.store.reasoning.representation.PartialRelation; | 8 | import tools.refinery.store.reasoning.representation.PartialRelation; |
9 | import tools.refinery.store.reasoning.translator.multiplicity.Multiplicity; | 9 | import tools.refinery.store.reasoning.translator.multiplicity.Multiplicity; |
10 | import tools.refinery.store.representation.TruthValue; | ||
10 | 11 | ||
11 | public record UndirectedCrossReferenceInfo(PartialRelation type, Multiplicity multiplicity) { | 12 | public record UndirectedCrossReferenceInfo(PartialRelation type, Multiplicity multiplicity, TruthValue defaultValue) { |
12 | public boolean isConstrained() { | 13 | public boolean isConstrained() { |
13 | return multiplicity.isConstrained(); | 14 | return multiplicity.isConstrained(); |
14 | } | 15 | } |
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/UndirectedCrossReferenceInitializer.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/UndirectedCrossReferenceInitializer.java new file mode 100644 index 00000000..77339aa0 --- /dev/null +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/UndirectedCrossReferenceInitializer.java | |||
@@ -0,0 +1,84 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.reasoning.translator.crossreference; | ||
7 | |||
8 | import org.jetbrains.annotations.NotNull; | ||
9 | import tools.refinery.store.model.Model; | ||
10 | import tools.refinery.store.reasoning.ReasoningAdapter; | ||
11 | import tools.refinery.store.reasoning.refinement.PartialModelInitializer; | ||
12 | import tools.refinery.store.reasoning.representation.PartialRelation; | ||
13 | import tools.refinery.store.reasoning.seed.ModelSeed; | ||
14 | import tools.refinery.store.reasoning.translator.TranslationException; | ||
15 | import tools.refinery.store.representation.Symbol; | ||
16 | import tools.refinery.store.representation.TruthValue; | ||
17 | import tools.refinery.store.tuple.Tuple; | ||
18 | |||
19 | import java.util.LinkedHashMap; | ||
20 | |||
21 | class UndirectedCrossReferenceInitializer implements PartialModelInitializer { | ||
22 | private final PartialRelation linkType; | ||
23 | private final PartialRelation sourceType; | ||
24 | private final Symbol<TruthValue> symbol; | ||
25 | |||
26 | UndirectedCrossReferenceInitializer(PartialRelation linkType, PartialRelation sourceType, | ||
27 | Symbol<TruthValue> symbol) { | ||
28 | this.linkType = linkType; | ||
29 | this.sourceType = sourceType; | ||
30 | this.symbol = symbol; | ||
31 | } | ||
32 | |||
33 | @Override | ||
34 | public void initialize(Model model, ModelSeed modelSeed) { | ||
35 | var reasoningAdapter = model.getAdapter(ReasoningAdapter.class); | ||
36 | var mergedMap = getMergedMap(modelSeed); | ||
37 | var sourceRefiner = reasoningAdapter.getRefiner(sourceType); | ||
38 | var interpretation = model.getInterpretation(symbol); | ||
39 | for (var entry : mergedMap.entrySet()) { | ||
40 | var key = entry.getKey(); | ||
41 | var value = entry.getValue(); | ||
42 | interpretation.put(key, value); | ||
43 | if (value.must()) { | ||
44 | boolean merged = sourceRefiner.merge(Tuple.of(key.get(0)), TruthValue.TRUE) && | ||
45 | sourceRefiner.merge(Tuple.of(key.get(1)), TruthValue.TRUE); | ||
46 | if (!merged) { | ||
47 | throw new IllegalArgumentException("Failed to merge end types of reference %s for key %s" | ||
48 | .formatted(linkType, key)); | ||
49 | } | ||
50 | } | ||
51 | } | ||
52 | } | ||
53 | |||
54 | @NotNull | ||
55 | private LinkedHashMap<Tuple, TruthValue> getMergedMap(ModelSeed modelSeed) { | ||
56 | var defaultValue = symbol.defaultValue(); | ||
57 | var originalMap = new LinkedHashMap<Tuple, TruthValue>(); | ||
58 | var cursor = modelSeed.getCursor(linkType, defaultValue); | ||
59 | while (cursor.move()) { | ||
60 | if (originalMap.put(cursor.getKey(), cursor.getValue()) != null) { | ||
61 | throw new TranslationException(linkType, "Duplicate value for key " + cursor.getKey()); | ||
62 | } | ||
63 | } | ||
64 | var mergedMap = LinkedHashMap.<Tuple, TruthValue>newLinkedHashMap(originalMap.size()); | ||
65 | for (var entry : originalMap.entrySet()) { | ||
66 | var key = entry.getKey(); | ||
67 | var value = entry.getValue(); | ||
68 | int first = key.get(0); | ||
69 | int second = key.get(1); | ||
70 | var oppositeKey = Tuple.of(second, first); | ||
71 | var oppositeValue = originalMap.get(oppositeKey); | ||
72 | if (oppositeValue != null && second < first) { | ||
73 | // Already processed entry. | ||
74 | continue; | ||
75 | } | ||
76 | var mergedValue = value.merge(oppositeValue == null ? defaultValue : oppositeValue); | ||
77 | mergedMap.put(key, mergedValue); | ||
78 | if (first != second) { | ||
79 | mergedMap.put(oppositeKey, mergedValue); | ||
80 | } | ||
81 | } | ||
82 | return mergedMap; | ||
83 | } | ||
84 | } | ||
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/UndirectedCrossReferenceTranslator.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/UndirectedCrossReferenceTranslator.java index c554e2a4..b76838b3 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/UndirectedCrossReferenceTranslator.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/UndirectedCrossReferenceTranslator.java | |||
@@ -5,6 +5,7 @@ | |||
5 | */ | 5 | */ |
6 | package tools.refinery.store.reasoning.translator.crossreference; | 6 | package tools.refinery.store.reasoning.translator.crossreference; |
7 | 7 | ||
8 | import tools.refinery.store.dse.propagation.PropagationBuilder; | ||
8 | import tools.refinery.store.dse.transition.Rule; | 9 | import tools.refinery.store.dse.transition.Rule; |
9 | import tools.refinery.store.model.ModelStoreBuilder; | 10 | import tools.refinery.store.model.ModelStoreBuilder; |
10 | import tools.refinery.store.model.ModelStoreConfiguration; | 11 | import tools.refinery.store.model.ModelStoreConfiguration; |
@@ -13,15 +14,16 @@ import tools.refinery.store.query.view.ForbiddenView; | |||
13 | import tools.refinery.store.reasoning.lifting.DnfLifter; | 14 | import tools.refinery.store.reasoning.lifting.DnfLifter; |
14 | import tools.refinery.store.reasoning.literal.Concreteness; | 15 | import tools.refinery.store.reasoning.literal.Concreteness; |
15 | import tools.refinery.store.reasoning.literal.Modality; | 16 | import tools.refinery.store.reasoning.literal.Modality; |
16 | import tools.refinery.store.reasoning.refinement.RefinementBasedInitializer; | ||
17 | import tools.refinery.store.reasoning.representation.PartialRelation; | 17 | import tools.refinery.store.reasoning.representation.PartialRelation; |
18 | import tools.refinery.store.reasoning.translator.PartialRelationTranslator; | 18 | import tools.refinery.store.reasoning.translator.PartialRelationTranslator; |
19 | import tools.refinery.store.reasoning.translator.TranslationException; | ||
19 | import tools.refinery.store.reasoning.translator.multiplicity.InvalidMultiplicityErrorTranslator; | 20 | import tools.refinery.store.reasoning.translator.multiplicity.InvalidMultiplicityErrorTranslator; |
20 | import tools.refinery.store.representation.Symbol; | 21 | import tools.refinery.store.representation.Symbol; |
21 | import tools.refinery.store.representation.TruthValue; | 22 | import tools.refinery.store.representation.TruthValue; |
22 | 23 | ||
23 | import static tools.refinery.store.query.literal.Literals.not; | 24 | import static tools.refinery.store.query.literal.Literals.not; |
24 | import static tools.refinery.store.reasoning.actions.PartialActionLiterals.add; | 25 | import static tools.refinery.store.reasoning.actions.PartialActionLiterals.add; |
26 | import static tools.refinery.store.reasoning.actions.PartialActionLiterals.merge; | ||
25 | import static tools.refinery.store.reasoning.literal.PartialLiterals.*; | 27 | import static tools.refinery.store.reasoning.literal.PartialLiterals.*; |
26 | import static tools.refinery.store.reasoning.translator.multiobject.MultiObjectTranslator.MULTI_VIEW; | 28 | import static tools.refinery.store.reasoning.translator.multiobject.MultiObjectTranslator.MULTI_VIEW; |
27 | 29 | ||
@@ -33,50 +35,77 @@ public class UndirectedCrossReferenceTranslator implements ModelStoreConfigurati | |||
33 | public UndirectedCrossReferenceTranslator(PartialRelation linkType, UndirectedCrossReferenceInfo info) { | 35 | public UndirectedCrossReferenceTranslator(PartialRelation linkType, UndirectedCrossReferenceInfo info) { |
34 | this.linkType = linkType; | 36 | this.linkType = linkType; |
35 | this.info = info; | 37 | this.info = info; |
36 | symbol = Symbol.of(linkType.name(), 2, TruthValue.class, TruthValue.UNKNOWN); | 38 | symbol = Symbol.of(linkType.name(), 2, TruthValue.class, info.defaultValue()); |
37 | } | 39 | } |
38 | 40 | ||
39 | @Override | 41 | @Override |
40 | public void apply(ModelStoreBuilder storeBuilder) { | 42 | public void apply(ModelStoreBuilder storeBuilder) { |
41 | var name = linkType.name(); | 43 | var name = linkType.name(); |
42 | var type = info.type(); | 44 | var type = info.type(); |
43 | var forbiddenView = new ForbiddenView(symbol); | ||
44 | var mayName = DnfLifter.decorateName(name, Modality.MAY, Concreteness.PARTIAL); | 45 | var mayName = DnfLifter.decorateName(name, Modality.MAY, Concreteness.PARTIAL); |
45 | 46 | ||
47 | var defaultValue = info.defaultValue(); | ||
48 | if (defaultValue.must()) { | ||
49 | throw new TranslationException(linkType, "Unsupported default value %s for directed cross references %s" | ||
50 | .formatted(defaultValue, linkType)); | ||
51 | } | ||
52 | |||
46 | var mayNewSource = CrossReferenceUtils.createMayHelper(linkType, type, info.multiplicity(), false); | 53 | var mayNewSource = CrossReferenceUtils.createMayHelper(linkType, type, info.multiplicity(), false); |
47 | 54 | ||
48 | storeBuilder.with(PartialRelationTranslator.of(linkType) | 55 | var translator = PartialRelationTranslator.of(linkType); |
49 | .symbol(symbol) | 56 | translator.symbol(symbol); |
50 | .may(Query.of(mayName, (builder, source, target) -> { | 57 | if (defaultValue.may()) { |
58 | var forbiddenView = new ForbiddenView(symbol); | ||
59 | translator.may(Query.of(mayName, (builder, source, target) -> { | ||
60 | builder.clause( | ||
61 | mayNewSource.call(source), | ||
62 | mayNewSource.call(target), | ||
63 | not(forbiddenView.call(source, target)) | ||
64 | ); | ||
65 | if (info.isConstrained()) { | ||
66 | // Violation of monotonicity: | ||
67 | // Edges violating upper multiplicity will not be marked as {@code ERROR}, but the | ||
68 | // corresponding error pattern will already mark the node as invalid. | ||
69 | builder.clause( | ||
70 | must(linkType.call(source, target)), | ||
71 | not(forbiddenView.call(source, target)), | ||
72 | may(type.call(source)), | ||
73 | may(type.call(target)) | ||
74 | ); | ||
75 | } | ||
76 | })); | ||
77 | } else { | ||
78 | var propagationBuilder = storeBuilder.getAdapter(PropagationBuilder.class); | ||
79 | propagationBuilder.rule(Rule.of(name + "#invalidLink", (builder, p1, p2) -> { | ||
80 | builder.clause( | ||
81 | may(linkType.call(p1, p2)), | ||
82 | not(may(type.call(p1))) | ||
83 | ); | ||
84 | if (info.isConstrained()) { | ||
51 | builder.clause( | 85 | builder.clause( |
52 | mayNewSource.call(source), | 86 | may(linkType.call(p1, p2)), |
53 | mayNewSource.call(target), | 87 | not(must(linkType.call(p1, p2))), |
54 | not(forbiddenView.call(source, target)) | 88 | not(mayNewSource.call(p1)) |
55 | ); | 89 | ); |
56 | if (info.isConstrained()) { | 90 | } |
57 | // Violation of monotonicity: | 91 | builder.action( |
58 | // Edges violating upper multiplicity will not be marked as {@code ERROR}, but the | 92 | merge(linkType, TruthValue.FALSE, p1, p2) |
59 | // corresponding error pattern will already mark the node as invalid. | 93 | ); |
60 | builder.clause( | 94 | })); |
61 | must(linkType.call(source, target)), | 95 | } |
62 | not(forbiddenView.call(source, target)), | 96 | translator.refiner(UndirectedCrossReferenceRefiner.of(symbol, type)); |
63 | may(type.call(source)), | 97 | translator.initializer(new UndirectedCrossReferenceInitializer(linkType, type, symbol)); |
64 | may(type.call(target)) | 98 | translator.decision(Rule.of(linkType.name(), (builder, source, target) -> builder |
65 | ); | 99 | .clause( |
66 | } | 100 | may(linkType.call(source, target)), |
67 | })) | 101 | not(candidateMust(linkType.call(source, target))), |
68 | .refiner(UndirectedCrossReferenceRefiner.of(symbol, type)) | 102 | not(MULTI_VIEW.call(source)), |
69 | .initializer(new RefinementBasedInitializer<>(linkType)) | 103 | not(MULTI_VIEW.call(target)) |
70 | .decision(Rule.of(linkType.name(), (builder, source, target) -> builder | 104 | ) |
71 | .clause( | 105 | .action( |
72 | may(linkType.call(source, target)), | 106 | add(linkType, source, target) |
73 | not(candidateMust(linkType.call(source, target))), | 107 | ))); |
74 | not(MULTI_VIEW.call(source)), | 108 | storeBuilder.with(translator); |
75 | not(MULTI_VIEW.call(target)) | ||
76 | ) | ||
77 | .action( | ||
78 | add(linkType, source, target) | ||
79 | )))); | ||
80 | 109 | ||
81 | storeBuilder.with(new InvalidMultiplicityErrorTranslator(type, linkType, false, info.multiplicity())); | 110 | storeBuilder.with(new InvalidMultiplicityErrorTranslator(type, linkType, false, info.multiplicity())); |
82 | } | 111 | } |
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/metamodel/MetamodelBuilder.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/metamodel/MetamodelBuilder.java index 74022fc6..a5047768 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/metamodel/MetamodelBuilder.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/metamodel/MetamodelBuilder.java | |||
@@ -16,6 +16,7 @@ import tools.refinery.store.reasoning.translator.multiplicity.UnconstrainedMulti | |||
16 | import tools.refinery.store.reasoning.translator.typehierarchy.TypeInfo; | 16 | import tools.refinery.store.reasoning.translator.typehierarchy.TypeInfo; |
17 | 17 | ||
18 | import java.util.*; | 18 | import java.util.*; |
19 | import java.util.function.Consumer; | ||
19 | 20 | ||
20 | public class MetamodelBuilder { | 21 | public class MetamodelBuilder { |
21 | private final ContainedTypeHierarchyBuilder typeHierarchyBuilder = new ContainedTypeHierarchyBuilder(); | 22 | private final ContainedTypeHierarchyBuilder typeHierarchyBuilder = new ContainedTypeHierarchyBuilder(); |
@@ -68,6 +69,12 @@ public class MetamodelBuilder { | |||
68 | return this; | 69 | return this; |
69 | } | 70 | } |
70 | 71 | ||
72 | public MetamodelBuilder reference(PartialRelation linkType, Consumer<ReferenceInfoBuilder> callback) { | ||
73 | var builder = ReferenceInfo.builder(); | ||
74 | callback.accept(builder); | ||
75 | return reference(linkType, builder.build()); | ||
76 | } | ||
77 | |||
71 | public MetamodelBuilder reference(PartialRelation linkType, ReferenceInfo info) { | 78 | public MetamodelBuilder reference(PartialRelation linkType, ReferenceInfo info) { |
72 | if (linkType.arity() != 2) { | 79 | if (linkType.arity() != 2) { |
73 | throw new TranslationException(linkType, | 80 | throw new TranslationException(linkType, |
@@ -81,47 +88,6 @@ public class MetamodelBuilder { | |||
81 | return this; | 88 | return this; |
82 | } | 89 | } |
83 | 90 | ||
84 | public MetamodelBuilder reference(PartialRelation linkType, PartialRelation sourceType, boolean containment, | ||
85 | Multiplicity multiplicity, PartialRelation targetType, | ||
86 | PartialRelation opposite) { | ||
87 | return reference(linkType, new ReferenceInfo(containment, sourceType, multiplicity, targetType, opposite)); | ||
88 | } | ||
89 | |||
90 | public MetamodelBuilder reference(PartialRelation linkType, PartialRelation sourceType, Multiplicity multiplicity, | ||
91 | PartialRelation targetType, PartialRelation opposite) { | ||
92 | return reference(linkType, sourceType, false, multiplicity, targetType, opposite); | ||
93 | } | ||
94 | |||
95 | public MetamodelBuilder reference(PartialRelation linkType, PartialRelation sourceType, | ||
96 | boolean containment, PartialRelation targetType, PartialRelation opposite) { | ||
97 | return reference(linkType, sourceType, containment, UnconstrainedMultiplicity.INSTANCE, targetType, opposite); | ||
98 | } | ||
99 | |||
100 | public MetamodelBuilder reference(PartialRelation linkType, PartialRelation sourceType, PartialRelation targetType, | ||
101 | PartialRelation opposite) { | ||
102 | return reference(linkType, sourceType, UnconstrainedMultiplicity.INSTANCE, targetType, opposite); | ||
103 | } | ||
104 | |||
105 | public MetamodelBuilder reference(PartialRelation linkType, PartialRelation sourceType, boolean containment, | ||
106 | Multiplicity multiplicity, PartialRelation targetType) { | ||
107 | return reference(linkType, sourceType, containment, multiplicity, targetType, null); | ||
108 | } | ||
109 | |||
110 | public MetamodelBuilder reference(PartialRelation linkType, PartialRelation sourceType, Multiplicity multiplicity, | ||
111 | PartialRelation targetType) { | ||
112 | return reference(linkType, sourceType, multiplicity, targetType, null); | ||
113 | } | ||
114 | |||
115 | public MetamodelBuilder reference(PartialRelation linkType, PartialRelation sourceType, boolean containment, | ||
116 | PartialRelation targetType) { | ||
117 | return reference(linkType, sourceType, containment, targetType, null); | ||
118 | } | ||
119 | |||
120 | public MetamodelBuilder reference(PartialRelation linkType, PartialRelation sourceType, | ||
121 | PartialRelation targetType) { | ||
122 | return reference(linkType, sourceType, targetType, null); | ||
123 | } | ||
124 | |||
125 | public MetamodelBuilder references(Collection<Map.Entry<PartialRelation, ReferenceInfo>> entries) { | 91 | public MetamodelBuilder references(Collection<Map.Entry<PartialRelation, ReferenceInfo>> entries) { |
126 | for (var entry : entries) { | 92 | for (var entry : entries) { |
127 | reference(entry.getKey(), entry.getValue()); | 93 | reference(entry.getKey(), entry.getValue()); |
@@ -160,10 +126,12 @@ public class MetamodelBuilder { | |||
160 | var targetType = info.targetType(); | 126 | var targetType = info.targetType(); |
161 | var opposite = info.opposite(); | 127 | var opposite = info.opposite(); |
162 | Multiplicity targetMultiplicity = UnconstrainedMultiplicity.INSTANCE; | 128 | Multiplicity targetMultiplicity = UnconstrainedMultiplicity.INSTANCE; |
129 | var defaultValue = info.defaultValue(); | ||
163 | if (opposite != null) { | 130 | if (opposite != null) { |
164 | var oppositeInfo = referenceInfoMap.get(opposite); | 131 | var oppositeInfo = referenceInfoMap.get(opposite); |
165 | validateOpposite(linkType, info, opposite, oppositeInfo); | 132 | validateOpposite(linkType, info, opposite, oppositeInfo); |
166 | targetMultiplicity = oppositeInfo.multiplicity(); | 133 | targetMultiplicity = oppositeInfo.multiplicity(); |
134 | defaultValue = defaultValue.merge(oppositeInfo.defaultValue()); | ||
167 | if (oppositeInfo.containment()) { | 135 | if (oppositeInfo.containment()) { |
168 | // Skip processing this reference and process it once we encounter its containment opposite. | 136 | // Skip processing this reference and process it once we encounter its containment opposite. |
169 | return; | 137 | return; |
@@ -175,7 +143,7 @@ public class MetamodelBuilder { | |||
175 | targetType, linkType, sourceType)); | 143 | targetType, linkType, sourceType)); |
176 | } | 144 | } |
177 | undirectedCrossReferences.put(linkType, new UndirectedCrossReferenceInfo(sourceType, | 145 | undirectedCrossReferences.put(linkType, new UndirectedCrossReferenceInfo(sourceType, |
178 | info.multiplicity())); | 146 | info.multiplicity(), defaultValue)); |
179 | return; | 147 | return; |
180 | } | 148 | } |
181 | oppositeReferences.put(opposite, linkType); | 149 | oppositeReferences.put(opposite, linkType); |
@@ -185,7 +153,7 @@ public class MetamodelBuilder { | |||
185 | return; | 153 | return; |
186 | } | 154 | } |
187 | directedCrossReferences.put(linkType, new DirectedCrossReferenceInfo(sourceType, info.multiplicity(), | 155 | directedCrossReferences.put(linkType, new DirectedCrossReferenceInfo(sourceType, info.multiplicity(), |
188 | targetType, targetMultiplicity)); | 156 | targetType, targetMultiplicity, defaultValue)); |
189 | } | 157 | } |
190 | 158 | ||
191 | private void processContainmentInfo(PartialRelation linkType, ReferenceInfo info, | 159 | private void processContainmentInfo(PartialRelation linkType, ReferenceInfo info, |
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/metamodel/ReferenceInfo.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/metamodel/ReferenceInfo.java index 9a6b4012..9d7fc9c3 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/metamodel/ReferenceInfo.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/metamodel/ReferenceInfo.java | |||
@@ -7,7 +7,11 @@ package tools.refinery.store.reasoning.translator.metamodel; | |||
7 | 7 | ||
8 | import tools.refinery.store.reasoning.representation.PartialRelation; | 8 | import tools.refinery.store.reasoning.representation.PartialRelation; |
9 | import tools.refinery.store.reasoning.translator.multiplicity.Multiplicity; | 9 | import tools.refinery.store.reasoning.translator.multiplicity.Multiplicity; |
10 | import tools.refinery.store.representation.TruthValue; | ||
10 | 11 | ||
11 | public record ReferenceInfo(boolean containment, PartialRelation sourceType, Multiplicity multiplicity, | 12 | public record ReferenceInfo(boolean containment, PartialRelation sourceType, Multiplicity multiplicity, |
12 | PartialRelation targetType, PartialRelation opposite) { | 13 | PartialRelation targetType, PartialRelation opposite, TruthValue defaultValue) { |
14 | public static ReferenceInfoBuilder builder() { | ||
15 | return new ReferenceInfoBuilder(); | ||
16 | } | ||
13 | } | 17 | } |
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/metamodel/ReferenceInfoBuilder.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/metamodel/ReferenceInfoBuilder.java new file mode 100644 index 00000000..43d01503 --- /dev/null +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/metamodel/ReferenceInfoBuilder.java | |||
@@ -0,0 +1,84 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.reasoning.translator.metamodel; | ||
7 | |||
8 | import org.jetbrains.annotations.NotNull; | ||
9 | import org.jetbrains.annotations.Nullable; | ||
10 | import tools.refinery.store.reasoning.representation.PartialRelation; | ||
11 | import tools.refinery.store.reasoning.translator.multiplicity.ConstrainedMultiplicity; | ||
12 | import tools.refinery.store.reasoning.translator.multiplicity.Multiplicity; | ||
13 | import tools.refinery.store.reasoning.translator.multiplicity.UnconstrainedMultiplicity; | ||
14 | import tools.refinery.store.representation.TruthValue; | ||
15 | import tools.refinery.store.representation.cardinality.CardinalityInterval; | ||
16 | |||
17 | public final class ReferenceInfoBuilder { | ||
18 | private boolean containment; | ||
19 | private PartialRelation sourceType; | ||
20 | private Multiplicity multiplicity = UnconstrainedMultiplicity.INSTANCE; | ||
21 | private PartialRelation targetType; | ||
22 | private PartialRelation opposite; | ||
23 | private TruthValue defaultValue = TruthValue.UNKNOWN; | ||
24 | |||
25 | ReferenceInfoBuilder() { | ||
26 | } | ||
27 | |||
28 | public ReferenceInfoBuilder source(@NotNull PartialRelation sourceType) { | ||
29 | if (sourceType.arity() != 1) { | ||
30 | throw new IllegalArgumentException("Source type %s must be of arity 1".formatted(sourceType)); | ||
31 | } | ||
32 | this.sourceType = sourceType; | ||
33 | return this; | ||
34 | } | ||
35 | |||
36 | public ReferenceInfoBuilder target(@NotNull PartialRelation targetType) { | ||
37 | if (targetType.arity() != 1) { | ||
38 | throw new IllegalArgumentException("Target type %s must be of arity 1".formatted(targetType)); | ||
39 | } | ||
40 | this.targetType = targetType; | ||
41 | return this; | ||
42 | } | ||
43 | |||
44 | public ReferenceInfoBuilder containment(boolean containment) { | ||
45 | this.containment = containment; | ||
46 | return this; | ||
47 | } | ||
48 | |||
49 | public ReferenceInfoBuilder multiplicity(@NotNull Multiplicity multiplicity) { | ||
50 | this.multiplicity = multiplicity; | ||
51 | return this; | ||
52 | } | ||
53 | |||
54 | public ReferenceInfoBuilder multiplicity(@NotNull CardinalityInterval multiplicityInterval, | ||
55 | @NotNull PartialRelation errorSymbol) { | ||
56 | return multiplicity(ConstrainedMultiplicity.of(multiplicityInterval, errorSymbol)); | ||
57 | } | ||
58 | |||
59 | public ReferenceInfoBuilder opposite(@Nullable PartialRelation opposite) { | ||
60 | if (opposite != null && opposite.arity() != 2) { | ||
61 | throw new IllegalArgumentException("Opposite %s must be of arity 2".formatted(targetType)); | ||
62 | } | ||
63 | this.opposite = opposite; | ||
64 | return this; | ||
65 | } | ||
66 | |||
67 | public ReferenceInfoBuilder defaultValue(@NotNull TruthValue defaultValue) { | ||
68 | if (defaultValue.must()) { | ||
69 | throw new IllegalArgumentException("Unsupported default value"); | ||
70 | } | ||
71 | this.defaultValue = defaultValue; | ||
72 | return this; | ||
73 | } | ||
74 | |||
75 | public ReferenceInfo build() { | ||
76 | if (sourceType == null) { | ||
77 | throw new IllegalStateException("Source type is required"); | ||
78 | } | ||
79 | if (targetType == null) { | ||
80 | throw new IllegalStateException("Target type is required"); | ||
81 | } | ||
82 | return new ReferenceInfo(containment, sourceType, multiplicity, targetType, opposite, defaultValue); | ||
83 | } | ||
84 | } | ||
diff --git a/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/metamodel/MetamodelBuilderTest.java b/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/metamodel/MetamodelBuilderTest.java index 0f1a1006..ba6ba6da 100644 --- a/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/metamodel/MetamodelBuilderTest.java +++ b/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/metamodel/MetamodelBuilderTest.java | |||
@@ -8,7 +8,6 @@ package tools.refinery.store.reasoning.translator.metamodel; | |||
8 | import org.junit.jupiter.api.Test; | 8 | import org.junit.jupiter.api.Test; |
9 | import tools.refinery.store.reasoning.representation.PartialRelation; | 9 | import tools.refinery.store.reasoning.representation.PartialRelation; |
10 | import tools.refinery.store.reasoning.translator.TranslationException; | 10 | import tools.refinery.store.reasoning.translator.TranslationException; |
11 | import tools.refinery.store.reasoning.translator.multiplicity.ConstrainedMultiplicity; | ||
12 | import tools.refinery.store.representation.cardinality.CardinalityIntervals; | 11 | import tools.refinery.store.representation.cardinality.CardinalityIntervals; |
13 | 12 | ||
14 | import static org.junit.jupiter.api.Assertions.assertThrows; | 13 | import static org.junit.jupiter.api.Assertions.assertThrows; |
@@ -24,8 +23,13 @@ class MetamodelBuilderTest { | |||
24 | var builder = Metamodel.builder() | 23 | var builder = Metamodel.builder() |
25 | .type(university) | 24 | .type(university) |
26 | .type(course) | 25 | .type(course) |
27 | .reference(courses, university, course, location) | 26 | .reference(courses, referenceBuilder -> referenceBuilder |
28 | .reference(location, course, university); | 27 | .source(university) |
28 | .target(course) | ||
29 | .opposite(location)) | ||
30 | .reference(location, referenceBuilder -> referenceBuilder | ||
31 | .source(course) | ||
32 | .target(university)); | ||
29 | 33 | ||
30 | assertThrows(TranslationException.class, builder::build); | 34 | assertThrows(TranslationException.class, builder::build); |
31 | } | 35 | } |
@@ -35,8 +39,14 @@ class MetamodelBuilderTest { | |||
35 | var builder = Metamodel.builder() | 39 | var builder = Metamodel.builder() |
36 | .type(university) | 40 | .type(university) |
37 | .type(course) | 41 | .type(course) |
38 | .reference(courses, university, course, location) | 42 | .reference(courses, referenceBuilder -> referenceBuilder |
39 | .reference(location, course, course, courses); | 43 | .source(university) |
44 | .target(course) | ||
45 | .opposite(location)) | ||
46 | .reference(location, referenceBuilder -> referenceBuilder | ||
47 | .source(course) | ||
48 | .target(course) | ||
49 | .opposite(courses)); | ||
40 | 50 | ||
41 | assertThrows(TranslationException.class, builder::build); | 51 | assertThrows(TranslationException.class, builder::build); |
42 | } | 52 | } |
@@ -48,10 +58,16 @@ class MetamodelBuilderTest { | |||
48 | var builder = Metamodel.builder() | 58 | var builder = Metamodel.builder() |
49 | .type(university) | 59 | .type(university) |
50 | .type(course) | 60 | .type(course) |
51 | .reference(courses, university, true, course, location) | 61 | .reference(courses, referenceBuilder -> referenceBuilder |
52 | .reference(location, course, | 62 | .containment(true) |
53 | ConstrainedMultiplicity.of(CardinalityIntervals.atLeast(2), invalidMultiplicity), | 63 | .source(university) |
54 | university, courses); | 64 | .target(course) |
65 | .opposite(location)) | ||
66 | .reference(location, referenceBuilder -> referenceBuilder | ||
67 | .source(course) | ||
68 | .multiplicity(CardinalityIntervals.atLeast(2), invalidMultiplicity) | ||
69 | .target(university) | ||
70 | .opposite(courses)); | ||
55 | 71 | ||
56 | assertThrows(TranslationException.class, builder::build); | 72 | assertThrows(TranslationException.class, builder::build); |
57 | } | 73 | } |
diff --git a/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/metamodel/MetamodelTest.java b/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/metamodel/MetamodelTest.java index 6c2f55af..88e6a4d7 100644 --- a/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/metamodel/MetamodelTest.java +++ b/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/metamodel/MetamodelTest.java | |||
@@ -16,7 +16,6 @@ import tools.refinery.store.reasoning.representation.PartialRelation; | |||
16 | import tools.refinery.store.reasoning.seed.ModelSeed; | 16 | import tools.refinery.store.reasoning.seed.ModelSeed; |
17 | import tools.refinery.store.reasoning.translator.containment.ContainmentHierarchyTranslator; | 17 | import tools.refinery.store.reasoning.translator.containment.ContainmentHierarchyTranslator; |
18 | import tools.refinery.store.reasoning.translator.multiobject.MultiObjectTranslator; | 18 | import tools.refinery.store.reasoning.translator.multiobject.MultiObjectTranslator; |
19 | import tools.refinery.store.reasoning.translator.multiplicity.ConstrainedMultiplicity; | ||
20 | import tools.refinery.store.representation.TruthValue; | 19 | import tools.refinery.store.representation.TruthValue; |
21 | import tools.refinery.store.representation.cardinality.CardinalityIntervals; | 20 | import tools.refinery.store.representation.cardinality.CardinalityIntervals; |
22 | import tools.refinery.store.tuple.Tuple; | 21 | import tools.refinery.store.tuple.Tuple; |
@@ -45,12 +44,23 @@ class MetamodelTest { | |||
45 | .type(teacher, person) | 44 | .type(teacher, person) |
46 | .type(university) | 45 | .type(university) |
47 | .type(course) | 46 | .type(course) |
48 | .reference(courses, university, true, course, location) | 47 | .reference(courses, builder -> builder |
49 | .reference(location, course, university, courses) | 48 | .containment(true) |
50 | .reference(lecturer, course, | 49 | .source(university) |
51 | ConstrainedMultiplicity.of(CardinalityIntervals.ONE, invalidLecturerCount), teacher) | 50 | .target(course) |
52 | .reference(enrolledStudents, course, | 51 | .opposite(location)) |
53 | ConstrainedMultiplicity.of(CardinalityIntervals.SOME, invalidStudentCount), student) | 52 | .reference(location, builder -> builder |
53 | .source(course) | ||
54 | .target(university) | ||
55 | .opposite(courses)) | ||
56 | .reference(lecturer, builder -> builder | ||
57 | .source(course) | ||
58 | .multiplicity(CardinalityIntervals.ONE, invalidLecturerCount) | ||
59 | .target(teacher)) | ||
60 | .reference(enrolledStudents, builder -> builder | ||
61 | .source(course) | ||
62 | .multiplicity(CardinalityIntervals.SOME, invalidStudentCount) | ||
63 | .target(student)) | ||
54 | .build(); | 64 | .build(); |
55 | 65 | ||
56 | var seed = ModelSeed.builder(5) | 66 | var seed = ModelSeed.builder(5) |
@@ -105,10 +115,12 @@ class MetamodelTest { | |||
105 | var metamodel = Metamodel.builder() | 115 | var metamodel = Metamodel.builder() |
106 | .type(university) | 116 | .type(university) |
107 | .type(course) | 117 | .type(course) |
108 | .reference(courses, university, true, course) | 118 | .reference(courses, builder -> builder |
119 | .containment(true) | ||
120 | .source(university) | ||
121 | .target(course)) | ||
109 | .build(); | 122 | .build(); |
110 | 123 | ||
111 | |||
112 | var seed = ModelSeed.builder(4) | 124 | var seed = ModelSeed.builder(4) |
113 | .seed(MultiObjectTranslator.COUNT_SYMBOL, builder -> builder | 125 | .seed(MultiObjectTranslator.COUNT_SYMBOL, builder -> builder |
114 | .reducedValue(CardinalityIntervals.ONE) | 126 | .reducedValue(CardinalityIntervals.ONE) |
@@ -1234,12 +1234,12 @@ __metadata: | |||
1234 | languageName: node | 1234 | languageName: node |
1235 | linkType: hard | 1235 | linkType: hard |
1236 | 1236 | ||
1237 | "@babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.23.4, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7": | 1237 | "@babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.23.5, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7": |
1238 | version: 7.23.5 | 1238 | version: 7.23.6 |
1239 | resolution: "@babel/runtime@npm:7.23.5" | 1239 | resolution: "@babel/runtime@npm:7.23.6" |
1240 | dependencies: | 1240 | dependencies: |
1241 | regenerator-runtime: "npm:^0.14.0" | 1241 | regenerator-runtime: "npm:^0.14.0" |
1242 | checksum: ca679cc91bb7e424bc2db87bb58cc3b06ade916b9adb21fbbdc43e54cdaacb3eea201ceba2a0464b11d2eb65b9fe6a6ffcf4d7521fa52994f19be96f1af14788 | 1242 | checksum: d886954e985ef8e421222f7a2848884d96a752e0020d3078b920dd104e672fdf23bcc6f51a44313a048796319f1ac9d09c2c88ec8cbb4e1f09174bcd3335b9ff |
1243 | languageName: node | 1243 | languageName: node |
1244 | linkType: hard | 1244 | linkType: hard |
1245 | 1245 | ||
@@ -1348,21 +1348,21 @@ __metadata: | |||
1348 | languageName: node | 1348 | languageName: node |
1349 | linkType: hard | 1349 | linkType: hard |
1350 | 1350 | ||
1351 | "@codemirror/state@npm:^6.0.0, @codemirror/state@npm:^6.1.4, @codemirror/state@npm:^6.2.0, @codemirror/state@npm:^6.3.2": | 1351 | "@codemirror/state@npm:^6.0.0, @codemirror/state@npm:^6.1.4, @codemirror/state@npm:^6.2.0, @codemirror/state@npm:^6.3.3": |
1352 | version: 6.3.2 | 1352 | version: 6.3.3 |
1353 | resolution: "@codemirror/state@npm:6.3.2" | 1353 | resolution: "@codemirror/state@npm:6.3.3" |
1354 | checksum: d0fa8c78bbccacc6bff5ac661a8e825c21c12fd45294d9a2e181d50af8294165b749094a3fbfc173a0aac72eabc3bf28aa48dfebc330239663680b2ded701ff5 | 1354 | checksum: 97f0174dd6aa43d6293630b0024918ce1bb1f7833de8fa75006de8b7dbd963e2bb8b5e7a805f5a98492a0379d8b60faaee319d42583562b8ea6347ab8b63bf5f |
1355 | languageName: node | 1355 | languageName: node |
1356 | linkType: hard | 1356 | linkType: hard |
1357 | 1357 | ||
1358 | "@codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.17.0, @codemirror/view@npm:^6.22.1": | 1358 | "@codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.17.0, @codemirror/view@npm:^6.22.3": |
1359 | version: 6.22.1 | 1359 | version: 6.22.3 |
1360 | resolution: "@codemirror/view@npm:6.22.1" | 1360 | resolution: "@codemirror/view@npm:6.22.3" |
1361 | dependencies: | 1361 | dependencies: |
1362 | "@codemirror/state": "npm:^6.1.4" | 1362 | "@codemirror/state": "npm:^6.1.4" |
1363 | style-mod: "npm:^4.1.0" | 1363 | style-mod: "npm:^4.1.0" |
1364 | w3c-keyname: "npm:^2.2.4" | 1364 | w3c-keyname: "npm:^2.2.4" |
1365 | checksum: 142a861c2bf6d0ba2817eaffdf985c19b556cc98af1bd565b1e9286bfcaf17eb12837ce41633a2462fca1731d043781c21c778fb0d5ae928c03c6a6f42485c78 | 1365 | checksum: ed5e48923f0522d2c55c0bb48eadb06823afaa5fb037b09b53b8eb00acdd4c7cb90816ee023ba90d7c70f7612bb8ab749d232398a6ae8bc2dc4df8d653ba7386 |
1366 | languageName: node | 1366 | languageName: node |
1367 | linkType: hard | 1367 | linkType: hard |
1368 | 1368 | ||
@@ -1421,14 +1421,14 @@ __metadata: | |||
1421 | languageName: node | 1421 | languageName: node |
1422 | linkType: hard | 1422 | linkType: hard |
1423 | 1423 | ||
1424 | "@emotion/react@npm:^11.11.1": | 1424 | "@emotion/react@npm:^11.11.3": |
1425 | version: 11.11.1 | 1425 | version: 11.11.3 |
1426 | resolution: "@emotion/react@npm:11.11.1" | 1426 | resolution: "@emotion/react@npm:11.11.3" |
1427 | dependencies: | 1427 | dependencies: |
1428 | "@babel/runtime": "npm:^7.18.3" | 1428 | "@babel/runtime": "npm:^7.18.3" |
1429 | "@emotion/babel-plugin": "npm:^11.11.0" | 1429 | "@emotion/babel-plugin": "npm:^11.11.0" |
1430 | "@emotion/cache": "npm:^11.11.0" | 1430 | "@emotion/cache": "npm:^11.11.0" |
1431 | "@emotion/serialize": "npm:^1.1.2" | 1431 | "@emotion/serialize": "npm:^1.1.3" |
1432 | "@emotion/use-insertion-effect-with-fallbacks": "npm:^1.0.1" | 1432 | "@emotion/use-insertion-effect-with-fallbacks": "npm:^1.0.1" |
1433 | "@emotion/utils": "npm:^1.2.1" | 1433 | "@emotion/utils": "npm:^1.2.1" |
1434 | "@emotion/weak-memoize": "npm:^0.3.1" | 1434 | "@emotion/weak-memoize": "npm:^0.3.1" |
@@ -1438,20 +1438,20 @@ __metadata: | |||
1438 | peerDependenciesMeta: | 1438 | peerDependenciesMeta: |
1439 | "@types/react": | 1439 | "@types/react": |
1440 | optional: true | 1440 | optional: true |
1441 | checksum: 1aea4d735b537fbfbeda828bbf929488a7e1b5b7d131f14aeede8737e92bb3b611e15fec353e97f85aed7a65a1c86a695a04ba6e9be905231beef6bd624cb705 | 1441 | checksum: ce995395b8714343715284beb8478afdfa72b89ed83981a15a170ca0f4a2f77d7a4a198fd50c1f9c6efcd0535768d168ff88c5921dc5f90bb33134c7a75f9455 |
1442 | languageName: node | 1442 | languageName: node |
1443 | linkType: hard | 1443 | linkType: hard |
1444 | 1444 | ||
1445 | "@emotion/serialize@npm:^1.1.2": | 1445 | "@emotion/serialize@npm:^1.1.2, @emotion/serialize@npm:^1.1.3": |
1446 | version: 1.1.2 | 1446 | version: 1.1.3 |
1447 | resolution: "@emotion/serialize@npm:1.1.2" | 1447 | resolution: "@emotion/serialize@npm:1.1.3" |
1448 | dependencies: | 1448 | dependencies: |
1449 | "@emotion/hash": "npm:^0.9.1" | 1449 | "@emotion/hash": "npm:^0.9.1" |
1450 | "@emotion/memoize": "npm:^0.8.1" | 1450 | "@emotion/memoize": "npm:^0.8.1" |
1451 | "@emotion/unitless": "npm:^0.8.1" | 1451 | "@emotion/unitless": "npm:^0.8.1" |
1452 | "@emotion/utils": "npm:^1.2.1" | 1452 | "@emotion/utils": "npm:^1.2.1" |
1453 | csstype: "npm:^3.0.2" | 1453 | csstype: "npm:^3.0.2" |
1454 | checksum: d243e0e5abce8d2183d25a32ec89bf650ee741ebadb29e6405abde05d4e2ed446ba5b3f725a29833ad709d0d08f0a5c8d0532fdcd43f4b23d931d8b6d4f218c1 | 1454 | checksum: 875241eafaa30e7d3b7cf9b585d8c1f224cbf627a674e87eb1d7662dafa76a8c8d67f14a79dbf7d1eaa017e9f68389962990fbcc699d5ad65035a1a047432a3f |
1455 | languageName: node | 1455 | languageName: node |
1456 | linkType: hard | 1456 | linkType: hard |
1457 | 1457 | ||
@@ -1701,10 +1701,10 @@ __metadata: | |||
1701 | languageName: node | 1701 | languageName: node |
1702 | linkType: hard | 1702 | linkType: hard |
1703 | 1703 | ||
1704 | "@eslint/js@npm:8.55.0": | 1704 | "@eslint/js@npm:8.56.0": |
1705 | version: 8.55.0 | 1705 | version: 8.56.0 |
1706 | resolution: "@eslint/js@npm:8.55.0" | 1706 | resolution: "@eslint/js@npm:8.56.0" |
1707 | checksum: 88ab9fc57a651becd2b32ec40a3958db27fae133b1ae77bebd733aa5bbd00a92f325bb02f20ad680d31c731fa49b22f060a4777dd52eb3e27da013d940bd978d | 1707 | checksum: 60b3a1cf240e2479cec9742424224465dc50e46d781da1b7f5ef240501b2d1202c225bd456207faac4b34a64f4765833345bc4ddffd00395e1db40fa8c426f5a |
1708 | languageName: node | 1708 | languageName: node |
1709 | linkType: hard | 1709 | linkType: hard |
1710 | 1710 | ||
@@ -1746,28 +1746,28 @@ __metadata: | |||
1746 | languageName: node | 1746 | languageName: node |
1747 | linkType: hard | 1747 | linkType: hard |
1748 | 1748 | ||
1749 | "@fontsource-variable/jetbrains-mono@npm:^5.0.18": | 1749 | "@fontsource-variable/jetbrains-mono@npm:^5.0.19": |
1750 | version: 5.0.18 | 1750 | version: 5.0.19 |
1751 | resolution: "@fontsource-variable/jetbrains-mono@npm:5.0.18" | 1751 | resolution: "@fontsource-variable/jetbrains-mono@npm:5.0.19" |
1752 | checksum: c11926a1c55c1f9983a4d94cedad0b5d9b718cd58050c95e2cd14dab165bfba939e3cbecda8dd4652198e7f681e720490914f42b3dfabd1e11796002ba5a2e01 | 1752 | checksum: 93622a6af324be162f028b974bd61f10530df30a1332dded4915509c0a21d80435ad623fb45325dd175afaa095ca6650f2de9da295b2bc9dea85474050d1a46b |
1753 | languageName: node | 1753 | languageName: node |
1754 | linkType: hard | 1754 | linkType: hard |
1755 | 1755 | ||
1756 | "@fontsource-variable/open-sans@npm:^5.0.18": | 1756 | "@fontsource-variable/open-sans@npm:^5.0.21": |
1757 | version: 5.0.18 | 1757 | version: 5.0.21 |
1758 | resolution: "@fontsource-variable/open-sans@npm:5.0.18" | 1758 | resolution: "@fontsource-variable/open-sans@npm:5.0.21" |
1759 | checksum: ec5e33654d5abfed6d7788bd404f91bab749f69ede1730ab0b958265e1dcc82b77972d0f8e98d477e2f41d3334c73c86a8e7bd90107295b4c44bb17607977b78 | 1759 | checksum: d7a5832751f24ca080355ac51259195dea1910cb4a7f74b5531e993e9892fadfb7784949d5d065d067403db1741bbedcbc96bb5cf1d988449ff647eeba0d4481 |
1760 | languageName: node | 1760 | languageName: node |
1761 | linkType: hard | 1761 | linkType: hard |
1762 | 1762 | ||
1763 | "@hpcc-js/wasm@npm:^2.14.1, @hpcc-js/wasm@npm:^2.15.0": | 1763 | "@hpcc-js/wasm@npm:^2.14.1, @hpcc-js/wasm@npm:^2.15.3": |
1764 | version: 2.15.0 | 1764 | version: 2.15.3 |
1765 | resolution: "@hpcc-js/wasm@npm:2.15.0" | 1765 | resolution: "@hpcc-js/wasm@npm:2.15.3" |
1766 | dependencies: | 1766 | dependencies: |
1767 | yargs: "npm:17.7.2" | 1767 | yargs: "npm:17.7.2" |
1768 | bin: | 1768 | bin: |
1769 | dot-wasm: bin/dot-wasm.js | 1769 | dot-wasm: bin/dot-wasm.js |
1770 | checksum: aa3daac878a1c6135fd1eeafa0952e75d37c2664e5ccfb98075a5a901fc898852440a476ab54528cce8a6ae9abea44c810e39695c80149fc60c51f0389288c80 | 1770 | checksum: 9e4474329f191d93cd4029afe4a5e83732bec732a7c83a913fefe64e08a82deb59dbdc33d42c92e4c8eb4df5853c8cbe10d8d53d7db5204d8c9919af082f64b1 |
1771 | languageName: node | 1771 | languageName: node |
1772 | linkType: hard | 1772 | linkType: hard |
1773 | 1773 | ||
@@ -1862,10 +1862,10 @@ __metadata: | |||
1862 | languageName: node | 1862 | languageName: node |
1863 | linkType: hard | 1863 | linkType: hard |
1864 | 1864 | ||
1865 | "@lezer/common@npm:^1.0.0, @lezer/common@npm:^1.0.2, @lezer/common@npm:^1.1.0, @lezer/common@npm:^1.1.1": | 1865 | "@lezer/common@npm:^1.0.0, @lezer/common@npm:^1.0.2, @lezer/common@npm:^1.1.0, @lezer/common@npm:^1.1.2": |
1866 | version: 1.1.1 | 1866 | version: 1.1.2 |
1867 | resolution: "@lezer/common@npm:1.1.1" | 1867 | resolution: "@lezer/common@npm:1.1.2" |
1868 | checksum: 495b76f33164c732461097ee6f8d6f1250a63d21f5c01e58a24f1da49b8d4b392188bbbe972c0c2d7ec48db8e3fd550563bcdefba3b81b4d895e821c1f91fc8e | 1868 | checksum: ed25e0b05ff073247266f2824d38159b93ab359be23c479ae0cf37131ec0d463a58dc2b78fb989ff9e29f87e0ef16291b2bd6243b082bb4116aed3e386cc069c |
1869 | languageName: node | 1869 | languageName: node |
1870 | linkType: hard | 1870 | linkType: hard |
1871 | 1871 | ||
@@ -1906,14 +1906,14 @@ __metadata: | |||
1906 | languageName: node | 1906 | languageName: node |
1907 | linkType: hard | 1907 | linkType: hard |
1908 | 1908 | ||
1909 | "@mui/base@npm:5.0.0-beta.25": | 1909 | "@mui/base@npm:5.0.0-beta.28": |
1910 | version: 5.0.0-beta.25 | 1910 | version: 5.0.0-beta.28 |
1911 | resolution: "@mui/base@npm:5.0.0-beta.25" | 1911 | resolution: "@mui/base@npm:5.0.0-beta.28" |
1912 | dependencies: | 1912 | dependencies: |
1913 | "@babel/runtime": "npm:^7.23.4" | 1913 | "@babel/runtime": "npm:^7.23.5" |
1914 | "@floating-ui/react-dom": "npm:^2.0.4" | 1914 | "@floating-ui/react-dom": "npm:^2.0.4" |
1915 | "@mui/types": "npm:^7.2.10" | 1915 | "@mui/types": "npm:^7.2.11" |
1916 | "@mui/utils": "npm:^5.14.19" | 1916 | "@mui/utils": "npm:^5.15.1" |
1917 | "@popperjs/core": "npm:^2.11.8" | 1917 | "@popperjs/core": "npm:^2.11.8" |
1918 | clsx: "npm:^2.0.0" | 1918 | clsx: "npm:^2.0.0" |
1919 | prop-types: "npm:^15.8.1" | 1919 | prop-types: "npm:^15.8.1" |
@@ -1924,22 +1924,22 @@ __metadata: | |||
1924 | peerDependenciesMeta: | 1924 | peerDependenciesMeta: |
1925 | "@types/react": | 1925 | "@types/react": |
1926 | optional: true | 1926 | optional: true |
1927 | checksum: 9b1865655cb94b7a40ea31c698f1163d5521a7bb110ddcc1131f83a76428628d11d1582d2e96968734eed17d26e69c6c2b10eb5b9757639e7ddd48be0bd22dc6 | 1927 | checksum: 31479d9548e1b29150e3b94bcb88edce409339ac047e78a8a70173a0fa2c7730b38f28c6b366e2b3dda3964f28e883153cae0dc2957218b1711bb58004ddc2d1 |
1928 | languageName: node | 1928 | languageName: node |
1929 | linkType: hard | 1929 | linkType: hard |
1930 | 1930 | ||
1931 | "@mui/core-downloads-tracker@npm:^5.14.19": | 1931 | "@mui/core-downloads-tracker@npm:^5.15.1": |
1932 | version: 5.14.19 | 1932 | version: 5.15.1 |
1933 | resolution: "@mui/core-downloads-tracker@npm:5.14.19" | 1933 | resolution: "@mui/core-downloads-tracker@npm:5.15.1" |
1934 | checksum: a0851424a067e0e0c266752e34000bcc63121191b93077d6dc01834a71c5defe95e54495f98347e2f8c247cebfe38d142600c71b9a698cf30f114e90598ebb91 | 1934 | checksum: 81e3afca19135336c1122aaa8bd69e411df95389c2654c03ce8a8787f4ee4b14403f58acfbf4eef1b9267685569ee9a0bee4b08cf15782d866e9277792d84657 |
1935 | languageName: node | 1935 | languageName: node |
1936 | linkType: hard | 1936 | linkType: hard |
1937 | 1937 | ||
1938 | "@mui/icons-material@npm:5.14.19": | 1938 | "@mui/icons-material@npm:^5.15.1": |
1939 | version: 5.14.19 | 1939 | version: 5.15.1 |
1940 | resolution: "@mui/icons-material@npm:5.14.19" | 1940 | resolution: "@mui/icons-material@npm:5.15.1" |
1941 | dependencies: | 1941 | dependencies: |
1942 | "@babel/runtime": "npm:^7.23.4" | 1942 | "@babel/runtime": "npm:^7.23.5" |
1943 | peerDependencies: | 1943 | peerDependencies: |
1944 | "@mui/material": ^5.0.0 | 1944 | "@mui/material": ^5.0.0 |
1945 | "@types/react": ^17.0.0 || ^18.0.0 | 1945 | "@types/react": ^17.0.0 || ^18.0.0 |
@@ -1947,21 +1947,21 @@ __metadata: | |||
1947 | peerDependenciesMeta: | 1947 | peerDependenciesMeta: |
1948 | "@types/react": | 1948 | "@types/react": |
1949 | optional: true | 1949 | optional: true |
1950 | checksum: 1af1a14622795dae1b999b49dc27d8d9f32344ccd3bc73a3b9dbce3d8d7ad43e6aa93e100a58ae423c9404fcb91dbdeb7758bd94f5f4614a4843f649645a42a1 | 1950 | checksum: 9ae975f7534094f6e80ffeb3946338a22b9656bb02544fa76e427daeff050c7db0ce83b261bca73a1aab17789d87cc19cc92749d0dc40501f889a9dbfb35709d |
1951 | languageName: node | 1951 | languageName: node |
1952 | linkType: hard | 1952 | linkType: hard |
1953 | 1953 | ||
1954 | "@mui/material@npm:5.14.19": | 1954 | "@mui/material@npm:^5.15.1": |
1955 | version: 5.14.19 | 1955 | version: 5.15.1 |
1956 | resolution: "@mui/material@npm:5.14.19" | 1956 | resolution: "@mui/material@npm:5.15.1" |
1957 | dependencies: | 1957 | dependencies: |
1958 | "@babel/runtime": "npm:^7.23.4" | 1958 | "@babel/runtime": "npm:^7.23.5" |
1959 | "@mui/base": "npm:5.0.0-beta.25" | 1959 | "@mui/base": "npm:5.0.0-beta.28" |
1960 | "@mui/core-downloads-tracker": "npm:^5.14.19" | 1960 | "@mui/core-downloads-tracker": "npm:^5.15.1" |
1961 | "@mui/system": "npm:^5.14.19" | 1961 | "@mui/system": "npm:^5.15.1" |
1962 | "@mui/types": "npm:^7.2.10" | 1962 | "@mui/types": "npm:^7.2.11" |
1963 | "@mui/utils": "npm:^5.14.19" | 1963 | "@mui/utils": "npm:^5.15.1" |
1964 | "@types/react-transition-group": "npm:^4.4.9" | 1964 | "@types/react-transition-group": "npm:^4.4.10" |
1965 | clsx: "npm:^2.0.0" | 1965 | clsx: "npm:^2.0.0" |
1966 | csstype: "npm:^3.1.2" | 1966 | csstype: "npm:^3.1.2" |
1967 | prop-types: "npm:^15.8.1" | 1967 | prop-types: "npm:^15.8.1" |
@@ -1980,16 +1980,16 @@ __metadata: | |||
1980 | optional: true | 1980 | optional: true |
1981 | "@types/react": | 1981 | "@types/react": |
1982 | optional: true | 1982 | optional: true |
1983 | checksum: 5ffce28bc26fa5c7ea4409f816698c9f9cb27ae70bcf06bd21aab40ea5b979f17568032a9ec74a9209d11272ee1efc9f4dcbb19f8574e3eec63a622220f58a3f | 1983 | checksum: d5fc5cba599a691d84424bfa8d8a3dc18ecbf85ea1bd4fc92292b716a4df9facf391d3c164743f83ae8c69905f92c0061cd311d2c6c3a051a277614940b87b1b |
1984 | languageName: node | 1984 | languageName: node |
1985 | linkType: hard | 1985 | linkType: hard |
1986 | 1986 | ||
1987 | "@mui/private-theming@npm:^5.14.19": | 1987 | "@mui/private-theming@npm:^5.15.1": |
1988 | version: 5.14.19 | 1988 | version: 5.15.1 |
1989 | resolution: "@mui/private-theming@npm:5.14.19" | 1989 | resolution: "@mui/private-theming@npm:5.15.1" |
1990 | dependencies: | 1990 | dependencies: |
1991 | "@babel/runtime": "npm:^7.23.4" | 1991 | "@babel/runtime": "npm:^7.23.5" |
1992 | "@mui/utils": "npm:^5.14.19" | 1992 | "@mui/utils": "npm:^5.15.1" |
1993 | prop-types: "npm:^15.8.1" | 1993 | prop-types: "npm:^15.8.1" |
1994 | peerDependencies: | 1994 | peerDependencies: |
1995 | "@types/react": ^17.0.0 || ^18.0.0 | 1995 | "@types/react": ^17.0.0 || ^18.0.0 |
@@ -1997,15 +1997,15 @@ __metadata: | |||
1997 | peerDependenciesMeta: | 1997 | peerDependenciesMeta: |
1998 | "@types/react": | 1998 | "@types/react": |
1999 | optional: true | 1999 | optional: true |
2000 | checksum: 06bb5c40f680c037c80fef67404d1181b5775ef38157e12d03c58d1b070e6bb89d82b028d0a544e5d78cbd7822f50d5596e1320cd822c9cfbf185cb3ab2f935c | 2000 | checksum: 1d5e334601eac1e1f153c91094cd513e98ccb8fef2fcbcf8c048723d171ceda59b8231dcc3daa665e5e5ee7e39aae1b653040efb64320ef89d4ec1ad88eea4de |
2001 | languageName: node | 2001 | languageName: node |
2002 | linkType: hard | 2002 | linkType: hard |
2003 | 2003 | ||
2004 | "@mui/styled-engine@npm:^5.14.19": | 2004 | "@mui/styled-engine@npm:^5.15.1": |
2005 | version: 5.14.19 | 2005 | version: 5.15.1 |
2006 | resolution: "@mui/styled-engine@npm:5.14.19" | 2006 | resolution: "@mui/styled-engine@npm:5.15.1" |
2007 | dependencies: | 2007 | dependencies: |
2008 | "@babel/runtime": "npm:^7.23.4" | 2008 | "@babel/runtime": "npm:^7.23.5" |
2009 | "@emotion/cache": "npm:^11.11.0" | 2009 | "@emotion/cache": "npm:^11.11.0" |
2010 | csstype: "npm:^3.1.2" | 2010 | csstype: "npm:^3.1.2" |
2011 | prop-types: "npm:^15.8.1" | 2011 | prop-types: "npm:^15.8.1" |
@@ -2018,19 +2018,19 @@ __metadata: | |||
2018 | optional: true | 2018 | optional: true |
2019 | "@emotion/styled": | 2019 | "@emotion/styled": |
2020 | optional: true | 2020 | optional: true |
2021 | checksum: eaa539b76008d0dbc22cf6b479885f223ca2d71e7338d73f583529ad9b57fe80656cfb5f3779d1c84b7fa7f779b15f3a5df28eb1e1bf797609f78f295b6219f0 | 2021 | checksum: fcfa7cd3ba9ab24ad557ac9e980b46ff4d4dfddab41b1cdd57257a5ad57bf13e3891d771218dca1b1f405609c6e1e9895b80fcd90211a8877279f7774bb70e70 |
2022 | languageName: node | 2022 | languageName: node |
2023 | linkType: hard | 2023 | linkType: hard |
2024 | 2024 | ||
2025 | "@mui/system@npm:^5.14.19": | 2025 | "@mui/system@npm:^5.15.1": |
2026 | version: 5.14.19 | 2026 | version: 5.15.1 |
2027 | resolution: "@mui/system@npm:5.14.19" | 2027 | resolution: "@mui/system@npm:5.15.1" |
2028 | dependencies: | 2028 | dependencies: |
2029 | "@babel/runtime": "npm:^7.23.4" | 2029 | "@babel/runtime": "npm:^7.23.5" |
2030 | "@mui/private-theming": "npm:^5.14.19" | 2030 | "@mui/private-theming": "npm:^5.15.1" |
2031 | "@mui/styled-engine": "npm:^5.14.19" | 2031 | "@mui/styled-engine": "npm:^5.15.1" |
2032 | "@mui/types": "npm:^7.2.10" | 2032 | "@mui/types": "npm:^7.2.11" |
2033 | "@mui/utils": "npm:^5.14.19" | 2033 | "@mui/utils": "npm:^5.15.1" |
2034 | clsx: "npm:^2.0.0" | 2034 | clsx: "npm:^2.0.0" |
2035 | csstype: "npm:^3.1.2" | 2035 | csstype: "npm:^3.1.2" |
2036 | prop-types: "npm:^15.8.1" | 2036 | prop-types: "npm:^15.8.1" |
@@ -2046,27 +2046,27 @@ __metadata: | |||
2046 | optional: true | 2046 | optional: true |
2047 | "@types/react": | 2047 | "@types/react": |
2048 | optional: true | 2048 | optional: true |
2049 | checksum: 8fb45a4bf6ca8736e029bcd42cd085eb3ade8d46c58f1ed2c1ab266cb89397855f1176a7d8dd4317d8ef08045d4e30a28c706b51415c37a8c8ae2589dc1a6d9a | 2049 | checksum: c8abf92fde14031b0e6af6ef2d947bde9e98ce08bb81550bb08fa56793adf1da086066299a7c09d7f26c6e3a6a780679064ed8e54914ae5d775bb87c44632dc5 |
2050 | languageName: node | 2050 | languageName: node |
2051 | linkType: hard | 2051 | linkType: hard |
2052 | 2052 | ||
2053 | "@mui/types@npm:^7.2.10": | 2053 | "@mui/types@npm:^7.2.11": |
2054 | version: 7.2.10 | 2054 | version: 7.2.11 |
2055 | resolution: "@mui/types@npm:7.2.10" | 2055 | resolution: "@mui/types@npm:7.2.11" |
2056 | peerDependencies: | 2056 | peerDependencies: |
2057 | "@types/react": ^17.0.0 || ^18.0.0 | 2057 | "@types/react": ^17.0.0 || ^18.0.0 |
2058 | peerDependenciesMeta: | 2058 | peerDependenciesMeta: |
2059 | "@types/react": | 2059 | "@types/react": |
2060 | optional: true | 2060 | optional: true |
2061 | checksum: 59c8162812581cd1021d319e8828f6220723ffceb13609a99b1ffee6943f81ab07291cc3837c28776ca919dbe74c6416b2014c10e16b19135ff94a80ad7d3270 | 2061 | checksum: 5aecdd9b02ca4537d05ec1809a31e64a3330dc104509bc470ec8e38a00259d36faf2dadee828987b385dff46fbec6fe112ef3a5c0c1b78e60c56755af04d38fa |
2062 | languageName: node | 2062 | languageName: node |
2063 | linkType: hard | 2063 | linkType: hard |
2064 | 2064 | ||
2065 | "@mui/utils@npm:^5.14.16, @mui/utils@npm:^5.14.19": | 2065 | "@mui/utils@npm:^5.14.16, @mui/utils@npm:^5.15.1": |
2066 | version: 5.14.19 | 2066 | version: 5.15.1 |
2067 | resolution: "@mui/utils@npm:5.14.19" | 2067 | resolution: "@mui/utils@npm:5.15.1" |
2068 | dependencies: | 2068 | dependencies: |
2069 | "@babel/runtime": "npm:^7.23.4" | 2069 | "@babel/runtime": "npm:^7.23.5" |
2070 | "@types/prop-types": "npm:^15.7.11" | 2070 | "@types/prop-types": "npm:^15.7.11" |
2071 | prop-types: "npm:^15.8.1" | 2071 | prop-types: "npm:^15.8.1" |
2072 | react-is: "npm:^18.2.0" | 2072 | react-is: "npm:^18.2.0" |
@@ -2076,13 +2076,13 @@ __metadata: | |||
2076 | peerDependenciesMeta: | 2076 | peerDependenciesMeta: |
2077 | "@types/react": | 2077 | "@types/react": |
2078 | optional: true | 2078 | optional: true |
2079 | checksum: fb049eed27249dabfba2b3bf3b6d6ebd0a31e837cde6651ab727482e24f3be700103ac04074c348cf8bdc5bed09d6e4c251e7ca46d7bbb66e2e5e9a062ea06cb | 2079 | checksum: 46a66c488ece0d5be5f179316495220ff95d5276f452ea1cf48836ed6aade63ceb5dd3cd0d3970eb958272eb4455deb657effcf52b7eb2355d9b99bef9d61909 |
2080 | languageName: node | 2080 | languageName: node |
2081 | linkType: hard | 2081 | linkType: hard |
2082 | 2082 | ||
2083 | "@mui/x-data-grid@npm:^6.18.2": | 2083 | "@mui/x-data-grid@npm:^6.18.6": |
2084 | version: 6.18.2 | 2084 | version: 6.18.6 |
2085 | resolution: "@mui/x-data-grid@npm:6.18.2" | 2085 | resolution: "@mui/x-data-grid@npm:6.18.6" |
2086 | dependencies: | 2086 | dependencies: |
2087 | "@babel/runtime": "npm:^7.23.2" | 2087 | "@babel/runtime": "npm:^7.23.2" |
2088 | "@mui/utils": "npm:^5.14.16" | 2088 | "@mui/utils": "npm:^5.14.16" |
@@ -2094,7 +2094,7 @@ __metadata: | |||
2094 | "@mui/system": ^5.4.1 | 2094 | "@mui/system": ^5.4.1 |
2095 | react: ^17.0.0 || ^18.0.0 | 2095 | react: ^17.0.0 || ^18.0.0 |
2096 | react-dom: ^17.0.0 || ^18.0.0 | 2096 | react-dom: ^17.0.0 || ^18.0.0 |
2097 | checksum: 441328df15f1d82651612229bee42c74eda893837bc08edc7c171a85bb755a612395f5abf8b4d09ddf4f70a74914faff221b6001ee8975c0ebe439ab7a1b4be1 | 2097 | checksum: a8931efe1cff8951331223defdf9b17cb501eef85d4b176f36f9b0fb8a9522d6c4d6f5b672ac4f9b710ab95faf98d7a405fb3a739cbe871123798ed82a71dee3 |
2098 | languageName: node | 2098 | languageName: node |
2099 | linkType: hard | 2099 | linkType: hard |
2100 | 2100 | ||
@@ -2171,56 +2171,56 @@ __metadata: | |||
2171 | "@codemirror/language": "npm:^6.9.3" | 2171 | "@codemirror/language": "npm:^6.9.3" |
2172 | "@codemirror/lint": "npm:^6.4.2" | 2172 | "@codemirror/lint": "npm:^6.4.2" |
2173 | "@codemirror/search": "npm:^6.5.5" | 2173 | "@codemirror/search": "npm:^6.5.5" |
2174 | "@codemirror/state": "npm:^6.3.2" | 2174 | "@codemirror/state": "npm:^6.3.3" |
2175 | "@codemirror/view": "npm:^6.22.1" | 2175 | "@codemirror/view": "npm:^6.22.3" |
2176 | "@emotion/react": "npm:^11.11.1" | 2176 | "@emotion/react": "npm:^11.11.3" |
2177 | "@emotion/styled": "npm:^11.11.0" | 2177 | "@emotion/styled": "npm:^11.11.0" |
2178 | "@fontsource-variable/jetbrains-mono": "npm:^5.0.18" | 2178 | "@fontsource-variable/jetbrains-mono": "npm:^5.0.19" |
2179 | "@fontsource-variable/open-sans": "npm:^5.0.18" | 2179 | "@fontsource-variable/open-sans": "npm:^5.0.21" |
2180 | "@hpcc-js/wasm": "npm:^2.15.0" | 2180 | "@hpcc-js/wasm": "npm:^2.15.3" |
2181 | "@lezer/common": "npm:^1.1.1" | 2181 | "@lezer/common": "npm:^1.1.2" |
2182 | "@lezer/generator": "npm:^1.5.1" | 2182 | "@lezer/generator": "npm:^1.5.1" |
2183 | "@lezer/highlight": "npm:^1.2.0" | 2183 | "@lezer/highlight": "npm:^1.2.0" |
2184 | "@lezer/lr": "npm:^1.3.14" | 2184 | "@lezer/lr": "npm:^1.3.14" |
2185 | "@material-icons/svg": "npm:^1.0.33" | 2185 | "@material-icons/svg": "npm:^1.0.33" |
2186 | "@mui/icons-material": "npm:5.14.19" | 2186 | "@mui/icons-material": "npm:^5.15.1" |
2187 | "@mui/material": "npm:5.14.19" | 2187 | "@mui/material": "npm:^5.15.1" |
2188 | "@mui/system": "npm:^5.14.19" | 2188 | "@mui/system": "npm:^5.15.1" |
2189 | "@mui/x-data-grid": "npm:^6.18.2" | 2189 | "@mui/x-data-grid": "npm:^6.18.6" |
2190 | "@types/d3": "npm:^7.4.3" | 2190 | "@types/d3": "npm:^7.4.3" |
2191 | "@types/d3-graphviz": "npm:^2.6.10" | 2191 | "@types/d3-graphviz": "npm:^2.6.10" |
2192 | "@types/d3-selection": "npm:^3.0.10" | 2192 | "@types/d3-selection": "npm:^3.0.10" |
2193 | "@types/d3-zoom": "npm:^3.0.8" | 2193 | "@types/d3-zoom": "npm:^3.0.8" |
2194 | "@types/eslint": "npm:^8.44.8" | 2194 | "@types/eslint": "npm:^8.56.0" |
2195 | "@types/html-minifier-terser": "npm:^7.0.2" | 2195 | "@types/html-minifier-terser": "npm:^7.0.2" |
2196 | "@types/lodash-es": "npm:^4.17.12" | 2196 | "@types/lodash-es": "npm:^4.17.12" |
2197 | "@types/micromatch": "npm:^4.0.6" | 2197 | "@types/micromatch": "npm:^4.0.6" |
2198 | "@types/ms": "npm:^0.7.34" | 2198 | "@types/ms": "npm:^0.7.34" |
2199 | "@types/node": "npm:^20.10.2" | 2199 | "@types/node": "npm:^20.10.5" |
2200 | "@types/pnpapi": "npm:^0.0.5" | 2200 | "@types/pnpapi": "npm:^0.0.5" |
2201 | "@types/react": "npm:^18.2.41" | 2201 | "@types/react": "npm:^18.2.45" |
2202 | "@types/react-dom": "npm:^18.2.17" | 2202 | "@types/react-dom": "npm:^18.2.18" |
2203 | "@typescript-eslint/eslint-plugin": "npm:^6.13.1" | 2203 | "@typescript-eslint/eslint-plugin": "npm:^6.15.0" |
2204 | "@typescript-eslint/parser": "npm:^6.13.1" | 2204 | "@typescript-eslint/parser": "npm:^6.15.0" |
2205 | "@vitejs/plugin-react-swc": "npm:^3.5.0" | 2205 | "@vitejs/plugin-react-swc": "npm:^3.5.0" |
2206 | "@xstate/cli": "npm:^0.5.11" | 2206 | "@xstate/cli": "npm:^0.5.15" |
2207 | ansi-styles: "npm:^6.2.1" | 2207 | ansi-styles: "npm:^6.2.1" |
2208 | cross-env: "npm:^7.0.3" | 2208 | cross-env: "npm:^7.0.3" |
2209 | csstype: "npm:^3.1.2" | 2209 | csstype: "npm:^3.1.3" |
2210 | d3: "npm:^7.8.5" | 2210 | d3: "npm:^7.8.5" |
2211 | d3-graphviz: "patch:d3-graphviz@npm%3A5.2.0#~/.yarn/patches/d3-graphviz-npm-5.2.0-161b1fbad4.patch" | 2211 | d3-graphviz: "patch:d3-graphviz@npm%3A5.2.0#~/.yarn/patches/d3-graphviz-npm-5.2.0-161b1fbad4.patch" |
2212 | d3-selection: "npm:^3.0.0" | 2212 | d3-selection: "npm:^3.0.0" |
2213 | d3-zoom: "patch:d3-zoom@npm%3A3.0.0#~/.yarn/patches/d3-zoom-npm-3.0.0-18f706a421.patch" | 2213 | d3-zoom: "patch:d3-zoom@npm%3A3.0.0#~/.yarn/patches/d3-zoom-npm-3.0.0-18f706a421.patch" |
2214 | escape-string-regexp: "npm:^5.0.0" | 2214 | escape-string-regexp: "npm:^5.0.0" |
2215 | eslint: "npm:^8.55.0" | 2215 | eslint: "npm:^8.56.0" |
2216 | eslint-config-airbnb: "npm:^19.0.4" | 2216 | eslint-config-airbnb: "npm:^19.0.4" |
2217 | eslint-config-airbnb-typescript: "npm:^17.1.0" | 2217 | eslint-config-airbnb-typescript: "npm:^17.1.0" |
2218 | eslint-config-prettier: "npm:^9.1.0" | 2218 | eslint-config-prettier: "npm:^9.1.0" |
2219 | eslint-import-resolver-typescript: "npm:^3.6.1" | 2219 | eslint-import-resolver-typescript: "npm:^3.6.1" |
2220 | eslint-plugin-import: "npm:^2.29.0" | 2220 | eslint-plugin-import: "npm:^2.29.1" |
2221 | eslint-plugin-jsx-a11y: "npm:^6.8.0" | 2221 | eslint-plugin-jsx-a11y: "npm:^6.8.0" |
2222 | eslint-plugin-mobx: "npm:^0.0.9" | 2222 | eslint-plugin-mobx: "npm:^0.0.9" |
2223 | eslint-plugin-prettier: "npm:^5.0.1" | 2223 | eslint-plugin-prettier: "npm:^5.1.1" |
2224 | eslint-plugin-react: "npm:^7.33.2" | 2224 | eslint-plugin-react: "npm:^7.33.2" |
2225 | eslint-plugin-react-hooks: "npm:^4.6.0" | 2225 | eslint-plugin-react-hooks: "npm:^4.6.0" |
2226 | html-minifier-terser: "npm:^7.2.0" | 2226 | html-minifier-terser: "npm:^7.2.0" |
@@ -2234,13 +2234,13 @@ __metadata: | |||
2234 | nanoid: "npm:^5.0.4" | 2234 | nanoid: "npm:^5.0.4" |
2235 | notistack: "npm:^3.0.1" | 2235 | notistack: "npm:^3.0.1" |
2236 | pnpapi: "npm:^0.0.0" | 2236 | pnpapi: "npm:^0.0.0" |
2237 | prettier: "npm:^3.1.0" | 2237 | prettier: "npm:^3.1.1" |
2238 | react: "npm:^18.2.0" | 2238 | react: "npm:^18.2.0" |
2239 | react-dom: "npm:^18.2.0" | 2239 | react-dom: "npm:^18.2.0" |
2240 | react-resize-detector: "npm:^9.1.0" | 2240 | react-resize-detector: "npm:^9.1.1" |
2241 | typescript: "npm:5.3.2" | 2241 | typescript: "npm:5.3.3" |
2242 | vite: "npm:^5.0.4" | 2242 | vite: "npm:^5.0.10" |
2243 | vite-plugin-pwa: "npm:^0.17.2" | 2243 | vite-plugin-pwa: "npm:^0.17.4" |
2244 | workbox-window: "npm:^7.0.0" | 2244 | workbox-window: "npm:^7.0.0" |
2245 | xstate: "npm:^4.38.3" | 2245 | xstate: "npm:^4.38.3" |
2246 | zod: "npm:^3.22.4" | 2246 | zod: "npm:^3.22.4" |
@@ -2251,8 +2251,8 @@ __metadata: | |||
2251 | version: 0.0.0-use.local | 2251 | version: 0.0.0-use.local |
2252 | resolution: "@refinery/root@workspace:." | 2252 | resolution: "@refinery/root@workspace:." |
2253 | dependencies: | 2253 | dependencies: |
2254 | eslint: "npm:^8.55.0" | 2254 | eslint: "npm:^8.56.0" |
2255 | typescript: "npm:5.3.2" | 2255 | typescript: "npm:5.3.3" |
2256 | languageName: unknown | 2256 | languageName: unknown |
2257 | linkType: soft | 2257 | linkType: soft |
2258 | 2258 | ||
@@ -2879,13 +2879,13 @@ __metadata: | |||
2879 | languageName: node | 2879 | languageName: node |
2880 | linkType: hard | 2880 | linkType: hard |
2881 | 2881 | ||
2882 | "@types/eslint@npm:^8.44.8": | 2882 | "@types/eslint@npm:^8.56.0": |
2883 | version: 8.44.8 | 2883 | version: 8.56.0 |
2884 | resolution: "@types/eslint@npm:8.44.8" | 2884 | resolution: "@types/eslint@npm:8.56.0" |
2885 | dependencies: | 2885 | dependencies: |
2886 | "@types/estree": "npm:*" | 2886 | "@types/estree": "npm:*" |
2887 | "@types/json-schema": "npm:*" | 2887 | "@types/json-schema": "npm:*" |
2888 | checksum: 610966753add984f6ac9f00eeb766691e141e66a7e20b724a45ad077f60e8cd8fd7874b7e655e93537e54873cc5711cd6f57728474e08b478407cd942f098263 | 2888 | checksum: afba97b10d02cb7c7e7658de38f626c65b81be0fe45bc479e058ab14bc089911193811dce681edd656fc6b59c91fd8d0c976972476fc98b5e782b2c3b08aaa6c |
2889 | languageName: node | 2889 | languageName: node |
2890 | linkType: hard | 2890 | linkType: hard |
2891 | 2891 | ||
@@ -2963,12 +2963,12 @@ __metadata: | |||
2963 | languageName: node | 2963 | languageName: node |
2964 | linkType: hard | 2964 | linkType: hard |
2965 | 2965 | ||
2966 | "@types/node@npm:*, @types/node@npm:^20.10.2": | 2966 | "@types/node@npm:*, @types/node@npm:^20.10.5": |
2967 | version: 20.10.2 | 2967 | version: 20.10.5 |
2968 | resolution: "@types/node@npm:20.10.2" | 2968 | resolution: "@types/node@npm:20.10.5" |
2969 | dependencies: | 2969 | dependencies: |
2970 | undici-types: "npm:~5.26.4" | 2970 | undici-types: "npm:~5.26.4" |
2971 | checksum: c24630d6bdd237f538d69886868fc29abba8c59f58996b6a6267c42e2253a84a18834c09408b3d887ec74f69e6828e25e3d23cf6fa0daac5902afccaf0568d7e | 2971 | checksum: be30609aae0bfe492097815f166ccc07f465220cb604647fa4e5ec05a1d16c012a41b82b5f11ecfe2485cbb479d4d20384b95b809ca0bcff6d94d5bbafa645bb |
2972 | languageName: node | 2972 | languageName: node |
2973 | linkType: hard | 2973 | linkType: hard |
2974 | 2974 | ||
@@ -2993,32 +2993,32 @@ __metadata: | |||
2993 | languageName: node | 2993 | languageName: node |
2994 | linkType: hard | 2994 | linkType: hard |
2995 | 2995 | ||
2996 | "@types/react-dom@npm:^18.2.17": | 2996 | "@types/react-dom@npm:^18.2.18": |
2997 | version: 18.2.17 | 2997 | version: 18.2.18 |
2998 | resolution: "@types/react-dom@npm:18.2.17" | 2998 | resolution: "@types/react-dom@npm:18.2.18" |
2999 | dependencies: | 2999 | dependencies: |
3000 | "@types/react": "npm:*" | 3000 | "@types/react": "npm:*" |
3001 | checksum: 33b53078ed7e9e0cfc4dc691e938f7db1cc06353bc345947b41b581c3efe2b980c9e4eb6460dbf5ddc521dd91959194c970221a2bd4bfad9d23ebce338e12938 | 3001 | checksum: 74dba11a1b8156f3a763f3fca1fb4ec1dcd349153279b8bf79210024a69f994bf2cf0728198c047f8130c5318420ea56281b0a4ef84c8ae943cd9a0cac705220 |
3002 | languageName: node | 3002 | languageName: node |
3003 | linkType: hard | 3003 | linkType: hard |
3004 | 3004 | ||
3005 | "@types/react-transition-group@npm:^4.4.9": | 3005 | "@types/react-transition-group@npm:^4.4.10": |
3006 | version: 4.4.9 | 3006 | version: 4.4.10 |
3007 | resolution: "@types/react-transition-group@npm:4.4.9" | 3007 | resolution: "@types/react-transition-group@npm:4.4.10" |
3008 | dependencies: | 3008 | dependencies: |
3009 | "@types/react": "npm:*" | 3009 | "@types/react": "npm:*" |
3010 | checksum: 279cd319202f7ec24ecad174dffd19fd161250bc438bf3c62951f467093e5664a0c895b185976bf45f55b68ec901e520924216eb8abafe934b66f55337319ff5 | 3010 | checksum: 3eb9bca143abc21eb781aa5cb1bded0c9335689d515bf0513fb8e63217b7a8122c6a323ecd5644a06938727e1f467ee061d8df1c93b68825a80ff1b47ab777a2 |
3011 | languageName: node | 3011 | languageName: node |
3012 | linkType: hard | 3012 | linkType: hard |
3013 | 3013 | ||
3014 | "@types/react@npm:*, @types/react@npm:^18.2.41": | 3014 | "@types/react@npm:*, @types/react@npm:^18.2.45": |
3015 | version: 18.2.41 | 3015 | version: 18.2.45 |
3016 | resolution: "@types/react@npm:18.2.41" | 3016 | resolution: "@types/react@npm:18.2.45" |
3017 | dependencies: | 3017 | dependencies: |
3018 | "@types/prop-types": "npm:*" | 3018 | "@types/prop-types": "npm:*" |
3019 | "@types/scheduler": "npm:*" | 3019 | "@types/scheduler": "npm:*" |
3020 | csstype: "npm:^3.0.2" | 3020 | csstype: "npm:^3.0.2" |
3021 | checksum: 5cc72491ce8be95e7bbedd8bf039ca971772ecd22d989feb045af7e73247c7e6cff25a2f1c2200be461fb2f6b5aacef739e1ba9fd83c744209dfd3ce8aa75afe | 3021 | checksum: 4cc650c47ffb88baac29fb7a74e842e4af4a55f437086ef70250fdc75f0a5f2fcf8adc272d05ab2e00b1de6e14613296881271caee037dadf9130fdeb498c59e |
3022 | languageName: node | 3022 | languageName: node |
3023 | linkType: hard | 3023 | linkType: hard |
3024 | 3024 | ||
@@ -3052,15 +3052,15 @@ __metadata: | |||
3052 | languageName: node | 3052 | languageName: node |
3053 | linkType: hard | 3053 | linkType: hard |
3054 | 3054 | ||
3055 | "@typescript-eslint/eslint-plugin@npm:^6.13.1": | 3055 | "@typescript-eslint/eslint-plugin@npm:^6.15.0": |
3056 | version: 6.13.1 | 3056 | version: 6.15.0 |
3057 | resolution: "@typescript-eslint/eslint-plugin@npm:6.13.1" | 3057 | resolution: "@typescript-eslint/eslint-plugin@npm:6.15.0" |
3058 | dependencies: | 3058 | dependencies: |
3059 | "@eslint-community/regexpp": "npm:^4.5.1" | 3059 | "@eslint-community/regexpp": "npm:^4.5.1" |
3060 | "@typescript-eslint/scope-manager": "npm:6.13.1" | 3060 | "@typescript-eslint/scope-manager": "npm:6.15.0" |
3061 | "@typescript-eslint/type-utils": "npm:6.13.1" | 3061 | "@typescript-eslint/type-utils": "npm:6.15.0" |
3062 | "@typescript-eslint/utils": "npm:6.13.1" | 3062 | "@typescript-eslint/utils": "npm:6.15.0" |
3063 | "@typescript-eslint/visitor-keys": "npm:6.13.1" | 3063 | "@typescript-eslint/visitor-keys": "npm:6.15.0" |
3064 | debug: "npm:^4.3.4" | 3064 | debug: "npm:^4.3.4" |
3065 | graphemer: "npm:^1.4.0" | 3065 | graphemer: "npm:^1.4.0" |
3066 | ignore: "npm:^5.2.4" | 3066 | ignore: "npm:^5.2.4" |
@@ -3073,44 +3073,44 @@ __metadata: | |||
3073 | peerDependenciesMeta: | 3073 | peerDependenciesMeta: |
3074 | typescript: | 3074 | typescript: |
3075 | optional: true | 3075 | optional: true |
3076 | checksum: ccbcbf2a16d985348f46f07c90db06d98878632e7e98eb2fe9275dc489e8a3406bbe002e6d5ff0da88f51a5fe44ea0e942ec35488a3f1939e009f0a43997d34a | 3076 | checksum: 78054afb0d4ab12d82db7a9cb005dfa2be42962341728abf4a81802e1f4c0f5b23de4870287f4b7e32aa4a4bc900bbc218f2d4d0c02aa77452e8e8e0b71fe3de |
3077 | languageName: node | 3077 | languageName: node |
3078 | linkType: hard | 3078 | linkType: hard |
3079 | 3079 | ||
3080 | "@typescript-eslint/parser@npm:^6.13.1": | 3080 | "@typescript-eslint/parser@npm:^6.15.0": |
3081 | version: 6.13.1 | 3081 | version: 6.15.0 |
3082 | resolution: "@typescript-eslint/parser@npm:6.13.1" | 3082 | resolution: "@typescript-eslint/parser@npm:6.15.0" |
3083 | dependencies: | 3083 | dependencies: |
3084 | "@typescript-eslint/scope-manager": "npm:6.13.1" | 3084 | "@typescript-eslint/scope-manager": "npm:6.15.0" |
3085 | "@typescript-eslint/types": "npm:6.13.1" | 3085 | "@typescript-eslint/types": "npm:6.15.0" |
3086 | "@typescript-eslint/typescript-estree": "npm:6.13.1" | 3086 | "@typescript-eslint/typescript-estree": "npm:6.15.0" |
3087 | "@typescript-eslint/visitor-keys": "npm:6.13.1" | 3087 | "@typescript-eslint/visitor-keys": "npm:6.15.0" |
3088 | debug: "npm:^4.3.4" | 3088 | debug: "npm:^4.3.4" |
3089 | peerDependencies: | 3089 | peerDependencies: |
3090 | eslint: ^7.0.0 || ^8.0.0 | 3090 | eslint: ^7.0.0 || ^8.0.0 |
3091 | peerDependenciesMeta: | 3091 | peerDependenciesMeta: |
3092 | typescript: | 3092 | typescript: |
3093 | optional: true | 3093 | optional: true |
3094 | checksum: 83f67374815f330ba96c2129f616ee1c8af3a7282c91e9645371ce4a9acfc2797df345cc65a34efa3ff0e574ac9422921cdac623a37be21e36e45c46d6de4731 | 3094 | checksum: e7f265fd4abd3bc49fa5b304cd4b9c22801ac5a9da4ee342bbab0c117d629ac4aad6998555b61a8c5a0b279c443a44ae99f16669e24e3ef17ccec20c8b7019e7 |
3095 | languageName: node | 3095 | languageName: node |
3096 | linkType: hard | 3096 | linkType: hard |
3097 | 3097 | ||
3098 | "@typescript-eslint/scope-manager@npm:6.13.1": | 3098 | "@typescript-eslint/scope-manager@npm:6.15.0": |
3099 | version: 6.13.1 | 3099 | version: 6.15.0 |
3100 | resolution: "@typescript-eslint/scope-manager@npm:6.13.1" | 3100 | resolution: "@typescript-eslint/scope-manager@npm:6.15.0" |
3101 | dependencies: | 3101 | dependencies: |
3102 | "@typescript-eslint/types": "npm:6.13.1" | 3102 | "@typescript-eslint/types": "npm:6.15.0" |
3103 | "@typescript-eslint/visitor-keys": "npm:6.13.1" | 3103 | "@typescript-eslint/visitor-keys": "npm:6.15.0" |
3104 | checksum: 2b00f087ba9a9940df4cbc96335312737b3a7744b61528e4949ffd8034067d4c419a7b20beeb4c47d0ed5f52ad82490e89622a0de0e33c4bb6af3ede14c680b8 | 3104 | checksum: 3428d99de440f227cbc2afb44cdcb25e44c4b49c5f490392f83e21d2048210a6ec2f2f68133376c842034f5b5ba4ec9721da7caa18e631e23b57e20927b5b6f0 |
3105 | languageName: node | 3105 | languageName: node |
3106 | linkType: hard | 3106 | linkType: hard |
3107 | 3107 | ||
3108 | "@typescript-eslint/type-utils@npm:6.13.1": | 3108 | "@typescript-eslint/type-utils@npm:6.15.0": |
3109 | version: 6.13.1 | 3109 | version: 6.15.0 |
3110 | resolution: "@typescript-eslint/type-utils@npm:6.13.1" | 3110 | resolution: "@typescript-eslint/type-utils@npm:6.15.0" |
3111 | dependencies: | 3111 | dependencies: |
3112 | "@typescript-eslint/typescript-estree": "npm:6.13.1" | 3112 | "@typescript-eslint/typescript-estree": "npm:6.15.0" |
3113 | "@typescript-eslint/utils": "npm:6.13.1" | 3113 | "@typescript-eslint/utils": "npm:6.15.0" |
3114 | debug: "npm:^4.3.4" | 3114 | debug: "npm:^4.3.4" |
3115 | ts-api-utils: "npm:^1.0.1" | 3115 | ts-api-utils: "npm:^1.0.1" |
3116 | peerDependencies: | 3116 | peerDependencies: |
@@ -3118,23 +3118,23 @@ __metadata: | |||
3118 | peerDependenciesMeta: | 3118 | peerDependenciesMeta: |
3119 | typescript: | 3119 | typescript: |
3120 | optional: true | 3120 | optional: true |
3121 | checksum: c958126cb9d28021ae8e3bb2c11d5f427ab09adff5deaf64927f9769b8ba1f7b561dfb30ac2e69f9ef923183566569500a27a188b534e6641a34e0a6fd144773 | 3121 | checksum: 32cb531a4b5e0ccd431cba553ec73b87d4453b48af288a33e359ba4f5278126390d82799b61d3f0fbf135cfde1ac6c2275c2cf37a676e8a2a2811e774e660f16 |
3122 | languageName: node | 3122 | languageName: node |
3123 | linkType: hard | 3123 | linkType: hard |
3124 | 3124 | ||
3125 | "@typescript-eslint/types@npm:6.13.1": | 3125 | "@typescript-eslint/types@npm:6.15.0": |
3126 | version: 6.13.1 | 3126 | version: 6.15.0 |
3127 | resolution: "@typescript-eslint/types@npm:6.13.1" | 3127 | resolution: "@typescript-eslint/types@npm:6.15.0" |
3128 | checksum: 26ea37ec6943859415d683b280e135c20da73281d742aaf123763bf9e10ea0629950422934c4ec3cc77a390a8fa8f33cc4f3914869ffd5af4d1edbbbae834d60 | 3128 | checksum: 6e33529ea301c8c4b8c1f589dadd5d2a66c1b24ec87a577524fbc996d4c7b65d4f4fdfa4a3937b691efee6a10a6b16f7bfcabe98a15e0fc0c0c57aa0d80dcc25 |
3129 | languageName: node | 3129 | languageName: node |
3130 | linkType: hard | 3130 | linkType: hard |
3131 | 3131 | ||
3132 | "@typescript-eslint/typescript-estree@npm:6.13.1": | 3132 | "@typescript-eslint/typescript-estree@npm:6.15.0": |
3133 | version: 6.13.1 | 3133 | version: 6.15.0 |
3134 | resolution: "@typescript-eslint/typescript-estree@npm:6.13.1" | 3134 | resolution: "@typescript-eslint/typescript-estree@npm:6.15.0" |
3135 | dependencies: | 3135 | dependencies: |
3136 | "@typescript-eslint/types": "npm:6.13.1" | 3136 | "@typescript-eslint/types": "npm:6.15.0" |
3137 | "@typescript-eslint/visitor-keys": "npm:6.13.1" | 3137 | "@typescript-eslint/visitor-keys": "npm:6.15.0" |
3138 | debug: "npm:^4.3.4" | 3138 | debug: "npm:^4.3.4" |
3139 | globby: "npm:^11.1.0" | 3139 | globby: "npm:^11.1.0" |
3140 | is-glob: "npm:^4.0.3" | 3140 | is-glob: "npm:^4.0.3" |
@@ -3143,34 +3143,34 @@ __metadata: | |||
3143 | peerDependenciesMeta: | 3143 | peerDependenciesMeta: |
3144 | typescript: | 3144 | typescript: |
3145 | optional: true | 3145 | optional: true |
3146 | checksum: d8aa409464f860f12ddc67ad8d94dcc37dc4da272b1d9d1937b6ccbcf397daa8bb495f409ee5c263053f87a9a0cc7d5ba6926137e5724d4ac6a839d8a481a8c0 | 3146 | checksum: 08955f6e84b8edb855a6769671e85889e52b15b82e00a64f595da867b21ad060e5342787c436d77702b2a1f39d411ac79b81a8d2e2006e9b1886eadb08b626df |
3147 | languageName: node | 3147 | languageName: node |
3148 | linkType: hard | 3148 | linkType: hard |
3149 | 3149 | ||
3150 | "@typescript-eslint/utils@npm:6.13.1": | 3150 | "@typescript-eslint/utils@npm:6.15.0": |
3151 | version: 6.13.1 | 3151 | version: 6.15.0 |
3152 | resolution: "@typescript-eslint/utils@npm:6.13.1" | 3152 | resolution: "@typescript-eslint/utils@npm:6.15.0" |
3153 | dependencies: | 3153 | dependencies: |
3154 | "@eslint-community/eslint-utils": "npm:^4.4.0" | 3154 | "@eslint-community/eslint-utils": "npm:^4.4.0" |
3155 | "@types/json-schema": "npm:^7.0.12" | 3155 | "@types/json-schema": "npm:^7.0.12" |
3156 | "@types/semver": "npm:^7.5.0" | 3156 | "@types/semver": "npm:^7.5.0" |
3157 | "@typescript-eslint/scope-manager": "npm:6.13.1" | 3157 | "@typescript-eslint/scope-manager": "npm:6.15.0" |
3158 | "@typescript-eslint/types": "npm:6.13.1" | 3158 | "@typescript-eslint/types": "npm:6.15.0" |
3159 | "@typescript-eslint/typescript-estree": "npm:6.13.1" | 3159 | "@typescript-eslint/typescript-estree": "npm:6.15.0" |
3160 | semver: "npm:^7.5.4" | 3160 | semver: "npm:^7.5.4" |
3161 | peerDependencies: | 3161 | peerDependencies: |
3162 | eslint: ^7.0.0 || ^8.0.0 | 3162 | eslint: ^7.0.0 || ^8.0.0 |
3163 | checksum: 6706527c6d979ba0a9756394382e945a2de51f54b8193da03ec2f980d479ffca0f58216c90f510b39601d07b37781af4236384f49afc63713662cd309bd43a1f | 3163 | checksum: 53519a2027681bdc8f028f9421c65f193f91b5bb1659465fedb8043376c693c2391211f1c01d8ba25bfaa7f7b3a102263d7123f9dfade12032159f4b4490f0fb |
3164 | languageName: node | 3164 | languageName: node |
3165 | linkType: hard | 3165 | linkType: hard |
3166 | 3166 | ||
3167 | "@typescript-eslint/visitor-keys@npm:6.13.1": | 3167 | "@typescript-eslint/visitor-keys@npm:6.15.0": |
3168 | version: 6.13.1 | 3168 | version: 6.15.0 |
3169 | resolution: "@typescript-eslint/visitor-keys@npm:6.13.1" | 3169 | resolution: "@typescript-eslint/visitor-keys@npm:6.15.0" |
3170 | dependencies: | 3170 | dependencies: |
3171 | "@typescript-eslint/types": "npm:6.13.1" | 3171 | "@typescript-eslint/types": "npm:6.15.0" |
3172 | eslint-visitor-keys: "npm:^3.4.1" | 3172 | eslint-visitor-keys: "npm:^3.4.1" |
3173 | checksum: 68daf60941fc4824f90480787587c9cbb447eeceac5698dfef2b0c2caa6d3c715f604c2357cc20abb6899be3c3e3ae3b5bbee310faccaab9ea98c8bd9137ec1f | 3173 | checksum: bf9f71af60bd63d1073900e75c5a0aa6eddd672f6c3ac6092c765d67deb7a0c32d2a5f6f3aee9e95f93a93d58563a76da209bd8487aadafd4d013100ffe38520 |
3174 | languageName: node | 3174 | languageName: node |
3175 | linkType: hard | 3175 | linkType: hard |
3176 | 3176 | ||
@@ -3192,13 +3192,13 @@ __metadata: | |||
3192 | languageName: node | 3192 | languageName: node |
3193 | linkType: hard | 3193 | linkType: hard |
3194 | 3194 | ||
3195 | "@xstate/cli@npm:^0.5.11": | 3195 | "@xstate/cli@npm:^0.5.15": |
3196 | version: 0.5.11 | 3196 | version: 0.5.15 |
3197 | resolution: "@xstate/cli@npm:0.5.11" | 3197 | resolution: "@xstate/cli@npm:0.5.15" |
3198 | dependencies: | 3198 | dependencies: |
3199 | "@babel/core": "npm:^7.21.4" | 3199 | "@babel/core": "npm:^7.21.4" |
3200 | "@xstate/machine-extractor": "npm:^0.13.0" | 3200 | "@xstate/machine-extractor": "npm:^0.14.1" |
3201 | "@xstate/tools-shared": "npm:^4.0.5" | 3201 | "@xstate/tools-shared": "npm:^4.0.8" |
3202 | chokidar: "npm:^3.5.3" | 3202 | chokidar: "npm:^3.5.3" |
3203 | commander: "npm:^8.0.0" | 3203 | commander: "npm:^8.0.0" |
3204 | dotenv: "npm:^16.0.3" | 3204 | dotenv: "npm:^16.0.3" |
@@ -3208,13 +3208,13 @@ __metadata: | |||
3208 | xstate-beta: "npm:xstate@beta" | 3208 | xstate-beta: "npm:xstate@beta" |
3209 | bin: | 3209 | bin: |
3210 | xstate: bin/bin.js | 3210 | xstate: bin/bin.js |
3211 | checksum: 02bf9f35661a2b8e93d3618ac1e44c07442e0453861800340c814caee03ce818d0a86e27d0682c6acbeca23d2e7c882713cfadc254c7f7e080c912dd81fe1373 | 3211 | checksum: 85dc3cfcc41328c694817d2aacfbae4fe3d93029fdf55a3fcc2b96e63b5c778abcaf9faf76fd6e2166612c393454b444ca3aa049c26bc9cdfb832b668c7eba2d |
3212 | languageName: node | 3212 | languageName: node |
3213 | linkType: hard | 3213 | linkType: hard |
3214 | 3214 | ||
3215 | "@xstate/machine-extractor@npm:^0.13.0": | 3215 | "@xstate/machine-extractor@npm:^0.14.1": |
3216 | version: 0.13.0 | 3216 | version: 0.14.1 |
3217 | resolution: "@xstate/machine-extractor@npm:0.13.0" | 3217 | resolution: "@xstate/machine-extractor@npm:0.14.1" |
3218 | dependencies: | 3218 | dependencies: |
3219 | "@babel/parser": "npm:^7.21.4" | 3219 | "@babel/parser": "npm:^7.21.4" |
3220 | "@babel/traverse": "npm:^7.21.4" | 3220 | "@babel/traverse": "npm:^7.21.4" |
@@ -3222,19 +3222,19 @@ __metadata: | |||
3222 | recast: "npm:^0.23.1" | 3222 | recast: "npm:^0.23.1" |
3223 | peerDependencies: | 3223 | peerDependencies: |
3224 | xstate: ^4 | 3224 | xstate: ^4 |
3225 | checksum: 449cd18e42afccfd7e927683190757b61dd7a74b5ec2a51c786698203370a8348c7b497d6d3b4666ec1a949016792e124d22a65c398ff0a011e82c11b2890453 | 3225 | checksum: bc3ea496bb8974a9431acb318a11684fd7954253539d7d59bcea6af190621f82f6ea729d37bd487ec0e52e90f866401af79d7f1c0ccd396b3ee14916b8519ac9 |
3226 | languageName: node | 3226 | languageName: node |
3227 | linkType: hard | 3227 | linkType: hard |
3228 | 3228 | ||
3229 | "@xstate/tools-shared@npm:^4.0.5": | 3229 | "@xstate/tools-shared@npm:^4.0.8": |
3230 | version: 4.0.5 | 3230 | version: 4.0.8 |
3231 | resolution: "@xstate/tools-shared@npm:4.0.5" | 3231 | resolution: "@xstate/tools-shared@npm:4.0.8" |
3232 | dependencies: | 3232 | dependencies: |
3233 | "@xstate/machine-extractor": "npm:^0.13.0" | 3233 | "@xstate/machine-extractor": "npm:^0.14.1" |
3234 | peerDependencies: | 3234 | peerDependencies: |
3235 | prettier: ^2 | 3235 | prettier: ^2 |
3236 | xstate: ^4 | 3236 | xstate: ^4 |
3237 | checksum: 9af83b255b586c4ee9e9131c41bcdb37377fbd9de2060d4782c0b8f96a89754e86d9101462d4b4dece6b2c82b8df9bb8d6f4c317fed5530d01ab1ceb593a36a1 | 3237 | checksum: 4f1b48b52f415505bb3186bf26cdc94f12630d1718ec4e6a003d5d95885590a6dafc2fbd8ed6c4ab0b7752b21e8357bf07bcd353b078429b55207f6d99217eb4 |
3238 | languageName: node | 3238 | languageName: node |
3239 | linkType: hard | 3239 | linkType: hard |
3240 | 3240 | ||
@@ -3741,9 +3741,9 @@ __metadata: | |||
3741 | linkType: hard | 3741 | linkType: hard |
3742 | 3742 | ||
3743 | "caniuse-lite@npm:^1.0.30001517": | 3743 | "caniuse-lite@npm:^1.0.30001517": |
3744 | version: 1.0.30001565 | 3744 | version: 1.0.30001571 |
3745 | resolution: "caniuse-lite@npm:1.0.30001565" | 3745 | resolution: "caniuse-lite@npm:1.0.30001571" |
3746 | checksum: b400e0364651a700e39d59449ca6c65b26e2caceecc4b93ae54a01ed1f62d2a7e1333b1dc640d95fbe620ffa5be38fe4dbacd880cd7a1f42fc72bb8de9a2d0c9 | 3746 | checksum: 632f476e39febbfb5dc91c236981f3d518dc0cf55c42cc2bba431a6b6f4cceae3f9cd74d26312f30e9de65a3cc92ccf80d964ba8de061e25f37b7f0518303dad |
3747 | languageName: node | 3747 | languageName: node |
3748 | linkType: hard | 3748 | linkType: hard |
3749 | 3749 | ||
@@ -3998,10 +3998,10 @@ __metadata: | |||
3998 | languageName: node | 3998 | languageName: node |
3999 | linkType: hard | 3999 | linkType: hard |
4000 | 4000 | ||
4001 | "csstype@npm:^3.0.2, csstype@npm:^3.1.2": | 4001 | "csstype@npm:^3.0.2, csstype@npm:^3.1.2, csstype@npm:^3.1.3": |
4002 | version: 3.1.2 | 4002 | version: 3.1.3 |
4003 | resolution: "csstype@npm:3.1.2" | 4003 | resolution: "csstype@npm:3.1.3" |
4004 | checksum: 32c038af259897c807ac738d9eab16b3d86747c72b09d5c740978e06f067f9b7b1737e1b75e407c7ab1fe1543dc95f20e202b4786aeb1b8d3bdf5d5ce655e6c6 | 4004 | checksum: 80c089d6f7e0c5b2bd83cf0539ab41474198579584fa10d86d0cafe0642202343cbc119e076a0b1aece191989477081415d66c9fefbf3c957fc2fc4b7009f248 |
4005 | languageName: node | 4005 | languageName: node |
4006 | linkType: hard | 4006 | linkType: hard |
4007 | 4007 | ||
@@ -4918,9 +4918,9 @@ __metadata: | |||
4918 | languageName: node | 4918 | languageName: node |
4919 | linkType: hard | 4919 | linkType: hard |
4920 | 4920 | ||
4921 | "eslint-plugin-import@npm:^2.29.0": | 4921 | "eslint-plugin-import@npm:^2.29.1": |
4922 | version: 2.29.0 | 4922 | version: 2.29.1 |
4923 | resolution: "eslint-plugin-import@npm:2.29.0" | 4923 | resolution: "eslint-plugin-import@npm:2.29.1" |
4924 | dependencies: | 4924 | dependencies: |
4925 | array-includes: "npm:^3.1.7" | 4925 | array-includes: "npm:^3.1.7" |
4926 | array.prototype.findlastindex: "npm:^1.2.3" | 4926 | array.prototype.findlastindex: "npm:^1.2.3" |
@@ -4938,10 +4938,10 @@ __metadata: | |||
4938 | object.groupby: "npm:^1.0.1" | 4938 | object.groupby: "npm:^1.0.1" |
4939 | object.values: "npm:^1.1.7" | 4939 | object.values: "npm:^1.1.7" |
4940 | semver: "npm:^6.3.1" | 4940 | semver: "npm:^6.3.1" |
4941 | tsconfig-paths: "npm:^3.14.2" | 4941 | tsconfig-paths: "npm:^3.15.0" |
4942 | peerDependencies: | 4942 | peerDependencies: |
4943 | eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 | 4943 | eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 |
4944 | checksum: 761a4e1fbc2cd318e62350bed4c448f8b11ed83091d6bb7776f096556363a09debd9922b39fd2714c895edc9aaea82e08e684eb632283f880c58a91e4bae6733 | 4944 | checksum: 5f35dfbf4e8e67f741f396987de9504ad125c49f4144508a93282b4ea0127e052bde65ab6def1f31b6ace6d5d430be698333f75bdd7dca3bc14226c92a083196 |
4945 | languageName: node | 4945 | languageName: node |
4946 | linkType: hard | 4946 | linkType: hard |
4947 | 4947 | ||
@@ -4980,22 +4980,23 @@ __metadata: | |||
4980 | languageName: node | 4980 | languageName: node |
4981 | linkType: hard | 4981 | linkType: hard |
4982 | 4982 | ||
4983 | "eslint-plugin-prettier@npm:^5.0.1": | 4983 | "eslint-plugin-prettier@npm:^5.1.1": |
4984 | version: 5.0.1 | 4984 | version: 5.1.1 |
4985 | resolution: "eslint-plugin-prettier@npm:5.0.1" | 4985 | resolution: "eslint-plugin-prettier@npm:5.1.1" |
4986 | dependencies: | 4986 | dependencies: |
4987 | prettier-linter-helpers: "npm:^1.0.0" | 4987 | prettier-linter-helpers: "npm:^1.0.0" |
4988 | synckit: "npm:^0.8.5" | 4988 | synckit: "npm:^0.8.5" |
4989 | peerDependencies: | 4989 | peerDependencies: |
4990 | "@types/eslint": ">=8.0.0" | 4990 | "@types/eslint": ">=8.0.0" |
4991 | eslint: ">=8.0.0" | 4991 | eslint: ">=8.0.0" |
4992 | eslint-config-prettier: "*" | ||
4992 | prettier: ">=3.0.0" | 4993 | prettier: ">=3.0.0" |
4993 | peerDependenciesMeta: | 4994 | peerDependenciesMeta: |
4994 | "@types/eslint": | 4995 | "@types/eslint": |
4995 | optional: true | 4996 | optional: true |
4996 | eslint-config-prettier: | 4997 | eslint-config-prettier: |
4997 | optional: true | 4998 | optional: true |
4998 | checksum: 08e2c7bed93d9f7c86e9aa0bd4f5cc51f65233a446ddfda11e821f12819e1e4be62cfbc2a4e17169c76fded1c4de7371e37e5f2525e81695decaf6c652a41fb0 | 4999 | checksum: cb9fb797e3b872864d9bd4a6154cc0aeccdd9b3d7add510b2077f6d5149fb4b681abd180dacb5dafda603defb6089824a7c6f97faf1f099dba4f4e77f86c46c3 |
4999 | languageName: node | 5000 | languageName: node |
5000 | linkType: hard | 5001 | linkType: hard |
5001 | 5002 | ||
@@ -5051,14 +5052,14 @@ __metadata: | |||
5051 | languageName: node | 5052 | languageName: node |
5052 | linkType: hard | 5053 | linkType: hard |
5053 | 5054 | ||
5054 | "eslint@npm:^8.55.0": | 5055 | "eslint@npm:^8.56.0": |
5055 | version: 8.55.0 | 5056 | version: 8.56.0 |
5056 | resolution: "eslint@npm:8.55.0" | 5057 | resolution: "eslint@npm:8.56.0" |
5057 | dependencies: | 5058 | dependencies: |
5058 | "@eslint-community/eslint-utils": "npm:^4.2.0" | 5059 | "@eslint-community/eslint-utils": "npm:^4.2.0" |
5059 | "@eslint-community/regexpp": "npm:^4.6.1" | 5060 | "@eslint-community/regexpp": "npm:^4.6.1" |
5060 | "@eslint/eslintrc": "npm:^2.1.4" | 5061 | "@eslint/eslintrc": "npm:^2.1.4" |
5061 | "@eslint/js": "npm:8.55.0" | 5062 | "@eslint/js": "npm:8.56.0" |
5062 | "@humanwhocodes/config-array": "npm:^0.11.13" | 5063 | "@humanwhocodes/config-array": "npm:^0.11.13" |
5063 | "@humanwhocodes/module-importer": "npm:^1.0.1" | 5064 | "@humanwhocodes/module-importer": "npm:^1.0.1" |
5064 | "@nodelib/fs.walk": "npm:^1.2.8" | 5065 | "@nodelib/fs.walk": "npm:^1.2.8" |
@@ -5095,7 +5096,7 @@ __metadata: | |||
5095 | text-table: "npm:^0.2.0" | 5096 | text-table: "npm:^0.2.0" |
5096 | bin: | 5097 | bin: |
5097 | eslint: bin/eslint.js | 5098 | eslint: bin/eslint.js |
5098 | checksum: d28c0b60f19bb7d355cb8393e77b018c8f548dba3f820b799c89bb2e0c436ee26084e700c5e57e1e97e7972ec93065277849141b82e7b0c0d02c2dc1e553a2a1 | 5099 | checksum: 2be598f7da1339d045ad933ffd3d4742bee610515cd2b0d9a2b8b729395a01d4e913552fff555b559fccaefd89d7b37632825789d1b06470608737ae69ab43fb |
5099 | languageName: node | 5100 | languageName: node |
5100 | linkType: hard | 5101 | linkType: hard |
5101 | 5102 | ||
@@ -6687,12 +6688,12 @@ __metadata: | |||
6687 | languageName: node | 6688 | languageName: node |
6688 | linkType: hard | 6689 | linkType: hard |
6689 | 6690 | ||
6690 | "nanoid@npm:^3.3.6": | 6691 | "nanoid@npm:^3.3.7": |
6691 | version: 3.3.6 | 6692 | version: 3.3.7 |
6692 | resolution: "nanoid@npm:3.3.6" | 6693 | resolution: "nanoid@npm:3.3.7" |
6693 | bin: | 6694 | bin: |
6694 | nanoid: bin/nanoid.cjs | 6695 | nanoid: bin/nanoid.cjs |
6695 | checksum: 606b355960d0fcbe3d27924c4c52ef7d47d3b57208808ece73279420d91469b01ec1dce10fae512b6d4a8c5a5432b352b228336a8b2202a6ea68e67fa348e2ee | 6696 | checksum: e3fb661aa083454f40500473bb69eedb85dc160e763150b9a2c567c7e9ff560ce028a9f833123b618a6ea742e311138b591910e795614a629029e86e180660f3 |
6696 | languageName: node | 6697 | languageName: node |
6697 | linkType: hard | 6698 | linkType: hard |
6698 | 6699 | ||
@@ -7080,14 +7081,14 @@ __metadata: | |||
7080 | languageName: node | 7081 | languageName: node |
7081 | linkType: hard | 7082 | linkType: hard |
7082 | 7083 | ||
7083 | "postcss@npm:^8.4.31": | 7084 | "postcss@npm:^8.4.32": |
7084 | version: 8.4.31 | 7085 | version: 8.4.32 |
7085 | resolution: "postcss@npm:8.4.31" | 7086 | resolution: "postcss@npm:8.4.32" |
7086 | dependencies: | 7087 | dependencies: |
7087 | nanoid: "npm:^3.3.6" | 7088 | nanoid: "npm:^3.3.7" |
7088 | picocolors: "npm:^1.0.0" | 7089 | picocolors: "npm:^1.0.0" |
7089 | source-map-js: "npm:^1.0.2" | 7090 | source-map-js: "npm:^1.0.2" |
7090 | checksum: 748b82e6e5fc34034dcf2ae88ea3d11fd09f69b6c50ecdd3b4a875cfc7cdca435c958b211e2cb52355422ab6fccb7d8f2f2923161d7a1b281029e4a913d59acf | 7091 | checksum: 39308a9195fa34d4dbdd7b58a896cff0c7809f84f7a4ac1b95b68ca86c9138a395addff33075668ed3983d41b90aac05754c445237a9365eb1c3a5602ebd03ad |
7091 | languageName: node | 7092 | languageName: node |
7092 | linkType: hard | 7093 | linkType: hard |
7093 | 7094 | ||
@@ -7116,12 +7117,12 @@ __metadata: | |||
7116 | languageName: node | 7117 | languageName: node |
7117 | linkType: hard | 7118 | linkType: hard |
7118 | 7119 | ||
7119 | "prettier@npm:^3.1.0": | 7120 | "prettier@npm:^3.1.1": |
7120 | version: 3.1.0 | 7121 | version: 3.1.1 |
7121 | resolution: "prettier@npm:3.1.0" | 7122 | resolution: "prettier@npm:3.1.1" |
7122 | bin: | 7123 | bin: |
7123 | prettier: bin/prettier.cjs | 7124 | prettier: bin/prettier.cjs |
7124 | checksum: a45ea70aa97fde162ea4c4aba3dfc7859aa6a732a1db34458d9535dc3c2c16d3bc3fb5689e6cd76aa835562555303b02d9449fd2e15af3b73c8053557e25c5b6 | 7125 | checksum: facc944ba20e194ff4db765e830ffbcb642803381f0d2033ed397e79904fa4ccc877dc25ad68f42d36985c01d051c990ca1b905fb83d2d7d65fe69e4386fa1a3 |
7125 | languageName: node | 7126 | languageName: node |
7126 | linkType: hard | 7127 | linkType: hard |
7127 | 7128 | ||
@@ -7209,15 +7210,15 @@ __metadata: | |||
7209 | languageName: node | 7210 | languageName: node |
7210 | linkType: hard | 7211 | linkType: hard |
7211 | 7212 | ||
7212 | "react-resize-detector@npm:^9.1.0": | 7213 | "react-resize-detector@npm:^9.1.1": |
7213 | version: 9.1.0 | 7214 | version: 9.1.1 |
7214 | resolution: "react-resize-detector@npm:9.1.0" | 7215 | resolution: "react-resize-detector@npm:9.1.1" |
7215 | dependencies: | 7216 | dependencies: |
7216 | lodash: "npm:^4.17.21" | 7217 | lodash: "npm:^4.17.21" |
7217 | peerDependencies: | 7218 | peerDependencies: |
7218 | react: ^16.0.0 || ^17.0.0 || ^18.0.0 | 7219 | react: ^16.0.0 || ^17.0.0 || ^18.0.0 |
7219 | react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 | 7220 | react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 |
7220 | checksum: ebd45b54ce68368a8d8b6b32ff3b7949e8f56d5cce21fb18b5044612b16ae9adfdd2eefa6494a700aaf6c64b2cec4c3c33d86c464d1772042dbb4d87dd3dafc6 | 7221 | checksum: 6a85892fe46a12fc27b09b5bf5fcc1438f3196f70c75d4685b09eed2c68a2c853dd6eb792bf852038082505a3b4f05dba359055ee0baca3f8b59f022a85a368c |
7221 | languageName: node | 7222 | languageName: node |
7222 | linkType: hard | 7223 | linkType: hard |
7223 | 7224 | ||
@@ -8108,15 +8109,15 @@ __metadata: | |||
8108 | languageName: node | 8109 | languageName: node |
8109 | linkType: hard | 8110 | linkType: hard |
8110 | 8111 | ||
8111 | "tsconfig-paths@npm:^3.14.2": | 8112 | "tsconfig-paths@npm:^3.15.0": |
8112 | version: 3.14.2 | 8113 | version: 3.15.0 |
8113 | resolution: "tsconfig-paths@npm:3.14.2" | 8114 | resolution: "tsconfig-paths@npm:3.15.0" |
8114 | dependencies: | 8115 | dependencies: |
8115 | "@types/json5": "npm:^0.0.29" | 8116 | "@types/json5": "npm:^0.0.29" |
8116 | json5: "npm:^1.0.2" | 8117 | json5: "npm:^1.0.2" |
8117 | minimist: "npm:^1.2.6" | 8118 | minimist: "npm:^1.2.6" |
8118 | strip-bom: "npm:^3.0.0" | 8119 | strip-bom: "npm:^3.0.0" |
8119 | checksum: fdc92bb7b18b31c0e76f8ec4f98d07236b09590fd6578e587ad024792c8b2235d65125a8fd007fa47a84400f84ceccbf33f24e5198d953249e7204f4cef3517c | 8120 | checksum: 5b4f301a2b7a3766a986baf8fc0e177eb80bdba6e396792ff92dc23b5bca8bb279fc96517dcaaef63a3b49bebc6c4c833653ec58155780bc906bdbcf7dda0ef5 |
8120 | languageName: node | 8121 | languageName: node |
8121 | linkType: hard | 8122 | linkType: hard |
8122 | 8123 | ||
@@ -8197,23 +8198,23 @@ __metadata: | |||
8197 | languageName: node | 8198 | languageName: node |
8198 | linkType: hard | 8199 | linkType: hard |
8199 | 8200 | ||
8200 | "typescript@npm:5.3.2": | 8201 | "typescript@npm:5.3.3": |
8201 | version: 5.3.2 | 8202 | version: 5.3.3 |
8202 | resolution: "typescript@npm:5.3.2" | 8203 | resolution: "typescript@npm:5.3.3" |
8203 | bin: | 8204 | bin: |
8204 | tsc: bin/tsc | 8205 | tsc: bin/tsc |
8205 | tsserver: bin/tsserver | 8206 | tsserver: bin/tsserver |
8206 | checksum: d7dbe1fbe19039e36a65468ea64b5d338c976550394ba576b7af9c68ed40c0bc5d12ecce390e4b94b287a09a71bd3229f19c2d5680611f35b7c53a3898791159 | 8207 | checksum: e33cef99d82573624fc0f854a2980322714986bc35b9cb4d1ce736ed182aeab78e2cb32b385efa493b2a976ef52c53e20d6c6918312353a91850e2b76f1ea44f |
8207 | languageName: node | 8208 | languageName: node |
8208 | linkType: hard | 8209 | linkType: hard |
8209 | 8210 | ||
8210 | "typescript@patch:typescript@npm%3A5.3.2#optional!builtin<compat/typescript>": | 8211 | "typescript@patch:typescript@npm%3A5.3.3#optional!builtin<compat/typescript>": |
8211 | version: 5.3.2 | 8212 | version: 5.3.3 |
8212 | resolution: "typescript@patch:typescript@npm%3A5.3.2#optional!builtin<compat/typescript>::version=5.3.2&hash=e012d7" | 8213 | resolution: "typescript@patch:typescript@npm%3A5.3.3#optional!builtin<compat/typescript>::version=5.3.3&hash=e012d7" |
8213 | bin: | 8214 | bin: |
8214 | tsc: bin/tsc | 8215 | tsc: bin/tsc |
8215 | tsserver: bin/tsserver | 8216 | tsserver: bin/tsserver |
8216 | checksum: 73c8bad74e732d93211c9d77f28b03307e2f5fc6a0afc73f4b783261ab567686a16d6ae958bdaef383a00be1b0b8c8b6741dd6ca3d13af4963fa7e47456d49c7 | 8217 | checksum: 1d0a5f4ce496c42caa9a30e659c467c5686eae15d54b027ee7866744952547f1be1262f2d40de911618c242b510029d51d43ff605dba8fb740ec85ca2d3f9500 |
8217 | languageName: node | 8218 | languageName: node |
8218 | linkType: hard | 8219 | linkType: hard |
8219 | 8220 | ||
@@ -8360,9 +8361,9 @@ __metadata: | |||
8360 | languageName: node | 8361 | languageName: node |
8361 | linkType: hard | 8362 | linkType: hard |
8362 | 8363 | ||
8363 | "vite-plugin-pwa@npm:^0.17.2": | 8364 | "vite-plugin-pwa@npm:^0.17.4": |
8364 | version: 0.17.2 | 8365 | version: 0.17.4 |
8365 | resolution: "vite-plugin-pwa@npm:0.17.2" | 8366 | resolution: "vite-plugin-pwa@npm:0.17.4" |
8366 | dependencies: | 8367 | dependencies: |
8367 | debug: "npm:^4.3.4" | 8368 | debug: "npm:^4.3.4" |
8368 | fast-glob: "npm:^3.3.2" | 8369 | fast-glob: "npm:^3.3.2" |
@@ -8373,17 +8374,17 @@ __metadata: | |||
8373 | vite: ^3.1.0 || ^4.0.0 || ^5.0.0 | 8374 | vite: ^3.1.0 || ^4.0.0 || ^5.0.0 |
8374 | workbox-build: ^7.0.0 | 8375 | workbox-build: ^7.0.0 |
8375 | workbox-window: ^7.0.0 | 8376 | workbox-window: ^7.0.0 |
8376 | checksum: a51ce04ac51df72a26dc84162872b812f5c88bf9683b4a48d1331d9349aa67ebc4602e92e1012a0348777db160142ed921083beccfc9b14bcfe44c88b7f98fb8 | 8377 | checksum: 092da93c53fac8f90028c9412ee647944b59dcd2dbdfabd5c2c4a344dd2e09b1abde66bb8c2dd85022ba0fa68e77f7a8fb67e2659199b4effe549c0d7c46f681 |
8377 | languageName: node | 8378 | languageName: node |
8378 | linkType: hard | 8379 | linkType: hard |
8379 | 8380 | ||
8380 | "vite@npm:^5.0.4": | 8381 | "vite@npm:^5.0.10": |
8381 | version: 5.0.4 | 8382 | version: 5.0.10 |
8382 | resolution: "vite@npm:5.0.4" | 8383 | resolution: "vite@npm:5.0.10" |
8383 | dependencies: | 8384 | dependencies: |
8384 | esbuild: "npm:^0.19.3" | 8385 | esbuild: "npm:^0.19.3" |
8385 | fsevents: "npm:~2.3.3" | 8386 | fsevents: "npm:~2.3.3" |
8386 | postcss: "npm:^8.4.31" | 8387 | postcss: "npm:^8.4.32" |
8387 | rollup: "npm:^4.2.0" | 8388 | rollup: "npm:^4.2.0" |
8388 | peerDependencies: | 8389 | peerDependencies: |
8389 | "@types/node": ^18.0.0 || >=20.0.0 | 8390 | "@types/node": ^18.0.0 || >=20.0.0 |
@@ -8413,7 +8414,7 @@ __metadata: | |||
8413 | optional: true | 8414 | optional: true |
8414 | bin: | 8415 | bin: |
8415 | vite: bin/vite.js | 8416 | vite: bin/vite.js |
8416 | checksum: 67a0df248af042e75b1ecbf20098096df80a1068a832c5c964a20d7c06853e12b7310989c3c273cb88a9a3a37f4bada0a2115018b36df0fc09a6b6dba9a7d5b5 | 8417 | checksum: d666b2760d2a7ea1d0d35f67c042053e562144f80554be4e4dc58e607fd5f62193cd203d73ab2e315df66830d8b9d9a2e3509d0208bdef1b2e92e0a5c364df84 |
8417 | languageName: node | 8418 | languageName: node |
8418 | linkType: hard | 8419 | linkType: hard |
8419 | 8420 | ||