diff options
Diffstat (limited to 'subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/util/CallInformation.java')
-rw-r--r-- | subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/util/CallInformation.java | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/util/CallInformation.java b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/util/CallInformation.java new file mode 100644 index 00000000..b141a7b0 --- /dev/null +++ b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/util/CallInformation.java | |||
@@ -0,0 +1,186 @@ | |||
1 | /******************************************************************************* | ||
2 | * Copyright (c) 2010-2017, Zoltan Ujhelyi, IncQuery Labs Ltd. | ||
3 | * 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 | * http://www.eclipse.org/legal/epl-v20.html. | ||
6 | * | ||
7 | * SPDX-License-Identifier: EPL-2.0 | ||
8 | *******************************************************************************/ | ||
9 | package tools.refinery.viatra.runtime.localsearch.operations.util; | ||
10 | |||
11 | import java.util.ArrayList; | ||
12 | import java.util.HashMap; | ||
13 | import java.util.HashSet; | ||
14 | import java.util.List; | ||
15 | import java.util.Map; | ||
16 | import java.util.Set; | ||
17 | import java.util.function.Function; | ||
18 | import java.util.stream.Collectors; | ||
19 | |||
20 | import tools.refinery.viatra.runtime.localsearch.matcher.CallWithAdornment; | ||
21 | import tools.refinery.viatra.runtime.localsearch.matcher.MatcherReference; | ||
22 | import tools.refinery.viatra.runtime.matchers.psystem.IQueryReference; | ||
23 | import tools.refinery.viatra.runtime.matchers.psystem.PVariable; | ||
24 | import tools.refinery.viatra.runtime.matchers.psystem.basicdeferred.PatternCallBasedDeferred; | ||
25 | import tools.refinery.viatra.runtime.matchers.psystem.basicenumerables.BinaryReflexiveTransitiveClosure; | ||
26 | import tools.refinery.viatra.runtime.matchers.psystem.basicenumerables.BinaryTransitiveClosure; | ||
27 | import tools.refinery.viatra.runtime.matchers.psystem.basicenumerables.PositivePatternCall; | ||
28 | import tools.refinery.viatra.runtime.matchers.psystem.queries.PParameter; | ||
29 | import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery; | ||
30 | import tools.refinery.viatra.runtime.matchers.tuple.Tuple; | ||
31 | import tools.refinery.viatra.runtime.matchers.tuple.TupleMask; | ||
32 | |||
33 | /** | ||
34 | * This class stores a precompiled version of call-related metadata and masks for local search operations | ||
35 | * | ||
36 | * @author Zoltan Ujhelyi | ||
37 | * @since 1.7 | ||
38 | */ | ||
39 | public final class CallInformation { | ||
40 | |||
41 | private final TupleMask fullFrameMask; | ||
42 | private final TupleMask thinFrameMask; | ||
43 | private final TupleMask parameterMask; | ||
44 | private final int[] freeParameterIndices; | ||
45 | |||
46 | private final Map<PParameter, Integer> mapping = new HashMap<>(); | ||
47 | private final Set<PParameter> adornment = new HashSet<>(); | ||
48 | private final PQuery referredQuery; | ||
49 | private final MatcherReference matcherReference; | ||
50 | private final IQueryReference call; | ||
51 | private CallWithAdornment callWithAdornment; | ||
52 | |||
53 | public static CallInformation create(PatternCallBasedDeferred constraint, Map<PVariable, Integer> variableMapping, Set<Integer> bindings) { | ||
54 | return new CallInformation(constraint.getActualParametersTuple(), constraint, bindings, variableMapping); | ||
55 | } | ||
56 | |||
57 | public static CallInformation create(PositivePatternCall pCall, Map<PVariable, Integer> variableMapping, Set<Integer> bindings) { | ||
58 | return new CallInformation(pCall.getVariablesTuple(), pCall, bindings, variableMapping); | ||
59 | } | ||
60 | |||
61 | public static CallInformation create(BinaryTransitiveClosure constraint, Map<PVariable, Integer> variableMapping, Set<Integer> bindings) { | ||
62 | return new CallInformation(constraint.getVariablesTuple(), constraint, bindings, variableMapping); | ||
63 | } | ||
64 | |||
65 | /** | ||
66 | * @since 2.0 | ||
67 | */ | ||
68 | public static CallInformation create(BinaryReflexiveTransitiveClosure constraint, Map<PVariable, Integer> variableMapping, Set<Integer> bindings) { | ||
69 | return new CallInformation(constraint.getVariablesTuple(), constraint, bindings, variableMapping); | ||
70 | } | ||
71 | |||
72 | private CallInformation(Tuple actualParameters, IQueryReference call, final Set<Integer> bindings, | ||
73 | Map<PVariable, Integer> variableMapping) { | ||
74 | this.call = call; | ||
75 | this.referredQuery = call.getReferredQuery(); | ||
76 | int keySize = actualParameters.getSize(); | ||
77 | List<Integer> parameterMaskIndices = new ArrayList<>(); | ||
78 | int[] fullParameterMaskIndices = new int[keySize]; | ||
79 | for (int i = 0; i < keySize; i++) { | ||
80 | PParameter symbolicParameter = referredQuery.getParameters().get(i); | ||
81 | PVariable parameter = (PVariable) actualParameters.get(i); | ||
82 | Integer originalFrameIndex = variableMapping.get(parameter); | ||
83 | mapping.put(symbolicParameter, originalFrameIndex); | ||
84 | fullParameterMaskIndices[i] = originalFrameIndex; | ||
85 | if (bindings.contains(originalFrameIndex)) { | ||
86 | parameterMaskIndices.add(originalFrameIndex); | ||
87 | adornment.add(symbolicParameter); | ||
88 | } | ||
89 | } | ||
90 | |||
91 | thinFrameMask = TupleMask.fromSelectedIndices(variableMapping.size(), parameterMaskIndices); | ||
92 | fullFrameMask = TupleMask.fromSelectedIndices(variableMapping.size(), fullParameterMaskIndices); | ||
93 | |||
94 | // This second iteration is necessary as we don't know beforehand the number of bound parameters | ||
95 | int[] boundParameterIndices = new int[adornment.size()]; | ||
96 | int boundIndex = 0; | ||
97 | freeParameterIndices = new int[keySize - adornment.size()]; | ||
98 | int freeIndex = 0; | ||
99 | for (int i = 0; i < keySize; i++) { | ||
100 | if (bindings.contains(variableMapping.get(actualParameters.get(i)))) { | ||
101 | boundParameterIndices[boundIndex] = i; | ||
102 | boundIndex++; | ||
103 | } else { | ||
104 | freeParameterIndices[freeIndex] = i; | ||
105 | freeIndex++; | ||
106 | } | ||
107 | } | ||
108 | parameterMask = TupleMask.fromSelectedIndices(keySize, boundParameterIndices); | ||
109 | callWithAdornment = new CallWithAdornment(call, adornment); | ||
110 | matcherReference = callWithAdornment.getMatcherReference(); | ||
111 | } | ||
112 | |||
113 | /** | ||
114 | * Returns a mask describing how the bound variables of a Matching Frame are mapped to parameter indexes | ||
115 | */ | ||
116 | public TupleMask getThinFrameMask() { | ||
117 | return thinFrameMask; | ||
118 | } | ||
119 | |||
120 | /** | ||
121 | * Returns a mask describing how all variables of a Matching Frame are mapped to parameter indexes | ||
122 | */ | ||
123 | public TupleMask getFullFrameMask() { | ||
124 | return fullFrameMask; | ||
125 | } | ||
126 | |||
127 | /** | ||
128 | * Returns a mask describing the adornment the called pattern uses | ||
129 | */ | ||
130 | public TupleMask getParameterMask() { | ||
131 | return parameterMask; | ||
132 | } | ||
133 | |||
134 | public MatcherReference getReference() { | ||
135 | return matcherReference; | ||
136 | } | ||
137 | |||
138 | /** | ||
139 | * @since 2.1 | ||
140 | */ | ||
141 | public IQueryReference getCall() { | ||
142 | return call; | ||
143 | } | ||
144 | |||
145 | /** | ||
146 | * @since 2.1 | ||
147 | */ | ||
148 | public CallWithAdornment getCallWithAdornment() { | ||
149 | return callWithAdornment; | ||
150 | } | ||
151 | |||
152 | /** | ||
153 | * Returns the parameter indices that are unbound before the call | ||
154 | */ | ||
155 | public int[] getFreeParameterIndices() { | ||
156 | return freeParameterIndices; | ||
157 | } | ||
158 | |||
159 | public List<Integer> getVariablePositions() { | ||
160 | List<Integer> variables = new ArrayList<>(mapping.size()); | ||
161 | for(PParameter p : referredQuery.getParameters()){ | ||
162 | variables.add(mapping.get(p)); | ||
163 | } | ||
164 | return variables; | ||
165 | } | ||
166 | |||
167 | |||
168 | |||
169 | @Override | ||
170 | public String toString() { | ||
171 | return toString(Object::toString); | ||
172 | } | ||
173 | |||
174 | /** | ||
175 | * @since 2.0 | ||
176 | */ | ||
177 | public String toString(Function<Integer, String> variableMapping) { | ||
178 | return referredQuery.getFullyQualifiedName() + "(" | ||
179 | + referredQuery.getParameters().stream().map( | ||
180 | input -> (adornment.contains(input) ? "+" : "-") + variableMapping.apply(mapping.get(input))) | ||
181 | .collect(Collectors.joining(",")) | ||
182 | + ")"; | ||
183 | } | ||
184 | |||
185 | |||
186 | } | ||