aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/store-query-viatra
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2023-05-01 02:07:23 +0200
committerLibravatar Kristóf Marussy <kristof@marussy.com>2023-05-01 02:42:34 +0200
commit4e698774925468062974b990143c1091e23ed63b (patch)
tree21f2fc38b6b3b5f3be6ecbdee100d385a2e92c05 /subprojects/store-query-viatra
parentfix(web): editor cursor styling (diff)
downloadrefinery-4e698774925468062974b990143c1091e23ed63b.tar.gz
refinery-4e698774925468062974b990143c1091e23ed63b.tar.zst
refinery-4e698774925468062974b990143c1091e23ed63b.zip
feat: query parameter binding validation
* Introduce parameter directions for constraints and DNF * Introduce variable directions for literals * Infer and check variable directions in DNF and topologically sort literals by their input variables
Diffstat (limited to 'subprojects/store-query-viatra')
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalQueryMetaContext.java13
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/Dnf2PQuery.java70
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/QueryWrapperFactory.java35
-rw-r--r--subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/DiagonalQueryTest.java6
4 files changed, 70 insertions, 54 deletions
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalQueryMetaContext.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalQueryMetaContext.java
index cf96b7fd..211eacb4 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalQueryMetaContext.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalQueryMetaContext.java
@@ -9,7 +9,6 @@ import org.eclipse.viatra.query.runtime.matchers.context.AbstractQueryMetaContex
9import org.eclipse.viatra.query.runtime.matchers.context.IInputKey; 9import org.eclipse.viatra.query.runtime.matchers.context.IInputKey;
10import org.eclipse.viatra.query.runtime.matchers.context.InputKeyImplication; 10import org.eclipse.viatra.query.runtime.matchers.context.InputKeyImplication;
11import org.eclipse.viatra.query.runtime.matchers.context.common.JavaTransitiveInstancesKey; 11import org.eclipse.viatra.query.runtime.matchers.context.common.JavaTransitiveInstancesKey;
12import tools.refinery.store.query.term.DataSort;
13import tools.refinery.store.query.viatra.internal.pquery.SymbolViewWrapper; 12import tools.refinery.store.query.viatra.internal.pquery.SymbolViewWrapper;
14import tools.refinery.store.query.view.AnySymbolView; 13import tools.refinery.store.query.view.AnySymbolView;
15 14
@@ -62,14 +61,14 @@ public class RelationalQueryMetaContext extends AbstractQueryMetaContext {
62 relationViewImplication.impliedIndices())); 61 relationViewImplication.impliedIndices()));
63 } 62 }
64 } 63 }
65 var sorts = symbolView.getSorts(); 64 var parameters = symbolView.getParameters();
66 int arity = symbolView.arity(); 65 int arity = symbolView.arity();
67 for (int i = 0; i < arity; i++) { 66 for (int i = 0; i < arity; i++) {
68 var sort = sorts.get(i); 67 var parameter = parameters.get(i);
69 if (sort instanceof DataSort<?> dataSort) { 68 var parameterType = parameter.tryGetType();
70 var javaTransitiveInstancesKey = new JavaTransitiveInstancesKey(dataSort.type()); 69 if (parameterType.isPresent()) {
71 var javaImplication = new InputKeyImplication(implyingKey, javaTransitiveInstancesKey, 70 var javaTransitiveInstancesKey = new JavaTransitiveInstancesKey(parameterType.get());
72 List.of(i)); 71 var javaImplication = new InputKeyImplication(implyingKey, javaTransitiveInstancesKey, List.of(i));
73 inputKeyImplications.add(javaImplication); 72 inputKeyImplications.add(javaImplication);
74 } 73 }
75 } 74 }
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/Dnf2PQuery.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/Dnf2PQuery.java
index b511a5c7..ec880435 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/Dnf2PQuery.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/Dnf2PQuery.java
@@ -19,11 +19,13 @@ import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.Consta
19import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.PositivePatternCall; 19import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.PositivePatternCall;
20import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; 20import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint;
21import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; 21import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter;
22import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection;
22import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery; 23import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery;
23import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; 24import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple;
24import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; 25import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples;
25import tools.refinery.store.query.dnf.Dnf; 26import tools.refinery.store.query.dnf.Dnf;
26import tools.refinery.store.query.dnf.DnfClause; 27import tools.refinery.store.query.dnf.DnfClause;
28import tools.refinery.store.query.dnf.SymbolicParameter;
27import tools.refinery.store.query.literal.*; 29import tools.refinery.store.query.literal.*;
28import tools.refinery.store.query.term.ConstantTerm; 30import tools.refinery.store.query.term.ConstantTerm;
29import tools.refinery.store.query.term.StatefulAggregator; 31import tools.refinery.store.query.term.StatefulAggregator;
@@ -82,15 +84,20 @@ public class Dnf2PQuery {
82 var pQuery = new RawPQuery(dnfQuery.getUniqueName()); 84 var pQuery = new RawPQuery(dnfQuery.getUniqueName());
83 pQuery.setEvaluationHints(consumeHint(dnfQuery)); 85 pQuery.setEvaluationHints(consumeHint(dnfQuery));
84 86
85 Map<Variable, PParameter> parameters = new HashMap<>(); 87 Map<SymbolicParameter, PParameter> parameters = new HashMap<>();
86 for (Variable variable : dnfQuery.getParameters()) {
87 parameters.put(variable, new PParameter(variable.getUniqueName()));
88 }
89
90 List<PParameter> parameterList = new ArrayList<>(); 88 List<PParameter> parameterList = new ArrayList<>();
91 for (var param : dnfQuery.getParameters()) { 89 for (var parameter : dnfQuery.getSymbolicParameters()) {
92 parameterList.add(parameters.get(param)); 90 var direction = switch (parameter.getDirection()) {
91 case IN_OUT -> PParameterDirection.INOUT;
92 case OUT -> PParameterDirection.OUT;
93 case IN -> throw new IllegalArgumentException("Query %s with input parameter %s is not supported"
94 .formatted(dnfQuery, parameter.getVariable()));
95 };
96 var pParameter = new PParameter(parameter.getVariable().getUniqueName(), null, null, direction);
97 parameters.put(parameter, pParameter);
98 parameterList.add(pParameter);
93 } 99 }
100
94 pQuery.setParameters(parameterList); 101 pQuery.setParameters(parameterList);
95 102
96 for (var functionalDependency : dnfQuery.getFunctionalDependencies()) { 103 for (var functionalDependency : dnfQuery.getFunctionalDependencies()) {
@@ -110,15 +117,15 @@ public class Dnf2PQuery {
110 synchronized (P_CONSTRAINT_LOCK) { 117 synchronized (P_CONSTRAINT_LOCK) {
111 for (DnfClause clause : dnfQuery.getClauses()) { 118 for (DnfClause clause : dnfQuery.getClauses()) {
112 PBody body = new PBody(pQuery); 119 PBody body = new PBody(pQuery);
113 List<ExportedParameter> symbolicParameters = new ArrayList<>(); 120 List<ExportedParameter> parameterExports = new ArrayList<>();
114 for (var param : dnfQuery.getParameters()) { 121 for (var parameter : dnfQuery.getSymbolicParameters()) {
115 PVariable pVar = body.getOrCreateVariableByName(param.getUniqueName()); 122 PVariable pVar = body.getOrCreateVariableByName(parameter.getVariable().getUniqueName());
116 symbolicParameters.add(new ExportedParameter(body, pVar, parameters.get(param))); 123 parameterExports.add(new ExportedParameter(body, pVar, parameters.get(parameter)));
117 } 124 }
118 body.setSymbolicParameters(symbolicParameters); 125 body.setSymbolicParameters(parameterExports);
119 pQuery.addBody(body); 126 pQuery.addBody(body);
120 for (Literal literal : clause.literals()) { 127 for (Literal literal : clause.literals()) {
121 translateLiteral(literal, clause, body); 128 translateLiteral(literal, body);
122 } 129 }
123 } 130 }
124 } 131 }
@@ -126,11 +133,11 @@ public class Dnf2PQuery {
126 return pQuery; 133 return pQuery;
127 } 134 }
128 135
129 private void translateLiteral(Literal literal, DnfClause clause, PBody body) { 136 private void translateLiteral(Literal literal, PBody body) {
130 if (literal instanceof EquivalenceLiteral equivalenceLiteral) { 137 if (literal instanceof EquivalenceLiteral equivalenceLiteral) {
131 translateEquivalenceLiteral(equivalenceLiteral, body); 138 translateEquivalenceLiteral(equivalenceLiteral, body);
132 } else if (literal instanceof CallLiteral callLiteral) { 139 } else if (literal instanceof CallLiteral callLiteral) {
133 translateCallLiteral(callLiteral, clause, body); 140 translateCallLiteral(callLiteral, body);
134 } else if (literal instanceof ConstantLiteral constantLiteral) { 141 } else if (literal instanceof ConstantLiteral constantLiteral) {
135 translateConstantLiteral(constantLiteral, body); 142 translateConstantLiteral(constantLiteral, body);
136 } else if (literal instanceof AssignLiteral<?> assignLiteral) { 143 } else if (literal instanceof AssignLiteral<?> assignLiteral) {
@@ -138,25 +145,25 @@ public class Dnf2PQuery {
138 } else if (literal instanceof AssumeLiteral assumeLiteral) { 145 } else if (literal instanceof AssumeLiteral assumeLiteral) {
139 translateAssumeLiteral(assumeLiteral, body); 146 translateAssumeLiteral(assumeLiteral, body);
140 } else if (literal instanceof CountLiteral countLiteral) { 147 } else if (literal instanceof CountLiteral countLiteral) {
141 translateCountLiteral(countLiteral, clause, body); 148 translateCountLiteral(countLiteral, body);
142 } else if (literal instanceof AggregationLiteral<?, ?> aggregationLiteral) { 149 } else if (literal instanceof AggregationLiteral<?, ?> aggregationLiteral) {
143 translateAggregationLiteral(aggregationLiteral, clause, body); 150 translateAggregationLiteral(aggregationLiteral, body);
144 } else { 151 } else {
145 throw new IllegalArgumentException("Unknown literal: " + literal.toString()); 152 throw new IllegalArgumentException("Unknown literal: " + literal.toString());
146 } 153 }
147 } 154 }
148 155
149 private void translateEquivalenceLiteral(EquivalenceLiteral equivalenceLiteral, PBody body) { 156 private void translateEquivalenceLiteral(EquivalenceLiteral equivalenceLiteral, PBody body) {
150 PVariable varSource = body.getOrCreateVariableByName(equivalenceLiteral.left().getUniqueName()); 157 PVariable varSource = body.getOrCreateVariableByName(equivalenceLiteral.getLeft().getUniqueName());
151 PVariable varTarget = body.getOrCreateVariableByName(equivalenceLiteral.right().getUniqueName()); 158 PVariable varTarget = body.getOrCreateVariableByName(equivalenceLiteral.getRight().getUniqueName());
152 if (equivalenceLiteral.positive()) { 159 if (equivalenceLiteral.isPositive()) {
153 new Equality(body, varSource, varTarget); 160 new Equality(body, varSource, varTarget);
154 } else { 161 } else {
155 new Inequality(body, varSource, varTarget); 162 new Inequality(body, varSource, varTarget);
156 } 163 }
157 } 164 }
158 165
159 private void translateCallLiteral(CallLiteral callLiteral, DnfClause clause, PBody body) { 166 private void translateCallLiteral(CallLiteral callLiteral, PBody body) {
160 var polarity = callLiteral.getPolarity(); 167 var polarity = callLiteral.getPolarity();
161 switch (polarity) { 168 switch (polarity) {
162 case POSITIVE -> { 169 case POSITIVE -> {
@@ -186,7 +193,7 @@ public class Dnf2PQuery {
186 new BinaryTransitiveClosure(body, substitution, pattern); 193 new BinaryTransitiveClosure(body, substitution, pattern);
187 } 194 }
188 case NEGATIVE -> { 195 case NEGATIVE -> {
189 var wrappedCall = wrapperFactory.maybeWrapConstraint(callLiteral, clause); 196 var wrappedCall = wrapperFactory.maybeWrapConstraint(callLiteral);
190 var substitution = translateSubstitution(wrappedCall.remappedArguments(), body); 197 var substitution = translateSubstitution(wrappedCall.remappedArguments(), body);
191 var pattern = wrappedCall.pattern(); 198 var pattern = wrappedCall.pattern();
192 new NegativePatternCall(body, substitution, pattern); 199 new NegativePatternCall(body, substitution, pattern);
@@ -206,13 +213,13 @@ public class Dnf2PQuery {
206 } 213 }
207 214
208 private void translateConstantLiteral(ConstantLiteral constantLiteral, PBody body) { 215 private void translateConstantLiteral(ConstantLiteral constantLiteral, PBody body) {
209 var variable = body.getOrCreateVariableByName(constantLiteral.variable().getUniqueName()); 216 var variable = body.getOrCreateVariableByName(constantLiteral.getVariable().getUniqueName());
210 new ConstantValue(body, variable, constantLiteral.nodeId()); 217 new ConstantValue(body, variable, constantLiteral.getNodeId());
211 } 218 }
212 219
213 private <T> void translateAssignLiteral(AssignLiteral<T> assignLiteral, PBody body) { 220 private <T> void translateAssignLiteral(AssignLiteral<T> assignLiteral, PBody body) {
214 var variable = body.getOrCreateVariableByName(assignLiteral.variable().getUniqueName()); 221 var variable = body.getOrCreateVariableByName(assignLiteral.getTargetVariable().getUniqueName());
215 var term = assignLiteral.term(); 222 var term = assignLiteral.getTerm();
216 if (term instanceof ConstantTerm<T> constantTerm) { 223 if (term instanceof ConstantTerm<T> constantTerm) {
217 new ConstantValue(body, variable, constantTerm.getValue()); 224 new ConstantValue(body, variable, constantTerm.getValue());
218 } else { 225 } else {
@@ -222,19 +229,18 @@ public class Dnf2PQuery {
222 } 229 }
223 230
224 private void translateAssumeLiteral(AssumeLiteral assumeLiteral, PBody body) { 231 private void translateAssumeLiteral(AssumeLiteral assumeLiteral, PBody body) {
225 var evaluator = new AssumptionEvaluator(assumeLiteral.term()); 232 var evaluator = new AssumptionEvaluator(assumeLiteral.getTerm());
226 new ExpressionEvaluation(body, evaluator, null); 233 new ExpressionEvaluation(body, evaluator, null);
227 } 234 }
228 235
229 private void translateCountLiteral(CountLiteral countLiteral, DnfClause clause, PBody body) { 236 private void translateCountLiteral(CountLiteral countLiteral, PBody body) {
230 var wrappedCall = wrapperFactory.maybeWrapConstraint(countLiteral, clause); 237 var wrappedCall = wrapperFactory.maybeWrapConstraint(countLiteral);
231 var substitution = translateSubstitution(wrappedCall.remappedArguments(), body); 238 var substitution = translateSubstitution(wrappedCall.remappedArguments(), body);
232 var resultVariable = body.getOrCreateVariableByName(countLiteral.getResultVariable().getUniqueName()); 239 var resultVariable = body.getOrCreateVariableByName(countLiteral.getResultVariable().getUniqueName());
233 new PatternMatchCounter(body, substitution, wrappedCall.pattern(), resultVariable); 240 new PatternMatchCounter(body, substitution, wrappedCall.pattern(), resultVariable);
234 } 241 }
235 242
236 private <R, T> void translateAggregationLiteral(AggregationLiteral<R, T> aggregationLiteral, DnfClause clause, 243 private <R, T> void translateAggregationLiteral(AggregationLiteral<R, T> aggregationLiteral, PBody body) {
237 PBody body) {
238 var aggregator = aggregationLiteral.getAggregator(); 244 var aggregator = aggregationLiteral.getAggregator();
239 IMultisetAggregationOperator<T, ?, R> aggregationOperator; 245 IMultisetAggregationOperator<T, ?, R> aggregationOperator;
240 if (aggregator instanceof StatelessAggregator<R, T> statelessAggregator) { 246 if (aggregator instanceof StatelessAggregator<R, T> statelessAggregator) {
@@ -244,7 +250,7 @@ public class Dnf2PQuery {
244 } else { 250 } else {
245 throw new IllegalArgumentException("Unknown aggregator: " + aggregator); 251 throw new IllegalArgumentException("Unknown aggregator: " + aggregator);
246 } 252 }
247 var wrappedCall = wrapperFactory.maybeWrapConstraint(aggregationLiteral, clause); 253 var wrappedCall = wrapperFactory.maybeWrapConstraint(aggregationLiteral);
248 var substitution = translateSubstitution(wrappedCall.remappedArguments(), body); 254 var substitution = translateSubstitution(wrappedCall.remappedArguments(), body);
249 var inputVariable = body.getOrCreateVariableByName(aggregationLiteral.getInputVariable().getUniqueName()); 255 var inputVariable = body.getOrCreateVariableByName(aggregationLiteral.getInputVariable().getUniqueName());
250 var aggregatedColumn = substitution.invertIndex().get(inputVariable); 256 var aggregatedColumn = substitution.invertIndex().get(inputVariable);
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/QueryWrapperFactory.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/QueryWrapperFactory.java
index 0d046455..2b7280f2 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/QueryWrapperFactory.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/QueryWrapperFactory.java
@@ -14,12 +14,13 @@ import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeCo
14import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; 14import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter;
15import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery; 15import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery;
16import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; 16import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility;
17import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple;
17import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; 18import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples;
18import tools.refinery.store.query.Constraint; 19import tools.refinery.store.query.Constraint;
19import tools.refinery.store.query.dnf.Dnf; 20import tools.refinery.store.query.dnf.Dnf;
20import tools.refinery.store.query.dnf.DnfClause;
21import tools.refinery.store.query.dnf.DnfUtils; 21import tools.refinery.store.query.dnf.DnfUtils;
22import tools.refinery.store.query.literal.AbstractCallLiteral; 22import tools.refinery.store.query.literal.AbstractCallLiteral;
23import tools.refinery.store.query.term.ParameterDirection;
23import tools.refinery.store.query.term.Variable; 24import tools.refinery.store.query.term.Variable;
24import tools.refinery.store.query.view.AnySymbolView; 25import tools.refinery.store.query.view.AnySymbolView;
25import tools.refinery.store.query.view.SymbolView; 26import tools.refinery.store.query.view.SymbolView;
@@ -45,21 +46,17 @@ class QueryWrapperFactory {
45 } 46 }
46 return maybeWrapConstraint(symbolView, identity); 47 return maybeWrapConstraint(symbolView, identity);
47 } 48 }
48 public WrappedCall maybeWrapConstraint(AbstractCallLiteral callLiteral, DnfClause clause) { 49
50 public WrappedCall maybeWrapConstraint(AbstractCallLiteral callLiteral) {
49 var arguments = callLiteral.getArguments(); 51 var arguments = callLiteral.getArguments();
50 int arity = arguments.size(); 52 int arity = arguments.size();
51 var remappedParameters = new int[arity]; 53 var remappedParameters = new int[arity];
52 var boundVariables = clause.boundVariables();
53 var unboundVariableIndices = new HashMap<Variable, Integer>(); 54 var unboundVariableIndices = new HashMap<Variable, Integer>();
54 var appendVariable = new VariableAppender(); 55 var appendVariable = new VariableAppender();
55 for (int i = 0; i < arity; i++) { 56 for (int i = 0; i < arity; i++) {
56 var variable = arguments.get(i); 57 var variable = arguments.get(i);
57 if (boundVariables.contains(variable)) { 58 // Unify all variables to avoid VIATRA bugs, even if they're bound in the containing clause.
58 // Do not join bound variable to make sure that the embedded pattern stays as general as possible. 59 remappedParameters[i] = unboundVariableIndices.computeIfAbsent(variable, appendVariable::applyAsInt);
59 remappedParameters[i] = appendVariable.applyAsInt(variable);
60 } else {
61 remappedParameters[i] = unboundVariableIndices.computeIfAbsent(variable, appendVariable::applyAsInt);
62 }
63 } 60 }
64 var pattern = maybeWrapConstraint(callLiteral.getTarget(), remappedParameters); 61 var pattern = maybeWrapConstraint(callLiteral.getTarget(), remappedParameters);
65 return new WrappedCall(pattern, appendVariable.getRemappedArguments()); 62 return new WrappedCall(pattern, appendVariable.getRemappedArguments());
@@ -89,6 +86,8 @@ class QueryWrapperFactory {
89 var constraint = remappedConstraint.constraint(); 86 var constraint = remappedConstraint.constraint();
90 var remappedParameters = remappedConstraint.remappedParameters(); 87 var remappedParameters = remappedConstraint.remappedParameters();
91 88
89 checkNoInputParameters(constraint);
90
92 var embeddedPQuery = new RawPQuery(DnfUtils.generateUniqueName(constraint.name()), PVisibility.EMBEDDED); 91 var embeddedPQuery = new RawPQuery(DnfUtils.generateUniqueName(constraint.name()), PVisibility.EMBEDDED);
93 var body = new PBody(embeddedPQuery); 92 var body = new PBody(embeddedPQuery);
94 int arity = Arrays.stream(remappedParameters).max().orElse(-1) + 1; 93 int arity = Arrays.stream(remappedParameters).max().orElse(-1) + 1;
@@ -112,6 +111,21 @@ class QueryWrapperFactory {
112 } 111 }
113 var argumentTuple = Tuples.flatTupleOf(arguments); 112 var argumentTuple = Tuples.flatTupleOf(arguments);
114 113
114 addPositiveConstraint(constraint, body, argumentTuple);
115 embeddedPQuery.addBody(body);
116 return embeddedPQuery;
117 }
118
119 private static void checkNoInputParameters(Constraint constraint) {
120 for (var constraintParameter : constraint.getParameters()) {
121 if (constraintParameter.getDirection() == ParameterDirection.IN) {
122 throw new IllegalArgumentException("Input parameter %s of %s is not supported"
123 .formatted(constraintParameter, constraint));
124 }
125 }
126 }
127
128 private void addPositiveConstraint(Constraint constraint, PBody body, Tuple argumentTuple) {
115 if (constraint instanceof SymbolView<?> view) { 129 if (constraint instanceof SymbolView<?> view) {
116 new TypeConstraint(body, argumentTuple, getInputKey(view)); 130 new TypeConstraint(body, argumentTuple, getInputKey(view));
117 } else if (constraint instanceof Dnf dnf) { 131 } else if (constraint instanceof Dnf dnf) {
@@ -120,9 +134,6 @@ class QueryWrapperFactory {
120 } else { 134 } else {
121 throw new IllegalArgumentException("Unknown Constraint: " + constraint); 135 throw new IllegalArgumentException("Unknown Constraint: " + constraint);
122 } 136 }
123
124 embeddedPQuery.addBody(body);
125 return embeddedPQuery;
126 } 137 }
127 138
128 public IInputKey getInputKey(AnySymbolView symbolView) { 139 public IInputKey getInputKey(AnySymbolView symbolView) {
diff --git a/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/DiagonalQueryTest.java b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/DiagonalQueryTest.java
index 56ddb9b4..86a27f5b 100644
--- a/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/DiagonalQueryTest.java
+++ b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/DiagonalQueryTest.java
@@ -298,10 +298,10 @@ class DiagonalQueryTest {
298 y.assign(x) 298 y.assign(x)
299 ); 299 );
300 }); 300 });
301 var query = Query.of("Diagonal", Integer.class, (builder, p1, output) -> builder.clause(Integer.class, 301 var query = Query.of("Diagonal", Integer.class, (builder, p1, output) -> builder.clause(
302 (p2, y) -> List.of( 302 Integer.class, Integer.class, (p2, y, z) -> List.of(
303 personView.call(p1), 303 personView.call(p1),
304 output.assign(subQuery.aggregate(y, INT_SUM, p1, p1, p2, p2, y, y)) 304 output.assign(subQuery.aggregate(y, INT_SUM, p1, p1, p2, p2, y, z))
305 ))); 305 )));
306 306
307 var store = ModelStore.builder() 307 var store = ModelStore.builder()