diff options
Diffstat (limited to 'subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/seed/MapBasedSeed.java')
-rw-r--r-- | subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/seed/MapBasedSeed.java | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/seed/MapBasedSeed.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/seed/MapBasedSeed.java new file mode 100644 index 00000000..8b1c3bb3 --- /dev/null +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/seed/MapBasedSeed.java | |||
@@ -0,0 +1,111 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.reasoning.seed; | ||
7 | |||
8 | import tools.refinery.store.map.Cursor; | ||
9 | import tools.refinery.store.map.Cursors; | ||
10 | import tools.refinery.store.tuple.Tuple; | ||
11 | |||
12 | import java.util.Map; | ||
13 | import java.util.Objects; | ||
14 | |||
15 | record MapBasedSeed<T>(int arity, Class<T> valueType, T reducedValue, Map<Tuple, T> map) implements Seed<T> { | ||
16 | @Override | ||
17 | public T get(Tuple key) { | ||
18 | var value = map.get(key); | ||
19 | return value == null ? reducedValue : value; | ||
20 | } | ||
21 | |||
22 | @Override | ||
23 | public Cursor<Tuple, T> getCursor(T defaultValue, int nodeCount) { | ||
24 | if (Objects.equals(defaultValue, reducedValue)) { | ||
25 | return Cursors.of(map); | ||
26 | } | ||
27 | return new CartesianProductCursor<>(arity, nodeCount, reducedValue, defaultValue, map); | ||
28 | } | ||
29 | |||
30 | private static class CartesianProductCursor<T> implements Cursor<Tuple, T> { | ||
31 | private final int nodeCount; | ||
32 | private final T reducedValue; | ||
33 | private final T defaultValue; | ||
34 | private final Map<Tuple, T> map; | ||
35 | private final int[] counter; | ||
36 | private State state = State.INITIAL; | ||
37 | private Tuple key; | ||
38 | private T value; | ||
39 | |||
40 | private CartesianProductCursor(int arity, int nodeCount, T reducedValue, T defaultValue, Map<Tuple, T> map) { | ||
41 | this.nodeCount = nodeCount; | ||
42 | this.reducedValue = reducedValue; | ||
43 | this.defaultValue = defaultValue; | ||
44 | this.map = map; | ||
45 | counter = new int[arity]; | ||
46 | } | ||
47 | |||
48 | @Override | ||
49 | public Tuple getKey() { | ||
50 | return key; | ||
51 | } | ||
52 | |||
53 | @Override | ||
54 | public T getValue() { | ||
55 | return value; | ||
56 | } | ||
57 | |||
58 | @Override | ||
59 | public boolean isTerminated() { | ||
60 | return state == State.TERMINATED; | ||
61 | } | ||
62 | |||
63 | @Override | ||
64 | public boolean move() { | ||
65 | return switch (state) { | ||
66 | case INITIAL -> { | ||
67 | state = State.STARTED; | ||
68 | yield checkValue() || moveToNext(); | ||
69 | } | ||
70 | case STARTED -> moveToNext(); | ||
71 | case TERMINATED -> false; | ||
72 | }; | ||
73 | } | ||
74 | |||
75 | private boolean moveToNext() { | ||
76 | do { | ||
77 | increment(); | ||
78 | } while (state != State.TERMINATED && !checkValue()); | ||
79 | return state != State.TERMINATED; | ||
80 | } | ||
81 | |||
82 | private void increment() { | ||
83 | int i = counter.length - 1; | ||
84 | while (i >= 0) { | ||
85 | counter[i]++; | ||
86 | if (counter[i] < nodeCount) { | ||
87 | return; | ||
88 | } | ||
89 | counter[i] = 0; | ||
90 | i--; | ||
91 | } | ||
92 | state = State.TERMINATED; | ||
93 | } | ||
94 | |||
95 | private boolean checkValue() { | ||
96 | key = Tuple.of(counter); | ||
97 | var valueInMap = map.get(key); | ||
98 | if (Objects.equals(valueInMap, defaultValue)) { | ||
99 | return false; | ||
100 | } | ||
101 | value = valueInMap == null ? reducedValue : valueInMap; | ||
102 | return true; | ||
103 | } | ||
104 | |||
105 | private enum State { | ||
106 | INITIAL, | ||
107 | STARTED, | ||
108 | TERMINATED | ||
109 | } | ||
110 | } | ||
111 | } | ||