diff options
Diffstat (limited to 'subprojects/store-query-viatra/src')
10 files changed, 326 insertions, 86 deletions
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/FunctionalCursor.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/FunctionalCursor.java index 4daa14a1..52a83f69 100644 --- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/FunctionalCursor.java +++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/FunctionalCursor.java | |||
@@ -1,17 +1,16 @@ | |||
1 | package tools.refinery.store.query.viatra.internal.matcher; | 1 | package tools.refinery.store.query.viatra.internal.matcher; |
2 | 2 | ||
3 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; | ||
4 | import org.eclipse.viatra.query.runtime.rete.index.IterableIndexer; | 3 | import org.eclipse.viatra.query.runtime.rete.index.IterableIndexer; |
5 | import tools.refinery.store.map.Cursor; | 4 | import tools.refinery.store.map.Cursor; |
6 | import tools.refinery.store.tuple.TupleLike; | 5 | import tools.refinery.store.tuple.Tuple; |
7 | 6 | ||
8 | import java.util.Iterator; | 7 | import java.util.Iterator; |
9 | 8 | ||
10 | class FunctionalCursor<T> implements Cursor<TupleLike, T> { | 9 | class FunctionalCursor<T> implements Cursor<Tuple, T> { |
11 | private final IterableIndexer indexer; | 10 | private final IterableIndexer indexer; |
12 | private final Iterator<Tuple> iterator; | 11 | private final Iterator<org.eclipse.viatra.query.runtime.matchers.tuple.Tuple> iterator; |
13 | private boolean terminated; | 12 | private boolean terminated; |
14 | private TupleLike key; | 13 | private Tuple key; |
15 | private T value; | 14 | private T value; |
16 | 15 | ||
17 | public FunctionalCursor(IterableIndexer indexer) { | 16 | public FunctionalCursor(IterableIndexer indexer) { |
@@ -20,7 +19,7 @@ class FunctionalCursor<T> implements Cursor<TupleLike, T> { | |||
20 | } | 19 | } |
21 | 20 | ||
22 | @Override | 21 | @Override |
23 | public TupleLike getKey() { | 22 | public Tuple getKey() { |
24 | return key; | 23 | return key; |
25 | } | 24 | } |
26 | 25 | ||
@@ -38,7 +37,7 @@ class FunctionalCursor<T> implements Cursor<TupleLike, T> { | |||
38 | public boolean move() { | 37 | public boolean move() { |
39 | if (!terminated && iterator.hasNext()) { | 38 | if (!terminated && iterator.hasNext()) { |
40 | var match = iterator.next(); | 39 | var match = iterator.next(); |
41 | key = new ViatraTupleLike(match); | 40 | key = MatcherUtils.toRefineryTuple(match); |
42 | value = MatcherUtils.getSingleValue(indexer.get(match)); | 41 | value = MatcherUtils.getSingleValue(indexer.get(match)); |
43 | return true; | 42 | return true; |
44 | } | 43 | } |
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/FunctionalViatraMatcher.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/FunctionalViatraMatcher.java index 6aa45af2..adb34b8b 100644 --- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/FunctionalViatraMatcher.java +++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/FunctionalViatraMatcher.java | |||
@@ -11,7 +11,7 @@ import tools.refinery.store.query.ResultSet; | |||
11 | import tools.refinery.store.query.dnf.FunctionalQuery; | 11 | import tools.refinery.store.query.dnf.FunctionalQuery; |
12 | import tools.refinery.store.query.dnf.Query; | 12 | import tools.refinery.store.query.dnf.Query; |
13 | import tools.refinery.store.query.viatra.internal.ViatraModelQueryAdapterImpl; | 13 | import tools.refinery.store.query.viatra.internal.ViatraModelQueryAdapterImpl; |
14 | import tools.refinery.store.tuple.TupleLike; | 14 | import tools.refinery.store.tuple.Tuple; |
15 | 15 | ||
16 | /** | 16 | /** |
17 | * Directly access the tuples inside a VIATRA pattern matcher.<p> | 17 | * Directly access the tuples inside a VIATRA pattern matcher.<p> |
@@ -63,7 +63,7 @@ public class FunctionalViatraMatcher<T> implements ResultSet<T> { | |||
63 | } | 63 | } |
64 | 64 | ||
65 | @Override | 65 | @Override |
66 | public T get(TupleLike parameters) { | 66 | public T get(Tuple parameters) { |
67 | var tuple = MatcherUtils.toViatraTuple(parameters); | 67 | var tuple = MatcherUtils.toViatraTuple(parameters); |
68 | if (omitOutputIndexer == null) { | 68 | if (omitOutputIndexer == null) { |
69 | return MatcherUtils.getSingleValue(backend.getAllMatches(omitOutputMask, tuple).iterator()); | 69 | return MatcherUtils.getSingleValue(backend.getAllMatches(omitOutputMask, tuple).iterator()); |
@@ -73,7 +73,7 @@ public class FunctionalViatraMatcher<T> implements ResultSet<T> { | |||
73 | } | 73 | } |
74 | 74 | ||
75 | @Override | 75 | @Override |
76 | public Cursor<TupleLike, T> getAll() { | 76 | public Cursor<Tuple, T> getAll() { |
77 | if (omitOutputIndexer == null) { | 77 | if (omitOutputIndexer == null) { |
78 | var allMatches = backend.getAllMatches(emptyMask, Tuples.staticArityFlatTupleOf()); | 78 | var allMatches = backend.getAllMatches(emptyMask, Tuples.staticArityFlatTupleOf()); |
79 | return new UnsafeFunctionalCursor<>(allMatches.iterator()); | 79 | return new UnsafeFunctionalCursor<>(allMatches.iterator()); |
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/MatcherUtils.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/MatcherUtils.java index 5d4be95d..d327c537 100644 --- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/MatcherUtils.java +++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/MatcherUtils.java | |||
@@ -3,8 +3,7 @@ package tools.refinery.store.query.viatra.internal.matcher; | |||
3 | import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple; | 3 | import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple; |
4 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; | 4 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; |
5 | import org.jetbrains.annotations.Nullable; | 5 | import org.jetbrains.annotations.Nullable; |
6 | import tools.refinery.store.tuple.Tuple; | 6 | import tools.refinery.store.tuple.*; |
7 | import tools.refinery.store.tuple.TupleLike; | ||
8 | 7 | ||
9 | import java.util.Iterator; | 8 | import java.util.Iterator; |
10 | 9 | ||
@@ -13,25 +12,80 @@ final class MatcherUtils { | |||
13 | throw new IllegalStateException("This is a static utility class and should not be instantiated directly"); | 12 | throw new IllegalStateException("This is a static utility class and should not be instantiated directly"); |
14 | } | 13 | } |
15 | 14 | ||
16 | public static org.eclipse.viatra.query.runtime.matchers.tuple.Tuple toViatraTuple(TupleLike tuple) { | 15 | public static org.eclipse.viatra.query.runtime.matchers.tuple.Tuple toViatraTuple(Tuple refineryTuple) { |
17 | if (tuple instanceof ViatraTupleLike viatraTupleLike) { | 16 | if (refineryTuple instanceof Tuple0) { |
18 | return viatraTupleLike.wrappedTuple().toImmutable(); | 17 | return Tuples.staticArityFlatTupleOf(); |
18 | } else if (refineryTuple instanceof Tuple1) { | ||
19 | return Tuples.staticArityFlatTupleOf(refineryTuple); | ||
20 | } else if (refineryTuple instanceof Tuple2 tuple2) { | ||
21 | return Tuples.staticArityFlatTupleOf(Tuple.of(tuple2.value0()), Tuple.of(tuple2.value1())); | ||
22 | } else if (refineryTuple instanceof Tuple3 tuple3) { | ||
23 | return Tuples.staticArityFlatTupleOf(Tuple.of(tuple3.value0()), Tuple.of(tuple3.value1()), | ||
24 | Tuple.of(tuple3.value2())); | ||
25 | } else if (refineryTuple instanceof Tuple4 tuple4) { | ||
26 | return Tuples.staticArityFlatTupleOf(Tuple.of(tuple4.value0()), Tuple.of(tuple4.value1()), | ||
27 | Tuple.of(tuple4.value2()), Tuple.of(tuple4.value3())); | ||
28 | } else { | ||
29 | int arity = refineryTuple.getSize(); | ||
30 | var values = new Object[arity]; | ||
31 | for (int i = 0; i < arity; i++) { | ||
32 | values[i] = Tuple.of(refineryTuple.get(i)); | ||
33 | } | ||
34 | return Tuples.flatTupleOf(values); | ||
19 | } | 35 | } |
20 | int size = tuple.getSize(); | 36 | } |
21 | var array = new Object[size]; | 37 | |
22 | for (int i = 0; i < size; i++) { | 38 | public static Tuple toRefineryTuple(ITuple viatraTuple) { |
23 | var value = tuple.get(i); | 39 | int arity = viatraTuple.getSize(); |
24 | array[i] = Tuple.of(value); | 40 | if (arity == 1) { |
41 | return getWrapper(viatraTuple, 0); | ||
25 | } | 42 | } |
26 | return Tuples.flatTupleOf(array); | 43 | return prefixToRefineryTuple(viatraTuple, viatraTuple.getSize()); |
44 | } | ||
45 | |||
46 | public static Tuple keyToRefineryTuple(ITuple viatraTuple) { | ||
47 | return prefixToRefineryTuple(viatraTuple, viatraTuple.getSize() - 1); | ||
27 | } | 48 | } |
28 | 49 | ||
50 | private static Tuple prefixToRefineryTuple(ITuple viatraTuple, int targetArity) { | ||
51 | if (targetArity < 0) { | ||
52 | throw new IllegalArgumentException("Requested negative prefix %d of %s" | ||
53 | .formatted(targetArity, viatraTuple)); | ||
54 | } | ||
55 | return switch (targetArity) { | ||
56 | case 0 -> Tuple.of(); | ||
57 | case 1 -> Tuple.of(unwrap(viatraTuple, 0)); | ||
58 | case 2 -> Tuple.of(unwrap(viatraTuple, 0), unwrap(viatraTuple, 1)); | ||
59 | case 3 -> Tuple.of(unwrap(viatraTuple, 0), unwrap(viatraTuple, 1), unwrap(viatraTuple, 2)); | ||
60 | case 4 -> Tuple.of(unwrap(viatraTuple, 0), unwrap(viatraTuple, 1), unwrap(viatraTuple, 2), | ||
61 | unwrap(viatraTuple, 3)); | ||
62 | default -> { | ||
63 | var entries = new int[targetArity]; | ||
64 | for (int i = 0; i < targetArity; i++) { | ||
65 | entries[i] = unwrap(viatraTuple, i); | ||
66 | } | ||
67 | yield Tuple.of(entries); | ||
68 | } | ||
69 | }; | ||
70 | } | ||
71 | |||
72 | private static Tuple1 getWrapper(ITuple viatraTuple, int index) { | ||
73 | if (!((viatraTuple.get(index)) instanceof Tuple1 wrappedObjectId)) { | ||
74 | throw new IllegalArgumentException("Element %d of tuple %s is not an object id" | ||
75 | .formatted(index, viatraTuple)); | ||
76 | } | ||
77 | return wrappedObjectId; | ||
78 | } | ||
79 | |||
80 | private static int unwrap(ITuple viatraTuple, int index) { | ||
81 | return getWrapper(viatraTuple, index).value0(); | ||
82 | } | ||
29 | 83 | ||
30 | public static <T> T getSingleValue(@Nullable Iterable<? extends ITuple> tuples) { | 84 | public static <T> T getSingleValue(@Nullable Iterable<? extends ITuple> viatraTuples) { |
31 | if (tuples == null) { | 85 | if (viatraTuples == null) { |
32 | return null; | 86 | return null; |
33 | } | 87 | } |
34 | return getSingleValue(tuples.iterator()); | 88 | return getSingleValue(viatraTuples.iterator()); |
35 | } | 89 | } |
36 | 90 | ||
37 | public static <T> T getSingleValue(Iterator<? extends ITuple> iterator) { | 91 | public static <T> T getSingleValue(Iterator<? extends ITuple> iterator) { |
@@ -42,7 +96,7 @@ final class MatcherUtils { | |||
42 | @SuppressWarnings("unchecked") | 96 | @SuppressWarnings("unchecked") |
43 | var result = (T) match.get(match.getSize() - 1); | 97 | var result = (T) match.get(match.getSize() - 1); |
44 | if (iterator.hasNext()) { | 98 | if (iterator.hasNext()) { |
45 | var input = new OmitOutputViatraTupleLike(match); | 99 | var input = keyToRefineryTuple(match); |
46 | throw new IllegalStateException("Query is not functional for input tuple: " + input); | 100 | throw new IllegalStateException("Query is not functional for input tuple: " + input); |
47 | } | 101 | } |
48 | return result; | 102 | return result; |
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/OmitOutputViatraTupleLike.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/OmitOutputViatraTupleLike.java deleted file mode 100644 index bd9301ba..00000000 --- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/OmitOutputViatraTupleLike.java +++ /dev/null | |||
@@ -1,23 +0,0 @@ | |||
1 | package tools.refinery.store.query.viatra.internal.matcher; | ||
2 | |||
3 | import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple; | ||
4 | import tools.refinery.store.tuple.Tuple1; | ||
5 | import tools.refinery.store.tuple.TupleLike; | ||
6 | |||
7 | record OmitOutputViatraTupleLike(ITuple wrappedTuple) implements TupleLike { | ||
8 | @Override | ||
9 | public int getSize() { | ||
10 | return wrappedTuple.getSize() - 1; | ||
11 | } | ||
12 | |||
13 | @Override | ||
14 | public int get(int element) { | ||
15 | var wrappedValue = (Tuple1) wrappedTuple.get(element); | ||
16 | return wrappedValue.value0(); | ||
17 | } | ||
18 | |||
19 | @Override | ||
20 | public String toString() { | ||
21 | return TupleLike.toString(this); | ||
22 | } | ||
23 | } | ||
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/RelationalCursor.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/RelationalCursor.java index c2dcc565..e3df0441 100644 --- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/RelationalCursor.java +++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/RelationalCursor.java | |||
@@ -2,21 +2,21 @@ package tools.refinery.store.query.viatra.internal.matcher; | |||
2 | 2 | ||
3 | import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple; | 3 | import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple; |
4 | import tools.refinery.store.map.Cursor; | 4 | import tools.refinery.store.map.Cursor; |
5 | import tools.refinery.store.tuple.TupleLike; | 5 | import tools.refinery.store.tuple.Tuple; |
6 | 6 | ||
7 | import java.util.Iterator; | 7 | import java.util.Iterator; |
8 | 8 | ||
9 | class RelationalCursor implements Cursor<TupleLike, Boolean> { | 9 | class RelationalCursor implements Cursor<Tuple, Boolean> { |
10 | private final Iterator<? extends ITuple> tuplesIterator; | 10 | private final Iterator<? extends ITuple> tuplesIterator; |
11 | private boolean terminated; | 11 | private boolean terminated; |
12 | private TupleLike key; | 12 | private Tuple key; |
13 | 13 | ||
14 | public RelationalCursor(Iterator<? extends ITuple> tuplesIterator) { | 14 | public RelationalCursor(Iterator<? extends ITuple> tuplesIterator) { |
15 | this.tuplesIterator = tuplesIterator; | 15 | this.tuplesIterator = tuplesIterator; |
16 | } | 16 | } |
17 | 17 | ||
18 | @Override | 18 | @Override |
19 | public TupleLike getKey() { | 19 | public Tuple getKey() { |
20 | return key; | 20 | return key; |
21 | } | 21 | } |
22 | 22 | ||
@@ -33,7 +33,7 @@ class RelationalCursor implements Cursor<TupleLike, Boolean> { | |||
33 | @Override | 33 | @Override |
34 | public boolean move() { | 34 | public boolean move() { |
35 | if (!terminated && tuplesIterator.hasNext()) { | 35 | if (!terminated && tuplesIterator.hasNext()) { |
36 | key = new ViatraTupleLike(tuplesIterator.next()); | 36 | key = MatcherUtils.toRefineryTuple(tuplesIterator.next()); |
37 | return true; | 37 | return true; |
38 | } | 38 | } |
39 | terminated = true; | 39 | terminated = true; |
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/RelationalViatraMatcher.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/RelationalViatraMatcher.java index b9bc3f1e..9373709d 100644 --- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/RelationalViatraMatcher.java +++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/RelationalViatraMatcher.java | |||
@@ -12,7 +12,7 @@ import tools.refinery.store.query.ResultSet; | |||
12 | import tools.refinery.store.query.dnf.Query; | 12 | import tools.refinery.store.query.dnf.Query; |
13 | import tools.refinery.store.query.dnf.RelationalQuery; | 13 | import tools.refinery.store.query.dnf.RelationalQuery; |
14 | import tools.refinery.store.query.viatra.internal.ViatraModelQueryAdapterImpl; | 14 | import tools.refinery.store.query.viatra.internal.ViatraModelQueryAdapterImpl; |
15 | import tools.refinery.store.tuple.TupleLike; | 15 | import tools.refinery.store.tuple.Tuple; |
16 | 16 | ||
17 | /** | 17 | /** |
18 | * Directly access the tuples inside a VIATRA pattern matcher.<p> | 18 | * Directly access the tuples inside a VIATRA pattern matcher.<p> |
@@ -58,7 +58,7 @@ public class RelationalViatraMatcher implements ResultSet<Boolean> { | |||
58 | } | 58 | } |
59 | 59 | ||
60 | @Override | 60 | @Override |
61 | public Boolean get(TupleLike parameters) { | 61 | public Boolean get(Tuple parameters) { |
62 | var tuple = MatcherUtils.toViatraTuple(parameters); | 62 | var tuple = MatcherUtils.toViatraTuple(parameters); |
63 | if (emptyMaskIndexer == null) { | 63 | if (emptyMaskIndexer == null) { |
64 | return backend.hasMatch(identityMask, tuple); | 64 | return backend.hasMatch(identityMask, tuple); |
@@ -68,7 +68,7 @@ public class RelationalViatraMatcher implements ResultSet<Boolean> { | |||
68 | } | 68 | } |
69 | 69 | ||
70 | @Override | 70 | @Override |
71 | public Cursor<TupleLike, Boolean> getAll() { | 71 | public Cursor<Tuple, Boolean> getAll() { |
72 | if (emptyMaskIndexer == null) { | 72 | if (emptyMaskIndexer == null) { |
73 | var allMatches = backend.getAllMatches(emptyMask, Tuples.staticArityFlatTupleOf()); | 73 | var allMatches = backend.getAllMatches(emptyMask, Tuples.staticArityFlatTupleOf()); |
74 | return new RelationalCursor(allMatches.iterator()); | 74 | return new RelationalCursor(allMatches.iterator()); |
@@ -85,5 +85,4 @@ public class RelationalViatraMatcher implements ResultSet<Boolean> { | |||
85 | var matches = emptyMaskIndexer.get(Tuples.staticArityFlatTupleOf()); | 85 | var matches = emptyMaskIndexer.get(Tuples.staticArityFlatTupleOf()); |
86 | return matches == null ? 0 : matches.size(); | 86 | return matches == null ? 0 : matches.size(); |
87 | } | 87 | } |
88 | |||
89 | } | 88 | } |
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/UnsafeFunctionalCursor.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/UnsafeFunctionalCursor.java index 6c53fff1..e9540d1d 100644 --- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/UnsafeFunctionalCursor.java +++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/UnsafeFunctionalCursor.java | |||
@@ -2,7 +2,7 @@ package tools.refinery.store.query.viatra.internal.matcher; | |||
2 | 2 | ||
3 | import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple; | 3 | import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple; |
4 | import tools.refinery.store.map.Cursor; | 4 | import tools.refinery.store.map.Cursor; |
5 | import tools.refinery.store.tuple.TupleLike; | 5 | import tools.refinery.store.tuple.Tuple; |
6 | 6 | ||
7 | import java.util.Iterator; | 7 | import java.util.Iterator; |
8 | 8 | ||
@@ -11,10 +11,10 @@ import java.util.Iterator; | |||
11 | * functional dependency of the output on the inputs is obeyed. | 11 | * functional dependency of the output on the inputs is obeyed. |
12 | * @param <T> The output type. | 12 | * @param <T> The output type. |
13 | */ | 13 | */ |
14 | class UnsafeFunctionalCursor<T> implements Cursor<TupleLike, T> { | 14 | class UnsafeFunctionalCursor<T> implements Cursor<Tuple, T> { |
15 | private final Iterator<? extends ITuple> tuplesIterator; | 15 | private final Iterator<? extends ITuple> tuplesIterator; |
16 | private boolean terminated; | 16 | private boolean terminated; |
17 | private TupleLike key; | 17 | private Tuple key; |
18 | private T value; | 18 | private T value; |
19 | 19 | ||
20 | public UnsafeFunctionalCursor(Iterator<? extends ITuple> tuplesIterator) { | 20 | public UnsafeFunctionalCursor(Iterator<? extends ITuple> tuplesIterator) { |
@@ -22,7 +22,7 @@ class UnsafeFunctionalCursor<T> implements Cursor<TupleLike, T> { | |||
22 | } | 22 | } |
23 | 23 | ||
24 | @Override | 24 | @Override |
25 | public TupleLike getKey() { | 25 | public Tuple getKey() { |
26 | return key; | 26 | return key; |
27 | } | 27 | } |
28 | 28 | ||
@@ -40,7 +40,7 @@ class UnsafeFunctionalCursor<T> implements Cursor<TupleLike, T> { | |||
40 | public boolean move() { | 40 | public boolean move() { |
41 | if (!terminated && tuplesIterator.hasNext()) { | 41 | if (!terminated && tuplesIterator.hasNext()) { |
42 | var match = tuplesIterator.next(); | 42 | var match = tuplesIterator.next(); |
43 | key = new OmitOutputViatraTupleLike(match); | 43 | key = MatcherUtils.keyToRefineryTuple(match); |
44 | @SuppressWarnings("unchecked") | 44 | @SuppressWarnings("unchecked") |
45 | var typedValue = (T) match.get(match.getSize() - 1); | 45 | var typedValue = (T) match.get(match.getSize() - 1); |
46 | value = typedValue; | 46 | value = typedValue; |
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/ViatraTupleLike.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/ViatraTupleLike.java deleted file mode 100644 index 76a3e40b..00000000 --- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/ViatraTupleLike.java +++ /dev/null | |||
@@ -1,23 +0,0 @@ | |||
1 | package tools.refinery.store.query.viatra.internal.matcher; | ||
2 | |||
3 | import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple; | ||
4 | import tools.refinery.store.tuple.Tuple1; | ||
5 | import tools.refinery.store.tuple.TupleLike; | ||
6 | |||
7 | record ViatraTupleLike(ITuple wrappedTuple) implements TupleLike { | ||
8 | @Override | ||
9 | public int getSize() { | ||
10 | return wrappedTuple.getSize(); | ||
11 | } | ||
12 | |||
13 | @Override | ||
14 | public int get(int element) { | ||
15 | var wrappedValue = (Tuple1) wrappedTuple.get(element); | ||
16 | return wrappedValue.value0(); | ||
17 | } | ||
18 | |||
19 | @Override | ||
20 | public String toString() { | ||
21 | return TupleLike.toString(this); | ||
22 | } | ||
23 | } | ||
diff --git a/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/internal/matcher/MatcherUtilsTest.java b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/internal/matcher/MatcherUtilsTest.java new file mode 100644 index 00000000..ea0b15ec --- /dev/null +++ b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/internal/matcher/MatcherUtilsTest.java | |||
@@ -0,0 +1,234 @@ | |||
1 | package tools.refinery.store.query.viatra.internal.matcher; | ||
2 | |||
3 | import org.eclipse.viatra.query.runtime.matchers.tuple.*; | ||
4 | import org.junit.jupiter.api.Test; | ||
5 | import tools.refinery.store.tuple.Tuple; | ||
6 | import tools.refinery.store.tuple.*; | ||
7 | |||
8 | import java.util.List; | ||
9 | |||
10 | import static org.hamcrest.MatcherAssert.assertThat; | ||
11 | import static org.hamcrest.Matchers.*; | ||
12 | import static org.junit.jupiter.api.Assertions.assertThrows; | ||
13 | |||
14 | class MatcherUtilsTest { | ||
15 | @Test | ||
16 | void toViatra0Test() { | ||
17 | var viatraTuple = MatcherUtils.toViatraTuple(Tuple.of()); | ||
18 | assertThat(viatraTuple.getSize(), is(0)); | ||
19 | assertThat(viatraTuple, instanceOf(FlatTuple0.class)); | ||
20 | } | ||
21 | |||
22 | @Test | ||
23 | void toViatra1Test() { | ||
24 | var viatraTuple = MatcherUtils.toViatraTuple(Tuple.of(2)); | ||
25 | assertThat(viatraTuple.getSize(), is(1)); | ||
26 | assertThat(viatraTuple.get(0), is(Tuple.of(2))); | ||
27 | assertThat(viatraTuple, instanceOf(FlatTuple1.class)); | ||
28 | } | ||
29 | |||
30 | @Test | ||
31 | void toViatra2Test() { | ||
32 | var viatraTuple = MatcherUtils.toViatraTuple(Tuple.of(2, 3)); | ||
33 | assertThat(viatraTuple.getSize(), is(2)); | ||
34 | assertThat(viatraTuple.get(0), is(Tuple.of(2))); | ||
35 | assertThat(viatraTuple.get(1), is(Tuple.of(3))); | ||
36 | assertThat(viatraTuple, instanceOf(FlatTuple2.class)); | ||
37 | } | ||
38 | |||
39 | @Test | ||
40 | void toViatra3Test() { | ||
41 | var viatraTuple = MatcherUtils.toViatraTuple(Tuple.of(2, 3, 5)); | ||
42 | assertThat(viatraTuple.getSize(), is(3)); | ||
43 | assertThat(viatraTuple.get(0), is(Tuple.of(2))); | ||
44 | assertThat(viatraTuple.get(1), is(Tuple.of(3))); | ||
45 | assertThat(viatraTuple.get(2), is(Tuple.of(5))); | ||
46 | assertThat(viatraTuple, instanceOf(FlatTuple3.class)); | ||
47 | } | ||
48 | |||
49 | @Test | ||
50 | void toViatra4Test() { | ||
51 | var viatraTuple = MatcherUtils.toViatraTuple(Tuple.of(2, 3, 5, 8)); | ||
52 | assertThat(viatraTuple.getSize(), is(4)); | ||
53 | assertThat(viatraTuple.get(0), is(Tuple.of(2))); | ||
54 | assertThat(viatraTuple.get(1), is(Tuple.of(3))); | ||
55 | assertThat(viatraTuple.get(2), is(Tuple.of(5))); | ||
56 | assertThat(viatraTuple.get(3), is(Tuple.of(8))); | ||
57 | assertThat(viatraTuple, instanceOf(FlatTuple4.class)); | ||
58 | } | ||
59 | |||
60 | @Test | ||
61 | void toViatra5Test() { | ||
62 | var viatraTuple = MatcherUtils.toViatraTuple(Tuple.of(2, 3, 5, 8, 13)); | ||
63 | assertThat(viatraTuple.getSize(), is(5)); | ||
64 | assertThat(viatraTuple.get(0), is(Tuple.of(2))); | ||
65 | assertThat(viatraTuple.get(1), is(Tuple.of(3))); | ||
66 | assertThat(viatraTuple.get(2), is(Tuple.of(5))); | ||
67 | assertThat(viatraTuple.get(3), is(Tuple.of(8))); | ||
68 | assertThat(viatraTuple.get(4), is(Tuple.of(13))); | ||
69 | assertThat(viatraTuple, instanceOf(FlatTuple.class)); | ||
70 | } | ||
71 | |||
72 | @Test | ||
73 | void toRefinery0Test() { | ||
74 | var refineryTuple = MatcherUtils.toRefineryTuple(Tuples.flatTupleOf()); | ||
75 | assertThat(refineryTuple.getSize(), is(0)); | ||
76 | assertThat(refineryTuple, instanceOf(Tuple0.class)); | ||
77 | } | ||
78 | |||
79 | @Test | ||
80 | void toRefinery1Test() { | ||
81 | var refineryTuple = MatcherUtils.toRefineryTuple(Tuples.flatTupleOf(Tuple.of(2))); | ||
82 | assertThat(refineryTuple.getSize(), is(1)); | ||
83 | assertThat(refineryTuple.get(0), is(2)); | ||
84 | assertThat(refineryTuple, instanceOf(Tuple1.class)); | ||
85 | } | ||
86 | |||
87 | @Test | ||
88 | void toRefinery2Test() { | ||
89 | var refineryTuple = MatcherUtils.toRefineryTuple(Tuples.flatTupleOf(Tuple.of(2), Tuple.of(3))); | ||
90 | assertThat(refineryTuple.getSize(), is(2)); | ||
91 | assertThat(refineryTuple.get(0), is(2)); | ||
92 | assertThat(refineryTuple.get(1), is(3)); | ||
93 | assertThat(refineryTuple, instanceOf(Tuple2.class)); | ||
94 | } | ||
95 | |||
96 | @Test | ||
97 | void toRefinery3Test() { | ||
98 | var refineryTuple = MatcherUtils.toRefineryTuple(Tuples.flatTupleOf(Tuple.of(2), Tuple.of(3), Tuple.of(5))); | ||
99 | assertThat(refineryTuple.getSize(), is(3)); | ||
100 | assertThat(refineryTuple.get(0), is(2)); | ||
101 | assertThat(refineryTuple.get(1), is(3)); | ||
102 | assertThat(refineryTuple.get(2), is(5)); | ||
103 | assertThat(refineryTuple, instanceOf(Tuple3.class)); | ||
104 | } | ||
105 | |||
106 | @Test | ||
107 | void toRefinery4Test() { | ||
108 | var refineryTuple = MatcherUtils.toRefineryTuple(Tuples.flatTupleOf(Tuple.of(2), Tuple.of(3), Tuple.of(5), | ||
109 | Tuple.of(8))); | ||
110 | assertThat(refineryTuple.getSize(), is(4)); | ||
111 | assertThat(refineryTuple.get(0), is(2)); | ||
112 | assertThat(refineryTuple.get(1), is(3)); | ||
113 | assertThat(refineryTuple.get(2), is(5)); | ||
114 | assertThat(refineryTuple.get(3), is(8)); | ||
115 | assertThat(refineryTuple, instanceOf(Tuple4.class)); | ||
116 | } | ||
117 | |||
118 | @Test | ||
119 | void toRefinery5Test() { | ||
120 | var refineryTuple = MatcherUtils.toRefineryTuple(Tuples.flatTupleOf(Tuple.of(2), Tuple.of(3), Tuple.of(5), | ||
121 | Tuple.of(8), Tuple.of(13))); | ||
122 | assertThat(refineryTuple.getSize(), is(5)); | ||
123 | assertThat(refineryTuple.get(0), is(2)); | ||
124 | assertThat(refineryTuple.get(1), is(3)); | ||
125 | assertThat(refineryTuple.get(2), is(5)); | ||
126 | assertThat(refineryTuple.get(3), is(8)); | ||
127 | assertThat(refineryTuple.get(4), is(13)); | ||
128 | assertThat(refineryTuple, instanceOf(TupleN.class)); | ||
129 | } | ||
130 | |||
131 | @Test | ||
132 | void toRefineryInvalidValueTest() { | ||
133 | var viatraTuple = Tuples.flatTupleOf(Tuple.of(2), -98); | ||
134 | assertThrows(IllegalArgumentException.class, () -> MatcherUtils.toRefineryTuple(viatraTuple)); | ||
135 | } | ||
136 | |||
137 | @Test | ||
138 | void keyToRefinery0Test() { | ||
139 | var refineryTuple = MatcherUtils.keyToRefineryTuple(Tuples.flatTupleOf(-99)); | ||
140 | assertThat(refineryTuple.getSize(), is(0)); | ||
141 | assertThat(refineryTuple, instanceOf(Tuple0.class)); | ||
142 | } | ||
143 | |||
144 | @Test | ||
145 | void keyToRefinery1Test() { | ||
146 | var refineryTuple = MatcherUtils.keyToRefineryTuple(Tuples.flatTupleOf(Tuple.of(2), -99)); | ||
147 | assertThat(refineryTuple.getSize(), is(1)); | ||
148 | assertThat(refineryTuple.get(0), is(2)); | ||
149 | assertThat(refineryTuple, instanceOf(Tuple1.class)); | ||
150 | } | ||
151 | |||
152 | @Test | ||
153 | void keyToRefinery2Test() { | ||
154 | var refineryTuple = MatcherUtils.keyToRefineryTuple(Tuples.flatTupleOf(Tuple.of(2), Tuple.of(3), -99)); | ||
155 | assertThat(refineryTuple.getSize(), is(2)); | ||
156 | assertThat(refineryTuple.get(0), is(2)); | ||
157 | assertThat(refineryTuple.get(1), is(3)); | ||
158 | assertThat(refineryTuple, instanceOf(Tuple2.class)); | ||
159 | } | ||
160 | |||
161 | @Test | ||
162 | void keyToRefinery3Test() { | ||
163 | var refineryTuple = MatcherUtils.keyToRefineryTuple(Tuples.flatTupleOf(Tuple.of(2), Tuple.of(3), Tuple.of(5), | ||
164 | -99)); | ||
165 | assertThat(refineryTuple.getSize(), is(3)); | ||
166 | assertThat(refineryTuple.get(0), is(2)); | ||
167 | assertThat(refineryTuple.get(1), is(3)); | ||
168 | assertThat(refineryTuple.get(2), is(5)); | ||
169 | assertThat(refineryTuple, instanceOf(Tuple3.class)); | ||
170 | } | ||
171 | |||
172 | @Test | ||
173 | void keyToRefinery4Test() { | ||
174 | var refineryTuple = MatcherUtils.keyToRefineryTuple(Tuples.flatTupleOf(Tuple.of(2), Tuple.of(3), Tuple.of(5), | ||
175 | Tuple.of(8), -99)); | ||
176 | assertThat(refineryTuple.getSize(), is(4)); | ||
177 | assertThat(refineryTuple.get(0), is(2)); | ||
178 | assertThat(refineryTuple.get(1), is(3)); | ||
179 | assertThat(refineryTuple.get(2), is(5)); | ||
180 | assertThat(refineryTuple.get(3), is(8)); | ||
181 | assertThat(refineryTuple, instanceOf(Tuple4.class)); | ||
182 | } | ||
183 | |||
184 | @Test | ||
185 | void keyToRefinery5Test() { | ||
186 | var refineryTuple = MatcherUtils.keyToRefineryTuple(Tuples.flatTupleOf(Tuple.of(2), Tuple.of(3), Tuple.of(5), | ||
187 | Tuple.of(8), Tuple.of(13), -99)); | ||
188 | assertThat(refineryTuple.getSize(), is(5)); | ||
189 | assertThat(refineryTuple.get(0), is(2)); | ||
190 | assertThat(refineryTuple.get(1), is(3)); | ||
191 | assertThat(refineryTuple.get(2), is(5)); | ||
192 | assertThat(refineryTuple.get(3), is(8)); | ||
193 | assertThat(refineryTuple.get(4), is(13)); | ||
194 | assertThat(refineryTuple, instanceOf(TupleN.class)); | ||
195 | } | ||
196 | |||
197 | @Test | ||
198 | void keyToRefineryTooShortTest() { | ||
199 | var viatraTuple = Tuples.flatTupleOf(); | ||
200 | assertThrows(IllegalArgumentException.class, () -> MatcherUtils.keyToRefineryTuple(viatraTuple)); | ||
201 | } | ||
202 | |||
203 | @Test | ||
204 | void keyToRefineryInvalidValueTest() { | ||
205 | var viatraTuple = Tuples.flatTupleOf(Tuple.of(2), -98, -99); | ||
206 | assertThrows(IllegalArgumentException.class, () -> MatcherUtils.keyToRefineryTuple(viatraTuple)); | ||
207 | } | ||
208 | |||
209 | @Test | ||
210 | void getSingleValueTest() { | ||
211 | var value = MatcherUtils.getSingleValue(List.of(Tuples.flatTupleOf(Tuple.of(2), -99))); | ||
212 | assertThat(value, is(-99)); | ||
213 | } | ||
214 | |||
215 | // Static analysis accurately determines that the result is always {@code null}, but we check anyways. | ||
216 | @SuppressWarnings("ConstantValue") | ||
217 | @Test | ||
218 | void getSingleValueNullTest() { | ||
219 | var value = MatcherUtils.getSingleValue((Iterable<? extends ITuple>) null); | ||
220 | assertThat(value, nullValue()); | ||
221 | } | ||
222 | |||
223 | @Test | ||
224 | void getSingleValueEmptyTest() { | ||
225 | var value = MatcherUtils.getSingleValue(List.of()); | ||
226 | assertThat(value, nullValue()); | ||
227 | } | ||
228 | |||
229 | @Test | ||
230 | void getSingleValueMultipleTest() { | ||
231 | var viatraTuples = List.of(Tuples.flatTupleOf(Tuple.of(2), -98), Tuples.flatTupleOf(Tuple.of(2), -99)); | ||
232 | assertThrows(IllegalStateException.class, () -> MatcherUtils.getSingleValue(viatraTuples)); | ||
233 | } | ||
234 | } | ||
diff --git a/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/tests/QueryAssertions.java b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/tests/QueryAssertions.java index 6f50ec73..2769621d 100644 --- a/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/tests/QueryAssertions.java +++ b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/tests/QueryAssertions.java | |||
@@ -42,7 +42,7 @@ public final class QueryAssertions { | |||
42 | var cursor = resultSet.getAll(); | 42 | var cursor = resultSet.getAll(); |
43 | while (cursor.move()) { | 43 | while (cursor.move()) { |
44 | var key = cursor.getKey(); | 44 | var key = cursor.getKey(); |
45 | var previous = actual.put(key.toTuple(), cursor.getValue()); | 45 | var previous = actual.put(key, cursor.getValue()); |
46 | assertThat("duplicate value for key " + key, previous, nullValue()); | 46 | assertThat("duplicate value for key " + key, previous, nullValue()); |
47 | } | 47 | } |
48 | executables.add(() -> assertThat("results cursor", actual, is(filteredExpected))); | 48 | executables.add(() -> assertThat("results cursor", actual, is(filteredExpected))); |