diff options
Diffstat (limited to 'subprojects/language-semantics')
6 files changed, 204 insertions, 31 deletions
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTree.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTree.java index d743ee2b..3893f396 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTree.java +++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTree.java | |||
@@ -20,21 +20,41 @@ public class DecisionTree { | |||
20 | root = node; | 20 | root = node; |
21 | } | 21 | } |
22 | 22 | ||
23 | public DecisionTree(int levels) { | ||
24 | this(levels, null); | ||
25 | } | ||
26 | |||
23 | public TruthValue get(Tuple tuple) { | 27 | public TruthValue get(Tuple tuple) { |
24 | return root.getValue(levels - 1, tuple).getTruthValue(); | 28 | return root.getValue(levels - 1, tuple).getTruthValue(); |
25 | } | 29 | } |
26 | 30 | ||
27 | public void mergeValue(Tuple tuple, TruthValue truthValue) { | 31 | public void mergeValue(Tuple tuple, TruthValue truthValue) { |
28 | if (truthValue == null) { | 32 | if (truthValue != null) { |
29 | return; | 33 | root.mergeValue(levels - 1, tuple, truthValue); |
34 | } | ||
35 | } | ||
36 | |||
37 | public void setIfMissing(Tuple tuple, TruthValue truthValue) { | ||
38 | if (truthValue != null) { | ||
39 | root.setIfMissing(levels - 1, tuple, truthValue); | ||
40 | } | ||
41 | } | ||
42 | |||
43 | public void setAllMissing(TruthValue truthValue) { | ||
44 | if (truthValue != null) { | ||
45 | root.setAllMissing(truthValue); | ||
30 | } | 46 | } |
31 | root.mergeValue(levels - 1, tuple, truthValue); | ||
32 | } | 47 | } |
33 | 48 | ||
34 | public void overwriteValues(DecisionTree values) { | 49 | public void overwriteValues(DecisionTree values) { |
35 | root.overwriteValues(values.root); | 50 | root.overwriteValues(values.root); |
36 | } | 51 | } |
37 | 52 | ||
53 | public TruthValue getReducedValue() { | ||
54 | var reducedValue = root.getReducedValue(); | ||
55 | return reducedValue == null ? null : reducedValue.getTruthValue(); | ||
56 | } | ||
57 | |||
38 | public Cursor<Tuple, TruthValue> getCursor(TruthValue defaultValue, int nodeCount) { | 58 | public Cursor<Tuple, TruthValue> getCursor(TruthValue defaultValue, int nodeCount) { |
39 | return new DecisionTreeCursor(levels, defaultValue, nodeCount, root); | 59 | return new DecisionTreeCursor(levels, defaultValue, nodeCount, root); |
40 | } | 60 | } |
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 index 7f38fc79..8ca54969 100644 --- 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 | |||
@@ -33,6 +33,24 @@ abstract class DecisionTreeNode { | |||
33 | return copy; | 33 | return copy; |
34 | } | 34 | } |
35 | 35 | ||
36 | public void setIfMissing(int level, Tuple tuple, TruthValue value) { | ||
37 | var key = tuple.get(level); | ||
38 | if (key < 0) { | ||
39 | throw new IllegalArgumentException("Not allowed set a missing wildcard"); | ||
40 | } | ||
41 | doSetIfMissing(key, level - 1, tuple, value); | ||
42 | } | ||
43 | |||
44 | protected abstract void doSetIfMissing(int key, int nextLevel, Tuple tuple, TruthValue value); | ||
45 | |||
46 | public DecisionTreeNode withValueSetIfMissing(int level, Tuple tuple, TruthValue value) { | ||
47 | var copy = deepCopy(); | ||
48 | copy.setIfMissing(level, tuple, value); | ||
49 | return copy; | ||
50 | } | ||
51 | |||
52 | public abstract void setAllMissing(TruthValue value); | ||
53 | |||
36 | public abstract void overwriteValues(DecisionTreeNode values); | 54 | public abstract void overwriteValues(DecisionTreeNode values); |
37 | 55 | ||
38 | public DecisionTreeNode withOverwrittenValues(DecisionTreeNode values) { | 56 | public DecisionTreeNode withOverwrittenValues(DecisionTreeNode values) { |
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTreeValue.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTreeValue.java index 1bf3c8b8..993987f5 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTreeValue.java +++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTreeValue.java | |||
@@ -19,14 +19,18 @@ public enum DecisionTreeValue { | |||
19 | return truthValue; | 19 | return truthValue; |
20 | } | 20 | } |
21 | 21 | ||
22 | public DecisionTreeValue merge(TruthValue other) { | 22 | public TruthValue merge(TruthValue other) { |
23 | return truthValue == null ? fromTruthValue(other) : fromTruthValue(truthValue.merge(other)); | 23 | return truthValue == null ? other : truthValue.merge(other); |
24 | } | 24 | } |
25 | 25 | ||
26 | public DecisionTreeValue overwrite(DecisionTreeValue other) { | 26 | public DecisionTreeValue overwrite(DecisionTreeValue other) { |
27 | return other == UNSET ? this : other; | 27 | return other == UNSET ? this : other; |
28 | } | 28 | } |
29 | 29 | ||
30 | public TruthValue getTruthValueOrElse(TruthValue other) { | ||
31 | return this == UNSET ? other : truthValue; | ||
32 | } | ||
33 | |||
30 | public static DecisionTreeValue fromTruthValue(TruthValue truthValue) { | 34 | public static DecisionTreeValue fromTruthValue(TruthValue truthValue) { |
31 | if (truthValue == null) { | 35 | if (truthValue == null) { |
32 | return DecisionTreeValue.UNSET; | 36 | return DecisionTreeValue.UNSET; |
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/IntermediateNode.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/IntermediateNode.java index 7165197c..a7486ecb 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/IntermediateNode.java +++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/IntermediateNode.java | |||
@@ -62,19 +62,43 @@ final class IntermediateNode extends DecisionTreeNode { | |||
62 | } | 62 | } |
63 | 63 | ||
64 | @Override | 64 | @Override |
65 | public void overwriteValues(DecisionTreeNode values) { | 65 | protected void doSetIfMissing(int key, int nextLevel, Tuple tuple, TruthValue value) { |
66 | if (values instanceof IntermediateNode intermediateValues) { | 66 | var child = children.get(key); |
67 | otherwise.overwriteValues(intermediateValues.otherwise); | 67 | if (child == null) { |
68 | for (var pair : children.keyValuesView()) { | 68 | var otherwiseReducedValue = getOtherwiseReducedValue(); |
69 | pair.getTwo().overwriteValues(intermediateValues.getChild(pair.getOne())); | 69 | if (otherwiseReducedValue != null && otherwiseReducedValue != DecisionTreeValue.UNSET) { |
70 | } | 70 | // Value already set. |
71 | for (var pair : intermediateValues.children.keyValuesView()) { | 71 | return; |
72 | children.getIfAbsentPut(pair.getOne(), () -> otherwise.withOverwrittenValues(pair.getTwo())); | ||
73 | } | 72 | } |
74 | reduceChildren(); | 73 | var newChild = otherwise.withValueSetIfMissing(nextLevel, tuple, value); |
75 | } else { | 74 | children.put(key, newChild); |
75 | return; | ||
76 | } | ||
77 | child.setIfMissing(nextLevel, tuple, value); | ||
78 | } | ||
79 | |||
80 | @Override | ||
81 | public void setAllMissing(TruthValue value) { | ||
82 | otherwise.setAllMissing(value); | ||
83 | for (var child : children) { | ||
84 | child.setAllMissing(value); | ||
85 | } | ||
86 | reduceChildren(); | ||
87 | } | ||
88 | |||
89 | @Override | ||
90 | public void overwriteValues(DecisionTreeNode values) { | ||
91 | if (!(values instanceof IntermediateNode intermediateValues)) { | ||
76 | throw new IllegalArgumentException("Level mismatch"); | 92 | throw new IllegalArgumentException("Level mismatch"); |
77 | } | 93 | } |
94 | otherwise.overwriteValues(intermediateValues.otherwise); | ||
95 | for (var pair : children.keyValuesView()) { | ||
96 | pair.getTwo().overwriteValues(intermediateValues.getChild(pair.getOne())); | ||
97 | } | ||
98 | for (var pair : intermediateValues.children.keyValuesView()) { | ||
99 | children.getIfAbsentPut(pair.getOne(), () -> otherwise.withOverwrittenValues(pair.getTwo())); | ||
100 | } | ||
101 | reduceChildren(); | ||
78 | } | 102 | } |
79 | 103 | ||
80 | private void reduceChildren() { | 104 | private void reduceChildren() { |
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/TerminalNode.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/TerminalNode.java index f3adea61..c0197e89 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/TerminalNode.java +++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/TerminalNode.java | |||
@@ -8,18 +8,18 @@ import tools.refinery.store.tuple.Tuple; | |||
8 | import tools.refinery.store.model.representation.TruthValue; | 8 | import tools.refinery.store.model.representation.TruthValue; |
9 | 9 | ||
10 | class TerminalNode extends DecisionTreeNode { | 10 | class TerminalNode extends DecisionTreeNode { |
11 | private MutableIntObjectMap<DecisionTreeValue> children; | 11 | private MutableIntObjectMap<TruthValue> children; |
12 | 12 | ||
13 | private DecisionTreeValue otherwise; | 13 | private DecisionTreeValue otherwise; |
14 | 14 | ||
15 | TerminalNode(MutableIntObjectMap<DecisionTreeValue> children, DecisionTreeValue otherwise) { | 15 | TerminalNode(MutableIntObjectMap<TruthValue> children, DecisionTreeValue otherwise) { |
16 | this.children = children; | 16 | this.children = children; |
17 | this.otherwise = otherwise; | 17 | this.otherwise = otherwise; |
18 | } | 18 | } |
19 | 19 | ||
20 | private DecisionTreeValue getChild(int index) { | 20 | private DecisionTreeValue getChild(int index) { |
21 | var child = children.get(index); | 21 | var child = children.get(index); |
22 | return child == null ? otherwise : child; | 22 | return child == null ? otherwise : DecisionTreeValue.fromTruthValue(child); |
23 | } | 23 | } |
24 | 24 | ||
25 | @Override | 25 | @Override |
@@ -41,7 +41,7 @@ class TerminalNode extends DecisionTreeNode { | |||
41 | 41 | ||
42 | @Override | 42 | @Override |
43 | protected void mergeAllValues(int nextLevel, Tuple tuple, TruthValue value) { | 43 | protected void mergeAllValues(int nextLevel, Tuple tuple, TruthValue value) { |
44 | otherwise = otherwise.merge(value); | 44 | otherwise = DecisionTreeValue.fromTruthValue(otherwise.merge(value)); |
45 | children = IntObjectMaps.mutable.from(children.keyValuesView(), IntObjectPair::getOne, | 45 | children = IntObjectMaps.mutable.from(children.keyValuesView(), IntObjectPair::getOne, |
46 | pair -> pair.getTwo().merge(value)); | 46 | pair -> pair.getTwo().merge(value)); |
47 | reduceChildren(); | 47 | reduceChildren(); |
@@ -50,7 +50,7 @@ class TerminalNode extends DecisionTreeNode { | |||
50 | @Override | 50 | @Override |
51 | protected void mergeSingleValue(int key, int nextLevel, Tuple tuple, TruthValue value) { | 51 | protected void mergeSingleValue(int key, int nextLevel, Tuple tuple, TruthValue value) { |
52 | var newChild = getChild(key).merge(value); | 52 | var newChild = getChild(key).merge(value); |
53 | if (newChild == otherwise) { | 53 | if (otherwise.getTruthValue() == newChild) { |
54 | children.remove(key); | 54 | children.remove(key); |
55 | } else { | 55 | } else { |
56 | children.put(key, newChild); | 56 | children.put(key, newChild); |
@@ -58,25 +58,45 @@ class TerminalNode extends DecisionTreeNode { | |||
58 | } | 58 | } |
59 | 59 | ||
60 | @Override | 60 | @Override |
61 | public void overwriteValues(DecisionTreeNode values) { | 61 | public void setIfMissing(int level, Tuple tuple, TruthValue value) { |
62 | if (values instanceof TerminalNode terminalValues) { | 62 | assertLevel(level); |
63 | otherwise = otherwise.overwrite(terminalValues.otherwise); | 63 | super.setIfMissing(level, tuple, value); |
64 | children = IntObjectMaps.mutable.from(children.keyValuesView(), IntObjectPair::getOne, | 64 | } |
65 | pair -> pair.getTwo().overwrite(terminalValues.getChild(pair.getOne()))); | 65 | |
66 | for (var pair : terminalValues.children.keyValuesView()) { | 66 | @Override |
67 | children.getIfAbsentPut(pair.getOne(), otherwise.overwrite(pair.getTwo())); | 67 | protected void doSetIfMissing(int key, int nextLevel, Tuple tuple, TruthValue value) { |
68 | } | 68 | if (otherwise == DecisionTreeValue.UNSET) { |
69 | children.getIfAbsentPut(key, value); | ||
70 | } | ||
71 | } | ||
72 | |||
73 | @Override | ||
74 | public void setAllMissing(TruthValue value) { | ||
75 | if (otherwise == DecisionTreeValue.UNSET) { | ||
76 | otherwise = DecisionTreeValue.fromTruthValue(value); | ||
69 | reduceChildren(); | 77 | reduceChildren(); |
70 | } else { | 78 | } |
79 | } | ||
80 | |||
81 | @Override | ||
82 | public void overwriteValues(DecisionTreeNode values) { | ||
83 | if (!(values instanceof TerminalNode terminalValues)) { | ||
71 | throw new IllegalArgumentException("Level mismatch"); | 84 | throw new IllegalArgumentException("Level mismatch"); |
72 | } | 85 | } |
86 | otherwise = otherwise.overwrite(terminalValues.otherwise); | ||
87 | children = IntObjectMaps.mutable.from(children.keyValuesView(), IntObjectPair::getOne, | ||
88 | pair -> terminalValues.getChild(pair.getOne()).getTruthValueOrElse(pair.getTwo())); | ||
89 | for (var pair : terminalValues.children.keyValuesView()) { | ||
90 | children.getIfAbsentPut(pair.getOne(), pair.getTwo()); | ||
91 | } | ||
92 | reduceChildren(); | ||
73 | } | 93 | } |
74 | 94 | ||
75 | private void reduceChildren() { | 95 | private void reduceChildren() { |
76 | var iterator = children.iterator(); | 96 | var iterator = children.iterator(); |
77 | while (iterator.hasNext()) { | 97 | while (iterator.hasNext()) { |
78 | var child = iterator.next(); | 98 | var child = iterator.next(); |
79 | if (child == otherwise) { | 99 | if (otherwise.getTruthValue() == child) { |
80 | iterator.remove(); | 100 | iterator.remove(); |
81 | } | 101 | } |
82 | } | 102 | } |
diff --git a/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/model/tests/DecisionTreeTests.java b/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/model/tests/DecisionTreeTests.java index 5268eb8a..f171e5c7 100644 --- a/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/model/tests/DecisionTreeTests.java +++ b/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/model/tests/DecisionTreeTests.java | |||
@@ -2,14 +2,15 @@ package tools.refinery.language.semantics.model.tests; | |||
2 | 2 | ||
3 | import org.junit.jupiter.api.Test; | 3 | import org.junit.jupiter.api.Test; |
4 | import tools.refinery.language.semantics.model.internal.DecisionTree; | 4 | import tools.refinery.language.semantics.model.internal.DecisionTree; |
5 | import tools.refinery.store.tuple.Tuple; | ||
6 | import tools.refinery.store.model.representation.TruthValue; | 5 | import tools.refinery.store.model.representation.TruthValue; |
6 | import tools.refinery.store.tuple.Tuple; | ||
7 | 7 | ||
8 | import java.util.LinkedHashMap; | 8 | import java.util.LinkedHashMap; |
9 | import java.util.Map; | 9 | import java.util.Map; |
10 | 10 | ||
11 | import static org.hamcrest.MatcherAssert.assertThat; | 11 | import static org.hamcrest.MatcherAssert.assertThat; |
12 | import static org.hamcrest.Matchers.*; | 12 | import static org.hamcrest.Matchers.*; |
13 | import static org.junit.jupiter.api.Assertions.assertThrows; | ||
13 | 14 | ||
14 | class DecisionTreeTests { | 15 | class DecisionTreeTests { |
15 | @Test | 16 | @Test |
@@ -165,6 +166,25 @@ class DecisionTreeTests { | |||
165 | } | 166 | } |
166 | 167 | ||
167 | @Test | 168 | @Test |
169 | void reducedValueEmptyTest() { | ||
170 | var sut = new DecisionTree(2, TruthValue.TRUE); | ||
171 | assertThat(sut.getReducedValue(), is(TruthValue.TRUE)); | ||
172 | } | ||
173 | |||
174 | @Test | ||
175 | void reducedValueUnsetTest() { | ||
176 | var sut = new DecisionTree(2); | ||
177 | assertThat(sut.getReducedValue(), is(nullValue())); | ||
178 | } | ||
179 | |||
180 | @Test | ||
181 | void reducedValueNonEmptyTest() { | ||
182 | var sut = new DecisionTree(2, TruthValue.UNKNOWN); | ||
183 | sut.mergeValue(Tuple.of(1, 2), TruthValue.TRUE); | ||
184 | assertThat(sut.getReducedValue(), is(nullValue())); | ||
185 | } | ||
186 | |||
187 | @Test | ||
168 | void removeIntermediateChildTest() { | 188 | void removeIntermediateChildTest() { |
169 | var sut = new DecisionTree(3, TruthValue.TRUE); | 189 | var sut = new DecisionTree(3, TruthValue.TRUE); |
170 | var values = new DecisionTree(3, null); | 190 | var values = new DecisionTree(3, null); |
@@ -172,6 +192,73 @@ class DecisionTreeTests { | |||
172 | sut.overwriteValues(values); | 192 | sut.overwriteValues(values); |
173 | sut.mergeValue(Tuple.of(1, 1, 1), TruthValue.TRUE); | 193 | sut.mergeValue(Tuple.of(1, 1, 1), TruthValue.TRUE); |
174 | assertThat(sut.get(Tuple.of(1, 1, 1)), is(TruthValue.TRUE)); | 194 | assertThat(sut.get(Tuple.of(1, 1, 1)), is(TruthValue.TRUE)); |
195 | assertThat(sut.getReducedValue(), is(TruthValue.TRUE)); | ||
196 | } | ||
197 | |||
198 | @Test | ||
199 | void setMissingValueTest() { | ||
200 | var sut = new DecisionTree(2); | ||
201 | sut.setIfMissing(Tuple.of(0, 0), TruthValue.FALSE); | ||
202 | assertThat(sut.get(Tuple.of(0, 0)), is(TruthValue.FALSE)); | ||
203 | } | ||
204 | |||
205 | @Test | ||
206 | void setNotMissingValueTest() { | ||
207 | var sut = new DecisionTree(2); | ||
208 | sut.mergeValue(Tuple.of(0, 0), TruthValue.TRUE); | ||
209 | sut.setIfMissing(Tuple.of(0, 0), TruthValue.FALSE); | ||
210 | assertThat(sut.get(Tuple.of(0, 0)), is(TruthValue.TRUE)); | ||
211 | } | ||
212 | |||
213 | @Test | ||
214 | void setNotMissingDefaultValueTest() { | ||
215 | var sut = new DecisionTree(2, TruthValue.TRUE); | ||
216 | sut.setIfMissing(Tuple.of(0, 0), TruthValue.FALSE); | ||
217 | assertThat(sut.get(Tuple.of(0, 0)), is(TruthValue.TRUE)); | ||
218 | } | ||
219 | |||
220 | @Test | ||
221 | void setMissingValueWildcardTest() { | ||
222 | var sut = new DecisionTree(2); | ||
223 | sut.mergeValue(Tuple.of(-1, 0), TruthValue.TRUE); | ||
224 | sut.mergeValue(Tuple.of(1, -1), TruthValue.TRUE); | ||
225 | sut.setIfMissing(Tuple.of(0, 0), TruthValue.FALSE); | ||
226 | sut.setIfMissing(Tuple.of(1, 1), TruthValue.FALSE); | ||
227 | sut.setIfMissing(Tuple.of(2, 2), TruthValue.FALSE); | ||
228 | assertThat(sut.get(Tuple.of(0, 0)), is(TruthValue.TRUE)); | ||
229 | assertThat(sut.get(Tuple.of(1, 1)), is(TruthValue.TRUE)); | ||
230 | assertThat(sut.get(Tuple.of(2, 2)), is(TruthValue.FALSE)); | ||
231 | assertThat(sut.get(Tuple.of(2, 3)), is(nullValue())); | ||
232 | } | ||
233 | |||
234 | @Test | ||
235 | void setMissingValueInvalidTupleTest() { | ||
236 | var sut = new DecisionTree(2); | ||
237 | var tuple = Tuple.of(-1, -1); | ||
238 | assertThrows(IllegalArgumentException.class, () -> sut.setIfMissing(tuple, TruthValue.TRUE)); | ||
239 | } | ||
240 | |||
241 | @Test | ||
242 | void setAllMissingTest() { | ||
243 | var sut = new DecisionTree(2); | ||
244 | sut.mergeValue(Tuple.of(-1, 0), TruthValue.TRUE); | ||
245 | sut.mergeValue(Tuple.of(1, -1), TruthValue.TRUE); | ||
246 | sut.mergeValue(Tuple.of(2, 2), TruthValue.TRUE); | ||
247 | sut.setAllMissing(TruthValue.FALSE); | ||
248 | assertThat(sut.get(Tuple.of(0, 0)), is(TruthValue.TRUE)); | ||
249 | assertThat(sut.get(Tuple.of(2, 0)), is(TruthValue.TRUE)); | ||
250 | assertThat(sut.get(Tuple.of(1, 1)), is(TruthValue.TRUE)); | ||
251 | assertThat(sut.get(Tuple.of(1, 2)), is(TruthValue.TRUE)); | ||
252 | assertThat(sut.get(Tuple.of(2, 2)), is(TruthValue.TRUE)); | ||
253 | assertThat(sut.get(Tuple.of(2, 3)), is(TruthValue.FALSE)); | ||
254 | assertThat(sut.get(Tuple.of(3, 2)), is(TruthValue.FALSE)); | ||
255 | } | ||
256 | |||
257 | @Test | ||
258 | void setAllMissingEmptyTest() { | ||
259 | var sut = new DecisionTree(2); | ||
260 | sut.setAllMissing(TruthValue.TRUE); | ||
261 | assertThat(sut.getReducedValue(), is(TruthValue.TRUE)); | ||
175 | } | 262 | } |
176 | 263 | ||
177 | private Map<Tuple, TruthValue> iterateAll(DecisionTree sut, TruthValue defaultValue, int nodeCount) { | 264 | private Map<Tuple, TruthValue> iterateAll(DecisionTree sut, TruthValue defaultValue, int nodeCount) { |