diff options
author | Kristóf Marussy <kristof@marussy.com> | 2023-07-10 21:42:52 +0200 |
---|---|---|
committer | Kristóf Marussy <kristof@marussy.com> | 2023-07-15 14:37:26 +0200 |
commit | 60e90db11d1a6898aa8b2e1d82ea647a7898f9f0 (patch) | |
tree | f0248c9b1148054357a74795bb8e9b20405fe8c9 /subprojects/store-query | |
parent | feat: DNF rewriting (diff) | |
download | refinery-60e90db11d1a6898aa8b2e1d82ea647a7898f9f0.tar.gz refinery-60e90db11d1a6898aa8b2e1d82ea647a7898f9f0.tar.zst refinery-60e90db11d1a6898aa8b2e1d82ea647a7898f9f0.zip |
feat: query rewriters for Viatra
Diffstat (limited to 'subprojects/store-query')
10 files changed, 41 insertions, 8 deletions
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/ModelQueryBuilder.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/ModelQueryBuilder.java index c62a95b5..332e6381 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/ModelQueryBuilder.java +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/ModelQueryBuilder.java | |||
@@ -8,6 +8,7 @@ package tools.refinery.store.query; | |||
8 | import tools.refinery.store.adapter.ModelAdapterBuilder; | 8 | import tools.refinery.store.adapter.ModelAdapterBuilder; |
9 | import tools.refinery.store.model.ModelStore; | 9 | import tools.refinery.store.model.ModelStore; |
10 | import tools.refinery.store.query.dnf.AnyQuery; | 10 | import tools.refinery.store.query.dnf.AnyQuery; |
11 | import tools.refinery.store.query.rewriter.DnfRewriter; | ||
11 | 12 | ||
12 | import java.util.Collection; | 13 | import java.util.Collection; |
13 | import java.util.List; | 14 | import java.util.List; |
@@ -25,6 +26,8 @@ public interface ModelQueryBuilder extends ModelAdapterBuilder { | |||
25 | 26 | ||
26 | ModelQueryBuilder query(AnyQuery query); | 27 | ModelQueryBuilder query(AnyQuery query); |
27 | 28 | ||
29 | ModelQueryBuilder rewriter(DnfRewriter rewriter); | ||
30 | |||
28 | @Override | 31 | @Override |
29 | ModelQueryStoreAdapter build(ModelStore store); | 32 | ModelQueryStoreAdapter build(ModelStore store); |
30 | } | 33 | } |
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 f0a950a6..8b67c5c1 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,6 +8,7 @@ package tools.refinery.store.query; | |||
8 | import tools.refinery.store.adapter.ModelStoreAdapter; | 8 | import tools.refinery.store.adapter.ModelStoreAdapter; |
9 | import tools.refinery.store.model.Model; | 9 | import tools.refinery.store.model.Model; |
10 | import tools.refinery.store.query.dnf.AnyQuery; | 10 | import tools.refinery.store.query.dnf.AnyQuery; |
11 | import tools.refinery.store.query.dnf.Query; | ||
11 | import tools.refinery.store.query.view.AnySymbolView; | 12 | import tools.refinery.store.query.view.AnySymbolView; |
12 | 13 | ||
13 | import java.util.Collection; | 14 | import java.util.Collection; |
@@ -17,6 +18,12 @@ public interface ModelQueryStoreAdapter extends ModelStoreAdapter { | |||
17 | 18 | ||
18 | Collection<AnyQuery> getQueries(); | 19 | Collection<AnyQuery> getQueries(); |
19 | 20 | ||
21 | default AnyQuery getCanonicalQuery(AnyQuery query) { | ||
22 | return getCanonicalQuery((Query<?>) query); | ||
23 | } | ||
24 | |||
25 | <T> Query<T> getCanonicalQuery(Query<T> query); | ||
26 | |||
20 | @Override | 27 | @Override |
21 | ModelQueryAdapter createModelAdapter(Model model); | 28 | ModelQueryAdapter createModelAdapter(Model model); |
22 | } | 29 | } |
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/Query.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/Query.java index 55f748da..83fe6ccd 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/Query.java +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/Query.java | |||
@@ -44,6 +44,9 @@ public abstract sealed class Query<T> implements AnyQuery permits FunctionalQuer | |||
44 | public abstract T defaultValue(); | 44 | public abstract T defaultValue(); |
45 | 45 | ||
46 | public Query<T> withDnf(Dnf newDnf) { | 46 | public Query<T> withDnf(Dnf newDnf) { |
47 | if (dnf.equals(newDnf)) { | ||
48 | return this; | ||
49 | } | ||
47 | int arity = dnf.arity(); | 50 | int arity = dnf.arity(); |
48 | if (newDnf.arity() != arity) { | 51 | if (newDnf.arity() != arity) { |
49 | throw new IllegalArgumentException("Arity of %s and %s do not match".formatted(dnf, newDnf)); | 52 | throw new IllegalArgumentException("Arity of %s and %s do not match".formatted(dnf, newDnf)); |
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/resultset/AbstractResultSet.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/resultset/AbstractResultSet.java index a710c64d..dcfe6cc5 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/resultset/AbstractResultSet.java +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/resultset/AbstractResultSet.java | |||
@@ -28,7 +28,7 @@ public abstract class AbstractResultSet<T> implements ResultSet<T> { | |||
28 | } | 28 | } |
29 | 29 | ||
30 | @Override | 30 | @Override |
31 | public Query<T> getQuery() { | 31 | public Query<T> getCanonicalQuery() { |
32 | return query; | 32 | return query; |
33 | } | 33 | } |
34 | 34 | ||
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/resultset/AnyResultSet.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/resultset/AnyResultSet.java index 02809477..5b75b103 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/resultset/AnyResultSet.java +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/resultset/AnyResultSet.java | |||
@@ -11,7 +11,7 @@ import tools.refinery.store.query.dnf.AnyQuery; | |||
11 | public sealed interface AnyResultSet permits ResultSet { | 11 | public sealed interface AnyResultSet permits ResultSet { |
12 | ModelQueryAdapter getAdapter(); | 12 | ModelQueryAdapter getAdapter(); |
13 | 13 | ||
14 | AnyQuery getQuery(); | 14 | AnyQuery getCanonicalQuery(); |
15 | 15 | ||
16 | int size(); | 16 | int size(); |
17 | } | 17 | } |
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/resultset/EmptyResultSet.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/resultset/EmptyResultSet.java index 2795a44b..991b1e32 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/resultset/EmptyResultSet.java +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/resultset/EmptyResultSet.java | |||
@@ -18,7 +18,7 @@ public record EmptyResultSet<T>(ModelQueryAdapter adapter, Query<T> query) imple | |||
18 | } | 18 | } |
19 | 19 | ||
20 | @Override | 20 | @Override |
21 | public Query<T> getQuery() { | 21 | public Query<T> getCanonicalQuery() { |
22 | return query; | 22 | return query; |
23 | } | 23 | } |
24 | 24 | ||
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/resultset/OrderedResultSet.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/resultset/OrderedResultSet.java index 39006d65..df12b967 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/resultset/OrderedResultSet.java +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/resultset/OrderedResultSet.java | |||
@@ -17,7 +17,7 @@ public class OrderedResultSet<T> implements AutoCloseable, ResultSet<T> { | |||
17 | private final ResultSet<T> resultSet; | 17 | private final ResultSet<T> resultSet; |
18 | private final OrderStatisticTree<Tuple> tree = new OrderStatisticTree<>(); | 18 | private final OrderStatisticTree<Tuple> tree = new OrderStatisticTree<>(); |
19 | private final ResultSetListener<T> listener = (key, fromValue, toValue) -> { | 19 | private final ResultSetListener<T> listener = (key, fromValue, toValue) -> { |
20 | var defaultValue = getQuery().defaultValue(); | 20 | var defaultValue = getCanonicalQuery().defaultValue(); |
21 | if (Objects.equals(defaultValue, toValue)) { | 21 | if (Objects.equals(defaultValue, toValue)) { |
22 | tree.remove(key); | 22 | tree.remove(key); |
23 | } else { | 23 | } else { |
@@ -45,8 +45,8 @@ public class OrderedResultSet<T> implements AutoCloseable, ResultSet<T> { | |||
45 | } | 45 | } |
46 | 46 | ||
47 | @Override | 47 | @Override |
48 | public Query<T> getQuery() { | 48 | public Query<T> getCanonicalQuery() { |
49 | return resultSet.getQuery(); | 49 | return resultSet.getCanonicalQuery(); |
50 | } | 50 | } |
51 | 51 | ||
52 | @Override | 52 | @Override |
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/resultset/ResultSet.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/resultset/ResultSet.java index 33d1ea95..a6e99784 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/resultset/ResultSet.java +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/resultset/ResultSet.java | |||
@@ -10,7 +10,7 @@ import tools.refinery.store.query.dnf.Query; | |||
10 | import tools.refinery.store.tuple.Tuple; | 10 | import tools.refinery.store.tuple.Tuple; |
11 | 11 | ||
12 | public non-sealed interface ResultSet<T> extends AnyResultSet { | 12 | public non-sealed interface ResultSet<T> extends AnyResultSet { |
13 | Query<T> getQuery(); | 13 | Query<T> getCanonicalQuery(); |
14 | 14 | ||
15 | T get(Tuple parameters); | 15 | T get(Tuple parameters); |
16 | 16 | ||
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/rewriter/ClauseInputParameterResolver.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/rewriter/ClauseInputParameterResolver.java index bdd07f19..aa06a05a 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/rewriter/ClauseInputParameterResolver.java +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/rewriter/ClauseInputParameterResolver.java | |||
@@ -53,7 +53,7 @@ class ClauseInputParameterResolver { | |||
53 | } | 53 | } |
54 | boolean hasInputParameter = hasInputParameter(targetDnf); | 54 | boolean hasInputParameter = hasInputParameter(targetDnf); |
55 | if (!hasInputParameter) { | 55 | if (!hasInputParameter) { |
56 | targetDnf = rewriter.doRewrite(targetDnf); | 56 | targetDnf = rewriter.rewrite(targetDnf); |
57 | } | 57 | } |
58 | if (inlinePositiveClause(abstractCallLiteral, targetDnf)) { | 58 | if (inlinePositiveClause(abstractCallLiteral, targetDnf)) { |
59 | return; | 59 | return; |
diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/rewriter/InputParameterResolverTest.java b/subprojects/store-query/src/test/java/tools/refinery/store/query/rewriter/InputParameterResolverTest.java index ddb2a069..ef0077e4 100644 --- a/subprojects/store-query/src/test/java/tools/refinery/store/query/rewriter/InputParameterResolverTest.java +++ b/subprojects/store-query/src/test/java/tools/refinery/store/query/rewriter/InputParameterResolverTest.java | |||
@@ -18,6 +18,7 @@ import tools.refinery.store.representation.Symbol; | |||
18 | import java.util.List; | 18 | import java.util.List; |
19 | 19 | ||
20 | import static org.hamcrest.MatcherAssert.assertThat; | 20 | import static org.hamcrest.MatcherAssert.assertThat; |
21 | import static org.hamcrest.Matchers.is; | ||
21 | import static tools.refinery.store.query.literal.Literals.not; | 22 | import static tools.refinery.store.query.literal.Literals.not; |
22 | import static tools.refinery.store.query.tests.QueryMatchers.structurallyEqualTo; | 23 | import static tools.refinery.store.query.tests.QueryMatchers.structurallyEqualTo; |
23 | 24 | ||
@@ -205,4 +206,23 @@ class InputParameterResolverTest { | |||
205 | 206 | ||
206 | assertThat(actual.getDnf(), structurallyEqualTo(expected.getDnf())); | 207 | assertThat(actual.getDnf(), structurallyEqualTo(expected.getDnf())); |
207 | } | 208 | } |
209 | |||
210 | @Test | ||
211 | void identityWhenNoWorkToDoTest() { | ||
212 | var dnf = Dnf.of("SubQuery", builder -> { | ||
213 | var x = builder.parameter("x", ParameterDirection.OUT); | ||
214 | builder.clause( | ||
215 | personView.call(x), | ||
216 | not(friendView.call(x, Variable.of())) | ||
217 | ); | ||
218 | }); | ||
219 | var query = Query.of("Actual", (builder, p1) -> builder.clause( | ||
220 | personView.call(p1), | ||
221 | not(dnf.call(p1)) | ||
222 | )); | ||
223 | |||
224 | var actual = sut.rewrite(query); | ||
225 | |||
226 | assertThat(actual, is(query)); | ||
227 | } | ||
208 | } | 228 | } |