diff options
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.java | 35 |
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 | |||
14 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; | 14 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; |
15 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery; | 15 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery; |
16 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; | 16 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; |
17 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; | ||
17 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; | 18 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; |
18 | import tools.refinery.store.query.Constraint; | 19 | import tools.refinery.store.query.Constraint; |
19 | import tools.refinery.store.query.dnf.Dnf; | 20 | import tools.refinery.store.query.dnf.Dnf; |
20 | import tools.refinery.store.query.dnf.DnfClause; | ||
21 | import tools.refinery.store.query.dnf.DnfUtils; | 21 | import tools.refinery.store.query.dnf.DnfUtils; |
22 | import tools.refinery.store.query.literal.AbstractCallLiteral; | 22 | import tools.refinery.store.query.literal.AbstractCallLiteral; |
23 | import tools.refinery.store.query.term.ParameterDirection; | ||
23 | import tools.refinery.store.query.term.Variable; | 24 | import tools.refinery.store.query.term.Variable; |
24 | import tools.refinery.store.query.view.AnySymbolView; | 25 | import tools.refinery.store.query.view.AnySymbolView; |
25 | import tools.refinery.store.query.view.SymbolView; | 26 | import 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) { |