aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/store-query
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2023-08-20 19:41:32 +0200
committerLibravatar Kristóf Marussy <kristof@marussy.com>2023-08-20 20:29:02 +0200
commita3f1e6872f4f768d14899a1e70bbdc14f32e478d (patch)
treeb2daf0c81724f31ee190f5d63eb42988086dabf2 /subprojects/store-query
parentfix: nullary model initialization (diff)
downloadrefinery-a3f1e6872f4f768d14899a1e70bbdc14f32e478d.tar.gz
refinery-a3f1e6872f4f768d14899a1e70bbdc14f32e478d.tar.zst
refinery-a3f1e6872f4f768d14899a1e70bbdc14f32e478d.zip
feat: improve semantics error reporting
Also makes model seeds cancellable to reduce server load during semantic analysis.
Diffstat (limited to 'subprojects/store-query')
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/InvalidQueryException.java23
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/ClausePostProcessor.java9
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/Dnf.java3
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/DnfBuilder.java88
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/DnfPostProcessor.java112
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/FunctionalDependency.java4
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/FunctionalQuery.java5
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/InvalidClauseException.java35
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/RelationalQuery.java3
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/literal/AbstractCallLiteral.java5
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/literal/AbstractCountLiteral.java5
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/literal/AggregationLiteral.java13
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/literal/AssignLiteral.java7
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CallLiteral.java7
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CallPolarity.java4
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CheckLiteral.java5
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/literal/EquivalenceLiteral.java3
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/literal/RepresentativeElectionLiteral.java9
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/term/AnyDataVariable.java3
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/term/BinaryTerm.java5
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/term/ConstantTerm.java3
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/term/DataVariable.java5
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/term/NodeVariable.java3
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/term/ParameterDirection.java4
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/term/UnaryTerm.java3
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/view/FilteredView.java3
-rw-r--r--subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/DnfToDefinitionStringTest.java4
-rw-r--r--subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/TopologicalSortTest.java7
-rw-r--r--subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/VariableDirectionTest.java10
-rw-r--r--subprojects/store-query/src/test/java/tools/refinery/store/query/literal/AggregationLiteralTest.java13
30 files changed, 261 insertions, 142 deletions
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/InvalidQueryException.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/InvalidQueryException.java
new file mode 100644
index 00000000..c39277a0
--- /dev/null
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/InvalidQueryException.java
@@ -0,0 +1,23 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.query;
7
8public class InvalidQueryException extends RuntimeException {
9 public InvalidQueryException() {
10 }
11
12 public InvalidQueryException(String message) {
13 super(message);
14 }
15
16 public InvalidQueryException(String message, Throwable cause) {
17 super(message, cause);
18 }
19
20 public InvalidQueryException(Throwable cause) {
21 super(cause);
22 }
23}
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/ClausePostProcessor.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/ClausePostProcessor.java
index 5d77b9aa..8800a155 100644
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/ClausePostProcessor.java
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/ClausePostProcessor.java
@@ -7,6 +7,7 @@ package tools.refinery.store.query.dnf;
7 7
8import org.jetbrains.annotations.NotNull; 8import org.jetbrains.annotations.NotNull;
9import tools.refinery.store.query.Constraint; 9import tools.refinery.store.query.Constraint;
10import tools.refinery.store.query.InvalidQueryException;
10import tools.refinery.store.query.literal.*; 11import tools.refinery.store.query.literal.*;
11import tools.refinery.store.query.substitution.MapBasedSubstitution; 12import tools.refinery.store.query.substitution.MapBasedSubstitution;
12import tools.refinery.store.query.substitution.StatelessSubstitution; 13import tools.refinery.store.query.substitution.StatelessSubstitution;
@@ -160,7 +161,7 @@ class ClausePostProcessor {
160 // Inputs count as positive, because they are already bound when we evaluate literals. 161 // Inputs count as positive, because they are already bound when we evaluate literals.
161 positiveVariables.add(variable); 162 positiveVariables.add(variable);
162 } else if (!existentiallyQuantifiedVariables.contains(variable)) { 163 } else if (!existentiallyQuantifiedVariables.contains(variable)) {
163 throw new IllegalArgumentException("Unbound %s parameter %s" 164 throw new InvalidQueryException("Unbound %s parameter %s"
164 .formatted(ParameterDirection.OUT, variable)); 165 .formatted(ParameterDirection.OUT, variable));
165 } 166 }
166 } 167 }
@@ -172,7 +173,7 @@ class ClausePostProcessor {
172 var representative = pair.getKey(); 173 var representative = pair.getKey();
173 if (!positiveVariables.contains(representative)) { 174 if (!positiveVariables.contains(representative)) {
174 var variableSet = pair.getValue(); 175 var variableSet = pair.getValue();
175 throw new IllegalArgumentException("Variables %s were merged by equivalence but are not bound" 176 throw new InvalidQueryException("Variables %s were merged by equivalence but are not bound"
176 .formatted(variableSet)); 177 .formatted(variableSet));
177 } 178 }
178 } 179 }
@@ -184,7 +185,7 @@ class ClausePostProcessor {
184 for (var variable : literal.getPrivateVariables(positiveVariables)) { 185 for (var variable : literal.getPrivateVariables(positiveVariables)) {
185 var oldLiteral = negativeVariablesMap.put(variable, literal); 186 var oldLiteral = negativeVariablesMap.put(variable, literal);
186 if (oldLiteral != null) { 187 if (oldLiteral != null) {
187 throw new IllegalArgumentException("Unbound variable %s appears in multiple literals %s and %s" 188 throw new InvalidQueryException("Unbound variable %s appears in multiple literals %s and %s"
188 .formatted(variable, oldLiteral, literal)); 189 .formatted(variable, oldLiteral, literal));
189 } 190 }
190 } 191 }
@@ -206,7 +207,7 @@ class ClausePostProcessor {
206 variable.addToSortedLiterals(); 207 variable.addToSortedLiterals();
207 } 208 }
208 if (!variableToLiteralInputMap.isEmpty()) { 209 if (!variableToLiteralInputMap.isEmpty()) {
209 throw new IllegalArgumentException("Unbound input variables %s" 210 throw new InvalidQueryException("Unbound input variables %s"
210 .formatted(variableToLiteralInputMap.keySet())); 211 .formatted(variableToLiteralInputMap.keySet()));
211 } 212 }
212 } 213 }
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/Dnf.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/Dnf.java
index 55f1aae5..86a1b6b2 100644
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/Dnf.java
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/Dnf.java
@@ -6,6 +6,7 @@
6package tools.refinery.store.query.dnf; 6package tools.refinery.store.query.dnf;
7 7
8import tools.refinery.store.query.Constraint; 8import tools.refinery.store.query.Constraint;
9import tools.refinery.store.query.InvalidQueryException;
9import tools.refinery.store.query.equality.DnfEqualityChecker; 10import tools.refinery.store.query.equality.DnfEqualityChecker;
10import tools.refinery.store.query.equality.LiteralEqualityHelper; 11import tools.refinery.store.query.equality.LiteralEqualityHelper;
11import tools.refinery.store.query.equality.SubstitutingLiteralEqualityHelper; 12import tools.refinery.store.query.equality.SubstitutingLiteralEqualityHelper;
@@ -55,7 +56,7 @@ public final class Dnf implements Constraint {
55 FunctionalDependency<Variable> functionalDependency) { 56 FunctionalDependency<Variable> functionalDependency) {
56 for (var variable : toValidate) { 57 for (var variable : toValidate) {
57 if (!parameterSet.contains(variable)) { 58 if (!parameterSet.contains(variable)) {
58 throw new IllegalArgumentException( 59 throw new InvalidQueryException(
59 "Variable %s of functional dependency %s does not appear in the parameter list %s" 60 "Variable %s of functional dependency %s does not appear in the parameter list %s"
60 .formatted(variable, functionalDependency, symbolicParameters)); 61 .formatted(variable, functionalDependency, symbolicParameters));
61 } 62 }
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/DnfBuilder.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/DnfBuilder.java
index 0538427f..0f9fd366 100644
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/DnfBuilder.java
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/DnfBuilder.java
@@ -5,10 +5,8 @@
5 */ 5 */
6package tools.refinery.store.query.dnf; 6package tools.refinery.store.query.dnf;
7 7
8import tools.refinery.store.query.InvalidQueryException;
8import tools.refinery.store.query.dnf.callback.*; 9import tools.refinery.store.query.dnf.callback.*;
9import tools.refinery.store.query.equality.DnfEqualityChecker;
10import tools.refinery.store.query.equality.SubstitutingLiteralEqualityHelper;
11import tools.refinery.store.query.equality.SubstitutingLiteralHashCodeHelper;
12import tools.refinery.store.query.literal.Literal; 10import tools.refinery.store.query.literal.Literal;
13import tools.refinery.store.query.term.*; 11import tools.refinery.store.query.term.*;
14 12
@@ -100,7 +98,7 @@ public final class DnfBuilder {
100 public DnfBuilder symbolicParameter(SymbolicParameter symbolicParameter) { 98 public DnfBuilder symbolicParameter(SymbolicParameter symbolicParameter) {
101 var variable = symbolicParameter.getVariable(); 99 var variable = symbolicParameter.getVariable();
102 if (!parameterVariables.add(variable)) { 100 if (!parameterVariables.add(variable)) {
103 throw new IllegalArgumentException("Variable %s is already on the parameter list %s" 101 throw new InvalidQueryException("Variable %s is already on the parameter list %s"
104 .formatted(variable, parameters)); 102 .formatted(variable, parameters));
105 } 103 }
106 parameters.add(symbolicParameter); 104 parameters.add(symbolicParameter);
@@ -218,88 +216,10 @@ public final class DnfBuilder {
218 } 216 }
219 217
220 public Dnf build() { 218 public Dnf build() {
221 var postProcessedClauses = postProcessClauses(); 219 var postProcessor = new DnfPostProcessor(parameters, clauses);
220 var postProcessedClauses = postProcessor.postProcessClauses();
222 return new Dnf(name, Collections.unmodifiableList(parameters), 221 return new Dnf(name, Collections.unmodifiableList(parameters),
223 Collections.unmodifiableList(functionalDependencies), 222 Collections.unmodifiableList(functionalDependencies),
224 Collections.unmodifiableList(postProcessedClauses)); 223 Collections.unmodifiableList(postProcessedClauses));
225 } 224 }
226
227 private List<DnfClause> postProcessClauses() {
228 var parameterInfoMap = getParameterInfoMap();
229 var postProcessedClauses = new LinkedHashSet<CanonicalClause>(clauses.size());
230 for (var literals : clauses) {
231 var postProcessor = new ClausePostProcessor(parameterInfoMap, literals);
232 var result = postProcessor.postProcessClause();
233 if (result instanceof ClausePostProcessor.ClauseResult clauseResult) {
234 postProcessedClauses.add(new CanonicalClause(clauseResult.clause()));
235 } else if (result instanceof ClausePostProcessor.ConstantResult constantResult) {
236 switch (constantResult) {
237 case ALWAYS_TRUE -> {
238 var inputVariables = getInputVariables();
239 return List.of(new DnfClause(inputVariables, List.of()));
240 }
241 case ALWAYS_FALSE -> {
242 // Skip this clause because it can never match.
243 }
244 default -> throw new IllegalStateException("Unexpected ClausePostProcessor.ConstantResult: " +
245 constantResult);
246 }
247 } else {
248 throw new IllegalStateException("Unexpected ClausePostProcessor.Result: " + result);
249 }
250 }
251 return postProcessedClauses.stream().map(CanonicalClause::getDnfClause).toList();
252 }
253
254 private Map<Variable, ClausePostProcessor.ParameterInfo> getParameterInfoMap() {
255 var mutableParameterInfoMap = new LinkedHashMap<Variable, ClausePostProcessor.ParameterInfo>();
256 int arity = parameters.size();
257 for (int i = 0; i < arity; i++) {
258 var parameter = parameters.get(i);
259 mutableParameterInfoMap.put(parameter.getVariable(),
260 new ClausePostProcessor.ParameterInfo(parameter.getDirection(), i));
261 }
262 return Collections.unmodifiableMap(mutableParameterInfoMap);
263 }
264
265 private Set<Variable> getInputVariables() {
266 var inputParameters = new LinkedHashSet<Variable>();
267 for (var parameter : parameters) {
268 if (parameter.getDirection() == ParameterDirection.IN) {
269 inputParameters.add(parameter.getVariable());
270 }
271 }
272 return Collections.unmodifiableSet(inputParameters);
273 }
274
275 private class CanonicalClause {
276 private final DnfClause dnfClause;
277
278 public CanonicalClause(DnfClause dnfClause) {
279 this.dnfClause = dnfClause;
280 }
281
282 public DnfClause getDnfClause() {
283 return dnfClause;
284 }
285
286 @Override
287 public boolean equals(Object obj) {
288 if (this == obj) {
289 return true;
290 }
291 if (obj == null || getClass() != obj.getClass()) {
292 return false;
293 }
294 var otherCanonicalClause = (CanonicalClause) obj;
295 var helper = new SubstitutingLiteralEqualityHelper(DnfEqualityChecker.DEFAULT, parameters, parameters);
296 return dnfClause.equalsWithSubstitution(helper, otherCanonicalClause.dnfClause);
297 }
298
299 @Override
300 public int hashCode() {
301 var helper = new SubstitutingLiteralHashCodeHelper(parameters);
302 return dnfClause.hashCodeWithSubstitution(helper);
303 }
304 }
305} 225}
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/DnfPostProcessor.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/DnfPostProcessor.java
new file mode 100644
index 00000000..50236642
--- /dev/null
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/DnfPostProcessor.java
@@ -0,0 +1,112 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.query.dnf;
7
8import tools.refinery.store.query.InvalidQueryException;
9import tools.refinery.store.query.equality.DnfEqualityChecker;
10import tools.refinery.store.query.equality.SubstitutingLiteralEqualityHelper;
11import tools.refinery.store.query.equality.SubstitutingLiteralHashCodeHelper;
12import tools.refinery.store.query.literal.Literal;
13import tools.refinery.store.query.term.ParameterDirection;
14import tools.refinery.store.query.term.Variable;
15
16import java.util.*;
17
18class DnfPostProcessor {
19 private final List<SymbolicParameter> parameters;
20 private final List<List<Literal>> clauses;
21
22 public DnfPostProcessor(List<SymbolicParameter> parameters, List<List<Literal>> clauses) {
23 this.parameters = parameters;
24 this.clauses = clauses;
25 }
26
27 public List<DnfClause> postProcessClauses() {
28 var parameterInfoMap = getParameterInfoMap();
29 var postProcessedClauses = new LinkedHashSet<CanonicalClause>(clauses.size());
30 int index = 0;
31 for (var literals : clauses) {
32 var postProcessor = new ClausePostProcessor(parameterInfoMap, literals);
33 ClausePostProcessor.Result result;
34 try {
35 result = postProcessor.postProcessClause();
36 } catch (InvalidQueryException e) {
37 throw new InvalidClauseException(index, e);
38 }
39 if (result instanceof ClausePostProcessor.ClauseResult clauseResult) {
40 postProcessedClauses.add(new CanonicalClause(clauseResult.clause()));
41 } else if (result instanceof ClausePostProcessor.ConstantResult constantResult) {
42 switch (constantResult) {
43 case ALWAYS_TRUE -> {
44 var inputVariables = getInputVariables();
45 return List.of(new DnfClause(inputVariables, List.of()));
46 }
47 case ALWAYS_FALSE -> {
48 // Skip this clause because it can never match.
49 }
50 default -> throw new IllegalStateException("Unexpected ClausePostProcessor.ConstantResult: " +
51 constantResult);
52 }
53 } else {
54 throw new IllegalStateException("Unexpected ClausePostProcessor.Result: " + result);
55 }
56 index++;
57 }
58 return postProcessedClauses.stream().map(CanonicalClause::getDnfClause).toList();
59 }
60
61 private Map<Variable, ClausePostProcessor.ParameterInfo> getParameterInfoMap() {
62 var mutableParameterInfoMap = new LinkedHashMap<Variable, ClausePostProcessor.ParameterInfo>();
63 int arity = parameters.size();
64 for (int i = 0; i < arity; i++) {
65 var parameter = parameters.get(i);
66 mutableParameterInfoMap.put(parameter.getVariable(),
67 new ClausePostProcessor.ParameterInfo(parameter.getDirection(), i));
68 }
69 return Collections.unmodifiableMap(mutableParameterInfoMap);
70 }
71
72 private Set<Variable> getInputVariables() {
73 var inputParameters = new LinkedHashSet<Variable>();
74 for (var parameter : parameters) {
75 if (parameter.getDirection() == ParameterDirection.IN) {
76 inputParameters.add(parameter.getVariable());
77 }
78 }
79 return Collections.unmodifiableSet(inputParameters);
80 }
81
82 private class CanonicalClause {
83 private final DnfClause dnfClause;
84
85 public CanonicalClause(DnfClause dnfClause) {
86 this.dnfClause = dnfClause;
87 }
88
89 public DnfClause getDnfClause() {
90 return dnfClause;
91 }
92
93 @Override
94 public boolean equals(Object obj) {
95 if (this == obj) {
96 return true;
97 }
98 if (obj == null || getClass() != obj.getClass()) {
99 return false;
100 }
101 var otherCanonicalClause = (CanonicalClause) obj;
102 var helper = new SubstitutingLiteralEqualityHelper(DnfEqualityChecker.DEFAULT, parameters, parameters);
103 return dnfClause.equalsWithSubstitution(helper, otherCanonicalClause.dnfClause);
104 }
105
106 @Override
107 public int hashCode() {
108 var helper = new SubstitutingLiteralHashCodeHelper(parameters);
109 return dnfClause.hashCodeWithSubstitution(helper);
110 }
111 }
112}
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/FunctionalDependency.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/FunctionalDependency.java
index b00b2cb7..aef07ee3 100644
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/FunctionalDependency.java
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/FunctionalDependency.java
@@ -5,6 +5,8 @@
5 */ 5 */
6package tools.refinery.store.query.dnf; 6package tools.refinery.store.query.dnf;
7 7
8import tools.refinery.store.query.InvalidQueryException;
9
8import java.util.HashSet; 10import java.util.HashSet;
9import java.util.Set; 11import java.util.Set;
10 12
@@ -13,7 +15,7 @@ public record FunctionalDependency<T>(Set<T> forEach, Set<T> unique) {
13 var uniqueForEach = new HashSet<>(unique); 15 var uniqueForEach = new HashSet<>(unique);
14 uniqueForEach.retainAll(forEach); 16 uniqueForEach.retainAll(forEach);
15 if (!uniqueForEach.isEmpty()) { 17 if (!uniqueForEach.isEmpty()) {
16 throw new IllegalArgumentException("Variables %s appear on both sides of the functional dependency" 18 throw new InvalidQueryException("Variables %s appear on both sides of the functional dependency"
17 .formatted(uniqueForEach)); 19 .formatted(uniqueForEach));
18 } 20 }
19 } 21 }
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/FunctionalQuery.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/FunctionalQuery.java
index bf7651ad..225f6844 100644
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/FunctionalQuery.java
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/FunctionalQuery.java
@@ -5,6 +5,7 @@
5 */ 5 */
6package tools.refinery.store.query.dnf; 6package tools.refinery.store.query.dnf;
7 7
8import tools.refinery.store.query.InvalidQueryException;
8import tools.refinery.store.query.literal.CallPolarity; 9import tools.refinery.store.query.literal.CallPolarity;
9import tools.refinery.store.query.term.Aggregator; 10import tools.refinery.store.query.term.Aggregator;
10import tools.refinery.store.query.term.AssignedValue; 11import tools.refinery.store.query.term.AssignedValue;
@@ -26,14 +27,14 @@ public final class FunctionalQuery<T> extends Query<T> {
26 var parameter = parameters.get(i); 27 var parameter = parameters.get(i);
27 var parameterType = parameter.tryGetType(); 28 var parameterType = parameter.tryGetType();
28 if (parameterType.isPresent()) { 29 if (parameterType.isPresent()) {
29 throw new IllegalArgumentException("Expected parameter %s of %s to be a node variable, got %s instead" 30 throw new InvalidQueryException("Expected parameter %s of %s to be a node variable, got %s instead"
30 .formatted(parameter, dnf, parameterType.get().getName())); 31 .formatted(parameter, dnf, parameterType.get().getName()));
31 } 32 }
32 } 33 }
33 var outputParameter = parameters.get(outputIndex); 34 var outputParameter = parameters.get(outputIndex);
34 var outputParameterType = outputParameter.tryGetType(); 35 var outputParameterType = outputParameter.tryGetType();
35 if (outputParameterType.isEmpty() || !outputParameterType.get().equals(type)) { 36 if (outputParameterType.isEmpty() || !outputParameterType.get().equals(type)) {
36 throw new IllegalArgumentException("Expected parameter %s of %s to be %s, but got %s instead".formatted( 37 throw new InvalidQueryException("Expected parameter %s of %s to be %s, but got %s instead".formatted(
37 outputParameter, dnf, type, outputParameterType.map(Class::getName).orElse("node"))); 38 outputParameter, dnf, type, outputParameterType.map(Class::getName).orElse("node")));
38 } 39 }
39 this.type = type; 40 this.type = type;
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/InvalidClauseException.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/InvalidClauseException.java
new file mode 100644
index 00000000..747574b9
--- /dev/null
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/InvalidClauseException.java
@@ -0,0 +1,35 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.query.dnf;
7
8import tools.refinery.store.query.InvalidQueryException;
9
10public class InvalidClauseException extends InvalidQueryException {
11 private final int clauseIndex;
12
13 public InvalidClauseException(int clauseIndex) {
14 this.clauseIndex = clauseIndex;
15 }
16
17 public InvalidClauseException(int clauseIndex, String message) {
18 super(message);
19 this.clauseIndex = clauseIndex;
20 }
21
22 public InvalidClauseException(int clauseIndex, String message, Throwable cause) {
23 super(message, cause);
24 this.clauseIndex = clauseIndex;
25 }
26
27 public InvalidClauseException(int clauseIndex, Throwable cause) {
28 super(cause);
29 this.clauseIndex = clauseIndex;
30 }
31
32 public int getClauseIndex() {
33 return clauseIndex;
34 }
35}
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/RelationalQuery.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/RelationalQuery.java
index 618fb595..98f71e11 100644
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/RelationalQuery.java
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/RelationalQuery.java
@@ -5,6 +5,7 @@
5 */ 5 */
6package tools.refinery.store.query.dnf; 6package tools.refinery.store.query.dnf;
7 7
8import tools.refinery.store.query.InvalidQueryException;
8import tools.refinery.store.query.literal.CallLiteral; 9import tools.refinery.store.query.literal.CallLiteral;
9import tools.refinery.store.query.literal.CallPolarity; 10import tools.refinery.store.query.literal.CallPolarity;
10import tools.refinery.store.query.term.AssignedValue; 11import tools.refinery.store.query.term.AssignedValue;
@@ -19,7 +20,7 @@ public final class RelationalQuery extends Query<Boolean> {
19 for (var parameter : dnf.getSymbolicParameters()) { 20 for (var parameter : dnf.getSymbolicParameters()) {
20 var parameterType = parameter.tryGetType(); 21 var parameterType = parameter.tryGetType();
21 if (parameterType.isPresent()) { 22 if (parameterType.isPresent()) {
22 throw new IllegalArgumentException("Expected parameter %s of %s to be a node variable, got %s instead" 23 throw new InvalidQueryException("Expected parameter %s of %s to be a node variable, got %s instead"
23 .formatted(parameter, dnf, parameterType.get().getName())); 24 .formatted(parameter, dnf, parameterType.get().getName()));
24 } 25 }
25 } 26 }
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/AbstractCallLiteral.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/AbstractCallLiteral.java
index 3722f7f9..0e99d441 100644
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/AbstractCallLiteral.java
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/AbstractCallLiteral.java
@@ -6,6 +6,7 @@
6package tools.refinery.store.query.literal; 6package tools.refinery.store.query.literal;
7 7
8import tools.refinery.store.query.Constraint; 8import tools.refinery.store.query.Constraint;
9import tools.refinery.store.query.InvalidQueryException;
9import tools.refinery.store.query.equality.LiteralEqualityHelper; 10import tools.refinery.store.query.equality.LiteralEqualityHelper;
10import tools.refinery.store.query.equality.LiteralHashCodeHelper; 11import tools.refinery.store.query.equality.LiteralHashCodeHelper;
11import tools.refinery.store.query.substitution.Substitution; 12import tools.refinery.store.query.substitution.Substitution;
@@ -27,7 +28,7 @@ public abstract class AbstractCallLiteral extends AbstractLiteral {
27 protected AbstractCallLiteral(Constraint target, List<Variable> arguments) { 28 protected AbstractCallLiteral(Constraint target, List<Variable> arguments) {
28 int arity = target.arity(); 29 int arity = target.arity();
29 if (arguments.size() != arity) { 30 if (arguments.size() != arity) {
30 throw new IllegalArgumentException("%s needs %d arguments, but got %s".formatted(target.name(), 31 throw new InvalidQueryException("%s needs %d arguments, but got %s".formatted(target.name(),
31 target.arity(), arguments.size())); 32 target.arity(), arguments.size()));
32 } 33 }
33 this.target = target; 34 this.target = target;
@@ -39,7 +40,7 @@ public abstract class AbstractCallLiteral extends AbstractLiteral {
39 var argument = arguments.get(i); 40 var argument = arguments.get(i);
40 var parameter = parameters.get(i); 41 var parameter = parameters.get(i);
41 if (!parameter.isAssignable(argument)) { 42 if (!parameter.isAssignable(argument)) {
42 throw new IllegalArgumentException("Argument %d of %s is not assignable to parameter %s" 43 throw new InvalidQueryException("Argument %d of %s is not assignable to parameter %s"
43 .formatted(i, target, parameter)); 44 .formatted(i, target, parameter));
44 } 45 }
45 switch (parameter.getDirection()) { 46 switch (parameter.getDirection()) {
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/AbstractCountLiteral.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/AbstractCountLiteral.java
index 75f4bd49..9bb572c0 100644
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/AbstractCountLiteral.java
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/AbstractCountLiteral.java
@@ -6,6 +6,7 @@
6package tools.refinery.store.query.literal; 6package tools.refinery.store.query.literal;
7 7
8import tools.refinery.store.query.Constraint; 8import tools.refinery.store.query.Constraint;
9import tools.refinery.store.query.InvalidQueryException;
9import tools.refinery.store.query.equality.LiteralEqualityHelper; 10import tools.refinery.store.query.equality.LiteralEqualityHelper;
10import tools.refinery.store.query.equality.LiteralHashCodeHelper; 11import tools.refinery.store.query.equality.LiteralHashCodeHelper;
11import tools.refinery.store.query.term.ConstantTerm; 12import tools.refinery.store.query.term.ConstantTerm;
@@ -26,11 +27,11 @@ public abstract class AbstractCountLiteral<T> extends AbstractCallLiteral {
26 List<Variable> arguments) { 27 List<Variable> arguments) {
27 super(target, arguments); 28 super(target, arguments);
28 if (!resultVariable.getType().equals(resultType)) { 29 if (!resultVariable.getType().equals(resultType)) {
29 throw new IllegalArgumentException("Count result variable %s must be of type %s, got %s instead".formatted( 30 throw new InvalidQueryException("Count result variable %s must be of type %s, got %s instead".formatted(
30 resultVariable, resultType, resultVariable.getType().getName())); 31 resultVariable, resultType, resultVariable.getType().getName()));
31 } 32 }
32 if (arguments.contains(resultVariable)) { 33 if (arguments.contains(resultVariable)) {
33 throw new IllegalArgumentException("Count result variable %s must not appear in the argument list" 34 throw new InvalidQueryException("Count result variable %s must not appear in the argument list"
34 .formatted(resultVariable)); 35 .formatted(resultVariable));
35 } 36 }
36 this.resultType = resultType; 37 this.resultType = resultType;
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/AggregationLiteral.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/AggregationLiteral.java
index a2f8e009..e3acfacc 100644
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/AggregationLiteral.java
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/AggregationLiteral.java
@@ -6,6 +6,7 @@
6package tools.refinery.store.query.literal; 6package tools.refinery.store.query.literal;
7 7
8import tools.refinery.store.query.Constraint; 8import tools.refinery.store.query.Constraint;
9import tools.refinery.store.query.InvalidQueryException;
9import tools.refinery.store.query.equality.LiteralEqualityHelper; 10import tools.refinery.store.query.equality.LiteralEqualityHelper;
10import tools.refinery.store.query.equality.LiteralHashCodeHelper; 11import tools.refinery.store.query.equality.LiteralHashCodeHelper;
11import tools.refinery.store.query.substitution.Substitution; 12import tools.refinery.store.query.substitution.Substitution;
@@ -26,19 +27,19 @@ public class AggregationLiteral<R, T> extends AbstractCallLiteral {
26 DataVariable<T> inputVariable, Constraint target, List<Variable> arguments) { 27 DataVariable<T> inputVariable, Constraint target, List<Variable> arguments) {
27 super(target, arguments); 28 super(target, arguments);
28 if (!inputVariable.getType().equals(aggregator.getInputType())) { 29 if (!inputVariable.getType().equals(aggregator.getInputType())) {
29 throw new IllegalArgumentException("Input variable %s must of type %s, got %s instead".formatted( 30 throw new InvalidQueryException("Input variable %s must of type %s, got %s instead".formatted(
30 inputVariable, aggregator.getInputType().getName(), inputVariable.getType().getName())); 31 inputVariable, aggregator.getInputType().getName(), inputVariable.getType().getName()));
31 } 32 }
32 if (!getArgumentsOfDirection(ParameterDirection.OUT).contains(inputVariable)) { 33 if (!getArgumentsOfDirection(ParameterDirection.OUT).contains(inputVariable)) {
33 throw new IllegalArgumentException("Input variable %s must be bound with direction %s in the argument list" 34 throw new InvalidQueryException("Input variable %s must be bound with direction %s in the argument list"
34 .formatted(inputVariable, ParameterDirection.OUT)); 35 .formatted(inputVariable, ParameterDirection.OUT));
35 } 36 }
36 if (!resultVariable.getType().equals(aggregator.getResultType())) { 37 if (!resultVariable.getType().equals(aggregator.getResultType())) {
37 throw new IllegalArgumentException("Result variable %s must of type %s, got %s instead".formatted( 38 throw new InvalidQueryException("Result variable %s must of type %s, got %s instead".formatted(
38 resultVariable, aggregator.getResultType().getName(), resultVariable.getType().getName())); 39 resultVariable, aggregator.getResultType().getName(), resultVariable.getType().getName()));
39 } 40 }
40 if (arguments.contains(resultVariable)) { 41 if (arguments.contains(resultVariable)) {
41 throw new IllegalArgumentException("Result variable %s must not appear in the argument list".formatted( 42 throw new InvalidQueryException("Result variable %s must not appear in the argument list".formatted(
42 resultVariable)); 43 resultVariable));
43 } 44 }
44 this.resultVariable = resultVariable; 45 this.resultVariable = resultVariable;
@@ -66,7 +67,7 @@ public class AggregationLiteral<R, T> extends AbstractCallLiteral {
66 @Override 67 @Override
67 public Set<Variable> getInputVariables(Set<? extends Variable> positiveVariablesInClause) { 68 public Set<Variable> getInputVariables(Set<? extends Variable> positiveVariablesInClause) {
68 if (positiveVariablesInClause.contains(inputVariable)) { 69 if (positiveVariablesInClause.contains(inputVariable)) {
69 throw new IllegalArgumentException("Aggregation variable %s must not be bound".formatted(inputVariable)); 70 throw new InvalidQueryException("Aggregation variable %s must not be bound".formatted(inputVariable));
70 } 71 }
71 return super.getInputVariables(positiveVariablesInClause); 72 return super.getInputVariables(positiveVariablesInClause);
72 } 73 }
@@ -80,7 +81,7 @@ public class AggregationLiteral<R, T> extends AbstractCallLiteral {
80 yield emptyValue == null ? BooleanLiteral.FALSE : 81 yield emptyValue == null ? BooleanLiteral.FALSE :
81 resultVariable.assign(new ConstantTerm<>(resultVariable.getType(), emptyValue)); 82 resultVariable.assign(new ConstantTerm<>(resultVariable.getType(), emptyValue));
82 } 83 }
83 case ALWAYS_TRUE -> throw new IllegalArgumentException("Trying to aggregate over an infinite set"); 84 case ALWAYS_TRUE -> throw new InvalidQueryException("Trying to aggregate over an infinite set");
84 case NOT_REDUCIBLE -> this; 85 case NOT_REDUCIBLE -> this;
85 }; 86 };
86 } 87 }
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/AssignLiteral.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/AssignLiteral.java
index d8a4b494..dadf487f 100644
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/AssignLiteral.java
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/AssignLiteral.java
@@ -5,6 +5,7 @@
5 */ 5 */
6package tools.refinery.store.query.literal; 6package tools.refinery.store.query.literal;
7 7
8import tools.refinery.store.query.InvalidQueryException;
8import tools.refinery.store.query.equality.LiteralEqualityHelper; 9import tools.refinery.store.query.equality.LiteralEqualityHelper;
9import tools.refinery.store.query.equality.LiteralHashCodeHelper; 10import tools.refinery.store.query.equality.LiteralHashCodeHelper;
10import tools.refinery.store.query.substitution.Substitution; 11import tools.refinery.store.query.substitution.Substitution;
@@ -16,18 +17,20 @@ import java.util.Collections;
16import java.util.Objects; 17import java.util.Objects;
17import java.util.Set; 18import java.util.Set;
18 19
20// {@link Object#equals(Object)} is implemented by {@link AbstractLiteral}.
21@SuppressWarnings("squid:S2160")
19public class AssignLiteral<T> extends AbstractLiteral { 22public class AssignLiteral<T> extends AbstractLiteral {
20 private final DataVariable<T> variable; 23 private final DataVariable<T> variable;
21 private final Term<T> term; 24 private final Term<T> term;
22 25
23 public AssignLiteral(DataVariable<T> variable, Term<T> term) { 26 public AssignLiteral(DataVariable<T> variable, Term<T> term) {
24 if (!term.getType().equals(variable.getType())) { 27 if (!term.getType().equals(variable.getType())) {
25 throw new IllegalArgumentException("Term %s must be of type %s, got %s instead".formatted( 28 throw new InvalidQueryException("Term %s must be of type %s, got %s instead".formatted(
26 term, variable.getType().getName(), term.getType().getName())); 29 term, variable.getType().getName(), term.getType().getName()));
27 } 30 }
28 var inputVariables = term.getInputVariables(); 31 var inputVariables = term.getInputVariables();
29 if (inputVariables.contains(variable)) { 32 if (inputVariables.contains(variable)) {
30 throw new IllegalArgumentException("Result variable %s must not appear in the term %s".formatted( 33 throw new InvalidQueryException("Result variable %s must not appear in the term %s".formatted(
31 variable, term)); 34 variable, term));
32 } 35 }
33 this.variable = variable; 36 this.variable = variable;
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CallLiteral.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CallLiteral.java
index 1b05943d..2d0e4e97 100644
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CallLiteral.java
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CallLiteral.java
@@ -6,6 +6,7 @@
6package tools.refinery.store.query.literal; 6package tools.refinery.store.query.literal;
7 7
8import tools.refinery.store.query.Constraint; 8import tools.refinery.store.query.Constraint;
9import tools.refinery.store.query.InvalidQueryException;
9import tools.refinery.store.query.equality.LiteralEqualityHelper; 10import tools.refinery.store.query.equality.LiteralEqualityHelper;
10import tools.refinery.store.query.equality.LiteralHashCodeHelper; 11import tools.refinery.store.query.equality.LiteralHashCodeHelper;
11import tools.refinery.store.query.substitution.Substitution; 12import tools.refinery.store.query.substitution.Substitution;
@@ -25,14 +26,14 @@ public final class CallLiteral extends AbstractCallLiteral implements CanNegate<
25 int arity = target.arity(); 26 int arity = target.arity();
26 if (polarity.isTransitive()) { 27 if (polarity.isTransitive()) {
27 if (arity != 2) { 28 if (arity != 2) {
28 throw new IllegalArgumentException("Transitive closures can only take binary relations"); 29 throw new InvalidQueryException("Transitive closures can only take binary relations");
29 } 30 }
30 if (parameters.get(0).isDataVariable() || parameters.get(1).isDataVariable()) { 31 if (parameters.get(0).isDataVariable() || parameters.get(1).isDataVariable()) {
31 throw new IllegalArgumentException("Transitive closures can only be computed over nodes"); 32 throw new InvalidQueryException("Transitive closures can only be computed over nodes");
32 } 33 }
33 if (parameters.get(0).getDirection() != ParameterDirection.OUT || 34 if (parameters.get(0).getDirection() != ParameterDirection.OUT ||
34 parameters.get(1).getDirection() != ParameterDirection.OUT) { 35 parameters.get(1).getDirection() != ParameterDirection.OUT) {
35 throw new IllegalArgumentException("Transitive closures cannot take input parameters"); 36 throw new InvalidQueryException("Transitive closures cannot take input parameters");
36 } 37 }
37 } 38 }
38 this.polarity = polarity; 39 this.polarity = polarity;
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CallPolarity.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CallPolarity.java
index ca70b0fd..716c7109 100644
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CallPolarity.java
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CallPolarity.java
@@ -5,6 +5,8 @@
5 */ 5 */
6package tools.refinery.store.query.literal; 6package tools.refinery.store.query.literal;
7 7
8import tools.refinery.store.query.InvalidQueryException;
9
8public enum CallPolarity { 10public enum CallPolarity {
9 POSITIVE(true, false), 11 POSITIVE(true, false),
10 NEGATIVE(false, false), 12 NEGATIVE(false, false),
@@ -31,7 +33,7 @@ public enum CallPolarity {
31 return switch (this) { 33 return switch (this) {
32 case POSITIVE -> NEGATIVE; 34 case POSITIVE -> NEGATIVE;
33 case NEGATIVE -> POSITIVE; 35 case NEGATIVE -> POSITIVE;
34 case TRANSITIVE -> throw new IllegalArgumentException("Transitive polarity cannot be negated"); 36 case TRANSITIVE -> throw new InvalidQueryException("Transitive polarity cannot be negated");
35 }; 37 };
36 } 38 }
37} 39}
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CheckLiteral.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CheckLiteral.java
index 1271183a..dfedd2cb 100644
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CheckLiteral.java
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CheckLiteral.java
@@ -5,6 +5,7 @@
5 */ 5 */
6package tools.refinery.store.query.literal; 6package tools.refinery.store.query.literal;
7 7
8import tools.refinery.store.query.InvalidQueryException;
8import tools.refinery.store.query.equality.LiteralEqualityHelper; 9import tools.refinery.store.query.equality.LiteralEqualityHelper;
9import tools.refinery.store.query.equality.LiteralHashCodeHelper; 10import tools.refinery.store.query.equality.LiteralHashCodeHelper;
10import tools.refinery.store.query.substitution.Substitution; 11import tools.refinery.store.query.substitution.Substitution;
@@ -18,12 +19,14 @@ import java.util.Collections;
18import java.util.Objects; 19import java.util.Objects;
19import java.util.Set; 20import java.util.Set;
20 21
22// {@link Object#equals(Object)} is implemented by {@link AbstractLiteral}.
23@SuppressWarnings("squid:S2160")
21public class CheckLiteral extends AbstractLiteral implements CanNegate<CheckLiteral> { 24public class CheckLiteral extends AbstractLiteral implements CanNegate<CheckLiteral> {
22 private final Term<Boolean> term; 25 private final Term<Boolean> term;
23 26
24 public CheckLiteral(Term<Boolean> term) { 27 public CheckLiteral(Term<Boolean> term) {
25 if (!term.getType().equals(Boolean.class)) { 28 if (!term.getType().equals(Boolean.class)) {
26 throw new IllegalArgumentException("Term %s must be of type %s, got %s instead".formatted( 29 throw new InvalidQueryException("Term %s must be of type %s, got %s instead".formatted(
27 term, Boolean.class.getName(), term.getType().getName())); 30 term, Boolean.class.getName(), term.getType().getName()));
28 } 31 }
29 this.term = term; 32 this.term = term;
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/EquivalenceLiteral.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/EquivalenceLiteral.java
index 9a0c22d1..7343f709 100644
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/EquivalenceLiteral.java
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/EquivalenceLiteral.java
@@ -5,6 +5,7 @@
5 */ 5 */
6package tools.refinery.store.query.literal; 6package tools.refinery.store.query.literal;
7 7
8import tools.refinery.store.query.InvalidQueryException;
8import tools.refinery.store.query.equality.LiteralEqualityHelper; 9import tools.refinery.store.query.equality.LiteralEqualityHelper;
9import tools.refinery.store.query.equality.LiteralHashCodeHelper; 10import tools.refinery.store.query.equality.LiteralHashCodeHelper;
10import tools.refinery.store.query.substitution.Substitution; 11import tools.refinery.store.query.substitution.Substitution;
@@ -22,7 +23,7 @@ public final class EquivalenceLiteral extends AbstractLiteral implements CanNega
22 23
23 public EquivalenceLiteral(boolean positive, Variable left, Variable right) { 24 public EquivalenceLiteral(boolean positive, Variable left, Variable right) {
24 if (!left.tryGetType().equals(right.tryGetType())) { 25 if (!left.tryGetType().equals(right.tryGetType())) {
25 throw new IllegalArgumentException("Variables %s and %s of different type cannot be equivalent" 26 throw new InvalidQueryException("Variables %s and %s of different type cannot be equivalent"
26 .formatted(left, right)); 27 .formatted(left, right));
27 } 28 }
28 this.positive = positive; 29 this.positive = positive;
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/RepresentativeElectionLiteral.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/RepresentativeElectionLiteral.java
index f6545f9f..f7323947 100644
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/RepresentativeElectionLiteral.java
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/RepresentativeElectionLiteral.java
@@ -6,6 +6,7 @@
6package tools.refinery.store.query.literal; 6package tools.refinery.store.query.literal;
7 7
8import tools.refinery.store.query.Constraint; 8import tools.refinery.store.query.Constraint;
9import tools.refinery.store.query.InvalidQueryException;
9import tools.refinery.store.query.equality.LiteralEqualityHelper; 10import tools.refinery.store.query.equality.LiteralEqualityHelper;
10import tools.refinery.store.query.equality.LiteralHashCodeHelper; 11import tools.refinery.store.query.equality.LiteralHashCodeHelper;
11import tools.refinery.store.query.substitution.Substitution; 12import tools.refinery.store.query.substitution.Substitution;
@@ -32,14 +33,14 @@ public class RepresentativeElectionLiteral extends AbstractCallLiteral {
32 var parameters = target.getParameters(); 33 var parameters = target.getParameters();
33 int arity = target.arity(); 34 int arity = target.arity();
34 if (arity != 2) { 35 if (arity != 2) {
35 throw new IllegalArgumentException("SCCs can only take binary relations"); 36 throw new InvalidQueryException("SCCs can only take binary relations");
36 } 37 }
37 if (parameters.get(0).isDataVariable() || parameters.get(1).isDataVariable()) { 38 if (parameters.get(0).isDataVariable() || parameters.get(1).isDataVariable()) {
38 throw new IllegalArgumentException("SCCs can only be computed over nodes"); 39 throw new InvalidQueryException("SCCs can only be computed over nodes");
39 } 40 }
40 if (parameters.get(0).getDirection() != ParameterDirection.OUT || 41 if (parameters.get(0).getDirection() != ParameterDirection.OUT ||
41 parameters.get(1).getDirection() != ParameterDirection.OUT) { 42 parameters.get(1).getDirection() != ParameterDirection.OUT) {
42 throw new IllegalArgumentException("SCCs cannot take input parameters"); 43 throw new InvalidQueryException("SCCs cannot take input parameters");
43 } 44 }
44 } 45 }
45 46
@@ -72,7 +73,7 @@ public class RepresentativeElectionLiteral extends AbstractCallLiteral {
72 var reduction = getTarget().getReduction(); 73 var reduction = getTarget().getReduction();
73 return switch (reduction) { 74 return switch (reduction) {
74 case ALWAYS_FALSE -> BooleanLiteral.FALSE; 75 case ALWAYS_FALSE -> BooleanLiteral.FALSE;
75 case ALWAYS_TRUE -> throw new IllegalArgumentException( 76 case ALWAYS_TRUE -> throw new InvalidQueryException(
76 "Trying to elect representatives over an infinite set"); 77 "Trying to elect representatives over an infinite set");
77 case NOT_REDUCIBLE -> this; 78 case NOT_REDUCIBLE -> this;
78 }; 79 };
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/AnyDataVariable.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/term/AnyDataVariable.java
index 4d88051b..3801bc11 100644
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/AnyDataVariable.java
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/term/AnyDataVariable.java
@@ -6,6 +6,7 @@
6package tools.refinery.store.query.term; 6package tools.refinery.store.query.term;
7 7
8import org.jetbrains.annotations.Nullable; 8import org.jetbrains.annotations.Nullable;
9import tools.refinery.store.query.InvalidQueryException;
9import tools.refinery.store.query.equality.LiteralEqualityHelper; 10import tools.refinery.store.query.equality.LiteralEqualityHelper;
10 11
11import java.util.Optional; 12import java.util.Optional;
@@ -33,7 +34,7 @@ public abstract sealed class AnyDataVariable extends Variable implements AnyTerm
33 34
34 @Override 35 @Override
35 public NodeVariable asNodeVariable() { 36 public NodeVariable asNodeVariable() {
36 throw new IllegalStateException("%s is a data variable".formatted(this)); 37 throw new InvalidQueryException("%s is a data variable".formatted(this));
37 } 38 }
38 39
39 @Override 40 @Override
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/BinaryTerm.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/term/BinaryTerm.java
index 09c86db6..cdbf592a 100644
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/BinaryTerm.java
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/term/BinaryTerm.java
@@ -5,6 +5,7 @@
5 */ 5 */
6package tools.refinery.store.query.term; 6package tools.refinery.store.query.term;
7 7
8import tools.refinery.store.query.InvalidQueryException;
8import tools.refinery.store.query.equality.LiteralEqualityHelper; 9import tools.refinery.store.query.equality.LiteralEqualityHelper;
9import tools.refinery.store.query.equality.LiteralHashCodeHelper; 10import tools.refinery.store.query.equality.LiteralHashCodeHelper;
10import tools.refinery.store.query.substitution.Substitution; 11import tools.refinery.store.query.substitution.Substitution;
@@ -26,11 +27,11 @@ public abstract class BinaryTerm<R, T1, T2> extends AbstractTerm<R> {
26 protected BinaryTerm(Class<R> type, Class<T1> leftType, Class<T2> rightType, Term<T1> left, Term<T2> right) { 27 protected BinaryTerm(Class<R> type, Class<T1> leftType, Class<T2> rightType, Term<T1> left, Term<T2> right) {
27 super(type); 28 super(type);
28 if (!left.getType().equals(leftType)) { 29 if (!left.getType().equals(leftType)) {
29 throw new IllegalArgumentException("Expected left %s to be of type %s, got %s instead".formatted( 30 throw new InvalidQueryException("Expected left %s to be of type %s, got %s instead".formatted(
30 left, leftType.getName(), left.getType().getName())); 31 left, leftType.getName(), left.getType().getName()));
31 } 32 }
32 if (!right.getType().equals(rightType)) { 33 if (!right.getType().equals(rightType)) {
33 throw new IllegalArgumentException("Expected right %s to be of type %s, got %s instead".formatted( 34 throw new InvalidQueryException("Expected right %s to be of type %s, got %s instead".formatted(
34 right, rightType.getName(), right.getType().getName())); 35 right, rightType.getName(), right.getType().getName()));
35 } 36 }
36 this.leftType = leftType; 37 this.leftType = leftType;
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/ConstantTerm.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/term/ConstantTerm.java
index e722c84f..415ae286 100644
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/ConstantTerm.java
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/term/ConstantTerm.java
@@ -5,6 +5,7 @@
5 */ 5 */
6package tools.refinery.store.query.term; 6package tools.refinery.store.query.term;
7 7
8import tools.refinery.store.query.InvalidQueryException;
8import tools.refinery.store.query.equality.LiteralEqualityHelper; 9import tools.refinery.store.query.equality.LiteralEqualityHelper;
9import tools.refinery.store.query.equality.LiteralHashCodeHelper; 10import tools.refinery.store.query.equality.LiteralHashCodeHelper;
10import tools.refinery.store.query.substitution.Substitution; 11import tools.refinery.store.query.substitution.Substitution;
@@ -21,7 +22,7 @@ public final class ConstantTerm<T> extends AbstractTerm<T> {
21 public ConstantTerm(Class<T> type, T value) { 22 public ConstantTerm(Class<T> type, T value) {
22 super(type); 23 super(type);
23 if (value != null && !type.isInstance(value)) { 24 if (value != null && !type.isInstance(value)) {
24 throw new IllegalArgumentException("Value %s is not an instance of %s".formatted(value, type.getName())); 25 throw new InvalidQueryException("Value %s is not an instance of %s".formatted(value, type.getName()));
25 } 26 }
26 this.value = value; 27 this.value = value;
27 } 28 }
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/DataVariable.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/term/DataVariable.java
index 9b62e545..2206b522 100644
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/DataVariable.java
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/term/DataVariable.java
@@ -6,6 +6,7 @@
6package tools.refinery.store.query.term; 6package tools.refinery.store.query.term;
7 7
8import org.jetbrains.annotations.Nullable; 8import org.jetbrains.annotations.Nullable;
9import tools.refinery.store.query.InvalidQueryException;
9import tools.refinery.store.query.equality.LiteralEqualityHelper; 10import tools.refinery.store.query.equality.LiteralEqualityHelper;
10import tools.refinery.store.query.equality.LiteralHashCodeHelper; 11import tools.refinery.store.query.equality.LiteralHashCodeHelper;
11import tools.refinery.store.query.literal.EquivalenceLiteral; 12import tools.refinery.store.query.literal.EquivalenceLiteral;
@@ -41,8 +42,8 @@ public final class DataVariable<T> extends AnyDataVariable implements Term<T> {
41 @Override 42 @Override
42 public <U> DataVariable<U> asDataVariable(Class<U> newType) { 43 public <U> DataVariable<U> asDataVariable(Class<U> newType) {
43 if (!getType().equals(newType)) { 44 if (!getType().equals(newType)) {
44 throw new IllegalStateException("%s is not of type %s but of type %s".formatted(this, newType.getName(), 45 throw new InvalidQueryException("%s is not of type %s but of type %s"
45 getType().getName())); 46 .formatted(this, newType.getName(), getType().getName()));
46 } 47 }
47 @SuppressWarnings("unchecked") 48 @SuppressWarnings("unchecked")
48 var result = (DataVariable<U>) this; 49 var result = (DataVariable<U>) this;
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/NodeVariable.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/term/NodeVariable.java
index 2f9c8bf1..53c32e20 100644
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/NodeVariable.java
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/term/NodeVariable.java
@@ -6,6 +6,7 @@
6package tools.refinery.store.query.term; 6package tools.refinery.store.query.term;
7 7
8import org.jetbrains.annotations.Nullable; 8import org.jetbrains.annotations.Nullable;
9import tools.refinery.store.query.InvalidQueryException;
9import tools.refinery.store.query.literal.ConstantLiteral; 10import tools.refinery.store.query.literal.ConstantLiteral;
10import tools.refinery.store.query.literal.EquivalenceLiteral; 11import tools.refinery.store.query.literal.EquivalenceLiteral;
11 12
@@ -48,7 +49,7 @@ public final class NodeVariable extends Variable {
48 49
49 @Override 50 @Override
50 public <T> DataVariable<T> asDataVariable(Class<T> type) { 51 public <T> DataVariable<T> asDataVariable(Class<T> type) {
51 throw new IllegalStateException("%s is a node variable".formatted(this)); 52 throw new InvalidQueryException("%s is a node variable".formatted(this));
52 } 53 }
53 54
54 @Override 55 @Override
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/ParameterDirection.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/term/ParameterDirection.java
index cd0739be..da83f3c3 100644
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/ParameterDirection.java
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/term/ParameterDirection.java
@@ -6,8 +6,8 @@
6package tools.refinery.store.query.term; 6package tools.refinery.store.query.term;
7 7
8public enum ParameterDirection { 8public enum ParameterDirection {
9 OUT("@Out"), 9 OUT("out"),
10 IN("@In"); 10 IN("in");
11 11
12 private final String name; 12 private final String name;
13 13
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/UnaryTerm.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/term/UnaryTerm.java
index 6451ea00..a464ece5 100644
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/UnaryTerm.java
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/term/UnaryTerm.java
@@ -5,6 +5,7 @@
5 */ 5 */
6package tools.refinery.store.query.term; 6package tools.refinery.store.query.term;
7 7
8import tools.refinery.store.query.InvalidQueryException;
8import tools.refinery.store.query.equality.LiteralEqualityHelper; 9import tools.refinery.store.query.equality.LiteralEqualityHelper;
9import tools.refinery.store.query.equality.LiteralHashCodeHelper; 10import tools.refinery.store.query.equality.LiteralHashCodeHelper;
10import tools.refinery.store.query.substitution.Substitution; 11import tools.refinery.store.query.substitution.Substitution;
@@ -22,7 +23,7 @@ public abstract class UnaryTerm<R, T> extends AbstractTerm<R> {
22 protected UnaryTerm(Class<R> type, Class<T> bodyType, Term<T> body) { 23 protected UnaryTerm(Class<R> type, Class<T> bodyType, Term<T> body) {
23 super(type); 24 super(type);
24 if (!body.getType().equals(bodyType)) { 25 if (!body.getType().equals(bodyType)) {
25 throw new IllegalArgumentException("Expected body %s to be of type %s, got %s instead".formatted(body, 26 throw new InvalidQueryException("Expected body %s to be of type %s, got %s instead".formatted(body,
26 bodyType.getName(), body.getType().getName())); 27 bodyType.getName(), body.getType().getName()));
27 } 28 }
28 this.bodyType = bodyType; 29 this.bodyType = bodyType;
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/FilteredView.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/FilteredView.java
index abae6e5c..924277ed 100644
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/FilteredView.java
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/FilteredView.java
@@ -5,6 +5,7 @@
5 */ 5 */
6package tools.refinery.store.query.view; 6package tools.refinery.store.query.view;
7 7
8import tools.refinery.store.query.InvalidQueryException;
8import tools.refinery.store.tuple.Tuple; 9import tools.refinery.store.tuple.Tuple;
9import tools.refinery.store.representation.Symbol; 10import tools.refinery.store.representation.Symbol;
10 11
@@ -66,7 +67,7 @@ public class FilteredView<T> extends TuplePreservingView<T> {
66 // The predicate doesn't need to handle the default value if it is null. 67 // The predicate doesn't need to handle the default value if it is null.
67 } 68 }
68 if (matchesDefaultValue) { 69 if (matchesDefaultValue) {
69 throw new IllegalArgumentException("Tuples with default value %s cannot be enumerated in %s" 70 throw new InvalidQueryException("Tuples with default value %s cannot be enumerated in %s"
70 .formatted(defaultValue, getSymbol())); 71 .formatted(defaultValue, getSymbol()));
71 } 72 }
72 } 73 }
diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/DnfToDefinitionStringTest.java b/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/DnfToDefinitionStringTest.java
index d75d7f17..12cfaa4e 100644
--- a/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/DnfToDefinitionStringTest.java
+++ b/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/DnfToDefinitionStringTest.java
@@ -50,7 +50,7 @@ class DnfToDefinitionStringTest {
50 var dnf = Dnf.builder("Example").parameter(p, ParameterDirection.IN).clause().build(); 50 var dnf = Dnf.builder("Example").parameter(p, ParameterDirection.IN).clause().build();
51 51
52 assertThat(dnf.toDefinitionString(), is(""" 52 assertThat(dnf.toDefinitionString(), is("""
53 pred Example(@In p) <-> 53 pred Example(in p) <->
54 <empty>. 54 <empty>.
55 """)); 55 """));
56 } 56 }
@@ -73,7 +73,7 @@ class DnfToDefinitionStringTest {
73 .build(); 73 .build();
74 74
75 assertThat(dnf.toDefinitionString(), is(""" 75 assertThat(dnf.toDefinitionString(), is("""
76 pred Example(@In p) <-> 76 pred Example(in p) <->
77 !(@RelationView("key") friend(p, q)). 77 !(@RelationView("key") friend(p, q)).
78 """)); 78 """));
79 } 79 }
diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/TopologicalSortTest.java b/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/TopologicalSortTest.java
index e22dbb21..854bd469 100644
--- a/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/TopologicalSortTest.java
+++ b/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/TopologicalSortTest.java
@@ -6,6 +6,7 @@
6package tools.refinery.store.query.dnf; 6package tools.refinery.store.query.dnf;
7 7
8import org.junit.jupiter.api.Test; 8import org.junit.jupiter.api.Test;
9import tools.refinery.store.query.InvalidQueryException;
9import tools.refinery.store.query.term.NodeVariable; 10import tools.refinery.store.query.term.NodeVariable;
10import tools.refinery.store.query.term.ParameterDirection; 11import tools.refinery.store.query.term.ParameterDirection;
11import tools.refinery.store.query.term.Variable; 12import tools.refinery.store.query.term.Variable;
@@ -80,7 +81,7 @@ class TopologicalSortTest {
80 example.call(r, t, q, s), 81 example.call(r, t, q, s),
81 friendView.call(r, t) 82 friendView.call(r, t)
82 ); 83 );
83 assertThrows(IllegalArgumentException.class, builder::build); 84 assertThrows(InvalidQueryException.class, builder::build);
84 } 85 }
85 86
86 @Test 87 @Test
@@ -93,7 +94,7 @@ class TopologicalSortTest {
93 example.call(p, q, r, s), 94 example.call(p, q, r, s),
94 example.call(r, t, q, s) 95 example.call(r, t, q, s)
95 ); 96 );
96 assertThrows(IllegalArgumentException.class, builder::build); 97 assertThrows(InvalidQueryException.class, builder::build);
97 } 98 }
98 99
99 @Test 100 @Test
@@ -107,6 +108,6 @@ class TopologicalSortTest {
107 example.call(r, t, q, s), 108 example.call(r, t, q, s),
108 example.call(p, q, r, t) 109 example.call(p, q, r, t)
109 ); 110 );
110 assertThrows(IllegalArgumentException.class, builder::build); 111 assertThrows(InvalidQueryException.class, builder::build);
111 } 112 }
112} 113}
diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/VariableDirectionTest.java b/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/VariableDirectionTest.java
index bfeaa447..fc3f5d48 100644
--- a/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/VariableDirectionTest.java
+++ b/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/VariableDirectionTest.java
@@ -48,7 +48,7 @@ class VariableDirectionTest {
48 @MethodSource("clausesWithVariableInput") 48 @MethodSource("clausesWithVariableInput")
49 void unboundOutVariableTest(List<? extends Literal> clause) { 49 void unboundOutVariableTest(List<? extends Literal> clause) {
50 var builder = Dnf.builder().parameter(p, ParameterDirection.OUT).clause(clause); 50 var builder = Dnf.builder().parameter(p, ParameterDirection.OUT).clause(clause);
51 assertThrows(IllegalArgumentException.class, builder::build); 51 assertThrows(InvalidClauseException.class, builder::build);
52 } 52 }
53 53
54 @ParameterizedTest 54 @ParameterizedTest
@@ -100,7 +100,7 @@ class VariableDirectionTest {
100 var clauseWithEquivalence = new ArrayList<Literal>(clause); 100 var clauseWithEquivalence = new ArrayList<Literal>(clause);
101 clauseWithEquivalence.add(r.isEquivalent(p)); 101 clauseWithEquivalence.add(r.isEquivalent(p));
102 var builder = Dnf.builder().clause(clauseWithEquivalence); 102 var builder = Dnf.builder().clause(clauseWithEquivalence);
103 assertThrows(IllegalArgumentException.class, builder::build); 103 assertThrows(InvalidClauseException.class, builder::build);
104 } 104 }
105 105
106 static Stream<Arguments> clausesNotBindingVariable() { 106 static Stream<Arguments> clausesNotBindingVariable() {
@@ -118,7 +118,7 @@ class VariableDirectionTest {
118 @MethodSource("literalsWithPrivateVariable") 118 @MethodSource("literalsWithPrivateVariable")
119 void unboundTwicePrivateVariableTest(Literal literal) { 119 void unboundTwicePrivateVariableTest(Literal literal) {
120 var builder = Dnf.builder().clause(not(personView.call(p)), literal); 120 var builder = Dnf.builder().clause(not(personView.call(p)), literal);
121 assertThrows(IllegalArgumentException.class, builder::build); 121 assertThrows(InvalidClauseException.class, builder::build);
122 } 122 }
123 123
124 @ParameterizedTest 124 @ParameterizedTest
@@ -126,7 +126,7 @@ class VariableDirectionTest {
126 void unboundTwiceByEquivalencePrivateVariableTest(Literal literal) { 126 void unboundTwiceByEquivalencePrivateVariableTest(Literal literal) {
127 var r = Variable.of("r"); 127 var r = Variable.of("r");
128 var builder = Dnf.builder().clause(not(personView.call(r)), r.isEquivalent(p), literal); 128 var builder = Dnf.builder().clause(not(personView.call(r)), r.isEquivalent(p), literal);
129 assertThrows(IllegalArgumentException.class, builder::build); 129 assertThrows(InvalidClauseException.class, builder::build);
130 } 130 }
131 131
132 static Stream<Arguments> literalsWithPrivateVariable() { 132 static Stream<Arguments> literalsWithPrivateVariable() {
@@ -159,7 +159,7 @@ class VariableDirectionTest {
159 @MethodSource("literalsWithRequiredVariableInput") 159 @MethodSource("literalsWithRequiredVariableInput")
160 void unboundPrivateVariableTest(Literal literal) { 160 void unboundPrivateVariableTest(Literal literal) {
161 var builder = Dnf.builder().clause(literal); 161 var builder = Dnf.builder().clause(literal);
162 assertThrows(IllegalArgumentException.class, builder::build); 162 assertThrows(InvalidClauseException.class, builder::build);
163 } 163 }
164 164
165 @ParameterizedTest 165 @ParameterizedTest
diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/literal/AggregationLiteralTest.java b/subprojects/store-query/src/test/java/tools/refinery/store/query/literal/AggregationLiteralTest.java
index 35910e08..ddd57e96 100644
--- a/subprojects/store-query/src/test/java/tools/refinery/store/query/literal/AggregationLiteralTest.java
+++ b/subprojects/store-query/src/test/java/tools/refinery/store/query/literal/AggregationLiteralTest.java
@@ -7,15 +7,16 @@ package tools.refinery.store.query.literal;
7 7
8import org.junit.jupiter.api.Test; 8import org.junit.jupiter.api.Test;
9import tools.refinery.store.query.Constraint; 9import tools.refinery.store.query.Constraint;
10import tools.refinery.store.query.InvalidQueryException;
10import tools.refinery.store.query.dnf.Dnf; 11import tools.refinery.store.query.dnf.Dnf;
12import tools.refinery.store.query.dnf.InvalidClauseException;
11import tools.refinery.store.query.term.*; 13import tools.refinery.store.query.term.*;
12 14
13import java.util.List; 15import java.util.List;
14import java.util.Set; 16import java.util.Set;
15 17
16import static org.hamcrest.MatcherAssert.assertThat; 18import static org.hamcrest.MatcherAssert.assertThat;
17import static org.hamcrest.Matchers.containsInAnyOrder; 19import static org.hamcrest.Matchers.*;
18import static org.hamcrest.Matchers.empty;
19import static org.junit.jupiter.api.Assertions.assertAll; 20import static org.junit.jupiter.api.Assertions.assertAll;
20import static org.junit.jupiter.api.Assertions.assertThrows; 21import static org.junit.jupiter.api.Assertions.assertThrows;
21import static tools.refinery.store.query.literal.Literals.not; 22import static tools.refinery.store.query.literal.Literals.not;
@@ -57,13 +58,13 @@ class AggregationLiteralTest {
57 @Test 58 @Test
58 void missingAggregationVariableTest() { 59 void missingAggregationVariableTest() {
59 var aggregation = fakeConstraint.aggregateBy(y, INT_SUM, p, z); 60 var aggregation = fakeConstraint.aggregateBy(y, INT_SUM, p, z);
60 assertThrows(IllegalArgumentException.class, () -> x.assign(aggregation)); 61 assertThrows(InvalidQueryException.class, () -> x.assign(aggregation));
61 } 62 }
62 63
63 @Test 64 @Test
64 void circularAggregationVariableTest() { 65 void circularAggregationVariableTest() {
65 var aggregation = fakeConstraint.aggregateBy(x, INT_SUM, p, x); 66 var aggregation = fakeConstraint.aggregateBy(x, INT_SUM, p, x);
66 assertThrows(IllegalArgumentException.class, () -> x.assign(aggregation)); 67 assertThrows(InvalidQueryException.class, () -> x.assign(aggregation));
67 } 68 }
68 69
69 @Test 70 @Test
@@ -73,7 +74,7 @@ class AggregationLiteralTest {
73 not(fakeConstraint.call(p, y)), 74 not(fakeConstraint.call(p, y)),
74 x.assign(fakeConstraint.aggregateBy(y, INT_SUM, p, y)) 75 x.assign(fakeConstraint.aggregateBy(y, INT_SUM, p, y))
75 ); 76 );
76 assertThrows(IllegalArgumentException.class, builder::build); 77 assertThrows(InvalidClauseException.class, builder::build);
77 } 78 }
78 79
79 @Test 80 @Test
@@ -83,6 +84,6 @@ class AggregationLiteralTest {
83 y.assign(constant(27)), 84 y.assign(constant(27)),
84 x.assign(fakeConstraint.aggregateBy(y, INT_SUM, p, y)) 85 x.assign(fakeConstraint.aggregateBy(y, INT_SUM, p, y))
85 ); 86 );
86 assertThrows(IllegalArgumentException.class, builder::build); 87 assertThrows(InvalidClauseException.class, builder::build);
87 } 88 }
88} 89}