aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/refinement/DefaultStorageRefiner.java
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/refinement/DefaultStorageRefiner.java')
-rw-r--r--subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/refinement/DefaultStorageRefiner.java80
1 files changed, 80 insertions, 0 deletions
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/refinement/DefaultStorageRefiner.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/refinement/DefaultStorageRefiner.java
new file mode 100644
index 00000000..0d7d6c5c
--- /dev/null
+++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/refinement/DefaultStorageRefiner.java
@@ -0,0 +1,80 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.reasoning.refinement;
7
8import tools.refinery.store.model.Interpretation;
9import tools.refinery.store.tuple.Tuple;
10
11public class DefaultStorageRefiner<T> implements StorageRefiner {
12 private static final StorageRefiner.Factory<Object> FACTORY = (symbol, model) -> {
13 var interpretation = model.getInterpretation(symbol);
14 return new DefaultStorageRefiner<>(interpretation);
15 };
16
17 private final Interpretation<T> interpretation;
18
19 public DefaultStorageRefiner(Interpretation<T> interpretation) {
20 this.interpretation = interpretation;
21 }
22
23 @Override
24 public boolean split(int parentNode, int childNode) {
25 var symbol = interpretation.getSymbol();
26 int arity = symbol.arity();
27 for (int i = 0; i < arity; i++) {
28 int adjacentSize = interpretation.getAdjacentSize(i, parentNode);
29 if (adjacentSize == 0) {
30 continue;
31 }
32 var toSetKeys = new Tuple[adjacentSize];
33 // This is safe, because we won't pass the array to the outside.
34 @SuppressWarnings("unchecked")
35 var toSetValues = (T[]) new Object[adjacentSize];
36 var cursor = interpretation.getAdjacent(i, parentNode);
37 int j = 0;
38 while (cursor.move()) {
39 toSetKeys[j] = cursor.getKey().set(i, childNode);
40 toSetValues[j] = cursor.getValue();
41 j++;
42 }
43 for (j = 0; j < adjacentSize; j++) {
44 interpretation.put(toSetKeys[j], toSetValues[j]);
45 }
46 }
47 return true;
48 }
49
50 @Override
51 public boolean cleanup(int nodeToDelete) {
52 var symbol = interpretation.getSymbol();
53 int arity = symbol.arity();
54 var defaultValue = symbol.defaultValue();
55 for (int i = 0; i < arity; i++) {
56 int adjacentSize = interpretation.getAdjacentSize(i, nodeToDelete);
57 if (adjacentSize == 0) {
58 continue;
59 }
60 var toDelete = new Tuple[adjacentSize];
61 var cursor = interpretation.getAdjacent(i, nodeToDelete);
62 int j = 0;
63 while (cursor.move()) {
64 toDelete[j] = cursor.getKey();
65 j++;
66 }
67 for (j = 0; j < adjacentSize; j++) {
68 interpretation.put(toDelete[j], defaultValue);
69 }
70 }
71 return true;
72 }
73
74 public static <T> StorageRefiner.Factory<T> factory() {
75 // This is safe, because {@code FACTORY} doesn't depend on {@code T} at all.
76 @SuppressWarnings("unchecked")
77 var typedFactory = (StorageRefiner.Factory<T>) FACTORY;
78 return typedFactory;
79 }
80}