diff options
author | Kristóf Marussy <kristof@marussy.com> | 2024-06-28 18:58:50 +0200 |
---|---|---|
committer | Kristóf Marussy <kristof@marussy.com> | 2024-06-28 18:58:50 +0200 |
commit | 2e8a2f6a80fbd974ad877aeee4ef76b740831311 (patch) | |
tree | 21aa932352a94ca0a811e60e474ab8e57cc84d4d | |
parent | refactor(reasoning): fix Sonar warnings (diff) | |
download | refinery-2e8a2f6a80fbd974ad877aeee4ef76b740831311.tar.gz refinery-2e8a2f6a80fbd974ad877aeee4ef76b740831311.tar.zst refinery-2e8a2f6a80fbd974ad877aeee4ef76b740831311.zip |
refactor: show semantics even if propagation fails
17 files changed, 135 insertions, 78 deletions
diff --git a/subprojects/frontend/src/editor/EditorStore.ts b/subprojects/frontend/src/editor/EditorStore.ts index d0b580ed..c5dd5728 100644 --- a/subprojects/frontend/src/editor/EditorStore.ts +++ b/subprojects/frontend/src/editor/EditorStore.ts | |||
@@ -36,7 +36,7 @@ import { | |||
36 | } from '../utils/fileIO'; | 36 | } from '../utils/fileIO'; |
37 | import getLogger from '../utils/getLogger'; | 37 | import getLogger from '../utils/getLogger'; |
38 | import type XtextClient from '../xtext/XtextClient'; | 38 | import type XtextClient from '../xtext/XtextClient'; |
39 | import type { SemanticsSuccessResult } from '../xtext/xtextServiceResults'; | 39 | import type { SemanticsModelResult } from '../xtext/xtextServiceResults'; |
40 | 40 | ||
41 | import EditorErrors from './EditorErrors'; | 41 | import EditorErrors from './EditorErrors'; |
42 | import GeneratedModelStore from './GeneratedModelStore'; | 42 | import GeneratedModelStore from './GeneratedModelStore'; |
@@ -365,12 +365,11 @@ export default class EditorStore { | |||
365 | } | 365 | } |
366 | } | 366 | } |
367 | 367 | ||
368 | setSemanticsError(semanticsError: string) { | 368 | setSemanticsError(semanticsError: string | undefined) { |
369 | this.semanticsError = semanticsError; | 369 | this.semanticsError = semanticsError; |
370 | } | 370 | } |
371 | 371 | ||
372 | setSemantics(semantics: SemanticsSuccessResult) { | 372 | setSemantics(semantics: SemanticsModelResult) { |
373 | this.semanticsError = undefined; | ||
374 | this.graph.setSemantics(semantics); | 373 | this.graph.setSemantics(semantics); |
375 | } | 374 | } |
376 | 375 | ||
@@ -447,7 +446,7 @@ export default class EditorStore { | |||
447 | 446 | ||
448 | setGeneratedModelSemantics( | 447 | setGeneratedModelSemantics( |
449 | uuid: string, | 448 | uuid: string, |
450 | semantics: SemanticsSuccessResult, | 449 | semantics: SemanticsModelResult, |
451 | ): void { | 450 | ): void { |
452 | this.generatedModels.get(uuid)?.setSemantics(semantics); | 451 | this.generatedModels.get(uuid)?.setSemantics(semantics); |
453 | } | 452 | } |
diff --git a/subprojects/frontend/src/editor/GeneratedModelStore.ts b/subprojects/frontend/src/editor/GeneratedModelStore.ts index 4af49e2c..fb9efbcf 100644 --- a/subprojects/frontend/src/editor/GeneratedModelStore.ts +++ b/subprojects/frontend/src/editor/GeneratedModelStore.ts | |||
@@ -7,7 +7,7 @@ | |||
7 | import { makeAutoObservable } from 'mobx'; | 7 | import { makeAutoObservable } from 'mobx'; |
8 | 8 | ||
9 | import GraphStore from '../graph/GraphStore'; | 9 | import GraphStore from '../graph/GraphStore'; |
10 | import type { SemanticsSuccessResult } from '../xtext/xtextServiceResults'; | 10 | import type { SemanticsModelResult } from '../xtext/xtextServiceResults'; |
11 | 11 | ||
12 | import type EditorStore from './EditorStore'; | 12 | import type EditorStore from './EditorStore'; |
13 | 13 | ||
@@ -48,7 +48,7 @@ export default class GeneratedModelStore { | |||
48 | } | 48 | } |
49 | } | 49 | } |
50 | 50 | ||
51 | setSemantics(semantics: SemanticsSuccessResult): void { | 51 | setSemantics(semantics: SemanticsModelResult): void { |
52 | if (this.running) { | 52 | if (this.running) { |
53 | const name = `${this.editorStore.simpleNameOrFallback}_solution_${this.randomSeed}`; | 53 | const name = `${this.editorStore.simpleNameOrFallback}_solution_${this.randomSeed}`; |
54 | this.graph = new GraphStore(this.editorStore, name); | 54 | this.graph = new GraphStore(this.editorStore, name); |
diff --git a/subprojects/frontend/src/graph/GraphStore.ts b/subprojects/frontend/src/graph/GraphStore.ts index 301b4d86..86ffd802 100644 --- a/subprojects/frontend/src/graph/GraphStore.ts +++ b/subprojects/frontend/src/graph/GraphStore.ts | |||
@@ -9,7 +9,7 @@ import { makeAutoObservable, observable } from 'mobx'; | |||
9 | import type EditorStore from '../editor/EditorStore'; | 9 | import type EditorStore from '../editor/EditorStore'; |
10 | import type { | 10 | import type { |
11 | RelationMetadata, | 11 | RelationMetadata, |
12 | SemanticsSuccessResult, | 12 | SemanticsModelResult, |
13 | } from '../xtext/xtextServiceResults'; | 13 | } from '../xtext/xtextServiceResults'; |
14 | 14 | ||
15 | export type Visibility = 'all' | 'must' | 'none'; | 15 | export type Visibility = 'all' | 'must' | 'none'; |
@@ -52,7 +52,7 @@ export function isVisibilityAllowed( | |||
52 | const TYPE_HASH_HEX_PREFFIX = '_'; | 52 | const TYPE_HASH_HEX_PREFFIX = '_'; |
53 | 53 | ||
54 | export default class GraphStore { | 54 | export default class GraphStore { |
55 | semantics: SemanticsSuccessResult = { | 55 | semantics: SemanticsModelResult = { |
56 | nodes: [], | 56 | nodes: [], |
57 | relations: [], | 57 | relations: [], |
58 | partialInterpretation: {}, | 58 | partialInterpretation: {}, |
@@ -175,7 +175,7 @@ export default class GraphStore { | |||
175 | } | 175 | } |
176 | } | 176 | } |
177 | 177 | ||
178 | setSemantics(semantics: SemanticsSuccessResult) { | 178 | setSemantics(semantics: SemanticsModelResult) { |
179 | this.semantics = semantics; | 179 | this.semantics = semantics; |
180 | this.relationMetadata.clear(); | 180 | this.relationMetadata.clear(); |
181 | this.semantics.relations.forEach((metadata) => { | 181 | this.semantics.relations.forEach((metadata) => { |
diff --git a/subprojects/frontend/src/xtext/SemanticsService.ts b/subprojects/frontend/src/xtext/SemanticsService.ts index d68b87a9..b6692f2b 100644 --- a/subprojects/frontend/src/xtext/SemanticsService.ts +++ b/subprojects/frontend/src/xtext/SemanticsService.ts | |||
@@ -1,9 +1,11 @@ | |||
1 | /* | 1 | /* |
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | 2 | * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors <https://refinery.tools/> |
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
6 | 6 | ||
7 | import { runInAction } from 'mobx'; | ||
8 | |||
7 | import type EditorStore from '../editor/EditorStore'; | 9 | import type EditorStore from '../editor/EditorStore'; |
8 | 10 | ||
9 | import type ValidationService from './ValidationService'; | 11 | import type ValidationService from './ValidationService'; |
@@ -17,16 +19,21 @@ export default class SemanticsService { | |||
17 | 19 | ||
18 | onPush(push: unknown): void { | 20 | onPush(push: unknown): void { |
19 | const result = SemanticsResult.parse(push); | 21 | const result = SemanticsResult.parse(push); |
20 | if ('issues' in result) { | 22 | runInAction(() => { |
21 | this.validationService.setSemanticsIssues(result.issues); | 23 | if ('issues' in result && result.issues !== undefined) { |
22 | } else { | 24 | this.validationService.setSemanticsIssues(result.issues); |
23 | this.validationService.setSemanticsIssues([]); | 25 | } else { |
26 | this.validationService.setSemanticsIssues([]); | ||
27 | } | ||
24 | if ('error' in result) { | 28 | if ('error' in result) { |
25 | this.store.setSemanticsError(result.error); | 29 | this.store.setSemanticsError(result.error); |
26 | } else { | 30 | } else { |
27 | this.store.setSemantics(result); | 31 | this.store.setSemanticsError(undefined); |
32 | } | ||
33 | if ('model' in result && result.model !== undefined) { | ||
34 | this.store.setSemantics(result.model); | ||
28 | } | 35 | } |
29 | } | 36 | this.store.analysisCompleted(); |
30 | this.store.analysisCompleted(); | 37 | }); |
31 | } | 38 | } |
32 | } | 39 | } |
diff --git a/subprojects/frontend/src/xtext/xtextServiceResults.ts b/subprojects/frontend/src/xtext/xtextServiceResults.ts index 792c7de3..c5bc1320 100644 --- a/subprojects/frontend/src/xtext/xtextServiceResults.ts +++ b/subprojects/frontend/src/xtext/xtextServiceResults.ts | |||
@@ -162,7 +162,7 @@ export const RelationMetadata = z.object({ | |||
162 | 162 | ||
163 | export type RelationMetadata = z.infer<typeof RelationMetadata>; | 163 | export type RelationMetadata = z.infer<typeof RelationMetadata>; |
164 | 164 | ||
165 | export const SemanticsSuccessResult = z.object({ | 165 | export const SemanticsModelResult = z.object({ |
166 | nodes: NodeMetadata.array(), | 166 | nodes: NodeMetadata.array(), |
167 | relations: RelationMetadata.array(), | 167 | relations: RelationMetadata.array(), |
168 | partialInterpretation: z.record( | 168 | partialInterpretation: z.record( |
@@ -171,13 +171,13 @@ export const SemanticsSuccessResult = z.object({ | |||
171 | ), | 171 | ), |
172 | }); | 172 | }); |
173 | 173 | ||
174 | export type SemanticsSuccessResult = z.infer<typeof SemanticsSuccessResult>; | 174 | export type SemanticsModelResult = z.infer<typeof SemanticsModelResult>; |
175 | 175 | ||
176 | export const SemanticsResult = z.union([ | 176 | export const SemanticsResult = z.object({ |
177 | z.object({ error: z.string() }), | 177 | model: SemanticsModelResult.optional(), |
178 | z.object({ issues: Issue.array() }), | 178 | error: z.string().min(1).optional(), |
179 | SemanticsSuccessResult, | 179 | issues: Issue.array().optional(), |
180 | ]); | 180 | }); |
181 | 181 | ||
182 | export type SemanticsResult = z.infer<typeof SemanticsResult>; | 182 | export type SemanticsResult = z.infer<typeof SemanticsResult>; |
183 | 183 | ||
@@ -190,7 +190,7 @@ export const ModelGenerationResult = z.union([ | |||
190 | uuid: z.string().min(1), | 190 | uuid: z.string().min(1), |
191 | error: z.string(), | 191 | error: z.string(), |
192 | }), | 192 | }), |
193 | SemanticsSuccessResult.extend({ | 193 | SemanticsModelResult.extend({ |
194 | uuid: z.string().min(1), | 194 | uuid: z.string().min(1), |
195 | }), | 195 | }), |
196 | ]); | 196 | ]); |
diff --git a/subprojects/generator/src/main/java/tools/refinery/generator/ModelFacade.java b/subprojects/generator/src/main/java/tools/refinery/generator/ModelFacade.java index eaf60082..459503cd 100644 --- a/subprojects/generator/src/main/java/tools/refinery/generator/ModelFacade.java +++ b/subprojects/generator/src/main/java/tools/refinery/generator/ModelFacade.java | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> | 2 | * SPDX-FileCopyrightText: 2023-2024 The Refinery Authors <https://refinery.tools/> |
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
@@ -15,11 +15,13 @@ import tools.refinery.store.reasoning.interpretation.PartialInterpretation; | |||
15 | import tools.refinery.store.reasoning.literal.Concreteness; | 15 | import tools.refinery.store.reasoning.literal.Concreteness; |
16 | import tools.refinery.store.reasoning.representation.PartialSymbol; | 16 | import tools.refinery.store.reasoning.representation.PartialSymbol; |
17 | import tools.refinery.store.reasoning.seed.ModelSeed; | 17 | import tools.refinery.store.reasoning.seed.ModelSeed; |
18 | import tools.refinery.store.reasoning.seed.PropagatedModel; | ||
18 | import tools.refinery.store.reasoning.translator.TranslationException; | 19 | import tools.refinery.store.reasoning.translator.TranslationException; |
19 | 20 | ||
20 | public abstract class ModelFacade { | 21 | public abstract class ModelFacade { |
21 | private final ProblemTrace problemTrace; | 22 | private final ProblemTrace problemTrace; |
22 | private final ModelStore store; | 23 | private final ModelStore store; |
24 | private final PropagatedModel propagatedModel; | ||
23 | private final Model model; | 25 | private final Model model; |
24 | private final ReasoningAdapter reasoningAdapter; | 26 | private final ReasoningAdapter reasoningAdapter; |
25 | private final Concreteness concreteness; | 27 | private final Concreteness concreteness; |
@@ -29,10 +31,11 @@ public abstract class ModelFacade { | |||
29 | this.problemTrace = problemTrace; | 31 | this.problemTrace = problemTrace; |
30 | this.store = store; | 32 | this.store = store; |
31 | try { | 33 | try { |
32 | model = store.getAdapter(ReasoningStoreAdapter.class).createInitialModel(modelSeed); | 34 | propagatedModel = store.getAdapter(ReasoningStoreAdapter.class).tryCreateInitialModel(modelSeed); |
33 | } catch (TranslationException e) { | 35 | } catch (TranslationException e) { |
34 | throw problemTrace.wrapException(e); | 36 | throw problemTrace.wrapException(e); |
35 | } | 37 | } |
38 | model = propagatedModel.model(); | ||
36 | reasoningAdapter = model.getAdapter(ReasoningAdapter.class); | 39 | reasoningAdapter = model.getAdapter(ReasoningAdapter.class); |
37 | this.concreteness = concreteness; | 40 | this.concreteness = concreteness; |
38 | } | 41 | } |
@@ -49,6 +52,14 @@ public abstract class ModelFacade { | |||
49 | return model; | 52 | return model; |
50 | } | 53 | } |
51 | 54 | ||
55 | public boolean isRejected() { | ||
56 | return propagatedModel.isRejected(); | ||
57 | } | ||
58 | |||
59 | public void throwIfRejected() { | ||
60 | propagatedModel.throwIfRejected(); | ||
61 | } | ||
62 | |||
52 | public Concreteness getConcreteness() { | 63 | public Concreteness getConcreteness() { |
53 | return concreteness; | 64 | return concreteness; |
54 | } | 65 | } |
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 3bdc1266..1b222204 100644 --- a/subprojects/generator/src/main/java/tools/refinery/generator/ModelGeneratorFactory.java +++ b/subprojects/generator/src/main/java/tools/refinery/generator/ModelGeneratorFactory.java | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> | 2 | * SPDX-FileCopyrightText: 2023-2024 The Refinery Authors <https://refinery.tools/> |
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
@@ -78,8 +78,10 @@ public final class ModelGeneratorFactory { | |||
78 | .requiredInterpretations(getRequiredInterpretations())); | 78 | .requiredInterpretations(getRequiredInterpretations())); |
79 | initializer.configureStoreBuilder(storeBuilder); | 79 | initializer.configureStoreBuilder(storeBuilder); |
80 | var store = storeBuilder.build(); | 80 | var store = storeBuilder.build(); |
81 | return new ModelGenerator(initializer.getProblemTrace(), store, initializer.getModelSeed(), | 81 | var generator = new ModelGenerator(initializer.getProblemTrace(), store, initializer.getModelSeed(), |
82 | solutionSerializerProvider); | 82 | solutionSerializerProvider); |
83 | generator.throwIfRejected(); | ||
84 | return generator; | ||
83 | } | 85 | } |
84 | 86 | ||
85 | private Collection<Concreteness> getRequiredInterpretations() { | 87 | private Collection<Concreteness> getRequiredInterpretations() { |
diff --git a/subprojects/generator/src/main/java/tools/refinery/generator/ModelSemanticsFactory.java b/subprojects/generator/src/main/java/tools/refinery/generator/ModelSemanticsFactory.java index b6263b37..20f404f3 100644 --- a/subprojects/generator/src/main/java/tools/refinery/generator/ModelSemanticsFactory.java +++ b/subprojects/generator/src/main/java/tools/refinery/generator/ModelSemanticsFactory.java | |||
@@ -30,6 +30,12 @@ public final class ModelSemanticsFactory { | |||
30 | } | 30 | } |
31 | 31 | ||
32 | public ModelSemantics createSemantics(Problem problem) { | 32 | public ModelSemantics createSemantics(Problem problem) { |
33 | var semantics = tryCreateSemantics(problem); | ||
34 | semantics.throwIfRejected(); | ||
35 | return semantics; | ||
36 | } | ||
37 | |||
38 | public ModelSemantics tryCreateSemantics(Problem problem) { | ||
33 | var initializer = initializerProvider.get(); | 39 | var initializer = initializerProvider.get(); |
34 | initializer.readProblem(problem); | 40 | initializer.readProblem(problem); |
35 | var storeBuilder = ModelStore.builder() | 41 | var storeBuilder = ModelStore.builder() |
diff --git a/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/SemanticsInternalErrorResult.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/SemanticsInternalErrorResult.java deleted file mode 100644 index ff592e93..00000000 --- a/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/SemanticsInternalErrorResult.java +++ /dev/null | |||
@@ -1,9 +0,0 @@ | |||
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.web.semantics; | ||
7 | |||
8 | public record SemanticsInternalErrorResult(String error) implements SemanticsResult { | ||
9 | } | ||
diff --git a/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/SemanticsIssuesResult.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/SemanticsIssuesResult.java deleted file mode 100644 index 644bd179..00000000 --- a/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/SemanticsIssuesResult.java +++ /dev/null | |||
@@ -1,13 +0,0 @@ | |||
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.web.semantics; | ||
7 | |||
8 | import org.eclipse.xtext.web.server.validation.ValidationResult; | ||
9 | |||
10 | import java.util.List; | ||
11 | |||
12 | public record SemanticsIssuesResult(List<ValidationResult.Issue> issues) implements SemanticsResult { | ||
13 | } | ||
diff --git a/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/SemanticsSuccessResult.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/SemanticsModelResult.java index f26fa2b2..b0ec58c3 100644 --- a/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/SemanticsSuccessResult.java +++ b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/SemanticsModelResult.java | |||
@@ -11,6 +11,7 @@ import tools.refinery.language.web.semantics.metadata.RelationMetadata; | |||
11 | 11 | ||
12 | import java.util.List; | 12 | import java.util.List; |
13 | 13 | ||
14 | public record SemanticsSuccessResult(List<NodeMetadata> nodes, List<RelationMetadata> relations, | 14 | public record SemanticsModelResult(List<NodeMetadata> nodes, List<RelationMetadata> relations, |
15 | JsonObject partialInterpretation) implements SemanticsResult { | 15 | JsonObject partialInterpretation) { |
16 | public static SemanticsModelResult EMPTY = new SemanticsModelResult(List.of(), List.of(), new JsonObject()); | ||
16 | } | 17 | } |
diff --git a/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/SemanticsResult.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/SemanticsResult.java index a2e19a2f..16f25309 100644 --- a/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/SemanticsResult.java +++ b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/SemanticsResult.java | |||
@@ -6,7 +6,25 @@ | |||
6 | package tools.refinery.language.web.semantics; | 6 | package tools.refinery.language.web.semantics; |
7 | 7 | ||
8 | import org.eclipse.xtext.web.server.IServiceResult; | 8 | import org.eclipse.xtext.web.server.IServiceResult; |
9 | import org.eclipse.xtext.web.server.validation.ValidationResult; | ||
9 | 10 | ||
10 | public sealed interface SemanticsResult extends IServiceResult permits SemanticsSuccessResult, | 11 | import java.util.List; |
11 | SemanticsInternalErrorResult, SemanticsIssuesResult { | 12 | |
13 | public record SemanticsResult(SemanticsModelResult model, String error, | ||
14 | List<ValidationResult.Issue> issues) implements IServiceResult { | ||
15 | public SemanticsResult(SemanticsModelResult model) { | ||
16 | this(model, null, List.of()); | ||
17 | } | ||
18 | |||
19 | public SemanticsResult(String error) { | ||
20 | this(null, error, List.of()); | ||
21 | } | ||
22 | |||
23 | public SemanticsResult(SemanticsModelResult model, String error) { | ||
24 | this(model, error, List.of()); | ||
25 | } | ||
26 | |||
27 | public SemanticsResult(List<ValidationResult.Issue> issues) { | ||
28 | this(null, null, issues); | ||
29 | } | ||
12 | } | 30 | } |
diff --git a/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/SemanticsService.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/SemanticsService.java index 331ef84b..f6b723fe 100644 --- a/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/SemanticsService.java +++ b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/SemanticsService.java | |||
@@ -5,7 +5,6 @@ | |||
5 | */ | 5 | */ |
6 | package tools.refinery.language.web.semantics; | 6 | package tools.refinery.language.web.semantics; |
7 | 7 | ||
8 | import com.google.gson.JsonObject; | ||
9 | import com.google.inject.Inject; | 8 | import com.google.inject.Inject; |
10 | import com.google.inject.Provider; | 9 | import com.google.inject.Provider; |
11 | import com.google.inject.Singleton; | 10 | import com.google.inject.Singleton; |
@@ -21,9 +20,11 @@ import org.slf4j.LoggerFactory; | |||
21 | import tools.refinery.language.model.problem.Problem; | 20 | import tools.refinery.language.model.problem.Problem; |
22 | import tools.refinery.language.web.xtext.server.push.PushWebDocument; | 21 | import tools.refinery.language.web.xtext.server.push.PushWebDocument; |
23 | 22 | ||
24 | import java.util.List; | ||
25 | import java.util.Optional; | 23 | import java.util.Optional; |
26 | import java.util.concurrent.*; | 24 | import java.util.concurrent.ExecutionException; |
25 | import java.util.concurrent.ExecutorService; | ||
26 | import java.util.concurrent.TimeUnit; | ||
27 | import java.util.concurrent.TimeoutException; | ||
27 | import java.util.concurrent.atomic.AtomicBoolean; | 28 | import java.util.concurrent.atomic.AtomicBoolean; |
28 | 29 | ||
29 | @Singleton | 30 | @Singleton |
@@ -74,7 +75,7 @@ public class SemanticsService extends AbstractCachedService<SemanticsResult> { | |||
74 | } | 75 | } |
75 | var problem = getProblem(doc); | 76 | var problem = getProblem(doc); |
76 | if (problem == null) { | 77 | if (problem == null) { |
77 | return new SemanticsSuccessResult(List.of(), List.of(), new JsonObject()); | 78 | return new SemanticsResult(SemanticsModelResult.EMPTY); |
78 | } | 79 | } |
79 | var worker = workerProvider.get(); | 80 | var worker = workerProvider.get(); |
80 | worker.setProblem(problem, cancelIndicator); | 81 | worker.setProblem(problem, cancelIndicator); |
@@ -101,14 +102,14 @@ public class SemanticsService extends AbstractCachedService<SemanticsResult> { | |||
101 | if (message == null) { | 102 | if (message == null) { |
102 | message = "Partial interpretation error"; | 103 | message = "Partial interpretation error"; |
103 | } | 104 | } |
104 | return new SemanticsInternalErrorResult(message); | 105 | return new SemanticsResult(message); |
105 | } catch (TimeoutException e) { | 106 | } catch (TimeoutException e) { |
106 | future.cancel(true); | 107 | future.cancel(true); |
107 | if (!warmedUpCurrently) { | 108 | if (!warmedUpCurrently) { |
108 | warmedUp.set(true); | 109 | warmedUp.set(true); |
109 | } | 110 | } |
110 | LOG.trace("Semantics service timeout", e); | 111 | LOG.trace("Semantics service timeout", e); |
111 | return new SemanticsInternalErrorResult("Partial interpretation timed out"); | 112 | return new SemanticsResult("Partial interpretation timed out"); |
112 | } | 113 | } |
113 | if (LOG.isTraceEnabled()) { | 114 | if (LOG.isTraceEnabled()) { |
114 | long end = System.currentTimeMillis(); | 115 | long end = System.currentTimeMillis(); |
@@ -133,7 +134,7 @@ public class SemanticsService extends AbstractCachedService<SemanticsResult> { | |||
133 | if (contents.isEmpty()) { | 134 | if (contents.isEmpty()) { |
134 | return null; | 135 | return null; |
135 | } | 136 | } |
136 | var model = contents.get(0); | 137 | var model = contents.getFirst(); |
137 | if (!(model instanceof Problem problem)) { | 138 | if (!(model instanceof Problem problem)) { |
138 | return null; | 139 | return null; |
139 | } | 140 | } |
diff --git a/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/SemanticsWorker.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/SemanticsWorker.java index fed3c8a3..32791960 100644 --- a/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/SemanticsWorker.java +++ b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/SemanticsWorker.java | |||
@@ -21,6 +21,7 @@ import tools.refinery.language.model.problem.Problem; | |||
21 | import tools.refinery.language.web.semantics.metadata.MetadataCreator; | 21 | import tools.refinery.language.web.semantics.metadata.MetadataCreator; |
22 | import tools.refinery.language.semantics.TracedException; | 22 | import tools.refinery.language.semantics.TracedException; |
23 | import tools.refinery.store.reasoning.literal.Concreteness; | 23 | import tools.refinery.store.reasoning.literal.Concreteness; |
24 | import tools.refinery.store.reasoning.seed.PropagatedModel; | ||
24 | import tools.refinery.store.reasoning.translator.TranslationException; | 25 | import tools.refinery.store.reasoning.translator.TranslationException; |
25 | import tools.refinery.store.util.CancellationToken; | 26 | import tools.refinery.store.util.CancellationToken; |
26 | 27 | ||
@@ -63,9 +64,9 @@ class SemanticsWorker implements Callable<SemanticsResult> { | |||
63 | cancellationToken.checkCancelled(); | 64 | cancellationToken.checkCancelled(); |
64 | ModelSemantics semantics; | 65 | ModelSemantics semantics; |
65 | try { | 66 | try { |
66 | semantics = semanticsFactory.cancellationToken(cancellationToken).createSemantics(problem); | 67 | semantics = semanticsFactory.cancellationToken(cancellationToken).tryCreateSemantics(problem); |
67 | } catch (TranslationException e) { | 68 | } catch (TranslationException e) { |
68 | return new SemanticsInternalErrorResult(e.getMessage()); | 69 | return new SemanticsResult(e.getMessage()); |
69 | } catch (TracedException e) { | 70 | } catch (TracedException e) { |
70 | var cause = e.getCause(); | 71 | var cause = e.getCause(); |
71 | // Suppress the type of the cause exception. | 72 | // Suppress the type of the cause exception. |
@@ -79,12 +80,14 @@ class SemanticsWorker implements Callable<SemanticsResult> { | |||
79 | var relationsMetadata = metadataCreator.getRelationsMetadata(); | 80 | var relationsMetadata = metadataCreator.getRelationsMetadata(); |
80 | cancellationToken.checkCancelled(); | 81 | cancellationToken.checkCancelled(); |
81 | var partialInterpretation = partialInterpretation2Json.getPartialInterpretation(semantics, cancellationToken); | 82 | var partialInterpretation = partialInterpretation2Json.getPartialInterpretation(semantics, cancellationToken); |
82 | return new SemanticsSuccessResult(nodesMetadata, relationsMetadata, partialInterpretation); | 83 | var modelResult = new SemanticsModelResult(nodesMetadata, relationsMetadata, partialInterpretation); |
84 | var error = semantics.isRejected() ? PropagatedModel.PROPAGATION_FAILED_MESSAGE : null; | ||
85 | return new SemanticsResult(modelResult, error); | ||
83 | } | 86 | } |
84 | 87 | ||
85 | private SemanticsResult getTracedErrorResult(EObject sourceElement, String message) { | 88 | private SemanticsResult getTracedErrorResult(EObject sourceElement, String message) { |
86 | if (sourceElement == null || !problem.eResource().equals(sourceElement.eResource())) { | 89 | if (sourceElement == null || !problem.eResource().equals(sourceElement.eResource())) { |
87 | return new SemanticsInternalErrorResult(message); | 90 | return new SemanticsResult(message); |
88 | } | 91 | } |
89 | var diagnostic = new FeatureBasedDiagnostic(Diagnostic.ERROR, message, sourceElement, null, 0, | 92 | var diagnostic = new FeatureBasedDiagnostic(Diagnostic.ERROR, message, sourceElement, null, 0, |
90 | CheckType.EXPENSIVE, DIAGNOSTIC_ID); | 93 | CheckType.EXPENSIVE, DIAGNOSTIC_ID); |
@@ -94,6 +97,6 @@ class SemanticsWorker implements Callable<SemanticsResult> { | |||
94 | .map(issue -> new ValidationResult.Issue(issue.getMessage(), "error", issue.getLineNumber(), | 97 | .map(issue -> new ValidationResult.Issue(issue.getMessage(), "error", issue.getLineNumber(), |
95 | issue.getColumn(), issue.getOffset(), issue.getLength())) | 98 | issue.getColumn(), issue.getOffset(), issue.getLength())) |
96 | .toList(); | 99 | .toList(); |
97 | return new SemanticsIssuesResult(issues); | 100 | return new SemanticsResult(issues); |
98 | } | 101 | } |
99 | } | 102 | } |
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/ReasoningStoreAdapter.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/ReasoningStoreAdapter.java index fe3cc3ea..98883dcf 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/ReasoningStoreAdapter.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/ReasoningStoreAdapter.java | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | 2 | * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors <https://refinery.tools/> |
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
@@ -10,6 +10,7 @@ import tools.refinery.store.model.Model; | |||
10 | import tools.refinery.store.reasoning.literal.Concreteness; | 10 | import tools.refinery.store.reasoning.literal.Concreteness; |
11 | import tools.refinery.store.reasoning.representation.AnyPartialSymbol; | 11 | import tools.refinery.store.reasoning.representation.AnyPartialSymbol; |
12 | import tools.refinery.store.reasoning.seed.ModelSeed; | 12 | import tools.refinery.store.reasoning.seed.ModelSeed; |
13 | import tools.refinery.store.reasoning.seed.PropagatedModel; | ||
13 | 14 | ||
14 | import java.util.Collection; | 15 | import java.util.Collection; |
15 | import java.util.Set; | 16 | import java.util.Set; |
@@ -21,7 +22,13 @@ public interface ReasoningStoreAdapter extends ModelStoreAdapter { | |||
21 | 22 | ||
22 | Set<Concreteness> getSupportedInterpretations(); | 23 | Set<Concreteness> getSupportedInterpretations(); |
23 | 24 | ||
24 | Model createInitialModel(ModelSeed modelSeed); | 25 | default Model createInitialModel(ModelSeed modelSeed) { |
26 | var result = tryCreateInitialModel(modelSeed); | ||
27 | result.throwIfRejected(); | ||
28 | return result.model(); | ||
29 | } | ||
30 | |||
31 | PropagatedModel tryCreateInitialModel(ModelSeed modelSeed); | ||
25 | 32 | ||
26 | @Override | 33 | @Override |
27 | ReasoningAdapter createModelAdapter(Model model); | 34 | ReasoningAdapter createModelAdapter(Model model); |
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/internal/ReasoningStoreAdapterImpl.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/internal/ReasoningStoreAdapterImpl.java index 9ef6fb16..df4b6457 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/internal/ReasoningStoreAdapterImpl.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/internal/ReasoningStoreAdapterImpl.java | |||
@@ -1,11 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | 2 | * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors <https://refinery.tools/> |
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
6 | package tools.refinery.store.reasoning.internal; | 6 | package tools.refinery.store.reasoning.internal; |
7 | 7 | ||
8 | import tools.refinery.store.dse.propagation.PropagationAdapter; | 8 | import tools.refinery.store.dse.propagation.PropagationAdapter; |
9 | import tools.refinery.store.dse.propagation.PropagationResult; | ||
9 | import tools.refinery.store.model.Model; | 10 | import tools.refinery.store.model.Model; |
10 | import tools.refinery.store.model.ModelStore; | 11 | import tools.refinery.store.model.ModelStore; |
11 | import tools.refinery.store.query.ModelQueryAdapter; | 12 | import tools.refinery.store.query.ModelQueryAdapter; |
@@ -17,6 +18,7 @@ import tools.refinery.store.reasoning.refinement.PartialModelInitializer; | |||
17 | import tools.refinery.store.reasoning.refinement.StorageRefiner; | 18 | import tools.refinery.store.reasoning.refinement.StorageRefiner; |
18 | import tools.refinery.store.reasoning.representation.AnyPartialSymbol; | 19 | import tools.refinery.store.reasoning.representation.AnyPartialSymbol; |
19 | import tools.refinery.store.reasoning.seed.ModelSeed; | 20 | import tools.refinery.store.reasoning.seed.ModelSeed; |
21 | import tools.refinery.store.reasoning.seed.PropagatedModel; | ||
20 | import tools.refinery.store.representation.AnySymbol; | 22 | import tools.refinery.store.representation.AnySymbol; |
21 | import tools.refinery.store.representation.Symbol; | 23 | import tools.refinery.store.representation.Symbol; |
22 | import tools.refinery.store.tuple.Tuple; | 24 | import tools.refinery.store.tuple.Tuple; |
@@ -98,19 +100,18 @@ class ReasoningStoreAdapterImpl implements ReasoningStoreAdapter { | |||
98 | return factory.create(typedSymbol, model); | 100 | return factory.create(typedSymbol, model); |
99 | } | 101 | } |
100 | 102 | ||
101 | public Model createInitialModel(ModelSeed modelSeed) { | 103 | @Override |
104 | public PropagatedModel tryCreateInitialModel(ModelSeed modelSeed) { | ||
102 | var model = store.createEmptyModel(); | 105 | var model = store.createEmptyModel(); |
103 | model.getInterpretation(ReasoningAdapterImpl.NODE_COUNT_SYMBOL).put(Tuple.of(), modelSeed.getNodeCount()); | 106 | model.getInterpretation(ReasoningAdapterImpl.NODE_COUNT_SYMBOL).put(Tuple.of(), modelSeed.getNodeCount()); |
104 | for (var initializer : initializers) { | 107 | for (var initializer : initializers) { |
105 | initializer.initialize(model, modelSeed); | 108 | initializer.initialize(model, modelSeed); |
106 | } | 109 | } |
107 | model.tryGetAdapter(PropagationAdapter.class).ifPresent(propagationAdapter -> { | 110 | var propagationResult = model.tryGetAdapter(PropagationAdapter.class) |
108 | if (propagationAdapter.propagate().isRejected()) { | 111 | .map(PropagationAdapter::propagate) |
109 | throw new IllegalArgumentException("Inconsistent initial mode: propagation failed"); | 112 | .orElse(PropagationResult.UNCHANGED); |
110 | } | ||
111 | }); | ||
112 | model.getAdapter(ModelQueryAdapter.class).flushChanges(); | 113 | model.getAdapter(ModelQueryAdapter.class).flushChanges(); |
113 | return model; | 114 | return new PropagatedModel(model, propagationResult); |
114 | } | 115 | } |
115 | 116 | ||
116 | @Override | 117 | @Override |
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/seed/PropagatedModel.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/seed/PropagatedModel.java new file mode 100644 index 00000000..42194a0e --- /dev/null +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/seed/PropagatedModel.java | |||
@@ -0,0 +1,23 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2024 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.reasoning.seed; | ||
7 | |||
8 | import tools.refinery.store.dse.propagation.PropagationResult; | ||
9 | import tools.refinery.store.model.Model; | ||
10 | |||
11 | public record PropagatedModel(Model model, PropagationResult propagationResult) { | ||
12 | public static final String PROPAGATION_FAILED_MESSAGE = "Inconsistent initial model: propagation failed"; | ||
13 | |||
14 | public boolean isRejected() { | ||
15 | return propagationResult.isRejected(); | ||
16 | } | ||
17 | |||
18 | public void throwIfRejected() { | ||
19 | if (isRejected()) { | ||
20 | throw new IllegalArgumentException(PROPAGATION_FAILED_MESSAGE); | ||
21 | } | ||
22 | } | ||
23 | } | ||