diff options
Diffstat (limited to 'subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTreeCursor.java')
-rw-r--r-- | subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTreeCursor.java | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTreeCursor.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTreeCursor.java new file mode 100644 index 00000000..71b54cbd --- /dev/null +++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTreeCursor.java | |||
@@ -0,0 +1,96 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.language.semantics.internal; | ||
7 | |||
8 | import tools.refinery.store.map.Cursor; | ||
9 | import tools.refinery.store.representation.TruthValue; | ||
10 | import tools.refinery.store.tuple.Tuple; | ||
11 | |||
12 | import java.util.ArrayDeque; | ||
13 | import java.util.Deque; | ||
14 | |||
15 | class DecisionTreeCursor implements Cursor<Tuple, TruthValue> { | ||
16 | static final int STATE_FINISH = Integer.MAX_VALUE; | ||
17 | |||
18 | private final int levels; | ||
19 | |||
20 | final DecisionTreeValue defaultValue; | ||
21 | |||
22 | final int nodeCount; | ||
23 | |||
24 | private final DecisionTreeNode root; | ||
25 | |||
26 | final int[][] sortedChildren; | ||
27 | |||
28 | final int[] iterationState; | ||
29 | |||
30 | final int[] rawTuple; | ||
31 | |||
32 | final Deque<DecisionTreeNode> path = new ArrayDeque<>(); | ||
33 | |||
34 | private Tuple key; | ||
35 | |||
36 | DecisionTreeValue value = DecisionTreeValue.UNSET; | ||
37 | |||
38 | private boolean terminated; | ||
39 | |||
40 | public DecisionTreeCursor(int levels, TruthValue defaultValue, int nodeCount, DecisionTreeNode root) { | ||
41 | this.levels = levels; | ||
42 | this.defaultValue = DecisionTreeValue.fromTruthValue(defaultValue); | ||
43 | this.nodeCount = nodeCount; | ||
44 | this.root = root; | ||
45 | sortedChildren = new int[levels][]; | ||
46 | iterationState = new int[levels]; | ||
47 | for (int i = 0; i < levels; i++) { | ||
48 | iterationState[i] = STATE_FINISH; | ||
49 | } | ||
50 | rawTuple = new int[levels]; | ||
51 | } | ||
52 | |||
53 | @Override | ||
54 | public Tuple getKey() { | ||
55 | return key; | ||
56 | } | ||
57 | |||
58 | @Override | ||
59 | public TruthValue getValue() { | ||
60 | return value.getTruthValue(); | ||
61 | } | ||
62 | |||
63 | @Override | ||
64 | public boolean isTerminated() { | ||
65 | return terminated; | ||
66 | } | ||
67 | |||
68 | @Override | ||
69 | public boolean move() { | ||
70 | while (moveOne()) { | ||
71 | if (!value.equals(defaultValue)) { | ||
72 | return true; | ||
73 | } | ||
74 | } | ||
75 | return false; | ||
76 | } | ||
77 | |||
78 | private boolean moveOne() { | ||
79 | boolean found = false; | ||
80 | if (path.isEmpty() && !terminated) { | ||
81 | found = root.moveNext(levels - 1, this); | ||
82 | } | ||
83 | while (!found && !path.isEmpty()) { | ||
84 | int level = levels - path.size(); | ||
85 | found = path.peek().moveNext(level, this); | ||
86 | } | ||
87 | if (!found) { | ||
88 | key = null; | ||
89 | value = DecisionTreeValue.UNSET; | ||
90 | terminated = true; | ||
91 | return false; | ||
92 | } | ||
93 | key = Tuple.of(rawTuple); | ||
94 | return true; | ||
95 | } | ||
96 | } | ||