aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTreeNode.java
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTreeNode.java')
-rw-r--r--subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTreeNode.java84
1 files changed, 84 insertions, 0 deletions
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTreeNode.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTreeNode.java
new file mode 100644
index 00000000..53954d62
--- /dev/null
+++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTreeNode.java
@@ -0,0 +1,84 @@
1package tools.refinery.language.semantics.model.internal;
2
3import org.eclipse.collections.api.LazyIntIterable;
4import tools.refinery.store.model.Tuple;
5import tools.refinery.store.model.representation.TruthValue;
6
7abstract class DecisionTreeNode {
8 public DecisionTreeValue getReducedValue() {
9 return getChildKeys().isEmpty() ? getOtherwiseReducedValue() : null;
10 }
11
12 public abstract DecisionTreeValue getValue(int level, Tuple tuple);
13
14 public abstract DecisionTreeNode deepCopy();
15
16 public void mergeValue(int level, Tuple tuple, TruthValue value) {
17 int nextLevel = level - 1;
18 var key = tuple.get(level);
19 if (key < 0) {
20 mergeAllValues(nextLevel, tuple, value);
21 } else {
22 mergeSingleValue(key, nextLevel, tuple, value);
23 }
24 }
25
26 protected abstract void mergeAllValues(int nextLevel, Tuple tuple, TruthValue value);
27
28 protected abstract void mergeSingleValue(int key, int nextLevel, Tuple tuple, TruthValue value);
29
30 public DecisionTreeNode withMergedValue(int level, Tuple tuple, TruthValue value) {
31 var copy = deepCopy();
32 copy.mergeValue(level, tuple, value);
33 return copy;
34 }
35
36 public abstract void overwriteValues(DecisionTreeNode values);
37
38 public DecisionTreeNode withOverwrittenValues(DecisionTreeNode values) {
39 var copy = deepCopy();
40 copy.overwriteValues(values);
41 return copy;
42 }
43
44 public boolean moveNext(int level, DecisionTreeCursor cursor) {
45 var currentState = cursor.iterationState[level];
46 boolean found;
47 if (currentState == DecisionTreeCursor.STATE_FINISH) {
48 // Entering this node for the first time.
49 cursor.path.push(this);
50 if (cursor.defaultValue == getOtherwiseReducedValue()) {
51 var sortedChildren = getChildKeys().toSortedArray();
52 cursor.sortedChildren[level] = sortedChildren;
53 found = moveNextSparse(level, cursor, 0, sortedChildren);
54 } else {
55 found = moveNextDense(level, cursor, 0);
56 }
57 } else {
58 var sortedChildren = cursor.sortedChildren[level];
59 if (sortedChildren == null) {
60 found = moveNextDense(level, cursor, currentState + 1);
61 } else {
62 found = moveNextSparse(level, cursor, currentState + 1, sortedChildren);
63 }
64 }
65 if (!found) {
66 cursor.sortedChildren[level] = null;
67 cursor.iterationState[level] = DecisionTreeCursor.STATE_FINISH;
68 var popped = cursor.path.pop();
69 if (popped != this) {
70 throw new IllegalStateException("Invalid decision diagram cursor");
71 }
72 }
73 return found;
74 }
75
76 protected abstract DecisionTreeValue getOtherwiseReducedValue();
77
78 protected abstract LazyIntIterable getChildKeys();
79
80 protected abstract boolean moveNextSparse(int level, DecisionTreeCursor cursor, int startIndex,
81 int[] sortedChildren);
82
83 protected abstract boolean moveNextDense(int level, DecisionTreeCursor cursor, int startIndex);
84}