aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/QueryWrapperFactory.java
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/QueryWrapperFactory.java')
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/QueryWrapperFactory.java35
1 files changed, 23 insertions, 12 deletions
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) {