aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem')
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/BasePConstraint.java108
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/DeferredPConstraint.java31
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/EnumerablePConstraint.java59
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/IExpressionEvaluator.java42
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/IMultiQueryReference.java26
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/IQueryReference.java33
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/IRelationEvaluator.java47
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/ITypeConstraint.java65
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/ITypeInfoProviderConstraint.java28
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/IValueProvider.java27
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/InitializablePQuery.java56
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/KeyedEnumerablePConstraint.java39
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/PBody.java289
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/PConstraint.java70
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/PTraceable.java16
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/PVariable.java203
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/TypeJudgement.java153
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/VariableDeferredPConstraint.java40
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/aggregations/AbstractMemorylessAggregationOperator.java31
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/aggregations/AggregatorType.java49
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/aggregations/BoundAggregator.java61
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/aggregations/IAggregatorFactory.java40
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/aggregations/IMultisetAggregationOperator.java106
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/analysis/QueryAnalyzer.java194
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/annotations/PAnnotation.java94
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/annotations/ParameterReference.java30
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/AggregatorConstraint.java98
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/BaseTypeSafeConstraint.java99
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/Equality.java96
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/ExportedParameter.java108
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/ExpressionEvaluation.java80
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/Inequality.java151
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/NegativePatternCall.java52
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/PatternCallBasedDeferred.java118
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/PatternMatchCounter.java70
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/RelationEvaluation.java57
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/TypeFilterConstraint.java105
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicenumerables/AbstractTransitiveClosure.java44
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicenumerables/BinaryReflexiveTransitiveClosure.java57
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicenumerables/BinaryTransitiveClosure.java33
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicenumerables/Connectivity.java11
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicenumerables/ConstantValue.java57
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicenumerables/PositivePatternCall.java76
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicenumerables/RepresentativeElectionConstraint.java43
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicenumerables/TypeConstraint.java79
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/queries/BasePQuery.java231
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/queries/PDisjunction.java104
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/queries/PParameter.java105
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/queries/PParameterDirection.java35
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/queries/PProblem.java68
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/queries/PQueries.java110
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/queries/PQuery.java154
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/queries/PQueryHeader.java101
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/queries/PVisibility.java37
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/queries/QueryInitializationException.java35
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/AbstractRewriterTraceSource.java53
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/ConstraintRemovalReason.java23
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/DefaultFlattenCallPredicate.java23
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/FlattenerCopier.java129
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/IConstraintFilter.java48
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/IDerivativeModificationReason.java19
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/IFlattenCallPredicate.java50
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/IPTraceableTraceProvider.java55
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/IRewriterTraceCollector.java33
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/IVariableRenamer.java59
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/MappingTraceCollector.java135
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/NeverFlattenCallPredicate.java26
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/NopTraceCollector.java68
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/PBodyCopier.java307
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/PBodyNormalizer.java310
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/PDisjunctionRewriter.java27
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/PDisjunctionRewriterCacher.java64
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/PQueryFlattener.java253
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/RewriterException.java31
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/SurrogateQueryRewriter.java63
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/VariableMappingExpressionEvaluatorWrapper.java88
76 files changed, 6215 insertions, 0 deletions
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/BasePConstraint.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/BasePConstraint.java
new file mode 100644
index 00000000..eda4aa25
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/BasePConstraint.java
@@ -0,0 +1,108 @@
1/*******************************************************************************
2 * Copyright (c) 2004-2010 Gabor Bergmann 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 *******************************************************************************/
9
10package tools.refinery.viatra.runtime.matchers.psystem;
11
12import tools.refinery.viatra.runtime.matchers.context.IQueryMetaContext;
13
14import java.util.Collections;
15import java.util.HashSet;
16import java.util.Map;
17import java.util.Set;
18import java.util.concurrent.atomic.AtomicInteger;
19
20/**
21 * @author Gabor Bergmann
22 *
23 */
24public abstract class BasePConstraint implements PConstraint {
25
26
27 protected PBody pBody;
28 private final Set<PVariable> affectedVariables;
29
30
31 private final int sequentialID = nextID.getAndIncrement();
32
33 // Use a static atomic integer to avoid race conditions when creating new constraints.
34 private static AtomicInteger nextID = new AtomicInteger(0);
35
36 public BasePConstraint(PBody pBody, Set<PVariable> affectedVariables) {
37 super();
38 this.pBody = pBody;
39 this.affectedVariables = new HashSet<PVariable>(affectedVariables);
40
41 for (PVariable pVariable : affectedVariables) {
42 pVariable.refer(this);
43 }
44 pBody.registerConstraint(this);
45 }
46
47 @Override
48 public String toString() {
49 return "PC[" + getClass().getSimpleName() + ":" + toStringRest() + "]";
50 }
51
52 protected abstract String toStringRest();
53
54 @Override
55 public Set<PVariable> getAffectedVariables() {
56 return affectedVariables;
57 }
58
59 @Override
60 public Map<Set<PVariable>, Set<PVariable>> getFunctionalDependencies(IQueryMetaContext context) {
61 return Collections.emptyMap();
62 }
63
64 @Override
65 public void replaceVariable(PVariable obsolete, PVariable replacement) {
66 pBody.checkMutability();
67 if (affectedVariables.remove(obsolete)) {
68 affectedVariables.add(replacement);
69 obsolete.unrefer(this);
70 replacement.refer(this);
71 doReplaceVariable(obsolete, replacement);
72 }
73 }
74
75 protected abstract void doReplaceVariable(PVariable obsolete, PVariable replacement);
76
77 @Override
78 public void delete() {
79 pBody.checkMutability();
80 for (PVariable pVariable : affectedVariables) {
81 pVariable.unrefer(this);
82 }
83 pBody.unregisterConstraint(this);
84 }
85
86 @Override
87 public void checkSanity() {
88 }
89
90 /**
91 * For backwards compatibility. Equivalent to {@link #getBody()}
92 */
93 public PBody getPSystem() {
94 return pBody;
95 }
96 /**
97 * @since 2.1
98 */
99 @Override
100 public PBody getBody() {
101 return pBody;
102 }
103
104 @Override
105 public int getMonotonousID() {
106 return sequentialID;
107 }
108}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/DeferredPConstraint.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/DeferredPConstraint.java
new file mode 100644
index 00000000..d2bf088c
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/DeferredPConstraint.java
@@ -0,0 +1,31 @@
1/*******************************************************************************
2 * Copyright (c) 2004-2010 Gabor Bergmann 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 *******************************************************************************/
9
10package tools.refinery.viatra.runtime.matchers.psystem;
11
12import java.util.Set;
13
14import tools.refinery.viatra.runtime.matchers.context.IQueryMetaContext;
15import tools.refinery.viatra.runtime.matchers.planning.SubPlan;
16
17/**
18 * Any constraint that can only be checked on certain SubPlans (e.g. those plans that already contain some variables).
19 *
20 * @author Gabor Bergmann
21 *
22 */
23public abstract class DeferredPConstraint extends BasePConstraint {
24
25 public DeferredPConstraint(PBody pBody, Set<PVariable> affectedVariables) {
26 super(pBody, affectedVariables);
27 }
28
29 public abstract boolean isReadyAt(SubPlan plan, IQueryMetaContext context);
30
31}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/EnumerablePConstraint.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/EnumerablePConstraint.java
new file mode 100644
index 00000000..9129aa47
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/EnumerablePConstraint.java
@@ -0,0 +1,59 @@
1/*******************************************************************************
2 * Copyright (c) 2004-2010 Gabor Bergmann 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 *******************************************************************************/
9
10package tools.refinery.viatra.runtime.matchers.psystem;
11
12import java.util.Set;
13
14import tools.refinery.viatra.runtime.matchers.tuple.Tuple;
15
16/**
17 * A constraint for which all satisfying tuples of variable values can be enumerated at any point during run-time.
18 *
19 * @author Gabor Bergmann
20 *
21 */
22public abstract class EnumerablePConstraint extends BasePConstraint {
23 protected Tuple variablesTuple;
24
25 protected EnumerablePConstraint(PBody pBody, Tuple variablesTuple) {
26 super(pBody, variablesTuple.<PVariable> getDistinctElements());
27 this.variablesTuple = variablesTuple;
28 }
29
30 @Override
31 public void doReplaceVariable(PVariable obsolete, PVariable replacement) {
32 variablesTuple = variablesTuple.replaceAll(obsolete, replacement);
33 }
34
35 @Override
36 protected String toStringRest() {
37 String stringRestRest = toStringRestRest();
38 String tupleString = "@" + variablesTuple.toString();
39 return stringRestRest == null ? tupleString : ":" + stringRestRest + tupleString;
40 }
41
42 protected String toStringRestRest() {
43 return null;
44 }
45
46 public Tuple getVariablesTuple() {
47 return variablesTuple;
48 }
49
50 @Override
51 public Set<PVariable> getDeducedVariables() {
52 return getAffectedVariables();
53 }
54
55 public PVariable getVariableInTuple(int index) {
56 return (PVariable) this.variablesTuple.get(index);
57 }
58
59}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/IExpressionEvaluator.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/IExpressionEvaluator.java
new file mode 100644
index 00000000..686999f7
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/IExpressionEvaluator.java
@@ -0,0 +1,42 @@
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.matchers.psystem;
10
11/**
12 * An expression evaluator is used to execute arbitrary Java code during pattern matching. In order to include the
13 * evaluation in the planning seemlessly it is expected from the evaluator implementors to report all used PVariables by
14 * name.
15 *
16 * @author Zoltan Ujhelyi
17 *
18 */
19public interface IExpressionEvaluator {
20
21 /**
22 * A textual description of the expression. Used only for debug purposes, but must not be null.
23 */
24 String getShortDescription();
25
26 /**
27 * All input parameter names should be reported correctly.
28 */
29 Iterable<String> getInputParameterNames();
30
31 /**
32 * The expression evaluator code
33 *
34 * @param provider
35 * the value provider is an engine-specific way of reading internal variable tuples to evaluate the
36 * expression with
37 * @return the result of the expression: in case of predicate evaluation the return value must be true or false;
38 * otherwise the result can be an arbitrary object. No null values should be returned.
39 * @throws Exception
40 */
41 Object evaluateExpression(IValueProvider provider) throws Exception;
42}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/IMultiQueryReference.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/IMultiQueryReference.java
new file mode 100644
index 00000000..8f647c64
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/IMultiQueryReference.java
@@ -0,0 +1,26 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2022, Tamas Szabo, GitHub
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.matchers.psystem;
10
11import java.util.Collection;
12
13import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery;
14
15/**
16 * A {@link PConstraint} that implements this interface refers to a list of PQueries.
17 *
18 * @author Tamas Szabo
19 * @since 2.8
20 *
21 */
22public interface IMultiQueryReference {
23
24 Collection<PQuery> getReferredQueries();
25
26}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/IQueryReference.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/IQueryReference.java
new file mode 100644
index 00000000..9ee05b39
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/IQueryReference.java
@@ -0,0 +1,33 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, 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.matchers.psystem;
10
11import java.util.Collections;
12import java.util.List;
13
14import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery;
15
16/**
17 * A {@link PConstraint} that implements this interface refers to a {@link PQuery}.
18 *
19 * @author Zoltan Ujhelyi
20 *
21 */
22public interface IQueryReference extends IMultiQueryReference {
23
24 PQuery getReferredQuery();
25
26 /**
27 * @since 2.8
28 */
29 @Override
30 default List<PQuery> getReferredQueries() {
31 return Collections.singletonList(getReferredQuery());
32 }
33}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/IRelationEvaluator.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/IRelationEvaluator.java
new file mode 100644
index 00000000..e4c396d8
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/IRelationEvaluator.java
@@ -0,0 +1,47 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2022, Tamas Szabo, GitHub
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.matchers.psystem;
10
11import java.util.List;
12import java.util.Set;
13
14import tools.refinery.viatra.runtime.matchers.tuple.Tuple;
15
16/**
17 * Implementations of this interface take an arbitrary number of input relations with their contents and compute the
18 * tuples of a single output relation.
19 *
20 * @author Tamas Szabo
21 * @since 2.8
22 *
23 */
24public interface IRelationEvaluator {
25
26 /**
27 * A textual description of the evaluator. Used only for debug purposes, but must not be null.
28 */
29 String getShortDescription();
30
31 /**
32 * The relation evaluator code. For performance reasons, it is expected that the returned set is a mutable
33 * collection, and the caller must be allowed to actually perform mutations!
34 */
35 Set<Tuple> evaluateRelation(List<Set<Tuple>> inputs) throws Exception;
36
37 /**
38 * For each input relation that this evaluator requires, this method returns the expected arities of the relations in order.
39 */
40 List<Integer> getInputArities();
41
42 /**
43 * Returns the arity of the output relation that this evaluator computes.
44 */
45 int getOutputArity();
46
47}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/ITypeConstraint.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/ITypeConstraint.java
new file mode 100644
index 00000000..b72035a8
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/ITypeConstraint.java
@@ -0,0 +1,65 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Bergmann Gabor, 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.matchers.psystem;
10
11import java.util.HashMap;
12import java.util.HashSet;
13import java.util.Map;
14import java.util.Map.Entry;
15
16import tools.refinery.viatra.runtime.matchers.context.IInputKey;
17import tools.refinery.viatra.runtime.matchers.context.IQueryMetaContext;
18import tools.refinery.viatra.runtime.matchers.tuple.Tuple;
19
20import java.util.Set;
21
22/**
23 * Common superinterface of enumerable and deferred type constraints.
24 * @author Bergmann Gabor
25 *
26 */
27public interface ITypeConstraint extends ITypeInfoProviderConstraint {
28
29 public abstract TypeJudgement getEquivalentJudgement();
30
31 /**
32 * Static internal utility class for implementations of {@link ITypeConstraint}s.
33 * @author Bergmann Gabor
34 */
35 public static class TypeConstraintUtil {
36
37 private TypeConstraintUtil() {
38 // Hiding constructor for utility class
39 }
40
41 public static Map<Set<PVariable>, Set<PVariable>> getFunctionalDependencies(IQueryMetaContext context, IInputKey inputKey, Tuple variablesTuple) {
42 final Map<Set<PVariable>, Set<PVariable>> result = new HashMap<Set<PVariable>, Set<PVariable>>();
43
44 Set<Entry<Set<Integer>, Set<Integer>>> dependencies = context.getFunctionalDependencies(inputKey).entrySet();
45 for (Entry<Set<Integer>, Set<Integer>> dependency : dependencies) {
46 result.put(
47 transcribeVariables(dependency.getKey(), variablesTuple),
48 transcribeVariables(dependency.getValue(), variablesTuple)
49 );
50 }
51
52 return result;
53 }
54
55 private static Set<PVariable> transcribeVariables(Set<Integer> indices, Tuple variablesTuple) {
56 Set<PVariable> result = new HashSet<PVariable>();
57 for (Integer index : indices) {
58 result.add((PVariable) variablesTuple.get(index));
59 }
60 return result;
61 }
62
63 }
64
65}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/ITypeInfoProviderConstraint.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/ITypeInfoProviderConstraint.java
new file mode 100644
index 00000000..ff127d38
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/ITypeInfoProviderConstraint.java
@@ -0,0 +1,28 @@
1/*******************************************************************************
2 * Copyright (c) 2004-2010 Gabor Bergmann 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 *******************************************************************************/
9
10package tools.refinery.viatra.runtime.matchers.psystem;
11
12import java.util.Set;
13
14import tools.refinery.viatra.runtime.matchers.context.IQueryMetaContext;
15
16/**
17 * @author Gabor Bergmann
18 *
19 */
20public interface ITypeInfoProviderConstraint extends PConstraint {
21
22 /**
23 * Returns type information implied by this constraint.
24 *
25 */
26 public Set<TypeJudgement> getImpliedJudgements(IQueryMetaContext context);
27
28}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/IValueProvider.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/IValueProvider.java
new file mode 100644
index 00000000..d959adc4
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/IValueProvider.java
@@ -0,0 +1,27 @@
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.matchers.psystem;
10
11/**
12 * Helper interface to get values from a tuple of variables. All pattern matching engines are expected to implement this
13 * to handle their internal structures.
14 *
15 * @author Zoltan Ujhelyi
16 *
17 */
18public interface IValueProvider {
19
20 /**
21 * Returns the value of the selected variable
22 * @param variableName
23 * @return the value of the variable; never null
24 * @throws IllegalArgumentException if the variable is not defined
25 */
26 Object getValue(String variableName);
27}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/InitializablePQuery.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/InitializablePQuery.java
new file mode 100644
index 00000000..a82d12ec
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/InitializablePQuery.java
@@ -0,0 +1,56 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, 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.matchers.psystem;
10
11import java.util.Set;
12
13import tools.refinery.viatra.runtime.matchers.ViatraQueryRuntimeException;
14import tools.refinery.viatra.runtime.matchers.psystem.annotations.PAnnotation;
15import tools.refinery.viatra.runtime.matchers.psystem.queries.PProblem;
16import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery;
17
18/**
19 * Adds extra methods to the PQuery interface to initialize its contents.
20 *
21 * @author Zoltan Ujhelyi
22 *
23 */
24public interface InitializablePQuery extends PQuery {
25
26 /**
27 * Sets the query status. Only applicable if the pattern is still {@link PQueryStatus#UNINITIALIZED uninitialized}.
28 *
29 * @param status the new status
30 */
31 void setStatus(PQueryStatus status);
32
33 /**
34 * Adds a detected error. Only applicable if the pattern is still {@link PQueryStatus#UNINITIALIZED uninitialized}.
35 *
36 * @param problem the new problem
37 */
38 void addError(PProblem problem);
39
40 /**
41 * Sets up the bodies of the pattern. Only applicable if the pattern is still {@link PQueryStatus#UNINITIALIZED
42 * uninitialized}.
43 *
44 * @param bodies
45 * @throws ViatraQueryRuntimeException
46 */
47 void initializeBodies(Set<PBody> bodies);
48
49 /**
50 * Adds an annotation to the specification. Only applicable if the pattern is still
51 * {@link PQueryStatus#UNINITIALIZED uninitialized}.
52 *
53 * @param annotation
54 */
55 void addAnnotation(PAnnotation annotation);
56}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/KeyedEnumerablePConstraint.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/KeyedEnumerablePConstraint.java
new file mode 100644
index 00000000..91eea817
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/KeyedEnumerablePConstraint.java
@@ -0,0 +1,39 @@
1/*******************************************************************************
2 * Copyright (c) 2004-2010 Gabor Bergmann 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 *******************************************************************************/
9
10package tools.refinery.viatra.runtime.matchers.psystem;
11
12import tools.refinery.viatra.runtime.matchers.tuple.Tuple;
13
14/**
15 * @author Gabor Bergmann
16 *
17 */
18public abstract class KeyedEnumerablePConstraint<KeyType> extends EnumerablePConstraint {
19
20 protected KeyType supplierKey;
21
22 public KeyedEnumerablePConstraint(PBody pBody, Tuple variablesTuple,
23 KeyType supplierKey) {
24 super(pBody, variablesTuple);
25 this.supplierKey = supplierKey;
26 }
27
28 @Override
29 protected String toStringRestRest() {
30 return supplierKey == null ? "$any(null)" : keyToString();
31 }
32
33 protected abstract String keyToString();
34
35 public KeyType getSupplierKey() {
36 return supplierKey;
37 }
38
39}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/PBody.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/PBody.java
new file mode 100644
index 00000000..c38dc23a
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/PBody.java
@@ -0,0 +1,289 @@
1/*******************************************************************************
2 * Copyright (c) 2004-2010 Gabor Bergmann 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 *******************************************************************************/
9
10package tools.refinery.viatra.runtime.matchers.psystem;
11
12import java.util.ArrayList;
13import java.util.HashMap;
14import java.util.HashSet;
15import java.util.LinkedHashSet;
16import java.util.List;
17import java.util.Map;
18import java.util.Set;
19import java.util.WeakHashMap;
20import java.util.stream.Collectors;
21
22import tools.refinery.viatra.runtime.matchers.context.IQueryMetaContext;
23import tools.refinery.viatra.runtime.matchers.planning.helpers.TypeHelper;
24import tools.refinery.viatra.runtime.matchers.psystem.basicdeferred.ExportedParameter;
25import tools.refinery.viatra.runtime.matchers.psystem.basicenumerables.ConstantValue;
26import tools.refinery.viatra.runtime.matchers.psystem.queries.PDisjunction;
27import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery;
28import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery.PQueryStatus;
29import tools.refinery.viatra.runtime.matchers.util.Preconditions;
30
31/**
32 * A set of constraints representing a pattern body
33 *
34 * @author Gabor Bergmann
35 *
36 */
37public class PBody implements PTraceable {
38
39 public static final String VIRTUAL_VARIABLE_PREFIX = ".virtual";
40 private static final String VIRTUAL_VARIABLE_PATTERN = VIRTUAL_VARIABLE_PREFIX + "{%d}";
41
42 private PQuery query;
43
44 /**
45 * If null, then parent query status is reused
46 */
47 private PQueryStatus status = PQueryStatus.UNINITIALIZED;
48
49 private Set<PVariable> allVariables;
50 private Set<PVariable> uniqueVariables;
51 private List<ExportedParameter> symbolicParameters;
52 private Map<Object, PVariable> variablesByName;
53 private Set<PConstraint> constraints;
54 private int nextVirtualNodeID;
55 private PDisjunction containerDisjunction;
56
57 public PBody(PQuery query) {
58 super();
59 this.query = query;
60 allVariables = new LinkedHashSet<>();
61 uniqueVariables = new LinkedHashSet<>();
62 variablesByName = new HashMap<>();
63 constraints = new LinkedHashSet<>();
64 }
65
66 /**
67 * @return whether the submission of the new variable was successful
68 */
69 private boolean addVariable(PVariable var) {
70 checkMutability();
71 Object name = var.getName();
72 if (!variablesByName.containsKey(name)) {
73 allVariables.add(var);
74 if (var.isUnique())
75 uniqueVariables.add(var);
76 variablesByName.put(name, var);
77 return true;
78 } else {
79 return false;
80 }
81 }
82
83 /**
84 * Use this method to add a newly created constraint to the pSystem.
85 *
86 * @return whether the submission of the new constraint was successful
87 */
88 boolean registerConstraint(PConstraint constraint) {
89 checkMutability();
90 return constraints.add(constraint);
91 }
92
93 /**
94 * Use this method to remove an obsolete constraint from the pSystem.
95 *
96 * @return whether the removal of the constraint was successful
97 */
98 boolean unregisterConstraint(PConstraint constraint) {
99 checkMutability();
100 return constraints.remove(constraint);
101 }
102
103 @SuppressWarnings("unchecked")
104 public <ConstraintType> Set<ConstraintType> getConstraintsOfType(Class<ConstraintType> constraintClass) {
105 Set<ConstraintType> result = new HashSet<ConstraintType>();
106 for (PConstraint pConstraint : constraints) {
107 if (constraintClass.isInstance(pConstraint))
108 result.add((ConstraintType) pConstraint);
109 }
110 return result;
111 }
112
113 public PVariable newVirtualVariable() {
114 checkMutability();
115 String name;
116 do {
117
118 name = String.format(VIRTUAL_VARIABLE_PATTERN, nextVirtualNodeID++);
119 } while (variablesByName.containsKey(name));
120 PVariable var = new PVariable(this, name, true);
121 addVariable(var);
122 return var;
123 }
124
125 public PVariable newVirtualVariable(String name) {
126 checkMutability();
127 Preconditions.checkArgument(!variablesByName.containsKey(name), "ID %s already used for a virtual variable", name);
128 PVariable var = new PVariable(this, name, true);
129 addVariable(var);
130 return var;
131 }
132
133 public PVariable newConstantVariable(Object value) {
134 checkMutability();
135 PVariable virtual = newVirtualVariable();
136 new ConstantValue(this, virtual, value);
137 return virtual;
138 }
139
140 public Set<PVariable> getAllVariables() {
141 return allVariables;
142 }
143
144 public Set<PVariable> getUniqueVariables() {
145 return uniqueVariables;
146 }
147
148 private PVariable getVariableByName(Object name) {
149 return variablesByName.get(name).getUnifiedIntoRoot();
150 }
151
152 /**
153 * Find a PVariable by name
154 *
155 * @param name
156 * @return the found variable
157 * @throws IllegalArgumentException
158 * if no PVariable is found with the selected name
159 */
160 public PVariable getVariableByNameChecked(Object name) {
161 if (!variablesByName.containsKey(name))
162 throw new IllegalArgumentException(String.format("Cannot find PVariable %s", name));
163 return getVariableByName(name);
164 }
165
166 /**
167 * Finds and returns a PVariable by name. If no PVariable exists with the name in the body, a new one is created. If
168 * the name of the variable starts with {@value #VIRTUAL_VARIABLE_PREFIX}, the created variable will be considered
169 * virtual.
170 *
171 * @param name
172 * @return a PVariable with the selected name; never null
173 */
174 public PVariable getOrCreateVariableByName(String name) {
175 checkMutability();
176 if (!variablesByName.containsKey(name)) {
177 addVariable(new PVariable(this, name, name.startsWith(VIRTUAL_VARIABLE_PREFIX)));
178 }
179 return getVariableByName(name);
180 }
181
182 public Set<PConstraint> getConstraints() {
183 return constraints;
184 }
185
186 public PQuery getPattern() {
187 return query;
188 }
189
190 void noLongerUnique(PVariable pVariable) {
191 assert (!pVariable.isUnique());
192 uniqueVariables.remove(pVariable);
193 }
194
195 /**
196 * Returns the symbolic parameters of the body. </p>
197 *
198 * <p>
199 * <strong>Warning</strong>: if two PVariables are unified, the returned list changes. If you want to have a stable
200 * version, consider using {@link #getSymbolicParameters()}.
201 *
202 * @return a non-null, but possibly empty list
203 */
204 public List<PVariable> getSymbolicParameterVariables() {
205 return getSymbolicParameters().stream().map(ExportedParameter::getParameterVariable)
206 .collect(Collectors.toList());
207 }
208
209 /**
210 * Returns the exported parameter constraints of the body.
211 *
212 * @return a non-null, but possibly empty list
213 */
214 public List<ExportedParameter> getSymbolicParameters() {
215 if (symbolicParameters == null)
216 symbolicParameters = new ArrayList<>();
217 return symbolicParameters;
218 }
219
220 /**
221 * Sets the exported parameter constraints of the body, if this instance is mutable.
222 * @param symbolicParameters the new value
223 */
224 public void setSymbolicParameters(List<ExportedParameter> symbolicParameters) {
225 checkMutability();
226 this.symbolicParameters = new ArrayList<>(symbolicParameters);
227 }
228
229 /**
230 * Sets a specific status for the body. If set, the parent PQuery status will not be checked; if set to null, its corresponding PQuery
231 * status is checked for mutability.
232 *
233 * @param status
234 * the status to set
235 */
236 public void setStatus(PQueryStatus status) {
237 this.status = status;
238 }
239
240 public boolean isMutable() {
241 if (status == null) {
242 return query.isMutable();
243 } else {
244 return status.equals(PQueryStatus.UNINITIALIZED);
245 }
246 }
247
248 void checkMutability() {
249 if (status == null) {
250 query.checkMutability();
251 } else {
252 Preconditions.checkState(status.equals(PQueryStatus.UNINITIALIZED), "Initialized queries are not mutable");
253 }
254 }
255
256 /**
257 * Returns the disjunction the body is contained with. This disjunction may either be the
258 * {@link PQuery#getDisjunctBodies() canonical disjunction of the corresponding query} or something equivalent.
259 *
260 * @return the container disjunction of the body. Can be null if body is not in a disjunction yet.
261 */
262 public PDisjunction getContainerDisjunction() {
263 return containerDisjunction;
264 }
265
266 /**
267 * @param containerDisjunction the containerDisjunction to set
268 */
269 public void setContainerDisjunction(PDisjunction containerDisjunction) {
270 Preconditions.checkArgument(query.equals(containerDisjunction.getQuery()), "Disjunction of pattern %s incompatible with body %s", containerDisjunction.getQuery().getFullyQualifiedName(), query.getFullyQualifiedName());
271 Preconditions.checkState(this.containerDisjunction == null, "Disjunction is already set.");
272 this.containerDisjunction = containerDisjunction;
273 }
274
275 /**
276 * All unary input keys directly prescribed by constraints, grouped by variable.
277 * <p> to supertype inference or subsumption applied at this point.
278 */
279 public Map<PVariable, Set<TypeJudgement>> getAllUnaryTypeRestrictions(IQueryMetaContext context) {
280 Map<PVariable, Set<TypeJudgement>> currentRestrictions = allUnaryTypeRestrictions.get(context);
281 if (currentRestrictions == null) {
282 currentRestrictions = TypeHelper.inferUnaryTypes(getConstraints(), context);
283 allUnaryTypeRestrictions.put(context, currentRestrictions);
284 }
285 return currentRestrictions;
286 }
287 private WeakHashMap<IQueryMetaContext, Map<PVariable, Set<TypeJudgement>>> allUnaryTypeRestrictions = new WeakHashMap<IQueryMetaContext, Map<PVariable,Set<TypeJudgement>>>();
288
289}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/PConstraint.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/PConstraint.java
new file mode 100644
index 00000000..ae2c4632
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/PConstraint.java
@@ -0,0 +1,70 @@
1/*******************************************************************************
2 * Copyright (c) 2004-2010 Gabor Bergmann 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 *******************************************************************************/
9
10package tools.refinery.viatra.runtime.matchers.psystem;
11
12import java.util.Comparator;
13import java.util.Map;
14import java.util.Set;
15
16import tools.refinery.viatra.runtime.matchers.context.IQueryMetaContext;
17import tools.refinery.viatra.runtime.matchers.psystem.analysis.QueryAnalyzer;
18
19/**
20 * @author Gabor Bergmann
21 *
22 */
23public interface PConstraint extends PTraceable {
24
25 /**
26 * @since 2.1
27 * @return the query body this constraint belongs to
28 */
29 public PBody getBody();
30
31 /**
32 * All variables affected by this constraint.
33 */
34 public Set<PVariable> getAffectedVariables();
35
36 /**
37 * The set of variables whose potential values can be enumerated (once all non-deduced variables have known values).
38 */
39 public Set<PVariable> getDeducedVariables();
40
41 /**
42 * A (preferably minimal) cover of known functional dependencies between variables.
43 * @noreference Use {@link QueryAnalyzer} instead to properly handle dependencies of pattern calls.
44 * @return non-trivial functional dependencies in the form of {variables} --> {variables}, where dependencies with the same lhs are unified.
45 */
46 public Map<Set<PVariable>,Set<PVariable>> getFunctionalDependencies(IQueryMetaContext context);
47
48 public void replaceVariable(PVariable obsolete, PVariable replacement);
49
50 public void delete();
51
52 public void checkSanity();
53
54 /**
55 * Returns an integer ID that is guaranteed to increase strictly monotonously for constraints within a pBody.
56 */
57 public abstract int getMonotonousID();
58
59
60 /**
61 * A comparator that orders constraints by their {@link #getMonotonousID() monotonous identifiers}. Should only used
62 * for tiebreaking in other comparators.
63 *
64 * @since 2.0
65 */
66 public static final Comparator<PConstraint> COMPARE_BY_MONOTONOUS_ID = (arg0, arg1) -> arg0.getMonotonousID() - arg1.getMonotonousID();
67
68
69
70}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/PTraceable.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/PTraceable.java
new file mode 100644
index 00000000..f0241a9c
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/PTraceable.java
@@ -0,0 +1,16 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2017, Dénes Harmath, IncQueryLabs 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.matchers.psystem;
10
11/**
12 * Marker interface for PSystem elements that can be traced.
13 * @since 1.6
14 */
15public interface PTraceable {
16}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/PVariable.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/PVariable.java
new file mode 100644
index 00000000..b6ea4861
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/PVariable.java
@@ -0,0 +1,203 @@
1/*******************************************************************************
2 * Copyright (c) 2004-2010 Gabor Bergmann 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 *******************************************************************************/
9
10package tools.refinery.viatra.runtime.matchers.psystem;
11
12import java.util.HashSet;
13import java.util.Set;
14
15/**
16 * @author Gabor Bergmann
17 *
18 */
19public class PVariable {
20 private PBody pBody;
21 /**
22 * The name of the pattern variable. This is the unique key of the pattern node.
23 */
24 private String name;
25 /**
26 * virtual pVariables are nodes that do not correspond to actual pattern variables; they represent constants or Term
27 * substitutes
28 */
29 private boolean virtual;
30
31 /**
32 * Set of constraints that mention this variable
33 */
34 private Set<PConstraint> referringConstraints;
35
36 /**
37 * Determines whether there are any constraints that can deduce this variable
38 */
39 private Boolean deducable;
40
41 /**
42 * Another PVariable this variable has been unified into. Please use the other variable instead of this. Null iff
43 * this is still a first-class variable.
44 */
45 private PVariable unifiedInto;
46
47 PVariable(PBody pBody, String name) {
48 this(pBody, name, false);
49 }
50
51 PVariable(PBody pBody, String name, boolean virtual) {
52 super();
53 this.pBody = pBody;
54 this.name = name;
55 this.virtual = virtual;
56 // this.exportedParameter = false;
57 this.referringConstraints = new HashSet<PConstraint>();
58 this.unifiedInto = null;
59 this.deducable = false;
60 }
61
62 /**
63 * Replaces this variable with a given other, resulting in their unification. This variable will no longer be
64 * unique.
65 *
66 * @param replacement
67 */
68 public void unifyInto(PVariable replacement) {
69 pBody.checkMutability();
70 replacementCheck();
71 replacement = replacement.getUnifiedIntoRoot();
72
73 if (this.equals(replacement))
74 return;
75
76 if (!this.isVirtual() && replacement.isVirtual()) {
77 replacement.unifyInto(this);
78 } else {
79 // replacement.referringConstraints.addAll(this.referringConstraints);
80 // replacement.exportedParameter |= this.exportedParameter;
81 replacement.virtual &= this.virtual;
82 if (replacement.deducable != null && this.deducable != null)
83 replacement.deducable |= this.deducable;
84 else
85 replacement.deducable = null;
86 Set<PConstraint> snapshotConstraints = // avoid ConcurrentModificationX
87 new HashSet<PConstraint>(this.referringConstraints);
88 for (PConstraint constraint : snapshotConstraints) {
89 constraint.replaceVariable(this, replacement);
90 }
91 // replacementCheck() will fail from this point
92 this.unifiedInto = replacement;
93 pBody.noLongerUnique(this);
94 }
95 }
96
97 /**
98 * Determines whether there are any constraints that can deduce this variable
99 */
100 public boolean isDeducable() {
101 replacementCheck();
102 if (deducable == null) {
103 deducable = false;
104 for (PConstraint pConstraint : getReferringConstraints()) {
105 if (pConstraint.getDeducedVariables().contains(this)) {
106 deducable = true;
107 break;
108 }
109 }
110 }
111 return deducable;
112 }
113
114 /**
115 * Register that this variable is referred by the given constraint.
116 *
117 * @param constraint
118 */
119 public void refer(PConstraint constraint) {
120 pBody.checkMutability();
121 replacementCheck();
122 deducable = null;
123 referringConstraints.add(constraint);
124 }
125
126 /**
127 * Register that this variable is no longer referred by the given constraint.
128 *
129 * @param constraint
130 */
131 public void unrefer(PConstraint constraint) {
132 pBody.checkMutability();
133 replacementCheck();
134 deducable = null;
135 referringConstraints.remove(constraint);
136 }
137
138 /**
139 * @return the name of the pattern variable. This is the unique key of the pattern node.
140 */
141 public String getName() {
142 replacementCheck();
143 return name;
144 }
145
146 /**
147 * @return the virtual
148 */
149 public boolean isVirtual() {
150 replacementCheck();
151 return virtual;
152 }
153
154 /**
155 * @return the referringConstraints
156 */
157 public Set<PConstraint> getReferringConstraints() {
158 replacementCheck();
159 return referringConstraints;
160 }
161
162 @SuppressWarnings("unchecked")
163 public <ConstraintType> Set<ConstraintType> getReferringConstraintsOfType(Class<ConstraintType> constraintClass) {
164 replacementCheck();
165 Set<ConstraintType> result = new HashSet<ConstraintType>();
166 for (PConstraint pConstraint : referringConstraints) {
167 if (constraintClass.isInstance(pConstraint))
168 result.add((ConstraintType) pConstraint);
169 }
170 return result;
171 }
172
173 @Override
174 public String toString() {
175 // replacementCheck();
176 return name;// + ":PatternNode";
177 }
178
179 public PVariable getDirectUnifiedInto() {
180 return unifiedInto;
181 }
182
183 public PVariable getUnifiedIntoRoot() {
184 PVariable nextUnified = unifiedInto;
185 PVariable oldUnifiedInto = this;
186 while (nextUnified != null) {
187 oldUnifiedInto = nextUnified;
188 nextUnified = oldUnifiedInto.getDirectUnifiedInto();
189 }
190 return oldUnifiedInto; // unifiedInto;
191 }
192
193 public boolean isUnique() {
194 return unifiedInto == null;
195 }
196
197 private void replacementCheck() {
198 if (unifiedInto != null)
199 throw new IllegalStateException("Illegal usage of variable " + name + " which has been replaced with "
200 + unifiedInto.name);
201 }
202
203}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/TypeJudgement.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/TypeJudgement.java
new file mode 100644
index 00000000..4447b225
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/TypeJudgement.java
@@ -0,0 +1,153 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Bergmann Gabor, 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.matchers.psystem;
10
11import java.util.Collection;
12import java.util.HashSet;
13import java.util.List;
14import java.util.Map;
15import java.util.stream.Collectors;
16import java.util.Set;
17
18import tools.refinery.viatra.runtime.matchers.context.IInputKey;
19import tools.refinery.viatra.runtime.matchers.context.IQueryMetaContext;
20import tools.refinery.viatra.runtime.matchers.context.InputKeyImplication;
21import tools.refinery.viatra.runtime.matchers.psystem.basicdeferred.TypeFilterConstraint;
22import tools.refinery.viatra.runtime.matchers.psystem.basicenumerables.TypeConstraint;
23import tools.refinery.viatra.runtime.matchers.tuple.Tuple;
24import tools.refinery.viatra.runtime.matchers.tuple.Tuples;
25
26/**
27 * A judgement that means that the given tuple of variables will represent a tuple of values that is a member of the extensional relation identified by the given input key.
28 * @author Bergmann Gabor
29 *
30 */
31public class TypeJudgement {
32
33 private IInputKey inputKey;
34 private Tuple variablesTuple;
35 /**
36 * @param inputKey
37 * @param variablesTuple
38 */
39 public TypeJudgement(IInputKey inputKey, Tuple variablesTuple) {
40 super();
41 this.inputKey = inputKey;
42 this.variablesTuple = variablesTuple;
43 }
44 public IInputKey getInputKey() {
45 return inputKey;
46 }
47 public Tuple getVariablesTuple() {
48 return variablesTuple;
49 }
50 @Override
51 public int hashCode() {
52 final int prime = 31;
53 int result = 1;
54 result = prime * result
55 + ((inputKey == null) ? 0 : inputKey.hashCode());
56 result = prime * result
57 + ((variablesTuple == null) ? 0 : variablesTuple.hashCode());
58 return result;
59 }
60 @Override
61 public boolean equals(Object obj) {
62 if (this == obj)
63 return true;
64 if (obj == null)
65 return false;
66 if (!(obj instanceof TypeJudgement))
67 return false;
68 TypeJudgement other = (TypeJudgement) obj;
69 if (inputKey == null) {
70 if (other.inputKey != null)
71 return false;
72 } else if (!inputKey.equals(other.inputKey))
73 return false;
74 if (variablesTuple == null) {
75 if (other.variablesTuple != null)
76 return false;
77 } else if (!variablesTuple.equals(other.variablesTuple))
78 return false;
79 return true;
80 }
81
82 public Set<TypeJudgement> getDirectlyImpliedJudgements(IQueryMetaContext context) {
83 Set<TypeJudgement> results = new HashSet<TypeJudgement>();
84 results.add(this);
85
86 Collection<InputKeyImplication> implications = context.getImplications(this.inputKey);
87 for (InputKeyImplication inputKeyImplication : implications) {
88 results.add(
89 transcribeImplication(inputKeyImplication)
90 );
91 }
92
93 return results;
94 }
95
96 /**
97 * @since 1.6
98 */
99 public Set<TypeJudgement> getWeakenedAlternativeJudgements(IQueryMetaContext context) {
100 Set<TypeJudgement> results = new HashSet<TypeJudgement>();
101
102 Collection<InputKeyImplication> implications = context.getWeakenedAlternatives(this.inputKey);
103 for (InputKeyImplication inputKeyImplication : implications) {
104 results.add(
105 transcribeImplication(inputKeyImplication)
106 );
107 }
108
109 return results;
110 }
111
112 /**
113 * @since 2.0
114 */
115 public Map<TypeJudgement, Set<TypeJudgement>> getConditionalImpliedJudgements(IQueryMetaContext context) {
116 return context.getConditionalImplications(this.inputKey).entrySet().stream().collect(Collectors.toMap(
117 entry -> transcribeImplication(entry.getKey()),
118 entry -> entry.getValue().stream().map(this::transcribeImplication).collect(Collectors.toSet())));
119 }
120
121
122
123 private TypeJudgement transcribeImplication(InputKeyImplication inputKeyImplication) {
124 return new TypeJudgement(
125 inputKeyImplication.getImpliedKey(),
126 transcribeVariablesToTuple(inputKeyImplication.getImpliedIndices())
127 );
128 }
129 private Tuple transcribeVariablesToTuple(List<Integer> indices) {
130 Object[] elements = new Object[indices.size()];
131 for (int i = 0; i < indices.size(); ++i)
132 elements[i] = variablesTuple.get(indices.get(i));
133 return Tuples.flatTupleOf(elements);
134 }
135
136 @Override
137 public String toString() {
138 return "TypeJudgement:" + inputKey.getPrettyPrintableName() + "@" + variablesTuple.toString();
139 }
140
141 /**
142 * Creates this judgement as a direct type constraint in the given PBody under construction.
143 * <p> pre: the variables tuple must be formed of variables of that PBody.
144 * @since 1.6
145 */
146 public PConstraint createConstraintFor(PBody pBody) {
147 if (inputKey.isEnumerable()) {
148 return new TypeConstraint(pBody, variablesTuple, inputKey);
149 } else {
150 return new TypeFilterConstraint(pBody, variablesTuple, inputKey);
151 }
152 }
153}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/VariableDeferredPConstraint.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/VariableDeferredPConstraint.java
new file mode 100644
index 00000000..8ea6bb93
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/VariableDeferredPConstraint.java
@@ -0,0 +1,40 @@
1/*******************************************************************************
2 * Copyright (c) 2004-2010 Gabor Bergmann 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 *******************************************************************************/
9
10package tools.refinery.viatra.runtime.matchers.psystem;
11
12import java.util.Set;
13
14import tools.refinery.viatra.runtime.matchers.context.IQueryMetaContext;
15import tools.refinery.viatra.runtime.matchers.planning.SubPlan;
16
17/**
18 * A kind of deferred constraint that can only be checked when a set of deferring variables are all present in a plan.
19 *
20 * @author Gabor Bergmann
21 *
22 */
23public abstract class VariableDeferredPConstraint extends DeferredPConstraint {
24
25 public VariableDeferredPConstraint(PBody pBody,
26 Set<PVariable> affectedVariables) {
27 super(pBody, affectedVariables);
28 }
29
30 public abstract Set<PVariable> getDeferringVariables();
31
32 /**
33 * Refine further if needed
34 */
35 @Override
36 public boolean isReadyAt(SubPlan plan, IQueryMetaContext context) {
37 return plan.getVisibleVariables().containsAll(getDeferringVariables());
38 }
39
40}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/aggregations/AbstractMemorylessAggregationOperator.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/aggregations/AbstractMemorylessAggregationOperator.java
new file mode 100644
index 00000000..63a37bbe
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/aggregations/AbstractMemorylessAggregationOperator.java
@@ -0,0 +1,31 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Gabor Bergmann, IncQueryLabs 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.matchers.psystem.aggregations;
10
11/**
12 *
13 * An aggregation operator that does not store interim results beyond the final aggregated value.
14 * @author Gabor Bergmann
15 * @since 1.4
16 */
17public abstract class AbstractMemorylessAggregationOperator<Domain, AggregateResult>
18 implements IMultisetAggregationOperator<Domain, AggregateResult, AggregateResult>
19{
20
21 @Override
22 public AggregateResult getAggregate(AggregateResult result) {
23 return result;
24 }
25
26 @Override
27 public AggregateResult clone(AggregateResult original) {
28 return original;
29 }
30
31}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/aggregations/AggregatorType.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/aggregations/AggregatorType.java
new file mode 100644
index 00000000..4cc40a2b
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/aggregations/AggregatorType.java
@@ -0,0 +1,49 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, 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.matchers.psystem.aggregations;
10
11import java.lang.annotation.ElementType;
12import java.lang.annotation.Inherited;
13import java.lang.annotation.Retention;
14import java.lang.annotation.RetentionPolicy;
15import java.lang.annotation.Target;
16
17import tools.refinery.viatra.runtime.matchers.aggregators.count;
18
19/**
20 * The aggregator type annotation describes the type constraints for the selected aggregator. In version 1.4, two kinds of
21 * aggregators are supported:
22 *
23 * <ol>
24 * <li>An aggregator that does not consider any parameter value from the call ({@link count}), just calculates the
25 * number of matches. This is represented by a single {@link Void} and a single corresponding return type.</li>
26 * <li>An aggregator that considers a single parameter from the call, and executes some aggregate operations over it.
27 * Such an aggregate operation can be defined over multiple types, where each possible parameter type has a corresponding return type declared.</li>
28 * </ol>
29 *
30 * <strong>Important!</strong> The parameterTypes and returnTypes arrays must have
31 * <ul>
32 * <li>The same number of classes defined each.</li>
33 * <li>Items are corresponded by index.</li>
34 * <li>Items should represent data types</li>
35 * </ul>
36 *
37 * @author Zoltan Ujhelyi
38 * @since 1.4
39 *
40 */
41@Target({ ElementType.TYPE })
42@Retention(RetentionPolicy.RUNTIME)
43@Inherited
44public @interface AggregatorType {
45
46 Class<?>[] parameterTypes();
47
48 Class<?>[] returnTypes();
49}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/aggregations/BoundAggregator.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/aggregations/BoundAggregator.java
new file mode 100644
index 00000000..e6972544
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/aggregations/BoundAggregator.java
@@ -0,0 +1,61 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Gabor Bergmann, IncQueryLabs 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.matchers.psystem.aggregations;
10
11import tools.refinery.viatra.runtime.matchers.context.IInputKey;
12import tools.refinery.viatra.runtime.matchers.context.common.JavaTransitiveInstancesKey;
13
14/**
15 * Augments an aggregator operator with type bindings for the type of values being aggregated and the aggregate result.
16 * <p> In case of <em>count</em>, the operator should be null.
17 * @author Gabor Bergmann
18 * @since 1.4
19 */
20public class BoundAggregator {
21 private final IMultisetAggregationOperator<?, ?, ?> operator;
22 private final Class<?> domainType;
23 private final Class<?> aggregateResultType;
24
25 public BoundAggregator(IMultisetAggregationOperator<?, ?, ?> operator,
26 Class<?> domainType,
27 Class<?> aggregateResultType) {
28 super();
29 this.operator = operator;
30 this.domainType = domainType;
31 this.aggregateResultType = aggregateResultType;
32 }
33
34 public IMultisetAggregationOperator<?, ?, ?> getOperator() {
35 return operator;
36 }
37
38 public Class<?> getDomainType() {
39 return domainType;
40 }
41
42 public Class<?> getAggregateResultType() {
43 return aggregateResultType;
44 }
45
46 public IInputKey getDomainTypeAsInputKey() {
47 return toJavaInputKey(domainType);
48 }
49
50 public IInputKey getAggregateResultTypeAsInputKey() {
51 return toJavaInputKey(aggregateResultType);
52 }
53
54 private static IInputKey toJavaInputKey(Class<?> type) {
55 if (type==null) {
56 return null;
57 } else {
58 return new JavaTransitiveInstancesKey(type);
59 }
60 }
61}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/aggregations/IAggregatorFactory.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/aggregations/IAggregatorFactory.java
new file mode 100644
index 00000000..c970bd6a
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/aggregations/IAggregatorFactory.java
@@ -0,0 +1,40 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Zoltan Ujhelyi, Tamas Szabo, 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.matchers.psystem.aggregations;
10
11/**
12 *
13 * Describes an aggregation operator keyword, potentially with type polymorphism. The actual runtime
14 * {@link IMultisetAggregationOperator} that implements the aggregation logic may depend on the type context.
15 *
16 * <p>
17 * Implementors are suggested to use lower-case classnames (as it will end up in the language) and are required use the
18 * annotation {@link AggregatorType} to indicate type inference rules.
19 *
20 * <p>
21 * <strong>Important!</strong> Implemented aggregators must be (1) deterministic (2) pure and (3)support incremental
22 * value updates in the internal operation.
23 *
24 * @author Zoltan Ujhelyi
25 * @since 1.4
26 */
27
28public interface IAggregatorFactory {
29
30 /**
31 * Given type parameters selected from {@link AggregatorType} annotations, returns a run-time aggregator operator
32 * that is bound to the actual types.
33 *
34 * @param domainClass
35 * Java type of the values that are being aggregated
36 * @return the actual run-time aggregator logic, with type bindings
37 */
38 public BoundAggregator getAggregatorLogic(Class<?> domainClass);
39
40}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/aggregations/IMultisetAggregationOperator.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/aggregations/IMultisetAggregationOperator.java
new file mode 100644
index 00000000..3bc22274
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/aggregations/IMultisetAggregationOperator.java
@@ -0,0 +1,106 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Gabor Bergmann, IncQueryLabs 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.matchers.psystem.aggregations;
10
11import java.util.Collection;
12import java.util.stream.Stream;
13
14import tools.refinery.viatra.runtime.matchers.aggregators.ExtremumOperator;
15
16/**
17 * A single column aggregator is used to incrementally compute the aggregate of a multiset of values according to an aggregator operator.
18 *
19 * <p> The operator provides two methods of computation: <ul>
20 * <li>Stateless aggregation of an explicit multiset, provided by {@link #aggregateStatelessly(Collection)}.</li>
21 * <li>Incremental aggregation, provided by {@link #createNeutral()}, {@link #update(Object, Object, boolean)}, {@link #isNeutral(Object)}, {@link #getAggregate(Object)}.
22 * </ul>
23 *
24 * <p> In case of incremental computation, the aggregable multiset is conceptual; it is not represented by an explicit Collection<Domain> object, but its update operations are tracked.
25 *
26 * <p> In case of incremental computation, internal results, potentially distinct from the final aggregate result, may be stored in a helper data structure called <b>accumulator</b>.
27 * The goal of this distinction is that the final result may not be sufficient for incremental updates (see e.g. {@link ExtremumOperator}).
28 *
29 * @author Gabor Bergmann
30 *
31 * @param <Domain> the type of elements to be aggregated.
32 * @param <Accumulator> the type used to store the interim results of the aggregate computation,
33 * that may be incrementally refreshed upon updates to the multiset, and that can easily yield the final result.
34 * @param <AggregateResult> the type of the final result of the aggregation to be output.
35 *
36 * @since 1.4
37 */
38public interface IMultisetAggregationOperator<Domain, Accumulator, AggregateResult> {
39
40 /**
41 * A textual description of the operator.
42 */
43 String getShortDescription();
44
45 /**
46 * A name or identifier of the operator.
47 */
48 String getName();
49
50 /**
51 * @return the neutral element, i.e. the interim result of aggregating an empty multiset.
52 */
53 Accumulator createNeutral();
54
55 /**
56 * @return true if the interim result is equivalent to the neutral element, as if there are no values in the multiset.
57 * Must return true if the multiset is empty.
58 */
59 boolean isNeutral(Accumulator result);
60
61 /**
62 * @return an updated intermediate result,
63 * changed to reflect that a given object was added to / removed from the multiset
64 * (as indicated by the parameter isInsertion)
65 */
66 Accumulator update(Accumulator oldResult, Domain updateValue, boolean isInsertion);
67
68 /**
69 * @return the aggregate result obtained from the given intermediate result.
70 * May be null to indicate that the current multiset cannot be aggregated (e.g. 0 elements have no minimum).
71 */
72 AggregateResult getAggregate(Accumulator result);
73
74 /**
75 * Calculates the aggregate results from a given stream of values; all values are considered as inserted
76 * @return the aggregate result, or null if no result can be calculated (e.g. because of an empty stream)
77 * @since 2.0
78 */
79 AggregateResult aggregateStream(Stream<Domain> stream);
80
81 /**
82 * Clones the given accumulator (with all its internal contents).
83 */
84 default Accumulator clone(Accumulator original) {
85 throw new UnsupportedOperationException();
86 }
87
88 /**
89 * Combines the given aggregate result and accumulator into a single aggregate result.
90 */
91 default AggregateResult combine(AggregateResult left, Accumulator right) {
92 throw new UnsupportedOperationException();
93 }
94
95 default boolean contains(Domain value, Accumulator accumulator) {
96 throw new UnsupportedOperationException();
97 }
98
99 /**
100 * Pretty prints the contents of the given accumulator.
101 */
102 default String prettyPrint(final Accumulator accumulator) {
103 return accumulator.toString();
104 }
105
106}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/analysis/QueryAnalyzer.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/analysis/QueryAnalyzer.java
new file mode 100644
index 00000000..e3f28cff
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/analysis/QueryAnalyzer.java
@@ -0,0 +1,194 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Gabor Bergmann, IncQueryLabs 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.matchers.psystem.analysis;
10
11import java.util.HashMap;
12import java.util.HashSet;
13import java.util.Map;
14import java.util.Map.Entry;
15import java.util.Set;
16import java.util.stream.Collectors;
17
18import tools.refinery.viatra.runtime.matchers.context.IQueryBackendContext;
19import tools.refinery.viatra.runtime.matchers.context.IQueryMetaContext;
20import tools.refinery.viatra.runtime.matchers.planning.helpers.FunctionalDependencyHelper;
21import tools.refinery.viatra.runtime.matchers.psystem.PBody;
22import tools.refinery.viatra.runtime.matchers.psystem.PConstraint;
23import tools.refinery.viatra.runtime.matchers.psystem.PVariable;
24import tools.refinery.viatra.runtime.matchers.psystem.annotations.PAnnotation;
25import tools.refinery.viatra.runtime.matchers.psystem.annotations.ParameterReference;
26import tools.refinery.viatra.runtime.matchers.psystem.basicdeferred.ExportedParameter;
27import tools.refinery.viatra.runtime.matchers.psystem.basicenumerables.PositivePatternCall;
28import tools.refinery.viatra.runtime.matchers.psystem.queries.PParameter;
29import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery;
30
31/**
32 * Object responsible for computing and caching static query analysis results.
33 * <p> Any client can instantiate this to statically analyze queries.
34 * Query backends should share an instance obtained via {@link IQueryBackendContext} to save resources.
35 * <p> Precondition: all involved queries must be initialized.
36 * @noinstantiate Considered unstable API; subject to change in future versions.
37 * Either use the analyzer provided by {@link IQueryBackendContext}, or anticipate
38 * potential future breakage when instantiating your own analyzer.
39 * @author Gabor Bergmann
40 * @since 1.5
41 */
42public final class QueryAnalyzer {
43
44 private IQueryMetaContext metaContext;
45
46 public QueryAnalyzer(IQueryMetaContext metaContext) {
47 this.metaContext = metaContext;
48 }
49
50 // Functional dependencies
51
52 /**
53 * Maps query and strictness to functional dependencies
54 */
55 private Map<PQuery, Map<Set<Integer>, Set<Integer>>> strictFunctionalDependencyGuarantees =
56 new HashMap<>();
57 private Map<PQuery, Map<Set<Integer>, Set<Integer>>> softFunctionalDependencyGuarantees =
58 new HashMap<>();
59
60 /**
61 * Functional dependency information, expressed on query parameters, that the match set of the query is guaranteed to respect.
62 * <p> The type dependencies shall be expressed on the <i>parameter index</i> integers, NOT the {@link PParameter} object.
63 * @return a non-null map of functional dependencies on parameters that can be processed by {@link FunctionalDependencyHelper}
64 * @param strict if true, only "hard" dependencies are taken into account that are strictly enforced by the model representation;
65 * if false, user-provided soft dependencies (@FunctionalDependency) are included as well, that are anticipated but not guaranteed by the storage mechanism;
66 * use true if superfluous dependencies may taint the correctness of a computation, false if they would merely impact performance
67 * @since 1.5
68 */
69 public Map<Set<Integer>, Set<Integer>> getProjectedFunctionalDependencies(PQuery query, boolean strict) {
70 Map<PQuery, Map<Set<Integer>, Set<Integer>>> guaranteeStore = strict ? strictFunctionalDependencyGuarantees : softFunctionalDependencyGuarantees;
71 Map<Set<Integer>, Set<Integer>> dependencies = guaranteeStore.get(query);
72 // Why not computeIfAbsent? See Bug 532507
73 // Invoked method #computeFunctionalDependencies may trigger functional dependency computation for called queries;
74 // and may thus recurs back into #getProjectedFunctionalDependencies, causing a ConcurrentModificationException
75 // if the called query has not been previously analyzed.
76 //
77 // Note: if patterns are recursive, the empty accumulator will be found in the store
78 // (this yields a safe lower estimate and guarantees termination for #getProjectedFunctionalDependencies)
79 // But this case probably will not occur due to recursive queries having a disjunction at some point,
80 // and thus ignored by #computeFunctionalDependencies
81 if (dependencies == null) {
82 dependencies = new HashMap<>(); // accumulator
83 guaranteeStore.put(query, dependencies);
84 computeFunctionalDependencies(dependencies, query, strict);
85 }
86 return dependencies;
87 }
88
89 private void computeFunctionalDependencies(Map<Set<Integer>, Set<Integer>> accumulator, PQuery query, boolean strict) {
90 Set<PBody> bodies = query.getDisjunctBodies().getBodies();
91 if (bodies.size() == 1) { // no support for recursion or disjunction
92
93 PBody body = bodies.iterator().next();
94
95 // collect parameter variables
96 Map<PVariable, Integer> parameters = body.getSymbolicParameters().stream()
97 .collect(Collectors.toMap(ExportedParameter::getParameterVariable,
98 param -> query.getParameters().indexOf(param.getPatternParameter())));
99
100 // collect all internal dependencies
101 Map<Set<PVariable>, Set<PVariable>> internalDependencies =
102 getFunctionalDependencies(body.getConstraints(), strict);
103
104 // project onto parameter variables
105 Map<Set<PVariable>, Set<PVariable>> projectedDeps =
106 FunctionalDependencyHelper.projectDependencies(internalDependencies, parameters.keySet());
107
108 // translate into indices
109 for (Entry<Set<PVariable>, Set<PVariable>> entry : projectedDeps.entrySet()) {
110 Set<Integer> left = new HashSet<Integer>();
111 Set<Integer> right = new HashSet<Integer>();
112 for (PVariable pVariable : entry.getKey()) {
113 left.add(parameters.get(pVariable));
114 }
115 for (PVariable pVariable : entry.getValue()) {
116 right.add(parameters.get(pVariable));
117 }
118 accumulator.put(left, right);
119 }
120
121 } else {
122 // Disjunctive case, no dependencies are inferred
123 // TODO: we can still salvage the intersection of dependencies IF
124 // - all bodies have disjoint match sets
125 // - and we avoid recursion
126 }
127
128 // add annotation-based soft dependencies (regardless of number of bodies)
129 if (!strict) {
130 outer:
131 for (PAnnotation annotation : query.getAnnotationsByName("FunctionalDependency")) {
132 Set<Integer> lefts = new HashSet<Integer>();
133 Set<Integer> rights = new HashSet<Integer>();
134
135 for (Object object : annotation.getAllValues("forEach")) {
136 ParameterReference parameter = (ParameterReference) object;
137 Integer position = query.getPositionOfParameter(parameter.getName());
138 if (position == null) continue outer;
139 lefts.add(position);
140 }
141 for (Object object : annotation.getAllValues("unique")) {
142 ParameterReference parameter = (ParameterReference) object;
143 Integer position = query.getPositionOfParameter(parameter.getName());
144 if (position == null) continue outer;
145 rights.add(position);
146 }
147
148 FunctionalDependencyHelper.includeDependency(accumulator, lefts, rights);
149 }
150 }
151 }
152
153 /**
154 * Functional dependency information, expressed on PVariables within a body, that the selected constraints imply.
155 * @return a non-null map of functional dependencies on PVariables that can be processed by {@link FunctionalDependencyHelper}
156 * @param constraints the set of constraints whose consequences will be analyzed
157 * @param strict if true, only "hard" dependencies are taken into account that are strictly enforced by the model representation;
158 * if false, user-provided soft dependencies (@FunctionalDependency) are included as well, that are anticipated but not guaranteed by the storage mechanism;
159 * use true if superfluous dependencies may taint the correctness of a computation, false if they would merely impact performance
160 * @since 1.5
161 */
162 public Map<Set<PVariable>, Set<PVariable>> getFunctionalDependencies(Set<? extends PConstraint> constraints, boolean strict) {
163 Map<Set<PVariable>, Set<PVariable>> accumulator = new HashMap<Set<PVariable>, Set<PVariable>>();
164 for (PConstraint pConstraint : constraints){
165 if (pConstraint instanceof PositivePatternCall) {
166 // use query analysis results instead
167 PositivePatternCall call = (PositivePatternCall) pConstraint;
168 PQuery query = call.getSupplierKey();
169 Map<Set<Integer>, Set<Integer>> paramDependencies = getProjectedFunctionalDependencies(query, strict);
170 for (Entry<Set<Integer>, Set<Integer>> entry : paramDependencies.entrySet()) {
171 Set<PVariable> lefts = new HashSet<PVariable>();
172 Set<PVariable> rights = new HashSet<PVariable>();
173
174 for (Integer index : entry.getKey()) {
175 lefts.add(call.getVariableInTuple(index));
176 }
177 for (Integer index : entry.getValue()) {
178 rights.add(call.getVariableInTuple(index));
179 }
180
181 FunctionalDependencyHelper.includeDependency(accumulator,
182 lefts, rights);
183 }
184 } else {
185 // delegate to PConstraint
186 FunctionalDependencyHelper.includeDependencies(accumulator,
187 pConstraint.getFunctionalDependencies(metaContext));
188 }
189 }
190 return accumulator;
191 }
192
193
194}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/annotations/PAnnotation.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/annotations/PAnnotation.java
new file mode 100644
index 00000000..c4fbe0e9
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/annotations/PAnnotation.java
@@ -0,0 +1,94 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, 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.matchers.psystem.annotations;
10
11import java.util.List;
12import java.util.Optional;
13import java.util.Set;
14import java.util.function.BiConsumer;
15
16import org.eclipse.collections.api.multimap.MutableMultimap;
17import org.eclipse.collections.impl.multimap.list.FastListMultimap;
18
19/**
20 * A container describing query annotations
21 * @author Zoltan Ujhelyi
22 *
23 */
24public class PAnnotation {
25
26 private final String name;
27 private MutableMultimap<String, Object> attributes = FastListMultimap.newMultimap();
28
29 public PAnnotation(String name) {
30 this.name = name;
31
32 }
33
34 /**
35 * Adds an attribute to the annotation
36 * @param attributeName
37 * @param value
38 */
39 public void addAttribute(String attributeName, Object value) {
40 attributes.put(attributeName, value);
41 }
42
43 /**
44 * Return the name of the annotation
45 */
46 public String getName() {
47 return name;
48 }
49
50 /**
51 * Returns the value of the first occurrence of an attribute
52 * @param attributeName
53 * @return the attribute value, or null, if attribute is not available
54 * @since 2.0
55 */
56 public Optional<Object> getFirstValue(String attributeName) {
57 return getAllValues(attributeName).stream().findFirst();
58 }
59
60 /**
61 * Returns the value of the first occurrence of an attribute
62 * @param attributeName
63 * @return the attribute value, or null, if attribute is not available
64 * @since 2.0
65 */
66 public <T> Optional<T> getFirstValue(String attributeName, Class<T> clazz) {
67 return getAllValues(attributeName).stream().filter(clazz::isInstance).map(clazz::cast).findFirst();
68 }
69
70 /**
71 * Returns all values of a selected attribute
72 * @param attributeName
73 * @return a non-null, but possibly empty list of attributes
74 */
75 public List<Object> getAllValues(String attributeName) {
76 return attributes.get(attributeName).toList();
77 }
78
79 /**
80 * Executes a consumer over all attributes. A selected attribute name (key) can appear (and thus consumed) multiple times.
81 * @since 2.0
82 */
83 public void forEachValue(BiConsumer<String, Object> consumer) {
84 attributes.forEachKeyValue(consumer::accept);
85 }
86
87 /**
88 * Returns a set of all attribute names used in this annotation
89 * @since 2.1
90 */
91 public Set<String> getAllAttributeNames() {
92 return attributes.keySet().toSet();
93 }
94}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/annotations/ParameterReference.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/annotations/ParameterReference.java
new file mode 100644
index 00000000..c67e9046
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/annotations/ParameterReference.java
@@ -0,0 +1,30 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, 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.matchers.psystem.annotations;
10
11/**
12 * An annotation parameter referencing a query parameter by name. Does not check whether the parameter exists.
13 *
14 * @author Zoltan Ujhelyi
15 *
16 */
17public class ParameterReference {
18
19 final String name;
20
21 public ParameterReference(String name) {
22 super();
23 this.name = name;
24 }
25
26 public String getName() {
27 return name;
28 }
29
30}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/AggregatorConstraint.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/AggregatorConstraint.java
new file mode 100644
index 00000000..56f86e89
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/AggregatorConstraint.java
@@ -0,0 +1,98 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Tamas Szabo, 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.matchers.psystem.basicdeferred;
10
11import java.util.Collections;
12import java.util.HashMap;
13import java.util.HashSet;
14import java.util.Map;
15import java.util.Set;
16
17import tools.refinery.viatra.runtime.matchers.context.IInputKey;
18import tools.refinery.viatra.runtime.matchers.context.IQueryMetaContext;
19import tools.refinery.viatra.runtime.matchers.psystem.ITypeInfoProviderConstraint;
20import tools.refinery.viatra.runtime.matchers.psystem.PBody;
21import tools.refinery.viatra.runtime.matchers.psystem.PVariable;
22import tools.refinery.viatra.runtime.matchers.psystem.TypeJudgement;
23import tools.refinery.viatra.runtime.matchers.psystem.aggregations.BoundAggregator;
24import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery;
25import tools.refinery.viatra.runtime.matchers.tuple.Tuple;
26import tools.refinery.viatra.runtime.matchers.tuple.Tuples;
27
28/**
29 * The PSystem representation of an aggregation.
30 *
31 * @author Tamas Szabo
32 * @since 1.4
33 */
34public class AggregatorConstraint extends PatternCallBasedDeferred implements ITypeInfoProviderConstraint {
35
36 protected PVariable resultVariable;
37 private BoundAggregator aggregator;
38 protected int aggregatedColumn;
39
40 public AggregatorConstraint(BoundAggregator aggregator, PBody pBody, Tuple actualParametersTuple, PQuery query,
41 PVariable resultVariable, int aggregatedColumn) {
42 super(pBody, actualParametersTuple, query, Collections.singleton(resultVariable));
43 this.resultVariable = resultVariable;
44 this.aggregatedColumn = aggregatedColumn;
45 this.aggregator = aggregator;
46 }
47
48 public int getAggregatedColumn() {
49 return this.aggregatedColumn;
50 }
51
52 public BoundAggregator getAggregator() {
53 return this.aggregator;
54 }
55
56 @Override
57 public Set<PVariable> getDeducedVariables() {
58 return Collections.singleton(resultVariable);
59 }
60
61 @Override
62 public Map<Set<PVariable>, Set<PVariable>> getFunctionalDependencies(IQueryMetaContext context) {
63 final Map<Set<PVariable>, Set<PVariable>> result = new HashMap<Set<PVariable>, Set<PVariable>>();
64 result.put(getDeferringVariables(), getDeducedVariables());
65 return result;
66 }
67
68 @Override
69 protected void doDoReplaceVariables(PVariable obsolete, PVariable replacement) {
70 if (resultVariable.equals(obsolete))
71 resultVariable = replacement;
72 }
73
74 @Override
75 protected Set<PVariable> getCandidateQuantifiedVariables() {
76 return actualParametersTuple.<PVariable> getDistinctElements();
77 }
78
79 @Override
80 protected String toStringRest() {
81 return query.getFullyQualifiedName() + "@" + actualParametersTuple.toString() + "->"
82 + resultVariable.toString();
83 }
84
85 public PVariable getResultVariable() {
86 return resultVariable;
87 }
88
89 @Override
90 public Set<TypeJudgement> getImpliedJudgements(IQueryMetaContext context) {
91 Set<TypeJudgement> result = new HashSet<TypeJudgement>();
92 IInputKey aggregateResultType = aggregator.getAggregateResultTypeAsInputKey();
93 if (aggregateResultType != null) {
94 result.add(new TypeJudgement(aggregateResultType, Tuples.staticArityFlatTupleOf(resultVariable)));
95 }
96 return result;
97 }
98}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/BaseTypeSafeConstraint.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/BaseTypeSafeConstraint.java
new file mode 100644
index 00000000..7bc949a8
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/BaseTypeSafeConstraint.java
@@ -0,0 +1,99 @@
1/*******************************************************************************
2 * Copyright (c) 2004-2010 Gabor Bergmann 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 *******************************************************************************/
9
10package tools.refinery.viatra.runtime.matchers.psystem.basicdeferred;
11
12import java.util.Collections;
13import java.util.Set;
14import java.util.stream.Collectors;
15import java.util.stream.Stream;
16
17import tools.refinery.viatra.runtime.matchers.context.IQueryMetaContext;
18import tools.refinery.viatra.runtime.matchers.planning.SubPlan;
19import tools.refinery.viatra.runtime.matchers.psystem.PBody;
20import tools.refinery.viatra.runtime.matchers.psystem.PVariable;
21import tools.refinery.viatra.runtime.matchers.psystem.TypeJudgement;
22import tools.refinery.viatra.runtime.matchers.psystem.VariableDeferredPConstraint;
23
24/**
25 * @author Gabor Bergmann
26 *
27 */
28public abstract class BaseTypeSafeConstraint extends
29 VariableDeferredPConstraint {
30
31 protected Set<PVariable> inputVariables;
32 protected PVariable outputVariable;
33
34 public PVariable getOutputVariable() {
35 return outputVariable;
36 }
37
38 /**
39 * @param pBody
40 * @param inputVariables
41 * @param outputVariable null iff no output (check-only)
42 */
43 public BaseTypeSafeConstraint(PBody pBody,
44 Set<PVariable> inputVariables, final PVariable outputVariable) {
45 super(pBody,
46 (outputVariable == null) ?
47 inputVariables :
48 Stream.concat(inputVariables.stream(), Stream.of(outputVariable)).collect(Collectors.toSet())
49 );
50 this.inputVariables = inputVariables;
51 this.outputVariable = outputVariable;
52 }
53
54 @Override
55 public Set<PVariable> getDeducedVariables() {
56 if (outputVariable == null)
57 return Collections.emptySet();
58 else
59 return Collections.singleton(outputVariable);
60 }
61
62 @Override
63 public Set<PVariable> getDeferringVariables() {
64 return inputVariables;
65 }
66
67 @Override
68 public boolean isReadyAt(SubPlan plan, IQueryMetaContext context) {
69 if (super.isReadyAt(plan, context)) {
70 return checkTypeSafety(plan, context) == null;
71 }
72 return false;
73 }
74
75 /**
76 * Checks whether all type restrictions are already enforced on affected variables.
77 *
78 * @param plan
79 * @return a variable whose type safety is not enforced yet, or null if the plan is typesafe
80 */
81 public PVariable checkTypeSafety(SubPlan plan, IQueryMetaContext context) {
82 Set<TypeJudgement> impliedJudgements = plan.getAllImpliedTypeJudgements(context);
83
84 for (PVariable pVariable : inputVariables) {
85 Set<TypeJudgement> allTypeRestrictionsForVariable = pBody.getAllUnaryTypeRestrictions(context).get(pVariable);
86 if (allTypeRestrictionsForVariable != null && !impliedJudgements.containsAll(allTypeRestrictionsForVariable))
87 return pVariable;
88 }
89 return null;
90 }
91
92 @Override
93 protected void doReplaceVariable(PVariable obsolete, PVariable replacement) {
94 if (inputVariables.remove(obsolete))
95 inputVariables.add(replacement);
96 if (outputVariable == obsolete)
97 outputVariable = replacement;
98 }
99}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/Equality.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/Equality.java
new file mode 100644
index 00000000..b978b62c
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/Equality.java
@@ -0,0 +1,96 @@
1/*******************************************************************************
2 * Copyright (c) 2004-2010 Gabor Bergmann 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 *******************************************************************************/
9
10package tools.refinery.viatra.runtime.matchers.psystem.basicdeferred;
11
12import java.util.Collections;
13import java.util.HashMap;
14import java.util.HashSet;
15import java.util.Map;
16import java.util.Set;
17
18import tools.refinery.viatra.runtime.matchers.context.IQueryMetaContext;
19import tools.refinery.viatra.runtime.matchers.planning.SubPlan;
20import tools.refinery.viatra.runtime.matchers.psystem.DeferredPConstraint;
21import tools.refinery.viatra.runtime.matchers.psystem.PBody;
22import tools.refinery.viatra.runtime.matchers.psystem.PVariable;
23
24/**
25 * @author Gabor Bergmann
26 *
27 */
28public class Equality extends DeferredPConstraint {
29
30 private PVariable who;
31 private PVariable withWhom;
32
33 public Equality(PBody pBody, PVariable who, PVariable withWhom) {
34 super(pBody, buildSet(who, withWhom));
35 this.who = who;
36 this.withWhom = withWhom;
37 }
38
39 private static Set<PVariable> buildSet(PVariable who, PVariable withWhom) {
40 Set<PVariable> set = new HashSet<PVariable>();
41 set.add(who);
42 set.add(withWhom);
43 return set;
44 }
45
46 /**
47 * An equality is moot if it compares the a variable with itself.
48 *
49 * @return true, if the equality is moot
50 */
51 public boolean isMoot() {
52 return who.equals(withWhom);
53 }
54
55 @Override
56 public void doReplaceVariable(PVariable obsolete, PVariable replacement) {
57 if (obsolete.equals(who))
58 who = replacement;
59 if (obsolete.equals(withWhom))
60 withWhom = replacement;
61 }
62
63 @Override
64 protected String toStringRest() {
65 return who.getName() + "=" + withWhom.getName();
66 }
67
68 public PVariable getWho() {
69 return who;
70 }
71
72 public PVariable getWithWhom() {
73 return withWhom;
74 }
75
76 @Override
77 public Set<PVariable> getDeducedVariables() {
78 return Collections.emptySet();
79 }
80
81 @Override
82 public Map<Set<PVariable>, Set<PVariable>> getFunctionalDependencies(IQueryMetaContext context) {
83 final Map<Set<PVariable>, Set<PVariable>> result = new HashMap<Set<PVariable>, Set<PVariable>>();
84 result.put(Collections.singleton(who), Collections.singleton(withWhom));
85 result.put(Collections.singleton(withWhom), Collections.singleton(who));
86 return result;
87 }
88
89 @Override
90 public boolean isReadyAt(SubPlan plan, IQueryMetaContext context) {
91 return plan.getVisibleVariables().contains(who) && plan.getVisibleVariables().contains(withWhom);
92 // will be replaced by || if copierNode is available;
93 // until then, LayoutHelper.unifyVariablesAlongEqualities(PSystem<PatternDescription, StubHandle, Collector>) is
94 // recommended.
95 }
96}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/ExportedParameter.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/ExportedParameter.java
new file mode 100644
index 00000000..80706792
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/ExportedParameter.java
@@ -0,0 +1,108 @@
1/*******************************************************************************
2 * Copyright (c) 2004-2010 Gabor Bergmann 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 *******************************************************************************/
9
10package tools.refinery.viatra.runtime.matchers.psystem.basicdeferred;
11
12import java.util.Collections;
13import java.util.Set;
14
15import tools.refinery.viatra.runtime.matchers.planning.QueryProcessingException;
16import tools.refinery.viatra.runtime.matchers.psystem.PBody;
17import tools.refinery.viatra.runtime.matchers.psystem.PVariable;
18import tools.refinery.viatra.runtime.matchers.psystem.VariableDeferredPConstraint;
19import tools.refinery.viatra.runtime.matchers.psystem.queries.PParameter;
20import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery;
21
22/**
23 * @author Gabor Bergmann
24 *
25 */
26public class ExportedParameter extends VariableDeferredPConstraint {
27 PVariable parameterVariable;
28 final String parameterName;
29 final PParameter patternParameter;
30
31 /**
32 * @since 1.4
33 */
34 public ExportedParameter(PBody pBody, PVariable parameterVariable, PParameter patternParameter) {
35 super(pBody, Collections.singleton(parameterVariable));
36 this.parameterVariable = parameterVariable;
37 this.patternParameter = patternParameter;
38 parameterName = patternParameter.getName();
39 }
40
41 @Override
42 public void doReplaceVariable(PVariable obsolete, PVariable replacement) {
43 if (obsolete.equals(parameterVariable))
44 parameterVariable = replacement;
45 }
46
47 @Override
48 protected String toStringRest() {
49 Object varName = parameterVariable.getName();
50 return parameterName.equals(varName) ? parameterName : parameterName + "(" + varName + ")";
51 }
52
53 @Override
54 public Set<PVariable> getDeducedVariables() {
55 return Collections.emptySet();
56 }
57
58 /**
59 * The name of the parameter; usually, it is expected that {@link #getParameterVariable()} is more useful, except
60 * maybe for debugging purposes.
61 *
62 * @return a non-null name of the parameter
63 */
64 public String getParameterName() {
65 return parameterName;
66 }
67
68 public PVariable getParameterVariable() {
69 return parameterVariable;
70 }
71
72 /**
73 * @since 1.4
74 */
75 public PParameter getPatternParameter() {
76 if (patternParameter == null) {
77 PQuery query = pBody.getPattern();
78 Integer index = query.getPositionOfParameter(parameterName);
79 if (index == null) {
80 throw new IllegalStateException(String.format("Pattern %s does not have a parameter named %s",
81 query.getFullyQualifiedName(), parameterName));
82 }
83 return query.getParameters().get(index);
84 } else {
85 return patternParameter;
86 }
87 }
88
89 @Override
90 public Set<PVariable> getDeferringVariables() {
91 return Collections.singleton(parameterVariable);
92 }
93
94 @Override
95 public void checkSanity() {
96 super.checkSanity();
97 if (!parameterVariable.isDeducable()) {
98 String[] args = { parameterName };
99 String msg = "Impossible to match pattern: "
100 + "exported pattern variable {1} can not be determined based on the pattern constraints. "
101 + "HINT: certain constructs (e.g. negative patterns or check expressions) cannot output symbolic parameters.";
102 String shortMsg = "Could not deduce value of parameter";
103 throw new QueryProcessingException(msg, args, shortMsg, null);
104 }
105
106 }
107
108}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/ExpressionEvaluation.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/ExpressionEvaluation.java
new file mode 100644
index 00000000..06688c36
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/ExpressionEvaluation.java
@@ -0,0 +1,80 @@
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.matchers.psystem.basicdeferred;
10
11import java.util.ArrayList;
12import java.util.Collections;
13import java.util.LinkedHashSet;
14import java.util.Map;
15import java.util.Set;
16
17import tools.refinery.viatra.runtime.matchers.context.IQueryMetaContext;
18import tools.refinery.viatra.runtime.matchers.psystem.IExpressionEvaluator;
19import tools.refinery.viatra.runtime.matchers.psystem.PBody;
20import tools.refinery.viatra.runtime.matchers.psystem.PVariable;
21import tools.refinery.viatra.runtime.matchers.tuple.Tuples;
22
23/**
24 * @author Zoltan Ujhelyi
25 *
26 */
27public class ExpressionEvaluation extends BaseTypeSafeConstraint {
28
29 private IExpressionEvaluator evaluator;
30 private boolean isUnwinding;
31
32 public ExpressionEvaluation(PBody pBody, IExpressionEvaluator evaluator, PVariable outputVariable) {
33 this(pBody, evaluator, outputVariable, false);
34 }
35
36 /**
37 * @since 2.4
38 */
39 public ExpressionEvaluation(PBody pBody, IExpressionEvaluator evaluator, PVariable outputVariable,
40 boolean isUnwinding) {
41 super(pBody, getPVariablesOfExpression(pBody, evaluator), outputVariable);
42 this.evaluator = evaluator;
43 this.isUnwinding = isUnwinding;
44 }
45
46 /**
47 * @since 2.4
48 */
49 public boolean isUnwinding() {
50 return isUnwinding;
51 }
52
53 public IExpressionEvaluator getEvaluator() {
54 return evaluator;
55 }
56
57 @Override
58 protected String toStringRest() {
59 return Tuples.flatTupleOf(new ArrayList<PVariable>(inputVariables).toArray()).toString() + "|="
60 + evaluator.getShortDescription();
61 }
62
63 @Override
64 public Map<Set<PVariable>, Set<PVariable>> getFunctionalDependencies(IQueryMetaContext context) {
65 if (outputVariable == null)
66 return Collections.emptyMap();
67 else
68 return Collections.singletonMap(inputVariables, Collections.singleton(outputVariable));
69 }
70
71 private static Set<PVariable> getPVariablesOfExpression(PBody pBody, IExpressionEvaluator evaluator) {
72 // use a linked set, so that the variables will come in the order of the parameters
73 Set<PVariable> result = new LinkedHashSet<PVariable>();
74 for (String name : evaluator.getInputParameterNames()) {
75 PVariable variable = pBody.getOrCreateVariableByName(name);
76 result.add(variable);
77 }
78 return result;
79 }
80}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/Inequality.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/Inequality.java
new file mode 100644
index 00000000..5cac33dc
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/Inequality.java
@@ -0,0 +1,151 @@
1/*******************************************************************************
2 * Copyright (c) 2004-2010 Gabor Bergmann 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 *******************************************************************************/
9
10package tools.refinery.viatra.runtime.matchers.psystem.basicdeferred;
11
12import java.util.Arrays;
13import java.util.Collections;
14import java.util.HashSet;
15import java.util.Set;
16
17import tools.refinery.viatra.runtime.matchers.psystem.PBody;
18import tools.refinery.viatra.runtime.matchers.psystem.PVariable;
19import tools.refinery.viatra.runtime.matchers.psystem.VariableDeferredPConstraint;
20
21/**
22 * @author Gabor Bergmann
23 *
24 */
25public class Inequality extends VariableDeferredPConstraint {
26
27 private PVariable who;
28 private PVariable withWhom;
29
30 /**
31 * The inequality constraint is weak if it can be ignored when who is the same as withWhom, or if any if them is
32 * undeducible.
33 */
34 private boolean weak;
35
36 public Inequality(PBody pBody, PVariable who, PVariable withWhom) {
37 this(pBody, who, withWhom, false);
38 }
39
40 public Inequality(PBody pBody, PVariable who, PVariable withWhom,
41 boolean weak) {
42 super(pBody, new HashSet<>(Arrays.asList(who, withWhom) ));
43 this.who = who;
44 this.withWhom = withWhom;
45 this.weak = weak;
46 }
47
48 // private Inequality(
49 // PSystem<PatternDescription, StubHandle, ?> pSystem,
50 // PVariable subject, Set<PVariable> inequals)
51 // {
52 // super(pSystem, include(inequals, subject));
53 // this.subject = subject;
54 // this.inequals = inequals;
55 // }
56
57 // private static HashSet<PVariable> include(Set<PVariable> inequals, PVariable subject) {
58 // HashSet<PVariable> hashSet = new HashSet<PVariable>(inequals);
59 // hashSet.add(subject);
60 // return hashSet;
61 // }
62
63 @Override
64 public Set<PVariable> getDeferringVariables() {
65 return getAffectedVariables();
66 }
67
68 // private static int[] mapIndices(Map<Object, Integer> variablesIndex, Set<PVariable> keys) {
69 // int[] result = new int[keys.size()];
70 // int k = 0;
71 // for (PVariable key : keys) {
72 // result[k++] = variablesIndex.get(key);
73 // }
74 // return result;
75 // }
76
77 // @Override
78 // public IFoldablePConstraint getIncorporator() {
79 // return incorporator;
80 // }
81 //
82 // @Override
83 // public void registerIncorporatationInto(IFoldablePConstraint incorporator) {
84 // this.incorporator = incorporator;
85 // }
86 //
87 // @Override
88 // public boolean incorporate(IFoldablePConstraint other) {
89 // if (other instanceof Inequality<?, ?>) {
90 // Inequality other2 = (Inequality) other;
91 // if (subject.equals(other2.subject)) {
92 // Set<PVariable> newInequals = new HashSet<PVariable>(inequals);
93 // newInequals.addAll(other2.inequals);
94 // return new Inequality<PatternDescription, StubHandle>(buildable, subject, newInequals);
95 // }
96 // } else return false;
97 // }
98
99 @Override
100 protected String toStringRest() {
101 return who.toString() + (isWeak() ? "!=?" : "!=") + withWhom.toString();
102 }
103
104 @Override
105 public void doReplaceVariable(PVariable obsolete, PVariable replacement) {
106 if (obsolete.equals(who))
107 who = replacement;
108 if (obsolete.equals(withWhom))
109 withWhom = replacement;
110 }
111
112 @Override
113 public Set<PVariable> getDeducedVariables() {
114 return Collections.emptySet();
115 }
116
117 /**
118 * The inequality constraint is weak if it can be ignored when who is the same as withWhom, or if any if them is
119 * undeducible.
120 *
121 * @return the weak
122 */
123 public boolean isWeak() {
124 return weak;
125 }
126
127 /**
128 * A weak inequality constraint is eliminable if who is the same as withWhom, or if any if them is undeducible.
129 */
130 public boolean isEliminable() {
131 return isWeak() && (who.equals(withWhom) || !who.isDeducable() || !withWhom.isDeducable());
132 }
133
134 /**
135 * Eliminates a weak inequality constraint if it can be ignored when who is the same as withWhom, or if any if them
136 * is undeducible.
137 */
138 public void eliminateWeak() {
139 if (isEliminable())
140 delete();
141 }
142
143 public PVariable getWho() {
144 return who;
145 }
146
147 public PVariable getWithWhom() {
148 return withWhom;
149 }
150
151}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/NegativePatternCall.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/NegativePatternCall.java
new file mode 100644
index 00000000..87d9d9fc
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/NegativePatternCall.java
@@ -0,0 +1,52 @@
1/*******************************************************************************
2 * Copyright (c) 2004-2010 Gabor Bergmann 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 *******************************************************************************/
9
10package tools.refinery.viatra.runtime.matchers.psystem.basicdeferred;
11
12import java.util.Collections;
13import java.util.Set;
14
15import tools.refinery.viatra.runtime.matchers.psystem.PBody;
16import tools.refinery.viatra.runtime.matchers.psystem.PVariable;
17import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery;
18import tools.refinery.viatra.runtime.matchers.tuple.Tuple;
19
20/**
21 * @author Gabor Bergmann
22 *
23 */
24public class NegativePatternCall extends PatternCallBasedDeferred {
25
26 public NegativePatternCall(PBody pBody, Tuple actualParametersTuple, PQuery query) {
27 super(pBody, actualParametersTuple, query);
28 }
29
30 @Override
31 public Set<PVariable> getDeducedVariables() {
32 return Collections.emptySet();
33 }
34
35 /**
36 * @return all variables that may potentially be quantified they are not used anywhere else
37 */
38 @Override
39 protected Set<PVariable> getCandidateQuantifiedVariables() {
40 return getAffectedVariables();
41 }
42
43 @Override
44 protected void doDoReplaceVariables(PVariable obsolete, PVariable replacement) {
45 }
46
47 @Override
48 protected String toStringRest() {
49 return "!" + query.getFullyQualifiedName() + "@" + actualParametersTuple.toString();
50 }
51
52}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/PatternCallBasedDeferred.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/PatternCallBasedDeferred.java
new file mode 100644
index 00000000..93eeffec
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/PatternCallBasedDeferred.java
@@ -0,0 +1,118 @@
1/*******************************************************************************
2 * Copyright (c) 2004-2010 Gabor Bergmann 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 *******************************************************************************/
9
10package tools.refinery.viatra.runtime.matchers.psystem.basicdeferred;
11
12import java.util.Collections;
13import java.util.HashSet;
14import java.util.Set;
15
16import tools.refinery.viatra.runtime.matchers.planning.QueryProcessingException;
17import tools.refinery.viatra.runtime.matchers.psystem.IQueryReference;
18import tools.refinery.viatra.runtime.matchers.psystem.PBody;
19import tools.refinery.viatra.runtime.matchers.psystem.PConstraint;
20import tools.refinery.viatra.runtime.matchers.psystem.PVariable;
21import tools.refinery.viatra.runtime.matchers.psystem.VariableDeferredPConstraint;
22import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery;
23import tools.refinery.viatra.runtime.matchers.tuple.Tuple;
24
25/**
26 * @author Gabor Bergmann
27 *
28 */
29public abstract class PatternCallBasedDeferred extends VariableDeferredPConstraint implements IQueryReference {
30
31 protected Tuple actualParametersTuple;
32
33 protected abstract void doDoReplaceVariables(PVariable obsolete, PVariable replacement);
34
35 protected abstract Set<PVariable> getCandidateQuantifiedVariables();
36
37 protected PQuery query;
38 private Set<PVariable> deferringVariables;
39
40 public PatternCallBasedDeferred(PBody pBody, Tuple actualParametersTuple,
41 PQuery pattern, Set<PVariable> additionalAffectedVariables) {
42 super(pBody, union(actualParametersTuple.<PVariable> getDistinctElements(), additionalAffectedVariables));
43 this.actualParametersTuple = actualParametersTuple;
44 this.query = pattern;
45 }
46
47 public PatternCallBasedDeferred(PBody pBody, Tuple actualParametersTuple,
48 PQuery pattern) {
49 this(pBody, actualParametersTuple, pattern, Collections.<PVariable> emptySet());
50 }
51
52 private static Set<PVariable> union(Set<PVariable> a, Set<PVariable> b) {
53 Set<PVariable> result = new HashSet<PVariable>();
54 result.addAll(a);
55 result.addAll(b);
56 return result;
57 }
58
59 @Override
60 public Set<PVariable> getDeferringVariables() {
61 if (deferringVariables == null) {
62 deferringVariables = new HashSet<PVariable>();
63 for (PVariable var : getCandidateQuantifiedVariables()) {
64 if (var.isDeducable())
65 deferringVariables.add(var);
66 }
67 }
68 return deferringVariables;
69 }
70
71 @Override
72 public void checkSanity() {
73 super.checkSanity();
74 for (Object obj : this.actualParametersTuple.getDistinctElements()) {
75 PVariable var = (PVariable) obj;
76 if (!getDeferringVariables().contains(var)) {
77 // so this is a free variable of the NAC / aggregation?
78 for (PConstraint pConstraint : var.getReferringConstraints()) {
79 if (pConstraint != this
80 && !(pConstraint instanceof Equality && ((Equality) pConstraint).isMoot()))
81 throw new QueryProcessingException (
82 "Variable {1} of constraint {2} is not a positively determined part of the pattern, yet it is also affected by {3}.",
83 new String[] { var.toString(), this.toString(), pConstraint.toString() },
84 "Read-only variable can not be deduced", null);
85 }
86 }
87 }
88
89 }
90
91// public SubPlan getSidePlan(IOperationCompiler compiler) throws QueryPlannerException {
92// SubPlan sidePlan = compiler.patternCallPlan(actualParametersTuple, query);
93// sidePlan = BuildHelper.enforceVariableCoincidences(compiler, sidePlan);
94// return sidePlan;
95// }
96
97 @Override
98 protected void doReplaceVariable(PVariable obsolete, PVariable replacement) {
99 if (deferringVariables != null) {
100 // FAIL instead of hopeless attempt to fix
101 // if (deferringVariables.remove(obsolete)) deferringVariables.add(replacement);
102 throw new IllegalStateException("Cannot replace variables on " + this
103 + " when deferring variables have already been identified.");
104 }
105 actualParametersTuple = actualParametersTuple.replaceAll(obsolete, replacement);
106 doDoReplaceVariables(obsolete, replacement);
107 }
108
109 public Tuple getActualParametersTuple() {
110 return actualParametersTuple;
111 }
112
113 @Override
114 public PQuery getReferredQuery() {
115 return query;
116 }
117
118}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/PatternMatchCounter.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/PatternMatchCounter.java
new file mode 100644
index 00000000..0c40d91e
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/PatternMatchCounter.java
@@ -0,0 +1,70 @@
1/*******************************************************************************
2 * Copyright (c) 2004-2010 Gabor Bergmann 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 *******************************************************************************/
9
10package tools.refinery.viatra.runtime.matchers.psystem.basicdeferred;
11
12import java.util.Collections;
13import java.util.HashMap;
14import java.util.Map;
15import java.util.Set;
16
17import tools.refinery.viatra.runtime.matchers.context.IQueryMetaContext;
18import tools.refinery.viatra.runtime.matchers.psystem.PBody;
19import tools.refinery.viatra.runtime.matchers.psystem.PVariable;
20import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery;
21import tools.refinery.viatra.runtime.matchers.tuple.Tuple;
22
23/**
24 * @author Gabor Bergmann
25 */
26public class PatternMatchCounter extends PatternCallBasedDeferred {
27
28 private PVariable resultVariable;
29
30 public PatternMatchCounter(PBody pBody, Tuple actualParametersTuple,
31 PQuery query, PVariable resultVariable) {
32 super(pBody, actualParametersTuple, query, Collections.singleton(resultVariable));
33 this.resultVariable = resultVariable;
34 }
35
36 @Override
37 public Set<PVariable> getDeducedVariables() {
38 return Collections.singleton(resultVariable);
39 }
40
41 @Override
42 public Map<Set<PVariable>, Set<PVariable>> getFunctionalDependencies(IQueryMetaContext context) {
43 final Map<Set<PVariable>, Set<PVariable>> result = new HashMap<Set<PVariable>, Set<PVariable>>();
44 result.put(getDeferringVariables(), getDeducedVariables());
45 return result;
46 }
47
48 @Override
49 protected void doDoReplaceVariables(PVariable obsolete, PVariable replacement) {
50 if (resultVariable.equals(obsolete))
51 resultVariable = replacement;
52 }
53
54 @Override
55 protected Set<PVariable> getCandidateQuantifiedVariables() {
56 return actualParametersTuple.<PVariable> getDistinctElements();
57 }
58
59
60 @Override
61 protected String toStringRest() {
62 return query.getFullyQualifiedName() + "@" + actualParametersTuple.toString() + "->"
63 + resultVariable.toString();
64 }
65
66 public PVariable getResultVariable() {
67 return resultVariable;
68 }
69
70} \ No newline at end of file
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/RelationEvaluation.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/RelationEvaluation.java
new file mode 100644
index 00000000..336a83fb
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/RelationEvaluation.java
@@ -0,0 +1,57 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2022, Tamas Szabo, GitHub
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.matchers.psystem.basicdeferred;
10
11import java.util.List;
12
13import tools.refinery.viatra.runtime.matchers.psystem.EnumerablePConstraint;
14import tools.refinery.viatra.runtime.matchers.psystem.IMultiQueryReference;
15import tools.refinery.viatra.runtime.matchers.psystem.IRelationEvaluator;
16import tools.refinery.viatra.runtime.matchers.psystem.PBody;
17import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery;
18import tools.refinery.viatra.runtime.matchers.tuple.Tuple;
19
20/**
21 * A constraint which prescribes the evaluation of custom Java logic that takes an arbitrary number of input relations
22 * and produces one output relation. Contrast this to {@link ExpressionEvaluation}, which produces a single output value
23 * given an input tuple.
24 *
25 * The assumption is that the relation evaluation logic is not incremental, that is, it can only perform from-scratch
26 * computation of the output relation given the complete input relations. To this end, the relation evaluator always
27 * receives the complete input relations with all their contents as input. However, the evaluator engine makes sure that
28 * the output of the relation evaluation is at least "seemingly" incremental. This means that the underlying computation
29 * network computes the delta on the output compared to the previous output and only propagates the delta further.
30 *
31 * @author Tamas Szabo
32 *
33 * @since 2.8
34 *
35 */
36public class RelationEvaluation extends EnumerablePConstraint implements IMultiQueryReference {
37
38 private final IRelationEvaluator evaluator;
39 private final List<PQuery> inputQueries;
40
41 public RelationEvaluation(final PBody body, final Tuple variablesTuple, final List<PQuery> inputQueries,
42 final IRelationEvaluator evaluator) {
43 super(body, variablesTuple);
44 this.evaluator = evaluator;
45 this.inputQueries = inputQueries;
46 }
47
48 public IRelationEvaluator getEvaluator() {
49 return this.evaluator;
50 }
51
52 @Override
53 public List<PQuery> getReferredQueries() {
54 return this.inputQueries;
55 }
56
57}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/TypeFilterConstraint.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/TypeFilterConstraint.java
new file mode 100644
index 00000000..8b6e29ef
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicdeferred/TypeFilterConstraint.java
@@ -0,0 +1,105 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Bergmann Gabor, 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.matchers.psystem.basicdeferred;
10
11import java.util.Collections;
12import java.util.Map;
13import java.util.Set;
14
15import tools.refinery.viatra.runtime.matchers.context.IInputKey;
16import tools.refinery.viatra.runtime.matchers.context.IQueryMetaContext;
17import tools.refinery.viatra.runtime.matchers.psystem.ITypeConstraint;
18import tools.refinery.viatra.runtime.matchers.psystem.PBody;
19import tools.refinery.viatra.runtime.matchers.psystem.PVariable;
20import tools.refinery.viatra.runtime.matchers.psystem.TypeJudgement;
21import tools.refinery.viatra.runtime.matchers.psystem.VariableDeferredPConstraint;
22import tools.refinery.viatra.runtime.matchers.psystem.basicenumerables.TypeConstraint;
23import tools.refinery.viatra.runtime.matchers.tuple.Tuple;
24
25/**
26 * Represents a non-enumerable type constraint that asserts that values substituted for the given tuple of variables
27 * form a tuple that belongs to a (typically non-enumerable) extensional relation identified by an {@link IInputKey}.
28 *
29 * <p> The InputKey is typically not enumerable. If it is enumerable, use {@link TypeConstraint} instead, so that the PConstraint carries over the property of enumerability.
30 *
31 * @author Bergmann Gabor
32 *
33 */
34public class TypeFilterConstraint extends VariableDeferredPConstraint implements
35 ITypeConstraint {
36
37 private Tuple variablesTuple;
38 private IInputKey inputKey;
39
40 private TypeJudgement equivalentJudgement;
41
42
43 public TypeFilterConstraint(PBody pBody, Tuple variablesTuple, IInputKey inputKey) {
44 super(pBody, variablesTuple.<PVariable> getDistinctElements());
45 this.equivalentJudgement = new TypeJudgement(inputKey, variablesTuple);
46
47 this.variablesTuple = variablesTuple;
48 this.inputKey = inputKey;
49
50 if (variablesTuple.getSize() != inputKey.getArity())
51 throw new IllegalArgumentException(
52 this.getClass().getSimpleName() +
53 " applied for variable tuple " + variablesTuple + " having wrong arity for input key " +
54 inputKey);
55 }
56
57
58
59 public Tuple getVariablesTuple() {
60 return variablesTuple;
61 }
62
63 public IInputKey getInputKey() {
64 return inputKey;
65 }
66
67 @Override
68 public TypeJudgement getEquivalentJudgement() {
69 return equivalentJudgement;
70 }
71
72 @Override
73 protected void doReplaceVariable(PVariable obsolete, PVariable replacement) {
74 variablesTuple = variablesTuple.replaceAll(obsolete, replacement);
75 this.equivalentJudgement = new TypeJudgement(inputKey, variablesTuple);
76 }
77
78 @Override
79 public Set<TypeJudgement> getImpliedJudgements(IQueryMetaContext context) {
80 return Collections.singleton(equivalentJudgement);
81 }
82
83 @Override
84 public Set<PVariable> getDeducedVariables() {
85 return Collections.emptySet();
86 }
87
88 @Override
89 public Set<PVariable> getDeferringVariables() {
90 return getAffectedVariables();
91 }
92
93 @Override
94 protected String toStringRest() {
95 return inputKey.getPrettyPrintableName() + "@" + variablesTuple;
96 }
97
98 @Override
99 public Map<Set<PVariable>, Set<PVariable>> getFunctionalDependencies(IQueryMetaContext context) {
100 return TypeConstraintUtil.getFunctionalDependencies(context, inputKey, variablesTuple);
101 }
102
103
104
105}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicenumerables/AbstractTransitiveClosure.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicenumerables/AbstractTransitiveClosure.java
new file mode 100644
index 00000000..7bbf7118
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicenumerables/AbstractTransitiveClosure.java
@@ -0,0 +1,44 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2018, Gabor Bergmann, 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.matchers.psystem.basicenumerables;
10
11import java.util.Set;
12
13import tools.refinery.viatra.runtime.matchers.context.IQueryMetaContext;
14import tools.refinery.viatra.runtime.matchers.psystem.IQueryReference;
15import tools.refinery.viatra.runtime.matchers.psystem.ITypeInfoProviderConstraint;
16import tools.refinery.viatra.runtime.matchers.psystem.KeyedEnumerablePConstraint;
17import tools.refinery.viatra.runtime.matchers.psystem.PBody;
18import tools.refinery.viatra.runtime.matchers.psystem.TypeJudgement;
19import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery;
20import tools.refinery.viatra.runtime.matchers.tuple.Tuple;
21
22/**
23 * @since 2.0
24 */
25public abstract class AbstractTransitiveClosure extends KeyedEnumerablePConstraint<PQuery> implements IQueryReference, ITypeInfoProviderConstraint {
26
27 public AbstractTransitiveClosure(PBody pBody, Tuple variablesTuple, PQuery supplierKey) {
28 super(pBody, variablesTuple, supplierKey);
29 }
30
31 @Override
32 public PQuery getReferredQuery() {
33 return supplierKey;
34 }
35
36 /**
37 * @since 1.3
38 */
39 @Override
40 public Set<TypeJudgement> getImpliedJudgements(IQueryMetaContext context) {
41 return PositivePatternCall.getTypesImpliedByCall(supplierKey, variablesTuple);
42 }
43
44} \ No newline at end of file
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicenumerables/BinaryReflexiveTransitiveClosure.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicenumerables/BinaryReflexiveTransitiveClosure.java
new file mode 100644
index 00000000..e3dae240
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicenumerables/BinaryReflexiveTransitiveClosure.java
@@ -0,0 +1,57 @@
1/*******************************************************************************
2 * Copyright (c) 2004-2010 Zoltan Ujhelyi, Gabor Bergmann, 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
10package tools.refinery.viatra.runtime.matchers.psystem.basicenumerables;
11
12import tools.refinery.viatra.runtime.matchers.context.IInputKey;
13import tools.refinery.viatra.runtime.matchers.planning.QueryProcessingException;
14import tools.refinery.viatra.runtime.matchers.psystem.PBody;
15import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery;
16import tools.refinery.viatra.runtime.matchers.tuple.Tuple;
17
18/**
19 * For a binary base pattern over an enumerable universe type, computes the reflexive transitive closure (base)*
20 *
21 * @author Gabor Bergmann, Zoltan Ujhelyi
22 * @since 2.0
23 */
24public class BinaryReflexiveTransitiveClosure extends AbstractTransitiveClosure {
25
26 private final IInputKey universeType;
27
28 public BinaryReflexiveTransitiveClosure(PBody pBody, Tuple variablesTuple,
29 PQuery pattern, IInputKey universeType) {
30 super(pBody, variablesTuple, pattern);
31 this.universeType = universeType;
32 }
33
34 @Override
35 protected String keyToString() {
36 return supplierKey.getFullyQualifiedName() + "*";
37 }
38
39 /**
40 * Returns the type whose instances should be returned as 0-long paths.
41 * @since 2.0
42 */
43 public IInputKey getUniverseType() {
44 return universeType;
45 }
46
47 @Override
48 public void checkSanity() {
49 if (!universeType.isEnumerable() || universeType.getArity() != 1) {
50 throw new QueryProcessingException(
51 String.format("Invalid universe type %s - it should be enumerable and must have an arity of 1.",
52 universeType.getPrettyPrintableName()),
53 pBody.getPattern());
54 }
55 }
56
57}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicenumerables/BinaryTransitiveClosure.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicenumerables/BinaryTransitiveClosure.java
new file mode 100644
index 00000000..716d043b
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicenumerables/BinaryTransitiveClosure.java
@@ -0,0 +1,33 @@
1/*******************************************************************************
2 * Copyright (c) 2004-2010 Gabor Bergmann 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 *******************************************************************************/
9
10package tools.refinery.viatra.runtime.matchers.psystem.basicenumerables;
11
12import tools.refinery.viatra.runtime.matchers.psystem.PBody;
13import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery;
14import tools.refinery.viatra.runtime.matchers.tuple.Tuple;
15
16/**
17 * For a binary base pattern, computes the irreflexive transitive closure (base)+
18 *
19 * @author Gabor Bergmann
20 *
21 */
22public class BinaryTransitiveClosure extends AbstractTransitiveClosure {
23
24 public BinaryTransitiveClosure(PBody pBody, Tuple variablesTuple,
25 PQuery pattern) {
26 super(pBody, variablesTuple, pattern);
27 }
28
29 @Override
30 protected String keyToString() {
31 return supplierKey.getFullyQualifiedName() + "+";
32 }
33}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicenumerables/Connectivity.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicenumerables/Connectivity.java
new file mode 100644
index 00000000..10da2e21
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicenumerables/Connectivity.java
@@ -0,0 +1,11 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.viatra.runtime.matchers.psystem.basicenumerables;
7
8public enum Connectivity {
9 WEAK,
10 STRONG;
11}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicenumerables/ConstantValue.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicenumerables/ConstantValue.java
new file mode 100644
index 00000000..251146c8
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicenumerables/ConstantValue.java
@@ -0,0 +1,57 @@
1/*******************************************************************************
2 * Copyright (c) 2004-2010 Gabor Bergmann 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 *******************************************************************************/
9
10package tools.refinery.viatra.runtime.matchers.psystem.basicenumerables;
11
12import java.util.Collections;
13import java.util.HashMap;
14import java.util.Map;
15import java.util.Set;
16
17import tools.refinery.viatra.runtime.matchers.context.IQueryMetaContext;
18import tools.refinery.viatra.runtime.matchers.psystem.KeyedEnumerablePConstraint;
19import tools.refinery.viatra.runtime.matchers.psystem.PBody;
20import tools.refinery.viatra.runtime.matchers.psystem.PVariable;
21import tools.refinery.viatra.runtime.matchers.tuple.Tuples;
22
23/**
24 * @author Gabor Bergmann
25 *
26 */
27public class ConstantValue extends KeyedEnumerablePConstraint<Object> {
28
29 private PVariable variable;
30
31 public ConstantValue(PBody pBody, PVariable variable, Object value) {
32 super(pBody, Tuples.staticArityFlatTupleOf(variable), value);
33 this.variable = variable;
34 }
35
36 @Override
37 protected String keyToString() {
38 return supplierKey.toString();
39 }
40
41 /**
42 * @since 1.7
43 */
44 public PVariable getVariable() {
45 return variable;
46 }
47
48 @Override
49 public Map<Set<PVariable>, Set<PVariable>> getFunctionalDependencies(IQueryMetaContext context) {
50 final Map<Set<PVariable>, Set<PVariable>> result = new HashMap<Set<PVariable>, Set<PVariable>>();
51 final Set<PVariable> emptySet = Collections.emptySet(); // a constant value is functionally determined by everything
52 result.put(emptySet, Collections.singleton(getVariableInTuple(0)));
53 return result;
54 }
55
56
57}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicenumerables/PositivePatternCall.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicenumerables/PositivePatternCall.java
new file mode 100644
index 00000000..25ab34b4
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicenumerables/PositivePatternCall.java
@@ -0,0 +1,76 @@
1/*******************************************************************************
2 * Copyright (c) 2004-2010 Gabor Bergmann 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 *******************************************************************************/
9
10package tools.refinery.viatra.runtime.matchers.psystem.basicenumerables;
11
12import java.util.HashSet;
13import java.util.Set;
14
15import tools.refinery.viatra.runtime.matchers.context.IInputKey;
16import tools.refinery.viatra.runtime.matchers.context.IQueryMetaContext;
17import tools.refinery.viatra.runtime.matchers.psystem.IQueryReference;
18import tools.refinery.viatra.runtime.matchers.psystem.ITypeInfoProviderConstraint;
19import tools.refinery.viatra.runtime.matchers.psystem.KeyedEnumerablePConstraint;
20import tools.refinery.viatra.runtime.matchers.psystem.PBody;
21import tools.refinery.viatra.runtime.matchers.psystem.TypeJudgement;
22import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery;
23import tools.refinery.viatra.runtime.matchers.tuple.Tuple;
24import tools.refinery.viatra.runtime.matchers.tuple.Tuples;
25
26/**
27 * @author Gabor Bergmann
28 *
29 */
30public class PositivePatternCall extends KeyedEnumerablePConstraint<PQuery> implements IQueryReference, ITypeInfoProviderConstraint {
31
32 public PositivePatternCall(PBody pBody, Tuple variablesTuple,
33 PQuery pattern) {
34 super(pBody, variablesTuple, pattern);
35 }
36
37 @Override
38 protected String keyToString() {
39 return supplierKey.getFullyQualifiedName();
40 }
41
42 // Note: #getFunctionalDependencies is intentionally not implemented - use QueryAnalyzer instead!
43// @Override
44// public Map<Set<PVariable>, Set<PVariable>> getFunctionalDependencies(IQueryMetaContext context) {
45// return super.getFunctionalDependencies(context);
46// }
47
48 @Override
49 public PQuery getReferredQuery() {
50 return supplierKey;
51 }
52
53 @Override
54 public Set<TypeJudgement> getImpliedJudgements(IQueryMetaContext context) {
55 return getTypesImpliedByCall(supplierKey, variablesTuple);
56 }
57
58 /**
59 * @since 1.3
60 */
61 public static Set<TypeJudgement> getTypesImpliedByCall(PQuery calledQuery, Tuple actualParametersTuple) {
62 Set<TypeJudgement> result = new HashSet<TypeJudgement>();
63 for (TypeJudgement parameterJudgement : calledQuery.getTypeGuarantees()) {
64 IInputKey inputKey = parameterJudgement.getInputKey();
65 Tuple judgementIndexTuple = parameterJudgement.getVariablesTuple();
66
67 Object[] judgementVariables = new Object[judgementIndexTuple.getSize()];
68 for (int i=0; i<judgementVariables.length; ++i)
69 judgementVariables[i] = actualParametersTuple.get((int) judgementIndexTuple.get(i));
70
71 result.add(new TypeJudgement(inputKey, Tuples.flatTupleOf(judgementVariables)));
72 }
73 return result;
74 }
75
76}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicenumerables/RepresentativeElectionConstraint.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicenumerables/RepresentativeElectionConstraint.java
new file mode 100644
index 00000000..b97ff55f
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicenumerables/RepresentativeElectionConstraint.java
@@ -0,0 +1,43 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.viatra.runtime.matchers.psystem.basicenumerables;
7
8import tools.refinery.viatra.runtime.matchers.context.IQueryMetaContext;
9import tools.refinery.viatra.runtime.matchers.psystem.*;
10import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery;
11import tools.refinery.viatra.runtime.matchers.tuple.Tuple;
12
13import java.util.Set;
14
15public class RepresentativeElectionConstraint extends KeyedEnumerablePConstraint<PQuery>
16 implements IQueryReference, ITypeInfoProviderConstraint {
17 private final Connectivity connectivity;
18
19 public RepresentativeElectionConstraint(PBody pBody, Tuple variablesTuple, PQuery supplierKey,
20 Connectivity connectivity) {
21 super(pBody, variablesTuple, supplierKey);
22 this.connectivity = connectivity;
23 }
24
25 public Connectivity getConnectivity() {
26 return connectivity;
27 }
28
29 @Override
30 public PQuery getReferredQuery() {
31 return supplierKey;
32 }
33
34 @Override
35 public Set<TypeJudgement> getImpliedJudgements(IQueryMetaContext context) {
36 return PositivePatternCall.getTypesImpliedByCall(supplierKey, variablesTuple);
37 }
38
39 @Override
40 protected String keyToString() {
41 return supplierKey.getFullyQualifiedName() + "#" + connectivity + "#representative";
42 }
43}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicenumerables/TypeConstraint.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicenumerables/TypeConstraint.java
new file mode 100644
index 00000000..2ca54cc0
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/basicenumerables/TypeConstraint.java
@@ -0,0 +1,79 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, 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.matchers.psystem.basicenumerables;
10
11import java.util.Collections;
12import java.util.Map;
13import java.util.Set;
14
15import tools.refinery.viatra.runtime.matchers.context.IInputKey;
16import tools.refinery.viatra.runtime.matchers.context.IQueryMetaContext;
17import tools.refinery.viatra.runtime.matchers.psystem.ITypeConstraint;
18import tools.refinery.viatra.runtime.matchers.psystem.KeyedEnumerablePConstraint;
19import tools.refinery.viatra.runtime.matchers.psystem.PBody;
20import tools.refinery.viatra.runtime.matchers.psystem.PVariable;
21import tools.refinery.viatra.runtime.matchers.psystem.TypeJudgement;
22import tools.refinery.viatra.runtime.matchers.tuple.Tuple;
23
24/**
25 * Represents an enumerable type constraint that asserts that values substituted for the given tuple of variables
26 * form a tuple that belongs to an enumerable extensional relation identified by an {@link IInputKey}.
27 *
28 * <p> The InputKey must be enumerable!
29 *
30 * @author Zoltan Ujhelyi
31 *
32 */
33public class TypeConstraint extends KeyedEnumerablePConstraint<IInputKey> implements ITypeConstraint {
34
35 private TypeJudgement equivalentJudgement;
36
37 public TypeConstraint(PBody pBody, Tuple variablesTuple, IInputKey inputKey) {
38 super(pBody, variablesTuple, inputKey);
39 this.equivalentJudgement = new TypeJudgement(inputKey, variablesTuple);
40
41 if (! inputKey.isEnumerable())
42 throw new IllegalArgumentException(
43 this.getClass().getSimpleName() +
44 " applicable for enumerable input keys only; received instead " +
45 inputKey);
46 if (variablesTuple.getSize() != inputKey.getArity())
47 throw new IllegalArgumentException(
48 this.getClass().getSimpleName() +
49 " applied for variable tuple " + variablesTuple + " having wrong arity for input key " +
50 inputKey);
51 }
52
53 @Override
54 protected String keyToString() {
55 return supplierKey.getPrettyPrintableName();
56 }
57
58 @Override
59 public TypeJudgement getEquivalentJudgement() {
60 return equivalentJudgement;
61 }
62
63 @Override
64 public Set<TypeJudgement> getImpliedJudgements(IQueryMetaContext context) {
65 return Collections.singleton(equivalentJudgement);
66 //return equivalentJudgement.getDirectlyImpliedJudgements(context);
67 }
68
69 @Override
70 public Map<Set<PVariable>, Set<PVariable>> getFunctionalDependencies(IQueryMetaContext context) {
71 return TypeConstraintUtil.getFunctionalDependencies(context, supplierKey, variablesTuple);
72 }
73
74 @Override
75 public void doReplaceVariable(PVariable obsolete, PVariable replacement) {
76 super.doReplaceVariable(obsolete, replacement);
77 this.equivalentJudgement = new TypeJudgement(getSupplierKey(), variablesTuple);
78 }
79} \ No newline at end of file
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/queries/BasePQuery.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/queries/BasePQuery.java
new file mode 100644
index 00000000..2c03a894
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/queries/BasePQuery.java
@@ -0,0 +1,231 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Bergmann Gabor, 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.matchers.psystem.queries;
10
11import java.util.ArrayList;
12import java.util.Collections;
13import java.util.HashSet;
14import java.util.List;
15import java.util.Objects;
16import java.util.Optional;
17import java.util.Set;
18import java.util.stream.Collectors;
19import java.util.stream.Stream;
20
21import tools.refinery.viatra.runtime.matchers.ViatraQueryRuntimeException;
22import tools.refinery.viatra.runtime.matchers.backend.IQueryBackendFactory;
23import tools.refinery.viatra.runtime.matchers.backend.QueryEvaluationHint;
24import tools.refinery.viatra.runtime.matchers.context.IInputKey;
25import tools.refinery.viatra.runtime.matchers.psystem.PBody;
26import tools.refinery.viatra.runtime.matchers.psystem.TypeJudgement;
27import tools.refinery.viatra.runtime.matchers.psystem.annotations.PAnnotation;
28import tools.refinery.viatra.runtime.matchers.tuple.Tuples;
29import tools.refinery.viatra.runtime.matchers.util.Preconditions;
30
31/**
32 * Default implementation of PQuery.
33 *
34 * @author Bergmann Gabor
35 */
36public abstract class BasePQuery implements PQuery {
37
38 protected PQueryStatus status = PQueryStatus.UNINITIALIZED;
39 /**
40 * @since 2.0
41 */
42 protected final PVisibility visibility;
43 protected List<PProblem> pProblems = new ArrayList<PProblem>();
44 private List<PAnnotation> annotations = new ArrayList<PAnnotation>();
45 private QueryEvaluationHint evaluationHints = new QueryEvaluationHint(null, (IQueryBackendFactory)null);
46 PDisjunction canonicalDisjunction;
47 private List<String> parameterNames = null; // Lazy initialization
48
49 /** For traceability only. */
50 private List<Object> wrappingQuerySpecifications = new ArrayList<Object>(1);
51
52 @Override
53 public Integer getPositionOfParameter(String parameterName) {
54 ensureInitialized();
55 int index = getParameterNames().indexOf(parameterName);
56 return index != -1 ? index : null;
57 }
58
59 protected void setStatus(PQueryStatus newStatus) {
60 this.status = newStatus;
61 }
62
63 protected void addError(PProblem problem) {
64 status = PQueryStatus.ERROR;
65 pProblems.add(problem);
66 }
67
68 @Override
69 public PQueryStatus getStatus() {
70 return status;
71 }
72
73 @Override
74 public List<PProblem> getPProblems() {
75 return Collections.unmodifiableList(pProblems);
76 }
77
78 @Override
79 public boolean isMutable() {
80 return status.equals(PQueryStatus.UNINITIALIZED) || status.equals(PQueryStatus.INITIALIZING);
81 }
82
83 @Override
84 public void checkMutability() {
85 Preconditions.checkState(isMutable(), "Cannot edit query definition %s", getFullyQualifiedName());
86 }
87
88 /**
89 * @since 1.5
90 */
91 public void setEvaluationHints(QueryEvaluationHint hints) {
92 checkMutability();
93 this.evaluationHints = hints;
94 }
95
96 @Override
97 public QueryEvaluationHint getEvaluationHints() {
98 ensureInitialized();
99 return evaluationHints;
100 // TODO instead of field, compute something from annotations?
101 }
102
103 protected void addAnnotation(PAnnotation annotation) {
104 checkMutability();
105 annotations.add(annotation);
106 }
107
108 @Override
109 public List<PAnnotation> getAllAnnotations() {
110 ensureInitialized();
111 return new ArrayList<>(annotations);
112 }
113
114 private Stream<PAnnotation> getAnnotationStreamByName(final String name) {
115 ensureInitialized();
116 return annotations.stream().filter(Objects::nonNull).filter(annotation -> Objects.equals(name, annotation.getName()));
117 }
118
119 @Override
120 public List<PAnnotation> getAnnotationsByName(final String annotationName) {
121 return getAnnotationStreamByName(annotationName).collect(Collectors.toList());
122 }
123
124 @Override
125 public Optional<PAnnotation> getFirstAnnotationByName(String annotationName) {
126 return getAnnotationStreamByName(annotationName).findFirst();
127 }
128
129 @Override
130 public List<String> getParameterNames() {
131 ensureInitialized();
132 if (parameterNames == null) {
133 parameterNames = getParameters().stream().map(PParameter::getName).collect(Collectors.toList());
134 }
135 return parameterNames;
136 }
137
138 @Override
139 public Set<PQuery> getDirectReferredQueries() {
140 ensureInitialized();
141 return canonicalDisjunction.getDirectReferredQueries();
142 }
143
144 @Override
145 public Set<PQuery> getAllReferredQueries() {
146 ensureInitialized();
147 return canonicalDisjunction.getAllReferredQueries();
148 }
149
150
151 @Override
152 public List<Object> publishedAs() {
153 return wrappingQuerySpecifications;
154 }
155
156 @Override
157 public Set<TypeJudgement> getTypeGuarantees() {
158 ensureInitialized();
159 Set<TypeJudgement> result = new HashSet<TypeJudgement>();
160
161 List<PParameter> parameters = getParameters();
162 for (int i=0; i<parameters.size(); ++i) {
163 PParameter parameter = parameters.get(i);
164 IInputKey declaredUnaryType = parameter.getDeclaredUnaryType();
165 if (declaredUnaryType != null) {
166 result.add(new TypeJudgement(declaredUnaryType, Tuples.staticArityFlatTupleOf(i)));
167 }
168 }
169
170 return result;
171 }
172
173 /**
174 * @since 2.0
175 */
176 public BasePQuery(PVisibility visibility) {
177 super();
178 this.visibility = visibility;
179 }
180
181 @Override
182 public PDisjunction getDisjunctBodies() {
183 ensureInitialized();
184 Preconditions.checkState(!status.equals(PQueryStatus.ERROR), "Query %s contains errors.", getFullyQualifiedName());
185 return canonicalDisjunction;
186 }
187
188 @Override
189 public final void ensureInitialized() {
190 try {
191 if (status.equals(PQueryStatus.UNINITIALIZED)) {
192 setStatus(PQueryStatus.INITIALIZING);
193 setBodies(doGetContainedBodies());
194 setStatus(PQueryStatus.OK);
195 }
196 } catch (QueryInitializationException e) {
197 addError(new PProblem(e, e.getShortMessage()));
198 throw e;
199 }
200 }
201
202 protected final void setBodies(Set<PBody> bodies) {
203 canonicalDisjunction = new PDisjunction(this, bodies);
204 for (PBody body : canonicalDisjunction.getBodies()) {
205 body.setStatus(null);
206 }
207 setStatus(PQueryStatus.OK);
208 }
209
210 /**
211 * Creates and returns the bodies of the query. If recalled again, a new instance is created.
212 *
213 * @return
214 * @throws ViatraQueryRuntimeException
215 */
216 protected abstract Set<PBody> doGetContainedBodies();
217
218 @Override
219 public String toString() {
220 return String.format("PQuery<%s>=%s", getFullyQualifiedName(), super.toString());
221 }
222
223 /**
224 * @since 2.0
225 */
226 @Override
227 public PVisibility getVisibility() {
228 return visibility;
229 }
230
231} \ No newline at end of file
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/queries/PDisjunction.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/queries/PDisjunction.java
new file mode 100644
index 00000000..eae4eacf
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/queries/PDisjunction.java
@@ -0,0 +1,104 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, 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.matchers.psystem.queries;
10
11import java.util.Collections;
12import java.util.LinkedHashSet;
13import java.util.Set;
14import java.util.stream.Collectors;
15
16import tools.refinery.viatra.runtime.matchers.psystem.PBody;
17
18/**
19 *
20 * A disjunction is a set of bodies representing separate conditions. A {@link PQuery} has a single, canonical
21 * PDisjunction, that can be replaced using rewriter
22 *
23 * @author Zoltan Ujhelyi
24 *
25 */
26public class PDisjunction {
27
28 private Set<PBody> bodies;
29 private PQuery query;
30
31 public PDisjunction(Set<PBody> bodies) {
32 this(bodies.iterator().next().getPattern(), bodies);
33 }
34
35 public PDisjunction(PQuery query, Set<PBody> bodies) {
36 super();
37 this.query = query;
38 this.bodies = Collections.unmodifiableSet(new LinkedHashSet<>(bodies));
39 this.bodies.forEach(body -> body.setContainerDisjunction(this));
40 }
41
42 /**
43 * Returns an immutable set of bodies that consists of this disjunction
44 *
45 * @return the bodies
46 */
47 public Set<PBody> getBodies() {
48 return bodies;
49 }
50
51 /**
52 * Returns the corresponding query specification. May be null if not set.
53 */
54 public PQuery getQuery() {
55 return query;
56 }
57
58 /**
59 * Returns all queries directly referred in the constraints. They are all required to evaluate this query
60 *
61 * @return a non-null, but possibly empty list of query definitions
62 */
63 public Set<PQuery> getDirectReferredQueries() {
64 return this.getBodies().stream().
65 flatMap(PQueries.directlyReferencedQueriesFunction()). // flatten stream of streams
66 collect(Collectors.toCollection(LinkedHashSet::new));
67 }
68
69 /**
70 * Returns all queries required to evaluate this query (transitively).
71 *
72 * @return a non-null, but possibly empty list of query definitions
73 */
74 public Set<PQuery> getAllReferredQueries() {
75 Set<PQuery> processedQueries = new LinkedHashSet<>();
76 processedQueries.add(this.getQuery());
77 Set<PQuery> foundQueries = getDirectReferredQueries();
78 Set<PQuery> newQueries = new LinkedHashSet<>(foundQueries);
79
80 while(!processedQueries.containsAll(newQueries)) {
81 PQuery query = newQueries.iterator().next();
82 processedQueries.add(query);
83 newQueries.remove(query);
84 Set<PQuery> referred = query.getDirectReferredQueries();
85 referred.removeAll(processedQueries);
86 foundQueries.addAll(referred);
87 newQueries.addAll(referred);
88 }
89 return foundQueries;
90 }
91
92 /**
93 * Decides whether a disjunction is mutable. A disjunction is mutable if all its contained bodies are mutable.
94 *
95 */
96 public boolean isMutable() {
97 for (PBody body : bodies) {
98 if (!body.isMutable()) {
99 return false;
100 }
101 }
102 return true;
103 }
104}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/queries/PParameter.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/queries/PParameter.java
new file mode 100644
index 00000000..07165aa2
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/queries/PParameter.java
@@ -0,0 +1,105 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, 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.matchers.psystem.queries;
10
11import java.util.Objects;
12
13import tools.refinery.viatra.runtime.matchers.context.IInputKey;
14
15/**
16 * A descriptor for declared PQuery parameters. A parameter has a name, a declared type and a direction constraint
17 *
18 * @author Zoltan Ujhelyi
19 *
20 */
21public class PParameter {
22
23 private final String name;
24 private final String typeName;
25 private final IInputKey declaredUnaryType;
26 private final PParameterDirection direction;
27
28 public PParameter(String name) {
29 this(name, (String) null);
30 }
31
32 public PParameter(String name, String typeName) {
33 this(name, typeName, (IInputKey) null);
34 }
35
36 public PParameter(String name, String typeName, IInputKey declaredUnaryType) {
37 this(name, typeName, declaredUnaryType, PParameterDirection.INOUT);
38 }
39
40 /**
41 * @since 1.4
42 */
43 public PParameter(String name, String typeName, IInputKey declaredUnaryType, PParameterDirection direction) {
44 super();
45 this.name = name;
46 this.typeName = typeName;
47 this.declaredUnaryType = declaredUnaryType;
48 this.direction = direction;
49
50 if (declaredUnaryType != null && declaredUnaryType.getArity() != 1) {
51 throw new IllegalArgumentException(
52 "PParameter declared type must be unary instead of " + declaredUnaryType.getPrettyPrintableName());
53 }
54 }
55
56 /**
57 * @return the direction
58 * @since 1.4
59 */
60 public PParameterDirection getDirection() {
61 return direction;
62 }
63
64 /**
65 * @return the name of the parameter
66 */
67 public String getName() {
68 return name;
69 }
70
71 /**
72 * Returns a textual representation of the declared type of the parameter
73 *
74 * @return the type description, or null if not available
75 */
76 public String getTypeName() {
77 return typeName;
78 }
79
80 /**
81 * Yield an {@link IInputKey} representation of the type declared for this parameter.
82 *
83 * @return the unary type that was declared on this parameter in the query header, or null if not available
84 */
85 public IInputKey getDeclaredUnaryType() {
86 return declaredUnaryType;
87 }
88
89 @Override
90 public boolean equals(Object obj) {
91 if (obj instanceof PParameter) {
92 return Objects.equals(name, ((PParameter) obj).name)
93 && Objects.equals(typeName, ((PParameter) obj).typeName)
94 && Objects.equals(declaredUnaryType, ((PParameter) obj).declaredUnaryType)
95 && Objects.equals(direction, ((PParameter) obj).direction);
96 }
97 return false;
98 }
99
100 @Override
101 public int hashCode() {
102 return Objects.hash(name, typeName, declaredUnaryType);
103 }
104
105}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/queries/PParameterDirection.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/queries/PParameterDirection.java
new file mode 100644
index 00000000..c94d4797
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/queries/PParameterDirection.java
@@ -0,0 +1,35 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Grill Balázs, IncQueryLabs
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.matchers.psystem.queries;
10
11/**
12 * Values of this enum describe a constraint to the calling of patterns regarding its parameters.
13 *
14 * @author Grill Balázs
15 * @since 1.4
16 *
17 */
18public enum PParameterDirection {
19
20 /**
21 * Default value, no additional constraint is applied
22 */
23 INOUT,
24
25 /**
26 * The parameters marked with this constraints shall be set to a value before calling the pattern
27 */
28 IN,
29
30 /**
31 * The parameters marked with this constraints shall not be set to a value before calling the pattern
32 */
33 OUT
34
35}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/queries/PProblem.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/queries/PProblem.java
new file mode 100644
index 00000000..1fe4f541
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/queries/PProblem.java
@@ -0,0 +1,68 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Bergmann Gabor, 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.matchers.psystem.queries;
10
11import tools.refinery.viatra.runtime.matchers.planning.QueryProcessingException;
12
13/**
14 * Represents an error that was detected while the {@link PQuery} object was built from a source.
15 * @author Bergmann Gabor
16 *
17 */
18public class PProblem {
19
20 private final String shortMessage;
21 private final String location;
22 private final Exception exception;
23
24 public PProblem(String shortMessage) {
25 this(null, shortMessage, null, null);
26 }
27 /**
28 * @since 2.0
29 */
30 public PProblem(String shortMessage, Integer line, Integer column) {
31 this(null, shortMessage, line, column);
32 }
33 public PProblem(QueryProcessingException exception) {
34 this(exception, exception.getShortMessage(), null, null);
35 }
36 public PProblem(Exception exception, String shortMessage) {
37 this(exception, shortMessage, null, null);
38 }
39
40 /**
41 * @since 2.0
42 */
43 public PProblem(Exception exception, String shortMessage, Integer line, Integer column) {
44 this.shortMessage = shortMessage;
45 this.exception = exception;
46 if (line == null) {
47 location = "Unspecified location";
48 } else if (column == null) {
49 location = String.format("Line %d", line);
50 } else {
51 location = String.format("Line %d Column %d", line, column);
52 }
53 }
54
55 public String getShortMessage() {
56 return shortMessage;
57 }
58 public Exception getException() {
59 return exception;
60 }
61 /**
62 * @since 2.0
63 */
64 public String getLocation() {
65 return location;
66 }
67
68}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/queries/PQueries.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/queries/PQueries.java
new file mode 100644
index 00000000..56f8ca76
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/queries/PQueries.java
@@ -0,0 +1,110 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, 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.matchers.psystem.queries;
10
11import java.util.HashSet;
12import java.util.Set;
13import java.util.function.Function;
14import java.util.function.Predicate;
15import java.util.stream.Stream;
16
17import tools.refinery.viatra.runtime.matchers.context.IInputKey;
18import tools.refinery.viatra.runtime.matchers.psystem.IMultiQueryReference;
19import tools.refinery.viatra.runtime.matchers.psystem.ITypeConstraint;
20import tools.refinery.viatra.runtime.matchers.psystem.PBody;
21import tools.refinery.viatra.runtime.matchers.psystem.PTraceable;
22import tools.refinery.viatra.runtime.matchers.psystem.basicenumerables.TypeConstraint;
23import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery.PQueryStatus;
24
25/**
26 * Utility class for using PQueries in functional/streaming collection operations effectively
27 *
28 * @author Zoltan Ujhelyi
29 *
30 */
31public final class PQueries {
32
33 /**
34 * Hidden constructor for utility class
35 */
36 private PQueries() {
37 }
38
39 /**
40 * Predicate checking for the status of selected queries
41 *
42 */
43 public static Predicate<PQuery> queryStatusPredicate(final PQueryStatus status) {
44 return query -> query.getStatus().equals(status);
45 }
46
47 /**
48 * Enumerates referred queries (without duplicates) for the given body
49 */
50 public static Function<PBody, Stream<PQuery>> directlyReferencedQueriesFunction() {
51 return body -> (body.getConstraintsOfType(IMultiQueryReference.class).stream()
52 .flatMap(e -> e.getReferredQueries().stream()).distinct());
53 }
54
55 /**
56 * Enumerates directly referred extensional relations (without duplicates) in the canonical form of the given query
57 *
58 * @param enumerablesOnly
59 * only enumerable type constraints are considered
60 * @since 2.0
61 */
62 public static Stream<IInputKey> directlyRequiredTypesOfQuery(PQuery query, boolean enumerablesOnly) {
63 return directlyRequiredTypesOfDisjunction(query.getDisjunctBodies(), enumerablesOnly);
64 }
65
66 /**
67 * Enumerates directly referred extensional relations (without duplicates) for the given formulation of a query.
68 *
69 * @param enumerablesOnly
70 * only enumerable type constraints are considered
71 * @since 2.0
72 */
73 public static Stream<IInputKey> directlyRequiredTypesOfDisjunction(PDisjunction disjunctBodies,
74 boolean enumerablesOnly) {
75 Class<? extends ITypeConstraint> filterClass = enumerablesOnly ? TypeConstraint.class : ITypeConstraint.class;
76 return disjunctBodies.getBodies().stream().flatMap(body -> body.getConstraintsOfType(filterClass).stream())
77 .map(constraint -> constraint.getEquivalentJudgement().getInputKey()).distinct();
78 }
79
80 /**
81 * @since 1.4
82 */
83 public static Predicate<PParameter> parameterDirectionPredicate(final PParameterDirection direction) {
84 return input -> input.getDirection() == direction;
85 }
86
87 /**
88 * Returns all {@link PTraceable}s contained in the given {@link PQuery}: itself, its bodies and their constraints.
89 *
90 * @since 1.6
91 */
92 public static Set<PTraceable> getTraceables(PQuery query) {
93 final Set<PTraceable> traceables = new HashSet<>();
94 traceables.add(query);
95 query.getDisjunctBodies().getBodies().forEach(body -> {
96 traceables.add(body);
97 body.getConstraints().forEach(traceables::add);
98 });
99 return traceables;
100 }
101
102 /**
103 * Calculates the simple name related from a given qualified name by finding the part after the last '.' character.
104 *
105 * @since 2.0
106 */
107 public static String calculateSimpleName(String qualifiedName) {
108 return qualifiedName.substring(qualifiedName.lastIndexOf('.') + 1);
109 }
110}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/queries/PQuery.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/queries/PQuery.java
new file mode 100644
index 00000000..a909c650
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/queries/PQuery.java
@@ -0,0 +1,154 @@
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.matchers.psystem.queries;
10
11import java.util.List;
12import java.util.Set;
13
14import tools.refinery.viatra.runtime.matchers.ViatraQueryRuntimeException;
15import tools.refinery.viatra.runtime.matchers.backend.IQueryBackend;
16import tools.refinery.viatra.runtime.matchers.backend.IQueryBackendHintProvider;
17import tools.refinery.viatra.runtime.matchers.backend.QueryEvaluationHint;
18import tools.refinery.viatra.runtime.matchers.psystem.PBody;
19import tools.refinery.viatra.runtime.matchers.psystem.PTraceable;
20import tools.refinery.viatra.runtime.matchers.psystem.TypeJudgement;
21
22/**
23 * Internal representation of a query / graph pattern (using a constraint system formalism),
24 * to be interpreted by a query evaluator ({@link IQueryBackend}).
25 * End-users of VIATRA Query should access a query as an IQuerySpecification instead.
26 *
27 * <p>
28 * PQuerys are definitions of queries usable inside pattern descriptions. Such description always has (a non-null) name. The query
29 * itself is defined as a (non-empty) set of {@link PBody} instances, the result is the disjunction of the single
30 * {@link PBody} instances. </p>
31 * <p>
32 * A PQuery might be constructed from erroneous patterns or might be uninitialized - this is represented by its status.
33 *
34 * @author Zoltan Ujhelyi
35 * @since 0.8.0
36 * @noimplement This interface is not intended to be implemented by clients. Use {@link BasePQuery} as a base class instead.
37 */
38public interface PQuery extends PQueryHeader, PTraceable {
39
40 // TODO rewritten as / rewritten from traceability to PDisjunction?
41
42 /**
43 * @author Zoltan Ujhelyi
44 *
45 */
46 public enum PQueryStatus {
47 /**
48 * Marks that the query definition is not initialized
49 */
50 UNINITIALIZED,
51 /**
52 * Marks that the query definition is being initialized
53 * @since 1.4
54 */
55 INITIALIZING,
56 /**
57 * The query definition was successfully initialized
58 */
59 OK,
60 /**
61 * The query definition was initialized, but some issues were present
62 */
63 WARNING,
64 /**
65 * The query definition was not successfully initialized because of an error
66 */
67 ERROR
68 }
69
70 /**
71 * Returns all bodies associated with the query in their canonical form. If called multiple times, the same set with
72 * the same contents will be returned.
73 *
74 */
75 PDisjunction getDisjunctBodies();
76
77 /**
78 * Returns all queries directly referred in the constraints. They are all required to evaluate this query
79 *
80 * @return a non-null, but possibly empty list of query definitions
81 */
82 Set<PQuery> getDirectReferredQueries();
83
84 /**
85 * Returns all queries required to evaluate this query (transitively).
86 *
87 * @return a non-null, but possibly empty list of query definitions
88 */
89 Set<PQuery> getAllReferredQueries();
90
91 /**
92 * Returns the initialization status of the definition
93 *
94 */
95 PQueryStatus getStatus();
96
97 /**
98 * Returns a list describing the problems that were found in this query.
99 *
100 * <p> TODO: formulate invariant connecting {@link #getPProblems()} and {@link #getStatus()}.
101 *
102 * @return a non-null, but possibly empty list of problems
103 */
104 List<PProblem> getPProblems();
105
106 /**
107 * Before a modification operation is executed, a mutability check is performed (via the {@link #getStatus()}
108 * implementation, and in case of problems an {@link IllegalStateException} is thrown.
109 */
110 void checkMutability();
111
112 /**
113 * An option to check mutability of the query. It can be used to avoid getting an {@link IllegalStateException} by
114 * the execution of {@link #checkMutability()}.
115 *
116 * @return true if the query specification is still editable
117 */
118 boolean isMutable();
119
120 /**
121 * Optional hints regarding the query evaluation strategy, to be interpreted by the query engine.
122 * <p> To ensure the possibility of external overrides,
123 * the evaluation engine should not directly consult this field,
124 * but use an {@link IQueryBackendHintProvider} instead.
125 */
126 public QueryEvaluationHint getEvaluationHints();
127
128
129 /**
130 * Type information, expressed on query parameters, that all matches of the query are guaranteed to respect.
131 * <p> At the very minimum, this should include the declared types of the parameters.
132 * <p> The type judgement tuples shall contain the <i>parameter index</i>, NOT the {@link PParameter} object.
133 *
134 * @return a non-null set of type judgements that the query guarantees for its matches
135 */
136 public Set<TypeJudgement> getTypeGuarantees();
137
138 /**
139 * If the query definition is uninitialized, initializes it.
140 * @throws ViatraQueryRuntimeException if initialization of query specification fails
141 */
142 public abstract void ensureInitialized();
143
144 /**
145 * Returns the end-user query specification API objects that wrap this query.
146 *
147 * <p> Intended for traceability and debug purposes, not part of normal operation.
148 * Returned list is intended to be appended during query specification construction time.
149 *
150 * @return a non-null, but possibly empty list of query specification objects;
151 */
152 List<Object> publishedAs();
153
154} \ No newline at end of file
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/queries/PQueryHeader.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/queries/PQueryHeader.java
new file mode 100644
index 00000000..f3671934
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/queries/PQueryHeader.java
@@ -0,0 +1,101 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Bergmann Gabor, 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.matchers.psystem.queries;
10
11import java.util.List;
12import java.util.Optional;
13
14import tools.refinery.viatra.runtime.matchers.psystem.annotations.PAnnotation;
15
16/**
17 * Represents header information (metainfo) about a query.
18 * <p> To be implemented both by IQuerySpecifications intended for end users,
19 * and the internal query representation {@link PQuery}.
20 *
21 *
22 * @author Bergmann Gabor
23 * @since 0.9
24 */
25public interface PQueryHeader {
26
27 /**
28 * Identifies the pattern for which matchers can be instantiated.
29 */
30 public String getFullyQualifiedName();
31
32 /**
33 * Return the list of parameter names
34 *
35 * @return a non-null, but possibly empty list of parameter names
36 */
37 public List<String> getParameterNames();
38
39 /**
40 * Returns a list of parameter descriptions
41 *
42 * @return a non-null, but possibly empty list of parameter descriptions
43 */
44 public List<PParameter> getParameters();
45
46 /**
47 * Returns the index of a named parameter
48 *
49 * @param parameterName
50 * @return the index, or null of no such parameter is available
51 */
52 public Integer getPositionOfParameter(String parameterName);
53
54 /**
55 * Returns a parameter by name if exists
56 * @since 2.1
57 */
58 default Optional<PParameter> getParameter(String parameterName) {
59 return Optional.ofNullable(getPositionOfParameter(parameterName))
60 .map(getParameters()::get);
61 }
62
63 /**
64 * Returns the list of annotations specified for this query
65 *
66 * @return a non-null, but possibly empty list of annotations
67 */
68 public List<PAnnotation> getAllAnnotations();
69
70 /**
71 * Returns the list of annotations with a specified name
72 *
73 * @param annotationName
74 * @return a non-null, but possibly empty list of annotations
75 */
76 public List<PAnnotation> getAnnotationsByName(String annotationName);
77
78 /**
79 * Returns the first annotation with a specified name
80 *
81 * @since 2.0
82 */
83 public Optional<PAnnotation> getFirstAnnotationByName(String annotationName);
84
85 /**
86 * Returns the visibility information about the query.
87 * @since 2.0
88 */
89 public PVisibility getVisibility();
90
91 /**
92 * Returns the non-qualified name of the query. By default this means returning the qualified name after the last
93 * '.' character.
94 *
95 * @since 2.0
96 */
97 public default String getSimpleName() {
98 return PQueries.calculateSimpleName(getFullyQualifiedName());
99 }
100
101} \ No newline at end of file
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/queries/PVisibility.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/queries/PVisibility.java
new file mode 100644
index 00000000..7cb312bd
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/queries/PVisibility.java
@@ -0,0 +1,37 @@
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.matchers.psystem.queries;
10
11/**
12 * @author Zoltan Ujhelyi
13 * @since 2.0
14 *
15 */
16public enum PVisibility {
17
18 /**
19 * A public (default) visibility means a pattern can be called at any time.
20 */
21 PUBLIC,
22 /**
23 * A private query is not expected to be called directly, only by a different query matcher.
24 */
25 PRIVATE,
26 /**
27 * A query that is only used inside a single caller query and is not visible outside its container query. Such
28 * patterns must also fulfill the following additional constraints:
29 *
30 * <ul>
31 * <li>An embedded query must have only a single body.</li>
32 * <li>An embedded query must not be recursice.</li>
33 * </ul>
34 */
35 EMBEDDED
36
37}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/queries/QueryInitializationException.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/queries/QueryInitializationException.java
new file mode 100644
index 00000000..470d7287
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/queries/QueryInitializationException.java
@@ -0,0 +1,35 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Bergmann Gabor, 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.matchers.psystem.queries;
10
11import tools.refinery.viatra.runtime.matchers.planning.QueryProcessingException;
12
13/**
14 * Represent an exception that occurred while initializing the specification of a query.
15 * @author Bergmann Gabor
16 * @since 0.9
17 *
18 */
19public class QueryInitializationException extends QueryProcessingException {
20
21 public QueryInitializationException(String message, String[] context, String shortMessage, Object patternDescription,
22 Throwable cause) {
23 super(message, context, shortMessage, patternDescription, cause);
24 }
25
26 public QueryInitializationException(String message, String[] context, String shortMessage, Object patternDescription) {
27 super(message, context, shortMessage, patternDescription);
28 }
29
30 private static final long serialVersionUID = 9106033062252951489L;
31
32
33
34
35}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/AbstractRewriterTraceSource.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/AbstractRewriterTraceSource.java
new file mode 100644
index 00000000..276b2b42
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/AbstractRewriterTraceSource.java
@@ -0,0 +1,53 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2017, Grill Balázs, IncQueryLabs
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.matchers.psystem.rewriters;
10
11import java.util.Objects;
12
13import tools.refinery.viatra.runtime.matchers.psystem.PConstraint;
14import tools.refinery.viatra.runtime.matchers.psystem.PTraceable;
15
16/**
17 * @since 1.6
18 *
19 */
20public class AbstractRewriterTraceSource {
21
22 private IRewriterTraceCollector traceCollector = NopTraceCollector.INSTANCE;
23
24 public void setTraceCollector(IRewriterTraceCollector traceCollector) {
25 this.traceCollector = Objects.requireNonNull(traceCollector);
26 }
27
28 public IPTraceableTraceProvider getTraces() {
29 return traceCollector;
30 }
31
32 protected IRewriterTraceCollector getTraceCollector() {
33 return traceCollector;
34 }
35
36 /**
37 * Mark the given derivative to be originated from the given original constraint.
38 * @since 1.6
39 */
40 protected void addTrace(PTraceable original, PTraceable derivative){
41 traceCollector.addTrace(original, derivative);
42 }
43
44 /**
45 * Indicate that the given derivative is removed from the resulting query, thus its trace
46 * information should be removed also.
47 * @since 1.6
48 */
49 protected void derivativeRemoved(PConstraint derivative, IDerivativeModificationReason reason){
50 traceCollector.derivativeRemoved(derivative, reason);
51 }
52
53}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/ConstraintRemovalReason.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/ConstraintRemovalReason.java
new file mode 100644
index 00000000..237a762d
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/ConstraintRemovalReason.java
@@ -0,0 +1,23 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2017, Grill Balázs, IncQueryLabs
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.matchers.psystem.rewriters;
10
11/**
12 * Common reasons for removing constraint through rewriters
13 *
14 * @noreference This enum is not intended to be referenced by clients.
15 */
16public enum ConstraintRemovalReason implements IDerivativeModificationReason {
17
18 MOOT_EQUALITY,
19 WEAK_INEQUALITY_SELF_LOOP,
20 TYPE_SUBSUMED,
21 DUPLICATE
22
23}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/DefaultFlattenCallPredicate.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/DefaultFlattenCallPredicate.java
new file mode 100644
index 00000000..3b5d7390
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/DefaultFlattenCallPredicate.java
@@ -0,0 +1,23 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Marton Bur, Zoltan Ujhelyi, Akos Horvath, 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.matchers.psystem.rewriters;
10import tools.refinery.viatra.runtime.matchers.psystem.basicenumerables.PositivePatternCall;
11
12/**
13 * @author Marton Bur
14 *
15 */
16public class DefaultFlattenCallPredicate implements IFlattenCallPredicate {
17
18 @Override
19 public boolean shouldFlatten(PositivePatternCall positivePatternCall) {
20 return true;
21 }
22
23}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/FlattenerCopier.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/FlattenerCopier.java
new file mode 100644
index 00000000..06b8d372
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/FlattenerCopier.java
@@ -0,0 +1,129 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Marton Bur, Akos Horvath, 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.matchers.psystem.rewriters;
10
11import java.util.HashMap;
12import java.util.List;
13import java.util.Map;
14import java.util.Map.Entry;
15import java.util.Objects;
16import java.util.Set;
17import java.util.stream.Collectors;
18
19import tools.refinery.viatra.runtime.matchers.psystem.PBody;
20import tools.refinery.viatra.runtime.matchers.psystem.PConstraint;
21import tools.refinery.viatra.runtime.matchers.psystem.PVariable;
22import tools.refinery.viatra.runtime.matchers.psystem.basicdeferred.Equality;
23import tools.refinery.viatra.runtime.matchers.psystem.basicdeferred.ExportedParameter;
24import tools.refinery.viatra.runtime.matchers.psystem.basicdeferred.ExpressionEvaluation;
25import tools.refinery.viatra.runtime.matchers.psystem.basicenumerables.PositivePatternCall;
26import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery;
27import tools.refinery.viatra.runtime.matchers.util.Preconditions;
28
29/**
30 * This rewriter class can add new equality constraints to the copied body
31 *
32 * @author Marton Bur
33 *
34 */
35class FlattenerCopier extends PBodyCopier {
36
37 private final Map<PositivePatternCall, CallInformation> calls;
38
39 private static class CallInformation {
40 final PBody body;
41 final Map<PVariable, PVariable> variableMapping;
42
43 private CallInformation(PBody body) {
44 this.body = body;
45 this.variableMapping = new HashMap<>();
46 }
47 }
48
49 public FlattenerCopier(PQuery query, Map<PositivePatternCall, PBody> callsToFlatten) {
50 super(query);
51 this.calls = callsToFlatten.entrySet().stream().collect(Collectors.toMap(Entry::getKey, entry -> new CallInformation(entry.getValue())));
52 }
53
54 protected void copyVariable(PositivePatternCall contextPatternCall, PVariable variable, String newName) {
55 PVariable newPVariable = body.getOrCreateVariableByName(newName);
56 calls.get(contextPatternCall).variableMapping.put(variable, newPVariable);
57 variableMapping.put(variable, newPVariable);
58 }
59
60 /**
61 * Merge all variables and constraints from the body called through the given pattern call to a target body. If
62 * multiple bodies are merged into a single one, use the renamer and filter options to avoid collisions.
63 *
64 * @param sourceBody
65 * @param namingTool
66 * @param filter
67 */
68 public void mergeBody(PositivePatternCall contextPatternCall, IVariableRenamer namingTool,
69 IConstraintFilter filter) {
70
71 PBody sourceBody = calls.get(contextPatternCall).body;
72
73 // Copy variables
74 Set<PVariable> allVariables = sourceBody.getAllVariables();
75 for (PVariable pVariable : allVariables) {
76 if (pVariable.isUnique()) {
77 copyVariable(contextPatternCall, pVariable,
78 namingTool.createVariableName(pVariable, sourceBody.getPattern()));
79 }
80 }
81
82 // Copy constraints which are not filtered
83 Set<PConstraint> constraints = sourceBody.getConstraints();
84 for (PConstraint pConstraint : constraints) {
85 if (!(pConstraint instanceof ExportedParameter) && !filter.filter(pConstraint)) {
86 copyConstraint(pConstraint);
87 }
88 }
89 }
90
91 @Override
92 protected void copyPositivePatternCallConstraint(PositivePatternCall positivePatternCall) {
93
94 if (!calls.containsKey(positivePatternCall)) {
95 // If the call was not flattened, copy the constraint
96 super.copyPositivePatternCallConstraint(positivePatternCall);
97 } else {
98 PBody calledBody = Objects.requireNonNull(calls.get(positivePatternCall).body);
99 Preconditions.checkArgument(positivePatternCall.getReferredQuery().equals(calledBody.getPattern()));
100
101 List<PVariable> symbolicParameters = calledBody.getSymbolicParameterVariables();
102 Object[] elements = positivePatternCall.getVariablesTuple().getElements();
103 for (int i = 0; i < elements.length; i++) {
104 // Create equality constraints between the caller PositivePatternCall and the corresponding body
105 // parameter variables
106 createEqualityConstraint((PVariable) elements[i], symbolicParameters.get(i), positivePatternCall);
107 }
108
109 }
110 }
111
112 private void createEqualityConstraint(PVariable pVariable1, PVariable pVariable2,
113 PositivePatternCall contextPatternCall) {
114 PVariable who = variableMapping.get(pVariable1);
115 PVariable withWhom = calls.get(contextPatternCall).variableMapping.get(pVariable2);
116 addTrace(contextPatternCall, new Equality(body, who, withWhom));
117 }
118
119 @Override
120 protected void copyExpressionEvaluationConstraint(final ExpressionEvaluation expressionEvaluation) {
121 Map<PVariable, PVariable> variableMapping = this.variableMapping.entrySet().stream()
122 .filter(input -> expressionEvaluation.getPSystem().getAllVariables().contains(input.getKey()))
123 .collect(Collectors.toMap(Entry::getKey, Entry::getValue));
124
125 PVariable mappedOutputVariable = variableMapping.get(expressionEvaluation.getOutputVariable());
126 addTrace(expressionEvaluation, new ExpressionEvaluation(body, new VariableMappingExpressionEvaluatorWrapper(expressionEvaluation.getEvaluator(), variableMapping), mappedOutputVariable, expressionEvaluation.isUnwinding()));
127 }
128
129}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/IConstraintFilter.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/IConstraintFilter.java
new file mode 100644
index 00000000..518b9c64
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/IConstraintFilter.java
@@ -0,0 +1,48 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Zoltan Ujhelyi, Marton Bur, 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.matchers.psystem.rewriters;
10
11import tools.refinery.viatra.runtime.matchers.psystem.PConstraint;
12import tools.refinery.viatra.runtime.matchers.psystem.basicdeferred.ExportedParameter;
13
14/**
15 * Helper interface to exclude constraints from PBody copy processes
16 *
17 * @author Marton Bur
18 *
19 */
20public interface IConstraintFilter {
21 /**
22 * Returns true, if the given constraint should be filtered (thus should not be copied)
23 *
24 * @param constraint
25 * to check
26 * @return true, if the constraint should be filtered
27 */
28 boolean filter(PConstraint constraint);
29
30 public static class ExportedParameterFilter implements IConstraintFilter {
31
32 @Override
33 public boolean filter(PConstraint constraint) {
34 return constraint instanceof ExportedParameter;
35 }
36
37 }
38
39 public static class AllowAllFilter implements IConstraintFilter {
40
41 @Override
42 public boolean filter(PConstraint constraint) {
43 // Nothing is filtered
44 return false;
45 }
46
47 }
48} \ No newline at end of file
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/IDerivativeModificationReason.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/IDerivativeModificationReason.java
new file mode 100644
index 00000000..dbd6a78d
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/IDerivativeModificationReason.java
@@ -0,0 +1,19 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2017, Grill Balázs, IncQueryLabs
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.matchers.psystem.rewriters;
10
11/**
12 * This is a role indication interface, implementations may provide a reason about
13 * why a modification is made during PQuery normalization.
14 * @since 1.6
15 *
16 */
17public interface IDerivativeModificationReason {
18
19}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/IFlattenCallPredicate.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/IFlattenCallPredicate.java
new file mode 100644
index 00000000..7e224e98
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/IFlattenCallPredicate.java
@@ -0,0 +1,50 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Marton Bur, Zoltan Ujhelyi, Akos Horvath, 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.matchers.psystem.rewriters;
10
11import tools.refinery.viatra.runtime.matchers.psystem.basicenumerables.PositivePatternCall;
12
13
14/**
15 * Interface used by the PQueryFlattener to decide which positive pattern calls to flatten
16 *
17 * @author Marton Bur
18 *
19 */
20public interface IFlattenCallPredicate {
21
22 /**
23 * Decides whether the called query by the pattern call should be flattened into the caller or not.
24 *
25 * @param positivePatternCall
26 * the pattern call
27 * @return true if the call should be flattened
28 */
29 boolean shouldFlatten(PositivePatternCall positivePatternCall);
30
31 /**
32 * Flattens only if all operand predicates vote for flattening.
33 * @author Gabor Bergmann
34 * @since 2.1
35 */
36 public static class And implements IFlattenCallPredicate {
37 private IFlattenCallPredicate[] operands;
38 public And(IFlattenCallPredicate... operands) {
39 this.operands = operands;
40 }
41
42 @Override
43 public boolean shouldFlatten(PositivePatternCall positivePatternCall) {
44 for (IFlattenCallPredicate operand : operands) {
45 if (!operand.shouldFlatten(positivePatternCall)) return false;
46 }
47 return true;
48 }
49 }
50}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/IPTraceableTraceProvider.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/IPTraceableTraceProvider.java
new file mode 100644
index 00000000..84da4d1b
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/IPTraceableTraceProvider.java
@@ -0,0 +1,55 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2017, Grill Balázs, IncQueryLabs
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.matchers.psystem.rewriters;
10
11import java.util.stream.Stream;
12
13import tools.refinery.viatra.runtime.matchers.psystem.PTraceable;
14import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery;
15
16/**
17 * This interface provides methods to trace the {@link PTraceable}s of a transformed {@link PQuery} produced by
18 * a {@link PDisjunctionRewriter}. In case the associated rewriter is a composite (a.k.a. {@link PDisjunctionRewriterCacher}),
19 * this trace provider handles traces end-to-end, hiding all the intermediate transformation steps.
20 *
21 * @since 1.6
22 * @noimplement This interface is not intended to be implemented by clients.
23 */
24public interface IPTraceableTraceProvider {
25
26 /**
27 * Find and return the canonical {@link PTraceable}s in the original query which are the sources of the given derivative
28 * {@link PTraceable} according to the transformation.
29 *
30 * @param derivative a {@link PTraceable} which is contained by the {@link PQuery} produced by the associated rewriter
31 * @since 2.0
32 */
33 public Stream<PTraceable> getCanonicalTraceables(PTraceable derivative);
34
35 /**
36 * Find and return the {@link PTraceable}s in the rewritten query which are the destinations of the given source
37 * {@link PTraceable} according to the transformation.
38 *
39 * @param source a {@link PTraceable} which is contained by a {@link PQuery} before rewriting
40 * @since 2.0
41 */
42 public Stream<PTraceable> getRewrittenTraceables(PTraceable source);
43
44 /**
45 * Returns whether the given traceable element has been removed by every rewriter for a reason.
46 */
47 public boolean isRemoved(PTraceable traceable);
48
49 /**
50 * Returns the reasons for which the traceable element has been removed by the rewriters.
51 * @return the reasons of removal during rewriting
52 * @since 2.0
53 */
54 public Stream<IDerivativeModificationReason> getRemovalReasons(PTraceable traceable);
55}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/IRewriterTraceCollector.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/IRewriterTraceCollector.java
new file mode 100644
index 00000000..70771ea7
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/IRewriterTraceCollector.java
@@ -0,0 +1,33 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2017, Grill Balázs, IncQueryLabs
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.matchers.psystem.rewriters;
10
11import tools.refinery.viatra.runtime.matchers.psystem.PTraceable;
12
13/**
14 * This is the internal API of {@link IPTraceableTraceProvider} expected to be used by
15 * copier and rewriter implementations.
16 *
17 * @since 1.6
18 * @noreference This interface is not intended to be referenced by clients.
19 */
20public interface IRewriterTraceCollector extends IPTraceableTraceProvider {
21
22 /**
23 * Mark the given derivative to be originated from the given original constraint.
24 */
25 public void addTrace(PTraceable origin, PTraceable derivative);
26
27 /**
28 * Indicate that the given derivative is removed from the resulting query, thus its trace
29 * information should be removed also.
30 */
31 public void derivativeRemoved(PTraceable derivative, IDerivativeModificationReason reason);
32
33}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/IVariableRenamer.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/IVariableRenamer.java
new file mode 100644
index 00000000..ce446e0d
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/IVariableRenamer.java
@@ -0,0 +1,59 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Zoltan Ujhelyi, Marton Bur, 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.matchers.psystem.rewriters;
10
11import tools.refinery.viatra.runtime.matchers.psystem.PVariable;
12import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery;
13
14/**
15 * Helper interface to ease the naming of the new variables during flattening
16 *
17 * @author Marton Bur
18 *
19 */
20public interface IVariableRenamer {
21 /**
22 * Creates a variable name based on a given variable and a given query. It only creates a String, doesn't set
23 * anything.
24 *
25 * @param pVariable
26 * @param query
27 * @return the new variable name as a String
28 */
29 String createVariableName(PVariable pVariable, PQuery query);
30
31 public class SameName implements IVariableRenamer {
32 @Override
33 public String createVariableName(PVariable pVariable, PQuery query) {
34 return pVariable.getName();
35 }
36 }
37
38 public class HierarchicalName implements IVariableRenamer {
39
40 private int callCount;
41
42 public void setCallCount(int callCount) {
43 this.callCount = callCount;
44 }
45
46 @Override
47 public String createVariableName(PVariable pVariable, PQuery query) {
48 // make sure to keep the "_" prefix before anonymous variables
49 String newVarName = getShortName(query) + "<" + callCount + ">" + "_" + pVariable.getName();
50 return pVariable.getName().startsWith("_") ? "_" + newVarName : newVarName ;
51 }
52
53 private String getShortName(PQuery query) {
54 String fullyQualifiedName = query.getFullyQualifiedName();
55 int beginIndex = fullyQualifiedName.lastIndexOf('.') + 1;
56 return fullyQualifiedName.substring(beginIndex);
57 }
58 }
59} \ No newline at end of file
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/MappingTraceCollector.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/MappingTraceCollector.java
new file mode 100644
index 00000000..7429fc60
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/MappingTraceCollector.java
@@ -0,0 +1,135 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2017, Grill Balázs, IncQueryLabs
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.matchers.psystem.rewriters;
10
11import java.util.Collections;
12import java.util.HashMap;
13import java.util.HashSet;
14import java.util.LinkedList;
15import java.util.Map;
16import java.util.Queue;
17import java.util.Set;
18import java.util.function.Predicate;
19import java.util.stream.Stream;
20
21import tools.refinery.viatra.runtime.matchers.psystem.PTraceable;
22import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery;
23import tools.refinery.viatra.runtime.matchers.util.CollectionsFactory;
24import tools.refinery.viatra.runtime.matchers.util.CollectionsFactory.MemoryType;
25import tools.refinery.viatra.runtime.matchers.util.IMemoryView;
26import tools.refinery.viatra.runtime.matchers.util.IMultiLookup;
27import tools.refinery.viatra.runtime.matchers.util.Preconditions;
28
29/**
30 * Multimap-based implementation to contain and query traces
31 *
32 * @since 1.6
33 *
34 */
35public class MappingTraceCollector implements IRewriterTraceCollector {
36
37 /**
38 * Traces from derivative to original
39 */
40 private final IMultiLookup<PTraceable, PTraceable> traces = CollectionsFactory.createMultiLookup(Object.class, MemoryType.SETS, Object.class);
41
42 /**
43 * Traces from original to derivative
44 */
45 private final IMultiLookup<PTraceable, PTraceable> inverseTraces = CollectionsFactory.createMultiLookup(Object.class, MemoryType.SETS, Object.class);
46
47 /**
48 * Reasons for removing {@link PTraceable}s
49 */
50 private final Map<PTraceable, IDerivativeModificationReason> removals = new HashMap<>();
51
52 /**
53 * Decides whether {@link PTraceable} is removed
54 */
55 private final Predicate<PTraceable> removed = removals::containsKey;
56
57 /**
58 * @since 2.0
59 */
60 @Override
61 public Stream<PTraceable> getCanonicalTraceables(PTraceable derivative) {
62 return findTraceEnds(derivative, traces).stream();
63 }
64
65 /**
66 * @since 2.0
67 */
68 @Override
69 public Stream<PTraceable> getRewrittenTraceables(PTraceable source) {
70 return findTraceEnds(source, inverseTraces).stream();
71 }
72
73 /**
74 * Returns the end of trace chains starting from the given {@link PTraceable} along the given trace edges.
75 */
76 private Set<PTraceable> findTraceEnds(PTraceable traceable, IMultiLookup<PTraceable, PTraceable> traceRecords) {
77 if (traceable instanceof PQuery) { // PQueries are preserved
78 return Collections.singleton(traceable);
79 }
80 Set<PTraceable> visited = new HashSet<>();
81 Set<PTraceable> result = new HashSet<>();
82 Queue<PTraceable> queue = new LinkedList<>();
83 queue.add(traceable);
84 while(!queue.isEmpty()){
85 PTraceable aDerivative = queue.poll();
86 // Track visited elements to avoid infinite loop via directed cycles in traces
87 visited.add(aDerivative);
88 IMemoryView<PTraceable> nextOrigins = traceRecords.lookup(aDerivative);
89 if (nextOrigins == null){
90 // End of trace chain
91 result.add(aDerivative);
92 } else {
93 // Follow traces
94 for(PTraceable nextOrigin : nextOrigins){
95 if (!visited.contains(nextOrigin)){
96 queue.add(nextOrigin);
97 }
98 }
99 }
100 }
101 return result;
102 }
103
104 @Override
105 public void addTrace(PTraceable original, PTraceable derivative){
106 traces.addPairOrNop(derivative, original);
107 inverseTraces.addPairOrNop(original, derivative);
108 // Even if this element was marked as removed earlier, now we replace it with another constraint!
109 removals.remove(original);
110 }
111
112 @Override
113 public void derivativeRemoved(PTraceable derivative, IDerivativeModificationReason reason){
114 Preconditions.checkState(!removals.containsKey(derivative), "Traceable %s removed multiple times", derivative);
115 // XXX the derivative must not be removed from the trace chain, as some rewriters, e.g. the normalizer keeps trace links to deleted elements
116 if (!inverseTraces.lookupExists(derivative)) {
117 // If there already exists a trace link, this removal means an update
118 removals.put(derivative, reason);
119 }
120 }
121
122 @Override
123 public boolean isRemoved(PTraceable traceable) {
124 return getRewrittenTraceables(traceable).allMatch(removed);
125 }
126
127 /**
128 * @since 2.0
129 */
130 @Override
131 public Stream<IDerivativeModificationReason> getRemovalReasons(PTraceable traceable) {
132 return getRewrittenTraceables(traceable).filter(removed).map(removals::get);
133 }
134
135}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/NeverFlattenCallPredicate.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/NeverFlattenCallPredicate.java
new file mode 100644
index 00000000..96c0b205
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/NeverFlattenCallPredicate.java
@@ -0,0 +1,26 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Grill Balázs, 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.matchers.psystem.rewriters;
10
11import tools.refinery.viatra.runtime.matchers.psystem.basicenumerables.PositivePatternCall;
12
13/**
14 * @author Grill Balázs
15 * @since 1.4
16 *
17 */
18public class NeverFlattenCallPredicate implements IFlattenCallPredicate {
19
20
21 @Override
22 public boolean shouldFlatten(PositivePatternCall positivePatternCall) {
23 return false;
24 }
25
26}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/NopTraceCollector.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/NopTraceCollector.java
new file mode 100644
index 00000000..15cf577e
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/NopTraceCollector.java
@@ -0,0 +1,68 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2017, Grill Balázs, IncQueryLabs
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.matchers.psystem.rewriters;
10
11import java.util.stream.Stream;
12
13import tools.refinery.viatra.runtime.matchers.psystem.PTraceable;
14
15/**
16 * This implementation does not store any traces and scales to NOP for every traceability feature.
17 * @since 1.6
18 *
19 */
20public class NopTraceCollector implements IRewriterTraceCollector {
21
22 public static final IRewriterTraceCollector INSTANCE = new NopTraceCollector();
23
24 private NopTraceCollector() {
25 // Private constructor to force using the common instance
26 }
27
28 /**
29 * @since 2.0
30 */
31 @Override
32 public Stream<PTraceable> getCanonicalTraceables(PTraceable derivative) {
33 return Stream.empty();
34 }
35
36 /**
37 * @since 2.0
38 */
39 @Override
40 public Stream<PTraceable> getRewrittenTraceables(PTraceable source) {
41 return Stream.empty();
42 }
43
44
45 @Override
46 public void addTrace(PTraceable origin, PTraceable derivative) {
47 // ignored
48 }
49
50 @Override
51 public void derivativeRemoved(PTraceable derivative, IDerivativeModificationReason reason) {
52 // ignored
53 }
54
55 @Override
56 public boolean isRemoved(PTraceable traceable) {
57 return false;
58 }
59
60 /**
61 * @since 2.0
62 */
63 @Override
64 public Stream<IDerivativeModificationReason> getRemovalReasons(PTraceable traceable) {
65 return Stream.empty();
66 }
67
68}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/PBodyCopier.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/PBodyCopier.java
new file mode 100644
index 00000000..10ab19c8
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/PBodyCopier.java
@@ -0,0 +1,307 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Marton Bur, Akos Horvath, Zoltan Ujhelyi, 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 *
8 * SPDX-License-Identifier: EPL-2.0
9 *******************************************************************************/
10package tools.refinery.viatra.runtime.matchers.psystem.rewriters;
11
12import tools.refinery.viatra.runtime.matchers.planning.QueryProcessingException;
13import tools.refinery.viatra.runtime.matchers.psystem.EnumerablePConstraint;
14import tools.refinery.viatra.runtime.matchers.psystem.PBody;
15import tools.refinery.viatra.runtime.matchers.psystem.PConstraint;
16import tools.refinery.viatra.runtime.matchers.psystem.PVariable;
17import tools.refinery.viatra.runtime.matchers.psystem.basicdeferred.*;
18import tools.refinery.viatra.runtime.matchers.psystem.basicenumerables.*;
19import tools.refinery.viatra.runtime.matchers.psystem.queries.PParameter;
20import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery;
21import tools.refinery.viatra.runtime.matchers.psystem.rewriters.IConstraintFilter.AllowAllFilter;
22import tools.refinery.viatra.runtime.matchers.psystem.rewriters.IVariableRenamer.SameName;
23import tools.refinery.viatra.runtime.matchers.tuple.Tuple;
24import tools.refinery.viatra.runtime.matchers.tuple.Tuples;
25
26import java.util.*;
27import java.util.stream.Collectors;
28
29/**
30 * This class can create a new PBody for a PQuery. The result body contains a copy of given variables and constraints.
31 *
32 * @author Marton Bur
33 *
34 */
35public class PBodyCopier extends AbstractRewriterTraceSource {
36
37 /**
38 * The created body
39 */
40 protected PBody body;
41 /**
42 * Mapping between the original and the copied variables
43 */
44 protected Map<PVariable, PVariable> variableMapping = new HashMap<>();
45
46 public Map<PVariable, PVariable> getVariableMapping() {
47 return variableMapping;
48 }
49
50 /**
51 * @since 1.6
52 */
53 public PBodyCopier(PBody body, IRewriterTraceCollector traceCollector) {
54 this.body = new PBody(body.getPattern());
55 setTraceCollector(traceCollector);
56
57 // do the actual copying
58 mergeBody(body);
59 }
60
61 /**
62 * @since 1.6
63 */
64 public PBodyCopier(PQuery query) {
65 this.body = new PBody(query);
66 }
67
68 public void mergeBody(PBody sourceBody) {
69 mergeBody(sourceBody, new SameName(), new AllowAllFilter());
70 }
71
72 /**
73 * Merge all variables and constraints from a source body to a target body. If multiple bodies are merged into a
74 * single one, use the renamer and filter options to avoid collisions.
75 */
76 public void mergeBody(PBody sourceBody, IVariableRenamer namingTool, IConstraintFilter filter) {
77
78 // Copy variables
79 Set<PVariable> allVariables = sourceBody.getAllVariables();
80 for (PVariable pVariable : allVariables) {
81 if (pVariable.isUnique()) {
82 copyVariable(pVariable, namingTool.createVariableName(pVariable, sourceBody.getPattern()));
83 }
84 }
85
86 // Copy exported parameters
87 this.body.setSymbolicParameters(sourceBody.getSymbolicParameters().stream()
88 .map(this::copyExportedParameterConstraint).collect(Collectors.toList()));
89
90 // Copy constraints which are not filtered
91 Set<PConstraint> constraints = sourceBody.getConstraints();
92 for (PConstraint pConstraint : constraints) {
93 if (!(pConstraint instanceof ExportedParameter) && !filter.filter(pConstraint)) {
94 copyConstraint(pConstraint);
95 }
96 }
97
98 // Add trace between original and copied body
99 addTrace(sourceBody, body);
100 }
101
102 protected void copyVariable(PVariable variable, String newName) {
103 PVariable newPVariable = body.getOrCreateVariableByName(newName);
104 variableMapping.put(variable, newPVariable);
105 }
106
107 /**
108 * Returns the body with the copied variables and constraints. The returned body is still uninitialized.
109 */
110 public PBody getCopiedBody() {
111 return body;
112 }
113
114 protected void copyConstraint(PConstraint constraint) {
115 if (constraint instanceof ExportedParameter) {
116 copyExportedParameterConstraint((ExportedParameter) constraint);
117 } else if (constraint instanceof Equality) {
118 copyEqualityConstraint((Equality) constraint);
119 } else if (constraint instanceof Inequality) {
120 copyInequalityConstraint((Inequality) constraint);
121 } else if (constraint instanceof TypeConstraint) {
122 copyTypeConstraint((TypeConstraint) constraint);
123 } else if (constraint instanceof TypeFilterConstraint) {
124 copyTypeFilterConstraint((TypeFilterConstraint) constraint);
125 } else if (constraint instanceof ConstantValue) {
126 copyConstantValueConstraint((ConstantValue) constraint);
127 } else if (constraint instanceof PositivePatternCall) {
128 copyPositivePatternCallConstraint((PositivePatternCall) constraint);
129 } else if (constraint instanceof NegativePatternCall) {
130 copyNegativePatternCallConstraint((NegativePatternCall) constraint);
131 } else if (constraint instanceof BinaryTransitiveClosure) {
132 copyBinaryTransitiveClosureConstraint((BinaryTransitiveClosure) constraint);
133 } else if (constraint instanceof RepresentativeElectionConstraint) {
134 copyRepresentativeElectionConstraint((RepresentativeElectionConstraint) constraint);
135 } else if (constraint instanceof RelationEvaluation) {
136 copyRelationEvaluationConstraint((RelationEvaluation) constraint);
137 } else if (constraint instanceof BinaryReflexiveTransitiveClosure) {
138 copyBinaryReflexiveTransitiveClosureConstraint((BinaryReflexiveTransitiveClosure) constraint);
139 } else if (constraint instanceof PatternMatchCounter) {
140 copyPatternMatchCounterConstraint((PatternMatchCounter) constraint);
141 } else if (constraint instanceof AggregatorConstraint) {
142 copyAggregatorConstraint((AggregatorConstraint) constraint);
143 } else if (constraint instanceof ExpressionEvaluation) {
144 copyExpressionEvaluationConstraint((ExpressionEvaluation) constraint);
145 } else {
146 throw new QueryProcessingException("Unknown PConstraint {0} encountered while copying PBody",
147 new String[] { constraint.getClass().getName() }, "Unknown PConstraint", body.getPattern());
148 }
149 }
150
151 protected ExportedParameter copyExportedParameterConstraint(ExportedParameter exportedParameter) {
152 PVariable mappedPVariable = variableMapping.get(exportedParameter.getParameterVariable());
153 PParameter parameter = exportedParameter.getPatternParameter();
154 ExportedParameter newExportedParameter;
155 newExportedParameter = new ExportedParameter(body, mappedPVariable, parameter);
156 body.getSymbolicParameters().add(newExportedParameter);
157 addTrace(exportedParameter, newExportedParameter);
158 return newExportedParameter;
159 }
160
161 protected void copyEqualityConstraint(Equality equality) {
162 PVariable who = equality.getWho();
163 PVariable withWhom = equality.getWithWhom();
164 addTrace(equality, new Equality(body, variableMapping.get(who), variableMapping.get(withWhom)));
165 }
166
167 protected void copyInequalityConstraint(Inequality inequality) {
168 PVariable who = inequality.getWho();
169 PVariable withWhom = inequality.getWithWhom();
170 addTrace(inequality, new Inequality(body, variableMapping.get(who), variableMapping.get(withWhom)));
171 }
172
173 protected void copyTypeConstraint(TypeConstraint typeConstraint) {
174 PVariable[] mappedVariables = extractMappedVariables(typeConstraint);
175 Tuple variablesTuple = Tuples.flatTupleOf((Object[]) mappedVariables);
176 addTrace(typeConstraint, new TypeConstraint(body, variablesTuple, typeConstraint.getSupplierKey()));
177 }
178
179 protected void copyTypeFilterConstraint(TypeFilterConstraint typeConstraint) {
180 PVariable[] mappedVariables = extractMappedVariables(typeConstraint);
181 Tuple variablesTuple = Tuples.flatTupleOf((Object[]) mappedVariables);
182 addTrace(typeConstraint, new TypeFilterConstraint(body, variablesTuple, typeConstraint.getInputKey()));
183 }
184
185 protected void copyConstantValueConstraint(ConstantValue constantValue) {
186 PVariable pVariable = (PVariable) constantValue.getVariablesTuple().getElements()[0];
187 addTrace(constantValue,
188 new ConstantValue(body, variableMapping.get(pVariable), constantValue.getSupplierKey()));
189 }
190
191 protected void copyPositivePatternCallConstraint(PositivePatternCall positivePatternCall) {
192 PVariable[] mappedVariables = extractMappedVariables(positivePatternCall);
193 Tuple variablesTuple = Tuples.flatTupleOf((Object[]) mappedVariables);
194 addTrace(positivePatternCall,
195 new PositivePatternCall(body, variablesTuple, positivePatternCall.getReferredQuery()));
196 }
197
198 protected void copyNegativePatternCallConstraint(NegativePatternCall negativePatternCall) {
199 PVariable[] mappedVariables = extractMappedVariables(negativePatternCall);
200 Tuple variablesTuple = Tuples.flatTupleOf((Object[]) mappedVariables);
201 addTrace(negativePatternCall,
202 new NegativePatternCall(body, variablesTuple, negativePatternCall.getReferredQuery()));
203 }
204
205 protected void copyBinaryTransitiveClosureConstraint(BinaryTransitiveClosure binaryTransitiveClosure) {
206 PVariable[] mappedVariables = extractMappedVariables(binaryTransitiveClosure);
207 Tuple variablesTuple = Tuples.flatTupleOf((Object[]) mappedVariables);
208 addTrace(binaryTransitiveClosure,
209 new BinaryTransitiveClosure(body, variablesTuple, binaryTransitiveClosure.getReferredQuery()));
210 }
211
212 protected void copyRepresentativeElectionConstraint(RepresentativeElectionConstraint constraint) {
213 var mappedVariables = extractMappedVariables(constraint);
214 var variablesTuple = Tuples.flatTupleOf((Object[]) mappedVariables);
215 addTrace(constraint, new RepresentativeElectionConstraint(body, variablesTuple, constraint.getReferredQuery(),
216 constraint.getConnectivity()));
217 }
218
219 /**
220 * @since 2.8
221 */
222 protected void copyRelationEvaluationConstraint(RelationEvaluation relationEvaluation) {
223 PVariable[] mappedVariables = extractMappedVariables(relationEvaluation);
224 Tuple variablesTuple = Tuples.flatTupleOf((Object[]) mappedVariables);
225 addTrace(relationEvaluation, new RelationEvaluation(body, variablesTuple, relationEvaluation.getReferredQueries(),
226 relationEvaluation.getEvaluator()));
227 }
228
229 /**
230 * @since 2.0
231 */
232 protected void copyBinaryReflexiveTransitiveClosureConstraint(
233 BinaryReflexiveTransitiveClosure binaryReflexiveTransitiveClosure) {
234 PVariable[] mappedVariables = extractMappedVariables(binaryReflexiveTransitiveClosure);
235 Tuple variablesTuple = Tuples.flatTupleOf((Object[]) mappedVariables);
236 addTrace(binaryReflexiveTransitiveClosure,
237 new BinaryReflexiveTransitiveClosure(body, variablesTuple,
238 binaryReflexiveTransitiveClosure.getReferredQuery(),
239 binaryReflexiveTransitiveClosure.getUniverseType()));
240 }
241
242 protected void copyPatternMatchCounterConstraint(PatternMatchCounter patternMatchCounter) {
243 PVariable[] mappedVariables = extractMappedVariables(patternMatchCounter);
244 PVariable mappedResultVariable = variableMapping.get(patternMatchCounter.getResultVariable());
245 Tuple variablesTuple = Tuples.flatTupleOf((Object[]) mappedVariables);
246 addTrace(patternMatchCounter, new PatternMatchCounter(body, variablesTuple,
247 patternMatchCounter.getReferredQuery(), mappedResultVariable));
248 }
249
250 /**
251 * @since 1.4
252 */
253 protected void copyAggregatorConstraint(AggregatorConstraint constraint) {
254 PVariable[] mappedVariables = extractMappedVariables(constraint);
255 PVariable mappedResultVariable = variableMapping.get(constraint.getResultVariable());
256 Tuple variablesTuple = Tuples.flatTupleOf((Object[]) mappedVariables);
257 addTrace(constraint, new AggregatorConstraint(constraint.getAggregator(), body, variablesTuple,
258 constraint.getReferredQuery(), mappedResultVariable, constraint.getAggregatedColumn()));
259 }
260
261 protected void copyExpressionEvaluationConstraint(ExpressionEvaluation expressionEvaluation) {
262 PVariable mappedOutputVariable = variableMapping.get(expressionEvaluation.getOutputVariable());
263 addTrace(expressionEvaluation, new ExpressionEvaluation(body,
264 new VariableMappingExpressionEvaluatorWrapper(expressionEvaluation.getEvaluator(), variableMapping),
265 mappedOutputVariable, expressionEvaluation.isUnwinding()));
266 }
267
268 /**
269 * For positive pattern calls
270 *
271 * @param positivePatternCall
272 * @return the mapped variables to the pattern's parameters
273 */
274 protected PVariable[] extractMappedVariables(EnumerablePConstraint enumerablePConstraint) {
275 Object[] pVariables = enumerablePConstraint.getVariablesTuple().getElements();
276 return mapVariableList(pVariables);
277 }
278
279 /**
280 * For negative and count pattern calls.
281 *
282 * @param patternMatchCounter
283 * @return the mapped variables to the pattern's parameters
284 */
285 private PVariable[] extractMappedVariables(PatternCallBasedDeferred patternCallBasedDeferred) {
286 Object[] pVariables = patternCallBasedDeferred.getActualParametersTuple().getElements();
287 return mapVariableList(pVariables);
288 }
289
290 /**
291 * For type filters.
292 */
293 private PVariable[] extractMappedVariables(TypeFilterConstraint typeFilterConstraint) {
294 Object[] pVariables = typeFilterConstraint.getVariablesTuple().getElements();
295 return mapVariableList(pVariables);
296 }
297
298 private PVariable[] mapVariableList(Object[] pVariables) {
299 List<PVariable> list = new ArrayList<PVariable>();
300 for (int i = 0; i < pVariables.length; i++) {
301 PVariable mappedVariable = variableMapping.get(pVariables[i]);
302 list.add(mappedVariable);
303 }
304 return list.toArray(new PVariable[0]);
305 }
306
307}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/PBodyNormalizer.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/PBodyNormalizer.java
new file mode 100644
index 00000000..90943129
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/PBodyNormalizer.java
@@ -0,0 +1,310 @@
1/*******************************************************************************
2 * Copyright (c) 2004-2010 Gabor Bergmann 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 *******************************************************************************/
9
10package tools.refinery.viatra.runtime.matchers.psystem.rewriters;
11
12import java.util.ArrayList;
13import java.util.Collection;
14import java.util.Collections;
15import java.util.Comparator;
16import java.util.HashMap;
17import java.util.HashSet;
18import java.util.Iterator;
19import java.util.LinkedHashSet;
20import java.util.LinkedList;
21import java.util.List;
22import java.util.Map;
23import java.util.Queue;
24import java.util.Set;
25
26import tools.refinery.viatra.runtime.matchers.context.IInputKey;
27import tools.refinery.viatra.runtime.matchers.context.IQueryMetaContext;
28import tools.refinery.viatra.runtime.matchers.planning.QueryProcessingException;
29import tools.refinery.viatra.runtime.matchers.planning.helpers.TypeHelper;
30import tools.refinery.viatra.runtime.matchers.psystem.ITypeConstraint;
31import tools.refinery.viatra.runtime.matchers.psystem.ITypeInfoProviderConstraint;
32import tools.refinery.viatra.runtime.matchers.psystem.PBody;
33import tools.refinery.viatra.runtime.matchers.psystem.PConstraint;
34import tools.refinery.viatra.runtime.matchers.psystem.TypeJudgement;
35import tools.refinery.viatra.runtime.matchers.psystem.basicdeferred.Equality;
36import tools.refinery.viatra.runtime.matchers.psystem.basicdeferred.Inequality;
37import tools.refinery.viatra.runtime.matchers.psystem.queries.PDisjunction;
38import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery;
39import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery.PQueryStatus;
40import tools.refinery.viatra.runtime.matchers.util.CollectionsFactory;
41
42/**
43 * A disjunction rewriter for creating a normalized form of specification, unifying variables and running basic sanity
44 * checks. This rewriter does not copy but modifies directly the original specification, requiring a mutable
45 * disjunction.
46 *
47 * @author Gabor Bergmann
48 *
49 */
50public class PBodyNormalizer extends PDisjunctionRewriter {
51
52 private IQueryMetaContext context;
53
54 public PBodyNormalizer(IQueryMetaContext context) {
55 this.context = context;
56 }
57
58 /**
59 * Returns whether unary constraint elimination is enabled. This behavior can be customized by creating a subclass
60 * with a custom implementation.
61 *
62 * @since 1.6
63 */
64 protected boolean shouldCalculateImpliedTypes(PQuery query) {
65 return true;
66 }
67
68 /**
69 * Returns whether 'weakened alternative' suggestions of the context shall be expanded as additional PConstraints.
70 * This behavior can be customized by creating a subclass
71 * with a custom implementation.
72 *
73 * @since 1.6
74 */
75 protected boolean shouldExpandWeakenedAlternatives(PQuery query) {
76 return false;
77 }
78
79 @Override
80 public PDisjunction rewrite(PDisjunction disjunction) {
81 Set<PBody> normalizedBodies = new LinkedHashSet<>();
82 for (PBody body : disjunction.getBodies()) {
83 PBodyCopier copier = new PBodyCopier(body, getTraceCollector());
84 PBody modifiedBody = copier.getCopiedBody();
85 normalizeBody(modifiedBody);
86 normalizedBodies.add(modifiedBody);
87 modifiedBody.setStatus(PQueryStatus.OK);
88 }
89 return new PDisjunction(normalizedBodies);
90 }
91
92 public void setContext(IQueryMetaContext context) {
93 this.context = context;
94 }
95
96 /**
97 * Provides a normalized version of the pattern body. May return a different version than the original version if
98 * needed.
99 *
100 * @param body
101 */
102 public PBody normalizeBody(PBody body) {
103 try {
104 return normalizeBodyInternal(body);
105 } catch (QueryProcessingException e) {
106 throw new RewriterException("Error during rewriting: {1}", new String[] { e.getMessage() },
107 e.getShortMessage(), body.getPattern(), e);
108 }
109 }
110
111 PBody normalizeBodyInternal(PBody body) {
112 // UNIFICATION AND WEAK INEQUALITY ELIMINATION
113 unifyVariablesAlongEqualities(body);
114 eliminateWeakInequalities(body);
115 removeMootEqualities(body);
116
117 // ADDING WEAKENED ALTERNATIVES
118 if (shouldExpandWeakenedAlternatives(body.getPattern())) {
119 expandWeakenedAlternativeConstraints(body);
120 }
121
122 // CONSTRAINT ELIMINATION WITH TYPE INFERENCE
123 if (shouldCalculateImpliedTypes(body.getPattern())) {
124 eliminateInferrableTypes(body, context);
125 } else {
126 // ELIMINATE DUPLICATE TYPE CONSTRAINTS
127 eliminateDuplicateTypeConstraints(body);
128 }
129
130
131 // PREVENTIVE CHECKS
132 checkSanity(body);
133 return body;
134 }
135
136 private void removeMootEqualities(PBody body) {
137 Set<Equality> equals = body.getConstraintsOfType(Equality.class);
138 for (Equality equality : equals) {
139 if (equality.isMoot()) {
140 equality.delete();
141 derivativeRemoved(equality, ConstraintRemovalReason.MOOT_EQUALITY);
142 }
143 }
144 }
145
146 /**
147 * Unifies allVariables along equalities so that they can be handled as one.
148 *
149 * @param body
150 */
151 void unifyVariablesAlongEqualities(PBody body) {
152 Set<Equality> equals = body.getConstraintsOfType(Equality.class);
153 for (Equality equality : equals) {
154 if (!equality.isMoot()) {
155 equality.getWho().unifyInto(equality.getWithWhom());
156 }
157 }
158 }
159
160 /**
161 * Eliminates weak inequalities if they are not substantiated.
162 *
163 * @param body
164 */
165 void eliminateWeakInequalities(PBody body) {
166 for (Inequality inequality : body.getConstraintsOfType(Inequality.class)){
167 if (inequality.isEliminable()){
168 inequality.eliminateWeak();
169 derivativeRemoved(inequality, ConstraintRemovalReason.WEAK_INEQUALITY_SELF_LOOP);
170 }
171 }
172 }
173
174 /**
175 * Eliminates all type constraints that are inferrable from other constraints.
176 */
177 void eliminateInferrableTypes(final PBody body, IQueryMetaContext context) {
178 Set<TypeJudgement> subsumedByRetainedConstraints = new HashSet<TypeJudgement>();
179 LinkedList<ITypeConstraint> allTypeConstraints = new LinkedList<ITypeConstraint>();
180 for (PConstraint pConstraint : body.getConstraints()) {
181 if (pConstraint instanceof ITypeConstraint) {
182 allTypeConstraints.add((ITypeConstraint) pConstraint);
183 } else if (pConstraint instanceof ITypeInfoProviderConstraint) {
184 // non-type constraints are all retained
185 final Set<TypeJudgement> directJudgements = ((ITypeInfoProviderConstraint) pConstraint)
186 .getImpliedJudgements(context);
187 subsumedByRetainedConstraints = TypeHelper.typeClosure(subsumedByRetainedConstraints, directJudgements,
188 context);
189 }
190 }
191 Comparator<ITypeConstraint> eliminationOrder = (o1, o2) -> {
192 IInputKey type1 = o1.getEquivalentJudgement().getInputKey();
193 IInputKey type2 = o2.getEquivalentJudgement().getInputKey();
194
195 int result = context.getSuggestedEliminationOrdering().compare(type1, type2);
196 return (result == 0)
197 ? PConstraint.COMPARE_BY_MONOTONOUS_ID.compare(o1, o2)
198 : result;
199 };
200
201 Collections.sort(allTypeConstraints, eliminationOrder);
202 Queue<ITypeConstraint> potentialConstraints = allTypeConstraints; // rename for better comprehension
203
204 while (!potentialConstraints.isEmpty()) {
205 ITypeConstraint candidate = potentialConstraints.poll();
206
207 boolean isSubsumed = subsumedByRetainedConstraints.contains(candidate.getEquivalentJudgement());
208 if (!isSubsumed) {
209 Set<TypeJudgement> typeClosure = subsumedByRetainedConstraints;
210 for (ITypeConstraint subsuming : potentialConstraints) { // the remaining ones
211 final Set<TypeJudgement> directJudgements = subsuming.getImpliedJudgements(context);
212 typeClosure = TypeHelper.typeClosure(typeClosure, directJudgements, context);
213
214 if (typeClosure.contains(candidate.getEquivalentJudgement())) {
215 isSubsumed = true;
216 break;
217 }
218 }
219 }
220 if (isSubsumed) { // eliminated
221 candidate.delete();
222 derivativeRemoved(candidate, ConstraintRemovalReason.TYPE_SUBSUMED);
223 } else { // retained
224 subsumedByRetainedConstraints = TypeHelper.typeClosure(subsumedByRetainedConstraints,
225 candidate.getImpliedJudgements(context), context);
226 }
227 }
228 }
229
230 /**
231 * Inserts "weakened alternative" constraints suggested by the meta context that aid in coming up with a query plan.
232 */
233 void expandWeakenedAlternativeConstraints(PBody body) {
234 Set<TypeJudgement> allJudgements = new HashSet<TypeJudgement>();
235 Set<TypeJudgement> newJudgementsToAdd = new HashSet<TypeJudgement>();
236 Queue<TypeJudgement> judgementsToProcess = new LinkedList<TypeJudgement>();
237 Map<TypeJudgement, List<PConstraint>> traceability = CollectionsFactory.createMap();
238
239 for (ITypeConstraint typeConstraint : body.getConstraintsOfType(ITypeConstraint.class)) {
240 TypeJudgement equivalentJudgement = typeConstraint.getEquivalentJudgement();
241 judgementsToProcess.add(equivalentJudgement);
242 allJudgements.add(equivalentJudgement);
243 traceability.computeIfAbsent(equivalentJudgement, k-> new ArrayList<>()).add(typeConstraint);
244 }
245
246 while (!judgementsToProcess.isEmpty()) {
247 TypeJudgement judgement = judgementsToProcess.poll();
248 for (TypeJudgement alternativeJudgement : judgement.getWeakenedAlternativeJudgements(context)) {
249 if (allJudgements.add(alternativeJudgement)) {
250 newJudgementsToAdd.add(alternativeJudgement);
251 judgementsToProcess.add(alternativeJudgement);
252 traceability.merge(
253 alternativeJudgement,
254 traceability.getOrDefault(judgement, new ArrayList<>()),
255 (old,further) -> {old.addAll(further); return old;}
256 );
257 }
258 }
259 }
260
261 for (TypeJudgement typeJudgement : newJudgementsToAdd) {
262 PConstraint newConstraint = typeJudgement.createConstraintFor(body);
263 for (PConstraint source : traceability.getOrDefault(typeJudgement, Collections.emptyList())) {
264 addTrace(source, newConstraint);
265 }
266 }
267 }
268
269 private Object getConstraintKey(PConstraint constraint) {
270 if (constraint instanceof ITypeConstraint) {
271 return ((ITypeConstraint) constraint).getEquivalentJudgement();
272 }
273 // Do not check duplication for any other types
274 return constraint;
275 }
276
277 void eliminateDuplicateTypeConstraints(PBody body) {
278 Map<Object, PConstraint> constraints = new HashMap<>();
279 for (PConstraint constraint : body.getConstraints()) {
280 Object key = getConstraintKey(constraint);
281 // Retain first found instance of a constraint
282 if (!constraints.containsKey(key)) {
283 constraints.put(key, constraint);
284 }
285 }
286
287 // Retain collected constraints, remove everything else
288 Iterator<PConstraint> iterator = body.getConstraints().iterator();
289 Collection<PConstraint> toRetain = constraints.values();
290 while(iterator.hasNext()){
291 PConstraint next = iterator.next();
292 if (!toRetain.contains(next)){
293 derivativeRemoved(next, ConstraintRemovalReason.DUPLICATE);
294 iterator.remove();
295 }
296 }
297 }
298
299 /**
300 * Verifies the sanity of all constraints. Should be issued as a preventive check before layouting.
301 *
302 * @param body
303 * @throws RetePatternBuildException
304 */
305 void checkSanity(PBody body) {
306 for (PConstraint pConstraint : body.getConstraints())
307 pConstraint.checkSanity();
308 }
309
310}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/PDisjunctionRewriter.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/PDisjunctionRewriter.java
new file mode 100644
index 00000000..c844ccf7
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/PDisjunctionRewriter.java
@@ -0,0 +1,27 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, 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.matchers.psystem.rewriters;
10
11import tools.refinery.viatra.runtime.matchers.psystem.queries.PDisjunction;
12import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery;
13
14/**
15 * An abstract base class for creating alternative representations for PDisjunctions.
16 * @author Zoltan Ujhelyi
17 *
18 */
19public abstract class PDisjunctionRewriter extends AbstractRewriterTraceSource{
20
21 public abstract PDisjunction rewrite(PDisjunction disjunction);
22
23 public PDisjunction rewrite(PQuery query) {
24 return rewrite(query.getDisjunctBodies());
25 }
26
27}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/PDisjunctionRewriterCacher.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/PDisjunctionRewriterCacher.java
new file mode 100644
index 00000000..eb5422ca
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/PDisjunctionRewriterCacher.java
@@ -0,0 +1,64 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, 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.matchers.psystem.rewriters;
10
11import java.util.ArrayList;
12import java.util.Arrays;
13import java.util.Collections;
14import java.util.List;
15import java.util.WeakHashMap;
16
17import tools.refinery.viatra.runtime.matchers.psystem.queries.PDisjunction;
18
19/**
20 * A rewriter that stores the previously computed results of a rewriter or a rewriter chain.
21 *
22 * @author Zoltan Ujhelyi
23 * @since 1.0
24 */
25public class PDisjunctionRewriterCacher extends PDisjunctionRewriter {
26
27 private final List<PDisjunctionRewriter> rewriterChain;
28 private WeakHashMap<PDisjunction, PDisjunction> cachedResults =
29 new WeakHashMap<PDisjunction, PDisjunction>();
30
31 private void setupTraceCollectorInChain(){
32 IRewriterTraceCollector collector = getTraceCollector();
33 for(PDisjunctionRewriter rewriter: rewriterChain){
34 rewriter.setTraceCollector(collector);
35 }
36 }
37
38 public PDisjunctionRewriterCacher(PDisjunctionRewriter rewriter) {
39 rewriterChain = Collections.singletonList(rewriter);
40 }
41
42 public PDisjunctionRewriterCacher(PDisjunctionRewriter... rewriters) {
43 rewriterChain = new ArrayList<>(Arrays.asList(rewriters));
44 }
45
46 public PDisjunctionRewriterCacher(List<PDisjunctionRewriter> rewriterChain) {
47 this.rewriterChain = new ArrayList<>(rewriterChain);
48 }
49
50 @Override
51 public PDisjunction rewrite(PDisjunction disjunction) {
52 if (!cachedResults.containsKey(disjunction)) {
53 PDisjunction rewritten = disjunction;
54 setupTraceCollectorInChain();
55 for (PDisjunctionRewriter rewriter : rewriterChain) {
56 rewritten = rewriter.rewrite(rewritten);
57 }
58
59 cachedResults.put(disjunction, rewritten);
60 }
61 return cachedResults.get(disjunction);
62 }
63
64}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/PQueryFlattener.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/PQueryFlattener.java
new file mode 100644
index 00000000..76311d8f
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/PQueryFlattener.java
@@ -0,0 +1,253 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Marton Bur, Akos Horvath, 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.matchers.psystem.rewriters;
10
11import java.util.ArrayDeque;
12import java.util.ArrayList;
13import java.util.Collections;
14import java.util.Deque;
15import java.util.HashMap;
16import java.util.HashSet;
17import java.util.LinkedHashSet;
18import java.util.LinkedList;
19import java.util.List;
20import java.util.Map;
21import java.util.Set;
22
23import tools.refinery.viatra.runtime.matchers.psystem.PBody;
24import tools.refinery.viatra.runtime.matchers.psystem.PConstraint;
25import tools.refinery.viatra.runtime.matchers.psystem.basicenumerables.PositivePatternCall;
26import tools.refinery.viatra.runtime.matchers.psystem.queries.PDisjunction;
27import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery;
28import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery.PQueryStatus;
29import tools.refinery.viatra.runtime.matchers.psystem.rewriters.IConstraintFilter.AllowAllFilter;
30import tools.refinery.viatra.runtime.matchers.psystem.rewriters.IConstraintFilter.ExportedParameterFilter;
31import tools.refinery.viatra.runtime.matchers.psystem.rewriters.IVariableRenamer.HierarchicalName;
32import tools.refinery.viatra.runtime.matchers.psystem.rewriters.IVariableRenamer.SameName;
33import tools.refinery.viatra.runtime.matchers.util.Preconditions;
34import tools.refinery.viatra.runtime.matchers.util.Sets;
35
36/**
37 * This rewriter class holds the query flattening logic
38 *
39 * @author Marton Bur
40 *
41 */
42public class PQueryFlattener extends PDisjunctionRewriter {
43
44 /**
45 * Utility function to produce the permutation of every possible mapping of values.
46 *
47 * @param values
48 * @return
49 */
50 private static <K, V> Set<Map<K, V>> permutation(Map<K, Set<V>> values) {
51 // An ordering of keys is defined here which will help restoring the appropriate values after the execution of
52 // the cartesian product
53 List<K> keyList = new ArrayList<>(values.keySet());
54
55 // Produce list of value sets with the ordering defined by keyList
56 List<Set<V>> valuesList = new ArrayList<Set<V>>(keyList.size());
57 for (K key : keyList) {
58 valuesList.add(values.get(key));
59 }
60
61 // Cartesian product will obey ordering of the list
62 Set<List<V>> valueMappings = Sets.cartesianProduct(valuesList);
63
64 // Build result
65 Set<Map<K, V>> result = new LinkedHashSet<>();
66 for (List<V> valueList : valueMappings) {
67 Map<K, V> map = new HashMap<>();
68 for (int i = 0; i < keyList.size(); i++) {
69 map.put(keyList.get(i), valueList.get(i));
70 }
71 result.add(map);
72 }
73
74 return result;
75 }
76
77 private IFlattenCallPredicate flattenCallPredicate;
78
79 public PQueryFlattener(IFlattenCallPredicate flattenCallPredicate) {
80 this.flattenCallPredicate = flattenCallPredicate;
81 }
82
83 @Override
84 public PDisjunction rewrite(PDisjunction disjunction) {
85 PQuery query = disjunction.getQuery();
86
87 // Check for recursion
88 Set<PQuery> allReferredQueries = disjunction.getAllReferredQueries();
89 for (PQuery referredQuery : allReferredQueries) {
90 if (referredQuery.getAllReferredQueries().contains(referredQuery)) {
91 throw new RewriterException("Recursive queries are not supported, can't flatten query named \"{1}\"",
92 new String[] { query.getFullyQualifiedName() }, "Unsupported recursive query", query);
93 }
94 }
95
96 return this.doFlatten(disjunction);
97 }
98
99 /**
100 * Return the list of dependencies (including the root) in chronological order
101 *
102 * @param rootDisjunction
103 * @return
104 */
105 private List<PDisjunction> disjunctionDependencies(PDisjunction rootDisjunction) {
106 // Disjunctions are first collected into a list usign a depth-first approach,
107 // which can be iterated backwards while removing duplicates
108 Deque<PDisjunction> stack = new ArrayDeque<>();
109 LinkedList<PDisjunction> list = new LinkedList<>();
110 stack.push(rootDisjunction);
111 list.add(rootDisjunction);
112
113 while (!stack.isEmpty()) {
114 PDisjunction disjunction = stack.pop();
115 // Collect dependencies
116 for (PBody pBody : disjunction.getBodies()) {
117 for (PConstraint constraint : pBody.getConstraints()) {
118 if (constraint instanceof PositivePatternCall) {
119 PositivePatternCall positivePatternCall = (PositivePatternCall) constraint;
120 if (flattenCallPredicate.shouldFlatten(positivePatternCall)) {
121 // If the above preconditions meet, the call should be flattened
122 PDisjunction calledDisjunction = positivePatternCall.getReferredQuery().getDisjunctBodies();
123 stack.push(calledDisjunction);
124 list.add(calledDisjunction);
125 }
126 }
127 }
128 }
129 }
130
131 // Remove duplicates (keeping the last instance) and reverse order
132 Set<PDisjunction> visited = new HashSet<PDisjunction>();
133 List<PDisjunction> result = new ArrayList<PDisjunction>(list.size());
134
135 list.descendingIterator().forEachRemaining(item -> {
136 if (!visited.contains(item)) {
137 result.add(item);
138 visited.add(item);
139 }
140
141 });
142
143 return result;
144 }
145
146 /**
147 * This function holds the actual flattening logic for a PQuery
148 *
149 * @param rootDisjunction
150 * to be flattened
151 * @return the flattened bodies of the pQuery
152 */
153 private PDisjunction doFlatten(PDisjunction rootDisjunction) {
154
155 Map<PDisjunction, Set<PBody>> flatBodyMapping = new HashMap<>();
156
157 List<PDisjunction> dependencies = disjunctionDependencies(rootDisjunction);
158
159 for (PDisjunction disjunction : dependencies) {
160 Set<PBody> flatBodies = new LinkedHashSet<>();
161 for (PBody body : disjunction.getBodies()) {
162 if (isFlatteningNeeded(body)) {
163 Map<PositivePatternCall, Set<PBody>> flattenedBodies = new HashMap<>();
164 for (PConstraint pConstraint : body.getConstraints()) {
165
166 if (pConstraint instanceof PositivePatternCall) {
167 PositivePatternCall positivePatternCall = (PositivePatternCall) pConstraint;
168 if (flattenCallPredicate.shouldFlatten(positivePatternCall)) {
169 // If the above preconditions meet, do the flattening and return the disjoint bodies
170 PDisjunction calledDisjunction = positivePatternCall.getReferredQuery()
171 .getDisjunctBodies();
172
173 Set<PBody> flattenedBodySet = flatBodyMapping.get(calledDisjunction);
174 Preconditions.checkArgument(!flattenedBodySet.isEmpty());
175 flattenedBodies.put(positivePatternCall, flattenedBodySet);
176 }
177 }
178 }
179 flatBodies.addAll(createSetOfFlatPBodies(body, flattenedBodies));
180 } else {
181 flatBodies.add(prepareFlatPBody(body));
182 }
183 }
184 flatBodyMapping.put(disjunction, flatBodies);
185 }
186
187 return new PDisjunction(rootDisjunction.getQuery(), flatBodyMapping.get(rootDisjunction));
188 }
189
190 /**
191 * Creates the flattened bodies based on the caller body and the called (and already flattened) disjunctions
192 *
193 * @param pBody
194 * the body to flatten
195 * @param flattenedDisjunctions
196 * the
197 * @param flattenedCalls
198 * @return
199 */
200 private Set<PBody> createSetOfFlatPBodies(PBody pBody, Map<PositivePatternCall, Set<PBody>> flattenedCalls) {
201 PQuery pQuery = pBody.getPattern();
202
203 Set<Map<PositivePatternCall, PBody>> conjunctedCalls = permutation(flattenedCalls);
204
205 // The result set containing the merged conjuncted bodies
206 Set<PBody> conjunctedBodies = new HashSet<>();
207
208 for (Map<PositivePatternCall, PBody> calledBodies : conjunctedCalls) {
209 FlattenerCopier copier = createBodyCopier(pQuery, calledBodies);
210
211 int i = 0;
212 HierarchicalName hierarchicalNamingTool = new HierarchicalName();
213 for (PositivePatternCall patternCall : calledBodies.keySet()) {
214 // Merge each called body
215 hierarchicalNamingTool.setCallCount(i++);
216 copier.mergeBody(patternCall, hierarchicalNamingTool, new ExportedParameterFilter());
217 }
218
219 // Merge the caller's constraints to the conjunct body
220 copier.mergeBody(pBody);
221
222 PBody copiedBody = copier.getCopiedBody();
223 copiedBody.setStatus(PQueryStatus.OK);
224 conjunctedBodies.add(copiedBody);
225 }
226
227 return conjunctedBodies;
228 }
229
230 private FlattenerCopier createBodyCopier(PQuery query, Map<PositivePatternCall, PBody> calledBodies) {
231 FlattenerCopier flattenerCopier = new FlattenerCopier(query, calledBodies);
232 flattenerCopier.setTraceCollector(getTraceCollector());
233 return flattenerCopier;
234 }
235
236 private PBody prepareFlatPBody(PBody pBody) {
237 PBodyCopier copier = createBodyCopier(pBody.getPattern(), Collections.<PositivePatternCall, PBody> emptyMap());
238 copier.mergeBody(pBody, new SameName(), new AllowAllFilter());
239 // the copying of the body here is necessary for only one containing PDisjunction can be assigned to a PBody
240 return copier.getCopiedBody();
241 }
242
243 private boolean isFlatteningNeeded(PBody pBody) {
244 // Check if the body contains positive pattern call AND if it should be flattened
245 for (PConstraint pConstraint : pBody.getConstraints()) {
246 if (pConstraint instanceof PositivePatternCall) {
247 return flattenCallPredicate.shouldFlatten((PositivePatternCall) pConstraint);
248 }
249 }
250 return false;
251 }
252
253}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/RewriterException.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/RewriterException.java
new file mode 100644
index 00000000..d0fc286b
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/RewriterException.java
@@ -0,0 +1,31 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, 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.matchers.psystem.rewriters;
10
11import tools.refinery.viatra.runtime.matchers.psystem.queries.QueryInitializationException;
12
13/**
14 * An exception to wrap various issues during PDisjunction rewriting.
15 * @author Zoltan Ujhelyi
16 *
17 */
18public class RewriterException extends QueryInitializationException {
19
20 private static final long serialVersionUID = -4703825954995497932L;
21
22 public RewriterException(String message, String[] context, String shortMessage, Object patternDescription,
23 Throwable cause) {
24 super(message, context, shortMessage, patternDescription, cause);
25 }
26
27 public RewriterException(String message, String[] context, String shortMessage, Object patternDescription) {
28 super(message, context, shortMessage, patternDescription);
29 }
30
31}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/SurrogateQueryRewriter.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/SurrogateQueryRewriter.java
new file mode 100644
index 00000000..71459558
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/SurrogateQueryRewriter.java
@@ -0,0 +1,63 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, 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.matchers.psystem.rewriters;
10
11import java.util.LinkedHashSet;
12import java.util.Set;
13
14import tools.refinery.viatra.runtime.matchers.context.IInputKey;
15import tools.refinery.viatra.runtime.matchers.context.surrogate.SurrogateQueryRegistry;
16import tools.refinery.viatra.runtime.matchers.psystem.PBody;
17import tools.refinery.viatra.runtime.matchers.psystem.PVariable;
18import tools.refinery.viatra.runtime.matchers.psystem.basicenumerables.PositivePatternCall;
19import tools.refinery.viatra.runtime.matchers.psystem.basicenumerables.TypeConstraint;
20import tools.refinery.viatra.runtime.matchers.psystem.queries.PDisjunction;
21import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery;
22import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery.PQueryStatus;
23import tools.refinery.viatra.runtime.matchers.tuple.Tuple;
24import tools.refinery.viatra.runtime.matchers.tuple.Tuples;
25
26/**
27 * @author Zoltan Ujhelyi
28 *
29 */
30public class SurrogateQueryRewriter extends PDisjunctionRewriter {
31
32 @Override
33 public PDisjunction rewrite(PDisjunction disjunction) {
34 Set<PBody> replacedBodies = new LinkedHashSet<>();
35 for (PBody body : disjunction.getBodies()) {
36 PBodyCopier copier = new PBodyCopier(body, getTraceCollector()) {
37
38 @Override
39 protected void copyTypeConstraint(TypeConstraint typeConstraint) {
40 PVariable[] mappedVariables = extractMappedVariables(typeConstraint);
41 Tuple variablesTuple = Tuples.flatTupleOf((Object[])mappedVariables);
42 final IInputKey supplierKey = typeConstraint.getSupplierKey();
43 if(SurrogateQueryRegistry.instance().hasSurrogateQueryFQN(supplierKey)) {
44 PQuery surrogateQuery = SurrogateQueryRegistry.instance().getSurrogateQuery(supplierKey);
45 if (surrogateQuery == null) {
46 throw new IllegalStateException(
47 String.format("Surrogate query for feature %s not found",
48 supplierKey.getPrettyPrintableName()));
49 }
50 addTrace(typeConstraint, new PositivePatternCall(getCopiedBody(), variablesTuple, surrogateQuery));
51 } else {
52 addTrace(typeConstraint, new TypeConstraint(getCopiedBody(), variablesTuple, supplierKey));
53 }
54 }
55 };
56 PBody modifiedBody = copier.getCopiedBody();
57 replacedBodies.add(modifiedBody);
58 modifiedBody.setStatus(PQueryStatus.OK);
59 }
60 return new PDisjunction(replacedBodies);
61 }
62
63}
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/VariableMappingExpressionEvaluatorWrapper.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/VariableMappingExpressionEvaluatorWrapper.java
new file mode 100644
index 00000000..10337979
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/VariableMappingExpressionEvaluatorWrapper.java
@@ -0,0 +1,88 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Grill Balázs, 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.matchers.psystem.rewriters;
10
11import java.util.HashMap;
12import java.util.LinkedHashMap;
13import java.util.Map;
14
15import tools.refinery.viatra.runtime.matchers.psystem.IExpressionEvaluator;
16import tools.refinery.viatra.runtime.matchers.psystem.IValueProvider;
17import tools.refinery.viatra.runtime.matchers.psystem.PVariable;
18import tools.refinery.viatra.runtime.matchers.util.Preconditions;
19
20/**
21 * A wrapper for {@link IExpressionEvaluator} which is capable of correctly mapping variable names used by the
22 * expression.
23 *
24 * @author Grill Balázs
25 *
26 */
27class VariableMappingExpressionEvaluatorWrapper implements IExpressionEvaluator {
28
29 private final IExpressionEvaluator wrapped;
30 private final Map<String, String> variableMapping;
31
32 public VariableMappingExpressionEvaluatorWrapper(IExpressionEvaluator wrapped,
33 Map<PVariable, PVariable> variableMapping) {
34
35 // Support to rewrap an already wrapped expression.
36 boolean rewrap = wrapped instanceof VariableMappingExpressionEvaluatorWrapper;
37 this.wrapped = rewrap ? ((VariableMappingExpressionEvaluatorWrapper)wrapped).wrapped : wrapped;
38
39 // Instead of just saving the reference of the mapping, save the actual (trimmed) state of the mapping as it
40 // may change during copying (especially during flattening). A LinkedHashMap is used to retain ordering of
41 // original parameter names iterator.
42 this.variableMapping = new LinkedHashMap<>();
43
44 // Index map by variable names
45 Map<String, PVariable> names = new HashMap<>();
46 for (PVariable originalVar : variableMapping.keySet()) {
47 names.put(originalVar.getName(), originalVar);
48 }
49
50 // In case of rewrapping, current names are contained by the previous mapping
51 Map<String, String> previousMapping = null;
52 if (rewrap){
53 previousMapping = ((VariableMappingExpressionEvaluatorWrapper)wrapped).variableMapping;
54 }
55
56 // Populate mapping
57 for (String inputParameterName : this.wrapped.getInputParameterNames()) {
58 String parameterName = rewrap ? previousMapping.get(inputParameterName) : inputParameterName;
59 Preconditions.checkArgument(parameterName != null);
60 PVariable original = names.get(parameterName);
61 Preconditions.checkArgument(original != null);
62 PVariable mapped = variableMapping.get(original);
63 if (mapped != null){
64 this.variableMapping.put(inputParameterName, mapped.getName());
65 }
66 }
67 }
68
69 @Override
70 public String getShortDescription() {
71 return wrapped.getShortDescription();
72 }
73
74 @Override
75 public Iterable<String> getInputParameterNames() {
76 return variableMapping.values();
77 }
78
79 @Override
80 public Object evaluateExpression(final IValueProvider provider) throws Exception {
81 return wrapped.evaluateExpression(variableName -> {
82 String mappedVariableName = variableMapping.get(variableName);
83 Preconditions.checkArgument(mappedVariableName != null, "Could not find variable %s", variableName);
84 return provider.getValue(mappedVariableName);
85 });
86 }
87
88}