diff options
Diffstat (limited to 'subprojects/store-query/src/main/java/tools/refinery/store/query/view/AbstractFunctionView.java')
-rw-r--r-- | subprojects/store-query/src/main/java/tools/refinery/store/query/view/AbstractFunctionView.java | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/AbstractFunctionView.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/AbstractFunctionView.java new file mode 100644 index 00000000..c0aa35bf --- /dev/null +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/AbstractFunctionView.java | |||
@@ -0,0 +1,116 @@ | |||
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.store.query.view; | ||
7 | |||
8 | import tools.refinery.store.model.Model; | ||
9 | import tools.refinery.store.query.dnf.FunctionalDependency; | ||
10 | import tools.refinery.store.query.term.NodeSort; | ||
11 | import tools.refinery.store.query.term.Sort; | ||
12 | import tools.refinery.store.representation.Symbol; | ||
13 | import tools.refinery.store.tuple.Tuple; | ||
14 | import tools.refinery.store.tuple.Tuple1; | ||
15 | |||
16 | import java.util.List; | ||
17 | import java.util.Objects; | ||
18 | import java.util.Set; | ||
19 | import java.util.stream.Collectors; | ||
20 | import java.util.stream.IntStream; | ||
21 | |||
22 | public abstract class AbstractFunctionView<T> extends SymbolView<T> { | ||
23 | private final T defaultValue; | ||
24 | |||
25 | protected AbstractFunctionView(Symbol<T> symbol, String name) { | ||
26 | super(symbol, name); | ||
27 | defaultValue = symbol.defaultValue(); | ||
28 | } | ||
29 | |||
30 | @Override | ||
31 | public Set<FunctionalDependency<Integer>> getFunctionalDependencies() { | ||
32 | var arity = getSymbol().arity(); | ||
33 | var forEach = IntStream.range(0, arity).boxed().collect(Collectors.toUnmodifiableSet()); | ||
34 | var unique = Set.of(arity); | ||
35 | return Set.of(new FunctionalDependency<>(forEach, unique)); | ||
36 | } | ||
37 | |||
38 | @Override | ||
39 | public Set<ViewImplication> getImpliedRelationViews() { | ||
40 | var symbol = getSymbol(); | ||
41 | var impliedIndices = IntStream.range(0, symbol.arity()).boxed().toList(); | ||
42 | var keysView = new KeyOnlyView<>(symbol); | ||
43 | return Set.of(new ViewImplication(this, keysView, impliedIndices)); | ||
44 | } | ||
45 | |||
46 | @Override | ||
47 | public final boolean filter(Tuple key, T value) { | ||
48 | return !Objects.equals(defaultValue, value); | ||
49 | } | ||
50 | |||
51 | protected abstract Sort getForwardMappedValueSort(); | ||
52 | |||
53 | protected Object forwardMapValue(Tuple key, T value) { | ||
54 | return value; | ||
55 | } | ||
56 | |||
57 | protected boolean valueEquals(Tuple key, T value, Object otherForwardMappedValue) { | ||
58 | return Objects.equals(otherForwardMappedValue, forwardMapValue(key, value)); | ||
59 | } | ||
60 | |||
61 | @Override | ||
62 | public Object[] forwardMap(Tuple key, T value) { | ||
63 | int size = key.getSize(); | ||
64 | Object[] result = new Object[size + 1]; | ||
65 | for (int i = 0; i < size; i++) { | ||
66 | result[i] = Tuple.of(key.get(i)); | ||
67 | } | ||
68 | result[key.getSize()] = forwardMapValue(key, value); | ||
69 | return result; | ||
70 | } | ||
71 | |||
72 | @Override | ||
73 | public boolean get(Model model, Object[] tuple) { | ||
74 | int[] content = new int[tuple.length - 1]; | ||
75 | for (int i = 0; i < tuple.length - 1; i++) { | ||
76 | if (!(tuple[i] instanceof Tuple1 wrapper)) { | ||
77 | return false; | ||
78 | } | ||
79 | content[i] = wrapper.value0(); | ||
80 | } | ||
81 | Tuple key = Tuple.of(content); | ||
82 | var valueInTuple = tuple[tuple.length - 1]; | ||
83 | T valueInMap = model.getInterpretation(getSymbol()).get(key); | ||
84 | return valueEquals(key, valueInMap, valueInTuple); | ||
85 | } | ||
86 | |||
87 | @Override | ||
88 | public int arity() { | ||
89 | return getSymbol().arity() + 1; | ||
90 | } | ||
91 | |||
92 | @Override | ||
93 | public List<Sort> getSorts() { | ||
94 | var sorts = new Sort[arity()]; | ||
95 | int valueIndex = sorts.length - 1; | ||
96 | for (int i = 0; i < valueIndex; i++) { | ||
97 | sorts[i] = NodeSort.INSTANCE; | ||
98 | } | ||
99 | sorts[valueIndex] = getForwardMappedValueSort(); | ||
100 | return List.of(sorts); | ||
101 | } | ||
102 | |||
103 | @Override | ||
104 | public boolean equals(Object o) { | ||
105 | if (this == o) return true; | ||
106 | if (o == null || getClass() != o.getClass()) return false; | ||
107 | if (!super.equals(o)) return false; | ||
108 | AbstractFunctionView<?> that = (AbstractFunctionView<?>) o; | ||
109 | return Objects.equals(defaultValue, that.defaultValue); | ||
110 | } | ||
111 | |||
112 | @Override | ||
113 | public int hashCode() { | ||
114 | return Objects.hash(super.hashCode(), defaultValue); | ||
115 | } | ||
116 | } | ||