diff options
Diffstat (limited to 'subprojects/store-query/src/main/java/tools/refinery/store/query/literal/RepresentativeElectionLiteral.java')
-rw-r--r-- | subprojects/store-query/src/main/java/tools/refinery/store/query/literal/RepresentativeElectionLiteral.java | 119 |
1 files changed, 119 insertions, 0 deletions
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..f7323947 --- /dev/null +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/RepresentativeElectionLiteral.java | |||
@@ -0,0 +1,119 @@ | |||
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.InvalidQueryException; | ||
10 | import tools.refinery.store.query.equality.LiteralEqualityHelper; | ||
11 | import tools.refinery.store.query.equality.LiteralHashCodeHelper; | ||
12 | import tools.refinery.store.query.substitution.Substitution; | ||
13 | import tools.refinery.store.query.term.NodeVariable; | ||
14 | import tools.refinery.store.query.term.ParameterDirection; | ||
15 | import tools.refinery.store.query.term.Variable; | ||
16 | |||
17 | import java.util.List; | ||
18 | import java.util.Set; | ||
19 | |||
20 | // {@link Object#equals(Object)} is implemented by {@link AbstractLiteral}. | ||
21 | @SuppressWarnings("squid:S2160") | ||
22 | public class RepresentativeElectionLiteral extends AbstractCallLiteral { | ||
23 | private final Connectivity connectivity; | ||
24 | |||
25 | public RepresentativeElectionLiteral(Connectivity connectivity, Constraint target, NodeVariable specific, | ||
26 | NodeVariable representative) { | ||
27 | this(connectivity, target, List.of(specific, representative)); | ||
28 | } | ||
29 | |||
30 | private RepresentativeElectionLiteral(Connectivity connectivity, Constraint target, List<Variable> arguments) { | ||
31 | super(target, arguments); | ||
32 | this.connectivity = connectivity; | ||
33 | var parameters = target.getParameters(); | ||
34 | int arity = target.arity(); | ||
35 | if (arity != 2) { | ||
36 | throw new InvalidQueryException("SCCs can only take binary relations"); | ||
37 | } | ||
38 | if (parameters.get(0).isDataVariable() || parameters.get(1).isDataVariable()) { | ||
39 | throw new InvalidQueryException("SCCs can only be computed over nodes"); | ||
40 | } | ||
41 | if (parameters.get(0).getDirection() != ParameterDirection.OUT || | ||
42 | parameters.get(1).getDirection() != ParameterDirection.OUT) { | ||
43 | throw new InvalidQueryException("SCCs cannot take input parameters"); | ||
44 | } | ||
45 | } | ||
46 | |||
47 | public Connectivity getConnectivity() { | ||
48 | return connectivity; | ||
49 | } | ||
50 | |||
51 | @Override | ||
52 | protected Literal doSubstitute(Substitution substitution, List<Variable> substitutedArguments) { | ||
53 | return new RepresentativeElectionLiteral(connectivity, getTarget(), substitutedArguments); | ||
54 | } | ||
55 | |||
56 | @Override | ||
57 | public Set<Variable> getOutputVariables() { | ||
58 | return getArgumentsOfDirection(ParameterDirection.OUT); | ||
59 | } | ||
60 | |||
61 | @Override | ||
62 | public Set<Variable> getInputVariables(Set<? extends Variable> positiveVariablesInClause) { | ||
63 | return Set.of(); | ||
64 | } | ||
65 | |||
66 | @Override | ||
67 | public Set<Variable> getPrivateVariables(Set<? extends Variable> positiveVariablesInClause) { | ||
68 | return Set.of(); | ||
69 | } | ||
70 | |||
71 | @Override | ||
72 | public Literal reduce() { | ||
73 | var reduction = getTarget().getReduction(); | ||
74 | return switch (reduction) { | ||
75 | case ALWAYS_FALSE -> BooleanLiteral.FALSE; | ||
76 | case ALWAYS_TRUE -> throw new InvalidQueryException( | ||
77 | "Trying to elect representatives over an infinite set"); | ||
78 | case NOT_REDUCIBLE -> this; | ||
79 | }; | ||
80 | } | ||
81 | |||
82 | @Override | ||
83 | public AbstractCallLiteral withArguments(Constraint newTarget, List<Variable> newArguments) { | ||
84 | return new RepresentativeElectionLiteral(connectivity, newTarget, newArguments); | ||
85 | } | ||
86 | |||
87 | @Override | ||
88 | public boolean equalsWithSubstitution(LiteralEqualityHelper helper, Literal other) { | ||
89 | if (!super.equalsWithSubstitution(helper, other)) { | ||
90 | return false; | ||
91 | } | ||
92 | var otherRepresentativeElectionLiteral = (RepresentativeElectionLiteral) other; | ||
93 | return connectivity.equals(otherRepresentativeElectionLiteral.connectivity); | ||
94 | } | ||
95 | |||
96 | @Override | ||
97 | public int hashCodeWithSubstitution(LiteralHashCodeHelper helper) { | ||
98 | return super.hashCodeWithSubstitution(helper) * 31 + connectivity.hashCode(); | ||
99 | } | ||
100 | |||
101 | @Override | ||
102 | public String toString() { | ||
103 | var builder = new StringBuilder(); | ||
104 | builder.append("@Representative(\""); | ||
105 | builder.append(connectivity); | ||
106 | builder.append("\") "); | ||
107 | builder.append(getTarget().toReferenceString()); | ||
108 | builder.append("("); | ||
109 | var argumentIterator = getArguments().iterator(); | ||
110 | if (argumentIterator.hasNext()) { | ||
111 | builder.append(argumentIterator.next()); | ||
112 | while (argumentIterator.hasNext()) { | ||
113 | builder.append(", ").append(argumentIterator.next()); | ||
114 | } | ||
115 | } | ||
116 | builder.append(")"); | ||
117 | return builder.toString(); | ||
118 | } | ||
119 | } | ||