aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/store-query-viatra/src/main
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2022-11-27 21:11:39 +0100
committerLibravatar Kristóf Marussy <kristof@marussy.com>2022-12-09 00:07:38 +0100
commit3c1e93b7cb50d20abe08f1b95b8dc8d62ed4c38c (patch)
tree21f4c04e750614d9f60484a08ee5402452acaf01 /subprojects/store-query-viatra/src/main
parentrefactor: be more conservative w/preview features (diff)
downloadrefinery-3c1e93b7cb50d20abe08f1b95b8dc8d62ed4c38c.tar.gz
refinery-3c1e93b7cb50d20abe08f1b95b8dc8d62ed4c38c.tar.zst
refinery-3c1e93b7cb50d20abe08f1b95b8dc8d62ed4c38c.zip
feat: add cardinality interval abstraction
Diffstat (limited to 'subprojects/store-query-viatra/src/main')
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/cardinality/UpperCardinalitySumAggregationOperator.java97
1 files changed, 97 insertions, 0 deletions
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/cardinality/UpperCardinalitySumAggregationOperator.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/cardinality/UpperCardinalitySumAggregationOperator.java
new file mode 100644
index 00000000..ffd5f6de
--- /dev/null
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/cardinality/UpperCardinalitySumAggregationOperator.java
@@ -0,0 +1,97 @@
1package tools.refinery.store.query.viatra.internal.cardinality;
2
3import org.eclipse.viatra.query.runtime.matchers.psystem.aggregations.BoundAggregator;
4import org.eclipse.viatra.query.runtime.matchers.psystem.aggregations.IMultisetAggregationOperator;
5import tools.refinery.store.model.representation.cardinality.FiniteUpperCardinality;
6import tools.refinery.store.model.representation.cardinality.UnboundedUpperCardinality;
7import tools.refinery.store.model.representation.cardinality.UpperCardinalities;
8import tools.refinery.store.model.representation.cardinality.UpperCardinality;
9
10import java.util.stream.Stream;
11
12public class UpperCardinalitySumAggregationOperator implements IMultisetAggregationOperator<UpperCardinality,
13 UpperCardinalitySumAggregationOperator.Accumulator, UpperCardinality> {
14 public static final UpperCardinalitySumAggregationOperator INSTANCE = new UpperCardinalitySumAggregationOperator();
15
16 public static final BoundAggregator BOUND_AGGREGATOR = new BoundAggregator(INSTANCE, UpperCardinality.class,
17 UpperCardinality.class);
18
19 private UpperCardinalitySumAggregationOperator() {
20 // Singleton constructor.
21 }
22
23 @Override
24 public String getName() {
25 return "sum<UpperCardinality>";
26 }
27
28 @Override
29 public String getShortDescription() {
30 return "%s computes the sum of finite or unbounded upper cardinalities".formatted(getName());
31 }
32
33 @Override
34 public Accumulator createNeutral() {
35 return new Accumulator();
36 }
37
38 @Override
39 public boolean isNeutral(Accumulator result) {
40 return result.sumFiniteUpperBounds == 0 && result.countUnbounded == 0;
41 }
42
43 @Override
44 public Accumulator update(Accumulator oldResult, UpperCardinality updateValue, boolean isInsertion) {
45 if (updateValue instanceof FiniteUpperCardinality finiteUpperCardinality) {
46 int finiteUpperBound = finiteUpperCardinality.finiteUpperBound();
47 if (isInsertion) {
48 oldResult.sumFiniteUpperBounds += finiteUpperBound;
49 } else {
50 oldResult.sumFiniteUpperBounds -= finiteUpperBound;
51 }
52 } else if (updateValue instanceof UnboundedUpperCardinality) {
53 if (isInsertion) {
54 oldResult.countUnbounded += 1;
55 } else {
56 oldResult.countUnbounded -= 1;
57 }
58 } else {
59 throw new IllegalArgumentException("Unknown UpperCardinality: " + updateValue);
60 }
61 return oldResult;
62 }
63
64 @Override
65 public UpperCardinality getAggregate(Accumulator result) {
66 return result.countUnbounded > 0 ? UpperCardinalities.UNBOUNDED :
67 UpperCardinalities.valueOf(result.sumFiniteUpperBounds);
68 }
69
70 @Override
71 public UpperCardinality aggregateStream(Stream<UpperCardinality> stream) {
72 var result = stream.collect(this::createNeutral, (accumulator, value) -> update(accumulator, value, true),
73 (left, right) -> new Accumulator(left.sumFiniteUpperBounds + right.sumFiniteUpperBounds,
74 left.countUnbounded + right.countUnbounded));
75 return getAggregate(result);
76 }
77
78 @Override
79 public Accumulator clone(Accumulator original) {
80 return new Accumulator(original.sumFiniteUpperBounds, original.countUnbounded);
81 }
82
83 public static class Accumulator {
84 private int sumFiniteUpperBounds;
85
86 private int countUnbounded;
87
88 private Accumulator(int sumFiniteUpperBounds, int countUnbounded) {
89 this.sumFiniteUpperBounds = sumFiniteUpperBounds;
90 this.countUnbounded = countUnbounded;
91 }
92
93 private Accumulator() {
94 this(0, 0);
95 }
96 }
97}