diff options
Diffstat (limited to 'subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/model/internal/DecisionTreeTests.java')
-rw-r--r-- | subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/model/internal/DecisionTreeTests.java | 289 |
1 files changed, 289 insertions, 0 deletions
diff --git a/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/model/internal/DecisionTreeTests.java b/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/model/internal/DecisionTreeTests.java new file mode 100644 index 00000000..5d039308 --- /dev/null +++ b/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/model/internal/DecisionTreeTests.java | |||
@@ -0,0 +1,289 @@ | |||
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.model.internal; | ||
7 | |||
8 | import org.junit.jupiter.api.Test; | ||
9 | import tools.refinery.store.representation.TruthValue; | ||
10 | import tools.refinery.store.tuple.Tuple; | ||
11 | |||
12 | import java.util.LinkedHashMap; | ||
13 | import java.util.Map; | ||
14 | |||
15 | import static org.hamcrest.MatcherAssert.assertThat; | ||
16 | import static org.hamcrest.Matchers.*; | ||
17 | import static org.junit.jupiter.api.Assertions.assertThrows; | ||
18 | |||
19 | class DecisionTreeTests { | ||
20 | @Test | ||
21 | void initialValueTest() { | ||
22 | var sut = new DecisionTree(3, TruthValue.UNKNOWN); | ||
23 | assertThat(sut.get(Tuple.of(3, 4, 5)), is(TruthValue.UNKNOWN)); | ||
24 | } | ||
25 | |||
26 | @Test | ||
27 | void mergeValueTest() { | ||
28 | var sut = new DecisionTree(3, TruthValue.FALSE); | ||
29 | sut.mergeValue(Tuple.of(3, 4, 5), TruthValue.TRUE); | ||
30 | assertThat(sut.get(Tuple.of(3, 4, 5)), is(TruthValue.ERROR)); | ||
31 | assertThat(sut.get(Tuple.of(3, 4, 6)), is(TruthValue.FALSE)); | ||
32 | } | ||
33 | |||
34 | @Test | ||
35 | void mergeUnknownValueTest() { | ||
36 | var sut = new DecisionTree(3, TruthValue.FALSE); | ||
37 | sut.mergeValue(Tuple.of(3, 4, 5), TruthValue.UNKNOWN); | ||
38 | assertThat(sut.get(Tuple.of(3, 4, 5)), is(TruthValue.FALSE)); | ||
39 | } | ||
40 | |||
41 | @Test | ||
42 | void mergeWildcardTest() { | ||
43 | var sut = new DecisionTree(3, TruthValue.UNKNOWN); | ||
44 | sut.mergeValue(Tuple.of(3, -1, 5), TruthValue.TRUE); | ||
45 | sut.mergeValue(Tuple.of(-1, 4, 5), TruthValue.FALSE); | ||
46 | assertThat(sut.get(Tuple.of(2, 4, 5)), is(TruthValue.FALSE)); | ||
47 | assertThat(sut.get(Tuple.of(3, 4, 5)), is(TruthValue.ERROR)); | ||
48 | assertThat(sut.get(Tuple.of(3, 6, 5)), is(TruthValue.TRUE)); | ||
49 | assertThat(sut.get(Tuple.of(3, 4, 6)), is(TruthValue.UNKNOWN)); | ||
50 | } | ||
51 | |||
52 | @Test | ||
53 | void mergeWildcardTest2() { | ||
54 | var sut = new DecisionTree(3, TruthValue.UNKNOWN); | ||
55 | sut.mergeValue(Tuple.of(-1, 4, -1), TruthValue.FALSE); | ||
56 | sut.mergeValue(Tuple.of(3, -1, 5), TruthValue.TRUE); | ||
57 | assertThat(sut.get(Tuple.of(2, 4, 5)), is(TruthValue.FALSE)); | ||
58 | assertThat(sut.get(Tuple.of(3, 4, 5)), is(TruthValue.ERROR)); | ||
59 | assertThat(sut.get(Tuple.of(3, 6, 5)), is(TruthValue.TRUE)); | ||
60 | assertThat(sut.get(Tuple.of(3, 4, 6)), is(TruthValue.FALSE)); | ||
61 | assertThat(sut.get(Tuple.of(3, 5, 6)), is(TruthValue.UNKNOWN)); | ||
62 | } | ||
63 | |||
64 | @Test | ||
65 | void mergeWildcardTest3() { | ||
66 | var sut = new DecisionTree(3, TruthValue.UNKNOWN); | ||
67 | sut.mergeValue(Tuple.of(-1, 4, -1), TruthValue.FALSE); | ||
68 | sut.mergeValue(Tuple.of(3, -1, 5), TruthValue.TRUE); | ||
69 | sut.mergeValue(Tuple.of(-1, -1, -1), TruthValue.ERROR); | ||
70 | assertThat(sut.get(Tuple.of(2, 4, 5)), is(TruthValue.ERROR)); | ||
71 | assertThat(sut.get(Tuple.of(3, 4, 5)), is(TruthValue.ERROR)); | ||
72 | assertThat(sut.get(Tuple.of(3, 6, 5)), is(TruthValue.ERROR)); | ||
73 | assertThat(sut.get(Tuple.of(3, 4, 6)), is(TruthValue.ERROR)); | ||
74 | assertThat(sut.get(Tuple.of(3, 5, 6)), is(TruthValue.ERROR)); | ||
75 | } | ||
76 | |||
77 | @Test | ||
78 | void mergeOverUnsetTest() { | ||
79 | var sut = new DecisionTree(3, null); | ||
80 | sut.mergeValue(Tuple.of(-1, 4, 5), TruthValue.UNKNOWN); | ||
81 | sut.mergeValue(Tuple.of(3, -1, 5), TruthValue.FALSE); | ||
82 | assertThat(sut.get(Tuple.of(2, 4, 5)), is(TruthValue.UNKNOWN)); | ||
83 | assertThat(sut.get(Tuple.of(3, 4, 5)), is(TruthValue.FALSE)); | ||
84 | assertThat(sut.get(Tuple.of(3, 6, 5)), is(TruthValue.FALSE)); | ||
85 | assertThat(sut.get(Tuple.of(3, 4, 6)), is(nullValue())); | ||
86 | } | ||
87 | |||
88 | @Test | ||
89 | void emptyIterationTest() { | ||
90 | var sut = new DecisionTree(3, TruthValue.UNKNOWN); | ||
91 | var map = iterateAll(sut, TruthValue.UNKNOWN, 2); | ||
92 | assertThat(map.keySet(), hasSize(0)); | ||
93 | } | ||
94 | |||
95 | @Test | ||
96 | void completeIterationTest() { | ||
97 | var sut = new DecisionTree(3, TruthValue.UNKNOWN); | ||
98 | var map = iterateAll(sut, TruthValue.FALSE, 2); | ||
99 | assertThat(map.keySet(), hasSize(8)); | ||
100 | assertThat(map, hasEntry(Tuple.of(0, 0, 0), TruthValue.UNKNOWN)); | ||
101 | assertThat(map, hasEntry(Tuple.of(0, 0, 1), TruthValue.UNKNOWN)); | ||
102 | assertThat(map, hasEntry(Tuple.of(0, 1, 0), TruthValue.UNKNOWN)); | ||
103 | assertThat(map, hasEntry(Tuple.of(0, 1, 1), TruthValue.UNKNOWN)); | ||
104 | assertThat(map, hasEntry(Tuple.of(1, 0, 0), TruthValue.UNKNOWN)); | ||
105 | assertThat(map, hasEntry(Tuple.of(1, 0, 1), TruthValue.UNKNOWN)); | ||
106 | assertThat(map, hasEntry(Tuple.of(1, 1, 0), TruthValue.UNKNOWN)); | ||
107 | assertThat(map, hasEntry(Tuple.of(1, 1, 1), TruthValue.UNKNOWN)); | ||
108 | } | ||
109 | |||
110 | @Test | ||
111 | void mergedIterationTest() { | ||
112 | var sut = new DecisionTree(2, TruthValue.UNKNOWN); | ||
113 | sut.mergeValue(Tuple.of(1, -1), TruthValue.TRUE); | ||
114 | sut.mergeValue(Tuple.of(-1, 2), TruthValue.FALSE); | ||
115 | var map = iterateAll(sut, TruthValue.UNKNOWN, 3); | ||
116 | assertThat(map.keySet(), hasSize(5)); | ||
117 | assertThat(map, hasEntry(Tuple.of(0, 2), TruthValue.FALSE)); | ||
118 | assertThat(map, hasEntry(Tuple.of(1, 0), TruthValue.TRUE)); | ||
119 | assertThat(map, hasEntry(Tuple.of(1, 1), TruthValue.TRUE)); | ||
120 | assertThat(map, hasEntry(Tuple.of(1, 2), TruthValue.ERROR)); | ||
121 | assertThat(map, hasEntry(Tuple.of(2, 2), TruthValue.FALSE)); | ||
122 | } | ||
123 | |||
124 | @Test | ||
125 | void sparseIterationTest() { | ||
126 | var sut = new DecisionTree(2, null); | ||
127 | sut.mergeValue(Tuple.of(0, 0), TruthValue.TRUE); | ||
128 | sut.mergeValue(Tuple.of(1, 1), TruthValue.FALSE); | ||
129 | var map = iterateAll(sut, null, 10); | ||
130 | assertThat(map.keySet(), hasSize(2)); | ||
131 | assertThat(map, hasEntry(Tuple.of(0, 0), TruthValue.TRUE)); | ||
132 | assertThat(map, hasEntry(Tuple.of(1, 1), TruthValue.FALSE)); | ||
133 | } | ||
134 | |||
135 | @Test | ||
136 | void overwriteIterationTest() { | ||
137 | var sut = new DecisionTree(1, TruthValue.TRUE); | ||
138 | var overwrite = new DecisionTree(1, null); | ||
139 | overwrite.mergeValue(Tuple.of(0), TruthValue.UNKNOWN); | ||
140 | sut.overwriteValues(overwrite); | ||
141 | var map = iterateAll(sut, TruthValue.UNKNOWN, 2); | ||
142 | assertThat(map.keySet(), hasSize(1)); | ||
143 | assertThat(map, hasEntry(Tuple.of(1), TruthValue.TRUE)); | ||
144 | } | ||
145 | |||
146 | @Test | ||
147 | void overwriteNothingTest() { | ||
148 | var sut = new DecisionTree(2, TruthValue.UNKNOWN); | ||
149 | var values = new DecisionTree(2, null); | ||
150 | sut.overwriteValues(values); | ||
151 | assertThat(sut.get(Tuple.of(0, 0)), is(TruthValue.UNKNOWN)); | ||
152 | } | ||
153 | |||
154 | @Test | ||
155 | void overwriteEverythingTest() { | ||
156 | var sut = new DecisionTree(2, TruthValue.FALSE); | ||
157 | sut.mergeValue(Tuple.of(0, 0), TruthValue.ERROR); | ||
158 | var values = new DecisionTree(2, TruthValue.TRUE); | ||
159 | sut.overwriteValues(values); | ||
160 | assertThat(sut.get(Tuple.of(0, 0)), is(TruthValue.TRUE)); | ||
161 | assertThat(sut.get(Tuple.of(0, 1)), is(TruthValue.TRUE)); | ||
162 | } | ||
163 | |||
164 | @Test | ||
165 | void overwriteWildcardTest() { | ||
166 | var sut = new DecisionTree(3, TruthValue.UNKNOWN); | ||
167 | sut.mergeValue(Tuple.of(1, 1, 1), TruthValue.FALSE); | ||
168 | sut.mergeValue(Tuple.of(-1, 4, 5), TruthValue.FALSE); | ||
169 | sut.mergeValue(Tuple.of(3, -1, 5), TruthValue.TRUE); | ||
170 | var values = new DecisionTree(3, null); | ||
171 | values.mergeValue(Tuple.of(2, 2, 2), TruthValue.TRUE); | ||
172 | values.mergeValue(Tuple.of(-1, 4, 5), TruthValue.UNKNOWN); | ||
173 | values.mergeValue(Tuple.of(3, -1, 5), TruthValue.FALSE); | ||
174 | sut.overwriteValues(values); | ||
175 | assertThat(sut.get(Tuple.of(1, 1, 1)), is(TruthValue.FALSE)); | ||
176 | assertThat(sut.get(Tuple.of(2, 2, 2)), is(TruthValue.TRUE)); | ||
177 | assertThat(sut.get(Tuple.of(2, 4, 5)), is(TruthValue.UNKNOWN)); | ||
178 | assertThat(sut.get(Tuple.of(3, 4, 5)), is(TruthValue.FALSE)); | ||
179 | assertThat(sut.get(Tuple.of(3, 6, 5)), is(TruthValue.FALSE)); | ||
180 | assertThat(sut.get(Tuple.of(3, 4, 6)), is(TruthValue.UNKNOWN)); | ||
181 | } | ||
182 | |||
183 | @Test | ||
184 | void reducedValueEmptyTest() { | ||
185 | var sut = new DecisionTree(2, TruthValue.TRUE); | ||
186 | assertThat(sut.getReducedValue(), is(TruthValue.TRUE)); | ||
187 | } | ||
188 | |||
189 | @Test | ||
190 | void reducedValueUnsetTest() { | ||
191 | var sut = new DecisionTree(2); | ||
192 | assertThat(sut.getReducedValue(), is(nullValue())); | ||
193 | } | ||
194 | |||
195 | @Test | ||
196 | void reducedValueNonEmptyTest() { | ||
197 | var sut = new DecisionTree(2, TruthValue.UNKNOWN); | ||
198 | sut.mergeValue(Tuple.of(1, 2), TruthValue.TRUE); | ||
199 | assertThat(sut.getReducedValue(), is(nullValue())); | ||
200 | } | ||
201 | |||
202 | @Test | ||
203 | void removeIntermediateChildTest() { | ||
204 | var sut = new DecisionTree(3, TruthValue.TRUE); | ||
205 | var values = new DecisionTree(3, null); | ||
206 | values.mergeValue(Tuple.of(1, 1, 1), TruthValue.UNKNOWN); | ||
207 | sut.overwriteValues(values); | ||
208 | sut.mergeValue(Tuple.of(1, 1, 1), TruthValue.TRUE); | ||
209 | assertThat(sut.get(Tuple.of(1, 1, 1)), is(TruthValue.TRUE)); | ||
210 | assertThat(sut.getReducedValue(), is(TruthValue.TRUE)); | ||
211 | } | ||
212 | |||
213 | @Test | ||
214 | void setMissingValueTest() { | ||
215 | var sut = new DecisionTree(2); | ||
216 | sut.setIfMissing(Tuple.of(0, 0), TruthValue.FALSE); | ||
217 | assertThat(sut.get(Tuple.of(0, 0)), is(TruthValue.FALSE)); | ||
218 | } | ||
219 | |||
220 | @Test | ||
221 | void setNotMissingValueTest() { | ||
222 | var sut = new DecisionTree(2); | ||
223 | sut.mergeValue(Tuple.of(0, 0), TruthValue.TRUE); | ||
224 | sut.setIfMissing(Tuple.of(0, 0), TruthValue.FALSE); | ||
225 | assertThat(sut.get(Tuple.of(0, 0)), is(TruthValue.TRUE)); | ||
226 | } | ||
227 | |||
228 | @Test | ||
229 | void setNotMissingDefaultValueTest() { | ||
230 | var sut = new DecisionTree(2, TruthValue.TRUE); | ||
231 | sut.setIfMissing(Tuple.of(0, 0), TruthValue.FALSE); | ||
232 | assertThat(sut.get(Tuple.of(0, 0)), is(TruthValue.TRUE)); | ||
233 | } | ||
234 | |||
235 | @Test | ||
236 | void setMissingValueWildcardTest() { | ||
237 | var sut = new DecisionTree(2); | ||
238 | sut.mergeValue(Tuple.of(-1, 0), TruthValue.TRUE); | ||
239 | sut.mergeValue(Tuple.of(1, -1), TruthValue.TRUE); | ||
240 | sut.setIfMissing(Tuple.of(0, 0), TruthValue.FALSE); | ||
241 | sut.setIfMissing(Tuple.of(1, 1), TruthValue.FALSE); | ||
242 | sut.setIfMissing(Tuple.of(2, 2), TruthValue.FALSE); | ||
243 | assertThat(sut.get(Tuple.of(0, 0)), is(TruthValue.TRUE)); | ||
244 | assertThat(sut.get(Tuple.of(1, 1)), is(TruthValue.TRUE)); | ||
245 | assertThat(sut.get(Tuple.of(2, 2)), is(TruthValue.FALSE)); | ||
246 | assertThat(sut.get(Tuple.of(2, 3)), is(nullValue())); | ||
247 | } | ||
248 | |||
249 | @Test | ||
250 | void setMissingValueInvalidTupleTest() { | ||
251 | var sut = new DecisionTree(2); | ||
252 | var tuple = Tuple.of(-1, -1); | ||
253 | assertThrows(IllegalArgumentException.class, () -> sut.setIfMissing(tuple, TruthValue.TRUE)); | ||
254 | } | ||
255 | |||
256 | @Test | ||
257 | void setAllMissingTest() { | ||
258 | var sut = new DecisionTree(2); | ||
259 | sut.mergeValue(Tuple.of(-1, 0), TruthValue.TRUE); | ||
260 | sut.mergeValue(Tuple.of(1, -1), TruthValue.TRUE); | ||
261 | sut.mergeValue(Tuple.of(2, 2), TruthValue.TRUE); | ||
262 | sut.setAllMissing(TruthValue.FALSE); | ||
263 | assertThat(sut.get(Tuple.of(0, 0)), is(TruthValue.TRUE)); | ||
264 | assertThat(sut.get(Tuple.of(2, 0)), is(TruthValue.TRUE)); | ||
265 | assertThat(sut.get(Tuple.of(1, 1)), is(TruthValue.TRUE)); | ||
266 | assertThat(sut.get(Tuple.of(1, 2)), is(TruthValue.TRUE)); | ||
267 | assertThat(sut.get(Tuple.of(2, 2)), is(TruthValue.TRUE)); | ||
268 | assertThat(sut.get(Tuple.of(2, 3)), is(TruthValue.FALSE)); | ||
269 | assertThat(sut.get(Tuple.of(3, 2)), is(TruthValue.FALSE)); | ||
270 | } | ||
271 | |||
272 | @Test | ||
273 | void setAllMissingEmptyTest() { | ||
274 | var sut = new DecisionTree(2); | ||
275 | sut.setAllMissing(TruthValue.TRUE); | ||
276 | assertThat(sut.getReducedValue(), is(TruthValue.TRUE)); | ||
277 | } | ||
278 | |||
279 | private Map<Tuple, TruthValue> iterateAll(DecisionTree sut, TruthValue defaultValue, int nodeCount) { | ||
280 | var cursor = sut.getCursor(defaultValue, nodeCount); | ||
281 | var map = new LinkedHashMap<Tuple, TruthValue>(); | ||
282 | while (cursor.move()) { | ||
283 | map.put(cursor.getKey(), cursor.getValue()); | ||
284 | } | ||
285 | assertThat(cursor.isDirty(), is(false)); | ||
286 | assertThat(cursor.isTerminated(), is(true)); | ||
287 | return map; | ||
288 | } | ||
289 | } | ||