diff options
author | 2023-07-21 02:18:06 +0200 | |
---|---|---|
committer | 2023-07-23 13:14:24 +0200 | |
commit | 7f2df1ba80aac7e1c5e99315bf5a8e32ad7456da (patch) | |
tree | d0a4c5e7104d054c6f77d1920a1459993726808c /subprojects/store-query | |
parent | feat: partial interpretation for type hierarchy (diff) | |
download | refinery-7f2df1ba80aac7e1c5e99315bf5a8e32ad7456da.tar.gz refinery-7f2df1ba80aac7e1c5e99315bf5a8e32ad7456da.tar.zst refinery-7f2df1ba80aac7e1c5e99315bf5a8e32ad7456da.zip |
feat: custom connected component RETE node
Diffstat (limited to 'subprojects/store-query')
3 files changed, 124 insertions, 0 deletions
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CallLiteral.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CallLiteral.java index b1585c77..3a80cefd 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CallLiteral.java +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CallLiteral.java | |||
@@ -30,6 +30,10 @@ public final class CallLiteral extends AbstractCallLiteral implements CanNegate< | |||
30 | if (parameters.get(0).isDataVariable() || parameters.get(1).isDataVariable()) { | 30 | if (parameters.get(0).isDataVariable() || parameters.get(1).isDataVariable()) { |
31 | throw new IllegalArgumentException("Transitive closures can only be computed over nodes"); | 31 | throw new IllegalArgumentException("Transitive closures can only be computed over nodes"); |
32 | } | 32 | } |
33 | if (parameters.get(0).getDirection() != ParameterDirection.OUT || | ||
34 | parameters.get(1).getDirection() != ParameterDirection.OUT) { | ||
35 | throw new IllegalArgumentException("Transitive closures cannot take input parameters"); | ||
36 | } | ||
33 | } | 37 | } |
34 | this.polarity = polarity; | 38 | this.polarity = polarity; |
35 | } | 39 | } |
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/Connectivity.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/Connectivity.java new file mode 100644 index 00000000..a058094d --- /dev/null +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/Connectivity.java | |||
@@ -0,0 +1,18 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.query.literal; | ||
7 | |||
8 | import java.util.Locale; | ||
9 | |||
10 | public enum Connectivity { | ||
11 | WEAK, | ||
12 | STRONG; | ||
13 | |||
14 | @Override | ||
15 | public String toString() { | ||
16 | return name().toLowerCase(Locale.ROOT); | ||
17 | } | ||
18 | } | ||
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/RepresentativeElectionLiteral.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/RepresentativeElectionLiteral.java new file mode 100644 index 00000000..876ae253 --- /dev/null +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/RepresentativeElectionLiteral.java | |||
@@ -0,0 +1,102 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.query.literal; | ||
7 | |||
8 | import tools.refinery.store.query.Constraint; | ||
9 | import tools.refinery.store.query.substitution.Substitution; | ||
10 | import tools.refinery.store.query.term.NodeVariable; | ||
11 | import tools.refinery.store.query.term.ParameterDirection; | ||
12 | import tools.refinery.store.query.term.Variable; | ||
13 | |||
14 | import java.util.List; | ||
15 | import java.util.Set; | ||
16 | |||
17 | // {@link Object#equals(Object)} is implemented by {@link AbstractLiteral}. | ||
18 | @SuppressWarnings("squid:S2160") | ||
19 | public class RepresentativeElectionLiteral extends AbstractCallLiteral { | ||
20 | private final Connectivity connectivity; | ||
21 | |||
22 | public RepresentativeElectionLiteral(Connectivity connectivity, Constraint target, NodeVariable specific, | ||
23 | NodeVariable representative) { | ||
24 | this(connectivity, target, List.of(specific, representative)); | ||
25 | } | ||
26 | |||
27 | private RepresentativeElectionLiteral(Connectivity connectivity, Constraint target, List<Variable> arguments) { | ||
28 | super(target, arguments); | ||
29 | this.connectivity = connectivity; | ||
30 | var parameters = target.getParameters(); | ||
31 | int arity = target.arity(); | ||
32 | if (arity != 2) { | ||
33 | throw new IllegalArgumentException("SCCs can only take binary relations"); | ||
34 | } | ||
35 | if (parameters.get(0).isDataVariable() || parameters.get(1).isDataVariable()) { | ||
36 | throw new IllegalArgumentException("SCCs can only be computed over nodes"); | ||
37 | } | ||
38 | if (parameters.get(0).getDirection() != ParameterDirection.OUT || | ||
39 | parameters.get(1).getDirection() != ParameterDirection.OUT) { | ||
40 | throw new IllegalArgumentException("SCCs cannot take input parameters"); | ||
41 | } | ||
42 | } | ||
43 | |||
44 | public Connectivity getConnectivity() { | ||
45 | return connectivity; | ||
46 | } | ||
47 | |||
48 | @Override | ||
49 | protected Literal doSubstitute(Substitution substitution, List<Variable> substitutedArguments) { | ||
50 | return new RepresentativeElectionLiteral(connectivity, getTarget(), substitutedArguments); | ||
51 | } | ||
52 | |||
53 | @Override | ||
54 | public Set<Variable> getOutputVariables() { | ||
55 | return getArgumentsOfDirection(ParameterDirection.OUT); | ||
56 | } | ||
57 | |||
58 | @Override | ||
59 | public Set<Variable> getInputVariables(Set<? extends Variable> positiveVariablesInClause) { | ||
60 | return Set.of(); | ||
61 | } | ||
62 | |||
63 | @Override | ||
64 | public Set<Variable> getPrivateVariables(Set<? extends Variable> positiveVariablesInClause) { | ||
65 | return Set.of(); | ||
66 | } | ||
67 | |||
68 | @Override | ||
69 | public Literal reduce() { | ||
70 | var reduction = getTarget().getReduction(); | ||
71 | return switch (reduction) { | ||
72 | case ALWAYS_FALSE -> BooleanLiteral.FALSE; | ||
73 | case ALWAYS_TRUE -> throw new IllegalArgumentException( | ||
74 | "Trying to elect representatives over an infinite set"); | ||
75 | case NOT_REDUCIBLE -> this; | ||
76 | }; | ||
77 | } | ||
78 | |||
79 | @Override | ||
80 | protected AbstractCallLiteral internalWithTarget(Constraint newTarget) { | ||
81 | return new RepresentativeElectionLiteral(connectivity, newTarget, getArguments()); | ||
82 | } | ||
83 | |||
84 | @Override | ||
85 | public String toString() { | ||
86 | var builder = new StringBuilder(); | ||
87 | builder.append("@Representative(\""); | ||
88 | builder.append(connectivity); | ||
89 | builder.append("\") "); | ||
90 | builder.append(getTarget().toReferenceString()); | ||
91 | builder.append("("); | ||
92 | var argumentIterator = getArguments().iterator(); | ||
93 | if (argumentIterator.hasNext()) { | ||
94 | builder.append(argumentIterator.next()); | ||
95 | while (argumentIterator.hasNext()) { | ||
96 | builder.append(", ").append(argumentIterator.next()); | ||
97 | } | ||
98 | } | ||
99 | builder.append(")"); | ||
100 | return builder.toString(); | ||
101 | } | ||
102 | } | ||