diff options
author | Kristóf Marussy <kristof@marussy.com> | 2024-03-07 22:10:42 +0100 |
---|---|---|
committer | Kristóf Marussy <kristof@marussy.com> | 2024-04-07 14:55:46 +0200 |
commit | 16a9b534adec2c53b50f92a43c1623918b1c59c0 (patch) | |
tree | 690b299a2ca31e302ddad219a7aa94bcf86d5d0b /subprojects/store | |
parent | fix(frontend): * operator highlighting (diff) | |
download | refinery-16a9b534adec2c53b50f92a43c1623918b1c59c0.tar.gz refinery-16a9b534adec2c53b50f92a43c1623918b1c59c0.tar.zst refinery-16a9b534adec2c53b50f92a43c1623918b1c59c0.zip |
refactor: move terms and DNF into logic subproject
Diffstat (limited to 'subprojects/store')
21 files changed, 0 insertions, 1164 deletions
diff --git a/subprojects/store/src/main/java/tools/refinery/store/representation/AbstractDomain.java b/subprojects/store/src/main/java/tools/refinery/store/representation/AbstractDomain.java deleted file mode 100644 index dfdb43bd..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/representation/AbstractDomain.java +++ /dev/null | |||
@@ -1,37 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.representation; | ||
7 | |||
8 | import java.util.Objects; | ||
9 | import java.util.Optional; | ||
10 | |||
11 | public non-sealed interface AbstractDomain<A, C> extends AnyAbstractDomain { | ||
12 | @Override | ||
13 | Class<A> abstractType(); | ||
14 | |||
15 | @Override | ||
16 | Class<C> concreteType(); | ||
17 | |||
18 | A toAbstract(C concreteValue); | ||
19 | |||
20 | Optional<C> toConcrete(A abstractValue); | ||
21 | |||
22 | default boolean isConcrete(A abstractValue) { | ||
23 | return toConcrete(abstractValue).isPresent(); | ||
24 | } | ||
25 | |||
26 | default boolean isRefinement(A originalValue, A refinedValue) { | ||
27 | return Objects.equals(commonRefinement(originalValue, refinedValue), refinedValue); | ||
28 | } | ||
29 | |||
30 | A commonRefinement(A leftValue, A rightValue); | ||
31 | |||
32 | A commonAncestor(A leftValue, A rightValue); | ||
33 | |||
34 | A unknown(); | ||
35 | |||
36 | boolean isError(A abstractValue); | ||
37 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/representation/AnyAbstractDomain.java b/subprojects/store/src/main/java/tools/refinery/store/representation/AnyAbstractDomain.java deleted file mode 100644 index c354fab7..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/representation/AnyAbstractDomain.java +++ /dev/null | |||
@@ -1,12 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.representation; | ||
7 | |||
8 | public sealed interface AnyAbstractDomain permits AbstractDomain { | ||
9 | Class<?> abstractType(); | ||
10 | |||
11 | Class<?> concreteType(); | ||
12 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/representation/TruthValue.java b/subprojects/store/src/main/java/tools/refinery/store/representation/TruthValue.java deleted file mode 100644 index f81ee9a4..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/representation/TruthValue.java +++ /dev/null | |||
@@ -1,76 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.representation; | ||
7 | |||
8 | public enum TruthValue { | ||
9 | TRUE("true"), | ||
10 | |||
11 | FALSE("false"), | ||
12 | |||
13 | UNKNOWN("unknown"), | ||
14 | |||
15 | ERROR("error"); | ||
16 | |||
17 | private final String name; | ||
18 | |||
19 | TruthValue(String name) { | ||
20 | this.name = name; | ||
21 | } | ||
22 | |||
23 | public String getName() { | ||
24 | return name; | ||
25 | } | ||
26 | |||
27 | public static TruthValue toTruthValue(boolean value) { | ||
28 | return value ? TRUE : FALSE; | ||
29 | } | ||
30 | |||
31 | public boolean isConsistent() { | ||
32 | return this != ERROR; | ||
33 | } | ||
34 | |||
35 | public boolean isComplete() { | ||
36 | return this != UNKNOWN; | ||
37 | } | ||
38 | |||
39 | public boolean isConcrete() { | ||
40 | return this == TRUE || this == FALSE; | ||
41 | } | ||
42 | |||
43 | public boolean must() { | ||
44 | return this == TRUE || this == ERROR; | ||
45 | } | ||
46 | |||
47 | public boolean may() { | ||
48 | return this == TRUE || this == UNKNOWN; | ||
49 | } | ||
50 | |||
51 | public TruthValue not() { | ||
52 | return switch (this) { | ||
53 | case TRUE -> FALSE; | ||
54 | case FALSE -> TRUE; | ||
55 | default -> this; | ||
56 | }; | ||
57 | } | ||
58 | |||
59 | public TruthValue merge(TruthValue other) { | ||
60 | return switch (this) { | ||
61 | case TRUE -> other == UNKNOWN || other == TRUE ? TRUE : ERROR; | ||
62 | case FALSE -> other == UNKNOWN || other == FALSE ? FALSE : ERROR; | ||
63 | case UNKNOWN -> other; | ||
64 | case ERROR -> ERROR; | ||
65 | }; | ||
66 | } | ||
67 | |||
68 | public TruthValue join(TruthValue other) { | ||
69 | return switch (this) { | ||
70 | case TRUE -> other == ERROR || other == TRUE ? TRUE : UNKNOWN; | ||
71 | case FALSE -> other == ERROR || other == FALSE ? FALSE : UNKNOWN; | ||
72 | case UNKNOWN -> UNKNOWN; | ||
73 | case ERROR -> other; | ||
74 | }; | ||
75 | } | ||
76 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/representation/TruthValueDomain.java b/subprojects/store/src/main/java/tools/refinery/store/representation/TruthValueDomain.java deleted file mode 100644 index 61696dca..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/representation/TruthValueDomain.java +++ /dev/null | |||
@@ -1,66 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.representation; | ||
7 | |||
8 | import java.util.Optional; | ||
9 | |||
10 | // Singleton pattern, because there is only one domain for truth values. | ||
11 | @SuppressWarnings("squid:S6548") | ||
12 | public final class TruthValueDomain implements AbstractDomain<TruthValue, Boolean> { | ||
13 | public static final TruthValueDomain INSTANCE = new TruthValueDomain(); | ||
14 | |||
15 | private TruthValueDomain() { | ||
16 | } | ||
17 | |||
18 | @Override | ||
19 | public Class<TruthValue> abstractType() { | ||
20 | return TruthValue.class; | ||
21 | } | ||
22 | |||
23 | @Override | ||
24 | public Class<Boolean> concreteType() { | ||
25 | return Boolean.class; | ||
26 | } | ||
27 | |||
28 | @Override | ||
29 | public TruthValue toAbstract(Boolean concreteValue) { | ||
30 | return TruthValue.toTruthValue(concreteValue); | ||
31 | } | ||
32 | |||
33 | @Override | ||
34 | public Optional<Boolean> toConcrete(TruthValue abstractValue) { | ||
35 | return switch (abstractValue) { | ||
36 | case TRUE -> Optional.of(true); | ||
37 | case FALSE -> Optional.of(false); | ||
38 | default -> Optional.empty(); | ||
39 | }; | ||
40 | } | ||
41 | |||
42 | @Override | ||
43 | public boolean isConcrete(TruthValue abstractValue) { | ||
44 | return abstractValue.isConcrete(); | ||
45 | } | ||
46 | |||
47 | @Override | ||
48 | public TruthValue commonRefinement(TruthValue leftValue, TruthValue rightValue) { | ||
49 | return leftValue.merge(rightValue); | ||
50 | } | ||
51 | |||
52 | @Override | ||
53 | public TruthValue commonAncestor(TruthValue leftValue, TruthValue rightValue) { | ||
54 | return leftValue.join(rightValue); | ||
55 | } | ||
56 | |||
57 | @Override | ||
58 | public TruthValue unknown() { | ||
59 | return TruthValue.UNKNOWN; | ||
60 | } | ||
61 | |||
62 | @Override | ||
63 | public boolean isError(TruthValue abstractValue) { | ||
64 | return !abstractValue.isConsistent(); | ||
65 | } | ||
66 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/CardinalityDomain.java b/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/CardinalityDomain.java deleted file mode 100644 index 7ae2d935..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/CardinalityDomain.java +++ /dev/null | |||
@@ -1,68 +0,0 @@ | |||
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.representation.cardinality; | ||
7 | |||
8 | import tools.refinery.store.representation.AbstractDomain; | ||
9 | |||
10 | import java.util.Optional; | ||
11 | |||
12 | // Singleton pattern, because there is only one domain for truth values. | ||
13 | @SuppressWarnings("squid:S6548") | ||
14 | public class CardinalityDomain implements AbstractDomain<CardinalityInterval, Integer> { | ||
15 | public static final CardinalityDomain INSTANCE = new CardinalityDomain(); | ||
16 | |||
17 | private CardinalityDomain() { | ||
18 | } | ||
19 | |||
20 | @Override | ||
21 | public Class<CardinalityInterval> abstractType() { | ||
22 | return CardinalityInterval.class; | ||
23 | } | ||
24 | |||
25 | @Override | ||
26 | public Class<Integer> concreteType() { | ||
27 | return Integer.class; | ||
28 | } | ||
29 | |||
30 | @Override | ||
31 | public CardinalityInterval toAbstract(Integer concreteValue) { | ||
32 | return CardinalityIntervals.exactly(concreteValue); | ||
33 | } | ||
34 | |||
35 | @Override | ||
36 | public Optional<Integer> toConcrete(CardinalityInterval abstractValue) { | ||
37 | return isConcrete(abstractValue) ? Optional.of(abstractValue.lowerBound()) : Optional.empty(); | ||
38 | } | ||
39 | |||
40 | @Override | ||
41 | public boolean isConcrete(CardinalityInterval abstractValue) { | ||
42 | if (!(abstractValue instanceof NonEmptyCardinalityInterval nonEmptyValue) || | ||
43 | !((nonEmptyValue.upperBound()) instanceof FiniteUpperCardinality finiteUpperCardinality)) { | ||
44 | return false; | ||
45 | } | ||
46 | return nonEmptyValue.lowerBound() == finiteUpperCardinality.finiteUpperBound(); | ||
47 | } | ||
48 | |||
49 | @Override | ||
50 | public CardinalityInterval commonRefinement(CardinalityInterval leftValue, CardinalityInterval rightValue) { | ||
51 | return leftValue.meet(rightValue); | ||
52 | } | ||
53 | |||
54 | @Override | ||
55 | public CardinalityInterval commonAncestor(CardinalityInterval leftValue, CardinalityInterval rightValue) { | ||
56 | return leftValue.join(rightValue); | ||
57 | } | ||
58 | |||
59 | @Override | ||
60 | public CardinalityInterval unknown() { | ||
61 | return CardinalityIntervals.SET; | ||
62 | } | ||
63 | |||
64 | @Override | ||
65 | public boolean isError(CardinalityInterval abstractValue) { | ||
66 | return abstractValue.isEmpty(); | ||
67 | } | ||
68 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/CardinalityInterval.java b/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/CardinalityInterval.java deleted file mode 100644 index b20c685a..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/CardinalityInterval.java +++ /dev/null | |||
@@ -1,28 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.representation.cardinality; | ||
7 | |||
8 | public sealed interface CardinalityInterval permits NonEmptyCardinalityInterval, EmptyCardinalityInterval { | ||
9 | int lowerBound(); | ||
10 | |||
11 | UpperCardinality upperBound(); | ||
12 | |||
13 | boolean isEmpty(); | ||
14 | |||
15 | CardinalityInterval min(CardinalityInterval other); | ||
16 | |||
17 | CardinalityInterval max(CardinalityInterval other); | ||
18 | |||
19 | CardinalityInterval add(CardinalityInterval other); | ||
20 | |||
21 | CardinalityInterval take(int count); | ||
22 | |||
23 | CardinalityInterval multiply(CardinalityInterval other); | ||
24 | |||
25 | CardinalityInterval meet(CardinalityInterval other); | ||
26 | |||
27 | CardinalityInterval join(CardinalityInterval other); | ||
28 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/CardinalityIntervals.java b/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/CardinalityIntervals.java deleted file mode 100644 index 855fd248..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/CardinalityIntervals.java +++ /dev/null | |||
@@ -1,51 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.representation.cardinality; | ||
7 | |||
8 | public final class CardinalityIntervals { | ||
9 | public static final CardinalityInterval NONE = exactly(0); | ||
10 | |||
11 | public static final CardinalityInterval ONE = exactly(1); | ||
12 | |||
13 | public static final CardinalityInterval LONE = atMost(1); | ||
14 | |||
15 | public static final CardinalityInterval SET = atLeast(0); | ||
16 | |||
17 | public static final CardinalityInterval SOME = atLeast(1); | ||
18 | |||
19 | public static final CardinalityInterval ERROR = EmptyCardinalityInterval.INSTANCE; | ||
20 | |||
21 | private CardinalityIntervals() { | ||
22 | throw new IllegalStateException("This is a static utility class and should not be instantiated directly"); | ||
23 | } | ||
24 | |||
25 | public static CardinalityInterval between(int lowerBound, UpperCardinality upperBound) { | ||
26 | if (upperBound.compareToInt(lowerBound) < 0) { | ||
27 | return ERROR; | ||
28 | } | ||
29 | return new NonEmptyCardinalityInterval(lowerBound, upperBound); | ||
30 | } | ||
31 | |||
32 | public static CardinalityInterval between(int lowerBound, int upperBound) { | ||
33 | return between(lowerBound, UpperCardinalities.atMost(upperBound)); | ||
34 | } | ||
35 | |||
36 | public static CardinalityInterval atMost(UpperCardinality upperBound) { | ||
37 | return new NonEmptyCardinalityInterval(0, upperBound); | ||
38 | } | ||
39 | |||
40 | public static CardinalityInterval atMost(int upperBound) { | ||
41 | return atMost(UpperCardinalities.atMost(upperBound)); | ||
42 | } | ||
43 | |||
44 | public static CardinalityInterval atLeast(int lowerBound) { | ||
45 | return new NonEmptyCardinalityInterval(lowerBound, UpperCardinalities.UNBOUNDED); | ||
46 | } | ||
47 | |||
48 | public static CardinalityInterval exactly(int lowerBound) { | ||
49 | return new NonEmptyCardinalityInterval(lowerBound, UpperCardinalities.atMost(lowerBound)); | ||
50 | } | ||
51 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/EmptyCardinalityInterval.java b/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/EmptyCardinalityInterval.java deleted file mode 100644 index 9e371e21..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/EmptyCardinalityInterval.java +++ /dev/null | |||
@@ -1,71 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.representation.cardinality; | ||
7 | |||
8 | // Singleton implementation, because there is only a single empty interval. | ||
9 | @SuppressWarnings("squid:S6548") | ||
10 | public final class EmptyCardinalityInterval implements CardinalityInterval { | ||
11 | static final EmptyCardinalityInterval INSTANCE = new EmptyCardinalityInterval(); | ||
12 | |||
13 | private EmptyCardinalityInterval() { | ||
14 | // Singleton constructor. | ||
15 | } | ||
16 | |||
17 | @Override | ||
18 | public int lowerBound() { | ||
19 | return 1; | ||
20 | } | ||
21 | |||
22 | @Override | ||
23 | public boolean isEmpty() { | ||
24 | return true; | ||
25 | } | ||
26 | |||
27 | @Override | ||
28 | public UpperCardinality upperBound() { | ||
29 | return UpperCardinalities.ZERO; | ||
30 | } | ||
31 | |||
32 | @Override | ||
33 | public CardinalityInterval min(CardinalityInterval other) { | ||
34 | return this; | ||
35 | } | ||
36 | |||
37 | @Override | ||
38 | public CardinalityInterval max(CardinalityInterval other) { | ||
39 | return this; | ||
40 | } | ||
41 | |||
42 | @Override | ||
43 | public CardinalityInterval add(CardinalityInterval other) { | ||
44 | return this; | ||
45 | } | ||
46 | |||
47 | @Override | ||
48 | public CardinalityInterval take(int count) { | ||
49 | return this; | ||
50 | } | ||
51 | |||
52 | @Override | ||
53 | public CardinalityInterval multiply(CardinalityInterval other) { | ||
54 | return this; | ||
55 | } | ||
56 | |||
57 | @Override | ||
58 | public CardinalityInterval meet(CardinalityInterval other) { | ||
59 | return this; | ||
60 | } | ||
61 | |||
62 | @Override | ||
63 | public CardinalityInterval join(CardinalityInterval other) { | ||
64 | return other; | ||
65 | } | ||
66 | |||
67 | @Override | ||
68 | public String toString() { | ||
69 | return "error"; | ||
70 | } | ||
71 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/FiniteUpperCardinality.java b/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/FiniteUpperCardinality.java deleted file mode 100644 index b63a8637..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/FiniteUpperCardinality.java +++ /dev/null | |||
@@ -1,83 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.representation.cardinality; | ||
7 | |||
8 | import org.jetbrains.annotations.NotNull; | ||
9 | import org.jetbrains.annotations.Nullable; | ||
10 | |||
11 | import java.util.function.IntBinaryOperator; | ||
12 | |||
13 | public record FiniteUpperCardinality(int finiteUpperBound) implements UpperCardinality { | ||
14 | public FiniteUpperCardinality { | ||
15 | if (finiteUpperBound < 0) { | ||
16 | throw new IllegalArgumentException("finiteUpperBound must not be negative"); | ||
17 | } | ||
18 | } | ||
19 | |||
20 | @Override | ||
21 | public UpperCardinality add(UpperCardinality other) { | ||
22 | return lift(other, Integer::sum); | ||
23 | } | ||
24 | |||
25 | @Override | ||
26 | @Nullable | ||
27 | public UpperCardinality take(int count) { | ||
28 | if (finiteUpperBound < count) { | ||
29 | return null; | ||
30 | } | ||
31 | return new FiniteUpperCardinality(finiteUpperBound - count); | ||
32 | } | ||
33 | |||
34 | @Override | ||
35 | public UpperCardinality multiply(UpperCardinality other) { | ||
36 | return lift(other, (a, b) -> a * b); | ||
37 | } | ||
38 | |||
39 | @Override | ||
40 | public int compareTo(@NotNull UpperCardinality upperCardinality) { | ||
41 | if (upperCardinality instanceof FiniteUpperCardinality finiteUpperCardinality) { | ||
42 | return compareToInt(finiteUpperCardinality.finiteUpperBound); | ||
43 | } | ||
44 | if (upperCardinality instanceof UnboundedUpperCardinality) { | ||
45 | return -1; | ||
46 | } | ||
47 | throw new IllegalArgumentException("Unknown UpperCardinality: " + upperCardinality); | ||
48 | } | ||
49 | |||
50 | @Override | ||
51 | public int compareToInt(int value) { | ||
52 | return Integer.compare(finiteUpperBound, value); | ||
53 | } | ||
54 | |||
55 | @Override | ||
56 | public String toString() { | ||
57 | return Integer.toString(finiteUpperBound); | ||
58 | } | ||
59 | |||
60 | private UpperCardinality lift(@NotNull UpperCardinality other, IntBinaryOperator operator) { | ||
61 | if (other instanceof FiniteUpperCardinality finiteUpperCardinality) { | ||
62 | return UpperCardinalities.atMost(operator.applyAsInt(finiteUpperBound, | ||
63 | finiteUpperCardinality.finiteUpperBound)); | ||
64 | } | ||
65 | if (other instanceof UnboundedUpperCardinality) { | ||
66 | return UpperCardinalities.UNBOUNDED; | ||
67 | } | ||
68 | throw new IllegalArgumentException("Unknown UpperCardinality: " + other); | ||
69 | } | ||
70 | |||
71 | @Override | ||
72 | public boolean equals(Object o) { | ||
73 | if (this == o) return true; | ||
74 | if (o == null || getClass() != o.getClass()) return false; | ||
75 | FiniteUpperCardinality that = (FiniteUpperCardinality) o; | ||
76 | return finiteUpperBound == that.finiteUpperBound; | ||
77 | } | ||
78 | |||
79 | @Override | ||
80 | public int hashCode() { | ||
81 | return finiteUpperBound; | ||
82 | } | ||
83 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/NonEmptyCardinalityInterval.java b/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/NonEmptyCardinalityInterval.java deleted file mode 100644 index 6bd66df7..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/NonEmptyCardinalityInterval.java +++ /dev/null | |||
@@ -1,106 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.representation.cardinality; | ||
7 | |||
8 | import java.util.Objects; | ||
9 | import java.util.function.BinaryOperator; | ||
10 | import java.util.function.IntBinaryOperator; | ||
11 | |||
12 | public record NonEmptyCardinalityInterval(int lowerBound, UpperCardinality upperBound) implements CardinalityInterval { | ||
13 | public NonEmptyCardinalityInterval { | ||
14 | if (lowerBound < 0) { | ||
15 | throw new IllegalArgumentException("lowerBound must not be negative"); | ||
16 | } | ||
17 | if (upperBound.compareToInt(lowerBound) < 0) { | ||
18 | throw new IllegalArgumentException("lowerBound must not be larger than upperBound"); | ||
19 | } | ||
20 | } | ||
21 | |||
22 | @Override | ||
23 | public boolean isEmpty() { | ||
24 | return false; | ||
25 | } | ||
26 | |||
27 | @Override | ||
28 | public CardinalityInterval min(CardinalityInterval other) { | ||
29 | return lift(other, Math::min, UpperCardinality::min); | ||
30 | } | ||
31 | |||
32 | @Override | ||
33 | public CardinalityInterval max(CardinalityInterval other) { | ||
34 | return lift(other, Math::max, UpperCardinality::max); | ||
35 | } | ||
36 | |||
37 | @Override | ||
38 | public CardinalityInterval add(CardinalityInterval other) { | ||
39 | return lift(other, Integer::sum, UpperCardinality::add); | ||
40 | } | ||
41 | |||
42 | @Override | ||
43 | public CardinalityInterval multiply(CardinalityInterval other) { | ||
44 | return lift(other, (a, b) -> a * b, UpperCardinality::multiply); | ||
45 | } | ||
46 | |||
47 | @Override | ||
48 | public CardinalityInterval meet(CardinalityInterval other) { | ||
49 | return lift(other, Math::max, UpperCardinality::min); | ||
50 | } | ||
51 | |||
52 | @Override | ||
53 | public CardinalityInterval join(CardinalityInterval other) { | ||
54 | return lift(other, Math::min, UpperCardinality::max, this); | ||
55 | } | ||
56 | |||
57 | @Override | ||
58 | public CardinalityInterval take(int count) { | ||
59 | int newLowerBound = Math.max(lowerBound - count, 0); | ||
60 | var newUpperBound = upperBound.take(count); | ||
61 | if (newUpperBound == null) { | ||
62 | return CardinalityIntervals.ERROR; | ||
63 | } | ||
64 | return CardinalityIntervals.between(newLowerBound, newUpperBound); | ||
65 | } | ||
66 | |||
67 | private CardinalityInterval lift(CardinalityInterval other, IntBinaryOperator lowerOperator, | ||
68 | BinaryOperator<UpperCardinality> upperOperator, | ||
69 | CardinalityInterval whenEmpty) { | ||
70 | if (other instanceof NonEmptyCardinalityInterval nonEmptyOther) { | ||
71 | return CardinalityIntervals.between(lowerOperator.applyAsInt(lowerBound, nonEmptyOther.lowerBound), | ||
72 | upperOperator.apply(upperBound, nonEmptyOther.upperBound)); | ||
73 | } | ||
74 | if (other instanceof EmptyCardinalityInterval) { | ||
75 | return whenEmpty; | ||
76 | } | ||
77 | throw new IllegalArgumentException("Unknown CardinalityInterval: " + other); | ||
78 | } | ||
79 | |||
80 | private CardinalityInterval lift(CardinalityInterval other, IntBinaryOperator lowerOperator, | ||
81 | BinaryOperator<UpperCardinality> upperOperator) { | ||
82 | return lift(other, lowerOperator, upperOperator, CardinalityIntervals.ERROR); | ||
83 | } | ||
84 | |||
85 | @Override | ||
86 | public String toString() { | ||
87 | if (upperBound instanceof FiniteUpperCardinality finiteUpperCardinality && | ||
88 | finiteUpperCardinality.finiteUpperBound() == lowerBound) { | ||
89 | return "[%d]".formatted(lowerBound); | ||
90 | } | ||
91 | return "[%d..%s]".formatted(lowerBound, upperBound); | ||
92 | } | ||
93 | |||
94 | @Override | ||
95 | public boolean equals(Object o) { | ||
96 | if (this == o) return true; | ||
97 | if (o == null || getClass() != o.getClass()) return false; | ||
98 | NonEmptyCardinalityInterval that = (NonEmptyCardinalityInterval) o; | ||
99 | return lowerBound == that.lowerBound && Objects.equals(upperBound, that.upperBound); | ||
100 | } | ||
101 | |||
102 | @Override | ||
103 | public int hashCode() { | ||
104 | return lowerBound * 31 + upperBound.hashCode(); | ||
105 | } | ||
106 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/UnboundedUpperCardinality.java b/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/UnboundedUpperCardinality.java deleted file mode 100644 index 03c701ae..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/UnboundedUpperCardinality.java +++ /dev/null | |||
@@ -1,66 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.representation.cardinality; | ||
7 | |||
8 | import org.jetbrains.annotations.NotNull; | ||
9 | |||
10 | // Singleton implementation, because there is only a single countable infinity. | ||
11 | @SuppressWarnings("squid:S6548") | ||
12 | public final class UnboundedUpperCardinality implements UpperCardinality { | ||
13 | static final UnboundedUpperCardinality INSTANCE = new UnboundedUpperCardinality(); | ||
14 | |||
15 | private UnboundedUpperCardinality() { | ||
16 | // Singleton constructor. | ||
17 | } | ||
18 | |||
19 | @Override | ||
20 | public UpperCardinality add(UpperCardinality other) { | ||
21 | return this; | ||
22 | } | ||
23 | |||
24 | @Override | ||
25 | public UpperCardinality take(int count) { | ||
26 | return this; | ||
27 | } | ||
28 | |||
29 | @Override | ||
30 | public UpperCardinality multiply(UpperCardinality other) { | ||
31 | return this; | ||
32 | } | ||
33 | |||
34 | // This should always be greater than any finite cardinality. | ||
35 | @SuppressWarnings("ComparatorMethodParameterNotUsed") | ||
36 | @Override | ||
37 | public int compareTo(@NotNull UpperCardinality upperCardinality) { | ||
38 | if (upperCardinality instanceof FiniteUpperCardinality) { | ||
39 | return 1; | ||
40 | } | ||
41 | if (upperCardinality instanceof UnboundedUpperCardinality) { | ||
42 | return 0; | ||
43 | } | ||
44 | throw new IllegalArgumentException("Unknown UpperCardinality: " + upperCardinality); | ||
45 | } | ||
46 | |||
47 | @Override | ||
48 | public int compareToInt(int value) { | ||
49 | return 1; | ||
50 | } | ||
51 | |||
52 | @Override | ||
53 | public String toString() { | ||
54 | return "*"; | ||
55 | } | ||
56 | |||
57 | @Override | ||
58 | public boolean equals(Object obj) { | ||
59 | return this == obj || (obj != null && getClass() == obj.getClass()); | ||
60 | } | ||
61 | |||
62 | @Override | ||
63 | public int hashCode() { | ||
64 | return -1; | ||
65 | } | ||
66 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/UpperCardinalities.java b/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/UpperCardinalities.java deleted file mode 100644 index 17d1b292..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/UpperCardinalities.java +++ /dev/null | |||
@@ -1,38 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.representation.cardinality; | ||
7 | |||
8 | public final class UpperCardinalities { | ||
9 | public static final UpperCardinality UNBOUNDED = UnboundedUpperCardinality.INSTANCE; | ||
10 | |||
11 | public static final UpperCardinality ZERO; | ||
12 | |||
13 | public static final UpperCardinality ONE; | ||
14 | |||
15 | private static final FiniteUpperCardinality[] cache = new FiniteUpperCardinality[256]; | ||
16 | |||
17 | static { | ||
18 | for (int i = 0; i < cache.length; i++) { | ||
19 | cache[i] = new FiniteUpperCardinality(i); | ||
20 | } | ||
21 | ZERO = cache[0]; | ||
22 | ONE = cache[1]; | ||
23 | } | ||
24 | |||
25 | private UpperCardinalities() { | ||
26 | throw new IllegalStateException("This is a static utility class and should not be instantiated directly"); | ||
27 | } | ||
28 | |||
29 | public static UpperCardinality atMost(int upperBound) { | ||
30 | if (upperBound < 0) { | ||
31 | return UNBOUNDED; | ||
32 | } | ||
33 | if (upperBound < cache.length) { | ||
34 | return cache[upperBound]; | ||
35 | } | ||
36 | return new FiniteUpperCardinality(upperBound); | ||
37 | } | ||
38 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/UpperCardinality.java b/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/UpperCardinality.java deleted file mode 100644 index 3f0db028..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/UpperCardinality.java +++ /dev/null | |||
@@ -1,32 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.representation.cardinality; | ||
7 | |||
8 | import org.jetbrains.annotations.Nullable; | ||
9 | |||
10 | public sealed interface UpperCardinality extends Comparable<UpperCardinality> permits FiniteUpperCardinality, | ||
11 | UnboundedUpperCardinality { | ||
12 | default UpperCardinality min(UpperCardinality other) { | ||
13 | return this.compareTo(other) <= 0 ? this : other; | ||
14 | } | ||
15 | |||
16 | default UpperCardinality max(UpperCardinality other) { | ||
17 | return this.compareTo(other) >= 0 ? this : other; | ||
18 | } | ||
19 | |||
20 | UpperCardinality add(UpperCardinality other); | ||
21 | |||
22 | @Nullable | ||
23 | UpperCardinality take(int count); | ||
24 | |||
25 | UpperCardinality multiply(UpperCardinality other); | ||
26 | |||
27 | int compareToInt(int value); | ||
28 | |||
29 | static UpperCardinality of(int upperBound) { | ||
30 | return UpperCardinalities.atMost(upperBound); | ||
31 | } | ||
32 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/util/CycleDetectingMapper.java b/subprojects/store/src/main/java/tools/refinery/store/util/CycleDetectingMapper.java deleted file mode 100644 index 2e302663..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/util/CycleDetectingMapper.java +++ /dev/null | |||
@@ -1,61 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.util; | ||
7 | |||
8 | import java.util.*; | ||
9 | import java.util.function.Function; | ||
10 | import java.util.stream.Collectors; | ||
11 | |||
12 | public class CycleDetectingMapper<T, R> { | ||
13 | private static final String SEPARATOR = " -> "; | ||
14 | |||
15 | private final Function<T, String> getName; | ||
16 | |||
17 | private final Function<T, R> doMap; | ||
18 | |||
19 | private final Set<T> inProgress = new LinkedHashSet<>(); | ||
20 | |||
21 | private final Map<T, R> results = new HashMap<>(); | ||
22 | |||
23 | public CycleDetectingMapper(Function<T, R> doMap) { | ||
24 | this(Objects::toString, doMap); | ||
25 | } | ||
26 | |||
27 | public CycleDetectingMapper(Function<T, String> getName, Function<T, R> doMap) { | ||
28 | this.getName = getName; | ||
29 | this.doMap = doMap; | ||
30 | } | ||
31 | |||
32 | public R map(T input) { | ||
33 | if (inProgress.contains(input)) { | ||
34 | var path = inProgress.stream().map(getName).collect(Collectors.joining(SEPARATOR)); | ||
35 | throw new IllegalArgumentException("Circular reference %s%s%s detected".formatted(path, SEPARATOR, | ||
36 | getName.apply(input))); | ||
37 | } | ||
38 | // We can't use computeIfAbsent here, because translating referenced queries calls this method in a reentrant | ||
39 | // way, which would cause a ConcurrentModificationException with computeIfAbsent. | ||
40 | @SuppressWarnings("squid:S3824") | ||
41 | var result = results.get(input); | ||
42 | if (result == null) { | ||
43 | inProgress.add(input); | ||
44 | try { | ||
45 | result = doMap.apply(input); | ||
46 | results.put(input, result); | ||
47 | } finally { | ||
48 | inProgress.remove(input); | ||
49 | } | ||
50 | } | ||
51 | return result; | ||
52 | } | ||
53 | |||
54 | public List<T> getInProgress() { | ||
55 | return List.copyOf(inProgress); | ||
56 | } | ||
57 | |||
58 | public R getAlreadyMapped(T input) { | ||
59 | return results.get(input); | ||
60 | } | ||
61 | } | ||
diff --git a/subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/CardinalityIntervalTest.java b/subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/CardinalityIntervalTest.java deleted file mode 100644 index 6a66fa84..00000000 --- a/subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/CardinalityIntervalTest.java +++ /dev/null | |||
@@ -1,128 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.representation.cardinality; | ||
7 | |||
8 | import org.junit.jupiter.params.ParameterizedTest; | ||
9 | import org.junit.jupiter.params.provider.Arguments; | ||
10 | import org.junit.jupiter.params.provider.MethodSource; | ||
11 | import tools.refinery.store.representation.cardinality.CardinalityInterval; | ||
12 | |||
13 | import java.util.stream.Stream; | ||
14 | |||
15 | import static org.hamcrest.MatcherAssert.assertThat; | ||
16 | import static org.hamcrest.Matchers.equalTo; | ||
17 | import static tools.refinery.store.representation.cardinality.CardinalityIntervals.*; | ||
18 | |||
19 | class CardinalityIntervalTest { | ||
20 | @ParameterizedTest(name = "min({0}, {1}) == {2}") | ||
21 | @MethodSource | ||
22 | void minTest(CardinalityInterval a, CardinalityInterval b, CardinalityInterval expected) { | ||
23 | assertThat(a.min(b), equalTo(expected)); | ||
24 | } | ||
25 | |||
26 | static Stream<Arguments> minTest() { | ||
27 | return Stream.of( | ||
28 | Arguments.of(atMost(1), atMost(1), atMost(1)), | ||
29 | Arguments.of(atMost(1), between(2, 3), atMost(1)), | ||
30 | Arguments.of(atMost(1), atLeast(2), atMost(1)), | ||
31 | Arguments.of(atMost(1), ERROR, ERROR), | ||
32 | Arguments.of(atLeast(1), atLeast(2), atLeast(1)), | ||
33 | Arguments.of(atLeast(1), ERROR, ERROR), | ||
34 | Arguments.of(ERROR, atLeast(2), ERROR), | ||
35 | Arguments.of(ERROR, ERROR, ERROR) | ||
36 | ); | ||
37 | } | ||
38 | |||
39 | @ParameterizedTest(name = "max({0}, {1}) == {2}") | ||
40 | @MethodSource | ||
41 | void maxTest(CardinalityInterval a, CardinalityInterval b, CardinalityInterval expected) { | ||
42 | assertThat(a.max(b), equalTo(expected)); | ||
43 | } | ||
44 | |||
45 | static Stream<Arguments> maxTest() { | ||
46 | return Stream.of( | ||
47 | Arguments.of(atMost(1), atMost(1), atMost(1)), | ||
48 | Arguments.of(atMost(1), between(2, 3), between(2, 3)), | ||
49 | Arguments.of(atMost(1), atLeast(2), atLeast(2)), | ||
50 | Arguments.of(atMost(1), ERROR, ERROR), | ||
51 | Arguments.of(atLeast(1), atLeast(2), atLeast(2)), | ||
52 | Arguments.of(atLeast(1), ERROR, ERROR), | ||
53 | Arguments.of(ERROR, atLeast(2), ERROR), | ||
54 | Arguments.of(ERROR, ERROR, ERROR) | ||
55 | ); | ||
56 | } | ||
57 | |||
58 | @ParameterizedTest(name = "{0} + {1} == {2}") | ||
59 | @MethodSource | ||
60 | void addTest(CardinalityInterval a, CardinalityInterval b, CardinalityInterval expected) { | ||
61 | assertThat(a.add(b), equalTo(expected)); | ||
62 | } | ||
63 | |||
64 | static Stream<Arguments> addTest() { | ||
65 | return Stream.of( | ||
66 | Arguments.of(atMost(1), atMost(1), atMost(2)), | ||
67 | Arguments.of(atMost(1), between(2, 3), between(2, 4)), | ||
68 | Arguments.of(atMost(1), atLeast(2), atLeast(2)), | ||
69 | Arguments.of(atMost(1), ERROR, ERROR), | ||
70 | Arguments.of(atLeast(1), atLeast(2), atLeast(3)), | ||
71 | Arguments.of(atLeast(1), ERROR, ERROR), | ||
72 | Arguments.of(ERROR, atLeast(2), ERROR), | ||
73 | Arguments.of(ERROR, ERROR, ERROR) | ||
74 | ); | ||
75 | } | ||
76 | |||
77 | @ParameterizedTest(name = "{0} * {1} == {2}") | ||
78 | @MethodSource | ||
79 | void multiplyTest(CardinalityInterval a, CardinalityInterval b, CardinalityInterval expected) { | ||
80 | assertThat(a.multiply(b), equalTo(expected)); | ||
81 | } | ||
82 | |||
83 | static Stream<Arguments> multiplyTest() { | ||
84 | return Stream.of( | ||
85 | Arguments.of(between(2, 3), between(4, 5), between(8, 15)), | ||
86 | Arguments.of(atLeast(2), between(4, 5), atLeast(8)), | ||
87 | Arguments.of(between(2, 3), atLeast(4), atLeast(8)), | ||
88 | Arguments.of(between(2, 3), ERROR, ERROR), | ||
89 | Arguments.of(ERROR, between(4, 5), ERROR), | ||
90 | Arguments.of(ERROR, ERROR, ERROR) | ||
91 | ); | ||
92 | } | ||
93 | |||
94 | @ParameterizedTest(name = "{0} /\\ {1} == {2}") | ||
95 | @MethodSource | ||
96 | void meetTest(CardinalityInterval a, CardinalityInterval b, CardinalityInterval expected) { | ||
97 | assertThat(a.meet(b), equalTo(expected)); | ||
98 | } | ||
99 | |||
100 | static Stream<Arguments> meetTest() { | ||
101 | return Stream.of( | ||
102 | Arguments.of(atMost(1), atMost(2), atMost(1)), | ||
103 | Arguments.of(atMost(2), between(1, 3), between(1, 2)), | ||
104 | Arguments.of(atMost(1), between(1, 3), exactly(1)), | ||
105 | Arguments.of(atMost(1), between(2, 3), ERROR), | ||
106 | Arguments.of(atMost(1), ERROR, ERROR), | ||
107 | Arguments.of(ERROR, atMost(1), ERROR), | ||
108 | Arguments.of(ERROR, ERROR, ERROR) | ||
109 | ); | ||
110 | } | ||
111 | |||
112 | @ParameterizedTest(name = "{0} \\/ {1} == {2}") | ||
113 | @MethodSource | ||
114 | void joinTest(CardinalityInterval a, CardinalityInterval b, CardinalityInterval expected) { | ||
115 | assertThat(a.join(b), equalTo(expected)); | ||
116 | } | ||
117 | |||
118 | static Stream<Arguments> joinTest() { | ||
119 | return Stream.of( | ||
120 | Arguments.of(atMost(1), atMost(2), atMost(2)), | ||
121 | Arguments.of(atMost(2), between(1, 3), atMost(3)), | ||
122 | Arguments.of(atMost(1), between(2, 3), atMost(3)), | ||
123 | Arguments.of(atMost(1), ERROR, atMost(1)), | ||
124 | Arguments.of(ERROR, atMost(1), atMost(1)), | ||
125 | Arguments.of(ERROR, ERROR, ERROR) | ||
126 | ); | ||
127 | } | ||
128 | } | ||
diff --git a/subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/CardinalityIntervalsTest.java b/subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/CardinalityIntervalsTest.java deleted file mode 100644 index 9fe76159..00000000 --- a/subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/CardinalityIntervalsTest.java +++ /dev/null | |||
@@ -1,28 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.representation.cardinality; | ||
7 | |||
8 | import org.junit.jupiter.api.Test; | ||
9 | import tools.refinery.store.representation.cardinality.CardinalityIntervals; | ||
10 | import tools.refinery.store.representation.cardinality.UpperCardinalities; | ||
11 | |||
12 | import static org.hamcrest.MatcherAssert.assertThat; | ||
13 | import static org.hamcrest.Matchers.*; | ||
14 | |||
15 | class CardinalityIntervalsTest { | ||
16 | @Test | ||
17 | void betweenEmptyTest() { | ||
18 | var interval = CardinalityIntervals.between(2, 1); | ||
19 | assertThat(interval.isEmpty(), equalTo(true)); | ||
20 | } | ||
21 | |||
22 | @Test | ||
23 | void betweenNegativeUpperBoundTest() { | ||
24 | var interval = CardinalityIntervals.between(0, -1); | ||
25 | assertThat(interval.upperBound(), equalTo(UpperCardinalities.UNBOUNDED)); | ||
26 | assertThat(interval.isEmpty(), equalTo(false)); | ||
27 | } | ||
28 | } | ||
diff --git a/subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/EmptyCardinalityIntervalTest.java b/subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/EmptyCardinalityIntervalTest.java deleted file mode 100644 index 24a788a8..00000000 --- a/subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/EmptyCardinalityIntervalTest.java +++ /dev/null | |||
@@ -1,20 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.representation.cardinality; | ||
7 | |||
8 | import org.junit.jupiter.api.Test; | ||
9 | import tools.refinery.store.representation.cardinality.CardinalityIntervals; | ||
10 | |||
11 | import static org.hamcrest.MatcherAssert.assertThat; | ||
12 | import static org.hamcrest.Matchers.lessThan; | ||
13 | |||
14 | class EmptyCardinalityIntervalTest { | ||
15 | @Test | ||
16 | void inconsistentBoundsTest() { | ||
17 | assertThat(CardinalityIntervals.ERROR.upperBound().compareToInt(CardinalityIntervals.ERROR.lowerBound()), | ||
18 | lessThan(0)); | ||
19 | } | ||
20 | } | ||
diff --git a/subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/FiniteCardinalityIntervalTest.java b/subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/FiniteCardinalityIntervalTest.java deleted file mode 100644 index 6cf56fae..00000000 --- a/subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/FiniteCardinalityIntervalTest.java +++ /dev/null | |||
@@ -1,28 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.representation.cardinality; | ||
7 | |||
8 | import org.junit.jupiter.api.Test; | ||
9 | import tools.refinery.store.representation.cardinality.NonEmptyCardinalityInterval; | ||
10 | import tools.refinery.store.representation.cardinality.UpperCardinalities; | ||
11 | import tools.refinery.store.representation.cardinality.UpperCardinality; | ||
12 | |||
13 | import static org.junit.jupiter.api.Assertions.assertThrows; | ||
14 | |||
15 | class FiniteCardinalityIntervalTest { | ||
16 | @Test | ||
17 | void invalidLowerBoundConstructorTest() { | ||
18 | assertThrows(IllegalArgumentException.class, () -> new NonEmptyCardinalityInterval(-1, | ||
19 | UpperCardinalities.UNBOUNDED)); | ||
20 | } | ||
21 | |||
22 | @Test | ||
23 | void invalidUpperBoundConstructorTest() { | ||
24 | var upperCardinality = UpperCardinality.of(1); | ||
25 | assertThrows(IllegalArgumentException.class, () -> new NonEmptyCardinalityInterval(2, | ||
26 | upperCardinality)); | ||
27 | } | ||
28 | } | ||
diff --git a/subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/FiniteUpperCardinalityTest.java b/subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/FiniteUpperCardinalityTest.java deleted file mode 100644 index 7c641c47..00000000 --- a/subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/FiniteUpperCardinalityTest.java +++ /dev/null | |||
@@ -1,18 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.representation.cardinality; | ||
7 | |||
8 | import org.junit.jupiter.api.Test; | ||
9 | import tools.refinery.store.representation.cardinality.FiniteUpperCardinality; | ||
10 | |||
11 | import static org.junit.jupiter.api.Assertions.assertThrows; | ||
12 | |||
13 | class FiniteUpperCardinalityTest { | ||
14 | @Test | ||
15 | void invalidConstructorTest() { | ||
16 | assertThrows(IllegalArgumentException.class, () -> new FiniteUpperCardinality(-1)); | ||
17 | } | ||
18 | } | ||
diff --git a/subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/UpperCardinalitiesTest.java b/subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/UpperCardinalitiesTest.java deleted file mode 100644 index e403eec2..00000000 --- a/subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/UpperCardinalitiesTest.java +++ /dev/null | |||
@@ -1,30 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.representation.cardinality; | ||
7 | |||
8 | import org.junit.jupiter.api.Test; | ||
9 | import org.junit.jupiter.params.ParameterizedTest; | ||
10 | import org.junit.jupiter.params.provider.ValueSource; | ||
11 | |||
12 | import static org.hamcrest.MatcherAssert.assertThat; | ||
13 | import static org.hamcrest.Matchers.equalTo; | ||
14 | import static org.hamcrest.Matchers.instanceOf; | ||
15 | |||
16 | class UpperCardinalitiesTest { | ||
17 | @ParameterizedTest | ||
18 | @ValueSource(ints = {0, 1, 255, 256, 1000, Integer.MAX_VALUE}) | ||
19 | void valueOfBoundedTest(int value) { | ||
20 | var upperCardinality = UpperCardinalities.atMost(value); | ||
21 | assertThat(upperCardinality, instanceOf(FiniteUpperCardinality.class)); | ||
22 | assertThat(((FiniteUpperCardinality) upperCardinality).finiteUpperBound(), equalTo(value)); | ||
23 | } | ||
24 | |||
25 | @Test | ||
26 | void valueOfUnboundedTest() { | ||
27 | var upperCardinality = UpperCardinalities.atMost(-1); | ||
28 | assertThat(upperCardinality, instanceOf(UnboundedUpperCardinality.class)); | ||
29 | } | ||
30 | } | ||
diff --git a/subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/UpperCardinalityTest.java b/subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/UpperCardinalityTest.java deleted file mode 100644 index 10b4dd20..00000000 --- a/subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/UpperCardinalityTest.java +++ /dev/null | |||
@@ -1,117 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.representation.cardinality; | ||
7 | |||
8 | import org.junit.jupiter.params.ParameterizedTest; | ||
9 | import org.junit.jupiter.params.provider.Arguments; | ||
10 | import org.junit.jupiter.params.provider.MethodSource; | ||
11 | import tools.refinery.store.representation.cardinality.UpperCardinalities; | ||
12 | import tools.refinery.store.representation.cardinality.UpperCardinality; | ||
13 | |||
14 | import java.util.stream.Stream; | ||
15 | |||
16 | import static org.hamcrest.MatcherAssert.assertThat; | ||
17 | import static org.hamcrest.Matchers.equalTo; | ||
18 | |||
19 | class UpperCardinalityTest { | ||
20 | @ParameterizedTest(name = "min({0}, {1}) == {2}") | ||
21 | @MethodSource | ||
22 | void minTest(UpperCardinality a, UpperCardinality b, UpperCardinality expected) { | ||
23 | assertThat(a.min(b), equalTo(expected)); | ||
24 | } | ||
25 | |||
26 | static Stream<Arguments> minTest() { | ||
27 | return Stream.of( | ||
28 | Arguments.of(UpperCardinality.of(0), UpperCardinality.of(0), UpperCardinality.of(0)), | ||
29 | Arguments.of(UpperCardinality.of(0), UpperCardinality.of(1), UpperCardinality.of(0)), | ||
30 | Arguments.of(UpperCardinality.of(1), UpperCardinality.of(0), UpperCardinality.of(0)), | ||
31 | Arguments.of(UpperCardinality.of(0), UpperCardinalities.UNBOUNDED, UpperCardinality.of(0)), | ||
32 | Arguments.of(UpperCardinalities.UNBOUNDED, UpperCardinality.of(0), UpperCardinality.of(0)), | ||
33 | Arguments.of(UpperCardinalities.UNBOUNDED, UpperCardinalities.UNBOUNDED, UpperCardinalities.UNBOUNDED) | ||
34 | ); | ||
35 | } | ||
36 | |||
37 | @ParameterizedTest(name = "max({0}, {1}) == {2}") | ||
38 | @MethodSource | ||
39 | void maxTest(UpperCardinality a, UpperCardinality b, UpperCardinality expected) { | ||
40 | assertThat(a.max(b), equalTo(expected)); | ||
41 | } | ||
42 | |||
43 | static Stream<Arguments> maxTest() { | ||
44 | return Stream.of( | ||
45 | Arguments.of(UpperCardinality.of(0), UpperCardinality.of(0), UpperCardinality.of(0)), | ||
46 | Arguments.of(UpperCardinality.of(0), UpperCardinality.of(1), UpperCardinality.of(1)), | ||
47 | Arguments.of(UpperCardinality.of(1), UpperCardinality.of(0), UpperCardinality.of(1)), | ||
48 | Arguments.of(UpperCardinality.of(0), UpperCardinalities.UNBOUNDED, UpperCardinalities.UNBOUNDED), | ||
49 | Arguments.of(UpperCardinalities.UNBOUNDED, UpperCardinality.of(0), UpperCardinalities.UNBOUNDED), | ||
50 | Arguments.of(UpperCardinalities.UNBOUNDED, UpperCardinalities.UNBOUNDED, UpperCardinalities.UNBOUNDED) | ||
51 | ); | ||
52 | } | ||
53 | |||
54 | @ParameterizedTest(name = "{0} + {1} == {2}") | ||
55 | @MethodSource | ||
56 | void addTest(UpperCardinality a, UpperCardinality b, UpperCardinality expected) { | ||
57 | assertThat(a.add(b), equalTo(expected)); | ||
58 | } | ||
59 | |||
60 | static Stream<Arguments> addTest() { | ||
61 | return Stream.of( | ||
62 | Arguments.of(UpperCardinality.of(2), UpperCardinality.of(3), UpperCardinality.of(5)), | ||
63 | Arguments.of(UpperCardinality.of(2), UpperCardinalities.UNBOUNDED, UpperCardinalities.UNBOUNDED), | ||
64 | Arguments.of(UpperCardinalities.UNBOUNDED, UpperCardinality.of(2), UpperCardinalities.UNBOUNDED), | ||
65 | Arguments.of(UpperCardinalities.UNBOUNDED, UpperCardinalities.UNBOUNDED, UpperCardinalities.UNBOUNDED) | ||
66 | ); | ||
67 | } | ||
68 | |||
69 | @ParameterizedTest(name = "{0} * {1} == {2}") | ||
70 | @MethodSource | ||
71 | void multiplyTest(UpperCardinality a, UpperCardinality b, UpperCardinality expected) { | ||
72 | assertThat(a.multiply(b), equalTo(expected)); | ||
73 | } | ||
74 | |||
75 | static Stream<Arguments> multiplyTest() { | ||
76 | return Stream.of( | ||
77 | Arguments.of(UpperCardinality.of(2), UpperCardinality.of(3), UpperCardinality.of(6)), | ||
78 | Arguments.of(UpperCardinality.of(2), UpperCardinalities.UNBOUNDED, UpperCardinalities.UNBOUNDED), | ||
79 | Arguments.of(UpperCardinalities.UNBOUNDED, UpperCardinality.of(2), UpperCardinalities.UNBOUNDED), | ||
80 | Arguments.of(UpperCardinalities.UNBOUNDED, UpperCardinalities.UNBOUNDED, UpperCardinalities.UNBOUNDED) | ||
81 | ); | ||
82 | } | ||
83 | |||
84 | @ParameterizedTest(name = "{0}.compareTo({1}) == {2}") | ||
85 | @MethodSource | ||
86 | void compareToTest(UpperCardinality a, UpperCardinality b, int expected) { | ||
87 | assertThat(a.compareTo(b), equalTo(expected)); | ||
88 | } | ||
89 | |||
90 | static Stream<Arguments> compareToTest() { | ||
91 | return Stream.of( | ||
92 | Arguments.of(UpperCardinality.of(0), UpperCardinality.of(0), 0), | ||
93 | Arguments.of(UpperCardinality.of(0), UpperCardinality.of(1), -1), | ||
94 | Arguments.of(UpperCardinality.of(1), UpperCardinality.of(0), 1), | ||
95 | Arguments.of(UpperCardinality.of(0), UpperCardinalities.UNBOUNDED, -1), | ||
96 | Arguments.of(UpperCardinalities.UNBOUNDED, UpperCardinality.of(0), 1), | ||
97 | Arguments.of(UpperCardinalities.UNBOUNDED, UpperCardinalities.UNBOUNDED, 0) | ||
98 | ); | ||
99 | } | ||
100 | |||
101 | @ParameterizedTest(name = "{0}.compareToInt({1}) == {2}") | ||
102 | @MethodSource | ||
103 | void compareToIntTest(UpperCardinality a, int b, int expected) { | ||
104 | assertThat(a.compareToInt(b), equalTo(expected)); | ||
105 | } | ||
106 | |||
107 | static Stream<Arguments> compareToIntTest() { | ||
108 | return Stream.of( | ||
109 | Arguments.of(UpperCardinality.of(3), -1, 1), | ||
110 | Arguments.of(UpperCardinality.of(3), 2, 1), | ||
111 | Arguments.of(UpperCardinality.of(3), 3, 0), | ||
112 | Arguments.of(UpperCardinality.of(3), 4, -1), | ||
113 | Arguments.of(UpperCardinalities.UNBOUNDED, -1, 1), | ||
114 | Arguments.of(UpperCardinalities.UNBOUNDED, 3, 1) | ||
115 | ); | ||
116 | } | ||
117 | } | ||