diff options
Diffstat (limited to 'subprojects/store-query/src/test/java/tools/refinery/store/query/rewriter/InputParameterResolverTest.java')
-rw-r--r-- | subprojects/store-query/src/test/java/tools/refinery/store/query/rewriter/InputParameterResolverTest.java | 228 |
1 files changed, 228 insertions, 0 deletions
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 new file mode 100644 index 00000000..ef0077e4 --- /dev/null +++ b/subprojects/store-query/src/test/java/tools/refinery/store/query/rewriter/InputParameterResolverTest.java | |||
@@ -0,0 +1,228 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.query.rewriter; | ||
7 | |||
8 | import org.junit.jupiter.api.BeforeEach; | ||
9 | import org.junit.jupiter.api.Test; | ||
10 | import tools.refinery.store.query.dnf.Dnf; | ||
11 | import tools.refinery.store.query.dnf.Query; | ||
12 | import tools.refinery.store.query.term.ParameterDirection; | ||
13 | import tools.refinery.store.query.term.Variable; | ||
14 | import tools.refinery.store.query.view.AnySymbolView; | ||
15 | import tools.refinery.store.query.view.KeyOnlyView; | ||
16 | import tools.refinery.store.representation.Symbol; | ||
17 | |||
18 | import java.util.List; | ||
19 | |||
20 | import static org.hamcrest.MatcherAssert.assertThat; | ||
21 | import static org.hamcrest.Matchers.is; | ||
22 | import static tools.refinery.store.query.literal.Literals.not; | ||
23 | import static tools.refinery.store.query.tests.QueryMatchers.structurallyEqualTo; | ||
24 | |||
25 | class InputParameterResolverTest { | ||
26 | private final static Symbol<Boolean> person = Symbol.of("Person", 1); | ||
27 | private final static Symbol<Boolean> friend = Symbol.of("friend", 2); | ||
28 | private final static AnySymbolView personView = new KeyOnlyView<>(person); | ||
29 | private final static AnySymbolView friendView = new KeyOnlyView<>(friend); | ||
30 | |||
31 | private InputParameterResolver sut; | ||
32 | |||
33 | @BeforeEach | ||
34 | void beforeEach() { | ||
35 | sut = new InputParameterResolver(); | ||
36 | } | ||
37 | |||
38 | @Test | ||
39 | void inlineSingleClauseTest() { | ||
40 | var dnf = Dnf.of("SubQuery", builder -> { | ||
41 | var x = builder.parameter("x", ParameterDirection.OUT); | ||
42 | builder.clause(friendView.call(x, Variable.of())); | ||
43 | }); | ||
44 | var query = Query.of("Actual", (builder, x) -> builder.clause( | ||
45 | dnf.call(x), | ||
46 | personView.call(x) | ||
47 | )); | ||
48 | |||
49 | var actual = sut.rewrite(query); | ||
50 | |||
51 | var expected = Query.of("Expected", (builder, x) -> builder.clause( | ||
52 | friendView.call(x, Variable.of()), | ||
53 | personView.call(x) | ||
54 | )); | ||
55 | |||
56 | assertThat(actual.getDnf(), structurallyEqualTo(expected.getDnf())); | ||
57 | } | ||
58 | |||
59 | @Test | ||
60 | void inlineSingleClauseWIthInputTest() { | ||
61 | var dnf = Dnf.of("SubQuery", builder -> { | ||
62 | var x = builder.parameter("x", ParameterDirection.IN); | ||
63 | builder.clause(not(friendView.call(x, Variable.of()))); | ||
64 | }); | ||
65 | var query = Query.of("Actual", (builder, x) -> builder.clause( | ||
66 | dnf.call(x), | ||
67 | personView.call(x) | ||
68 | )); | ||
69 | |||
70 | var actual = sut.rewrite(query); | ||
71 | |||
72 | var expected = Query.of("Expected", (builder, x) -> builder.clause( | ||
73 | personView.call(x), | ||
74 | not(friendView.call(x, Variable.of())) | ||
75 | )); | ||
76 | |||
77 | assertThat(actual.getDnf(), structurallyEqualTo(expected.getDnf())); | ||
78 | } | ||
79 | |||
80 | @Test | ||
81 | void singleLiteralDemandSetTest() { | ||
82 | var dnf = Dnf.of("SubQuery", builder -> { | ||
83 | var x = builder.parameter("x", ParameterDirection.IN); | ||
84 | builder.clause(not(friendView.call(x, Variable.of()))); | ||
85 | builder.clause(not(friendView.call(Variable.of(), x))); | ||
86 | }); | ||
87 | var query = Query.of("Actual", (builder, x) -> builder.clause( | ||
88 | dnf.call(x), | ||
89 | personView.call(x) | ||
90 | )); | ||
91 | |||
92 | var actual = sut.rewrite(query); | ||
93 | |||
94 | var expectedSubQuery = Dnf.of("ExpectedSubQuery", builder -> { | ||
95 | var x = builder.parameter("x", ParameterDirection.OUT); | ||
96 | builder.clause( | ||
97 | personView.call(x), | ||
98 | not(friendView.call(x, Variable.of())) | ||
99 | ); | ||
100 | builder.clause( | ||
101 | personView.call(x), | ||
102 | not(friendView.call(Variable.of(), x)) | ||
103 | ); | ||
104 | }); | ||
105 | var expected = Query.of("Expected", (builder, x) -> builder.clause( | ||
106 | personView.call(x), | ||
107 | expectedSubQuery.call(x) | ||
108 | )); | ||
109 | |||
110 | assertThat(actual.getDnf(), structurallyEqualTo(expected.getDnf())); | ||
111 | } | ||
112 | |||
113 | @Test | ||
114 | void multipleLiteralDemandSetTest() { | ||
115 | var dnf = Dnf.of("SubQuery", builder -> { | ||
116 | var x = builder.parameter("x", ParameterDirection.IN); | ||
117 | var y = builder.parameter("y", ParameterDirection.IN); | ||
118 | builder.clause(not(friendView.call(x, y))); | ||
119 | builder.clause(not(friendView.call(y, x))); | ||
120 | }); | ||
121 | var query = Query.of("Actual", (builder, p1) -> builder.clause(p2 -> List.of( | ||
122 | not(dnf.call(p1, p2)), | ||
123 | personView.call(p1), | ||
124 | personView.call(p2) | ||
125 | ))); | ||
126 | |||
127 | var actual = sut.rewrite(query); | ||
128 | |||
129 | var context = Dnf.of("Context", builder -> { | ||
130 | var x = builder.parameter("x", ParameterDirection.OUT); | ||
131 | var y = builder.parameter("y", ParameterDirection.OUT); | ||
132 | builder.clause( | ||
133 | personView.call(x), | ||
134 | personView.call(y) | ||
135 | ); | ||
136 | }); | ||
137 | var expectedSubQuery = Dnf.of("ExpectedSubQuery", builder -> { | ||
138 | var x = builder.parameter("x", ParameterDirection.OUT); | ||
139 | var y = builder.parameter("x", ParameterDirection.OUT); | ||
140 | builder.clause( | ||
141 | context.call(x, y), | ||
142 | not(friendView.call(x, y)) | ||
143 | ); | ||
144 | builder.clause( | ||
145 | context.call(x, y), | ||
146 | not(friendView.call(y, x)) | ||
147 | ); | ||
148 | }); | ||
149 | var expected = Query.of("Expected", (builder, p1) -> builder.clause(p2 -> List.of( | ||
150 | context.call(p1, p2), | ||
151 | not(expectedSubQuery.call(p1, p2)) | ||
152 | ))); | ||
153 | |||
154 | assertThat(actual.getDnf(), structurallyEqualTo(expected.getDnf())); | ||
155 | } | ||
156 | |||
157 | @Test | ||
158 | void multipleParameterDemandSetTest() { | ||
159 | var dnf = Dnf.of("SubQuery", builder -> { | ||
160 | var x = builder.parameter("x", ParameterDirection.IN); | ||
161 | var y = builder.parameter("y", ParameterDirection.IN); | ||
162 | builder.clause(not(friendView.call(x, y))); | ||
163 | builder.clause(not(friendView.call(y, x))); | ||
164 | }); | ||
165 | var query = Query.of("Actual", (builder, p1) -> builder.clause( | ||
166 | not(dnf.call(p1, p1)), | ||
167 | personView.call(p1) | ||
168 | )); | ||
169 | |||
170 | var actual = sut.rewrite(query); | ||
171 | |||
172 | var expectedSubQuery = Dnf.of("ExpectedSubQuery", builder -> { | ||
173 | var x = builder.parameter("x", ParameterDirection.OUT); | ||
174 | var y = builder.parameter("y", ParameterDirection.OUT); | ||
175 | builder.clause( | ||
176 | y.isEquivalent(x), | ||
177 | personView.call(x), | ||
178 | not(friendView.call(x, x)) | ||
179 | ); | ||
180 | }); | ||
181 | var expected = Query.of("Expected", (builder, p1) -> builder.clause( | ||
182 | personView.call(p1), | ||
183 | not(expectedSubQuery.call(p1, p1)) | ||
184 | )); | ||
185 | |||
186 | assertThat(actual.getDnf(), structurallyEqualTo(expected.getDnf())); | ||
187 | } | ||
188 | |||
189 | @Test | ||
190 | void eliminateDoubleNegationTest() { | ||
191 | var dnf = Dnf.of("SubQuery", builder -> { | ||
192 | var x = builder.parameter("x", ParameterDirection.IN); | ||
193 | builder.clause(not(friendView.call(x, Variable.of()))); | ||
194 | }); | ||
195 | var query = Query.of("Actual", (builder, p1) -> builder.clause( | ||
196 | personView.call(p1), | ||
197 | not(dnf.call(p1)) | ||
198 | )); | ||
199 | |||
200 | var actual = sut.rewrite(query); | ||
201 | |||
202 | var expected = Query.of("Actual", (builder, p1) -> builder.clause( | ||
203 | personView.call(p1), | ||
204 | friendView.call(p1, Variable.of()) | ||
205 | )); | ||
206 | |||
207 | assertThat(actual.getDnf(), structurallyEqualTo(expected.getDnf())); | ||
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 | } | ||
228 | } | ||