aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/check/BinaryTransitiveClosureCheck.java
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/check/BinaryTransitiveClosureCheck.java')
-rw-r--r--subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/check/BinaryTransitiveClosureCheck.java135
1 files changed, 135 insertions, 0 deletions
diff --git a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/check/BinaryTransitiveClosureCheck.java b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/check/BinaryTransitiveClosureCheck.java
new file mode 100644
index 00000000..8f818542
--- /dev/null
+++ b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/check/BinaryTransitiveClosureCheck.java
@@ -0,0 +1,135 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2013, Zoltan Ujhelyi, Istvan Rath and Daniel Varro
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.check;
10
11import java.util.Arrays;
12import java.util.HashSet;
13import java.util.LinkedList;
14import java.util.List;
15import java.util.Objects;
16import java.util.Queue;
17import java.util.Set;
18import java.util.function.Function;
19
20import tools.refinery.viatra.runtime.localsearch.MatchingFrame;
21import tools.refinery.viatra.runtime.localsearch.matcher.ISearchContext;
22import tools.refinery.viatra.runtime.localsearch.operations.CheckOperationExecutor;
23import tools.refinery.viatra.runtime.localsearch.operations.IPatternMatcherOperation;
24import tools.refinery.viatra.runtime.localsearch.operations.ISearchOperation;
25import tools.refinery.viatra.runtime.localsearch.operations.util.CallInformation;
26import tools.refinery.viatra.runtime.matchers.backend.IQueryResultProvider;
27import tools.refinery.viatra.runtime.matchers.tuple.Tuple;
28
29/**
30 * Checking for a transitive closure expressed as a local search pattern matcher. The matched pattern must have two
31 * parameters of the same model type.
32 *
33 * @author Zoltan Ujhelyi
34 * @noextend This class is not intended to be subclassed by clients.
35 * @noinstantiate This class is not intended to be instantiated by clients.
36 *
37 */
38public class BinaryTransitiveClosureCheck implements ISearchOperation, IPatternMatcherOperation {
39
40 private class Executor extends CheckOperationExecutor {
41
42 @Override
43 public void onInitialize(MatchingFrame frame, ISearchContext context) {
44 super.onInitialize(frame, context);
45 matcher = context.getMatcher(information.getCallWithAdornment());
46 // Note: second parameter is NOT bound during execution, but the first is
47 }
48
49 @Override
50 protected boolean check(MatchingFrame frame, ISearchContext context) {
51 if (checkReflexive(frame)) {
52 return true;
53 }
54
55 Object targetValue = frame.get(targetPosition);
56 Queue<Object> sourcesToEvaluate = new LinkedList<>();
57 sourcesToEvaluate.add(frame.get(sourcePosition));
58 Set<Object> sourceEvaluated = new HashSet<>();
59 final Object[] mappedFrame = new Object[] {null, null};
60 while (!sourcesToEvaluate.isEmpty()) {
61 Object currentValue = sourcesToEvaluate.poll();
62 sourceEvaluated.add(currentValue);
63 mappedFrame[0] = currentValue;
64 for (Tuple match : (Iterable<Tuple>) () -> matcher.getAllMatches(mappedFrame).iterator()) {
65 Object foundTarget = match.get(1);
66 if (targetValue.equals(foundTarget)) {
67 return true;
68 } else if (!sourceEvaluated.contains(foundTarget)) {
69 sourcesToEvaluate.add(foundTarget);
70 }
71 }
72 }
73 return false;
74 }
75
76 protected boolean checkReflexive(MatchingFrame frame) {
77 return reflexive && Objects.equals(frame.get(sourcePosition), frame.get(targetPosition));
78 }
79
80 @Override
81 public ISearchOperation getOperation() {
82 return BinaryTransitiveClosureCheck.this;
83 }
84 }
85
86 private final CallInformation information;
87 private IQueryResultProvider matcher;
88 private final int sourcePosition;
89 private final int targetPosition;
90 private final boolean reflexive;
91
92 /**
93 * The source position will be matched in the called pattern to the first parameter; while target to the second.
94 * </p>
95 * <strong>NOTE</strong>: the reflexive check call does not include the parameter type checks; appropriate type checks should be
96 * added as necessary by the operation compiler.
97 *
98 * @since 2.0
99 */
100 public BinaryTransitiveClosureCheck(CallInformation information, int sourcePosition, int targetPosition, boolean reflexive) {
101 super();
102 this.sourcePosition = sourcePosition;
103 this.targetPosition = targetPosition;
104 this.information = information;
105 this.reflexive = reflexive;
106 }
107
108 @Override
109 public ISearchOperationExecutor createExecutor() {
110 return new Executor();
111 }
112
113 @Override
114 public String toString() {
115 return toString(Object::toString);
116 }
117
118 @Override
119 public String toString(Function<Integer, String> variableMapping) {
120 String c = information.toString(variableMapping);
121 int p = c.indexOf('(');
122 String modifier = reflexive ? "*" : "+";
123 return "check find "+c.substring(0, p)+ modifier +c.substring(p);
124 }
125
126 @Override
127 public List<Integer> getVariablePositions() {
128 return Arrays.asList(sourcePosition, targetPosition);
129 }
130
131 @Override
132 public CallInformation getCallInformation() {
133 return information;
134 }
135}