aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/store-query
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2023-04-10 19:18:29 +0200
committerLibravatar Kristóf Marussy <kristof@marussy.com>2023-04-15 17:15:50 +0200
commit7c15c0e6e6a035458bdd89a939aacdf4a207e1cd (patch)
treee9318d8f1c326c05ee981e4ec966fb3fcffd6afa /subprojects/store-query
parentbuild: add workflow for REUSE compliance check (diff)
downloadrefinery-7c15c0e6e6a035458bdd89a939aacdf4a207e1cd.tar.gz
refinery-7c15c0e6e6a035458bdd89a939aacdf4a207e1cd.tar.zst
refinery-7c15c0e6e6a035458bdd89a939aacdf4a207e1cd.zip
refactor: rename RelationView to SymbolView
* Add NodeFunctionView for symbols that hold function-like (single associated object for each key) relations as integer values for performance.
Diffstat (limited to 'subprojects/store-query')
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/ModelQueryStoreAdapter.java4
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/view/AbstractFunctionView.java (renamed from subprojects/store-query/src/main/java/tools/refinery/store/query/view/FunctionalRelationView.java)44
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/view/AnySymbolView.java (renamed from subprojects/store-query/src/main/java/tools/refinery/store/query/view/AnyRelationView.java)4
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/view/FilteredView.java (renamed from subprojects/store-query/src/main/java/tools/refinery/store/query/view/FilteredRelationView.java)12
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/view/ForbiddenView.java (renamed from subprojects/store-query/src/main/java/tools/refinery/store/query/view/ForbiddenRelationView.java)4
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/view/KeyOnlyView.java (renamed from subprojects/store-query/src/main/java/tools/refinery/store/query/view/KeyOnlyRelationView.java)6
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/view/MayView.java (renamed from subprojects/store-query/src/main/java/tools/refinery/store/query/view/MayRelationView.java)4
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/view/MustView.java (renamed from subprojects/store-query/src/main/java/tools/refinery/store/query/view/MustRelationView.java)4
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/view/RelationViewImplication.java24
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/view/SymbolView.java (renamed from subprojects/store-query/src/main/java/tools/refinery/store/query/view/RelationView.java)8
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/view/TuplePreservingView.java (renamed from subprojects/store-query/src/main/java/tools/refinery/store/query/view/TuplePreservingRelationView.java)11
-rw-r--r--subprojects/store-query/src/test/java/tools/refinery/store/query/DnfBuilderTest.java26
-rw-r--r--subprojects/store-query/src/test/java/tools/refinery/store/query/DnfToDefinitionStringTest.java20
-rw-r--r--subprojects/store-query/src/test/java/tools/refinery/store/query/tests/StructurallyEqualToTest.java10
14 files changed, 83 insertions, 98 deletions
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/ModelQueryStoreAdapter.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/ModelQueryStoreAdapter.java
index 33318abc..f0a950a6 100644
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/ModelQueryStoreAdapter.java
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/ModelQueryStoreAdapter.java
@@ -8,12 +8,12 @@ package tools.refinery.store.query;
8import tools.refinery.store.adapter.ModelStoreAdapter; 8import tools.refinery.store.adapter.ModelStoreAdapter;
9import tools.refinery.store.model.Model; 9import tools.refinery.store.model.Model;
10import tools.refinery.store.query.dnf.AnyQuery; 10import tools.refinery.store.query.dnf.AnyQuery;
11import tools.refinery.store.query.view.AnyRelationView; 11import tools.refinery.store.query.view.AnySymbolView;
12 12
13import java.util.Collection; 13import java.util.Collection;
14 14
15public interface ModelQueryStoreAdapter extends ModelStoreAdapter { 15public interface ModelQueryStoreAdapter extends ModelStoreAdapter {
16 Collection<AnyRelationView> getRelationViews(); 16 Collection<AnySymbolView> getSymbolViews();
17 17
18 Collection<AnyQuery> getQueries(); 18 Collection<AnyQuery> getQueries();
19 19
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/FunctionalRelationView.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/AbstractFunctionView.java
index ab48386e..c0aa35bf 100644
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/FunctionalRelationView.java
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/AbstractFunctionView.java
@@ -7,7 +7,6 @@ package tools.refinery.store.query.view;
7 7
8import tools.refinery.store.model.Model; 8import tools.refinery.store.model.Model;
9import tools.refinery.store.query.dnf.FunctionalDependency; 9import tools.refinery.store.query.dnf.FunctionalDependency;
10import tools.refinery.store.query.term.DataSort;
11import tools.refinery.store.query.term.NodeSort; 10import tools.refinery.store.query.term.NodeSort;
12import tools.refinery.store.query.term.Sort; 11import tools.refinery.store.query.term.Sort;
13import tools.refinery.store.representation.Symbol; 12import tools.refinery.store.representation.Symbol;
@@ -20,19 +19,14 @@ import java.util.Set;
20import java.util.stream.Collectors; 19import java.util.stream.Collectors;
21import java.util.stream.IntStream; 20import java.util.stream.IntStream;
22 21
23public final class FunctionalRelationView<T> extends RelationView<T> { 22public abstract class AbstractFunctionView<T> extends SymbolView<T> {
24 private final T defaultValue; 23 private final T defaultValue;
25 24
26 public FunctionalRelationView(Symbol<T> symbol, String name) { 25 protected AbstractFunctionView(Symbol<T> symbol, String name) {
27 super(symbol, name); 26 super(symbol, name);
28 defaultValue = symbol.defaultValue(); 27 defaultValue = symbol.defaultValue();
29 } 28 }
30 29
31 public FunctionalRelationView(Symbol<T> symbol) {
32 super(symbol);
33 defaultValue = symbol.defaultValue();
34 }
35
36 @Override 30 @Override
37 public Set<FunctionalDependency<Integer>> getFunctionalDependencies() { 31 public Set<FunctionalDependency<Integer>> getFunctionalDependencies() {
38 var arity = getSymbol().arity(); 32 var arity = getSymbol().arity();
@@ -42,18 +36,28 @@ public final class FunctionalRelationView<T> extends RelationView<T> {
42 } 36 }
43 37
44 @Override 38 @Override
45 public Set<RelationViewImplication> getImpliedRelationViews() { 39 public Set<ViewImplication> getImpliedRelationViews() {
46 var symbol = getSymbol(); 40 var symbol = getSymbol();
47 var impliedIndices = IntStream.range(0, symbol.arity()).boxed().toList(); 41 var impliedIndices = IntStream.range(0, symbol.arity()).boxed().toList();
48 var keyOnlyRelationView = new KeyOnlyRelationView<>(symbol); 42 var keysView = new KeyOnlyView<>(symbol);
49 return Set.of(new RelationViewImplication(this, keyOnlyRelationView, impliedIndices)); 43 return Set.of(new ViewImplication(this, keysView, impliedIndices));
50 } 44 }
51 45
52 @Override 46 @Override
53 public boolean filter(Tuple key, T value) { 47 public final boolean filter(Tuple key, T value) {
54 return !Objects.equals(defaultValue, value); 48 return !Objects.equals(defaultValue, value);
55 } 49 }
56 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
57 @Override 61 @Override
58 public Object[] forwardMap(Tuple key, T value) { 62 public Object[] forwardMap(Tuple key, T value) {
59 int size = key.getSize(); 63 int size = key.getSize();
@@ -61,7 +65,7 @@ public final class FunctionalRelationView<T> extends RelationView<T> {
61 for (int i = 0; i < size; i++) { 65 for (int i = 0; i < size; i++) {
62 result[i] = Tuple.of(key.get(i)); 66 result[i] = Tuple.of(key.get(i));
63 } 67 }
64 result[key.getSize()] = value; 68 result[key.getSize()] = forwardMapValue(key, value);
65 return result; 69 return result;
66 } 70 }
67 71
@@ -69,13 +73,15 @@ public final class FunctionalRelationView<T> extends RelationView<T> {
69 public boolean get(Model model, Object[] tuple) { 73 public boolean get(Model model, Object[] tuple) {
70 int[] content = new int[tuple.length - 1]; 74 int[] content = new int[tuple.length - 1];
71 for (int i = 0; i < tuple.length - 1; i++) { 75 for (int i = 0; i < tuple.length - 1; i++) {
72 content[i] = ((Tuple1) tuple[i]).value0(); 76 if (!(tuple[i] instanceof Tuple1 wrapper)) {
77 return false;
78 }
79 content[i] = wrapper.value0();
73 } 80 }
74 Tuple key = Tuple.of(content); 81 Tuple key = Tuple.of(content);
75 @SuppressWarnings("unchecked") 82 var valueInTuple = tuple[tuple.length - 1];
76 T valueInTuple = (T) tuple[tuple.length - 1];
77 T valueInMap = model.getInterpretation(getSymbol()).get(key); 83 T valueInMap = model.getInterpretation(getSymbol()).get(key);
78 return valueInTuple.equals(valueInMap); 84 return valueEquals(key, valueInMap, valueInTuple);
79 } 85 }
80 86
81 @Override 87 @Override
@@ -90,7 +96,7 @@ public final class FunctionalRelationView<T> extends RelationView<T> {
90 for (int i = 0; i < valueIndex; i++) { 96 for (int i = 0; i < valueIndex; i++) {
91 sorts[i] = NodeSort.INSTANCE; 97 sorts[i] = NodeSort.INSTANCE;
92 } 98 }
93 sorts[valueIndex] = new DataSort<>(getSymbol().valueType()); 99 sorts[valueIndex] = getForwardMappedValueSort();
94 return List.of(sorts); 100 return List.of(sorts);
95 } 101 }
96 102
@@ -99,7 +105,7 @@ public final class FunctionalRelationView<T> extends RelationView<T> {
99 if (this == o) return true; 105 if (this == o) return true;
100 if (o == null || getClass() != o.getClass()) return false; 106 if (o == null || getClass() != o.getClass()) return false;
101 if (!super.equals(o)) return false; 107 if (!super.equals(o)) return false;
102 FunctionalRelationView<?> that = (FunctionalRelationView<?>) o; 108 AbstractFunctionView<?> that = (AbstractFunctionView<?>) o;
103 return Objects.equals(defaultValue, that.defaultValue); 109 return Objects.equals(defaultValue, that.defaultValue);
104 } 110 }
105 111
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/AnyRelationView.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/AnySymbolView.java
index 9aa923af..90b27ebb 100644
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/AnyRelationView.java
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/AnySymbolView.java
@@ -12,7 +12,7 @@ import tools.refinery.store.query.Constraint;
12 12
13import java.util.Set; 13import java.util.Set;
14 14
15public sealed interface AnyRelationView extends Constraint permits RelationView { 15public sealed interface AnySymbolView extends Constraint permits SymbolView {
16 AnySymbol getSymbol(); 16 AnySymbol getSymbol();
17 17
18 String getViewName(); 18 String getViewName();
@@ -21,7 +21,7 @@ public sealed interface AnyRelationView extends Constraint permits RelationView
21 return Set.of(); 21 return Set.of();
22 } 22 }
23 23
24 default Set<RelationViewImplication> getImpliedRelationViews() { 24 default Set<ViewImplication> getImpliedRelationViews() {
25 return Set.of(); 25 return Set.of();
26 } 26 }
27 27
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/FilteredRelationView.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/FilteredView.java
index 9717b2c1..922c7355 100644
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/FilteredRelationView.java
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/FilteredView.java
@@ -12,24 +12,24 @@ import java.util.Objects;
12import java.util.function.BiPredicate; 12import java.util.function.BiPredicate;
13import java.util.function.Predicate; 13import java.util.function.Predicate;
14 14
15public class FilteredRelationView<T> extends TuplePreservingRelationView<T> { 15public class FilteredView<T> extends TuplePreservingView<T> {
16 private final BiPredicate<Tuple, T> predicate; 16 private final BiPredicate<Tuple, T> predicate;
17 17
18 public FilteredRelationView(Symbol<T> symbol, String name, BiPredicate<Tuple, T> predicate) { 18 public FilteredView(Symbol<T> symbol, String name, BiPredicate<Tuple, T> predicate) {
19 super(symbol, name); 19 super(symbol, name);
20 this.predicate = predicate; 20 this.predicate = predicate;
21 } 21 }
22 22
23 public FilteredRelationView(Symbol<T> symbol, BiPredicate<Tuple, T> predicate) { 23 public FilteredView(Symbol<T> symbol, BiPredicate<Tuple, T> predicate) {
24 super(symbol); 24 super(symbol);
25 this.predicate = predicate; 25 this.predicate = predicate;
26 } 26 }
27 27
28 public FilteredRelationView(Symbol<T> symbol, String name, Predicate<T> predicate) { 28 public FilteredView(Symbol<T> symbol, String name, Predicate<T> predicate) {
29 this(symbol, name, (k, v) -> predicate.test(v)); 29 this(symbol, name, (k, v) -> predicate.test(v));
30 } 30 }
31 31
32 public FilteredRelationView(Symbol<T> symbol, Predicate<T> predicate) { 32 public FilteredView(Symbol<T> symbol, Predicate<T> predicate) {
33 this(symbol, (k, v) -> predicate.test(v)); 33 this(symbol, (k, v) -> predicate.test(v));
34 } 34 }
35 35
@@ -43,7 +43,7 @@ public class FilteredRelationView<T> extends TuplePreservingRelationView<T> {
43 if (this == o) return true; 43 if (this == o) return true;
44 if (o == null || getClass() != o.getClass()) return false; 44 if (o == null || getClass() != o.getClass()) return false;
45 if (!super.equals(o)) return false; 45 if (!super.equals(o)) return false;
46 FilteredRelationView<?> that = (FilteredRelationView<?>) o; 46 FilteredView<?> that = (FilteredView<?>) o;
47 return Objects.equals(predicate, that.predicate); 47 return Objects.equals(predicate, that.predicate);
48 } 48 }
49 49
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/ForbiddenRelationView.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/ForbiddenView.java
index c19d9282..26b717ee 100644
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/ForbiddenRelationView.java
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/ForbiddenView.java
@@ -9,8 +9,8 @@ import tools.refinery.store.representation.Symbol;
9import tools.refinery.store.representation.TruthValue; 9import tools.refinery.store.representation.TruthValue;
10import tools.refinery.store.tuple.Tuple; 10import tools.refinery.store.tuple.Tuple;
11 11
12public class ForbiddenRelationView extends TuplePreservingRelationView<TruthValue> { 12public class ForbiddenView extends TuplePreservingView<TruthValue> {
13 public ForbiddenRelationView(Symbol<TruthValue> symbol) { 13 public ForbiddenView(Symbol<TruthValue> symbol) {
14 super(symbol, "forbidden"); 14 super(symbol, "forbidden");
15 } 15 }
16 16
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/KeyOnlyRelationView.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/KeyOnlyView.java
index 9553a0cc..7e86f6e4 100644
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/KeyOnlyRelationView.java
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/KeyOnlyView.java
@@ -10,12 +10,12 @@ import tools.refinery.store.tuple.Tuple;
10 10
11import java.util.Objects; 11import java.util.Objects;
12 12
13public final class KeyOnlyRelationView<T> extends TuplePreservingRelationView<T> { 13public final class KeyOnlyView<T> extends TuplePreservingView<T> {
14 public static final String VIEW_NAME = "key"; 14 public static final String VIEW_NAME = "key";
15 15
16 private final T defaultValue; 16 private final T defaultValue;
17 17
18 public KeyOnlyRelationView(Symbol<T> symbol) { 18 public KeyOnlyView(Symbol<T> symbol) {
19 super(symbol, VIEW_NAME); 19 super(symbol, VIEW_NAME);
20 defaultValue = symbol.defaultValue(); 20 defaultValue = symbol.defaultValue();
21 } 21 }
@@ -30,7 +30,7 @@ public final class KeyOnlyRelationView<T> extends TuplePreservingRelationView<T>
30 if (this == o) return true; 30 if (this == o) return true;
31 if (o == null || getClass() != o.getClass()) return false; 31 if (o == null || getClass() != o.getClass()) return false;
32 if (!super.equals(o)) return false; 32 if (!super.equals(o)) return false;
33 KeyOnlyRelationView<?> that = (KeyOnlyRelationView<?>) o; 33 KeyOnlyView<?> that = (KeyOnlyView<?>) o;
34 return Objects.equals(defaultValue, that.defaultValue); 34 return Objects.equals(defaultValue, that.defaultValue);
35 } 35 }
36 36
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/MayRelationView.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/MayView.java
index 60325f35..e75a8171 100644
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/MayRelationView.java
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/MayView.java
@@ -9,8 +9,8 @@ import tools.refinery.store.representation.Symbol;
9import tools.refinery.store.representation.TruthValue; 9import tools.refinery.store.representation.TruthValue;
10import tools.refinery.store.tuple.Tuple; 10import tools.refinery.store.tuple.Tuple;
11 11
12public class MayRelationView extends TuplePreservingRelationView<TruthValue> { 12public class MayView extends TuplePreservingView<TruthValue> {
13 public MayRelationView(Symbol<TruthValue> symbol) { 13 public MayView(Symbol<TruthValue> symbol) {
14 super(symbol, "may"); 14 super(symbol, "may");
15 } 15 }
16 16
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/MustRelationView.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/MustView.java
index d7e7ae2e..a48f8045 100644
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/MustRelationView.java
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/MustView.java
@@ -9,8 +9,8 @@ import tools.refinery.store.representation.Symbol;
9import tools.refinery.store.representation.TruthValue; 9import tools.refinery.store.representation.TruthValue;
10import tools.refinery.store.tuple.Tuple; 10import tools.refinery.store.tuple.Tuple;
11 11
12public class MustRelationView extends TuplePreservingRelationView<TruthValue> { 12public class MustView extends TuplePreservingView<TruthValue> {
13 public MustRelationView(Symbol<TruthValue> symbol) { 13 public MustView(Symbol<TruthValue> symbol) {
14 super(symbol, "must"); 14 super(symbol, "must");
15 } 15 }
16 16
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/RelationViewImplication.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/RelationViewImplication.java
deleted file mode 100644
index c54cce2f..00000000
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/RelationViewImplication.java
+++ /dev/null
@@ -1,24 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.query.view;
7
8import java.util.List;
9
10public record RelationViewImplication(AnyRelationView implyingRelationView, AnyRelationView impliedRelationView,
11 List<Integer> impliedIndices) {
12 public RelationViewImplication {
13 if (impliedIndices.size() != impliedRelationView.arity()) {
14 throw new IllegalArgumentException("Expected %d implied indices for %s, but %d are provided"
15 .formatted(impliedRelationView.arity(), impliedRelationView, impliedIndices.size()));
16 }
17 for (var index : impliedIndices) {
18 if (impliedRelationView.invalidIndex(index)) {
19 throw new IllegalArgumentException("%d is not a valid index for %s".formatted(index,
20 implyingRelationView));
21 }
22 }
23 }
24}
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/RelationView.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/SymbolView.java
index fd4f47b4..267a99d3 100644
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/RelationView.java
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/SymbolView.java
@@ -19,17 +19,17 @@ import java.util.UUID;
19 * @param <T> 19 * @param <T>
20 * @author Oszkar Semerath 20 * @author Oszkar Semerath
21 */ 21 */
22public abstract non-sealed class RelationView<T> implements AnyRelationView { 22public abstract non-sealed class SymbolView<T> implements AnySymbolView {
23 private final Symbol<T> symbol; 23 private final Symbol<T> symbol;
24 24
25 private final String viewName; 25 private final String viewName;
26 26
27 protected RelationView(Symbol<T> symbol, String viewName) { 27 protected SymbolView(Symbol<T> symbol, String viewName) {
28 this.symbol = symbol; 28 this.symbol = symbol;
29 this.viewName = viewName; 29 this.viewName = viewName;
30 } 30 }
31 31
32 protected RelationView(Symbol<T> representation) { 32 protected SymbolView(Symbol<T> representation) {
33 this(representation, UUID.randomUUID().toString()); 33 this(representation, UUID.randomUUID().toString());
34 } 34 }
35 35
@@ -71,7 +71,7 @@ public abstract non-sealed class RelationView<T> implements AnyRelationView {
71 public boolean equals(Object o) { 71 public boolean equals(Object o) {
72 if (this == o) return true; 72 if (this == o) return true;
73 if (o == null || getClass() != o.getClass()) return false; 73 if (o == null || getClass() != o.getClass()) return false;
74 RelationView<?> that = (RelationView<?>) o; 74 SymbolView<?> that = (SymbolView<?>) o;
75 return Objects.equals(symbol, that.symbol) && Objects.equals(viewName, that.viewName); 75 return Objects.equals(symbol, that.symbol) && Objects.equals(viewName, that.viewName);
76 } 76 }
77 77
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/TuplePreservingRelationView.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/TuplePreservingView.java
index e6e54aa1..19862e3a 100644
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/TuplePreservingRelationView.java
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/TuplePreservingView.java
@@ -15,12 +15,12 @@ import tools.refinery.store.representation.Symbol;
15import java.util.Arrays; 15import java.util.Arrays;
16import java.util.List; 16import java.util.List;
17 17
18public abstract class TuplePreservingRelationView<T> extends RelationView<T> { 18public abstract class TuplePreservingView<T> extends SymbolView<T> {
19 protected TuplePreservingRelationView(Symbol<T> symbol, String name) { 19 protected TuplePreservingView(Symbol<T> symbol, String name) {
20 super(symbol, name); 20 super(symbol, name);
21 } 21 }
22 22
23 protected TuplePreservingRelationView(Symbol<T> symbol) { 23 protected TuplePreservingView(Symbol<T> symbol) {
24 super(symbol); 24 super(symbol);
25 } 25 }
26 26
@@ -41,7 +41,10 @@ public abstract class TuplePreservingRelationView<T> extends RelationView<T> {
41 public boolean get(Model model, Object[] tuple) { 41 public boolean get(Model model, Object[] tuple) {
42 int[] content = new int[tuple.length]; 42 int[] content = new int[tuple.length];
43 for (int i = 0; i < tuple.length; i++) { 43 for (int i = 0; i < tuple.length; i++) {
44 content[i] = ((Tuple1) tuple[i]).value0(); 44 if (!(tuple[i] instanceof Tuple1 wrapper)) {
45 return false;
46 }
47 content[i] = wrapper.value0();
45 } 48 }
46 Tuple key = Tuple.of(content); 49 Tuple key = Tuple.of(content);
47 T value = model.getInterpretation(getSymbol()).get(key); 50 T value = model.getInterpretation(getSymbol()).get(key);
diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/DnfBuilderTest.java b/subprojects/store-query/src/test/java/tools/refinery/store/query/DnfBuilderTest.java
index 70cd386b..152840f8 100644
--- a/subprojects/store-query/src/test/java/tools/refinery/store/query/DnfBuilderTest.java
+++ b/subprojects/store-query/src/test/java/tools/refinery/store/query/DnfBuilderTest.java
@@ -9,7 +9,7 @@ import org.junit.jupiter.api.Test;
9import tools.refinery.store.query.dnf.Dnf; 9import tools.refinery.store.query.dnf.Dnf;
10import tools.refinery.store.query.literal.BooleanLiteral; 10import tools.refinery.store.query.literal.BooleanLiteral;
11import tools.refinery.store.query.term.Variable; 11import tools.refinery.store.query.term.Variable;
12import tools.refinery.store.query.view.KeyOnlyRelationView; 12import tools.refinery.store.query.view.KeyOnlyView;
13import tools.refinery.store.representation.Symbol; 13import tools.refinery.store.representation.Symbol;
14 14
15import static org.hamcrest.MatcherAssert.assertThat; 15import static org.hamcrest.MatcherAssert.assertThat;
@@ -22,7 +22,7 @@ class DnfBuilderTest {
22 var p = Variable.of("p"); 22 var p = Variable.of("p");
23 var q = Variable.of("q"); 23 var q = Variable.of("q");
24 var friend = new Symbol<>("friend", 2, Boolean.class, false); 24 var friend = new Symbol<>("friend", 2, Boolean.class, false);
25 var friendView = new KeyOnlyRelationView<>(friend); 25 var friendView = new KeyOnlyView<>(friend);
26 26
27 var actual = Dnf.builder() 27 var actual = Dnf.builder()
28 .parameters(p, q) 28 .parameters(p, q)
@@ -38,7 +38,7 @@ class DnfBuilderTest {
38 var p = Variable.of("p"); 38 var p = Variable.of("p");
39 var q = Variable.of("q"); 39 var q = Variable.of("q");
40 var friend = new Symbol<>("friend", 2, Boolean.class, false); 40 var friend = new Symbol<>("friend", 2, Boolean.class, false);
41 var friendView = new KeyOnlyRelationView<>(friend); 41 var friendView = new KeyOnlyView<>(friend);
42 42
43 var actual = Dnf.builder() 43 var actual = Dnf.builder()
44 .parameters(p, q) 44 .parameters(p, q)
@@ -55,7 +55,7 @@ class DnfBuilderTest {
55 var p = Variable.of("p"); 55 var p = Variable.of("p");
56 var q = Variable.of("q"); 56 var q = Variable.of("q");
57 var friend = new Symbol<>("friend", 2, Boolean.class, false); 57 var friend = new Symbol<>("friend", 2, Boolean.class, false);
58 var friendView = new KeyOnlyRelationView<>(friend); 58 var friendView = new KeyOnlyView<>(friend);
59 59
60 var actual = Dnf.builder() 60 var actual = Dnf.builder()
61 .parameters(p, q) 61 .parameters(p, q)
@@ -72,7 +72,7 @@ class DnfBuilderTest {
72 var p = Variable.of("p"); 72 var p = Variable.of("p");
73 var q = Variable.of("q"); 73 var q = Variable.of("q");
74 var friend = new Symbol<>("friend", 2, Boolean.class, false); 74 var friend = new Symbol<>("friend", 2, Boolean.class, false);
75 var friendView = new KeyOnlyRelationView<>(friend); 75 var friendView = new KeyOnlyView<>(friend);
76 76
77 var actual = Dnf.builder() 77 var actual = Dnf.builder()
78 .parameters(p, q) 78 .parameters(p, q)
@@ -88,7 +88,7 @@ class DnfBuilderTest {
88 var p = Variable.of("p"); 88 var p = Variable.of("p");
89 var q = Variable.of("q"); 89 var q = Variable.of("q");
90 var friend = new Symbol<>("friend", 2, Boolean.class, false); 90 var friend = new Symbol<>("friend", 2, Boolean.class, false);
91 var friendView = new KeyOnlyRelationView<>(friend); 91 var friendView = new KeyOnlyView<>(friend);
92 var trueDnf = Dnf.builder().parameter(p).clause().build(); 92 var trueDnf = Dnf.builder().parameter(p).clause().build();
93 93
94 var actual = Dnf.builder() 94 var actual = Dnf.builder()
@@ -105,7 +105,7 @@ class DnfBuilderTest {
105 var p = Variable.of("p"); 105 var p = Variable.of("p");
106 var q = Variable.of("q"); 106 var q = Variable.of("q");
107 var friend = new Symbol<>("friend", 2, Boolean.class, false); 107 var friend = new Symbol<>("friend", 2, Boolean.class, false);
108 var friendView = new KeyOnlyRelationView<>(friend); 108 var friendView = new KeyOnlyView<>(friend);
109 var falseDnf = Dnf.builder().parameter(p).build(); 109 var falseDnf = Dnf.builder().parameter(p).build();
110 110
111 var actual = Dnf.builder() 111 var actual = Dnf.builder()
@@ -123,7 +123,7 @@ class DnfBuilderTest {
123 var p = Variable.of("p"); 123 var p = Variable.of("p");
124 var q = Variable.of("q"); 124 var q = Variable.of("q");
125 var friend = new Symbol<>("friend", 2, Boolean.class, false); 125 var friend = new Symbol<>("friend", 2, Boolean.class, false);
126 var friendView = new KeyOnlyRelationView<>(friend); 126 var friendView = new KeyOnlyView<>(friend);
127 var trueDnf = Dnf.builder().parameter(p).clause().build(); 127 var trueDnf = Dnf.builder().parameter(p).clause().build();
128 128
129 var actual = Dnf.builder() 129 var actual = Dnf.builder()
@@ -141,7 +141,7 @@ class DnfBuilderTest {
141 var p = Variable.of("p"); 141 var p = Variable.of("p");
142 var q = Variable.of("q"); 142 var q = Variable.of("q");
143 var friend = new Symbol<>("friend", 2, Boolean.class, false); 143 var friend = new Symbol<>("friend", 2, Boolean.class, false);
144 var friendView = new KeyOnlyRelationView<>(friend); 144 var friendView = new KeyOnlyView<>(friend);
145 var falseDnf = Dnf.builder().parameter(p).build(); 145 var falseDnf = Dnf.builder().parameter(p).build();
146 146
147 var actual = Dnf.builder() 147 var actual = Dnf.builder()
@@ -158,7 +158,7 @@ class DnfBuilderTest {
158 var p = Variable.of("p"); 158 var p = Variable.of("p");
159 var q = Variable.of("q"); 159 var q = Variable.of("q");
160 var friend = new Symbol<>("friend", 2, Boolean.class, false); 160 var friend = new Symbol<>("friend", 2, Boolean.class, false);
161 var friendView = new KeyOnlyRelationView<>(friend); 161 var friendView = new KeyOnlyView<>(friend);
162 var falseDnf = Dnf.builder().parameter(p).build(); 162 var falseDnf = Dnf.builder().parameter(p).build();
163 163
164 var actual = Dnf.builder() 164 var actual = Dnf.builder()
@@ -175,7 +175,7 @@ class DnfBuilderTest {
175 var p = Variable.of("p"); 175 var p = Variable.of("p");
176 var q = Variable.of("q"); 176 var q = Variable.of("q");
177 var friend = new Symbol<>("friend", 2, Boolean.class, false); 177 var friend = new Symbol<>("friend", 2, Boolean.class, false);
178 var friendView = new KeyOnlyRelationView<>(friend); 178 var friendView = new KeyOnlyView<>(friend);
179 var trueDnf = Dnf.builder().parameter(p).clause().build(); 179 var trueDnf = Dnf.builder().parameter(p).clause().build();
180 180
181 var actual = Dnf.builder() 181 var actual = Dnf.builder()
@@ -193,7 +193,7 @@ class DnfBuilderTest {
193 var p = Variable.of("p"); 193 var p = Variable.of("p");
194 var q = Variable.of("q"); 194 var q = Variable.of("q");
195 var friend = new Symbol<>("friend", 2, Boolean.class, false); 195 var friend = new Symbol<>("friend", 2, Boolean.class, false);
196 var friendView = new KeyOnlyRelationView<>(friend); 196 var friendView = new KeyOnlyView<>(friend);
197 var falseDnf = Dnf.builder().parameter(p).build(); 197 var falseDnf = Dnf.builder().parameter(p).build();
198 198
199 var actual = Dnf.builder() 199 var actual = Dnf.builder()
@@ -211,7 +211,7 @@ class DnfBuilderTest {
211 var p = Variable.of("p"); 211 var p = Variable.of("p");
212 var q = Variable.of("q"); 212 var q = Variable.of("q");
213 var friend = new Symbol<>("friend", 2, Boolean.class, false); 213 var friend = new Symbol<>("friend", 2, Boolean.class, false);
214 var friendView = new KeyOnlyRelationView<>(friend); 214 var friendView = new KeyOnlyView<>(friend);
215 var trueDnf = Dnf.builder().parameter(p).clause().build(); 215 var trueDnf = Dnf.builder().parameter(p).clause().build();
216 216
217 var actual = Dnf.builder() 217 var actual = Dnf.builder()
diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/DnfToDefinitionStringTest.java b/subprojects/store-query/src/test/java/tools/refinery/store/query/DnfToDefinitionStringTest.java
index 7be57745..e89ab682 100644
--- a/subprojects/store-query/src/test/java/tools/refinery/store/query/DnfToDefinitionStringTest.java
+++ b/subprojects/store-query/src/test/java/tools/refinery/store/query/DnfToDefinitionStringTest.java
@@ -8,7 +8,7 @@ package tools.refinery.store.query;
8import org.junit.jupiter.api.Test; 8import org.junit.jupiter.api.Test;
9import tools.refinery.store.query.dnf.Dnf; 9import tools.refinery.store.query.dnf.Dnf;
10import tools.refinery.store.query.term.Variable; 10import tools.refinery.store.query.term.Variable;
11import tools.refinery.store.query.view.KeyOnlyRelationView; 11import tools.refinery.store.query.view.KeyOnlyView;
12import tools.refinery.store.representation.Symbol; 12import tools.refinery.store.representation.Symbol;
13 13
14import static org.hamcrest.MatcherAssert.assertThat; 14import static org.hamcrest.MatcherAssert.assertThat;
@@ -53,7 +53,7 @@ class DnfToDefinitionStringTest {
53 var p = Variable.of("p"); 53 var p = Variable.of("p");
54 var q = Variable.of("q"); 54 var q = Variable.of("q");
55 var friend = new Symbol<>("friend", 2, Boolean.class, false); 55 var friend = new Symbol<>("friend", 2, Boolean.class, false);
56 var friendView = new KeyOnlyRelationView<>(friend); 56 var friendView = new KeyOnlyView<>(friend);
57 var dnf = Dnf.builder("Example").parameter(p).clause(friendView.call(p, q)).build(); 57 var dnf = Dnf.builder("Example").parameter(p).clause(friendView.call(p, q)).build();
58 58
59 assertThat(dnf.toDefinitionString(), is(""" 59 assertThat(dnf.toDefinitionString(), is("""
@@ -67,7 +67,7 @@ class DnfToDefinitionStringTest {
67 var p = Variable.of("p"); 67 var p = Variable.of("p");
68 var q = Variable.of("q"); 68 var q = Variable.of("q");
69 var friend = new Symbol<>("friend", 2, Boolean.class, false); 69 var friend = new Symbol<>("friend", 2, Boolean.class, false);
70 var friendView = new KeyOnlyRelationView<>(friend); 70 var friendView = new KeyOnlyView<>(friend);
71 var dnf = Dnf.builder("Example").parameter(p).clause(not(friendView.call(p, q))).build(); 71 var dnf = Dnf.builder("Example").parameter(p).clause(not(friendView.call(p, q))).build();
72 72
73 assertThat(dnf.toDefinitionString(), is(""" 73 assertThat(dnf.toDefinitionString(), is("""
@@ -81,7 +81,7 @@ class DnfToDefinitionStringTest {
81 var p = Variable.of("p"); 81 var p = Variable.of("p");
82 var q = Variable.of("q"); 82 var q = Variable.of("q");
83 var friend = new Symbol<>("friend", 2, Boolean.class, false); 83 var friend = new Symbol<>("friend", 2, Boolean.class, false);
84 var friendView = new KeyOnlyRelationView<>(friend); 84 var friendView = new KeyOnlyView<>(friend);
85 var dnf = Dnf.builder("Example").parameter(p).clause(friendView.callTransitive(p, q)).build(); 85 var dnf = Dnf.builder("Example").parameter(p).clause(friendView.callTransitive(p, q)).build();
86 86
87 assertThat(dnf.toDefinitionString(), is(""" 87 assertThat(dnf.toDefinitionString(), is("""
@@ -95,7 +95,7 @@ class DnfToDefinitionStringTest {
95 var p = Variable.of("p"); 95 var p = Variable.of("p");
96 var q = Variable.of("q"); 96 var q = Variable.of("q");
97 var friend = new Symbol<>("friend", 2, Boolean.class, false); 97 var friend = new Symbol<>("friend", 2, Boolean.class, false);
98 var friendView = new KeyOnlyRelationView<>(friend); 98 var friendView = new KeyOnlyView<>(friend);
99 var dnf = Dnf.builder("Example").parameters(p, q).clause(friendView.call(p, q)).build(); 99 var dnf = Dnf.builder("Example").parameters(p, q).clause(friendView.call(p, q)).build();
100 100
101 assertThat(dnf.toDefinitionString(), is(""" 101 assertThat(dnf.toDefinitionString(), is("""
@@ -109,9 +109,9 @@ class DnfToDefinitionStringTest {
109 var p = Variable.of("p"); 109 var p = Variable.of("p");
110 var q = Variable.of("q"); 110 var q = Variable.of("q");
111 var person = new Symbol<>("person", 1, Boolean.class, false); 111 var person = new Symbol<>("person", 1, Boolean.class, false);
112 var personView = new KeyOnlyRelationView<>(person); 112 var personView = new KeyOnlyView<>(person);
113 var friend = new Symbol<>("friend", 2, Boolean.class, false); 113 var friend = new Symbol<>("friend", 2, Boolean.class, false);
114 var friendView = new KeyOnlyRelationView<>(friend); 114 var friendView = new KeyOnlyView<>(friend);
115 var dnf = Dnf.builder("Example") 115 var dnf = Dnf.builder("Example")
116 .parameter(p) 116 .parameter(p)
117 .clause( 117 .clause(
@@ -134,7 +134,7 @@ class DnfToDefinitionStringTest {
134 var p = Variable.of("p"); 134 var p = Variable.of("p");
135 var q = Variable.of("q"); 135 var q = Variable.of("q");
136 var friend = new Symbol<>("friend", 2, Boolean.class, false); 136 var friend = new Symbol<>("friend", 2, Boolean.class, false);
137 var friendView = new KeyOnlyRelationView<>(friend); 137 var friendView = new KeyOnlyView<>(friend);
138 var dnf = Dnf.builder("Example") 138 var dnf = Dnf.builder("Example")
139 .parameter(p) 139 .parameter(p)
140 .clause(friendView.call(p, q)) 140 .clause(friendView.call(p, q))
@@ -156,9 +156,9 @@ class DnfToDefinitionStringTest {
156 var r = Variable.of("r"); 156 var r = Variable.of("r");
157 var s = Variable.of("s"); 157 var s = Variable.of("s");
158 var person = new Symbol<>("person", 1, Boolean.class, false); 158 var person = new Symbol<>("person", 1, Boolean.class, false);
159 var personView = new KeyOnlyRelationView<>(person); 159 var personView = new KeyOnlyView<>(person);
160 var friend = new Symbol<>("friend", 2, Boolean.class, false); 160 var friend = new Symbol<>("friend", 2, Boolean.class, false);
161 var friendView = new KeyOnlyRelationView<>(friend); 161 var friendView = new KeyOnlyView<>(friend);
162 var called = Dnf.builder("Called").parameters(r, s).clause(friendView.call(r, s)).build(); 162 var called = Dnf.builder("Called").parameters(r, s).clause(friendView.call(r, s)).build();
163 var dnf = Dnf.builder("Example") 163 var dnf = Dnf.builder("Example")
164 .parameter(p) 164 .parameter(p)
diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/tests/StructurallyEqualToTest.java b/subprojects/store-query/src/test/java/tools/refinery/store/query/tests/StructurallyEqualToTest.java
index e292b3ab..a1407288 100644
--- a/subprojects/store-query/src/test/java/tools/refinery/store/query/tests/StructurallyEqualToTest.java
+++ b/subprojects/store-query/src/test/java/tools/refinery/store/query/tests/StructurallyEqualToTest.java
@@ -8,7 +8,7 @@ package tools.refinery.store.query.tests;
8import org.junit.jupiter.api.Test; 8import org.junit.jupiter.api.Test;
9import tools.refinery.store.query.dnf.Dnf; 9import tools.refinery.store.query.dnf.Dnf;
10import tools.refinery.store.query.term.Variable; 10import tools.refinery.store.query.term.Variable;
11import tools.refinery.store.query.view.KeyOnlyRelationView; 11import tools.refinery.store.query.view.KeyOnlyView;
12import tools.refinery.store.representation.Symbol; 12import tools.refinery.store.representation.Symbol;
13 13
14import static org.hamcrest.CoreMatchers.containsString; 14import static org.hamcrest.CoreMatchers.containsString;
@@ -22,7 +22,7 @@ class StructurallyEqualToTest {
22 var p = Variable.of("p"); 22 var p = Variable.of("p");
23 var q = Variable.of("q"); 23 var q = Variable.of("q");
24 var person = new Symbol<>("Person", 1, Boolean.class, false); 24 var person = new Symbol<>("Person", 1, Boolean.class, false);
25 var personView = new KeyOnlyRelationView<>(person); 25 var personView = new KeyOnlyView<>(person);
26 26
27 var expected = Dnf.builder("Expected").parameters(q).clause(personView.call(q)).build(); 27 var expected = Dnf.builder("Expected").parameters(q).clause(personView.call(q)).build();
28 var actual = Dnf.builder("Actual").parameters(p).clause(personView.call(p)).build(); 28 var actual = Dnf.builder("Actual").parameters(p).clause(personView.call(p)).build();
@@ -35,7 +35,7 @@ class StructurallyEqualToTest {
35 var p = Variable.of("p"); 35 var p = Variable.of("p");
36 var q = Variable.of("q"); 36 var q = Variable.of("q");
37 var person = new Symbol<>("Person", 1, Boolean.class, false); 37 var person = new Symbol<>("Person", 1, Boolean.class, false);
38 var personView = new KeyOnlyRelationView<>(person); 38 var personView = new KeyOnlyView<>(person);
39 39
40 var expected = Dnf.builder("Expected").parameters(q).clause(personView.call(q)).build(); 40 var expected = Dnf.builder("Expected").parameters(q).clause(personView.call(q)).build();
41 var actual = Dnf.builder("Actual").parameters(p).clause(personView.call(q)).build(); 41 var actual = Dnf.builder("Actual").parameters(p).clause(personView.call(q)).build();
@@ -49,7 +49,7 @@ class StructurallyEqualToTest {
49 var p = Variable.of("p"); 49 var p = Variable.of("p");
50 var q = Variable.of("q"); 50 var q = Variable.of("q");
51 var person = new Symbol<>("Person", 1, Boolean.class, false); 51 var person = new Symbol<>("Person", 1, Boolean.class, false);
52 var personView = new KeyOnlyRelationView<>(person); 52 var personView = new KeyOnlyView<>(person);
53 53
54 var expected = Dnf.builder("Expected").parameters(q).clause( 54 var expected = Dnf.builder("Expected").parameters(q).clause(
55 Dnf.builder("Expected2").parameters(p).clause(personView.call(p)).build().call(q) 55 Dnf.builder("Expected2").parameters(p).clause(personView.call(p)).build().call(q)
@@ -66,7 +66,7 @@ class StructurallyEqualToTest {
66 var p = Variable.of("p"); 66 var p = Variable.of("p");
67 var q = Variable.of("q"); 67 var q = Variable.of("q");
68 var person = new Symbol<>("Person", 1, Boolean.class, false); 68 var person = new Symbol<>("Person", 1, Boolean.class, false);
69 var personView = new KeyOnlyRelationView<>(person); 69 var personView = new KeyOnlyView<>(person);
70 70
71 var expected = Dnf.builder("Expected").parameters(q).clause( 71 var expected = Dnf.builder("Expected").parameters(q).clause(
72 Dnf.builder("Expected2").parameters(p).clause(personView.call(p)).build().call(q) 72 Dnf.builder("Expected2").parameters(p).clause(personView.call(p)).build().call(q)