aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/generic/GenericTypeExtend.java
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/generic/GenericTypeExtend.java')
-rw-r--r--subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/generic/GenericTypeExtend.java145
1 files changed, 145 insertions, 0 deletions
diff --git a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/generic/GenericTypeExtend.java b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/generic/GenericTypeExtend.java
new file mode 100644
index 00000000..dfc3e9ad
--- /dev/null
+++ b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/generic/GenericTypeExtend.java
@@ -0,0 +1,145 @@
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 *******************************************************************************/
9package tools.refinery.viatra.runtime.localsearch.operations.generic;
10
11import java.util.ArrayList;
12import java.util.Collections;
13import java.util.Iterator;
14import java.util.List;
15import java.util.Objects;
16import java.util.Set;
17import java.util.function.Function;
18import java.util.stream.Collectors;
19
20import tools.refinery.viatra.runtime.localsearch.MatchingFrame;
21import tools.refinery.viatra.runtime.localsearch.matcher.ISearchContext;
22import tools.refinery.viatra.runtime.localsearch.operations.ExtendOperationExecutor;
23import tools.refinery.viatra.runtime.localsearch.operations.IIteratingSearchOperation;
24import tools.refinery.viatra.runtime.localsearch.operations.ISearchOperation;
25import tools.refinery.viatra.runtime.matchers.context.IInputKey;
26import tools.refinery.viatra.runtime.matchers.tuple.Tuple;
27import tools.refinery.viatra.runtime.matchers.tuple.TupleMask;
28import tools.refinery.viatra.runtime.matchers.tuple.VolatileMaskedTuple;
29import tools.refinery.viatra.runtime.matchers.util.Preconditions;
30
31/**
32 * @author Zoltan Ujhelyi
33 * @since 1.7
34 * @noextend This class is not intended to be subclassed by clients.
35 */
36public class GenericTypeExtend implements IIteratingSearchOperation {
37
38 private class Executor extends ExtendOperationExecutor<Tuple> {
39 private final VolatileMaskedTuple maskedTuple;
40
41 public Executor() {
42 this.maskedTuple = new VolatileMaskedTuple(callMask);
43 }
44
45 @Override
46 protected Iterator<? extends Tuple> getIterator(MatchingFrame frame, ISearchContext context) {
47 maskedTuple.updateTuple(frame);
48 return context.getRuntimeContext().enumerateTuples(type, indexerMask, maskedTuple).iterator();
49 }
50
51 @Override
52 protected boolean fillInValue(Tuple newTuple, MatchingFrame frame, ISearchContext context) {
53 for (Integer position : unboundVariableIndices) {
54 frame.setValue(position, null);
55 }
56 for (int i = 0; i < positions.length; i++) {
57 Object newValue = newTuple.get(i);
58 Object oldValue = frame.getValue(positions[i]);
59 if (oldValue != null && !Objects.equals(oldValue, newValue)) {
60 // If positions tuple maps more than one values for the same element (e.g. loop), it means that
61 // these arguments are to unified by the caller. In this case if the callee assigns different values
62 // the frame shall be considered a failed match
63 return false;
64 }
65 frame.setValue(positions[i], newValue);
66 }
67 return true;
68 }
69
70 @Override
71 protected void cleanup(MatchingFrame frame, ISearchContext context) {
72 for (Integer position : unboundVariableIndices) {
73 frame.setValue(position, null);
74 }
75 }
76
77 @Override
78 public ISearchOperation getOperation() {
79 return GenericTypeExtend.this;
80 }
81 }
82
83 private final IInputKey type;
84 private final int[] positions;
85 private final List<Integer> positionList;
86 private final Set<Integer> unboundVariableIndices;
87 private final TupleMask indexerMask;
88 private final TupleMask callMask;
89
90 /**
91 *
92 * @param type
93 * the type to execute the extend operation on
94 * @param positions
95 * the parameter positions that represent the variables of the input key
96 * @param unboundVariableIndices
97 * the set of positions that are bound at the start of the operation
98 */
99 public GenericTypeExtend(IInputKey type, int[] positions, TupleMask callMask, TupleMask indexerMask, Set<Integer> unboundVariableIndices) {
100 Preconditions.checkArgument(positions.length == type.getArity(),
101 "The type %s requires %d parameters, but %d positions are provided", type.getPrettyPrintableName(),
102 type.getArity(), positions.length);
103 List<Integer> modifiablePositionList = new ArrayList<>();
104 for (int position : positions) {
105 modifiablePositionList.add(position);
106 }
107 this.positionList = Collections.unmodifiableList(modifiablePositionList);
108 this.positions = positions;
109 this.type = type;
110
111 this.unboundVariableIndices = unboundVariableIndices;
112 this.indexerMask = indexerMask;
113 this.callMask = callMask;
114 }
115
116 @Override
117 public IInputKey getIteratedInputKey() {
118 return type;
119 }
120
121 @Override
122 public ISearchOperationExecutor createExecutor() {
123 return new Executor();
124 }
125
126 @Override
127 public List<Integer> getVariablePositions() {
128 return positionList;
129 }
130
131 @Override
132 public String toString() {
133 return toString(Object::toString);
134 }
135
136 @Override
137 public String toString(Function<Integer, String> variableMapping) {
138 return "extend " + type.getPrettyPrintableName() + "("
139 + positionList.stream()
140 .map(input -> String.format("%s%s", unboundVariableIndices.contains(input) ? "-" : "+", variableMapping.apply(input)))
141 .collect(Collectors.joining(", "))
142 + ")";
143 }
144
145}