aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/store-reasoning/src/test/java/tools
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2023-08-13 22:23:38 +0200
committerLibravatar Kristóf Marussy <kristof@marussy.com>2023-08-13 22:23:38 +0200
commit9639e80f72f62940baaaf465f818e9f7ce3e265f (patch)
tree50f17fc9fa10f141cff5229515be091317c8816f /subprojects/store-reasoning/src/test/java/tools
parentrefactor: partial model initialzer unique table (diff)
downloadrefinery-9639e80f72f62940baaaf465f818e9f7ce3e265f.tar.gz
refinery-9639e80f72f62940baaaf465f818e9f7ce3e265f.tar.zst
refinery-9639e80f72f62940baaaf465f818e9f7ce3e265f.zip
feat: metamodel translator
Diffstat (limited to 'subprojects/store-reasoning/src/test/java/tools')
-rw-r--r--subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/PartialModelTest.java2
-rw-r--r--subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/metamodel/MetamodelTest.java108
-rw-r--r--subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/multiobject/CandidateCountTest.java321
-rw-r--r--subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/multiobject/PartialCountTest.java (renamed from subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/ConcreteCountTest.java)27
4 files changed, 442 insertions, 16 deletions
diff --git a/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/PartialModelTest.java b/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/PartialModelTest.java
index b2188f5d..77560a68 100644
--- a/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/PartialModelTest.java
+++ b/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/PartialModelTest.java
@@ -49,7 +49,7 @@ class PartialModelTest {
49 .symbol(personStorage)) 49 .symbol(personStorage))
50 .with(PartialRelationTranslator.of(friend) 50 .with(PartialRelationTranslator.of(friend)
51 .symbol(friendStorage) 51 .symbol(friendStorage)
52 .may(Query.of("mayPerson", (builder, p1, p2) -> builder.clause( 52 .may(Query.of("mayFriend", (builder, p1, p2) -> builder.clause(
53 may(person.call(p1)), 53 may(person.call(p1)),
54 may(person.call(p2)), 54 may(person.call(p2)),
55 not(must(EQUALS_SYMBOL.call(p1, p2))), 55 not(must(EQUALS_SYMBOL.call(p1, p2))),
diff --git a/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/metamodel/MetamodelTest.java b/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/metamodel/MetamodelTest.java
new file mode 100644
index 00000000..9e74cf02
--- /dev/null
+++ b/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/metamodel/MetamodelTest.java
@@ -0,0 +1,108 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.reasoning.translator.metamodel;
7
8import org.junit.jupiter.api.Test;
9import tools.refinery.store.model.ModelStore;
10import tools.refinery.store.query.viatra.ViatraModelQueryAdapter;
11import tools.refinery.store.reasoning.ReasoningAdapter;
12import tools.refinery.store.reasoning.ReasoningStoreAdapter;
13import tools.refinery.store.reasoning.literal.Concreteness;
14import tools.refinery.store.reasoning.representation.PartialRelation;
15import tools.refinery.store.reasoning.seed.ModelSeed;
16import tools.refinery.store.reasoning.translator.containment.ContainmentHierarchyTranslator;
17import tools.refinery.store.reasoning.translator.multiobject.MultiObjectTranslator;
18import tools.refinery.store.reasoning.translator.multiplicity.ConstrainedMultiplicity;
19import tools.refinery.store.representation.TruthValue;
20import tools.refinery.store.representation.cardinality.CardinalityIntervals;
21import tools.refinery.store.tuple.Tuple;
22
23import static org.hamcrest.MatcherAssert.assertThat;
24import static org.hamcrest.Matchers.is;
25
26class MetamodelTest {
27 private final PartialRelation person = new PartialRelation("Person", 1);
28 private final PartialRelation student = new PartialRelation("Student", 1);
29 private final PartialRelation teacher = new PartialRelation("Teacher", 1);
30 private final PartialRelation university = new PartialRelation("University", 1);
31 private final PartialRelation course = new PartialRelation("Course", 1);
32 private final PartialRelation courses = new PartialRelation("courses", 2);
33 private final PartialRelation location = new PartialRelation("location", 2);
34 private final PartialRelation lecturer = new PartialRelation("lecturer", 2);
35 private final PartialRelation invalidLecturerCount = new PartialRelation("invalidLecturerCount", 1);
36 private final PartialRelation enrolledStudents = new PartialRelation("enrolledStudents", 2);
37 private final PartialRelation invalidStudentCount = new PartialRelation("invalidStudentCount", 1);
38
39 @Test
40 void metamodelTest() {
41 var metamodel = Metamodel.builder()
42 .type(person, true)
43 .type(student, person)
44 .type(teacher, person)
45 .type(university)
46 .type(course)
47 .reference(courses, university, true, course, location)
48 .reference(location, course, university, courses)
49 .reference(lecturer, course,
50 ConstrainedMultiplicity.of(CardinalityIntervals.ONE, invalidLecturerCount), teacher)
51 .reference(enrolledStudents, course,
52 ConstrainedMultiplicity.of(CardinalityIntervals.SOME, invalidStudentCount), student)
53 .build();
54
55 var store = ModelStore.builder()
56 .with(ViatraModelQueryAdapter.builder())
57 .with(ReasoningAdapter.builder())
58 .with(new MultiObjectTranslator())
59 .with(new MetamodelTranslator(metamodel))
60 .build();
61
62 var seed = ModelSeed.builder(5)
63 .seed(MultiObjectTranslator.COUNT_SYMBOL, builder -> builder
64 .reducedValue(CardinalityIntervals.ONE)
65 .put(Tuple.of(1), CardinalityIntervals.SET)
66 .put(Tuple.of(4), CardinalityIntervals.SET))
67 .seed(ContainmentHierarchyTranslator.CONTAINED_SYMBOL, builder -> builder
68 .reducedValue(TruthValue.UNKNOWN))
69 .seed(ContainmentHierarchyTranslator.CONTAINS_SYMBOL, builder -> builder
70 .reducedValue(TruthValue.UNKNOWN))
71 .seed(person, builder -> builder.reducedValue(TruthValue.UNKNOWN))
72 .seed(student, builder -> builder.reducedValue(TruthValue.UNKNOWN))
73 .seed(teacher, builder -> builder.reducedValue(TruthValue.UNKNOWN))
74 .seed(university, builder -> builder
75 .reducedValue(TruthValue.UNKNOWN)
76 .put(Tuple.of(0), TruthValue.TRUE))
77 .seed(course, builder -> builder
78 .reducedValue(TruthValue.UNKNOWN)
79 .put(Tuple.of(2), TruthValue.TRUE))
80 .seed(courses, builder -> builder.reducedValue(TruthValue.UNKNOWN))
81 .seed(location, builder -> builder
82 .reducedValue(TruthValue.UNKNOWN)
83 .put(Tuple.of(1, 0), TruthValue.TRUE))
84 .seed(lecturer, builder -> builder
85 .reducedValue(TruthValue.FALSE)
86 .put(Tuple.of(1, 3), TruthValue.TRUE))
87 .seed(enrolledStudents, builder -> builder.reducedValue(TruthValue.UNKNOWN))
88 .build();
89
90 var model = store.getAdapter(ReasoningStoreAdapter.class).createInitialModel(seed);
91 var reasoningAdapter = model.getAdapter(ReasoningAdapter.class);
92
93 var coursesInterpretation = reasoningAdapter.getPartialInterpretation(Concreteness.PARTIAL, courses);
94 assertThat(coursesInterpretation.get(Tuple.of(0, 1)), is(TruthValue.TRUE));
95 assertThat(coursesInterpretation.get(Tuple.of(0, 2)), is(TruthValue.UNKNOWN));
96 assertThat(coursesInterpretation.get(Tuple.of(0, 3)), is(TruthValue.FALSE));
97
98 var invalidLecturerCountInterpretation = reasoningAdapter.getPartialInterpretation(Concreteness.PARTIAL,
99 invalidLecturerCount);
100 assertThat(invalidLecturerCountInterpretation.get(Tuple.of(1)), is(TruthValue.FALSE));
101 assertThat(invalidLecturerCountInterpretation.get(Tuple.of(2)), is(TruthValue.ERROR));
102
103 var enrolledStudentsInterpretation = reasoningAdapter.getPartialInterpretation(Concreteness.PARTIAL,
104 enrolledStudents);
105 assertThat(enrolledStudentsInterpretation.get(Tuple.of(1, 3)), is(TruthValue.FALSE));
106 assertThat(enrolledStudentsInterpretation.get(Tuple.of(1, 4)), is(TruthValue.UNKNOWN));
107 }
108}
diff --git a/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/multiobject/CandidateCountTest.java b/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/multiobject/CandidateCountTest.java
new file mode 100644
index 00000000..28391ec7
--- /dev/null
+++ b/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/multiobject/CandidateCountTest.java
@@ -0,0 +1,321 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.reasoning.translator.multiobject;
7
8import org.junit.jupiter.api.Test;
9import tools.refinery.store.model.ModelStore;
10import tools.refinery.store.query.ModelQueryAdapter;
11import tools.refinery.store.query.dnf.Query;
12import tools.refinery.store.query.resultset.ResultSet;
13import tools.refinery.store.query.term.Variable;
14import tools.refinery.store.query.viatra.ViatraModelQueryAdapter;
15import tools.refinery.store.reasoning.ReasoningAdapter;
16import tools.refinery.store.reasoning.ReasoningStoreAdapter;
17import tools.refinery.store.reasoning.literal.CountCandidateLowerBoundLiteral;
18import tools.refinery.store.reasoning.literal.CountCandidateUpperBoundLiteral;
19import tools.refinery.store.reasoning.representation.PartialRelation;
20import tools.refinery.store.reasoning.seed.ModelSeed;
21import tools.refinery.store.reasoning.translator.PartialRelationTranslator;
22import tools.refinery.store.representation.Symbol;
23import tools.refinery.store.representation.TruthValue;
24import tools.refinery.store.representation.cardinality.CardinalityIntervals;
25import tools.refinery.store.tuple.Tuple;
26
27import java.util.List;
28
29import static org.hamcrest.MatcherAssert.assertThat;
30import static org.hamcrest.Matchers.is;
31import static tools.refinery.store.query.literal.Literals.not;
32import static tools.refinery.store.reasoning.literal.PartialLiterals.must;
33
34class CandidateCountTest {
35 private static final PartialRelation person = new PartialRelation("Person", 1);
36 private static final PartialRelation friend = new PartialRelation("friend", 2);
37
38 @Test
39 void lowerBoundZeroTest() {
40 var query = Query.of("LowerBound", Integer.class, (builder, p1, p2, output) -> builder.clause(
41 must(person.call(p1)),
42 must(person.call(p2)),
43 new CountCandidateLowerBoundLiteral(output, friend, List.of(p1, p2))
44 ));
45
46 var modelSeed = ModelSeed.builder(2)
47 .seed(MultiObjectTranslator.COUNT_SYMBOL, builder -> builder
48 .put(Tuple.of(0), CardinalityIntervals.atLeast(3))
49 .put(Tuple.of(1), CardinalityIntervals.atMost(7)))
50 .seed(person, builder -> builder.reducedValue(TruthValue.TRUE))
51 .seed(friend, builder -> builder
52 .put(Tuple.of(0, 1), TruthValue.TRUE)
53 .put(Tuple.of(1, 0), TruthValue.UNKNOWN)
54 .put(Tuple.of(1, 1), TruthValue.ERROR))
55 .build();
56
57 var resultSet = getResultSet(query, modelSeed);
58 assertThat(resultSet.get(Tuple.of(0, 0)), is(0));
59 assertThat(resultSet.get(Tuple.of(0, 1)), is(1));
60 assertThat(resultSet.get(Tuple.of(1, 0)), is(0));
61 assertThat(resultSet.get(Tuple.of(1, 1)), is(1));
62 }
63
64 @Test
65 void upperBoundZeroTest() {
66 var query = Query.of("UpperBound", Integer.class, (builder, p1, p2, output) -> builder.clause(
67 must(person.call(p1)),
68 must(person.call(p2)),
69 new CountCandidateUpperBoundLiteral(output, friend, List.of(p1, p2))
70 ));
71
72 var modelSeed = ModelSeed.builder(2)
73 .seed(MultiObjectTranslator.COUNT_SYMBOL, builder -> builder
74 .put(Tuple.of(0), CardinalityIntervals.atLeast(3))
75 .put(Tuple.of(1), CardinalityIntervals.atMost(7)))
76 .seed(person, builder -> builder.reducedValue(TruthValue.TRUE))
77 .seed(friend, builder -> builder
78 .put(Tuple.of(0, 1), TruthValue.TRUE)
79 .put(Tuple.of(1, 0), TruthValue.UNKNOWN)
80 .put(Tuple.of(1, 1), TruthValue.ERROR))
81 .build();
82
83 var resultSet = getResultSet(query, modelSeed);
84 assertThat(resultSet.get(Tuple.of(0, 0)), is(0));
85 assertThat(resultSet.get(Tuple.of(0, 1)), is(1));
86 assertThat(resultSet.get(Tuple.of(1, 0)), is(0));
87 assertThat(resultSet.get(Tuple.of(1, 1)), is(1));
88 }
89
90 @Test
91 void lowerBoundOneTest() {
92 var query = Query.of("LowerBound", Integer.class, (builder, p1, output) -> builder.clause(
93 must(person.call(p1)),
94 new CountCandidateLowerBoundLiteral(output, friend, List.of(p1, Variable.of()))
95 ));
96
97 var modelSeed = ModelSeed.builder(4)
98 .seed(MultiObjectTranslator.COUNT_SYMBOL, builder -> builder
99 .reducedValue(CardinalityIntervals.ONE)
100 .put(Tuple.of(1), CardinalityIntervals.atLeast(3))
101 .put(Tuple.of(2), CardinalityIntervals.atMost(7)))
102 .seed(person, builder -> builder.reducedValue(TruthValue.TRUE))
103 .seed(friend, builder -> builder
104 .put(Tuple.of(0, 1), TruthValue.TRUE)
105 .put(Tuple.of(0, 2), TruthValue.TRUE)
106 .put(Tuple.of(0, 3), TruthValue.TRUE)
107 .put(Tuple.of(1, 0), TruthValue.TRUE)
108 .put(Tuple.of(1, 2), TruthValue.UNKNOWN)
109 .put(Tuple.of(1, 3), TruthValue.UNKNOWN)
110 .put(Tuple.of(2, 0), TruthValue.TRUE)
111 .put(Tuple.of(2, 1), TruthValue.ERROR))
112 .build();
113
114 var resultSet = getResultSet(query, modelSeed);
115 assertThat(resultSet.get(Tuple.of(0)), is(2));
116 assertThat(resultSet.get(Tuple.of(1)), is(1));
117 assertThat(resultSet.get(Tuple.of(2)), is(2));
118 assertThat(resultSet.get(Tuple.of(3)), is(0));
119 }
120
121 @Test
122 void upperBoundOneTest() {
123 var query = Query.of("UpperBound", Integer.class, (builder, p1, output) -> builder.clause(
124 must(person.call(p1)),
125 new CountCandidateUpperBoundLiteral(output, friend, List.of(p1, Variable.of()))
126 ));
127
128 var modelSeed = ModelSeed.builder(4)
129 .seed(MultiObjectTranslator.COUNT_SYMBOL, builder -> builder
130 .reducedValue(CardinalityIntervals.ONE)
131 .put(Tuple.of(1), CardinalityIntervals.atLeast(3))
132 .put(Tuple.of(2), CardinalityIntervals.atMost(7)))
133 .seed(person, builder -> builder.reducedValue(TruthValue.TRUE))
134 .seed(friend, builder -> builder
135 .put(Tuple.of(0, 1), TruthValue.TRUE)
136 .put(Tuple.of(0, 2), TruthValue.TRUE)
137 .put(Tuple.of(0, 3), TruthValue.TRUE)
138 .put(Tuple.of(1, 0), TruthValue.TRUE)
139 .put(Tuple.of(1, 2), TruthValue.UNKNOWN)
140 .put(Tuple.of(1, 3), TruthValue.UNKNOWN)
141 .put(Tuple.of(2, 0), TruthValue.TRUE)
142 .put(Tuple.of(2, 1), TruthValue.ERROR))
143 .build();
144
145 var resultSet = getResultSet(query, modelSeed);
146 assertThat(resultSet.get(Tuple.of(0)), is(2));
147 assertThat(resultSet.get(Tuple.of(1)), is(1));
148 assertThat(resultSet.get(Tuple.of(2)), is(2));
149 assertThat(resultSet.get(Tuple.of(3)), is(0));
150 }
151
152 @Test
153 void lowerBoundTwoTest() {
154 var subQuery = Query.of("SubQuery", (builder, p1, p2, p3) -> builder.clause(
155 friend.call(p1, p2),
156 friend.call(p1, p3),
157 friend.call(p2, p3)
158 ));
159 var query = Query.of("LowerBound", Integer.class, (builder, p1, output) -> builder.clause(
160 must(person.call(p1)),
161 new CountCandidateLowerBoundLiteral(output, subQuery.getDnf(),
162 List.of(p1, Variable.of(), Variable.of()))
163 ));
164
165 var modelSeed = ModelSeed.builder(4)
166 .seed(MultiObjectTranslator.COUNT_SYMBOL, builder -> builder
167 .reducedValue(CardinalityIntervals.ONE)
168 .put(Tuple.of(0), CardinalityIntervals.between(5, 9))
169 .put(Tuple.of(1), CardinalityIntervals.atLeast(3))
170 .put(Tuple.of(2), CardinalityIntervals.atMost(7)))
171 .seed(person, builder -> builder.reducedValue(TruthValue.TRUE))
172 .seed(friend, builder -> builder
173 .put(Tuple.of(0, 1), TruthValue.TRUE)
174 .put(Tuple.of(0, 2), TruthValue.TRUE)
175 .put(Tuple.of(0, 3), TruthValue.TRUE)
176 .put(Tuple.of(1, 0), TruthValue.TRUE)
177 .put(Tuple.of(1, 2), TruthValue.TRUE)
178 .put(Tuple.of(1, 3), TruthValue.TRUE)
179 .put(Tuple.of(2, 0), TruthValue.TRUE)
180 .put(Tuple.of(2, 1), TruthValue.ERROR))
181 .build();
182
183 var resultSet = getResultSet(query, modelSeed);
184 assertThat(resultSet.get(Tuple.of(0)), is(1));
185 assertThat(resultSet.get(Tuple.of(1)), is(1));
186 assertThat(resultSet.get(Tuple.of(2)), is(2));
187 assertThat(resultSet.get(Tuple.of(3)), is(0));
188 }
189
190 @Test
191 void upperBoundTwoTest() {
192 var subQuery = Query.of("SubQuery", (builder, p1, p2, p3) -> builder.clause(
193 friend.call(p1, p2),
194 friend.call(p1, p3),
195 friend.call(p2, p3)
196 ));
197 var query = Query.of("UpperBound", Integer.class, (builder, p1, output) -> builder.clause(
198 must(person.call(p1)),
199 new CountCandidateUpperBoundLiteral(output, subQuery.getDnf(),
200 List.of(p1, Variable.of(), Variable.of()))
201 ));
202
203 var modelSeed = ModelSeed.builder(4)
204 .seed(MultiObjectTranslator.COUNT_SYMBOL, builder -> builder
205 .reducedValue(CardinalityIntervals.ONE)
206 .put(Tuple.of(0), CardinalityIntervals.between(5, 9))
207 .put(Tuple.of(1), CardinalityIntervals.atLeast(3))
208 .put(Tuple.of(2), CardinalityIntervals.atMost(7)))
209 .seed(person, builder -> builder.reducedValue(TruthValue.TRUE))
210 .seed(friend, builder -> builder
211 .put(Tuple.of(0, 1), TruthValue.TRUE)
212 .put(Tuple.of(0, 2), TruthValue.TRUE)
213 .put(Tuple.of(0, 3), TruthValue.TRUE)
214 .put(Tuple.of(1, 0), TruthValue.TRUE)
215 .put(Tuple.of(1, 2), TruthValue.UNKNOWN)
216 .put(Tuple.of(1, 3), TruthValue.UNKNOWN)
217 .put(Tuple.of(2, 0), TruthValue.TRUE)
218 .put(Tuple.of(2, 1), TruthValue.ERROR))
219 .build();
220
221 var resultSet = getResultSet(query, modelSeed);
222 assertThat(resultSet.get(Tuple.of(0)), is(0));
223 assertThat(resultSet.get(Tuple.of(1)), is(0));
224 assertThat(resultSet.get(Tuple.of(2)), is(2));
225 assertThat(resultSet.get(Tuple.of(3)), is(0));
226 }
227
228 @Test
229 void lowerBoundDiagonalTest() {
230 var subQuery = Query.of("SubQuery", (builder, p1, p2, p3) -> builder.clause(
231 friend.call(p1, p2),
232 friend.call(p1, p3),
233 not(friend.call(p2, p3))
234 ));
235 var query = Query.of("LowerBound", Integer.class, (builder, p1, output) -> builder.clause(v1 -> List.of(
236 must(person.call(p1)),
237 new CountCandidateLowerBoundLiteral(output, subQuery.getDnf(), List.of(p1, v1, v1))
238 )));
239
240 var modelSeed = ModelSeed.builder(4)
241 .seed(MultiObjectTranslator.COUNT_SYMBOL, builder -> builder
242 .reducedValue(CardinalityIntervals.ONE)
243 .put(Tuple.of(0), CardinalityIntervals.between(5, 9))
244 .put(Tuple.of(1), CardinalityIntervals.atLeast(3))
245 .put(Tuple.of(2), CardinalityIntervals.atMost(7)))
246 .seed(person, builder -> builder.reducedValue(TruthValue.TRUE))
247 .seed(friend, builder -> builder
248 .put(Tuple.of(0, 1), TruthValue.TRUE)
249 .put(Tuple.of(0, 2), TruthValue.TRUE)
250 .put(Tuple.of(0, 3), TruthValue.TRUE)
251 .put(Tuple.of(1, 0), TruthValue.TRUE)
252 .put(Tuple.of(1, 2), TruthValue.UNKNOWN)
253 .put(Tuple.of(1, 3), TruthValue.UNKNOWN)
254 .put(Tuple.of(2, 0), TruthValue.TRUE)
255 .put(Tuple.of(2, 1), TruthValue.ERROR))
256 .build();
257
258 var resultSet = getResultSet(query, modelSeed);
259 assertThat(resultSet.get(Tuple.of(0)), is(2));
260 assertThat(resultSet.get(Tuple.of(1)), is(1));
261 assertThat(resultSet.get(Tuple.of(2)), is(2));
262 assertThat(resultSet.get(Tuple.of(3)), is(0));
263 }
264
265 @Test
266 void upperBoundDiagonalTest() {
267 var subQuery = Query.of("SubQuery", (builder, p1, p2, p3) -> builder.clause(
268 friend.call(p1, p2),
269 friend.call(p1, p3),
270 not(friend.call(p2, p3))
271 ));
272 var query = Query.of("UpperBound", Integer.class, (builder, p1, output) -> builder
273 .clause(v1 -> List.of(
274 must(person.call(p1)),
275 new CountCandidateUpperBoundLiteral(output, subQuery.getDnf(), List.of(p1, v1, v1))
276 )));
277
278 var modelSeed = ModelSeed.builder(4)
279 .seed(MultiObjectTranslator.COUNT_SYMBOL, builder -> builder
280 .reducedValue(CardinalityIntervals.ONE)
281 .put(Tuple.of(0), CardinalityIntervals.between(5, 9))
282 .put(Tuple.of(1), CardinalityIntervals.atLeast(3))
283 .put(Tuple.of(2), CardinalityIntervals.atMost(7)))
284 .seed(person, builder -> builder.reducedValue(TruthValue.TRUE))
285 .seed(friend, builder -> builder
286 .put(Tuple.of(0, 1), TruthValue.TRUE)
287 .put(Tuple.of(0, 2), TruthValue.TRUE)
288 .put(Tuple.of(0, 3), TruthValue.TRUE)
289 .put(Tuple.of(1, 0), TruthValue.TRUE)
290 .put(Tuple.of(1, 2), TruthValue.UNKNOWN)
291 .put(Tuple.of(1, 3), TruthValue.UNKNOWN)
292 .put(Tuple.of(2, 0), TruthValue.TRUE)
293 .put(Tuple.of(2, 1), TruthValue.ERROR))
294 .build();
295
296 var resultSet = getResultSet(query, modelSeed);
297 assertThat(resultSet.get(Tuple.of(0)), is(2));
298 assertThat(resultSet.get(Tuple.of(1)), is(1));
299 assertThat(resultSet.get(Tuple.of(2)), is(2));
300 assertThat(resultSet.get(Tuple.of(3)), is(0));
301 }
302
303 private static <T> ResultSet<T> getResultSet(Query<T> query, ModelSeed modelSeed) {
304 var personStorage = Symbol.of("Person", 1, TruthValue.class, TruthValue.FALSE);
305 var friendStorage = Symbol.of("friend", 2, TruthValue.class, TruthValue.FALSE);
306
307 var store = ModelStore.builder()
308 .with(ViatraModelQueryAdapter.builder()
309 .query(query))
310 .with(ReasoningAdapter.builder())
311 .with(new MultiObjectTranslator())
312 .with(PartialRelationTranslator.of(person)
313 .symbol(personStorage))
314 .with(PartialRelationTranslator.of(friend)
315 .symbol(friendStorage))
316 .build();
317
318 var model = store.getAdapter(ReasoningStoreAdapter.class).createInitialModel(modelSeed);
319 return model.getAdapter(ModelQueryAdapter.class).getResultSet(query);
320 }
321}
diff --git a/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/ConcreteCountTest.java b/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/multiobject/PartialCountTest.java
index 21111d7c..64230cf6 100644
--- a/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/ConcreteCountTest.java
+++ b/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/multiobject/PartialCountTest.java
@@ -3,7 +3,7 @@
3 * 3 *
4 * SPDX-License-Identifier: EPL-2.0 4 * SPDX-License-Identifier: EPL-2.0
5 */ 5 */
6package tools.refinery.store.reasoning; 6package tools.refinery.store.reasoning.translator.multiobject;
7 7
8import org.junit.jupiter.api.Test; 8import org.junit.jupiter.api.Test;
9import tools.refinery.store.model.ModelStore; 9import tools.refinery.store.model.ModelStore;
@@ -12,13 +12,13 @@ import tools.refinery.store.query.dnf.Query;
12import tools.refinery.store.query.resultset.ResultSet; 12import tools.refinery.store.query.resultset.ResultSet;
13import tools.refinery.store.query.term.Variable; 13import tools.refinery.store.query.term.Variable;
14import tools.refinery.store.query.viatra.ViatraModelQueryAdapter; 14import tools.refinery.store.query.viatra.ViatraModelQueryAdapter;
15import tools.refinery.store.reasoning.literal.Concreteness; 15import tools.refinery.store.reasoning.ReasoningAdapter;
16import tools.refinery.store.reasoning.ReasoningStoreAdapter;
16import tools.refinery.store.reasoning.literal.CountLowerBoundLiteral; 17import tools.refinery.store.reasoning.literal.CountLowerBoundLiteral;
17import tools.refinery.store.reasoning.literal.CountUpperBoundLiteral; 18import tools.refinery.store.reasoning.literal.CountUpperBoundLiteral;
18import tools.refinery.store.reasoning.representation.PartialRelation; 19import tools.refinery.store.reasoning.representation.PartialRelation;
19import tools.refinery.store.reasoning.seed.ModelSeed; 20import tools.refinery.store.reasoning.seed.ModelSeed;
20import tools.refinery.store.reasoning.translator.PartialRelationTranslator; 21import tools.refinery.store.reasoning.translator.PartialRelationTranslator;
21import tools.refinery.store.reasoning.translator.multiobject.MultiObjectTranslator;
22import tools.refinery.store.representation.Symbol; 22import tools.refinery.store.representation.Symbol;
23import tools.refinery.store.representation.TruthValue; 23import tools.refinery.store.representation.TruthValue;
24import tools.refinery.store.representation.cardinality.CardinalityIntervals; 24import tools.refinery.store.representation.cardinality.CardinalityIntervals;
@@ -33,7 +33,7 @@ import static org.hamcrest.Matchers.is;
33import static tools.refinery.store.query.literal.Literals.not; 33import static tools.refinery.store.query.literal.Literals.not;
34import static tools.refinery.store.reasoning.literal.PartialLiterals.must; 34import static tools.refinery.store.reasoning.literal.PartialLiterals.must;
35 35
36class ConcreteCountTest { 36class PartialCountTest {
37 private static final PartialRelation person = new PartialRelation("Person", 1); 37 private static final PartialRelation person = new PartialRelation("Person", 1);
38 private static final PartialRelation friend = new PartialRelation("friend", 2); 38 private static final PartialRelation friend = new PartialRelation("friend", 2);
39 39
@@ -42,7 +42,7 @@ class ConcreteCountTest {
42 var query = Query.of("LowerBound", Integer.class, (builder, p1, p2, output) -> builder.clause( 42 var query = Query.of("LowerBound", Integer.class, (builder, p1, p2, output) -> builder.clause(
43 must(person.call(p1)), 43 must(person.call(p1)),
44 must(person.call(p2)), 44 must(person.call(p2)),
45 new CountLowerBoundLiteral(output, Concreteness.PARTIAL, friend, List.of(p1, p2)) 45 new CountLowerBoundLiteral(output, friend, List.of(p1, p2))
46 )); 46 ));
47 47
48 var modelSeed = ModelSeed.builder(2) 48 var modelSeed = ModelSeed.builder(2)
@@ -68,7 +68,7 @@ class ConcreteCountTest {
68 var query = Query.of("UpperBound", UpperCardinality.class, (builder, p1, p2, output) -> builder.clause( 68 var query = Query.of("UpperBound", UpperCardinality.class, (builder, p1, p2, output) -> builder.clause(
69 must(person.call(p1)), 69 must(person.call(p1)),
70 must(person.call(p2)), 70 must(person.call(p2)),
71 new CountUpperBoundLiteral(output, Concreteness.PARTIAL, friend, List.of(p1, p2)) 71 new CountUpperBoundLiteral(output, friend, List.of(p1, p2))
72 )); 72 ));
73 73
74 var modelSeed = ModelSeed.builder(2) 74 var modelSeed = ModelSeed.builder(2)
@@ -93,7 +93,7 @@ class ConcreteCountTest {
93 void lowerBoundOneTest() { 93 void lowerBoundOneTest() {
94 var query = Query.of("LowerBound", Integer.class, (builder, p1, output) -> builder.clause( 94 var query = Query.of("LowerBound", Integer.class, (builder, p1, output) -> builder.clause(
95 must(person.call(p1)), 95 must(person.call(p1)),
96 new CountLowerBoundLiteral(output, Concreteness.PARTIAL, friend, List.of(p1, Variable.of())) 96 new CountLowerBoundLiteral(output, friend, List.of(p1, Variable.of()))
97 )); 97 ));
98 98
99 var modelSeed = ModelSeed.builder(4) 99 var modelSeed = ModelSeed.builder(4)
@@ -124,7 +124,7 @@ class ConcreteCountTest {
124 void upperBoundOneTest() { 124 void upperBoundOneTest() {
125 var query = Query.of("UpperBound", UpperCardinality.class, (builder, p1, output) -> builder.clause( 125 var query = Query.of("UpperBound", UpperCardinality.class, (builder, p1, output) -> builder.clause(
126 must(person.call(p1)), 126 must(person.call(p1)),
127 new CountUpperBoundLiteral(output, Concreteness.PARTIAL, friend, List.of(p1, Variable.of())) 127 new CountUpperBoundLiteral(output, friend, List.of(p1, Variable.of()))
128 )); 128 ));
129 129
130 var modelSeed = ModelSeed.builder(4) 130 var modelSeed = ModelSeed.builder(4)
@@ -160,8 +160,7 @@ class ConcreteCountTest {
160 )); 160 ));
161 var query = Query.of("LowerBound", Integer.class, (builder, p1, output) -> builder.clause( 161 var query = Query.of("LowerBound", Integer.class, (builder, p1, output) -> builder.clause(
162 must(person.call(p1)), 162 must(person.call(p1)),
163 new CountLowerBoundLiteral(output, Concreteness.PARTIAL, subQuery.getDnf(), 163 new CountLowerBoundLiteral(output, subQuery.getDnf(), List.of(p1, Variable.of(), Variable.of()))
164 List.of(p1, Variable.of(), Variable.of()))
165 )); 164 ));
166 165
167 var modelSeed = ModelSeed.builder(4) 166 var modelSeed = ModelSeed.builder(4)
@@ -198,8 +197,7 @@ class ConcreteCountTest {
198 )); 197 ));
199 var query = Query.of("UpperBound", UpperCardinality.class, (builder, p1, output) -> builder.clause( 198 var query = Query.of("UpperBound", UpperCardinality.class, (builder, p1, output) -> builder.clause(
200 must(person.call(p1)), 199 must(person.call(p1)),
201 new CountUpperBoundLiteral(output, Concreteness.PARTIAL, subQuery.getDnf(), 200 new CountUpperBoundLiteral(output, subQuery.getDnf(), List.of(p1, Variable.of(), Variable.of()))
202 List.of(p1, Variable.of(), Variable.of()))
203 )); 201 ));
204 202
205 var modelSeed = ModelSeed.builder(4) 203 var modelSeed = ModelSeed.builder(4)
@@ -236,7 +234,7 @@ class ConcreteCountTest {
236 )); 234 ));
237 var query = Query.of("LowerBound", Integer.class, (builder, p1, output) -> builder.clause(v1 -> List.of( 235 var query = Query.of("LowerBound", Integer.class, (builder, p1, output) -> builder.clause(v1 -> List.of(
238 must(person.call(p1)), 236 must(person.call(p1)),
239 new CountLowerBoundLiteral(output, Concreteness.PARTIAL, subQuery.getDnf(), List.of(p1, v1, v1)) 237 new CountLowerBoundLiteral(output, subQuery.getDnf(), List.of(p1, v1, v1))
240 ))); 238 )));
241 239
242 var modelSeed = ModelSeed.builder(4) 240 var modelSeed = ModelSeed.builder(4)
@@ -274,8 +272,7 @@ class ConcreteCountTest {
274 var query = Query.of("UpperBound", UpperCardinality.class, (builder, p1, output) -> builder 272 var query = Query.of("UpperBound", UpperCardinality.class, (builder, p1, output) -> builder
275 .clause(v1 -> List.of( 273 .clause(v1 -> List.of(
276 must(person.call(p1)), 274 must(person.call(p1)),
277 new CountUpperBoundLiteral(output, Concreteness.PARTIAL, subQuery.getDnf(), 275 new CountUpperBoundLiteral(output, subQuery.getDnf(), List.of(p1, v1, v1))
278 List.of(p1, v1, v1))
279 ))); 276 )));
280 277
281 var modelSeed = ModelSeed.builder(4) 278 var modelSeed = ModelSeed.builder(4)