diff options
author | Kristóf Marussy <kristof@marussy.com> | 2023-09-11 19:22:26 +0200 |
---|---|---|
committer | Kristóf Marussy <kristof@marussy.com> | 2023-09-11 19:22:26 +0200 |
commit | 4d365b54dad8d066bba2a2b1a05092b4802b9970 (patch) | |
tree | 12e5ae36b0041463ded54e7a69dcdc9f3662794f | |
parent | fix: build failures after integrating generation (diff) | |
download | refinery-4d365b54dad8d066bba2a2b1a05092b4802b9970.tar.gz refinery-4d365b54dad8d066bba2a2b1a05092b4802b9970.tar.zst refinery-4d365b54dad8d066bba2a2b1a05092b4802b9970.zip |
feat: cancellation token for ModelStore
28 files changed, 131 insertions, 153 deletions
diff --git a/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/model/ModelGenerationTest.java b/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/model/ModelGenerationTest.java index ecd5d39c..d756099c 100644 --- a/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/model/ModelGenerationTest.java +++ b/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/model/ModelGenerationTest.java | |||
@@ -209,7 +209,7 @@ class ModelGenerationTest { | |||
209 | error choiceHasNoIncoming(Choice c) <-> | 209 | error choiceHasNoIncoming(Choice c) <-> |
210 | !target(_, c). | 210 | !target(_, c). |
211 | 211 | ||
212 | scope node = 50..60, Region = 5..10, Statechart = 1. | 212 | scope node = 200..210, Region = 10..*, Choice = 1..*, Statechart = 1. |
213 | """); | 213 | """); |
214 | assertThat(parsedProblem.errors(), empty()); | 214 | assertThat(parsedProblem.errors(), empty()); |
215 | var problem = parsedProblem.problem(); | 215 | var problem = parsedProblem.problem(); |
diff --git a/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/CancellableSeed.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/CancellableSeed.java deleted file mode 100644 index aa14f39d..00000000 --- a/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/CancellableSeed.java +++ /dev/null | |||
@@ -1,99 +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 tools.refinery.store.map.AnyVersionedMap; | ||
9 | import tools.refinery.store.map.Cursor; | ||
10 | import tools.refinery.store.reasoning.representation.PartialSymbol; | ||
11 | import tools.refinery.store.reasoning.seed.ModelSeed; | ||
12 | import tools.refinery.store.reasoning.seed.Seed; | ||
13 | import tools.refinery.store.tuple.Tuple; | ||
14 | import tools.refinery.viatra.runtime.CancellationToken; | ||
15 | |||
16 | import java.util.Set; | ||
17 | |||
18 | class CancellableSeed<T> implements Seed<T> { | ||
19 | private final CancellationToken cancellationToken; | ||
20 | private final Seed<T> seed; | ||
21 | |||
22 | private CancellableSeed(CancellationToken cancellationToken, Seed<T> seed) { | ||
23 | this.cancellationToken = cancellationToken; | ||
24 | this.seed = seed; | ||
25 | } | ||
26 | |||
27 | @Override | ||
28 | public int arity() { | ||
29 | return seed.arity(); | ||
30 | } | ||
31 | |||
32 | @Override | ||
33 | public Class<T> valueType() { | ||
34 | return seed.valueType(); | ||
35 | } | ||
36 | |||
37 | @Override | ||
38 | public T reducedValue() { | ||
39 | return seed.reducedValue(); | ||
40 | } | ||
41 | |||
42 | @Override | ||
43 | public T get(Tuple key) { | ||
44 | return seed.get(key); | ||
45 | } | ||
46 | |||
47 | @Override | ||
48 | public Cursor<Tuple, T> getCursor(T defaultValue, int nodeCount) { | ||
49 | return new CancellableCursor<>(cancellationToken, seed.getCursor(defaultValue, nodeCount)); | ||
50 | } | ||
51 | |||
52 | public static ModelSeed wrap(CancellationToken cancellationToken, ModelSeed modelSeed) { | ||
53 | var builder = ModelSeed.builder(modelSeed.getNodeCount()); | ||
54 | for (var partialSymbol : modelSeed.getSeededSymbols()) { | ||
55 | wrap(cancellationToken, (PartialSymbol<?, ?>) partialSymbol, modelSeed, builder); | ||
56 | } | ||
57 | return builder.build(); | ||
58 | } | ||
59 | |||
60 | private static <A, C> void wrap(CancellationToken cancellationToken, PartialSymbol<A, C> partialSymbol, | ||
61 | ModelSeed originalModelSeed, ModelSeed.Builder builder) { | ||
62 | var originalSeed = originalModelSeed.getSeed(partialSymbol); | ||
63 | builder.seed(partialSymbol, new CancellableSeed<>(cancellationToken, originalSeed)); | ||
64 | } | ||
65 | |||
66 | private record CancellableCursor<T>(CancellationToken cancellationToken, Cursor<Tuple, T> cursor) | ||
67 | implements Cursor<Tuple, T> { | ||
68 | @Override | ||
69 | public Tuple getKey() { | ||
70 | return cursor.getKey(); | ||
71 | } | ||
72 | |||
73 | @Override | ||
74 | public T getValue() { | ||
75 | return cursor.getValue(); | ||
76 | } | ||
77 | |||
78 | @Override | ||
79 | public boolean isTerminated() { | ||
80 | return cursor.isTerminated(); | ||
81 | } | ||
82 | |||
83 | @Override | ||
84 | public boolean move() { | ||
85 | cancellationToken.checkCancelled(); | ||
86 | return cursor.move(); | ||
87 | } | ||
88 | |||
89 | @Override | ||
90 | public boolean isDirty() { | ||
91 | return cursor.isDirty(); | ||
92 | } | ||
93 | |||
94 | @Override | ||
95 | public Set<AnyVersionedMap> getDependingMaps() { | ||
96 | return cursor.getDependingMaps(); | ||
97 | } | ||
98 | } | ||
99 | } | ||
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 c745d86e..33b1c4fb 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 | |||
@@ -34,7 +34,7 @@ import tools.refinery.store.reasoning.representation.PartialRelation; | |||
34 | import tools.refinery.store.reasoning.translator.TranslationException; | 34 | import tools.refinery.store.reasoning.translator.TranslationException; |
35 | import tools.refinery.store.reasoning.translator.multiobject.MultiObjectTranslator; | 35 | import tools.refinery.store.reasoning.translator.multiobject.MultiObjectTranslator; |
36 | import tools.refinery.store.tuple.Tuple; | 36 | import tools.refinery.store.tuple.Tuple; |
37 | import tools.refinery.viatra.runtime.CancellationToken; | 37 | import tools.refinery.store.util.CancellationToken; |
38 | 38 | ||
39 | import java.util.ArrayList; | 39 | import java.util.ArrayList; |
40 | import java.util.TreeMap; | 40 | import java.util.TreeMap; |
@@ -74,8 +74,8 @@ class SemanticsWorker implements Callable<SemanticsResult> { | |||
74 | @Override | 74 | @Override |
75 | public SemanticsResult call() { | 75 | public SemanticsResult call() { |
76 | var builder = ModelStore.builder() | 76 | var builder = ModelStore.builder() |
77 | .with(ViatraModelQueryAdapter.builder() | 77 | .cancellationToken(cancellationToken) |
78 | .cancellationToken(cancellationToken)) | 78 | .with(ViatraModelQueryAdapter.builder()) |
79 | .with(PropagationAdapter.builder()) | 79 | .with(PropagationAdapter.builder()) |
80 | .with(ReasoningAdapter.builder() | 80 | .with(ReasoningAdapter.builder() |
81 | .requiredInterpretations(Concreteness.PARTIAL)); | 81 | .requiredInterpretations(Concreteness.PARTIAL)); |
@@ -91,8 +91,7 @@ class SemanticsWorker implements Callable<SemanticsResult> { | |||
91 | cancellationToken.checkCancelled(); | 91 | cancellationToken.checkCancelled(); |
92 | var store = builder.build(); | 92 | var store = builder.build(); |
93 | cancellationToken.checkCancelled(); | 93 | cancellationToken.checkCancelled(); |
94 | var cancellableModelSeed = CancellableSeed.wrap(cancellationToken, modelSeed); | 94 | var model = store.getAdapter(ReasoningStoreAdapter.class).createInitialModel(modelSeed); |
95 | var model = store.getAdapter(ReasoningStoreAdapter.class).createInitialModel(cancellableModelSeed); | ||
96 | cancellationToken.checkCancelled(); | 95 | cancellationToken.checkCancelled(); |
97 | var partialInterpretation = getPartialInterpretation(initializer, model); | 96 | var partialInterpretation = getPartialInterpretation(initializer, model); |
98 | 97 | ||
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/propagation/impl/PropagationAdapterImpl.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/propagation/impl/PropagationAdapterImpl.java index 586a8d7a..fdd19217 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/propagation/impl/PropagationAdapterImpl.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/propagation/impl/PropagationAdapterImpl.java | |||
@@ -31,6 +31,7 @@ class PropagationAdapterImpl implements PropagationAdapter { | |||
31 | PropagationResult result = PropagationResult.UNCHANGED; | 31 | PropagationResult result = PropagationResult.UNCHANGED; |
32 | PropagationResult lastResult; | 32 | PropagationResult lastResult; |
33 | do { | 33 | do { |
34 | model.checkCancelled(); | ||
34 | lastResult = propagateOne(); | 35 | lastResult = propagateOne(); |
35 | result = result.andThen(lastResult); | 36 | result = result.andThen(lastResult); |
36 | } while (lastResult.isChanged()); | 37 | } while (lastResult.isChanged()); |
@@ -40,6 +41,7 @@ class PropagationAdapterImpl implements PropagationAdapter { | |||
40 | private PropagationResult propagateOne() { | 41 | private PropagationResult propagateOne() { |
41 | PropagationResult result = PropagationResult.UNCHANGED; | 42 | PropagationResult result = PropagationResult.UNCHANGED; |
42 | for (int i = 0; i < boundPropagators.length; i++) { | 43 | for (int i = 0; i < boundPropagators.length; i++) { |
44 | model.checkCancelled(); | ||
43 | var lastResult = propagateUntilFixedPoint(i); | 45 | var lastResult = propagateUntilFixedPoint(i); |
44 | result = result.andThen(lastResult); | 46 | result = result.andThen(lastResult); |
45 | if (result.isRejected()) { | 47 | if (result.isRejected()) { |
@@ -54,6 +56,7 @@ class PropagationAdapterImpl implements PropagationAdapter { | |||
54 | PropagationResult result = PropagationResult.UNCHANGED; | 56 | PropagationResult result = PropagationResult.UNCHANGED; |
55 | PropagationResult lastResult; | 57 | PropagationResult lastResult; |
56 | do { | 58 | do { |
59 | model.checkCancelled(); | ||
57 | lastResult = propagator.propagateOne(); | 60 | lastResult = propagator.propagateOne(); |
58 | result = result.andThen(lastResult); | 61 | result = result.andThen(lastResult); |
59 | } while (lastResult.isChanged()); | 62 | } while (lastResult.isChanged()); |
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/propagation/impl/rule/BoundPropagationRule.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/propagation/impl/rule/BoundPropagationRule.java index 6e6a78d2..a70292ad 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/propagation/impl/rule/BoundPropagationRule.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/propagation/impl/rule/BoundPropagationRule.java | |||
@@ -13,10 +13,12 @@ import tools.refinery.store.query.ModelQueryAdapter; | |||
13 | import tools.refinery.store.query.resultset.ResultSet; | 13 | import tools.refinery.store.query.resultset.ResultSet; |
14 | 14 | ||
15 | class BoundPropagationRule { | 15 | class BoundPropagationRule { |
16 | private final Model model; | ||
16 | private final ResultSet<Boolean> resultSet; | 17 | private final ResultSet<Boolean> resultSet; |
17 | private final BoundAction action; | 18 | private final BoundAction action; |
18 | 19 | ||
19 | public BoundPropagationRule(Model model, Rule rule) { | 20 | public BoundPropagationRule(Model model, Rule rule) { |
21 | this.model = model; | ||
20 | resultSet = model.getAdapter(ModelQueryAdapter.class).getResultSet(rule.getPrecondition()); | 22 | resultSet = model.getAdapter(ModelQueryAdapter.class).getResultSet(rule.getPrecondition()); |
21 | action = rule.createAction(model); | 23 | action = rule.createAction(model); |
22 | } | 24 | } |
@@ -27,6 +29,7 @@ class BoundPropagationRule { | |||
27 | } | 29 | } |
28 | var cursor = resultSet.getAll(); | 30 | var cursor = resultSet.getAll(); |
29 | while (cursor.move()) { | 31 | while (cursor.move()) { |
32 | model.checkCancelled(); | ||
30 | var result = action.fire(cursor.getKey()); | 33 | var result = action.fire(cursor.getKey()); |
31 | if (!result) { | 34 | if (!result) { |
32 | return PropagationResult.REJECTED; | 35 | return PropagationResult.REJECTED; |
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 4a75a3a6..5e2f8fa9 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 | |||
@@ -19,14 +19,9 @@ public class BestFirstExplorer extends BestFirstWorker { | |||
19 | this.random = new Random(id); | 19 | this.random = new Random(id); |
20 | } | 20 | } |
21 | 21 | ||
22 | private boolean interrupted = false; | ||
23 | |||
24 | public void interrupt() { | ||
25 | this.interrupted = true; | ||
26 | } | ||
27 | |||
28 | private boolean shouldRun() { | 22 | private boolean shouldRun() { |
29 | return !interrupted && !hasEnoughSolution(); | 23 | model.checkCancelled(); |
24 | return !hasEnoughSolution(); | ||
30 | } | 25 | } |
31 | 26 | ||
32 | public void explore() { | 27 | public void explore() { |
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/BoundAction.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/BoundAction.java index ed2ff33d..4da609fa 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/BoundAction.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/BoundAction.java | |||
@@ -23,6 +23,7 @@ public class BoundAction { | |||
23 | } | 23 | } |
24 | 24 | ||
25 | public boolean fire(Tuple activation) { | 25 | public boolean fire(Tuple activation) { |
26 | model.checkCancelled(); | ||
26 | if (this.activation != null) { | 27 | if (this.activation != null) { |
27 | throw new IllegalStateException("Reentrant firing is not allowed"); | 28 | throw new IllegalStateException("Reentrant firing is not allowed"); |
28 | } | 29 | } |
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/internal/DesignSpaceExplorationAdapterImpl.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/internal/DesignSpaceExplorationAdapterImpl.java index e1a29d40..23325a1f 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/internal/DesignSpaceExplorationAdapterImpl.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/internal/DesignSpaceExplorationAdapterImpl.java | |||
@@ -56,6 +56,7 @@ public class DesignSpaceExplorationAdapterImpl implements DesignSpaceExploration | |||
56 | @Override | 56 | @Override |
57 | public boolean checkAccept() { | 57 | public boolean checkAccept() { |
58 | for (var accept : this.accepts) { | 58 | for (var accept : this.accepts) { |
59 | model.checkCancelled(); | ||
59 | if (!accept.isSatisfied()) { | 60 | if (!accept.isSatisfied()) { |
60 | return false; | 61 | return false; |
61 | } | 62 | } |
@@ -66,6 +67,7 @@ public class DesignSpaceExplorationAdapterImpl implements DesignSpaceExploration | |||
66 | @Override | 67 | @Override |
67 | public boolean checkExclude() { | 68 | public boolean checkExclude() { |
68 | for (var exclude : this.excludes) { | 69 | for (var exclude : this.excludes) { |
70 | model.checkCancelled(); | ||
69 | if (exclude.isSatisfied()) { | 71 | if (exclude.isSatisfied()) { |
70 | return true; | 72 | return true; |
71 | } | 73 | } |
@@ -75,6 +77,7 @@ public class DesignSpaceExplorationAdapterImpl implements DesignSpaceExploration | |||
75 | 77 | ||
76 | @Override | 78 | @Override |
77 | public ObjectiveValue getObjectiveValue() { | 79 | public ObjectiveValue getObjectiveValue() { |
80 | model.checkCancelled(); | ||
78 | if (objectives.size() == 1) { | 81 | if (objectives.size() == 1) { |
79 | return ObjectiveValue.of(objectives.get(0).getValue()); | 82 | return ObjectiveValue.of(objectives.get(0).getValue()); |
80 | } else if (objectives.size() == 2) { | 83 | } else if (objectives.size() == 2) { |
@@ -82,6 +85,7 @@ public class DesignSpaceExplorationAdapterImpl implements DesignSpaceExploration | |||
82 | } else { | 85 | } else { |
83 | double[] res = new double[objectives.size()]; | 86 | double[] res = new double[objectives.size()]; |
84 | for (int i = 0; i < objectives.size(); i++) { | 87 | for (int i = 0; i < objectives.size(); i++) { |
88 | model.checkCancelled(); | ||
85 | res[i] = objectives.get(i).getValue(); | 89 | res[i] = objectives.get(i).getValue(); |
86 | } | 90 | } |
87 | return ObjectiveValue.of(res); | 91 | return ObjectiveValue.of(res); |
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/ViatraModelQueryBuilder.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/ViatraModelQueryBuilder.java index 6b3be115..d19c3bb4 100644 --- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/ViatraModelQueryBuilder.java +++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/ViatraModelQueryBuilder.java | |||
@@ -10,7 +10,6 @@ import tools.refinery.store.query.ModelQueryBuilder; | |||
10 | import tools.refinery.store.query.dnf.AnyQuery; | 10 | import tools.refinery.store.query.dnf.AnyQuery; |
11 | import tools.refinery.store.query.dnf.Dnf; | 11 | import tools.refinery.store.query.dnf.Dnf; |
12 | import tools.refinery.store.query.rewriter.DnfRewriter; | 12 | import tools.refinery.store.query.rewriter.DnfRewriter; |
13 | import tools.refinery.viatra.runtime.CancellationToken; | ||
14 | import tools.refinery.viatra.runtime.api.ViatraQueryEngineOptions; | 13 | import tools.refinery.viatra.runtime.api.ViatraQueryEngineOptions; |
15 | import tools.refinery.viatra.runtime.matchers.backend.IQueryBackendFactory; | 14 | import tools.refinery.viatra.runtime.matchers.backend.IQueryBackendFactory; |
16 | import tools.refinery.viatra.runtime.matchers.backend.QueryEvaluationHint; | 15 | import tools.refinery.viatra.runtime.matchers.backend.QueryEvaluationHint; |
@@ -30,8 +29,6 @@ public interface ViatraModelQueryBuilder extends ModelQueryBuilder { | |||
30 | 29 | ||
31 | ViatraModelQueryBuilder searchBackend(IQueryBackendFactory queryBackendFactory); | 30 | ViatraModelQueryBuilder searchBackend(IQueryBackendFactory queryBackendFactory); |
32 | 31 | ||
33 | ViatraModelQueryBuilder cancellationToken(CancellationToken cancellationToken); | ||
34 | |||
35 | @Override | 32 | @Override |
36 | default ViatraModelQueryBuilder queries(AnyQuery... queries) { | 33 | default ViatraModelQueryBuilder queries(AnyQuery... queries) { |
37 | ModelQueryBuilder.super.queries(queries); | 34 | ModelQueryBuilder.super.queries(queries); |
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/ViatraModelQueryBuilderImpl.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/ViatraModelQueryBuilderImpl.java index bb0630f3..c68152e3 100644 --- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/ViatraModelQueryBuilderImpl.java +++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/ViatraModelQueryBuilderImpl.java | |||
@@ -17,7 +17,6 @@ import tools.refinery.store.query.viatra.ViatraModelQueryBuilder; | |||
17 | import tools.refinery.store.query.viatra.internal.localsearch.FlatCostFunction; | 17 | import tools.refinery.store.query.viatra.internal.localsearch.FlatCostFunction; |
18 | import tools.refinery.store.query.viatra.internal.matcher.RawPatternMatcher; | 18 | import tools.refinery.store.query.viatra.internal.matcher.RawPatternMatcher; |
19 | import tools.refinery.store.query.viatra.internal.pquery.Dnf2PQuery; | 19 | import tools.refinery.store.query.viatra.internal.pquery.Dnf2PQuery; |
20 | import tools.refinery.viatra.runtime.CancellationToken; | ||
21 | import tools.refinery.viatra.runtime.api.IQuerySpecification; | 20 | import tools.refinery.viatra.runtime.api.IQuerySpecification; |
22 | import tools.refinery.viatra.runtime.api.ViatraQueryEngineOptions; | 21 | import tools.refinery.viatra.runtime.api.ViatraQueryEngineOptions; |
23 | import tools.refinery.viatra.runtime.localsearch.matcher.integration.LocalSearchGenericBackendFactory; | 22 | import tools.refinery.viatra.runtime.localsearch.matcher.integration.LocalSearchGenericBackendFactory; |
@@ -36,7 +35,6 @@ public class ViatraModelQueryBuilderImpl extends AbstractModelAdapterBuilder<Via | |||
36 | // Use a cost function that ignores the initial (empty) model but allows higher arity input keys. | 35 | // Use a cost function that ignores the initial (empty) model but allows higher arity input keys. |
37 | LocalSearchHintOptions.PLANNER_COST_FUNCTION, new FlatCostFunction() | 36 | LocalSearchHintOptions.PLANNER_COST_FUNCTION, new FlatCostFunction() |
38 | ), (IQueryBackendFactory) null); | 37 | ), (IQueryBackendFactory) null); |
39 | private CancellationToken cancellationToken = CancellationToken.NONE; | ||
40 | private final CompositeRewriter rewriter; | 38 | private final CompositeRewriter rewriter; |
41 | private final Dnf2PQuery dnf2PQuery = new Dnf2PQuery(); | 39 | private final Dnf2PQuery dnf2PQuery = new Dnf2PQuery(); |
42 | private final Set<AnyQuery> queries = new LinkedHashSet<>(); | 40 | private final Set<AnyQuery> queries = new LinkedHashSet<>(); |
@@ -87,12 +85,6 @@ public class ViatraModelQueryBuilderImpl extends AbstractModelAdapterBuilder<Via | |||
87 | } | 85 | } |
88 | 86 | ||
89 | @Override | 87 | @Override |
90 | public ViatraModelQueryBuilder cancellationToken(CancellationToken cancellationToken) { | ||
91 | this.cancellationToken = cancellationToken; | ||
92 | return this; | ||
93 | } | ||
94 | |||
95 | @Override | ||
96 | public ViatraModelQueryBuilder queries(Collection<? extends AnyQuery> queries) { | 88 | public ViatraModelQueryBuilder queries(Collection<? extends AnyQuery> queries) { |
97 | checkNotConfigured(); | 89 | checkNotConfigured(); |
98 | this.queries.addAll(queries); | 90 | this.queries.addAll(queries); |
@@ -144,7 +136,7 @@ public class ViatraModelQueryBuilderImpl extends AbstractModelAdapterBuilder<Via | |||
144 | validateSymbols(store); | 136 | validateSymbols(store); |
145 | return new ViatraModelQueryStoreAdapterImpl(store, buildEngineOptions(), dnf2PQuery.getSymbolViews(), | 137 | return new ViatraModelQueryStoreAdapterImpl(store, buildEngineOptions(), dnf2PQuery.getSymbolViews(), |
146 | Collections.unmodifiableMap(canonicalQueryMap), Collections.unmodifiableMap(querySpecifications), | 138 | Collections.unmodifiableMap(canonicalQueryMap), Collections.unmodifiableMap(querySpecifications), |
147 | Collections.unmodifiableSet(vacuousQueries), cancellationToken); | 139 | Collections.unmodifiableSet(vacuousQueries), store::checkCancelled); |
148 | } | 140 | } |
149 | 141 | ||
150 | private ViatraQueryEngineOptions buildEngineOptions() { | 142 | private ViatraQueryEngineOptions buildEngineOptions() { |
diff --git a/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/BoundScopePropagator.java b/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/BoundScopePropagator.java index 62aadb4a..3ae4d84b 100644 --- a/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/BoundScopePropagator.java +++ b/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/BoundScopePropagator.java | |||
@@ -22,6 +22,7 @@ import tools.refinery.store.representation.cardinality.*; | |||
22 | import tools.refinery.store.tuple.Tuple; | 22 | import tools.refinery.store.tuple.Tuple; |
23 | 23 | ||
24 | class BoundScopePropagator implements BoundPropagator { | 24 | class BoundScopePropagator implements BoundPropagator { |
25 | private final Model model; | ||
25 | private final ModelQueryAdapter queryEngine; | 26 | private final ModelQueryAdapter queryEngine; |
26 | private final Interpretation<CardinalityInterval> countInterpretation; | 27 | private final Interpretation<CardinalityInterval> countInterpretation; |
27 | private final MPSolver solver; | 28 | private final MPSolver solver; |
@@ -32,6 +33,7 @@ class BoundScopePropagator implements BoundPropagator { | |||
32 | private boolean changed = true; | 33 | private boolean changed = true; |
33 | 34 | ||
34 | public BoundScopePropagator(Model model, ScopePropagator storeAdapter) { | 35 | public BoundScopePropagator(Model model, ScopePropagator storeAdapter) { |
36 | this.model = model; | ||
35 | queryEngine = model.getAdapter(ModelQueryAdapter.class); | 37 | queryEngine = model.getAdapter(ModelQueryAdapter.class); |
36 | countInterpretation = model.getInterpretation(storeAdapter.getCountSymbol()); | 38 | countInterpretation = model.getInterpretation(storeAdapter.getCountSymbol()); |
37 | solver = MPSolver.createSolver("GLOP"); | 39 | solver = MPSolver.createSolver("GLOP"); |
@@ -41,6 +43,7 @@ class BoundScopePropagator implements BoundPropagator { | |||
41 | var propagatorFactories = storeAdapter.getTypeScopePropagatorFactories(); | 43 | var propagatorFactories = storeAdapter.getTypeScopePropagatorFactories(); |
42 | propagators = new TypeScopePropagator[propagatorFactories.size()]; | 44 | propagators = new TypeScopePropagator[propagatorFactories.size()]; |
43 | for (int i = 0; i < propagators.length; i++) { | 45 | for (int i = 0; i < propagators.length; i++) { |
46 | model.checkCancelled(); | ||
44 | propagators[i] = propagatorFactories.get(i).createPropagator(this); | 47 | propagators[i] = propagatorFactories.get(i).createPropagator(this); |
45 | } | 48 | } |
46 | } | 49 | } |
@@ -145,6 +148,7 @@ class BoundScopePropagator implements BoundPropagator { | |||
145 | } | 148 | } |
146 | changed = false; | 149 | changed = false; |
147 | for (var propagator : propagators) { | 150 | for (var propagator : propagators) { |
151 | model.checkCancelled(); | ||
148 | propagator.updateBounds(); | 152 | propagator.updateBounds(); |
149 | } | 153 | } |
150 | var result = PropagationResult.UNCHANGED; | 154 | var result = PropagationResult.UNCHANGED; |
@@ -167,6 +171,7 @@ class BoundScopePropagator implements BoundPropagator { | |||
167 | } | 171 | } |
168 | 172 | ||
169 | private PropagationResult checkEmptiness() { | 173 | private PropagationResult checkEmptiness() { |
174 | model.checkCancelled(); | ||
170 | var emptinessCheckingResult = solver.solve(); | 175 | var emptinessCheckingResult = solver.solve(); |
171 | return switch (emptinessCheckingResult) { | 176 | return switch (emptinessCheckingResult) { |
172 | case OPTIMAL, UNBOUNDED -> PropagationResult.UNCHANGED; | 177 | case OPTIMAL, UNBOUNDED -> PropagationResult.UNCHANGED; |
@@ -178,6 +183,7 @@ class BoundScopePropagator implements BoundPropagator { | |||
178 | private PropagationResult propagateNode(int nodeId, MPVariable variable) { | 183 | private PropagationResult propagateNode(int nodeId, MPVariable variable) { |
179 | objective.setCoefficient(variable, 1); | 184 | objective.setCoefficient(variable, 1); |
180 | try { | 185 | try { |
186 | model.checkCancelled(); | ||
181 | objective.setMinimization(); | 187 | objective.setMinimization(); |
182 | var minimizationResult = solver.solve(); | 188 | var minimizationResult = solver.solve(); |
183 | int lowerBound; | 189 | int lowerBound; |
@@ -191,6 +197,7 @@ class BoundScopePropagator implements BoundPropagator { | |||
191 | .formatted(variable, minimizationResult)); | 197 | .formatted(variable, minimizationResult)); |
192 | } | 198 | } |
193 | 199 | ||
200 | model.checkCancelled(); | ||
194 | objective.setMaximization(); | 201 | objective.setMaximization(); |
195 | var maximizationResult = solver.solve(); | 202 | var maximizationResult = solver.solve(); |
196 | UpperCardinality upperBound; | 203 | UpperCardinality upperBound; |
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/MultiObjectInitializer.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/MultiObjectInitializer.java index f11ab46b..89918155 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/MultiObjectInitializer.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/MultiObjectInitializer.java | |||
@@ -30,9 +30,9 @@ class MultiObjectInitializer implements PartialModelInitializer { | |||
30 | 30 | ||
31 | @Override | 31 | @Override |
32 | public void initialize(Model model, ModelSeed modelSeed) { | 32 | public void initialize(Model model, ModelSeed modelSeed) { |
33 | var intervals = initializeIntervals(modelSeed); | 33 | var intervals = initializeIntervals(model, modelSeed); |
34 | initializeExists(intervals, modelSeed); | 34 | initializeExists(intervals, model, modelSeed); |
35 | initializeEquals(intervals, modelSeed); | 35 | initializeEquals(intervals, model, modelSeed); |
36 | var countInterpretation = model.getInterpretation(countSymbol); | 36 | var countInterpretation = model.getInterpretation(countSymbol); |
37 | var uniqueTable = new HashMap<CardinalityInterval, CardinalityInterval>(); | 37 | var uniqueTable = new HashMap<CardinalityInterval, CardinalityInterval>(); |
38 | for (int i = 0; i < intervals.length; i++) { | 38 | for (int i = 0; i < intervals.length; i++) { |
@@ -47,12 +47,13 @@ class MultiObjectInitializer implements PartialModelInitializer { | |||
47 | } | 47 | } |
48 | 48 | ||
49 | @NotNull | 49 | @NotNull |
50 | private CardinalityInterval[] initializeIntervals(ModelSeed modelSeed) { | 50 | private CardinalityInterval[] initializeIntervals(Model model, ModelSeed modelSeed) { |
51 | var intervals = new CardinalityInterval[modelSeed.getNodeCount()]; | 51 | var intervals = new CardinalityInterval[modelSeed.getNodeCount()]; |
52 | if (modelSeed.containsSeed(MultiObjectTranslator.COUNT_SYMBOL)) { | 52 | if (modelSeed.containsSeed(MultiObjectTranslator.COUNT_SYMBOL)) { |
53 | Arrays.fill(intervals, CardinalityIntervals.ONE); | 53 | Arrays.fill(intervals, CardinalityIntervals.ONE); |
54 | var cursor = modelSeed.getCursor(MultiObjectTranslator.COUNT_SYMBOL, CardinalityIntervals.ONE); | 54 | var cursor = modelSeed.getCursor(MultiObjectTranslator.COUNT_SYMBOL, CardinalityIntervals.ONE); |
55 | while (cursor.move()) { | 55 | while (cursor.move()) { |
56 | model.checkCancelled(); | ||
56 | int i = cursor.getKey().get(0); | 57 | int i = cursor.getKey().get(0); |
57 | checkNodeId(intervals, i); | 58 | checkNodeId(intervals, i); |
58 | intervals[i] = cursor.getValue(); | 59 | intervals[i] = cursor.getValue(); |
@@ -70,12 +71,13 @@ class MultiObjectInitializer implements PartialModelInitializer { | |||
70 | return intervals; | 71 | return intervals; |
71 | } | 72 | } |
72 | 73 | ||
73 | private void initializeExists(CardinalityInterval[] intervals, ModelSeed modelSeed) { | 74 | private void initializeExists(CardinalityInterval[] intervals, Model model, ModelSeed modelSeed) { |
74 | if (!modelSeed.containsSeed(ReasoningAdapter.EXISTS_SYMBOL)) { | 75 | if (!modelSeed.containsSeed(ReasoningAdapter.EXISTS_SYMBOL)) { |
75 | return; | 76 | return; |
76 | } | 77 | } |
77 | var cursor = modelSeed.getCursor(ReasoningAdapter.EXISTS_SYMBOL, TruthValue.UNKNOWN); | 78 | var cursor = modelSeed.getCursor(ReasoningAdapter.EXISTS_SYMBOL, TruthValue.UNKNOWN); |
78 | while (cursor.move()) { | 79 | while (cursor.move()) { |
80 | model.checkCancelled(); | ||
79 | int i = cursor.getKey().get(0); | 81 | int i = cursor.getKey().get(0); |
80 | checkNodeId(intervals, i); | 82 | checkNodeId(intervals, i); |
81 | switch (cursor.getValue()) { | 83 | switch (cursor.getValue()) { |
@@ -89,13 +91,14 @@ class MultiObjectInitializer implements PartialModelInitializer { | |||
89 | } | 91 | } |
90 | } | 92 | } |
91 | 93 | ||
92 | private void initializeEquals(CardinalityInterval[] intervals, ModelSeed modelSeed) { | 94 | private void initializeEquals(CardinalityInterval[] intervals, Model model, ModelSeed modelSeed) { |
93 | if (!modelSeed.containsSeed(ReasoningAdapter.EQUALS_SYMBOL)) { | 95 | if (!modelSeed.containsSeed(ReasoningAdapter.EQUALS_SYMBOL)) { |
94 | return; | 96 | return; |
95 | } | 97 | } |
96 | var seed = modelSeed.getSeed(ReasoningAdapter.EQUALS_SYMBOL); | 98 | var seed = modelSeed.getSeed(ReasoningAdapter.EQUALS_SYMBOL); |
97 | var cursor = seed.getCursor(TruthValue.FALSE, modelSeed.getNodeCount()); | 99 | var cursor = seed.getCursor(TruthValue.FALSE, modelSeed.getNodeCount()); |
98 | while (cursor.move()) { | 100 | while (cursor.move()) { |
101 | model.checkCancelled(); | ||
99 | var key = cursor.getKey(); | 102 | var key = cursor.getKey(); |
100 | int i = key.get(0); | 103 | int i = key.get(0); |
101 | int otherIndex = key.get(1); | 104 | int otherIndex = key.get(1); |
@@ -116,6 +119,7 @@ class MultiObjectInitializer implements PartialModelInitializer { | |||
116 | } | 119 | } |
117 | } | 120 | } |
118 | for (int i = 0; i < intervals.length; i++) { | 121 | for (int i = 0; i < intervals.length; i++) { |
122 | model.checkCancelled(); | ||
119 | if (seed.get(Tuple.of(i, i)) == TruthValue.FALSE) { | 123 | if (seed.get(Tuple.of(i, i)) == TruthValue.FALSE) { |
120 | throw new TranslationException(ReasoningAdapter.EQUALS_SYMBOL, "Inconsistent equality for node " + i); | 124 | throw new TranslationException(ReasoningAdapter.EQUALS_SYMBOL, "Inconsistent equality for node " + i); |
121 | } | 125 | } |
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/TypeHierarchyInitializer.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/TypeHierarchyInitializer.java index c74f1e78..233e43f0 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/TypeHierarchyInitializer.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/TypeHierarchyInitializer.java | |||
@@ -31,20 +31,23 @@ public class TypeHierarchyInitializer implements PartialModelInitializer { | |||
31 | var inferredTypes = new InferredType[modelSeed.getNodeCount()]; | 31 | var inferredTypes = new InferredType[modelSeed.getNodeCount()]; |
32 | Arrays.fill(inferredTypes, typeHierarchy.getUnknownType()); | 32 | Arrays.fill(inferredTypes, typeHierarchy.getUnknownType()); |
33 | for (var type : typeHierarchy.getAllTypes()) { | 33 | for (var type : typeHierarchy.getAllTypes()) { |
34 | initializeType(type, inferredTypes, modelSeed); | 34 | model.checkCancelled(); |
35 | initializeType(type, inferredTypes, model, modelSeed); | ||
35 | } | 36 | } |
36 | var typeInterpretation = model.getInterpretation(typeSymbol); | 37 | var typeInterpretation = model.getInterpretation(typeSymbol); |
37 | var uniqueTable = new HashMap<InferredType, InferredType>(); | 38 | var uniqueTable = new HashMap<InferredType, InferredType>(); |
38 | for (int i = 0; i < inferredTypes.length; i++) { | 39 | for (int i = 0; i < inferredTypes.length; i++) { |
40 | model.checkCancelled(); | ||
39 | var uniqueType = uniqueTable.computeIfAbsent(inferredTypes[i], Function.identity()); | 41 | var uniqueType = uniqueTable.computeIfAbsent(inferredTypes[i], Function.identity()); |
40 | typeInterpretation.put(Tuple.of(i), uniqueType); | 42 | typeInterpretation.put(Tuple.of(i), uniqueType); |
41 | } | 43 | } |
42 | } | 44 | } |
43 | 45 | ||
44 | private void initializeType(PartialRelation type, InferredType[] inferredTypes, ModelSeed modelSeed) { | 46 | private void initializeType(PartialRelation type, InferredType[] inferredTypes, Model model, ModelSeed modelSeed) { |
45 | var cursor = modelSeed.getCursor(type, TruthValue.UNKNOWN); | 47 | var cursor = modelSeed.getCursor(type, TruthValue.UNKNOWN); |
46 | var analysisResult = typeHierarchy.getAnalysisResult(type); | 48 | var analysisResult = typeHierarchy.getAnalysisResult(type); |
47 | while (cursor.move()) { | 49 | while (cursor.move()) { |
50 | model.checkCancelled(); | ||
48 | var i = cursor.getKey().get(0); | 51 | var i = cursor.getKey().get(0); |
49 | checkNodeId(inferredTypes, i); | 52 | checkNodeId(inferredTypes, i); |
50 | var value = cursor.getValue(); | 53 | var value = cursor.getValue(); |
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/Model.java b/subprojects/store/src/main/java/tools/refinery/store/model/Model.java index e2ab72e7..c4ce5207 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/model/Model.java +++ b/subprojects/store/src/main/java/tools/refinery/store/model/Model.java | |||
@@ -8,11 +8,9 @@ package tools.refinery.store.model; | |||
8 | import tools.refinery.store.adapter.ModelAdapter; | 8 | import tools.refinery.store.adapter.ModelAdapter; |
9 | import tools.refinery.store.map.Version; | 9 | import tools.refinery.store.map.Version; |
10 | import tools.refinery.store.map.Versioned; | 10 | import tools.refinery.store.map.Versioned; |
11 | import tools.refinery.store.model.internal.VersionedInterpretation; | ||
12 | import tools.refinery.store.representation.AnySymbol; | 11 | import tools.refinery.store.representation.AnySymbol; |
13 | import tools.refinery.store.representation.Symbol; | 12 | import tools.refinery.store.representation.Symbol; |
14 | 13 | ||
15 | import java.util.Map; | ||
16 | import java.util.Optional; | 14 | import java.util.Optional; |
17 | 15 | ||
18 | public interface Model extends Versioned { | 16 | public interface Model extends Versioned { |
@@ -38,4 +36,6 @@ public interface Model extends Versioned { | |||
38 | void addListener(ModelListener listener); | 36 | void addListener(ModelListener listener); |
39 | 37 | ||
40 | void removeListener(ModelListener listener); | 38 | void removeListener(ModelListener listener); |
39 | |||
40 | void checkCancelled(); | ||
41 | } | 41 | } |
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/ModelStore.java b/subprojects/store/src/main/java/tools/refinery/store/model/ModelStore.java index 89382b3a..61abf126 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/model/ModelStore.java +++ b/subprojects/store/src/main/java/tools/refinery/store/model/ModelStore.java | |||
@@ -26,6 +26,8 @@ public interface ModelStore { | |||
26 | 26 | ||
27 | <T extends ModelStoreAdapter> T getAdapter(Class<T> adapterType); | 27 | <T extends ModelStoreAdapter> T getAdapter(Class<T> adapterType); |
28 | 28 | ||
29 | void checkCancelled(); | ||
30 | |||
29 | static ModelStoreBuilder builder() { | 31 | static ModelStoreBuilder builder() { |
30 | return new ModelStoreBuilderImpl(); | 32 | return new ModelStoreBuilderImpl(); |
31 | } | 33 | } |
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/ModelStoreBuilder.java b/subprojects/store/src/main/java/tools/refinery/store/model/ModelStoreBuilder.java index 8f652762..9b2b38c3 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/model/ModelStoreBuilder.java +++ b/subprojects/store/src/main/java/tools/refinery/store/model/ModelStoreBuilder.java | |||
@@ -8,12 +8,15 @@ package tools.refinery.store.model; | |||
8 | import tools.refinery.store.adapter.ModelAdapterBuilder; | 8 | import tools.refinery.store.adapter.ModelAdapterBuilder; |
9 | import tools.refinery.store.representation.AnySymbol; | 9 | import tools.refinery.store.representation.AnySymbol; |
10 | import tools.refinery.store.representation.Symbol; | 10 | import tools.refinery.store.representation.Symbol; |
11 | import tools.refinery.store.util.CancellationToken; | ||
11 | 12 | ||
12 | import java.util.Collection; | 13 | import java.util.Collection; |
13 | import java.util.List; | 14 | import java.util.List; |
14 | import java.util.Optional; | 15 | import java.util.Optional; |
15 | 16 | ||
16 | public interface ModelStoreBuilder { | 17 | public interface ModelStoreBuilder { |
18 | ModelStoreBuilder cancellationToken(CancellationToken cancellationToken); | ||
19 | |||
17 | default ModelStoreBuilder symbols(AnySymbol... symbols) { | 20 | default ModelStoreBuilder symbols(AnySymbol... symbols) { |
18 | return symbols(List.of(symbols)); | 21 | return symbols(List.of(symbols)); |
19 | } | 22 | } |
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/internal/ModelImpl.java b/subprojects/store/src/main/java/tools/refinery/store/model/internal/ModelImpl.java index 2b12d5a6..d11e431b 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/model/internal/ModelImpl.java +++ b/subprojects/store/src/main/java/tools/refinery/store/model/internal/ModelImpl.java | |||
@@ -13,23 +13,26 @@ import tools.refinery.store.model.*; | |||
13 | import tools.refinery.store.representation.AnySymbol; | 13 | import tools.refinery.store.representation.AnySymbol; |
14 | import tools.refinery.store.representation.Symbol; | 14 | import tools.refinery.store.representation.Symbol; |
15 | import tools.refinery.store.tuple.Tuple; | 15 | import tools.refinery.store.tuple.Tuple; |
16 | import tools.refinery.store.util.CancellationToken; | ||
16 | 17 | ||
17 | import java.util.*; | 18 | import java.util.*; |
18 | 19 | ||
19 | public class ModelImpl implements Model { | 20 | public class ModelImpl implements Model { |
20 | private final ModelStore store; | 21 | private final ModelStoreImpl store; |
21 | private Version state; | 22 | private Version state; |
22 | private LinkedHashMap<? extends AnySymbol, ? extends VersionedInterpretation<?>> interpretations; | 23 | private LinkedHashMap<? extends AnySymbol, ? extends VersionedInterpretation<?>> interpretations; |
23 | private final List<ModelAdapter> adapters; | 24 | private final List<ModelAdapter> adapters; |
24 | private final List<ModelListener> listeners = new ArrayList<>(); | 25 | private final List<ModelListener> listeners = new ArrayList<>(); |
26 | private final CancellationToken cancellationToken; | ||
25 | private boolean uncommittedChanges; | 27 | private boolean uncommittedChanges; |
26 | private ModelAction pendingAction = ModelAction.NONE; | 28 | private ModelAction pendingAction = ModelAction.NONE; |
27 | private Version restoringToState = null; | 29 | private Version restoringToState = null; |
28 | 30 | ||
29 | ModelImpl(ModelStore store, Version state, int adapterCount) { | 31 | ModelImpl(ModelStoreImpl store, Version state, int adapterCount) { |
30 | this.store = store; | 32 | this.store = store; |
31 | this.state = state; | 33 | this.state = state; |
32 | adapters = new ArrayList<>(adapterCount); | 34 | adapters = new ArrayList<>(adapterCount); |
35 | cancellationToken = store.getCancellationToken(); | ||
33 | } | 36 | } |
34 | 37 | ||
35 | void setInterpretations(LinkedHashMap<? extends AnySymbol, ? extends VersionedInterpretation<?>> interpretations) { | 38 | void setInterpretations(LinkedHashMap<? extends AnySymbol, ? extends VersionedInterpretation<?>> interpretations) { |
@@ -88,6 +91,7 @@ public class ModelImpl implements Model { | |||
88 | 91 | ||
89 | @Override | 92 | @Override |
90 | public Version commit() { | 93 | public Version commit() { |
94 | checkCancelled(); | ||
91 | if (hasPendingAction()) { | 95 | if (hasPendingAction()) { |
92 | throw pendingActionError("commit"); | 96 | throw pendingActionError("commit"); |
93 | } | 97 | } |
@@ -106,6 +110,7 @@ public class ModelImpl implements Model { | |||
106 | Version[] interpretationVersions = new Version[interpretations.size()]; | 110 | Version[] interpretationVersions = new Version[interpretations.size()]; |
107 | int j = 0; | 111 | int j = 0; |
108 | for (var interpretationEntry : interpretations.entrySet()) { | 112 | for (var interpretationEntry : interpretations.entrySet()) { |
113 | checkCancelled(); | ||
109 | interpretationVersions[j++] = interpretationEntry.getValue().commit(); | 114 | interpretationVersions[j++] = interpretationEntry.getValue().commit(); |
110 | } | 115 | } |
111 | ModelVersion modelVersion = new ModelVersion(interpretationVersions); | 116 | ModelVersion modelVersion = new ModelVersion(interpretationVersions); |
@@ -125,6 +130,7 @@ public class ModelImpl implements Model { | |||
125 | 130 | ||
126 | @Override | 131 | @Override |
127 | public void restore(Version version) { | 132 | public void restore(Version version) { |
133 | checkCancelled(); | ||
128 | if (hasPendingAction()) { | 134 | if (hasPendingAction()) { |
129 | throw pendingActionError("restore to %s".formatted(version)); | 135 | throw pendingActionError("restore to %s".formatted(version)); |
130 | } | 136 | } |
@@ -140,6 +146,7 @@ public class ModelImpl implements Model { | |||
140 | } | 146 | } |
141 | int j = 0; | 147 | int j = 0; |
142 | for (var interpretation : interpretations.values()) { | 148 | for (var interpretation : interpretations.values()) { |
149 | checkCancelled(); | ||
143 | interpretation.restore(ModelVersion.getInternalVersion(version, j++)); | 150 | interpretation.restore(ModelVersion.getInternalVersion(version, j++)); |
144 | } | 151 | } |
145 | 152 | ||
@@ -187,4 +194,9 @@ public class ModelImpl implements Model { | |||
187 | public void removeListener(ModelListener listener) { | 194 | public void removeListener(ModelListener listener) { |
188 | listeners.remove(listener); | 195 | listeners.remove(listener); |
189 | } | 196 | } |
197 | |||
198 | @Override | ||
199 | public void checkCancelled() { | ||
200 | cancellationToken.checkCancelled(); | ||
201 | } | ||
190 | } | 202 | } |
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/internal/ModelStoreBuilderImpl.java b/subprojects/store/src/main/java/tools/refinery/store/model/internal/ModelStoreBuilderImpl.java index 2dde7a4c..53ecde5e 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/model/internal/ModelStoreBuilderImpl.java +++ b/subprojects/store/src/main/java/tools/refinery/store/model/internal/ModelStoreBuilderImpl.java | |||
@@ -16,15 +16,29 @@ import tools.refinery.store.model.ModelStoreConfiguration; | |||
16 | import tools.refinery.store.representation.AnySymbol; | 16 | import tools.refinery.store.representation.AnySymbol; |
17 | import tools.refinery.store.representation.Symbol; | 17 | import tools.refinery.store.representation.Symbol; |
18 | import tools.refinery.store.tuple.Tuple; | 18 | import tools.refinery.store.tuple.Tuple; |
19 | import tools.refinery.store.util.CancellationToken; | ||
19 | 20 | ||
20 | import java.util.*; | 21 | import java.util.*; |
21 | 22 | ||
22 | public class ModelStoreBuilderImpl implements ModelStoreBuilder { | 23 | public class ModelStoreBuilderImpl implements ModelStoreBuilder { |
24 | private CancellationToken cancellationToken; | ||
23 | private final LinkedHashSet<AnySymbol> allSymbols = new LinkedHashSet<>(); | 25 | private final LinkedHashSet<AnySymbol> allSymbols = new LinkedHashSet<>(); |
24 | private final LinkedHashMap<SymbolEquivalenceClass<?>, List<AnySymbol>> equivalenceClasses = new LinkedHashMap<>(); | 26 | private final LinkedHashMap<SymbolEquivalenceClass<?>, List<AnySymbol>> equivalenceClasses = new LinkedHashMap<>(); |
25 | private final List<ModelAdapterBuilder> adapters = new ArrayList<>(); | 27 | private final List<ModelAdapterBuilder> adapters = new ArrayList<>(); |
26 | 28 | ||
27 | @Override | 29 | @Override |
30 | public ModelStoreBuilder cancellationToken(CancellationToken cancellationToken) { | ||
31 | if (this.cancellationToken != null) { | ||
32 | throw new IllegalStateException("Cancellation token was already set"); | ||
33 | } | ||
34 | if (cancellationToken == null) { | ||
35 | throw new IllegalStateException("Cancellation token must not be null"); | ||
36 | } | ||
37 | this.cancellationToken = cancellationToken; | ||
38 | return this; | ||
39 | } | ||
40 | |||
41 | @Override | ||
28 | public <T> ModelStoreBuilder symbol(Symbol<T> symbol) { | 42 | public <T> ModelStoreBuilder symbol(Symbol<T> symbol) { |
29 | if (!allSymbols.add(symbol)) { | 43 | if (!allSymbols.add(symbol)) { |
30 | // No need to add symbol twice. | 44 | // No need to add symbol twice. |
@@ -75,7 +89,8 @@ public class ModelStoreBuilderImpl implements ModelStoreBuilder { | |||
75 | for (var entry : equivalenceClasses.entrySet()) { | 89 | for (var entry : equivalenceClasses.entrySet()) { |
76 | createStores(stores, entry.getKey(), entry.getValue()); | 90 | createStores(stores, entry.getKey(), entry.getValue()); |
77 | } | 91 | } |
78 | var modelStore = new ModelStoreImpl(stores, adapters.size()); | 92 | var modelStore = new ModelStoreImpl(stores, adapters.size(), cancellationToken == null ? |
93 | CancellationToken.NONE : cancellationToken); | ||
79 | for (var adapterBuilder : adapters) { | 94 | for (var adapterBuilder : adapters) { |
80 | var storeAdapter = adapterBuilder.build(modelStore); | 95 | var storeAdapter = adapterBuilder.build(modelStore); |
81 | modelStore.addAdapter(storeAdapter); | 96 | modelStore.addAdapter(storeAdapter); |
@@ -86,8 +101,8 @@ public class ModelStoreBuilderImpl implements ModelStoreBuilder { | |||
86 | private <T> void createStores(Map<AnySymbol, VersionedMapStore<Tuple, ?>> stores, | 101 | private <T> void createStores(Map<AnySymbol, VersionedMapStore<Tuple, ?>> stores, |
87 | SymbolEquivalenceClass<T> equivalenceClass, List<AnySymbol> symbols) { | 102 | SymbolEquivalenceClass<T> equivalenceClass, List<AnySymbol> symbols) { |
88 | int size = symbols.size(); | 103 | int size = symbols.size(); |
89 | VersionedMapStoreFactory<Tuple,T> mapFactory = VersionedMapStore | 104 | VersionedMapStoreFactory<Tuple, T> mapFactory = VersionedMapStore |
90 | .<Tuple,T>builder() | 105 | .<Tuple, T>builder() |
91 | .strategy(VersionedMapStoreFactoryBuilder.StoreStrategy.DELTA) | 106 | .strategy(VersionedMapStoreFactoryBuilder.StoreStrategy.DELTA) |
92 | .defaultValue(equivalenceClass.defaultValue()) | 107 | .defaultValue(equivalenceClass.defaultValue()) |
93 | .build(); | 108 | .build(); |
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/internal/ModelStoreImpl.java b/subprojects/store/src/main/java/tools/refinery/store/model/internal/ModelStoreImpl.java index a320a618..fd4cc160 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/model/internal/ModelStoreImpl.java +++ b/subprojects/store/src/main/java/tools/refinery/store/model/internal/ModelStoreImpl.java | |||
@@ -14,16 +14,20 @@ import tools.refinery.store.model.ModelDiffCursor; | |||
14 | import tools.refinery.store.model.ModelStore; | 14 | import tools.refinery.store.model.ModelStore; |
15 | import tools.refinery.store.representation.AnySymbol; | 15 | import tools.refinery.store.representation.AnySymbol; |
16 | import tools.refinery.store.tuple.Tuple; | 16 | import tools.refinery.store.tuple.Tuple; |
17 | import tools.refinery.store.util.CancellationToken; | ||
17 | 18 | ||
18 | import java.util.*; | 19 | import java.util.*; |
19 | 20 | ||
20 | public class ModelStoreImpl implements ModelStore { | 21 | public class ModelStoreImpl implements ModelStore { |
21 | private final LinkedHashMap<? extends AnySymbol, ? extends VersionedMapStore<Tuple, ?>> stores; | 22 | private final LinkedHashMap<? extends AnySymbol, ? extends VersionedMapStore<Tuple, ?>> stores; |
22 | private final List<ModelStoreAdapter> adapters; | 23 | private final List<ModelStoreAdapter> adapters; |
24 | private final CancellationToken cancellationToken; | ||
23 | 25 | ||
24 | ModelStoreImpl(LinkedHashMap<? extends AnySymbol, ? extends VersionedMapStore<Tuple, ?>> stores, int adapterCount) { | 26 | ModelStoreImpl(LinkedHashMap<? extends AnySymbol, ? extends VersionedMapStore<Tuple, ?>> stores, int adapterCount, |
27 | CancellationToken cancellationToken) { | ||
25 | this.stores = stores; | 28 | this.stores = stores; |
26 | adapters = new ArrayList<>(adapterCount); | 29 | adapters = new ArrayList<>(adapterCount); |
30 | this.cancellationToken = cancellationToken; | ||
27 | } | 31 | } |
28 | 32 | ||
29 | @Override | 33 | @Override |
@@ -100,4 +104,13 @@ public class ModelStoreImpl implements ModelStore { | |||
100 | void addAdapter(ModelStoreAdapter adapter) { | 104 | void addAdapter(ModelStoreAdapter adapter) { |
101 | adapters.add(adapter); | 105 | adapters.add(adapter); |
102 | } | 106 | } |
107 | |||
108 | @Override | ||
109 | public void checkCancelled() { | ||
110 | cancellationToken.checkCancelled(); | ||
111 | } | ||
112 | |||
113 | CancellationToken getCancellationToken() { | ||
114 | return cancellationToken; | ||
115 | } | ||
103 | } | 116 | } |
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/internal/VersionedInterpretation.java b/subprojects/store/src/main/java/tools/refinery/store/model/internal/VersionedInterpretation.java index 71df3962..dcf0ad08 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/model/internal/VersionedInterpretation.java +++ b/subprojects/store/src/main/java/tools/refinery/store/model/internal/VersionedInterpretation.java | |||
@@ -75,6 +75,7 @@ public abstract class VersionedInterpretation<T> implements Interpretation<T> { | |||
75 | @Override | 75 | @Override |
76 | public T put(Tuple key, T value) { | 76 | public T put(Tuple key, T value) { |
77 | checkKey(key); | 77 | checkKey(key); |
78 | model.checkCancelled(); | ||
78 | model.markAsChanged(); | 79 | model.markAsChanged(); |
79 | var oldValue = map.put(key, value); | 80 | var oldValue = map.put(key, value); |
80 | valueChanged(key, oldValue, value, false); | 81 | valueChanged(key, oldValue, value, false); |
@@ -83,15 +84,12 @@ public abstract class VersionedInterpretation<T> implements Interpretation<T> { | |||
83 | 84 | ||
84 | @Override | 85 | @Override |
85 | public void putAll(Cursor<Tuple, T> cursor) { | 86 | public void putAll(Cursor<Tuple, T> cursor) { |
86 | if (listeners.isEmpty()) { | ||
87 | map.putAll(cursor); | ||
88 | return; | ||
89 | } | ||
90 | model.markAsChanged(); | 87 | model.markAsChanged(); |
91 | if (cursor.getDependingMaps().contains(map)) { | 88 | if (cursor.getDependingMaps().contains(map)) { |
92 | List<Tuple> keys = new ArrayList<>(); | 89 | List<Tuple> keys = new ArrayList<>(); |
93 | List<T> values = new ArrayList<>(); | 90 | List<T> values = new ArrayList<>(); |
94 | while (cursor.move()) { | 91 | while (cursor.move()) { |
92 | model.checkCancelled(); | ||
95 | keys.add(cursor.getKey()); | 93 | keys.add(cursor.getKey()); |
96 | values.add(cursor.getValue()); | 94 | values.add(cursor.getValue()); |
97 | } | 95 | } |
diff --git a/subprojects/store/src/main/java/tools/refinery/store/statecoding/StateCodeCalculatorFactory.java b/subprojects/store/src/main/java/tools/refinery/store/statecoding/StateCodeCalculatorFactory.java index 04e17a13..809205e4 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/statecoding/StateCodeCalculatorFactory.java +++ b/subprojects/store/src/main/java/tools/refinery/store/statecoding/StateCodeCalculatorFactory.java | |||
@@ -7,9 +7,10 @@ package tools.refinery.store.statecoding; | |||
7 | 7 | ||
8 | import org.eclipse.collections.api.set.primitive.IntSet; | 8 | import org.eclipse.collections.api.set.primitive.IntSet; |
9 | import tools.refinery.store.model.Interpretation; | 9 | import tools.refinery.store.model.Interpretation; |
10 | import tools.refinery.store.model.Model; | ||
10 | 11 | ||
11 | import java.util.List; | 12 | import java.util.List; |
12 | 13 | ||
13 | public interface StateCodeCalculatorFactory { | 14 | public interface StateCodeCalculatorFactory { |
14 | StateCodeCalculator create(List<? extends Interpretation<?>> interpretations, IntSet individuals); | 15 | StateCodeCalculator create(Model model, List<? extends Interpretation<?>> interpretations, IntSet individuals); |
15 | } | 16 | } |
diff --git a/subprojects/store/src/main/java/tools/refinery/store/statecoding/internal/StateCoderStoreAdapterImpl.java b/subprojects/store/src/main/java/tools/refinery/store/statecoding/internal/StateCoderStoreAdapterImpl.java index 89586bfb..2cb6f3c1 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/statecoding/internal/StateCoderStoreAdapterImpl.java +++ b/subprojects/store/src/main/java/tools/refinery/store/statecoding/internal/StateCoderStoreAdapterImpl.java | |||
@@ -68,7 +68,7 @@ public class StateCoderStoreAdapterImpl implements StateCoderStoreAdapter { | |||
68 | @Override | 68 | @Override |
69 | public StateCoderAdapter createModelAdapter(Model model) { | 69 | public StateCoderAdapter createModelAdapter(Model model) { |
70 | var interpretations = symbols.stream().map(model::getInterpretation).toList(); | 70 | var interpretations = symbols.stream().map(model::getInterpretation).toList(); |
71 | var coder = codeCalculatorFactory.create(interpretations, individuals); | 71 | var coder = codeCalculatorFactory.create(model, interpretations, individuals); |
72 | return new StateCoderAdapterImpl(this, coder, model); | 72 | return new StateCoderAdapterImpl(this, coder, model); |
73 | } | 73 | } |
74 | } | 74 | } |
diff --git a/subprojects/store/src/main/java/tools/refinery/store/statecoding/neighbourhood/AbstractNeighbourhoodCalculator.java b/subprojects/store/src/main/java/tools/refinery/store/statecoding/neighbourhood/AbstractNeighbourhoodCalculator.java index 5d390da2..4cef6786 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/statecoding/neighbourhood/AbstractNeighbourhoodCalculator.java +++ b/subprojects/store/src/main/java/tools/refinery/store/statecoding/neighbourhood/AbstractNeighbourhoodCalculator.java | |||
@@ -10,6 +10,7 @@ import org.eclipse.collections.api.map.primitive.MutableIntLongMap; | |||
10 | import org.eclipse.collections.api.set.primitive.IntSet; | 10 | import org.eclipse.collections.api.set.primitive.IntSet; |
11 | import tools.refinery.store.model.AnyInterpretation; | 11 | import tools.refinery.store.model.AnyInterpretation; |
12 | import tools.refinery.store.model.Interpretation; | 12 | import tools.refinery.store.model.Interpretation; |
13 | import tools.refinery.store.model.Model; | ||
13 | import tools.refinery.store.statecoding.ObjectCode; | 14 | import tools.refinery.store.statecoding.ObjectCode; |
14 | import tools.refinery.store.tuple.Tuple; | 15 | import tools.refinery.store.tuple.Tuple; |
15 | import tools.refinery.store.tuple.Tuple0; | 16 | import tools.refinery.store.tuple.Tuple0; |
@@ -17,13 +18,16 @@ import tools.refinery.store.tuple.Tuple0; | |||
17 | import java.util.*; | 18 | import java.util.*; |
18 | 19 | ||
19 | public abstract class AbstractNeighbourhoodCalculator { | 20 | public abstract class AbstractNeighbourhoodCalculator { |
21 | protected final Model model; | ||
20 | protected final List<AnyInterpretation> nullImpactValues; | 22 | protected final List<AnyInterpretation> nullImpactValues; |
21 | protected final LinkedHashMap<AnyInterpretation, long[]> impactValues; | 23 | protected final LinkedHashMap<AnyInterpretation, long[]> impactValues; |
22 | protected final MutableIntLongMap individualHashValues = IntLongMaps.mutable.empty(); | 24 | protected final MutableIntLongMap individualHashValues = IntLongMaps.mutable.empty(); |
23 | 25 | ||
24 | protected static final long PRIME = 31; | 26 | protected static final long PRIME = 31; |
25 | 27 | ||
26 | protected AbstractNeighbourhoodCalculator(List<? extends AnyInterpretation> interpretations, IntSet individuals) { | 28 | protected AbstractNeighbourhoodCalculator(Model model, List<? extends AnyInterpretation> interpretations, |
29 | IntSet individuals) { | ||
30 | this.model = model; | ||
27 | this.nullImpactValues = new ArrayList<>(); | 31 | this.nullImpactValues = new ArrayList<>(); |
28 | this.impactValues = new LinkedHashMap<>(); | 32 | this.impactValues = new LinkedHashMap<>(); |
29 | // Random isn't used for cryptographical purposes but just to assign distinguishable identifiers to symbols. | 33 | // Random isn't used for cryptographical purposes but just to assign distinguishable identifiers to symbols. |
diff --git a/subprojects/store/src/main/java/tools/refinery/store/statecoding/neighbourhood/LazyNeighbourhoodCalculator.java b/subprojects/store/src/main/java/tools/refinery/store/statecoding/neighbourhood/LazyNeighbourhoodCalculator.java index c188a839..04335141 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/statecoding/neighbourhood/LazyNeighbourhoodCalculator.java +++ b/subprojects/store/src/main/java/tools/refinery/store/statecoding/neighbourhood/LazyNeighbourhoodCalculator.java | |||
@@ -12,6 +12,7 @@ import org.eclipse.collections.api.set.primitive.IntSet; | |||
12 | import tools.refinery.store.map.Cursor; | 12 | import tools.refinery.store.map.Cursor; |
13 | import tools.refinery.store.model.AnyInterpretation; | 13 | import tools.refinery.store.model.AnyInterpretation; |
14 | import tools.refinery.store.model.Interpretation; | 14 | import tools.refinery.store.model.Interpretation; |
15 | import tools.refinery.store.model.Model; | ||
15 | import tools.refinery.store.statecoding.StateCodeCalculator; | 16 | import tools.refinery.store.statecoding.StateCodeCalculator; |
16 | import tools.refinery.store.statecoding.StateCoderResult; | 17 | import tools.refinery.store.statecoding.StateCoderResult; |
17 | import tools.refinery.store.tuple.Tuple; | 18 | import tools.refinery.store.tuple.Tuple; |
@@ -19,8 +20,9 @@ import tools.refinery.store.tuple.Tuple; | |||
19 | import java.util.List; | 20 | import java.util.List; |
20 | 21 | ||
21 | public class LazyNeighbourhoodCalculator extends AbstractNeighbourhoodCalculator implements StateCodeCalculator { | 22 | public class LazyNeighbourhoodCalculator extends AbstractNeighbourhoodCalculator implements StateCodeCalculator { |
22 | public LazyNeighbourhoodCalculator(List<? extends AnyInterpretation> interpretations, IntSet individuals) { | 23 | public LazyNeighbourhoodCalculator(Model model, List<? extends AnyInterpretation> interpretations, |
23 | super(interpretations, individuals); | 24 | IntSet individuals) { |
25 | super(model, interpretations, individuals); | ||
24 | } | 26 | } |
25 | 27 | ||
26 | public StateCoderResult calculateCodes() { | 28 | public StateCoderResult calculateCodes() { |
diff --git a/subprojects/store/src/main/java/tools/refinery/store/statecoding/neighbourhood/NeighbourhoodCalculator.java b/subprojects/store/src/main/java/tools/refinery/store/statecoding/neighbourhood/NeighbourhoodCalculator.java index 1442c915..5e6de53b 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/statecoding/neighbourhood/NeighbourhoodCalculator.java +++ b/subprojects/store/src/main/java/tools/refinery/store/statecoding/neighbourhood/NeighbourhoodCalculator.java | |||
@@ -8,6 +8,7 @@ package tools.refinery.store.statecoding.neighbourhood; | |||
8 | import org.eclipse.collections.api.set.primitive.IntSet; | 8 | import org.eclipse.collections.api.set.primitive.IntSet; |
9 | import tools.refinery.store.map.Cursor; | 9 | import tools.refinery.store.map.Cursor; |
10 | import tools.refinery.store.model.Interpretation; | 10 | import tools.refinery.store.model.Interpretation; |
11 | import tools.refinery.store.model.Model; | ||
11 | import tools.refinery.store.statecoding.ObjectCode; | 12 | import tools.refinery.store.statecoding.ObjectCode; |
12 | import tools.refinery.store.statecoding.StateCodeCalculator; | 13 | import tools.refinery.store.statecoding.StateCodeCalculator; |
13 | import tools.refinery.store.statecoding.StateCoderResult; | 14 | import tools.refinery.store.statecoding.StateCoderResult; |
@@ -21,17 +22,19 @@ public class NeighbourhoodCalculator extends AbstractNeighbourhoodCalculator imp | |||
21 | private ObjectCodeImpl previousObjectCode = new ObjectCodeImpl(); | 22 | private ObjectCodeImpl previousObjectCode = new ObjectCodeImpl(); |
22 | private ObjectCodeImpl nextObjectCode = new ObjectCodeImpl(); | 23 | private ObjectCodeImpl nextObjectCode = new ObjectCodeImpl(); |
23 | 24 | ||
24 | public NeighbourhoodCalculator(List<? extends Interpretation<?>> interpretations, IntSet individuals) { | 25 | public NeighbourhoodCalculator(Model model, List<? extends Interpretation<?>> interpretations, IntSet individuals) { |
25 | super(interpretations, individuals); | 26 | super(model, interpretations, individuals); |
26 | } | 27 | } |
27 | 28 | ||
28 | public StateCoderResult calculateCodes() { | 29 | public StateCoderResult calculateCodes() { |
30 | model.checkCancelled(); | ||
29 | previousObjectCode.clear(); | 31 | previousObjectCode.clear(); |
30 | nextObjectCode.clear(); | 32 | nextObjectCode.clear(); |
31 | initializeWithIndividuals(previousObjectCode); | 33 | initializeWithIndividuals(previousObjectCode); |
32 | 34 | ||
33 | int rounds = 0; | 35 | int rounds = 0; |
34 | do { | 36 | do { |
37 | model.checkCancelled(); | ||
35 | constructNextObjectCodes(previousObjectCode, nextObjectCode); | 38 | constructNextObjectCodes(previousObjectCode, nextObjectCode); |
36 | var tempObjectCode = previousObjectCode; | 39 | var tempObjectCode = previousObjectCode; |
37 | previousObjectCode = nextObjectCode; | 40 | previousObjectCode = nextObjectCode; |
@@ -60,6 +63,7 @@ public class NeighbourhoodCalculator extends AbstractNeighbourhoodCalculator imp | |||
60 | 63 | ||
61 | private void constructNextObjectCodes(ObjectCodeImpl previous, ObjectCodeImpl next) { | 64 | private void constructNextObjectCodes(ObjectCodeImpl previous, ObjectCodeImpl next) { |
62 | for (var impactValueEntry : this.impactValues.entrySet()) { | 65 | for (var impactValueEntry : this.impactValues.entrySet()) { |
66 | model.checkCancelled(); | ||
63 | Interpretation<?> interpretation = (Interpretation<?>) impactValueEntry.getKey(); | 67 | Interpretation<?> interpretation = (Interpretation<?>) impactValueEntry.getKey(); |
64 | var cursor = interpretation.getAll(); | 68 | var cursor = interpretation.getAll(); |
65 | int arity = interpretation.getSymbol().arity(); | 69 | int arity = interpretation.getSymbol().arity(); |
diff --git a/subprojects/store/src/main/java/tools/refinery/store/util/CancellationToken.java b/subprojects/store/src/main/java/tools/refinery/store/util/CancellationToken.java new file mode 100644 index 00000000..be294013 --- /dev/null +++ b/subprojects/store/src/main/java/tools/refinery/store/util/CancellationToken.java | |||
@@ -0,0 +1,13 @@ | |||
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.util; | ||
7 | |||
8 | @FunctionalInterface | ||
9 | public interface CancellationToken { | ||
10 | CancellationToken NONE = () -> {}; | ||
11 | |||
12 | void checkCancelled(); | ||
13 | } | ||
diff --git a/subprojects/store/src/test/java/tools/refinery/store/statecoding/EquivalenceTest.java b/subprojects/store/src/test/java/tools/refinery/store/statecoding/EquivalenceTest.java index 3c35849e..f2d2f7b5 100644 --- a/subprojects/store/src/test/java/tools/refinery/store/statecoding/EquivalenceTest.java +++ b/subprojects/store/src/test/java/tools/refinery/store/statecoding/EquivalenceTest.java | |||
@@ -192,7 +192,8 @@ class EquivalenceTest { | |||
192 | ModelStore store = ModelStore.builder() | 192 | ModelStore store = ModelStore.builder() |
193 | .symbols(person, age, friend, parents, population) | 193 | .symbols(person, age, friend, parents, population) |
194 | .with(StateCoderAdapter.builder() | 194 | .with(StateCoderAdapter.builder() |
195 | .stateCodeCalculatorFactory((p1, p2) -> calculator)) | 195 | .stateCodeCalculatorFactory((ignoredModel, ignoredInterpretations, ignoredIndividuals) -> |
196 | calculator)) | ||
196 | .build(); | 197 | .build(); |
197 | 198 | ||
198 | var stateCoder = store.getAdapter(StateCoderStoreAdapter.class); | 199 | var stateCoder = store.getAdapter(StateCoderStoreAdapter.class); |
diff --git a/subprojects/store/src/test/java/tools/refinery/store/statecoding/StateCoderBuildTest.java b/subprojects/store/src/test/java/tools/refinery/store/statecoding/StateCoderBuildTest.java index 0b738005..0928aa8e 100644 --- a/subprojects/store/src/test/java/tools/refinery/store/statecoding/StateCoderBuildTest.java +++ b/subprojects/store/src/test/java/tools/refinery/store/statecoding/StateCoderBuildTest.java | |||
@@ -124,7 +124,8 @@ class StateCoderBuildTest { | |||
124 | var store = ModelStore.builder() | 124 | var store = ModelStore.builder() |
125 | .symbols(friend) | 125 | .symbols(friend) |
126 | .with(StateCoderAdapter.builder() | 126 | .with(StateCoderAdapter.builder() |
127 | .stateCodeCalculatorFactory((interpretations, individuals) -> mock)) | 127 | .stateCodeCalculatorFactory((ignoredModel, ignoredInterpretations, ignoredIndividuals) -> |
128 | mock)) | ||
128 | .build(); | 129 | .build(); |
129 | 130 | ||
130 | var model = store.createEmptyModel(); | 131 | var model = store.createEmptyModel(); |