diff options
Diffstat (limited to 'subprojects')
9 files changed, 39 insertions, 523 deletions
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/ViatraModelQueryBuilderImpl.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/ViatraModelQueryBuilderImpl.java index c8aa067c..cfdc43ba 100644 --- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/ViatraModelQueryBuilderImpl.java +++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/ViatraModelQueryBuilderImpl.java | |||
@@ -15,11 +15,11 @@ import tools.refinery.store.query.rewriter.DuplicateDnfRemover; | |||
15 | import tools.refinery.store.query.rewriter.InputParameterResolver; | 15 | import tools.refinery.store.query.rewriter.InputParameterResolver; |
16 | import tools.refinery.store.query.viatra.ViatraModelQueryBuilder; | 16 | import tools.refinery.store.query.viatra.ViatraModelQueryBuilder; |
17 | import tools.refinery.store.query.viatra.internal.localsearch.FlatCostFunction; | 17 | import tools.refinery.store.query.viatra.internal.localsearch.FlatCostFunction; |
18 | import tools.refinery.store.query.viatra.internal.localsearch.RelationalLocalSearchBackendFactory; | ||
19 | import tools.refinery.store.query.viatra.internal.matcher.RawPatternMatcher; | 18 | import tools.refinery.store.query.viatra.internal.matcher.RawPatternMatcher; |
20 | import tools.refinery.store.query.viatra.internal.pquery.Dnf2PQuery; | 19 | import tools.refinery.store.query.viatra.internal.pquery.Dnf2PQuery; |
21 | import tools.refinery.viatra.runtime.api.IQuerySpecification; | 20 | import tools.refinery.viatra.runtime.api.IQuerySpecification; |
22 | import tools.refinery.viatra.runtime.api.ViatraQueryEngineOptions; | 21 | import tools.refinery.viatra.runtime.api.ViatraQueryEngineOptions; |
22 | import tools.refinery.viatra.runtime.localsearch.matcher.integration.LocalSearchGenericBackendFactory; | ||
23 | import tools.refinery.viatra.runtime.localsearch.matcher.integration.LocalSearchHintOptions; | 23 | import tools.refinery.viatra.runtime.localsearch.matcher.integration.LocalSearchHintOptions; |
24 | import tools.refinery.viatra.runtime.matchers.backend.IQueryBackendFactory; | 24 | import tools.refinery.viatra.runtime.matchers.backend.IQueryBackendFactory; |
25 | import tools.refinery.viatra.runtime.matchers.backend.QueryEvaluationHint; | 25 | import tools.refinery.viatra.runtime.matchers.backend.QueryEvaluationHint; |
@@ -43,7 +43,7 @@ public class ViatraModelQueryBuilderImpl extends AbstractModelAdapterBuilder<Via | |||
43 | engineOptionsBuilder = new ViatraQueryEngineOptions.Builder() | 43 | engineOptionsBuilder = new ViatraQueryEngineOptions.Builder() |
44 | .withDefaultBackend(ReteBackendFactory.INSTANCE) | 44 | .withDefaultBackend(ReteBackendFactory.INSTANCE) |
45 | .withDefaultCachingBackend(ReteBackendFactory.INSTANCE) | 45 | .withDefaultCachingBackend(ReteBackendFactory.INSTANCE) |
46 | .withDefaultSearchBackend(RelationalLocalSearchBackendFactory.INSTANCE); | 46 | .withDefaultSearchBackend(LocalSearchGenericBackendFactory.INSTANCE); |
47 | rewriter = new CompositeRewriter(); | 47 | rewriter = new CompositeRewriter(); |
48 | rewriter.addFirst(new DuplicateDnfRemover()); | 48 | rewriter.addFirst(new DuplicateDnfRemover()); |
49 | rewriter.addFirst(new InputParameterResolver()); | 49 | rewriter.addFirst(new InputParameterResolver()); |
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/ExtendOperationExecutor.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/ExtendOperationExecutor.java deleted file mode 100644 index fc75198c..00000000 --- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/ExtendOperationExecutor.java +++ /dev/null | |||
@@ -1,76 +0,0 @@ | |||
1 | /******************************************************************************* | ||
2 | * Copyright (c) 2010-2013, Zoltan Ujhelyi, Akos Horvath, Istvan Rath and Daniel Varro | ||
3 | * Copyright (c) 2023 The Refinery Authors <https://refinery.tools/> | ||
4 | * This program and the accompanying materials are made available under the | ||
5 | * terms of the Eclipse Public License v. 2.0 which is available at | ||
6 | * http://www.eclipse.org/legal/epl-v20.html. | ||
7 | * SPDX-License-Identifier: EPL-2.0 | ||
8 | *******************************************************************************/ | ||
9 | package tools.refinery.store.query.viatra.internal.localsearch; | ||
10 | |||
11 | import tools.refinery.viatra.runtime.localsearch.MatchingFrame; | ||
12 | import tools.refinery.viatra.runtime.localsearch.matcher.ISearchContext; | ||
13 | import tools.refinery.viatra.runtime.localsearch.operations.ISearchOperation.ISearchOperationExecutor; | ||
14 | |||
15 | import java.util.Iterator; | ||
16 | |||
17 | /** | ||
18 | * An operation that can be used to enumerate all possible values for a single position based on a constraint | ||
19 | * @author Zoltan Ujhelyi, Akos Horvath | ||
20 | * @since 2.0 | ||
21 | */ | ||
22 | abstract class ExtendOperationExecutor<T> implements ISearchOperationExecutor { | ||
23 | |||
24 | private Iterator<? extends T> it; | ||
25 | |||
26 | /** | ||
27 | * Returns an iterator with the possible options from the current state | ||
28 | * @since 2.0 | ||
29 | */ | ||
30 | @SuppressWarnings("squid:S1452") | ||
31 | protected abstract Iterator<? extends T> getIterator(MatchingFrame frame, ISearchContext context); | ||
32 | /** | ||
33 | * Updates the frame with the next element of the iterator. Called during {@link #execute(MatchingFrame, ISearchContext)}. | ||
34 | * | ||
35 | * @return true if the update is successful or false otherwise; in case of false is returned, the next element should be taken from the iterator. | ||
36 | * @since 2.0 | ||
37 | */ | ||
38 | protected abstract boolean fillInValue(T newValue, MatchingFrame frame, ISearchContext context); | ||
39 | |||
40 | /** | ||
41 | * Restores the frame to the state before {@link #fillInValue(Object, MatchingFrame, ISearchContext)}. Called during | ||
42 | * {@link #onBacktrack(MatchingFrame, ISearchContext)}. | ||
43 | * | ||
44 | * @since 2.0 | ||
45 | */ | ||
46 | protected abstract void cleanup(MatchingFrame frame, ISearchContext context); | ||
47 | |||
48 | @Override | ||
49 | public void onInitialize(MatchingFrame frame, ISearchContext context) { | ||
50 | it = getIterator(frame, context); | ||
51 | } | ||
52 | |||
53 | @Override | ||
54 | public void onBacktrack(MatchingFrame frame, ISearchContext context) { | ||
55 | it = null; | ||
56 | |||
57 | } | ||
58 | |||
59 | /** | ||
60 | * Fixed version of {@link tools.refinery.viatra.runtime.localsearch.operations.ExtendOperationExecutor#execute} | ||
61 | * that handles failed unification of variables correctly. | ||
62 | * @param frame The matching frame to extend. | ||
63 | * @param context The search context. | ||
64 | * @return {@code true} if an extension was found, {@code false} otherwise. | ||
65 | */ | ||
66 | @Override | ||
67 | public boolean execute(MatchingFrame frame, ISearchContext context) { | ||
68 | while (it.hasNext()) { | ||
69 | var newValue = it.next(); | ||
70 | if (fillInValue(newValue, frame, context)) { | ||
71 | return true; | ||
72 | } | ||
73 | } | ||
74 | return false; | ||
75 | } | ||
76 | } | ||
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/ExtendPositivePatternCall.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/ExtendPositivePatternCall.java deleted file mode 100644 index b8b6b159..00000000 --- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/ExtendPositivePatternCall.java +++ /dev/null | |||
@@ -1,117 +0,0 @@ | |||
1 | /******************************************************************************* | ||
2 | * Copyright (c) 2010-2016, Grill Balázs, IncQueryLabs | ||
3 | * Copyright (c) 2023 The Refinery Authors <https://refinery.tools/> | ||
4 | * This program and the accompanying materials are made available under the | ||
5 | * terms of the Eclipse Public License v. 2.0 which is available at | ||
6 | * http://www.eclipse.org/legal/epl-v20.html. | ||
7 | * SPDX-License-Identifier: EPL-2.0 | ||
8 | *******************************************************************************/ | ||
9 | package tools.refinery.store.query.viatra.internal.localsearch; | ||
10 | |||
11 | import tools.refinery.viatra.runtime.localsearch.MatchingFrame; | ||
12 | import tools.refinery.viatra.runtime.localsearch.matcher.ISearchContext; | ||
13 | import tools.refinery.viatra.runtime.localsearch.operations.IPatternMatcherOperation; | ||
14 | import tools.refinery.viatra.runtime.localsearch.operations.ISearchOperation; | ||
15 | import tools.refinery.viatra.runtime.localsearch.operations.util.CallInformation; | ||
16 | import tools.refinery.viatra.runtime.matchers.backend.IQueryResultProvider; | ||
17 | import tools.refinery.viatra.runtime.matchers.tuple.Tuple; | ||
18 | import tools.refinery.viatra.runtime.matchers.tuple.TupleMask; | ||
19 | import tools.refinery.viatra.runtime.matchers.tuple.VolatileModifiableMaskedTuple; | ||
20 | |||
21 | import java.util.Iterator; | ||
22 | import java.util.List; | ||
23 | import java.util.function.Function; | ||
24 | |||
25 | /** | ||
26 | * @author Grill Balázs | ||
27 | * @since 1.4 | ||
28 | * | ||
29 | */ | ||
30 | public class ExtendPositivePatternCall implements ISearchOperation, IPatternMatcherOperation { | ||
31 | |||
32 | private class Executor extends ExtendOperationExecutor<Tuple> { | ||
33 | private final VolatileModifiableMaskedTuple maskedTuple; | ||
34 | |||
35 | public Executor() { | ||
36 | maskedTuple = new VolatileModifiableMaskedTuple(information.getThinFrameMask()); | ||
37 | } | ||
38 | |||
39 | @Override | ||
40 | protected Iterator<? extends Tuple> getIterator(MatchingFrame frame, ISearchContext context) { | ||
41 | maskedTuple.updateTuple(frame); | ||
42 | IQueryResultProvider matcher = context.getMatcher(information.getCallWithAdornment()); | ||
43 | return matcher.getAllMatches(information.getParameterMask(), maskedTuple).iterator(); | ||
44 | } | ||
45 | |||
46 | /** | ||
47 | * @since 2.0 | ||
48 | */ | ||
49 | @Override | ||
50 | protected boolean fillInValue(Tuple result, MatchingFrame frame, ISearchContext context) { | ||
51 | TupleMask mask = information.getFullFrameMask(); | ||
52 | // The first loop clears out the elements from a possible previous iteration | ||
53 | for(int i : information.getFreeParameterIndices()) { | ||
54 | mask.set(frame, i, null); | ||
55 | } | ||
56 | for(int i : information.getFreeParameterIndices()) { | ||
57 | Object oldValue = mask.getValue(frame, i); | ||
58 | Object valueToFill = result.get(i); | ||
59 | if (oldValue != null && !oldValue.equals(valueToFill)){ | ||
60 | // If the inverse map contains more than one values for the same key, it means that these arguments are unified by the caller. | ||
61 | // In this case if the callee assigns different values the frame shall be dropped | ||
62 | return false; | ||
63 | } | ||
64 | mask.set(frame, i, valueToFill); | ||
65 | } | ||
66 | return true; | ||
67 | } | ||
68 | |||
69 | @Override | ||
70 | protected void cleanup(MatchingFrame frame, ISearchContext context) { | ||
71 | TupleMask mask = information.getFullFrameMask(); | ||
72 | for(int i : information.getFreeParameterIndices()){ | ||
73 | mask.set(frame, i, null); | ||
74 | } | ||
75 | |||
76 | } | ||
77 | |||
78 | @Override | ||
79 | public ISearchOperation getOperation() { | ||
80 | return ExtendPositivePatternCall.this; | ||
81 | } | ||
82 | } | ||
83 | |||
84 | private final CallInformation information; | ||
85 | |||
86 | /** | ||
87 | * @since 1.7 | ||
88 | */ | ||
89 | public ExtendPositivePatternCall(CallInformation information) { | ||
90 | this.information = information; | ||
91 | } | ||
92 | |||
93 | @Override | ||
94 | public ISearchOperationExecutor createExecutor() { | ||
95 | return new Executor(); | ||
96 | } | ||
97 | |||
98 | @Override | ||
99 | public List<Integer> getVariablePositions() { | ||
100 | return information.getVariablePositions(); | ||
101 | } | ||
102 | |||
103 | @Override | ||
104 | public String toString() { | ||
105 | return toString(Object::toString); | ||
106 | } | ||
107 | |||
108 | @Override | ||
109 | public String toString(@SuppressWarnings("squid:S4276") Function<Integer, String> variableMapping) { | ||
110 | return "extend find " + information.toString(variableMapping); | ||
111 | } | ||
112 | |||
113 | @Override | ||
114 | public CallInformation getCallInformation() { | ||
115 | return information; | ||
116 | } | ||
117 | } | ||
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/GenericTypeExtend.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/GenericTypeExtend.java deleted file mode 100644 index 0ee69b88..00000000 --- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/GenericTypeExtend.java +++ /dev/null | |||
@@ -1,137 +0,0 @@ | |||
1 | /******************************************************************************* | ||
2 | * Copyright (c) 2010-2017, Zoltan Ujhelyi, IncQuery Labs Ltd. | ||
3 | * Copyright (c) 2023 The Refinery Authors <https://refinery.tools/> | ||
4 | * This program and the accompanying materials are made available under the | ||
5 | * terms of the Eclipse Public License v. 2.0 which is available at | ||
6 | * http://www.eclipse.org/legal/epl-v20.html. | ||
7 | * SPDX-License-Identifier: EPL-2.0 | ||
8 | *******************************************************************************/ | ||
9 | package tools.refinery.store.query.viatra.internal.localsearch; | ||
10 | |||
11 | import tools.refinery.viatra.runtime.localsearch.MatchingFrame; | ||
12 | import tools.refinery.viatra.runtime.localsearch.matcher.ISearchContext; | ||
13 | import tools.refinery.viatra.runtime.localsearch.operations.IIteratingSearchOperation; | ||
14 | import tools.refinery.viatra.runtime.localsearch.operations.ISearchOperation; | ||
15 | import tools.refinery.viatra.runtime.matchers.context.IInputKey; | ||
16 | import tools.refinery.viatra.runtime.matchers.tuple.Tuple; | ||
17 | import tools.refinery.viatra.runtime.matchers.tuple.TupleMask; | ||
18 | import tools.refinery.viatra.runtime.matchers.tuple.VolatileMaskedTuple; | ||
19 | import tools.refinery.viatra.runtime.matchers.util.Preconditions; | ||
20 | |||
21 | import java.util.*; | ||
22 | import java.util.function.Function; | ||
23 | import java.util.stream.Collectors; | ||
24 | |||
25 | /** | ||
26 | * @author Zoltan Ujhelyi | ||
27 | * @since 1.7 | ||
28 | */ | ||
29 | public class GenericTypeExtend implements IIteratingSearchOperation { | ||
30 | private class Executor extends ExtendOperationExecutor<Tuple> { | ||
31 | private final VolatileMaskedTuple maskedTuple; | ||
32 | |||
33 | public Executor() { | ||
34 | this.maskedTuple = new VolatileMaskedTuple(callMask); | ||
35 | } | ||
36 | |||
37 | @Override | ||
38 | protected Iterator<? extends Tuple> getIterator(MatchingFrame frame, ISearchContext context) { | ||
39 | maskedTuple.updateTuple(frame); | ||
40 | return context.getRuntimeContext().enumerateTuples(type, indexerMask, maskedTuple).iterator(); | ||
41 | } | ||
42 | |||
43 | @Override | ||
44 | protected boolean fillInValue(Tuple newTuple, MatchingFrame frame, ISearchContext context) { | ||
45 | for (Integer position : unboundVariableIndices) { | ||
46 | frame.setValue(position, null); | ||
47 | } | ||
48 | for (int i = 0; i < positions.length; i++) { | ||
49 | Object newValue = newTuple.get(i); | ||
50 | Object oldValue = frame.getValue(positions[i]); | ||
51 | if (oldValue != null && !Objects.equals(oldValue, newValue)) { | ||
52 | // If positions tuple maps more than one values for the same element (e.g. loop), it means that | ||
53 | // these arguments are to unified by the caller. In this case if the callee assigns different values | ||
54 | // the frame shall be considered a failed match | ||
55 | return false; | ||
56 | } | ||
57 | frame.setValue(positions[i], newValue); | ||
58 | } | ||
59 | return true; | ||
60 | } | ||
61 | |||
62 | @Override | ||
63 | protected void cleanup(MatchingFrame frame, ISearchContext context) { | ||
64 | for (Integer position : unboundVariableIndices) { | ||
65 | frame.setValue(position, null); | ||
66 | } | ||
67 | } | ||
68 | |||
69 | @Override | ||
70 | public ISearchOperation getOperation() { | ||
71 | return GenericTypeExtend.this; | ||
72 | } | ||
73 | } | ||
74 | |||
75 | private final IInputKey type; | ||
76 | private final int[] positions; | ||
77 | private final List<Integer> positionList; | ||
78 | private final Set<Integer> unboundVariableIndices; | ||
79 | private final TupleMask indexerMask; | ||
80 | private final TupleMask callMask; | ||
81 | |||
82 | /** | ||
83 | * | ||
84 | * @param type | ||
85 | * the type to execute the extend operation on | ||
86 | * @param positions | ||
87 | * the parameter positions that represent the variables of the input key | ||
88 | * @param unboundVariableIndices | ||
89 | * the set of positions that are bound at the start of the operation | ||
90 | */ | ||
91 | public GenericTypeExtend(IInputKey type, int[] positions, TupleMask callMask, TupleMask indexerMask, Set<Integer> unboundVariableIndices) { | ||
92 | Preconditions.checkArgument(positions.length == type.getArity(), | ||
93 | "The type %s requires %d parameters, but %d positions are provided", type.getPrettyPrintableName(), | ||
94 | type.getArity(), positions.length); | ||
95 | List<Integer> modifiablePositionList = new ArrayList<>(); | ||
96 | for (int position : positions) { | ||
97 | modifiablePositionList.add(position); | ||
98 | } | ||
99 | this.positionList = Collections.unmodifiableList(modifiablePositionList); | ||
100 | this.positions = positions; | ||
101 | this.type = type; | ||
102 | |||
103 | this.unboundVariableIndices = unboundVariableIndices; | ||
104 | this.indexerMask = indexerMask; | ||
105 | this.callMask = callMask; | ||
106 | } | ||
107 | |||
108 | @Override | ||
109 | public IInputKey getIteratedInputKey() { | ||
110 | return type; | ||
111 | } | ||
112 | |||
113 | @Override | ||
114 | public ISearchOperationExecutor createExecutor() { | ||
115 | return new Executor(); | ||
116 | } | ||
117 | |||
118 | @Override | ||
119 | public List<Integer> getVariablePositions() { | ||
120 | return positionList; | ||
121 | } | ||
122 | |||
123 | @Override | ||
124 | public String toString() { | ||
125 | return toString(Object::toString); | ||
126 | } | ||
127 | |||
128 | @Override | ||
129 | public String toString(@SuppressWarnings("squid:S4276") Function<Integer, String> variableMapping) { | ||
130 | return "extend " + type.getPrettyPrintableName() + "(" | ||
131 | + positionList.stream() | ||
132 | .map(input -> String.format("%s%s", unboundVariableIndices.contains(input) ? "-" : "+", variableMapping.apply(input))) | ||
133 | .collect(Collectors.joining(", ")) | ||
134 | + ")"; | ||
135 | } | ||
136 | |||
137 | } | ||
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/RelationalLocalSearchBackendFactory.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/RelationalLocalSearchBackendFactory.java deleted file mode 100644 index 7d5401c6..00000000 --- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/RelationalLocalSearchBackendFactory.java +++ /dev/null | |||
@@ -1,60 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.query.viatra.internal.localsearch; | ||
7 | |||
8 | import tools.refinery.viatra.runtime.localsearch.matcher.integration.AbstractLocalSearchResultProvider; | ||
9 | import tools.refinery.viatra.runtime.localsearch.matcher.integration.LocalSearchBackend; | ||
10 | import tools.refinery.viatra.runtime.localsearch.matcher.integration.LocalSearchHints; | ||
11 | import tools.refinery.viatra.runtime.localsearch.plan.IPlanProvider; | ||
12 | import tools.refinery.viatra.runtime.localsearch.plan.SimplePlanProvider; | ||
13 | import tools.refinery.viatra.runtime.matchers.backend.IMatcherCapability; | ||
14 | import tools.refinery.viatra.runtime.matchers.backend.IQueryBackend; | ||
15 | import tools.refinery.viatra.runtime.matchers.backend.IQueryBackendFactory; | ||
16 | import tools.refinery.viatra.runtime.matchers.backend.QueryEvaluationHint; | ||
17 | import tools.refinery.viatra.runtime.matchers.context.IQueryBackendContext; | ||
18 | import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery; | ||
19 | |||
20 | public class RelationalLocalSearchBackendFactory implements IQueryBackendFactory { | ||
21 | public static final RelationalLocalSearchBackendFactory INSTANCE = new RelationalLocalSearchBackendFactory(); | ||
22 | |||
23 | private RelationalLocalSearchBackendFactory() { | ||
24 | } | ||
25 | |||
26 | @Override | ||
27 | public IQueryBackend create(IQueryBackendContext context) { | ||
28 | return new LocalSearchBackend(context) { | ||
29 | // Create a new {@link IPlanProvider}, because the original {@link LocalSearchBackend#planProvider} is not | ||
30 | // accessible. | ||
31 | private final IPlanProvider planProvider = new SimplePlanProvider(context.getLogger()); | ||
32 | |||
33 | @Override | ||
34 | protected AbstractLocalSearchResultProvider initializeResultProvider(PQuery query, | ||
35 | QueryEvaluationHint hints) { | ||
36 | return new RelationalLocalSearchResultProvider(this, context, query, planProvider, hints); | ||
37 | } | ||
38 | |||
39 | @Override | ||
40 | public IQueryBackendFactory getFactory() { | ||
41 | return RelationalLocalSearchBackendFactory.this; | ||
42 | } | ||
43 | }; | ||
44 | } | ||
45 | |||
46 | @Override | ||
47 | public Class<? extends IQueryBackend> getBackendClass() { | ||
48 | return LocalSearchBackend.class; | ||
49 | } | ||
50 | |||
51 | @Override | ||
52 | public IMatcherCapability calculateRequiredCapability(PQuery pQuery, QueryEvaluationHint queryEvaluationHint) { | ||
53 | return LocalSearchHints.parse(queryEvaluationHint); | ||
54 | } | ||
55 | |||
56 | @Override | ||
57 | public boolean isCaching() { | ||
58 | return false; | ||
59 | } | ||
60 | } | ||
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/RelationalLocalSearchResultProvider.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/RelationalLocalSearchResultProvider.java deleted file mode 100644 index 37d06864..00000000 --- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/RelationalLocalSearchResultProvider.java +++ /dev/null | |||
@@ -1,28 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.query.viatra.internal.localsearch; | ||
7 | |||
8 | import tools.refinery.viatra.runtime.localsearch.matcher.integration.AbstractLocalSearchResultProvider; | ||
9 | import tools.refinery.viatra.runtime.localsearch.matcher.integration.LocalSearchBackend; | ||
10 | import tools.refinery.viatra.runtime.localsearch.matcher.integration.LocalSearchHints; | ||
11 | import tools.refinery.viatra.runtime.localsearch.plan.IPlanProvider; | ||
12 | import tools.refinery.viatra.runtime.localsearch.planner.compiler.IOperationCompiler; | ||
13 | import tools.refinery.viatra.runtime.matchers.backend.QueryEvaluationHint; | ||
14 | import tools.refinery.viatra.runtime.matchers.context.IQueryBackendContext; | ||
15 | import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery; | ||
16 | |||
17 | class RelationalLocalSearchResultProvider extends AbstractLocalSearchResultProvider { | ||
18 | public RelationalLocalSearchResultProvider(LocalSearchBackend backend, IQueryBackendContext context, PQuery query, | ||
19 | IPlanProvider planProvider, QueryEvaluationHint userHints) { | ||
20 | super(backend, context, query, planProvider, userHints); | ||
21 | } | ||
22 | |||
23 | @Override | ||
24 | protected IOperationCompiler getOperationCompiler(IQueryBackendContext backendContext, | ||
25 | LocalSearchHints configuration) { | ||
26 | return new RelationalOperationCompiler(runtimeContext); | ||
27 | } | ||
28 | } | ||
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/RelationalOperationCompiler.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/RelationalOperationCompiler.java deleted file mode 100644 index 37f264ae..00000000 --- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/RelationalOperationCompiler.java +++ /dev/null | |||
@@ -1,70 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.query.viatra.internal.localsearch; | ||
7 | |||
8 | import tools.refinery.viatra.runtime.localsearch.operations.generic.GenericTypeExtendSingleValue; | ||
9 | import tools.refinery.viatra.runtime.localsearch.operations.util.CallInformation; | ||
10 | import tools.refinery.viatra.runtime.localsearch.planner.compiler.GenericOperationCompiler; | ||
11 | import tools.refinery.viatra.runtime.matchers.context.IInputKey; | ||
12 | import tools.refinery.viatra.runtime.matchers.context.IQueryRuntimeContext; | ||
13 | import tools.refinery.viatra.runtime.matchers.psystem.PVariable; | ||
14 | import tools.refinery.viatra.runtime.matchers.psystem.basicenumerables.PositivePatternCall; | ||
15 | import tools.refinery.viatra.runtime.matchers.psystem.basicenumerables.TypeConstraint; | ||
16 | import tools.refinery.viatra.runtime.matchers.tuple.Tuple; | ||
17 | import tools.refinery.viatra.runtime.matchers.tuple.TupleMask; | ||
18 | |||
19 | import java.util.*; | ||
20 | |||
21 | public class RelationalOperationCompiler extends GenericOperationCompiler { | ||
22 | public RelationalOperationCompiler(IQueryRuntimeContext runtimeContext) { | ||
23 | super(runtimeContext); | ||
24 | } | ||
25 | |||
26 | @Override | ||
27 | protected void createExtend(TypeConstraint typeConstraint, Map<PVariable, Integer> variableMapping) { | ||
28 | IInputKey inputKey = typeConstraint.getSupplierKey(); | ||
29 | Tuple tuple = typeConstraint.getVariablesTuple(); | ||
30 | |||
31 | int[] positions = new int[tuple.getSize()]; | ||
32 | List<Integer> boundVariableIndices = new ArrayList<>(); | ||
33 | List<Integer> boundVariables = new ArrayList<>(); | ||
34 | Set<Integer> unboundVariables = new HashSet<>(); | ||
35 | for (int i = 0; i < tuple.getSize(); i++) { | ||
36 | PVariable variable = (PVariable) tuple.get(i); | ||
37 | Integer position = variableMapping.get(variable); | ||
38 | positions[i] = position; | ||
39 | if (variableBindings.get(typeConstraint).contains(position)) { | ||
40 | boundVariableIndices.add(i); | ||
41 | boundVariables.add(position); | ||
42 | } else { | ||
43 | unboundVariables.add(position); | ||
44 | } | ||
45 | } | ||
46 | TupleMask indexerMask = TupleMask.fromSelectedIndices(inputKey.getArity(), boundVariableIndices); | ||
47 | TupleMask callMask = TupleMask.fromSelectedIndices(variableMapping.size(), boundVariables); | ||
48 | // If multiple tuple elements from the indexer should be bound to the same variable, we must use a | ||
49 | // {@link GenericTypeExtend} check whether the tuple elements have the same value. | ||
50 | if (unboundVariables.size() == 1 && indexerMask.getSize() + 1 == indexerMask.getSourceWidth()) { | ||
51 | operations.add(new GenericTypeExtendSingleValue(inputKey, positions, callMask, indexerMask, | ||
52 | unboundVariables.iterator().next())); | ||
53 | } else { | ||
54 | // Use a fixed version of | ||
55 | // {@code tools.refinery.viatra.runtime.localsearch.operations.generic.GenericTypeExtend} that handles | ||
56 | // failed unification of variables correctly. | ||
57 | operations.add(new GenericTypeExtend(inputKey, positions, callMask, indexerMask, unboundVariables)); | ||
58 | } | ||
59 | } | ||
60 | |||
61 | @Override | ||
62 | protected void createExtend(PositivePatternCall pCall, Map<PVariable, Integer> variableMapping) { | ||
63 | CallInformation information = CallInformation.create(pCall, variableMapping, variableBindings.get(pCall)); | ||
64 | // Use a fixed version of | ||
65 | // {@code tools.refinery.viatra.runtime.localsearch.operations.extend.ExtendPositivePatternCall} that handles | ||
66 | // failed unification of variables correctly. | ||
67 | operations.add(new ExtendPositivePatternCall(information)); | ||
68 | dependencies.add(information.getCallWithAdornment()); | ||
69 | } | ||
70 | } | ||
diff --git a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/ExtendOperationExecutor.java b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/ExtendOperationExecutor.java index 01179118..a72c30dd 100644 --- a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/ExtendOperationExecutor.java +++ b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/ExtendOperationExecutor.java | |||
@@ -1,19 +1,20 @@ | |||
1 | /******************************************************************************* | 1 | /******************************************************************************* |
2 | * Copyright (c) 2010-2013, Zoltan Ujhelyi, Akos Horvath, Istvan Rath and Daniel Varro | 2 | * Copyright (c) 2010-2013, Zoltan Ujhelyi, Akos Horvath, Istvan Rath and Daniel Varro |
3 | * Copyright (c) 2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * This program and the accompanying materials are made available under the | 4 | * This program and the accompanying materials are made available under the |
4 | * terms of the Eclipse Public License v. 2.0 which is available at | 5 | * terms of the Eclipse Public License v. 2.0 which is available at |
5 | * http://www.eclipse.org/legal/epl-v20.html. | 6 | * http://www.eclipse.org/legal/epl-v20.html. |
6 | * | 7 | * |
7 | * SPDX-License-Identifier: EPL-2.0 | 8 | * SPDX-License-Identifier: EPL-2.0 |
8 | *******************************************************************************/ | 9 | *******************************************************************************/ |
9 | package tools.refinery.viatra.runtime.localsearch.operations; | 10 | package tools.refinery.viatra.runtime.localsearch.operations; |
10 | 11 | ||
11 | import java.util.Iterator; | ||
12 | |||
13 | import tools.refinery.viatra.runtime.localsearch.MatchingFrame; | 12 | import tools.refinery.viatra.runtime.localsearch.MatchingFrame; |
14 | import tools.refinery.viatra.runtime.localsearch.matcher.ISearchContext; | 13 | import tools.refinery.viatra.runtime.localsearch.matcher.ISearchContext; |
15 | import tools.refinery.viatra.runtime.localsearch.operations.ISearchOperation.ISearchOperationExecutor; | 14 | import tools.refinery.viatra.runtime.localsearch.operations.ISearchOperation.ISearchOperationExecutor; |
16 | 15 | ||
16 | import java.util.Iterator; | ||
17 | |||
17 | /** | 18 | /** |
18 | * An operation that can be used to enumerate all possible values for a single position based on a constraint | 19 | * An operation that can be used to enumerate all possible values for a single position based on a constraint |
19 | * @author Zoltan Ujhelyi, Akos Horvath | 20 | * @author Zoltan Ujhelyi, Akos Horvath |
@@ -31,42 +32,46 @@ public abstract class ExtendOperationExecutor<T> implements ISearchOperationExec | |||
31 | protected abstract Iterator<? extends T> getIterator(MatchingFrame frame, ISearchContext context); | 32 | protected abstract Iterator<? extends T> getIterator(MatchingFrame frame, ISearchContext context); |
32 | /** | 33 | /** |
33 | * Updates the frame with the next element of the iterator. Called during {@link #execute(MatchingFrame, ISearchContext)}. | 34 | * Updates the frame with the next element of the iterator. Called during {@link #execute(MatchingFrame, ISearchContext)}. |
34 | * | 35 | * |
35 | * @return true if the update is successful or false otherwise; in case of false is returned, the next element should be taken from the iterator. | 36 | * @return true if the update is successful or false otherwise; in case of false is returned, the next element should be taken from the iterator. |
36 | * @since 2.0 | 37 | * @since 2.0 |
37 | */ | 38 | */ |
38 | protected abstract boolean fillInValue(T newValue, MatchingFrame frame, ISearchContext context); | 39 | protected abstract boolean fillInValue(T newValue, MatchingFrame frame, ISearchContext context); |
39 | 40 | ||
40 | /** | 41 | /** |
41 | * Restores the frame to the state before {@link #fillInValue(Object, MatchingFrame, ISearchContext)}. Called during | 42 | * Restores the frame to the state before {@link #fillInValue(Object, MatchingFrame, ISearchContext)}. Called during |
42 | * {@link #onBacktrack(MatchingFrame, ISearchContext)}. | 43 | * {@link #onBacktrack(MatchingFrame, ISearchContext)}. |
43 | * | 44 | * |
44 | * @since 2.0 | 45 | * @since 2.0 |
45 | */ | 46 | */ |
46 | protected abstract void cleanup(MatchingFrame frame, ISearchContext context); | 47 | protected abstract void cleanup(MatchingFrame frame, ISearchContext context); |
47 | 48 | ||
48 | @Override | 49 | @Override |
49 | public void onInitialize(MatchingFrame frame, ISearchContext context) { | 50 | public void onInitialize(MatchingFrame frame, ISearchContext context) { |
50 | it = getIterator(frame, context); | 51 | it = getIterator(frame, context); |
51 | } | 52 | } |
52 | 53 | ||
53 | @Override | 54 | @Override |
54 | public void onBacktrack(MatchingFrame frame, ISearchContext context) { | 55 | public void onBacktrack(MatchingFrame frame, ISearchContext context) { |
55 | it = null; | 56 | it = null; |
56 | 57 | ||
57 | } | 58 | } |
58 | 59 | ||
59 | @Override | 60 | /** |
60 | public boolean execute(MatchingFrame frame, ISearchContext context) { | 61 | * Fixed version that handles failed unification of variables correctly. |
61 | if (it.hasNext()){ | 62 | * @param frame The matching frame to extend. |
62 | T newValue = it.next(); | 63 | * @param context The search context. |
63 | while(!fillInValue(newValue, frame, context) && it.hasNext()){ | 64 | * @return {@code true} if an extension was found, {@code false} otherwise. |
64 | newValue = it.next(); | 65 | */ |
65 | } | 66 | @Override |
66 | return true; | 67 | public boolean execute(MatchingFrame frame, ISearchContext context) { |
67 | } else { | 68 | while (it.hasNext()) { |
68 | return false; | 69 | var newValue = it.next(); |
69 | } | 70 | if (fillInValue(newValue, frame, context)) { |
70 | } | 71 | return true; |
71 | 72 | } | |
73 | } | ||
74 | return false; | ||
75 | } | ||
76 | |||
72 | } | 77 | } |
diff --git a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/planner/compiler/GenericOperationCompiler.java b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/planner/compiler/GenericOperationCompiler.java index 606048b7..d86982e9 100644 --- a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/planner/compiler/GenericOperationCompiler.java +++ b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/planner/compiler/GenericOperationCompiler.java | |||
@@ -1,19 +1,14 @@ | |||
1 | /******************************************************************************* | 1 | /******************************************************************************* |
2 | * Copyright (c) 2010-2017, Zoltan Ujhelyi, IncQuery Labs Ltd. | 2 | * Copyright (c) 2010-2017, Zoltan Ujhelyi, IncQuery Labs Ltd. |
3 | * Copyright (c) 2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * This program and the accompanying materials are made available under the | 4 | * This program and the accompanying materials are made available under the |
4 | * terms of the Eclipse Public License v. 2.0 which is available at | 5 | * terms of the Eclipse Public License v. 2.0 which is available at |
5 | * http://www.eclipse.org/legal/epl-v20.html. | 6 | * http://www.eclipse.org/legal/epl-v20.html. |
6 | * | 7 | * |
7 | * SPDX-License-Identifier: EPL-2.0 | 8 | * SPDX-License-Identifier: EPL-2.0 |
8 | *******************************************************************************/ | 9 | *******************************************************************************/ |
9 | package tools.refinery.viatra.runtime.localsearch.planner.compiler; | 10 | package tools.refinery.viatra.runtime.localsearch.planner.compiler; |
10 | 11 | ||
11 | import java.util.ArrayList; | ||
12 | import java.util.HashSet; | ||
13 | import java.util.List; | ||
14 | import java.util.Map; | ||
15 | import java.util.Set; | ||
16 | |||
17 | import tools.refinery.viatra.runtime.localsearch.operations.generic.GenericTypeCheck; | 12 | import tools.refinery.viatra.runtime.localsearch.operations.generic.GenericTypeCheck; |
18 | import tools.refinery.viatra.runtime.localsearch.operations.generic.GenericTypeExtend; | 13 | import tools.refinery.viatra.runtime.localsearch.operations.generic.GenericTypeExtend; |
19 | import tools.refinery.viatra.runtime.localsearch.operations.generic.GenericTypeExtendSingleValue; | 14 | import tools.refinery.viatra.runtime.localsearch.operations.generic.GenericTypeExtendSingleValue; |
@@ -25,6 +20,8 @@ import tools.refinery.viatra.runtime.matchers.psystem.basicenumerables.TypeConst | |||
25 | import tools.refinery.viatra.runtime.matchers.tuple.Tuple; | 20 | import tools.refinery.viatra.runtime.matchers.tuple.Tuple; |
26 | import tools.refinery.viatra.runtime.matchers.tuple.TupleMask; | 21 | import tools.refinery.viatra.runtime.matchers.tuple.TupleMask; |
27 | 22 | ||
23 | import java.util.*; | ||
24 | |||
28 | /** | 25 | /** |
29 | * @author Zoltan Ujhelyi | 26 | * @author Zoltan Ujhelyi |
30 | * @since 1.7 | 27 | * @since 1.7 |
@@ -46,9 +43,9 @@ public class GenericOperationCompiler extends AbstractOperationCompiler { | |||
46 | positions[i] = variableMapping.get(variable); | 43 | positions[i] = variableMapping.get(variable); |
47 | } | 44 | } |
48 | operations.add(new GenericTypeCheck(inputKey, positions, TupleMask.fromSelectedIndices(variableMapping.size(), positions))); | 45 | operations.add(new GenericTypeCheck(inputKey, positions, TupleMask.fromSelectedIndices(variableMapping.size(), positions))); |
49 | 46 | ||
50 | } | 47 | } |
51 | 48 | ||
52 | @Override | 49 | @Override |
53 | protected void createCheck(TypeConstraint typeConstraint, Map<PVariable, Integer> variableMapping) { | 50 | protected void createCheck(TypeConstraint typeConstraint, Map<PVariable, Integer> variableMapping) { |
54 | IInputKey inputKey = typeConstraint.getSupplierKey(); | 51 | IInputKey inputKey = typeConstraint.getSupplierKey(); |
@@ -60,7 +57,7 @@ public class GenericOperationCompiler extends AbstractOperationCompiler { | |||
60 | } | 57 | } |
61 | operations.add(new GenericTypeCheck(inputKey, positions, TupleMask.fromSelectedIndices(variableMapping.size(), positions))); | 58 | operations.add(new GenericTypeCheck(inputKey, positions, TupleMask.fromSelectedIndices(variableMapping.size(), positions))); |
62 | } | 59 | } |
63 | 60 | ||
64 | @Override | 61 | @Override |
65 | protected void createUnaryTypeCheck(IInputKey inputKey, int position) { | 62 | protected void createUnaryTypeCheck(IInputKey inputKey, int position) { |
66 | int[] positions = new int[] {position}; | 63 | int[] positions = new int[] {position}; |
@@ -71,7 +68,7 @@ public class GenericOperationCompiler extends AbstractOperationCompiler { | |||
71 | protected void createExtend(TypeConstraint typeConstraint, Map<PVariable, Integer> variableMapping) { | 68 | protected void createExtend(TypeConstraint typeConstraint, Map<PVariable, Integer> variableMapping) { |
72 | IInputKey inputKey = typeConstraint.getSupplierKey(); | 69 | IInputKey inputKey = typeConstraint.getSupplierKey(); |
73 | Tuple tuple = typeConstraint.getVariablesTuple(); | 70 | Tuple tuple = typeConstraint.getVariablesTuple(); |
74 | 71 | ||
75 | int[] positions = new int[tuple.getSize()]; | 72 | int[] positions = new int[tuple.getSize()]; |
76 | List<Integer> boundVariableIndices = new ArrayList<>(); | 73 | List<Integer> boundVariableIndices = new ArrayList<>(); |
77 | List<Integer> boundVariables = new ArrayList<>(); | 74 | List<Integer> boundVariables = new ArrayList<>(); |
@@ -89,7 +86,9 @@ public class GenericOperationCompiler extends AbstractOperationCompiler { | |||
89 | } | 86 | } |
90 | TupleMask indexerMask = TupleMask.fromSelectedIndices(inputKey.getArity(), boundVariableIndices); | 87 | TupleMask indexerMask = TupleMask.fromSelectedIndices(inputKey.getArity(), boundVariableIndices); |
91 | TupleMask callMask = TupleMask.fromSelectedIndices(variableMapping.size(), boundVariables); | 88 | TupleMask callMask = TupleMask.fromSelectedIndices(variableMapping.size(), boundVariables); |
92 | if (unboundVariables.size() == 1) { | 89 | // If multiple tuple elements from the indexer should be bound to the same variable, we must use a |
90 | // {@link GenericTypeExtend} check whether the tuple elements have the same value. | ||
91 | if (unboundVariables.size() == 1 && indexerMask.getSize() + 1 == indexerMask.getSourceWidth()) { | ||
93 | operations.add(new GenericTypeExtendSingleValue(inputKey, positions, callMask, indexerMask, unboundVariables.iterator().next())); | 92 | operations.add(new GenericTypeExtendSingleValue(inputKey, positions, callMask, indexerMask, unboundVariables.iterator().next())); |
94 | } else { | 93 | } else { |
95 | operations.add(new GenericTypeExtend(inputKey, positions, callMask, indexerMask, unboundVariables)); | 94 | operations.add(new GenericTypeExtend(inputKey, positions, callMask, indexerMask, unboundVariables)); |