aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--subprojects/frontend/src/editor/EditorStore.ts9
-rw-r--r--subprojects/frontend/src/editor/GeneratedModelStore.ts4
-rw-r--r--subprojects/frontend/src/graph/GraphStore.ts6
-rw-r--r--subprojects/frontend/src/xtext/SemanticsService.ts23
-rw-r--r--subprojects/frontend/src/xtext/xtextServiceResults.ts16
-rw-r--r--subprojects/generator/src/main/java/tools/refinery/generator/ModelFacade.java15
-rw-r--r--subprojects/generator/src/main/java/tools/refinery/generator/ModelGeneratorFactory.java6
-rw-r--r--subprojects/generator/src/main/java/tools/refinery/generator/ModelSemanticsFactory.java6
-rw-r--r--subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/SemanticsInternalErrorResult.java9
-rw-r--r--subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/SemanticsIssuesResult.java13
-rw-r--r--subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/SemanticsModelResult.java (renamed from subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/SemanticsSuccessResult.java)5
-rw-r--r--subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/SemanticsResult.java22
-rw-r--r--subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/SemanticsService.java15
-rw-r--r--subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/SemanticsWorker.java13
-rw-r--r--subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/ReasoningStoreAdapter.java11
-rw-r--r--subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/internal/ReasoningStoreAdapterImpl.java17
-rw-r--r--subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/seed/PropagatedModel.java23
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';
37import getLogger from '../utils/getLogger'; 37import getLogger from '../utils/getLogger';
38import type XtextClient from '../xtext/XtextClient'; 38import type XtextClient from '../xtext/XtextClient';
39import type { SemanticsSuccessResult } from '../xtext/xtextServiceResults'; 39import type { SemanticsModelResult } from '../xtext/xtextServiceResults';
40 40
41import EditorErrors from './EditorErrors'; 41import EditorErrors from './EditorErrors';
42import GeneratedModelStore from './GeneratedModelStore'; 42import 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 @@
7import { makeAutoObservable } from 'mobx'; 7import { makeAutoObservable } from 'mobx';
8 8
9import GraphStore from '../graph/GraphStore'; 9import GraphStore from '../graph/GraphStore';
10import type { SemanticsSuccessResult } from '../xtext/xtextServiceResults'; 10import type { SemanticsModelResult } from '../xtext/xtextServiceResults';
11 11
12import type EditorStore from './EditorStore'; 12import 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';
9import type EditorStore from '../editor/EditorStore'; 9import type EditorStore from '../editor/EditorStore';
10import type { 10import type {
11 RelationMetadata, 11 RelationMetadata,
12 SemanticsSuccessResult, 12 SemanticsModelResult,
13} from '../xtext/xtextServiceResults'; 13} from '../xtext/xtextServiceResults';
14 14
15export type Visibility = 'all' | 'must' | 'none'; 15export type Visibility = 'all' | 'must' | 'none';
@@ -52,7 +52,7 @@ export function isVisibilityAllowed(
52const TYPE_HASH_HEX_PREFFIX = '_'; 52const TYPE_HASH_HEX_PREFFIX = '_';
53 53
54export default class GraphStore { 54export 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
7import { runInAction } from 'mobx';
8
7import type EditorStore from '../editor/EditorStore'; 9import type EditorStore from '../editor/EditorStore';
8 10
9import type ValidationService from './ValidationService'; 11import 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
163export type RelationMetadata = z.infer<typeof RelationMetadata>; 163export type RelationMetadata = z.infer<typeof RelationMetadata>;
164 164
165export const SemanticsSuccessResult = z.object({ 165export 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
174export type SemanticsSuccessResult = z.infer<typeof SemanticsSuccessResult>; 174export type SemanticsModelResult = z.infer<typeof SemanticsModelResult>;
175 175
176export const SemanticsResult = z.union([ 176export 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
182export type SemanticsResult = z.infer<typeof SemanticsResult>; 182export 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;
15import tools.refinery.store.reasoning.literal.Concreteness; 15import tools.refinery.store.reasoning.literal.Concreteness;
16import tools.refinery.store.reasoning.representation.PartialSymbol; 16import tools.refinery.store.reasoning.representation.PartialSymbol;
17import tools.refinery.store.reasoning.seed.ModelSeed; 17import tools.refinery.store.reasoning.seed.ModelSeed;
18import tools.refinery.store.reasoning.seed.PropagatedModel;
18import tools.refinery.store.reasoning.translator.TranslationException; 19import tools.refinery.store.reasoning.translator.TranslationException;
19 20
20public abstract class ModelFacade { 21public 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 */
6package tools.refinery.language.web.semantics;
7
8public 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 */
6package tools.refinery.language.web.semantics;
7
8import org.eclipse.xtext.web.server.validation.ValidationResult;
9
10import java.util.List;
11
12public 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
12import java.util.List; 12import java.util.List;
13 13
14public record SemanticsSuccessResult(List<NodeMetadata> nodes, List<RelationMetadata> relations, 14public 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 @@
6package tools.refinery.language.web.semantics; 6package tools.refinery.language.web.semantics;
7 7
8import org.eclipse.xtext.web.server.IServiceResult; 8import org.eclipse.xtext.web.server.IServiceResult;
9import org.eclipse.xtext.web.server.validation.ValidationResult;
9 10
10public sealed interface SemanticsResult extends IServiceResult permits SemanticsSuccessResult, 11import java.util.List;
11 SemanticsInternalErrorResult, SemanticsIssuesResult { 12
13public 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 */
6package tools.refinery.language.web.semantics; 6package tools.refinery.language.web.semantics;
7 7
8import com.google.gson.JsonObject;
9import com.google.inject.Inject; 8import com.google.inject.Inject;
10import com.google.inject.Provider; 9import com.google.inject.Provider;
11import com.google.inject.Singleton; 10import com.google.inject.Singleton;
@@ -21,9 +20,11 @@ import org.slf4j.LoggerFactory;
21import tools.refinery.language.model.problem.Problem; 20import tools.refinery.language.model.problem.Problem;
22import tools.refinery.language.web.xtext.server.push.PushWebDocument; 21import tools.refinery.language.web.xtext.server.push.PushWebDocument;
23 22
24import java.util.List;
25import java.util.Optional; 23import java.util.Optional;
26import java.util.concurrent.*; 24import java.util.concurrent.ExecutionException;
25import java.util.concurrent.ExecutorService;
26import java.util.concurrent.TimeUnit;
27import java.util.concurrent.TimeoutException;
27import java.util.concurrent.atomic.AtomicBoolean; 28import 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;
21import tools.refinery.language.web.semantics.metadata.MetadataCreator; 21import tools.refinery.language.web.semantics.metadata.MetadataCreator;
22import tools.refinery.language.semantics.TracedException; 22import tools.refinery.language.semantics.TracedException;
23import tools.refinery.store.reasoning.literal.Concreteness; 23import tools.refinery.store.reasoning.literal.Concreteness;
24import tools.refinery.store.reasoning.seed.PropagatedModel;
24import tools.refinery.store.reasoning.translator.TranslationException; 25import tools.refinery.store.reasoning.translator.TranslationException;
25import tools.refinery.store.util.CancellationToken; 26import 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;
10import tools.refinery.store.reasoning.literal.Concreteness; 10import tools.refinery.store.reasoning.literal.Concreteness;
11import tools.refinery.store.reasoning.representation.AnyPartialSymbol; 11import tools.refinery.store.reasoning.representation.AnyPartialSymbol;
12import tools.refinery.store.reasoning.seed.ModelSeed; 12import tools.refinery.store.reasoning.seed.ModelSeed;
13import tools.refinery.store.reasoning.seed.PropagatedModel;
13 14
14import java.util.Collection; 15import java.util.Collection;
15import java.util.Set; 16import 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 */
6package tools.refinery.store.reasoning.internal; 6package tools.refinery.store.reasoning.internal;
7 7
8import tools.refinery.store.dse.propagation.PropagationAdapter; 8import tools.refinery.store.dse.propagation.PropagationAdapter;
9import tools.refinery.store.dse.propagation.PropagationResult;
9import tools.refinery.store.model.Model; 10import tools.refinery.store.model.Model;
10import tools.refinery.store.model.ModelStore; 11import tools.refinery.store.model.ModelStore;
11import tools.refinery.store.query.ModelQueryAdapter; 12import tools.refinery.store.query.ModelQueryAdapter;
@@ -17,6 +18,7 @@ import tools.refinery.store.reasoning.refinement.PartialModelInitializer;
17import tools.refinery.store.reasoning.refinement.StorageRefiner; 18import tools.refinery.store.reasoning.refinement.StorageRefiner;
18import tools.refinery.store.reasoning.representation.AnyPartialSymbol; 19import tools.refinery.store.reasoning.representation.AnyPartialSymbol;
19import tools.refinery.store.reasoning.seed.ModelSeed; 20import tools.refinery.store.reasoning.seed.ModelSeed;
21import tools.refinery.store.reasoning.seed.PropagatedModel;
20import tools.refinery.store.representation.AnySymbol; 22import tools.refinery.store.representation.AnySymbol;
21import tools.refinery.store.representation.Symbol; 23import tools.refinery.store.representation.Symbol;
22import tools.refinery.store.tuple.Tuple; 24import 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 */
6package tools.refinery.store.reasoning.seed;
7
8import tools.refinery.store.dse.propagation.PropagationResult;
9import tools.refinery.store.model.Model;
10
11public 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}