diff options
author | Kristóf Marussy <kristof@marussy.com> | 2023-02-20 20:23:27 +0100 |
---|---|---|
committer | Kristóf Marussy <kristof@marussy.com> | 2023-02-20 20:23:27 +0100 |
commit | b3f7c4d7707435803921c4fec2c4d95b3dd45c53 (patch) | |
tree | 18a90112efe3ece8678709db322dddcefafaace1 /subprojects/store/src/main/java | |
parent | feat: type inference for class hierarchies (diff) | |
download | refinery-b3f7c4d7707435803921c4fec2c4d95b3dd45c53.tar.gz refinery-b3f7c4d7707435803921c4fec2c4d95b3dd45c53.tar.zst refinery-b3f7c4d7707435803921c4fec2c4d95b3dd45c53.zip |
refactor: split query and partial from store
Allows more complicated dependency hiearchies (e.g., use
store-query-viatra for testing store-partial) and better separation of
test fixtures.
Diffstat (limited to 'subprojects/store/src/main/java')
52 files changed, 0 insertions, 1893 deletions
diff --git a/subprojects/store/src/main/java/tools/refinery/store/partial/PartialInterpretation.java b/subprojects/store/src/main/java/tools/refinery/store/partial/PartialInterpretation.java deleted file mode 100644 index 331fa294..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/partial/PartialInterpretation.java +++ /dev/null | |||
@@ -1,19 +0,0 @@ | |||
1 | package tools.refinery.store.partial; | ||
2 | |||
3 | import tools.refinery.store.adapter.ModelAdapterBuilderFactory; | ||
4 | import tools.refinery.store.model.ModelStoreBuilder; | ||
5 | import tools.refinery.store.partial.internal.PartialInterpretationBuilderImpl; | ||
6 | |||
7 | public final class PartialInterpretation extends ModelAdapterBuilderFactory<PartialInterpretationAdapter, | ||
8 | PartialInterpretationStoreAdapter, PartialInterpretationBuilder> { | ||
9 | public static final PartialInterpretation ADAPTER = new PartialInterpretation(); | ||
10 | |||
11 | private PartialInterpretation() { | ||
12 | super(PartialInterpretationAdapter.class, PartialInterpretationStoreAdapter.class, PartialInterpretationBuilder.class); | ||
13 | } | ||
14 | |||
15 | @Override | ||
16 | public PartialInterpretationBuilder createBuilder(ModelStoreBuilder storeBuilder) { | ||
17 | return new PartialInterpretationBuilderImpl(storeBuilder); | ||
18 | } | ||
19 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/partial/PartialInterpretationAdapter.java b/subprojects/store/src/main/java/tools/refinery/store/partial/PartialInterpretationAdapter.java deleted file mode 100644 index 2c83a200..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/partial/PartialInterpretationAdapter.java +++ /dev/null | |||
@@ -1,9 +0,0 @@ | |||
1 | package tools.refinery.store.partial; | ||
2 | |||
3 | import tools.refinery.store.adapter.ModelAdapter; | ||
4 | |||
5 | public interface PartialInterpretationAdapter extends ModelAdapter { | ||
6 | @Override | ||
7 | PartialInterpretationStoreAdapter getStoreAdapter(); | ||
8 | } | ||
9 | |||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/partial/PartialInterpretationBuilder.java b/subprojects/store/src/main/java/tools/refinery/store/partial/PartialInterpretationBuilder.java deleted file mode 100644 index 0ec13836..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/partial/PartialInterpretationBuilder.java +++ /dev/null | |||
@@ -1,9 +0,0 @@ | |||
1 | package tools.refinery.store.partial; | ||
2 | |||
3 | import tools.refinery.store.adapter.ModelAdapterBuilder; | ||
4 | import tools.refinery.store.model.ModelStore; | ||
5 | |||
6 | public interface PartialInterpretationBuilder extends ModelAdapterBuilder { | ||
7 | @Override | ||
8 | PartialInterpretationStoreAdapter createStoreAdapter(ModelStore store); | ||
9 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/partial/PartialInterpretationStoreAdapter.java b/subprojects/store/src/main/java/tools/refinery/store/partial/PartialInterpretationStoreAdapter.java deleted file mode 100644 index d4eb770d..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/partial/PartialInterpretationStoreAdapter.java +++ /dev/null | |||
@@ -1,9 +0,0 @@ | |||
1 | package tools.refinery.store.partial; | ||
2 | |||
3 | import tools.refinery.store.adapter.ModelStoreAdapter; | ||
4 | import tools.refinery.store.model.Model; | ||
5 | |||
6 | public interface PartialInterpretationStoreAdapter extends ModelStoreAdapter { | ||
7 | @Override | ||
8 | PartialInterpretationAdapter createModelAdapter(Model model); | ||
9 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/partial/internal/PartialInterpretationAdapterImpl.java b/subprojects/store/src/main/java/tools/refinery/store/partial/internal/PartialInterpretationAdapterImpl.java deleted file mode 100644 index 4b3977c0..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/partial/internal/PartialInterpretationAdapterImpl.java +++ /dev/null | |||
@@ -1,24 +0,0 @@ | |||
1 | package tools.refinery.store.partial.internal; | ||
2 | |||
3 | import tools.refinery.store.model.Model; | ||
4 | import tools.refinery.store.partial.PartialInterpretationAdapter; | ||
5 | |||
6 | public class PartialInterpretationAdapterImpl implements PartialInterpretationAdapter { | ||
7 | private final Model model; | ||
8 | private final PartialInterpretationStoreAdapterImpl storeAdapter; | ||
9 | |||
10 | PartialInterpretationAdapterImpl(Model model, PartialInterpretationStoreAdapterImpl storeAdapter) { | ||
11 | this.model = model; | ||
12 | this.storeAdapter = storeAdapter; | ||
13 | } | ||
14 | |||
15 | @Override | ||
16 | public Model getModel() { | ||
17 | return model; | ||
18 | } | ||
19 | |||
20 | @Override | ||
21 | public PartialInterpretationStoreAdapterImpl getStoreAdapter() { | ||
22 | return storeAdapter; | ||
23 | } | ||
24 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/partial/internal/PartialInterpretationBuilderImpl.java b/subprojects/store/src/main/java/tools/refinery/store/partial/internal/PartialInterpretationBuilderImpl.java deleted file mode 100644 index 4609dc32..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/partial/internal/PartialInterpretationBuilderImpl.java +++ /dev/null | |||
@@ -1,17 +0,0 @@ | |||
1 | package tools.refinery.store.partial.internal; | ||
2 | |||
3 | import tools.refinery.store.adapter.AbstractModelAdapterBuilder; | ||
4 | import tools.refinery.store.model.ModelStore; | ||
5 | import tools.refinery.store.model.ModelStoreBuilder; | ||
6 | import tools.refinery.store.partial.PartialInterpretationBuilder; | ||
7 | |||
8 | public class PartialInterpretationBuilderImpl extends AbstractModelAdapterBuilder implements PartialInterpretationBuilder { | ||
9 | public PartialInterpretationBuilderImpl(ModelStoreBuilder storeBuilder) { | ||
10 | super(storeBuilder); | ||
11 | } | ||
12 | |||
13 | @Override | ||
14 | public PartialInterpretationStoreAdapterImpl createStoreAdapter(ModelStore store) { | ||
15 | return null; | ||
16 | } | ||
17 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/partial/internal/PartialInterpretationStoreAdapterImpl.java b/subprojects/store/src/main/java/tools/refinery/store/partial/internal/PartialInterpretationStoreAdapterImpl.java deleted file mode 100644 index 970b802b..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/partial/internal/PartialInterpretationStoreAdapterImpl.java +++ /dev/null | |||
@@ -1,23 +0,0 @@ | |||
1 | package tools.refinery.store.partial.internal; | ||
2 | |||
3 | import tools.refinery.store.model.Model; | ||
4 | import tools.refinery.store.model.ModelStore; | ||
5 | import tools.refinery.store.partial.PartialInterpretationStoreAdapter; | ||
6 | |||
7 | public class PartialInterpretationStoreAdapterImpl implements PartialInterpretationStoreAdapter { | ||
8 | private final ModelStore store; | ||
9 | |||
10 | PartialInterpretationStoreAdapterImpl(ModelStore store) { | ||
11 | this.store = store; | ||
12 | } | ||
13 | |||
14 | @Override | ||
15 | public ModelStore getStore() { | ||
16 | return store; | ||
17 | } | ||
18 | |||
19 | @Override | ||
20 | public PartialInterpretationAdapterImpl createModelAdapter(Model model) { | ||
21 | return new PartialInterpretationAdapterImpl(model, this); | ||
22 | } | ||
23 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/partial/literal/ModalDnfCallLiteral.java b/subprojects/store/src/main/java/tools/refinery/store/partial/literal/ModalDnfCallLiteral.java deleted file mode 100644 index 8070726a..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/partial/literal/ModalDnfCallLiteral.java +++ /dev/null | |||
@@ -1,30 +0,0 @@ | |||
1 | package tools.refinery.store.partial.literal; | ||
2 | |||
3 | import tools.refinery.store.query.Dnf; | ||
4 | import tools.refinery.store.query.Variable; | ||
5 | import tools.refinery.store.query.literal.CallPolarity; | ||
6 | import tools.refinery.store.query.literal.DnfCallLiteral; | ||
7 | import tools.refinery.store.query.literal.PolarLiteral; | ||
8 | |||
9 | import java.util.List; | ||
10 | import java.util.Map; | ||
11 | |||
12 | public class ModalDnfCallLiteral extends ModalLiteral<Dnf> implements PolarLiteral<ModalDnfCallLiteral> { | ||
13 | public ModalDnfCallLiteral(CallPolarity polarity, Modality modality, Dnf target, List<Variable> arguments) { | ||
14 | super(polarity, modality, target, arguments); | ||
15 | } | ||
16 | |||
17 | public ModalDnfCallLiteral(Modality modality, DnfCallLiteral baseLiteral) { | ||
18 | super(modality.commute(baseLiteral.getPolarity()), baseLiteral); | ||
19 | } | ||
20 | |||
21 | @Override | ||
22 | public ModalDnfCallLiteral substitute(Map<Variable, Variable> substitution) { | ||
23 | return new ModalDnfCallLiteral(getPolarity(), getModality(), getTarget(), substituteArguments(substitution)); | ||
24 | } | ||
25 | |||
26 | @Override | ||
27 | public ModalDnfCallLiteral negate() { | ||
28 | return new ModalDnfCallLiteral(getPolarity().negate(), getModality(), getTarget(), getArguments()); | ||
29 | } | ||
30 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/partial/literal/ModalLiteral.java b/subprojects/store/src/main/java/tools/refinery/store/partial/literal/ModalLiteral.java deleted file mode 100644 index a1b6c83e..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/partial/literal/ModalLiteral.java +++ /dev/null | |||
@@ -1,45 +0,0 @@ | |||
1 | package tools.refinery.store.partial.literal; | ||
2 | |||
3 | import tools.refinery.store.query.RelationLike; | ||
4 | import tools.refinery.store.query.Variable; | ||
5 | import tools.refinery.store.query.literal.CallLiteral; | ||
6 | import tools.refinery.store.query.literal.CallPolarity; | ||
7 | |||
8 | import java.util.List; | ||
9 | import java.util.Objects; | ||
10 | |||
11 | public abstract class ModalLiteral<T extends RelationLike> extends CallLiteral<T> { | ||
12 | private final Modality modality; | ||
13 | |||
14 | protected ModalLiteral(CallPolarity polarity, Modality modality, T target, List<Variable> arguments) { | ||
15 | super(polarity, target, arguments); | ||
16 | this.modality = modality; | ||
17 | } | ||
18 | |||
19 | protected ModalLiteral(Modality modality, CallLiteral<? extends T> baseLiteral) { | ||
20 | this(baseLiteral.getPolarity(), commute(modality, baseLiteral.getPolarity()), baseLiteral.getTarget(), | ||
21 | baseLiteral.getArguments()); | ||
22 | } | ||
23 | |||
24 | public Modality getModality() { | ||
25 | return modality; | ||
26 | } | ||
27 | |||
28 | @Override | ||
29 | public boolean equals(Object o) { | ||
30 | if (this == o) return true; | ||
31 | if (o == null || getClass() != o.getClass()) return false; | ||
32 | if (!super.equals(o)) return false; | ||
33 | ModalLiteral<?> that = (ModalLiteral<?>) o; | ||
34 | return modality == that.modality; | ||
35 | } | ||
36 | |||
37 | @Override | ||
38 | public int hashCode() { | ||
39 | return Objects.hash(super.hashCode(), modality); | ||
40 | } | ||
41 | |||
42 | private static Modality commute(Modality modality, CallPolarity polarity) { | ||
43 | return polarity.isPositive() ? modality : modality.negate(); | ||
44 | } | ||
45 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/partial/literal/ModalRelationLiteral.java b/subprojects/store/src/main/java/tools/refinery/store/partial/literal/ModalRelationLiteral.java deleted file mode 100644 index dbaa524f..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/partial/literal/ModalRelationLiteral.java +++ /dev/null | |||
@@ -1,31 +0,0 @@ | |||
1 | package tools.refinery.store.partial.literal; | ||
2 | |||
3 | import tools.refinery.store.partial.representation.PartialRelation; | ||
4 | import tools.refinery.store.query.Variable; | ||
5 | import tools.refinery.store.query.literal.CallPolarity; | ||
6 | import tools.refinery.store.query.literal.PolarLiteral; | ||
7 | |||
8 | import java.util.List; | ||
9 | import java.util.Map; | ||
10 | |||
11 | public final class ModalRelationLiteral extends ModalLiteral<PartialRelation> | ||
12 | implements PolarLiteral<ModalRelationLiteral> { | ||
13 | public ModalRelationLiteral(CallPolarity polarity, Modality modality, PartialRelation target, | ||
14 | List<Variable> arguments) { | ||
15 | super(polarity, modality, target, arguments); | ||
16 | } | ||
17 | |||
18 | public ModalRelationLiteral(Modality modality, PartialRelationLiteral baseLiteral) { | ||
19 | super(modality, baseLiteral); | ||
20 | } | ||
21 | |||
22 | @Override | ||
23 | public ModalRelationLiteral substitute(Map<Variable, Variable> substitution) { | ||
24 | return new ModalRelationLiteral(getPolarity(), getModality(), getTarget(), substituteArguments(substitution)); | ||
25 | } | ||
26 | |||
27 | @Override | ||
28 | public ModalRelationLiteral negate() { | ||
29 | return new ModalRelationLiteral(getPolarity().negate(), getModality(), getTarget(), getArguments()); | ||
30 | } | ||
31 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/partial/literal/Modality.java b/subprojects/store/src/main/java/tools/refinery/store/partial/literal/Modality.java deleted file mode 100644 index d647ef0a..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/partial/literal/Modality.java +++ /dev/null | |||
@@ -1,31 +0,0 @@ | |||
1 | package tools.refinery.store.partial.literal; | ||
2 | |||
3 | import tools.refinery.store.query.literal.CallPolarity; | ||
4 | |||
5 | import java.util.Locale; | ||
6 | |||
7 | public enum Modality { | ||
8 | MUST, | ||
9 | MAY, | ||
10 | CURRENT; | ||
11 | |||
12 | public Modality negate() { | ||
13 | return switch(this) { | ||
14 | case MUST -> MAY; | ||
15 | case MAY -> MUST; | ||
16 | case CURRENT -> CURRENT; | ||
17 | }; | ||
18 | } | ||
19 | |||
20 | public Modality commute(CallPolarity polarity) { | ||
21 | if (polarity.isPositive()) { | ||
22 | return this; | ||
23 | } | ||
24 | return this.negate(); | ||
25 | } | ||
26 | |||
27 | @Override | ||
28 | public String toString() { | ||
29 | return name().toLowerCase(Locale.ROOT); | ||
30 | } | ||
31 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/partial/literal/PartialLiterals.java b/subprojects/store/src/main/java/tools/refinery/store/partial/literal/PartialLiterals.java deleted file mode 100644 index 51d388d3..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/partial/literal/PartialLiterals.java +++ /dev/null | |||
@@ -1,33 +0,0 @@ | |||
1 | package tools.refinery.store.partial.literal; | ||
2 | |||
3 | import tools.refinery.store.query.literal.DnfCallLiteral; | ||
4 | |||
5 | public final class PartialLiterals { | ||
6 | private PartialLiterals() { | ||
7 | throw new IllegalStateException("This is a static utility class and should not be instantiated directly"); | ||
8 | } | ||
9 | |||
10 | public ModalRelationLiteral may(PartialRelationLiteral literal) { | ||
11 | return new ModalRelationLiteral(Modality.MAY, literal); | ||
12 | } | ||
13 | |||
14 | public ModalRelationLiteral must(PartialRelationLiteral literal) { | ||
15 | return new ModalRelationLiteral(Modality.MUST, literal); | ||
16 | } | ||
17 | |||
18 | public ModalRelationLiteral current(PartialRelationLiteral literal) { | ||
19 | return new ModalRelationLiteral(Modality.CURRENT, literal); | ||
20 | } | ||
21 | |||
22 | public ModalDnfCallLiteral may(DnfCallLiteral literal) { | ||
23 | return new ModalDnfCallLiteral(Modality.MAY, literal); | ||
24 | } | ||
25 | |||
26 | public ModalDnfCallLiteral must(DnfCallLiteral literal) { | ||
27 | return new ModalDnfCallLiteral(Modality.MUST, literal); | ||
28 | } | ||
29 | |||
30 | public ModalDnfCallLiteral current(DnfCallLiteral literal) { | ||
31 | return new ModalDnfCallLiteral(Modality.CURRENT, literal); | ||
32 | } | ||
33 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/partial/literal/PartialRelationLiteral.java b/subprojects/store/src/main/java/tools/refinery/store/partial/literal/PartialRelationLiteral.java deleted file mode 100644 index dc1a1da3..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/partial/literal/PartialRelationLiteral.java +++ /dev/null | |||
@@ -1,27 +0,0 @@ | |||
1 | package tools.refinery.store.partial.literal; | ||
2 | |||
3 | import tools.refinery.store.partial.representation.PartialRelation; | ||
4 | import tools.refinery.store.query.Variable; | ||
5 | import tools.refinery.store.query.literal.CallLiteral; | ||
6 | import tools.refinery.store.query.literal.CallPolarity; | ||
7 | import tools.refinery.store.query.literal.PolarLiteral; | ||
8 | |||
9 | import java.util.List; | ||
10 | import java.util.Map; | ||
11 | |||
12 | public final class PartialRelationLiteral extends CallLiteral<PartialRelation> | ||
13 | implements PolarLiteral<PartialRelationLiteral> { | ||
14 | public PartialRelationLiteral(CallPolarity polarity, PartialRelation target, List<Variable> substitution) { | ||
15 | super(polarity, target, substitution); | ||
16 | } | ||
17 | |||
18 | @Override | ||
19 | public PartialRelationLiteral substitute(Map<Variable, Variable> substitution) { | ||
20 | return new PartialRelationLiteral(getPolarity(), getTarget(), substituteArguments(substitution)); | ||
21 | } | ||
22 | |||
23 | @Override | ||
24 | public PartialRelationLiteral negate() { | ||
25 | return new PartialRelationLiteral(getPolarity().negate(), getTarget(), getArguments()); | ||
26 | } | ||
27 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/partial/representation/AnyPartialFunction.java b/subprojects/store/src/main/java/tools/refinery/store/partial/representation/AnyPartialFunction.java deleted file mode 100644 index 1113245e..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/partial/representation/AnyPartialFunction.java +++ /dev/null | |||
@@ -1,4 +0,0 @@ | |||
1 | package tools.refinery.store.partial.representation; | ||
2 | |||
3 | public sealed interface AnyPartialFunction extends AnyPartialSymbol permits PartialFunction { | ||
4 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/partial/representation/AnyPartialSymbol.java b/subprojects/store/src/main/java/tools/refinery/store/partial/representation/AnyPartialSymbol.java deleted file mode 100644 index 25096e74..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/partial/representation/AnyPartialSymbol.java +++ /dev/null | |||
@@ -1,11 +0,0 @@ | |||
1 | package tools.refinery.store.partial.representation; | ||
2 | |||
3 | import tools.refinery.store.representation.AnyAbstractDomain; | ||
4 | |||
5 | public sealed interface AnyPartialSymbol permits AnyPartialFunction, PartialSymbol { | ||
6 | String name(); | ||
7 | |||
8 | int arity(); | ||
9 | |||
10 | AnyAbstractDomain abstractDomain(); | ||
11 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/partial/representation/PartialFunction.java b/subprojects/store/src/main/java/tools/refinery/store/partial/representation/PartialFunction.java deleted file mode 100644 index 3c186f6f..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/partial/representation/PartialFunction.java +++ /dev/null | |||
@@ -1,32 +0,0 @@ | |||
1 | package tools.refinery.store.partial.representation; | ||
2 | |||
3 | import tools.refinery.store.representation.AbstractDomain; | ||
4 | |||
5 | public record PartialFunction<A, C>(String name, int arity, AbstractDomain<A, C> abstractDomain) | ||
6 | implements AnyPartialFunction, PartialSymbol<A, C> { | ||
7 | @Override | ||
8 | public A defaultValue() { | ||
9 | return null; | ||
10 | } | ||
11 | |||
12 | @Override | ||
13 | public C defaultConcreteValue() { | ||
14 | return null; | ||
15 | } | ||
16 | |||
17 | @Override | ||
18 | public boolean equals(Object o) { | ||
19 | return this == o; | ||
20 | } | ||
21 | |||
22 | @Override | ||
23 | public int hashCode() { | ||
24 | // Compare by identity to make hash table lookups more efficient. | ||
25 | return System.identityHashCode(this); | ||
26 | } | ||
27 | |||
28 | @Override | ||
29 | public String toString() { | ||
30 | return "%s/%d".formatted(name, arity); | ||
31 | } | ||
32 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/partial/representation/PartialRelation.java b/subprojects/store/src/main/java/tools/refinery/store/partial/representation/PartialRelation.java deleted file mode 100644 index 127355ca..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/partial/representation/PartialRelation.java +++ /dev/null | |||
@@ -1,66 +0,0 @@ | |||
1 | package tools.refinery.store.partial.representation; | ||
2 | |||
3 | import tools.refinery.store.partial.literal.ModalRelationLiteral; | ||
4 | import tools.refinery.store.partial.literal.PartialRelationLiteral; | ||
5 | import tools.refinery.store.query.RelationLike; | ||
6 | import tools.refinery.store.query.Variable; | ||
7 | import tools.refinery.store.query.literal.CallPolarity; | ||
8 | import tools.refinery.store.partial.literal.Modality; | ||
9 | import tools.refinery.store.representation.AbstractDomain; | ||
10 | import tools.refinery.store.representation.TruthValue; | ||
11 | import tools.refinery.store.representation.TruthValueDomain; | ||
12 | |||
13 | import java.util.List; | ||
14 | |||
15 | public record PartialRelation(String name, int arity) implements PartialSymbol<TruthValue, Boolean>, RelationLike { | ||
16 | @Override | ||
17 | public AbstractDomain<TruthValue, Boolean> abstractDomain() { | ||
18 | return TruthValueDomain.INSTANCE; | ||
19 | } | ||
20 | |||
21 | @Override | ||
22 | public TruthValue defaultValue() { | ||
23 | return TruthValue.FALSE; | ||
24 | } | ||
25 | |||
26 | @Override | ||
27 | public Boolean defaultConcreteValue() { | ||
28 | return false; | ||
29 | } | ||
30 | |||
31 | public ModalRelationLiteral call(CallPolarity polarity, Modality modality, List<Variable> arguments) { | ||
32 | return new ModalRelationLiteral(polarity, modality, this, arguments); | ||
33 | } | ||
34 | |||
35 | public PartialRelationLiteral call(CallPolarity polarity, List<Variable> arguments) { | ||
36 | return new PartialRelationLiteral(polarity, this, arguments); | ||
37 | } | ||
38 | |||
39 | public PartialRelationLiteral call(CallPolarity polarity, Variable... arguments) { | ||
40 | return call(polarity, List.of(arguments)); | ||
41 | } | ||
42 | |||
43 | public PartialRelationLiteral call(Variable... arguments) { | ||
44 | return call(CallPolarity.POSITIVE, arguments); | ||
45 | } | ||
46 | |||
47 | public PartialRelationLiteral callTransitive(Variable left, Variable right) { | ||
48 | return call(CallPolarity.TRANSITIVE, List.of(left, right)); | ||
49 | } | ||
50 | |||
51 | @Override | ||
52 | public boolean equals(Object o) { | ||
53 | return this == o; | ||
54 | } | ||
55 | |||
56 | @Override | ||
57 | public int hashCode() { | ||
58 | // Compare by identity to make hash table lookups more efficient. | ||
59 | return System.identityHashCode(this); | ||
60 | } | ||
61 | |||
62 | @Override | ||
63 | public String toString() { | ||
64 | return "%s/%d".formatted(name, arity); | ||
65 | } | ||
66 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/partial/representation/PartialSymbol.java b/subprojects/store/src/main/java/tools/refinery/store/partial/representation/PartialSymbol.java deleted file mode 100644 index 38533fa9..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/partial/representation/PartialSymbol.java +++ /dev/null | |||
@@ -1,12 +0,0 @@ | |||
1 | package tools.refinery.store.partial.representation; | ||
2 | |||
3 | import tools.refinery.store.representation.AbstractDomain; | ||
4 | |||
5 | public sealed interface PartialSymbol<A, C> extends AnyPartialSymbol permits PartialFunction, PartialRelation { | ||
6 | @Override | ||
7 | AbstractDomain<A, C> abstractDomain(); | ||
8 | |||
9 | A defaultValue(); | ||
10 | |||
11 | C defaultConcreteValue(); | ||
12 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/partial/translator/typehierarchy/EliminatedType.java b/subprojects/store/src/main/java/tools/refinery/store/partial/translator/typehierarchy/EliminatedType.java deleted file mode 100644 index 9adf6bc8..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/partial/translator/typehierarchy/EliminatedType.java +++ /dev/null | |||
@@ -1,6 +0,0 @@ | |||
1 | package tools.refinery.store.partial.translator.typehierarchy; | ||
2 | |||
3 | import tools.refinery.store.partial.representation.PartialRelation; | ||
4 | |||
5 | record EliminatedType(PartialRelation replacement) implements TypeAnalysisResult { | ||
6 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/partial/translator/typehierarchy/ExtendedTypeInfo.java b/subprojects/store/src/main/java/tools/refinery/store/partial/translator/typehierarchy/ExtendedTypeInfo.java deleted file mode 100644 index d3f66a4c..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/partial/translator/typehierarchy/ExtendedTypeInfo.java +++ /dev/null | |||
@@ -1,101 +0,0 @@ | |||
1 | package tools.refinery.store.partial.translator.typehierarchy; | ||
2 | |||
3 | import org.jetbrains.annotations.NotNull; | ||
4 | import tools.refinery.store.partial.representation.PartialRelation; | ||
5 | |||
6 | import java.util.HashSet; | ||
7 | import java.util.LinkedHashSet; | ||
8 | import java.util.Objects; | ||
9 | import java.util.Set; | ||
10 | |||
11 | final class ExtendedTypeInfo implements Comparable<ExtendedTypeInfo> { | ||
12 | private final int index; | ||
13 | private final PartialRelation type; | ||
14 | private final TypeInfo typeInfo; | ||
15 | private final Set<PartialRelation> allSubtypes = new LinkedHashSet<>(); | ||
16 | private final Set<PartialRelation> allSupertypes; | ||
17 | private final Set<PartialRelation> concreteSubtypesAndSelf = new LinkedHashSet<>(); | ||
18 | private Set<PartialRelation> directSubtypes; | ||
19 | private final Set<PartialRelation> unsortedDirectSupertypes = new HashSet<>(); | ||
20 | |||
21 | public ExtendedTypeInfo(int index, PartialRelation type, TypeInfo typeInfo) { | ||
22 | this.index = index; | ||
23 | this.type = type; | ||
24 | this.typeInfo = typeInfo; | ||
25 | this.allSupertypes = new LinkedHashSet<>(typeInfo.supertypes()); | ||
26 | } | ||
27 | |||
28 | public PartialRelation getType() { | ||
29 | return type; | ||
30 | } | ||
31 | |||
32 | public TypeInfo getTypeInfo() { | ||
33 | return typeInfo; | ||
34 | } | ||
35 | |||
36 | public boolean isAbstractType() { | ||
37 | return getTypeInfo().abstractType(); | ||
38 | } | ||
39 | |||
40 | public Set<PartialRelation> getAllSubtypes() { | ||
41 | return allSubtypes; | ||
42 | } | ||
43 | |||
44 | public Set<PartialRelation> getAllSupertypes() { | ||
45 | return allSupertypes; | ||
46 | } | ||
47 | |||
48 | public Set<PartialRelation> getAllSupertypesAndSelf() { | ||
49 | var allSubtypesAndSelf = new HashSet<PartialRelation>(allSupertypes.size() + 1); | ||
50 | addMust(allSubtypesAndSelf); | ||
51 | return allSubtypesAndSelf; | ||
52 | } | ||
53 | |||
54 | public Set<PartialRelation> getConcreteSubtypesAndSelf() { | ||
55 | return concreteSubtypesAndSelf; | ||
56 | } | ||
57 | |||
58 | public Set<PartialRelation> getDirectSubtypes() { | ||
59 | return directSubtypes; | ||
60 | } | ||
61 | |||
62 | public Set<PartialRelation> getUnsortedDirectSupertypes() { | ||
63 | return unsortedDirectSupertypes; | ||
64 | } | ||
65 | |||
66 | public void setDirectSubtypes(Set<PartialRelation> directSubtypes) { | ||
67 | this.directSubtypes = directSubtypes; | ||
68 | } | ||
69 | |||
70 | public boolean allowsAllConcreteTypes(Set<PartialRelation> concreteTypes) { | ||
71 | for (var concreteType : concreteTypes) { | ||
72 | if (!concreteSubtypesAndSelf.contains(concreteType)) { | ||
73 | return false; | ||
74 | } | ||
75 | } | ||
76 | return true; | ||
77 | } | ||
78 | |||
79 | public void addMust(Set<PartialRelation> mustTypes) { | ||
80 | mustTypes.add(type); | ||
81 | mustTypes.addAll(allSupertypes); | ||
82 | } | ||
83 | |||
84 | @Override | ||
85 | public int compareTo(@NotNull ExtendedTypeInfo extendedTypeInfo) { | ||
86 | return Integer.compare(index, extendedTypeInfo.index); | ||
87 | } | ||
88 | |||
89 | @Override | ||
90 | public boolean equals(Object o) { | ||
91 | if (this == o) return true; | ||
92 | if (o == null || getClass() != o.getClass()) return false; | ||
93 | ExtendedTypeInfo that = (ExtendedTypeInfo) o; | ||
94 | return index == that.index; | ||
95 | } | ||
96 | |||
97 | @Override | ||
98 | public int hashCode() { | ||
99 | return Objects.hash(index); | ||
100 | } | ||
101 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/partial/translator/typehierarchy/InferredType.java b/subprojects/store/src/main/java/tools/refinery/store/partial/translator/typehierarchy/InferredType.java deleted file mode 100644 index 729b1fb5..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/partial/translator/typehierarchy/InferredType.java +++ /dev/null | |||
@@ -1,30 +0,0 @@ | |||
1 | package tools.refinery.store.partial.translator.typehierarchy; | ||
2 | |||
3 | import tools.refinery.store.partial.representation.PartialRelation; | ||
4 | |||
5 | import java.util.Collections; | ||
6 | import java.util.Set; | ||
7 | |||
8 | record InferredType(Set<PartialRelation> mustTypes, Set<PartialRelation> mayConcreteTypes, | ||
9 | PartialRelation currentType) { | ||
10 | public static final InferredType UNTYPED = new InferredType(Set.of(), Set.of(), null); | ||
11 | |||
12 | public InferredType(Set<PartialRelation> mustTypes, Set<PartialRelation> mayConcreteTypes, | ||
13 | PartialRelation currentType) { | ||
14 | this.mustTypes = Collections.unmodifiableSet(mustTypes); | ||
15 | this.mayConcreteTypes = Collections.unmodifiableSet(mayConcreteTypes); | ||
16 | this.currentType = currentType; | ||
17 | } | ||
18 | |||
19 | public boolean isConsistent() { | ||
20 | return currentType != null || mustTypes.isEmpty(); | ||
21 | } | ||
22 | |||
23 | public boolean isMust(PartialRelation partialRelation) { | ||
24 | return mustTypes.contains(partialRelation); | ||
25 | } | ||
26 | |||
27 | public boolean isMayConcrete(PartialRelation partialRelation) { | ||
28 | return mayConcreteTypes.contains(partialRelation); | ||
29 | } | ||
30 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/partial/translator/typehierarchy/PreservedType.java b/subprojects/store/src/main/java/tools/refinery/store/partial/translator/typehierarchy/PreservedType.java deleted file mode 100644 index 0299ae03..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/partial/translator/typehierarchy/PreservedType.java +++ /dev/null | |||
@@ -1,136 +0,0 @@ | |||
1 | package tools.refinery.store.partial.translator.typehierarchy; | ||
2 | |||
3 | import tools.refinery.store.partial.representation.PartialRelation; | ||
4 | import tools.refinery.store.representation.TruthValue; | ||
5 | |||
6 | import java.util.*; | ||
7 | |||
8 | final class PreservedType implements TypeAnalysisResult { | ||
9 | private final ExtendedTypeInfo extendedTypeInfo; | ||
10 | private final List<PartialRelation> directSubtypes; | ||
11 | private final List<ExtendedTypeInfo> allExternalTypeInfoList; | ||
12 | private final InferredType inferredType; | ||
13 | |||
14 | public PreservedType(ExtendedTypeInfo extendedTypeInfo, List<ExtendedTypeInfo> allExternalTypeInfoList) { | ||
15 | this.extendedTypeInfo = extendedTypeInfo; | ||
16 | directSubtypes = List.copyOf(extendedTypeInfo.getDirectSubtypes()); | ||
17 | this.allExternalTypeInfoList = allExternalTypeInfoList; | ||
18 | inferredType = propagateMust(extendedTypeInfo.getAllSupertypesAndSelf(), | ||
19 | extendedTypeInfo.getConcreteSubtypesAndSelf()); | ||
20 | } | ||
21 | |||
22 | public PartialRelation type() { | ||
23 | return extendedTypeInfo.getType(); | ||
24 | } | ||
25 | |||
26 | public List<PartialRelation> getDirectSubtypes() { | ||
27 | return directSubtypes; | ||
28 | } | ||
29 | |||
30 | public boolean isAbstractType() { | ||
31 | return extendedTypeInfo.isAbstractType(); | ||
32 | } | ||
33 | |||
34 | public boolean isVacuous() { | ||
35 | return isAbstractType() && directSubtypes.isEmpty(); | ||
36 | } | ||
37 | |||
38 | public InferredType asInferredType() { | ||
39 | return inferredType; | ||
40 | } | ||
41 | |||
42 | public InferredType merge(InferredType inferredType, TruthValue value) { | ||
43 | return switch (value) { | ||
44 | case UNKNOWN -> inferredType; | ||
45 | case TRUE -> addMust(inferredType); | ||
46 | case FALSE -> removeMay(inferredType); | ||
47 | case ERROR -> addError(inferredType); | ||
48 | }; | ||
49 | } | ||
50 | |||
51 | private InferredType addMust(InferredType inferredType) { | ||
52 | var originalMustTypes = inferredType.mustTypes(); | ||
53 | if (originalMustTypes.contains(type())) { | ||
54 | return inferredType; | ||
55 | } | ||
56 | var mustTypes = new HashSet<>(originalMustTypes); | ||
57 | extendedTypeInfo.addMust(mustTypes); | ||
58 | var originalMayConcreteTypes = inferredType.mayConcreteTypes(); | ||
59 | var mayConcreteTypes = new LinkedHashSet<>(originalMayConcreteTypes); | ||
60 | Set<PartialRelation> mayConcreteTypesResult; | ||
61 | if (mayConcreteTypes.retainAll(extendedTypeInfo.getConcreteSubtypesAndSelf())) { | ||
62 | mayConcreteTypesResult = mayConcreteTypes; | ||
63 | } else { | ||
64 | mayConcreteTypesResult = originalMayConcreteTypes; | ||
65 | } | ||
66 | return propagateMust(mustTypes, mayConcreteTypesResult); | ||
67 | } | ||
68 | |||
69 | private InferredType removeMay(InferredType inferredType) { | ||
70 | var originalMayConcreteTypes = inferredType.mayConcreteTypes(); | ||
71 | var mayConcreteTypes = new LinkedHashSet<>(originalMayConcreteTypes); | ||
72 | if (!mayConcreteTypes.removeAll(extendedTypeInfo.getConcreteSubtypesAndSelf())) { | ||
73 | return inferredType; | ||
74 | } | ||
75 | return propagateMust(inferredType.mustTypes(), mayConcreteTypes); | ||
76 | } | ||
77 | |||
78 | private InferredType addError(InferredType inferredType) { | ||
79 | var originalMustTypes = inferredType.mustTypes(); | ||
80 | if (originalMustTypes.contains(type())) { | ||
81 | if (inferredType.mayConcreteTypes().isEmpty()) { | ||
82 | return inferredType; | ||
83 | } | ||
84 | return new InferredType(originalMustTypes, Set.of(), null); | ||
85 | } | ||
86 | var mustTypes = new HashSet<>(originalMustTypes); | ||
87 | extendedTypeInfo.addMust(mustTypes); | ||
88 | return new InferredType(mustTypes, Set.of(), null); | ||
89 | } | ||
90 | |||
91 | private InferredType propagateMust(Set<PartialRelation> originalMustTypes, | ||
92 | Set<PartialRelation> mayConcreteTypes) { | ||
93 | // It is possible that there is not type at all, do not force one by propagation. | ||
94 | var maybeUntyped = originalMustTypes.isEmpty(); | ||
95 | // Para-consistent case, do not propagate must types to avoid logical explosion. | ||
96 | var paraConsistentOrSurelyUntyped = mayConcreteTypes.isEmpty(); | ||
97 | if (maybeUntyped || paraConsistentOrSurelyUntyped) { | ||
98 | return new InferredType(originalMustTypes, mayConcreteTypes, null); | ||
99 | } | ||
100 | var currentType = computeCurrentType(mayConcreteTypes); | ||
101 | var mustTypes = new HashSet<>(originalMustTypes); | ||
102 | boolean changed = false; | ||
103 | for (var newMustExtendedTypeInfo : allExternalTypeInfoList) { | ||
104 | var newMustType = newMustExtendedTypeInfo.getType(); | ||
105 | if (mustTypes.contains(newMustType)) { | ||
106 | continue; | ||
107 | } | ||
108 | if (newMustExtendedTypeInfo.allowsAllConcreteTypes(mayConcreteTypes)) { | ||
109 | newMustExtendedTypeInfo.addMust(mustTypes); | ||
110 | changed = true; | ||
111 | } | ||
112 | } | ||
113 | if (!changed) { | ||
114 | return new InferredType(originalMustTypes, mayConcreteTypes, currentType); | ||
115 | } | ||
116 | return new InferredType(mustTypes, mayConcreteTypes, currentType); | ||
117 | } | ||
118 | |||
119 | /** | ||
120 | * Returns a concrete type that is allowed by a (consistent, i.e., nonempty) set of <b>may</b> concrete types. | ||
121 | * | ||
122 | * @param mayConcreteTypes The set of allowed concrete types. Must not be empty. | ||
123 | * @return The first concrete type that is allowed by {@code matConcreteTypes}. | ||
124 | */ | ||
125 | private PartialRelation computeCurrentType(Set<PartialRelation> mayConcreteTypes) { | ||
126 | for (var concreteExtendedTypeInfo : allExternalTypeInfoList) { | ||
127 | var concreteType = concreteExtendedTypeInfo.getType(); | ||
128 | if (!concreteExtendedTypeInfo.isAbstractType() && mayConcreteTypes.contains(concreteType)) { | ||
129 | return concreteType; | ||
130 | } | ||
131 | } | ||
132 | // We have already filtered out the para-consistent case in {@link #propagateMust(Set<PartialRelation>, | ||
133 | // Set<PartialRelation>}. | ||
134 | throw new AssertionError("No concrete type in %s".formatted(mayConcreteTypes)); | ||
135 | } | ||
136 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/partial/translator/typehierarchy/TypeAnalysisResult.java b/subprojects/store/src/main/java/tools/refinery/store/partial/translator/typehierarchy/TypeAnalysisResult.java deleted file mode 100644 index 0745f84e..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/partial/translator/typehierarchy/TypeAnalysisResult.java +++ /dev/null | |||
@@ -1,4 +0,0 @@ | |||
1 | package tools.refinery.store.partial.translator.typehierarchy; | ||
2 | |||
3 | sealed interface TypeAnalysisResult permits EliminatedType, PreservedType { | ||
4 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/partial/translator/typehierarchy/TypeAnalyzer.java b/subprojects/store/src/main/java/tools/refinery/store/partial/translator/typehierarchy/TypeAnalyzer.java deleted file mode 100644 index 062b4c49..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/partial/translator/typehierarchy/TypeAnalyzer.java +++ /dev/null | |||
@@ -1,202 +0,0 @@ | |||
1 | package tools.refinery.store.partial.translator.typehierarchy; | ||
2 | |||
3 | import tools.refinery.store.partial.representation.PartialRelation; | ||
4 | |||
5 | import java.util.*; | ||
6 | |||
7 | class TypeAnalyzer { | ||
8 | private final Map<PartialRelation, ExtendedTypeInfo> extendedTypeInfoMap; | ||
9 | private final Map<PartialRelation, PartialRelation> replacements = new LinkedHashMap<>(); | ||
10 | private final InferredType unknownType; | ||
11 | private final Map<PartialRelation, TypeAnalysisResult> analysisResults; | ||
12 | |||
13 | public TypeAnalyzer(Map<PartialRelation, TypeInfo> typeInfoMap) { | ||
14 | int size = typeInfoMap.size(); | ||
15 | extendedTypeInfoMap = new LinkedHashMap<>(size); | ||
16 | var concreteTypes = new LinkedHashSet<PartialRelation>(); | ||
17 | int index = 0; | ||
18 | for (var entry : typeInfoMap.entrySet()) { | ||
19 | var type = entry.getKey(); | ||
20 | var typeInfo = entry.getValue(); | ||
21 | extendedTypeInfoMap.put(type, new ExtendedTypeInfo(index, type, typeInfo)); | ||
22 | if (!typeInfo.abstractType()) { | ||
23 | concreteTypes.add(type); | ||
24 | } | ||
25 | index++; | ||
26 | } | ||
27 | unknownType = new InferredType(Set.of(), concreteTypes, null); | ||
28 | computeAllSupertypes(); | ||
29 | computeAllAndConcreteSubtypes(); | ||
30 | computeDirectSubtypes(); | ||
31 | eliminateTrivialSupertypes(); | ||
32 | analysisResults = computeAnalysisResults(); | ||
33 | } | ||
34 | |||
35 | public InferredType getUnknownType() { | ||
36 | return unknownType; | ||
37 | } | ||
38 | |||
39 | public Map<PartialRelation, TypeAnalysisResult> getAnalysisResults() { | ||
40 | return analysisResults; | ||
41 | } | ||
42 | |||
43 | private void computeAllSupertypes() { | ||
44 | boolean changed; | ||
45 | do { | ||
46 | changed = false; | ||
47 | for (var extendedTypeInfo : extendedTypeInfoMap.values()) { | ||
48 | var found = new HashSet<PartialRelation>(); | ||
49 | var allSupertypes = extendedTypeInfo.getAllSupertypes(); | ||
50 | for (var supertype : allSupertypes) { | ||
51 | found.addAll(extendedTypeInfoMap.get(supertype).getAllSupertypes()); | ||
52 | } | ||
53 | if (allSupertypes.addAll(found)) { | ||
54 | changed = true; | ||
55 | } | ||
56 | } | ||
57 | } while (changed); | ||
58 | } | ||
59 | |||
60 | private void computeAllAndConcreteSubtypes() { | ||
61 | for (var extendedTypeInfo : extendedTypeInfoMap.values()) { | ||
62 | var type = extendedTypeInfo.getType(); | ||
63 | if (!extendedTypeInfo.isAbstractType()) { | ||
64 | extendedTypeInfo.getConcreteSubtypesAndSelf().add(type); | ||
65 | } | ||
66 | for (var supertype : extendedTypeInfo.getAllSupertypes()) { | ||
67 | if (type.equals(supertype)) { | ||
68 | throw new IllegalArgumentException("%s cannot be a supertype of itself".formatted(type)); | ||
69 | } | ||
70 | var supertypeInfo = extendedTypeInfoMap.get(supertype); | ||
71 | supertypeInfo.getAllSubtypes().add(type); | ||
72 | if (!extendedTypeInfo.isAbstractType()) { | ||
73 | supertypeInfo.getConcreteSubtypesAndSelf().add(type); | ||
74 | } | ||
75 | } | ||
76 | } | ||
77 | } | ||
78 | |||
79 | private void computeDirectSubtypes() { | ||
80 | for (var extendedTypeInfo : extendedTypeInfoMap.values()) { | ||
81 | var allSubtypes = extendedTypeInfo.getAllSubtypes(); | ||
82 | var directSubtypes = new LinkedHashSet<>(allSubtypes); | ||
83 | var indirectSubtypes = new LinkedHashSet<PartialRelation>(allSubtypes.size()); | ||
84 | for (var subtype : allSubtypes) { | ||
85 | indirectSubtypes.addAll(extendedTypeInfoMap.get(subtype).getAllSubtypes()); | ||
86 | } | ||
87 | directSubtypes.removeAll(indirectSubtypes); | ||
88 | extendedTypeInfo.setDirectSubtypes(directSubtypes); | ||
89 | } | ||
90 | } | ||
91 | |||
92 | private void eliminateTrivialSupertypes() { | ||
93 | boolean changed; | ||
94 | do { | ||
95 | var toRemove = new ArrayList<PartialRelation>(); | ||
96 | for (var entry : extendedTypeInfoMap.entrySet()) { | ||
97 | var extendedTypeInfo = entry.getValue(); | ||
98 | boolean isAbstract = extendedTypeInfo.isAbstractType(); | ||
99 | // Do not eliminate abstract types with 0 subtypes, because they can be used para-consistently, i.e., | ||
100 | // an object determined to <b>must</b> have an abstract type with 0 subtypes <b>may not</b> ever exist. | ||
101 | boolean hasSingleDirectSubtype = extendedTypeInfo.getDirectSubtypes().size() == 1; | ||
102 | if (isAbstract && hasSingleDirectSubtype) { | ||
103 | toRemove.add(entry.getKey()); | ||
104 | } | ||
105 | } | ||
106 | toRemove.forEach(this::removeTrivialType); | ||
107 | changed = !toRemove.isEmpty(); | ||
108 | } while (changed); | ||
109 | } | ||
110 | |||
111 | private void removeTrivialType(PartialRelation trivialType) { | ||
112 | var extendedTypeInfo = extendedTypeInfoMap.get(trivialType); | ||
113 | var iterator = extendedTypeInfo.getDirectSubtypes().iterator(); | ||
114 | if (!iterator.hasNext()) { | ||
115 | throw new AssertionError("Expected trivial supertype %s to have a direct subtype" | ||
116 | .formatted(trivialType)); | ||
117 | } | ||
118 | PartialRelation replacement = setReplacement(trivialType, iterator.next()); | ||
119 | if (iterator.hasNext()) { | ||
120 | throw new AssertionError("Expected trivial supertype %s to have at most 1 direct subtype" | ||
121 | .formatted(trivialType)); | ||
122 | } | ||
123 | replacements.put(trivialType, replacement); | ||
124 | for (var supertype : extendedTypeInfo.getAllSupertypes()) { | ||
125 | var extendedSupertypeInfo = extendedTypeInfoMap.get(supertype); | ||
126 | if (!extendedSupertypeInfo.getAllSubtypes().remove(trivialType)) { | ||
127 | throw new AssertionError("Expected %s to be subtype of %s".formatted(trivialType, supertype)); | ||
128 | } | ||
129 | var directSubtypes = extendedSupertypeInfo.getDirectSubtypes(); | ||
130 | if (directSubtypes.remove(trivialType)) { | ||
131 | directSubtypes.add(replacement); | ||
132 | } | ||
133 | } | ||
134 | for (var subtype : extendedTypeInfo.getAllSubtypes()) { | ||
135 | var extendedSubtypeInfo = extendedTypeInfoMap.get(subtype); | ||
136 | if (!extendedSubtypeInfo.getAllSupertypes().remove(trivialType)) { | ||
137 | throw new AssertionError("Expected %s to be supertype of %s".formatted(trivialType, subtype)); | ||
138 | } | ||
139 | } | ||
140 | extendedTypeInfoMap.remove(trivialType); | ||
141 | } | ||
142 | |||
143 | private PartialRelation setReplacement(PartialRelation trivialRelation, PartialRelation replacement) { | ||
144 | if (replacement == null) { | ||
145 | return trivialRelation; | ||
146 | } | ||
147 | var resolved = setReplacement(replacement, replacements.get(replacement)); | ||
148 | replacements.put(trivialRelation, resolved); | ||
149 | return resolved; | ||
150 | } | ||
151 | |||
152 | private Map<PartialRelation, TypeAnalysisResult> computeAnalysisResults() { | ||
153 | var allExtendedTypeInfoList = sortTypes(); | ||
154 | var results = new LinkedHashMap<PartialRelation, TypeAnalysisResult>( | ||
155 | allExtendedTypeInfoList.size() + replacements.size()); | ||
156 | for (var extendedTypeInfo : allExtendedTypeInfoList) { | ||
157 | var type = extendedTypeInfo.getType(); | ||
158 | results.put(type, new PreservedType(extendedTypeInfo, allExtendedTypeInfoList)); | ||
159 | } | ||
160 | for (var entry : replacements.entrySet()) { | ||
161 | var type = entry.getKey(); | ||
162 | results.put(type, new EliminatedType(entry.getValue())); | ||
163 | } | ||
164 | return Collections.unmodifiableMap(results); | ||
165 | } | ||
166 | |||
167 | private List<ExtendedTypeInfo> sortTypes() { | ||
168 | // Invert {@code directSubtypes} to keep track of the out-degree of types. | ||
169 | for (var extendedTypeInfo : extendedTypeInfoMap.values()) { | ||
170 | for (var directSubtype : extendedTypeInfo.getDirectSubtypes()) { | ||
171 | var extendedDirectSubtypeInfo = extendedTypeInfoMap.get(directSubtype); | ||
172 | extendedDirectSubtypeInfo.getUnsortedDirectSupertypes().add(extendedTypeInfo.getType()); | ||
173 | } | ||
174 | } | ||
175 | // Build a <i>inverse</i> topological order ({@code extends} edges always points to earlier nodes in the order, | ||
176 | // breaking ties according to the original order ({@link ExtendedTypeInfo#index}) to form a 'stable' sort. | ||
177 | // See, e.g., https://stackoverflow.com/a/11236027. | ||
178 | var priorityQueue = new PriorityQueue<ExtendedTypeInfo>(); | ||
179 | for (var extendedTypeInfo : extendedTypeInfoMap.values()) { | ||
180 | if (extendedTypeInfo.getUnsortedDirectSupertypes().isEmpty()) { | ||
181 | priorityQueue.add(extendedTypeInfo); | ||
182 | } | ||
183 | } | ||
184 | var sorted = new ArrayList<ExtendedTypeInfo>(extendedTypeInfoMap.size()); | ||
185 | while (!priorityQueue.isEmpty()) { | ||
186 | var extendedTypeInfo = priorityQueue.remove(); | ||
187 | sorted.add(extendedTypeInfo); | ||
188 | for (var directSubtype : extendedTypeInfo.getDirectSubtypes()) { | ||
189 | var extendedDirectSubtypeInfo = extendedTypeInfoMap.get(directSubtype); | ||
190 | var unsortedDirectSupertypes = extendedDirectSubtypeInfo.getUnsortedDirectSupertypes(); | ||
191 | if (!unsortedDirectSupertypes.remove(extendedTypeInfo.getType())) { | ||
192 | throw new AssertionError("Expected %s to be a direct supertype of %s" | ||
193 | .formatted(extendedTypeInfo.getType(), directSubtype)); | ||
194 | } | ||
195 | if (unsortedDirectSupertypes.isEmpty()) { | ||
196 | priorityQueue.add(extendedDirectSubtypeInfo); | ||
197 | } | ||
198 | } | ||
199 | } | ||
200 | return Collections.unmodifiableList(sorted); | ||
201 | } | ||
202 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/partial/translator/typehierarchy/TypeInfo.java b/subprojects/store/src/main/java/tools/refinery/store/partial/translator/typehierarchy/TypeInfo.java deleted file mode 100644 index 1b0922fe..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/partial/translator/typehierarchy/TypeInfo.java +++ /dev/null | |||
@@ -1,46 +0,0 @@ | |||
1 | package tools.refinery.store.partial.translator.typehierarchy; | ||
2 | |||
3 | import tools.refinery.store.partial.representation.PartialRelation; | ||
4 | |||
5 | import java.util.*; | ||
6 | |||
7 | public record TypeInfo(Collection<PartialRelation> supertypes, boolean abstractType) { | ||
8 | public static Builder builder() { | ||
9 | return new Builder(); | ||
10 | } | ||
11 | |||
12 | public static class Builder { | ||
13 | private final Set<PartialRelation> supertypes = new LinkedHashSet<>(); | ||
14 | private boolean abstractType; | ||
15 | |||
16 | private Builder() { | ||
17 | } | ||
18 | |||
19 | public Builder supertypes(Collection<PartialRelation> supertypes) { | ||
20 | this.supertypes.addAll(supertypes); | ||
21 | return this; | ||
22 | } | ||
23 | |||
24 | public Builder supertypes(PartialRelation... supertypes) { | ||
25 | return supertypes(List.of(supertypes)); | ||
26 | } | ||
27 | |||
28 | public Builder supertype(PartialRelation supertype) { | ||
29 | supertypes.add(supertype); | ||
30 | return this; | ||
31 | } | ||
32 | |||
33 | public Builder abstractType(boolean abstractType) { | ||
34 | this.abstractType = abstractType; | ||
35 | return this; | ||
36 | } | ||
37 | |||
38 | public Builder abstractType() { | ||
39 | return abstractType(true); | ||
40 | } | ||
41 | |||
42 | public TypeInfo build() { | ||
43 | return new TypeInfo(Collections.unmodifiableSet(supertypes), abstractType); | ||
44 | } | ||
45 | } | ||
46 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/Dnf.java b/subprojects/store/src/main/java/tools/refinery/store/query/Dnf.java deleted file mode 100644 index b080094f..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/Dnf.java +++ /dev/null | |||
@@ -1,187 +0,0 @@ | |||
1 | package tools.refinery.store.query; | ||
2 | |||
3 | import tools.refinery.store.query.literal.CallPolarity; | ||
4 | import tools.refinery.store.query.literal.DnfCallLiteral; | ||
5 | import tools.refinery.store.query.literal.Literal; | ||
6 | |||
7 | import java.util.*; | ||
8 | |||
9 | public final class Dnf implements RelationLike { | ||
10 | private final String name; | ||
11 | |||
12 | private final String uniqueName; | ||
13 | |||
14 | private final List<Variable> parameters; | ||
15 | |||
16 | private final List<FunctionalDependency<Variable>> functionalDependencies; | ||
17 | |||
18 | private final List<DnfClause> clauses; | ||
19 | |||
20 | private Dnf(String name, List<Variable> parameters, List<FunctionalDependency<Variable>> functionalDependencies, | ||
21 | List<DnfClause> clauses) { | ||
22 | validateFunctionalDependencies(parameters, functionalDependencies); | ||
23 | this.name = name; | ||
24 | this.uniqueName = DnfUtils.generateUniqueName(name); | ||
25 | this.parameters = parameters; | ||
26 | this.functionalDependencies = functionalDependencies; | ||
27 | this.clauses = clauses; | ||
28 | } | ||
29 | |||
30 | private static void validateFunctionalDependencies( | ||
31 | Collection<Variable> parameters, Collection<FunctionalDependency<Variable>> functionalDependencies) { | ||
32 | var parameterSet = new HashSet<>(parameters); | ||
33 | for (var functionalDependency : functionalDependencies) { | ||
34 | validateParameters(parameters, parameterSet, functionalDependency.forEach(), functionalDependency); | ||
35 | validateParameters(parameters, parameterSet, functionalDependency.unique(), functionalDependency); | ||
36 | } | ||
37 | } | ||
38 | |||
39 | private static void validateParameters(Collection<Variable> parameters, Set<Variable> parameterSet, | ||
40 | Collection<Variable> toValidate, | ||
41 | FunctionalDependency<Variable> functionalDependency) { | ||
42 | for (var variable : toValidate) { | ||
43 | if (!parameterSet.contains(variable)) { | ||
44 | throw new IllegalArgumentException( | ||
45 | "Variable %s of functional dependency %s does not appear in the parameter list %s" | ||
46 | .formatted(variable, functionalDependency, parameters)); | ||
47 | } | ||
48 | } | ||
49 | } | ||
50 | |||
51 | @Override | ||
52 | public String name() { | ||
53 | return name; | ||
54 | } | ||
55 | |||
56 | public String getUniqueName() { | ||
57 | return uniqueName; | ||
58 | } | ||
59 | |||
60 | public List<Variable> getParameters() { | ||
61 | return parameters; | ||
62 | } | ||
63 | |||
64 | public List<FunctionalDependency<Variable>> getFunctionalDependencies() { | ||
65 | return functionalDependencies; | ||
66 | } | ||
67 | |||
68 | @Override | ||
69 | public int arity() { | ||
70 | return parameters.size(); | ||
71 | } | ||
72 | |||
73 | public List<DnfClause> getClauses() { | ||
74 | return clauses; | ||
75 | } | ||
76 | |||
77 | public DnfCallLiteral call(CallPolarity polarity, List<Variable> arguments) { | ||
78 | return new DnfCallLiteral(polarity, this, arguments); | ||
79 | } | ||
80 | |||
81 | public DnfCallLiteral call(CallPolarity polarity, Variable... arguments) { | ||
82 | return call(polarity, List.of(arguments)); | ||
83 | } | ||
84 | |||
85 | public DnfCallLiteral call(Variable... arguments) { | ||
86 | return call(CallPolarity.POSITIVE, arguments); | ||
87 | } | ||
88 | |||
89 | public DnfCallLiteral callTransitive(Variable left, Variable right) { | ||
90 | return call(CallPolarity.TRANSITIVE, List.of(left, right)); | ||
91 | } | ||
92 | |||
93 | public static Builder builder() { | ||
94 | return builder(null); | ||
95 | } | ||
96 | |||
97 | public static Builder builder(String name) { | ||
98 | return new Builder(name); | ||
99 | } | ||
100 | |||
101 | @SuppressWarnings("UnusedReturnValue") | ||
102 | public static class Builder { | ||
103 | private final String name; | ||
104 | |||
105 | private final List<Variable> parameters = new ArrayList<>(); | ||
106 | |||
107 | private final List<FunctionalDependency<Variable>> functionalDependencies = new ArrayList<>(); | ||
108 | |||
109 | private final List<List<Literal>> clauses = new ArrayList<>(); | ||
110 | |||
111 | private Builder(String name) { | ||
112 | this.name = name; | ||
113 | } | ||
114 | |||
115 | public Builder parameter(Variable variable) { | ||
116 | parameters.add(variable); | ||
117 | return this; | ||
118 | } | ||
119 | |||
120 | public Builder parameters(Variable... variables) { | ||
121 | return parameters(List.of(variables)); | ||
122 | } | ||
123 | |||
124 | public Builder parameters(Collection<Variable> variables) { | ||
125 | parameters.addAll(variables); | ||
126 | return this; | ||
127 | } | ||
128 | |||
129 | public Builder functionalDependencies(Collection<FunctionalDependency<Variable>> functionalDependencies) { | ||
130 | this.functionalDependencies.addAll(functionalDependencies); | ||
131 | return this; | ||
132 | } | ||
133 | |||
134 | public Builder functionalDependency(FunctionalDependency<Variable> functionalDependency) { | ||
135 | functionalDependencies.add(functionalDependency); | ||
136 | return this; | ||
137 | } | ||
138 | |||
139 | public Builder functionalDependency(Set<Variable> forEach, Set<Variable> unique) { | ||
140 | return functionalDependency(new FunctionalDependency<>(forEach, unique)); | ||
141 | } | ||
142 | |||
143 | public Builder clause(Literal... atoms) { | ||
144 | clauses.add(List.of(atoms)); | ||
145 | return this; | ||
146 | } | ||
147 | |||
148 | public Builder clause(Collection<Literal> atoms) { | ||
149 | clauses.add(List.copyOf(atoms)); | ||
150 | return this; | ||
151 | } | ||
152 | |||
153 | public Builder clause(DnfClause clause) { | ||
154 | return clause(clause.literals()); | ||
155 | } | ||
156 | |||
157 | public Builder clauses(DnfClause... clauses) { | ||
158 | for (var clause : clauses) { | ||
159 | this.clause(clause); | ||
160 | } | ||
161 | return this; | ||
162 | } | ||
163 | |||
164 | public Builder clauses(Collection<DnfClause> clauses) { | ||
165 | for (var clause : clauses) { | ||
166 | this.clause(clause); | ||
167 | } | ||
168 | return this; | ||
169 | } | ||
170 | |||
171 | public Dnf build() { | ||
172 | var postProcessedClauses = new ArrayList<DnfClause>(); | ||
173 | for (var constraints : clauses) { | ||
174 | var variables = new HashSet<Variable>(); | ||
175 | for (var constraint : constraints) { | ||
176 | constraint.collectAllVariables(variables); | ||
177 | } | ||
178 | parameters.forEach(variables::remove); | ||
179 | postProcessedClauses.add(new DnfClause(Collections.unmodifiableSet(variables), | ||
180 | Collections.unmodifiableList(constraints))); | ||
181 | } | ||
182 | return new Dnf(name, Collections.unmodifiableList(parameters), | ||
183 | Collections.unmodifiableList(functionalDependencies), | ||
184 | Collections.unmodifiableList(postProcessedClauses)); | ||
185 | } | ||
186 | } | ||
187 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/DnfClause.java b/subprojects/store/src/main/java/tools/refinery/store/query/DnfClause.java deleted file mode 100644 index 2ba6becc..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/DnfClause.java +++ /dev/null | |||
@@ -1,9 +0,0 @@ | |||
1 | package tools.refinery.store.query; | ||
2 | |||
3 | import tools.refinery.store.query.literal.Literal; | ||
4 | |||
5 | import java.util.List; | ||
6 | import java.util.Set; | ||
7 | |||
8 | public record DnfClause(Set<Variable> quantifiedVariables, List<Literal> literals) { | ||
9 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/DnfUtils.java b/subprojects/store/src/main/java/tools/refinery/store/query/DnfUtils.java deleted file mode 100644 index 17564d43..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/DnfUtils.java +++ /dev/null | |||
@@ -1,24 +0,0 @@ | |||
1 | package tools.refinery.store.query; | ||
2 | |||
3 | import java.util.Map; | ||
4 | import java.util.UUID; | ||
5 | |||
6 | public final class DnfUtils { | ||
7 | private DnfUtils() { | ||
8 | throw new IllegalStateException("This is a static utility class and should not be instantiated directly"); | ||
9 | } | ||
10 | |||
11 | public static String generateUniqueName(String originalName) { | ||
12 | UUID uuid = UUID.randomUUID(); | ||
13 | String uniqueString = "_" + uuid.toString().replace('-', '_'); | ||
14 | if (originalName == null) { | ||
15 | return uniqueString; | ||
16 | } else { | ||
17 | return originalName + uniqueString; | ||
18 | } | ||
19 | } | ||
20 | |||
21 | public static Variable maybeSubstitute(Variable variable, Map<Variable, Variable> substitution) { | ||
22 | return substitution.getOrDefault(variable, variable); | ||
23 | } | ||
24 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/FunctionalDependency.java b/subprojects/store/src/main/java/tools/refinery/store/query/FunctionalDependency.java deleted file mode 100644 index 63a81713..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/FunctionalDependency.java +++ /dev/null | |||
@@ -1,15 +0,0 @@ | |||
1 | package tools.refinery.store.query; | ||
2 | |||
3 | import java.util.HashSet; | ||
4 | import java.util.Set; | ||
5 | |||
6 | public record FunctionalDependency<T>(Set<T> forEach, Set<T> unique) { | ||
7 | public FunctionalDependency { | ||
8 | var uniqueForEach = new HashSet<>(unique); | ||
9 | uniqueForEach.retainAll(forEach); | ||
10 | if (!uniqueForEach.isEmpty()) { | ||
11 | throw new IllegalArgumentException("Variables %s appear on both sides of the functional dependency" | ||
12 | .formatted(uniqueForEach)); | ||
13 | } | ||
14 | } | ||
15 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/ModelQuery.java b/subprojects/store/src/main/java/tools/refinery/store/query/ModelQuery.java deleted file mode 100644 index 6a1aeabb..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/ModelQuery.java +++ /dev/null | |||
@@ -1,11 +0,0 @@ | |||
1 | package tools.refinery.store.query; | ||
2 | |||
3 | import tools.refinery.store.adapter.ModelAdapterType; | ||
4 | |||
5 | public final class ModelQuery extends ModelAdapterType<ModelQueryAdapter, ModelQueryStoreAdapter, ModelQueryBuilder> { | ||
6 | public static final ModelQuery ADAPTER = new ModelQuery(); | ||
7 | |||
8 | private ModelQuery() { | ||
9 | super(ModelQueryAdapter.class, ModelQueryStoreAdapter.class, ModelQueryBuilder.class); | ||
10 | } | ||
11 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/ModelQueryAdapter.java b/subprojects/store/src/main/java/tools/refinery/store/query/ModelQueryAdapter.java deleted file mode 100644 index f7762444..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/ModelQueryAdapter.java +++ /dev/null | |||
@@ -1,13 +0,0 @@ | |||
1 | package tools.refinery.store.query; | ||
2 | |||
3 | import tools.refinery.store.adapter.ModelAdapter; | ||
4 | |||
5 | public interface ModelQueryAdapter extends ModelAdapter { | ||
6 | ModelQueryStoreAdapter getStoreAdapter(); | ||
7 | |||
8 | ResultSet getResultSet(Dnf query); | ||
9 | |||
10 | boolean hasPendingChanges(); | ||
11 | |||
12 | void flushChanges(); | ||
13 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/ModelQueryBuilder.java b/subprojects/store/src/main/java/tools/refinery/store/query/ModelQueryBuilder.java deleted file mode 100644 index b3cfb4b4..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/ModelQueryBuilder.java +++ /dev/null | |||
@@ -1,23 +0,0 @@ | |||
1 | package tools.refinery.store.query; | ||
2 | |||
3 | import tools.refinery.store.adapter.ModelAdapterBuilder; | ||
4 | import tools.refinery.store.model.ModelStore; | ||
5 | |||
6 | import java.util.Collection; | ||
7 | import java.util.List; | ||
8 | |||
9 | public interface ModelQueryBuilder extends ModelAdapterBuilder { | ||
10 | default ModelQueryBuilder queries(Dnf... queries) { | ||
11 | return queries(List.of(queries)); | ||
12 | } | ||
13 | |||
14 | default ModelQueryBuilder queries(Collection<Dnf> queries) { | ||
15 | queries.forEach(this::query); | ||
16 | return this; | ||
17 | } | ||
18 | |||
19 | ModelQueryBuilder query(Dnf query); | ||
20 | |||
21 | @Override | ||
22 | ModelQueryStoreAdapter createStoreAdapter(ModelStore store); | ||
23 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/ModelQueryStoreAdapter.java b/subprojects/store/src/main/java/tools/refinery/store/query/ModelQueryStoreAdapter.java deleted file mode 100644 index 3efeacaa..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/ModelQueryStoreAdapter.java +++ /dev/null | |||
@@ -1,16 +0,0 @@ | |||
1 | package tools.refinery.store.query; | ||
2 | |||
3 | import tools.refinery.store.adapter.ModelStoreAdapter; | ||
4 | import tools.refinery.store.model.Model; | ||
5 | import tools.refinery.store.query.view.AnyRelationView; | ||
6 | |||
7 | import java.util.Collection; | ||
8 | |||
9 | public interface ModelQueryStoreAdapter extends ModelStoreAdapter { | ||
10 | Collection<AnyRelationView> getRelationViews(); | ||
11 | |||
12 | Collection<Dnf> getQueries(); | ||
13 | |||
14 | @Override | ||
15 | ModelQueryAdapter createModelAdapter(Model model); | ||
16 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/RelationLike.java b/subprojects/store/src/main/java/tools/refinery/store/query/RelationLike.java deleted file mode 100644 index 8c784d8b..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/RelationLike.java +++ /dev/null | |||
@@ -1,11 +0,0 @@ | |||
1 | package tools.refinery.store.query; | ||
2 | |||
3 | public interface RelationLike { | ||
4 | String name(); | ||
5 | |||
6 | int arity(); | ||
7 | |||
8 | default boolean invalidIndex(int i) { | ||
9 | return i < 0 || i >= arity(); | ||
10 | } | ||
11 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/ResultSet.java b/subprojects/store/src/main/java/tools/refinery/store/query/ResultSet.java deleted file mode 100644 index 3542e252..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/ResultSet.java +++ /dev/null | |||
@@ -1,25 +0,0 @@ | |||
1 | package tools.refinery.store.query; | ||
2 | |||
3 | import tools.refinery.store.tuple.Tuple; | ||
4 | import tools.refinery.store.tuple.TupleLike; | ||
5 | |||
6 | import java.util.Optional; | ||
7 | import java.util.stream.Stream; | ||
8 | |||
9 | public interface ResultSet { | ||
10 | boolean hasResult(); | ||
11 | |||
12 | boolean hasResult(Tuple parameters); | ||
13 | |||
14 | Optional<TupleLike> oneResult(); | ||
15 | |||
16 | Optional<TupleLike> oneResult(Tuple parameters); | ||
17 | |||
18 | Stream<TupleLike> allResults(); | ||
19 | |||
20 | Stream<TupleLike> allResults(Tuple parameters); | ||
21 | |||
22 | int countResults(); | ||
23 | |||
24 | int countResults(Tuple parameters); | ||
25 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/Variable.java b/subprojects/store/src/main/java/tools/refinery/store/query/Variable.java deleted file mode 100644 index 2eb87649..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/Variable.java +++ /dev/null | |||
@@ -1,58 +0,0 @@ | |||
1 | package tools.refinery.store.query; | ||
2 | |||
3 | import tools.refinery.store.query.literal.ConstantLiteral; | ||
4 | import tools.refinery.store.query.literal.EquivalenceLiteral; | ||
5 | |||
6 | import java.util.Objects; | ||
7 | |||
8 | public class Variable { | ||
9 | private final String name; | ||
10 | private final String uniqueName; | ||
11 | |||
12 | public Variable() { | ||
13 | this(null); | ||
14 | } | ||
15 | |||
16 | public Variable(String name) { | ||
17 | super(); | ||
18 | this.name = name; | ||
19 | this.uniqueName = DnfUtils.generateUniqueName(name); | ||
20 | |||
21 | } | ||
22 | public String getName() { | ||
23 | return name; | ||
24 | } | ||
25 | |||
26 | public String getUniqueName() { | ||
27 | return uniqueName; | ||
28 | } | ||
29 | |||
30 | public boolean isNamed() { | ||
31 | return name != null; | ||
32 | } | ||
33 | |||
34 | public ConstantLiteral isConstant(int value) { | ||
35 | return new ConstantLiteral(this, value); | ||
36 | } | ||
37 | |||
38 | public EquivalenceLiteral isEquivalent(Variable other) { | ||
39 | return new EquivalenceLiteral(true, this, other); | ||
40 | } | ||
41 | |||
42 | public EquivalenceLiteral notEquivalent(Variable other) { | ||
43 | return new EquivalenceLiteral(false, this, other); | ||
44 | } | ||
45 | |||
46 | @Override | ||
47 | public boolean equals(Object o) { | ||
48 | if (this == o) return true; | ||
49 | if (o == null || getClass() != o.getClass()) return false; | ||
50 | Variable variable = (Variable) o; | ||
51 | return Objects.equals(uniqueName, variable.uniqueName); | ||
52 | } | ||
53 | |||
54 | @Override | ||
55 | public int hashCode() { | ||
56 | return Objects.hash(uniqueName); | ||
57 | } | ||
58 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/literal/CallLiteral.java b/subprojects/store/src/main/java/tools/refinery/store/query/literal/CallLiteral.java deleted file mode 100644 index 5e1ae94d..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/literal/CallLiteral.java +++ /dev/null | |||
@@ -1,66 +0,0 @@ | |||
1 | package tools.refinery.store.query.literal; | ||
2 | |||
3 | import tools.refinery.store.query.DnfUtils; | ||
4 | import tools.refinery.store.query.RelationLike; | ||
5 | import tools.refinery.store.query.Variable; | ||
6 | |||
7 | import java.util.List; | ||
8 | import java.util.Map; | ||
9 | import java.util.Objects; | ||
10 | import java.util.Set; | ||
11 | |||
12 | public abstract class CallLiteral<T extends RelationLike> implements Literal { | ||
13 | private final CallPolarity polarity; | ||
14 | private final T target; | ||
15 | private final List<Variable> arguments; | ||
16 | |||
17 | protected CallLiteral(CallPolarity polarity, T target, List<Variable> arguments) { | ||
18 | if (arguments.size() != target.arity()) { | ||
19 | throw new IllegalArgumentException("%s needs %d arguments, but got %s".formatted(target.name(), | ||
20 | target.arity(), arguments.size())); | ||
21 | } | ||
22 | if (polarity.isTransitive() && target.arity() != 2) { | ||
23 | throw new IllegalArgumentException("Transitive closures can only take binary relations"); | ||
24 | } | ||
25 | this.polarity = polarity; | ||
26 | this.target = target; | ||
27 | this.arguments = arguments; | ||
28 | } | ||
29 | |||
30 | public CallPolarity getPolarity() { | ||
31 | return polarity; | ||
32 | } | ||
33 | |||
34 | public T getTarget() { | ||
35 | return target; | ||
36 | } | ||
37 | |||
38 | public List<Variable> getArguments() { | ||
39 | return arguments; | ||
40 | } | ||
41 | |||
42 | @Override | ||
43 | public void collectAllVariables(Set<Variable> variables) { | ||
44 | if (polarity.isPositive()) { | ||
45 | variables.addAll(arguments); | ||
46 | } | ||
47 | } | ||
48 | |||
49 | protected List<Variable> substituteArguments(Map<Variable, Variable> substitution) { | ||
50 | return arguments.stream().map(variable -> DnfUtils.maybeSubstitute(variable, substitution)).toList(); | ||
51 | } | ||
52 | |||
53 | @Override | ||
54 | public boolean equals(Object o) { | ||
55 | if (this == o) return true; | ||
56 | if (o == null || getClass() != o.getClass()) return false; | ||
57 | CallLiteral<?> callAtom = (CallLiteral<?>) o; | ||
58 | return polarity == callAtom.polarity && Objects.equals(target, callAtom.target) && | ||
59 | Objects.equals(arguments, callAtom.arguments); | ||
60 | } | ||
61 | |||
62 | @Override | ||
63 | public int hashCode() { | ||
64 | return Objects.hash(polarity, target, arguments); | ||
65 | } | ||
66 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/literal/CallPolarity.java b/subprojects/store/src/main/java/tools/refinery/store/query/literal/CallPolarity.java deleted file mode 100644 index 84b4b771..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/literal/CallPolarity.java +++ /dev/null | |||
@@ -1,32 +0,0 @@ | |||
1 | package tools.refinery.store.query.literal; | ||
2 | |||
3 | public enum CallPolarity { | ||
4 | POSITIVE(true, false), | ||
5 | NEGATIVE(false, false), | ||
6 | TRANSITIVE(true, true); | ||
7 | |||
8 | private final boolean positive; | ||
9 | |||
10 | private final boolean transitive; | ||
11 | |||
12 | CallPolarity(boolean positive, boolean transitive) { | ||
13 | this.positive = positive; | ||
14 | this.transitive = transitive; | ||
15 | } | ||
16 | |||
17 | public boolean isPositive() { | ||
18 | return positive; | ||
19 | } | ||
20 | |||
21 | public boolean isTransitive() { | ||
22 | return transitive; | ||
23 | } | ||
24 | |||
25 | public CallPolarity negate() { | ||
26 | return switch (this) { | ||
27 | case POSITIVE -> NEGATIVE; | ||
28 | case NEGATIVE -> POSITIVE; | ||
29 | case TRANSITIVE -> throw new IllegalArgumentException("Transitive polarity cannot be negated"); | ||
30 | }; | ||
31 | } | ||
32 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/literal/ConstantLiteral.java b/subprojects/store/src/main/java/tools/refinery/store/query/literal/ConstantLiteral.java deleted file mode 100644 index 746d23af..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/literal/ConstantLiteral.java +++ /dev/null | |||
@@ -1,19 +0,0 @@ | |||
1 | package tools.refinery.store.query.literal; | ||
2 | |||
3 | import tools.refinery.store.query.DnfUtils; | ||
4 | import tools.refinery.store.query.Variable; | ||
5 | |||
6 | import java.util.Map; | ||
7 | import java.util.Set; | ||
8 | |||
9 | public record ConstantLiteral(Variable variable, int nodeId) implements Literal { | ||
10 | @Override | ||
11 | public void collectAllVariables(Set<Variable> variables) { | ||
12 | variables.add(variable); | ||
13 | } | ||
14 | |||
15 | @Override | ||
16 | public ConstantLiteral substitute(Map<Variable, Variable> substitution) { | ||
17 | return new ConstantLiteral(DnfUtils.maybeSubstitute(variable, substitution), nodeId); | ||
18 | } | ||
19 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/literal/DnfCallLiteral.java b/subprojects/store/src/main/java/tools/refinery/store/query/literal/DnfCallLiteral.java deleted file mode 100644 index 40499222..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/literal/DnfCallLiteral.java +++ /dev/null | |||
@@ -1,23 +0,0 @@ | |||
1 | package tools.refinery.store.query.literal; | ||
2 | |||
3 | import tools.refinery.store.query.Dnf; | ||
4 | import tools.refinery.store.query.Variable; | ||
5 | |||
6 | import java.util.List; | ||
7 | import java.util.Map; | ||
8 | |||
9 | public final class DnfCallLiteral extends CallLiteral<Dnf> implements PolarLiteral<DnfCallLiteral> { | ||
10 | public DnfCallLiteral(CallPolarity polarity, Dnf target, List<Variable> arguments) { | ||
11 | super(polarity, target, arguments); | ||
12 | } | ||
13 | |||
14 | @Override | ||
15 | public DnfCallLiteral substitute(Map<Variable, Variable> substitution) { | ||
16 | return new DnfCallLiteral(getPolarity(), getTarget(), substituteArguments(substitution)); | ||
17 | } | ||
18 | |||
19 | @Override | ||
20 | public DnfCallLiteral negate() { | ||
21 | return new DnfCallLiteral(getPolarity().negate(), getTarget(), getArguments()); | ||
22 | } | ||
23 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/literal/EquivalenceLiteral.java b/subprojects/store/src/main/java/tools/refinery/store/query/literal/EquivalenceLiteral.java deleted file mode 100644 index 5fee54b1..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/literal/EquivalenceLiteral.java +++ /dev/null | |||
@@ -1,27 +0,0 @@ | |||
1 | package tools.refinery.store.query.literal; | ||
2 | |||
3 | import tools.refinery.store.query.DnfUtils; | ||
4 | import tools.refinery.store.query.Variable; | ||
5 | |||
6 | import java.util.Map; | ||
7 | import java.util.Set; | ||
8 | |||
9 | public record EquivalenceLiteral(boolean positive, Variable left, Variable right) | ||
10 | implements PolarLiteral<EquivalenceLiteral> { | ||
11 | @Override | ||
12 | public void collectAllVariables(Set<Variable> variables) { | ||
13 | variables.add(left); | ||
14 | variables.add(right); | ||
15 | } | ||
16 | |||
17 | @Override | ||
18 | public EquivalenceLiteral negate() { | ||
19 | return new EquivalenceLiteral(!positive, left, right); | ||
20 | } | ||
21 | |||
22 | @Override | ||
23 | public EquivalenceLiteral substitute(Map<Variable, Variable> substitution) { | ||
24 | return new EquivalenceLiteral(positive, DnfUtils.maybeSubstitute(left, substitution), | ||
25 | DnfUtils.maybeSubstitute(right, substitution)); | ||
26 | } | ||
27 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/literal/Literal.java b/subprojects/store/src/main/java/tools/refinery/store/query/literal/Literal.java deleted file mode 100644 index e0f5f605..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/literal/Literal.java +++ /dev/null | |||
@@ -1,12 +0,0 @@ | |||
1 | package tools.refinery.store.query.literal; | ||
2 | |||
3 | import tools.refinery.store.query.Variable; | ||
4 | |||
5 | import java.util.Map; | ||
6 | import java.util.Set; | ||
7 | |||
8 | public interface Literal { | ||
9 | void collectAllVariables(Set<Variable> variables); | ||
10 | |||
11 | Literal substitute(Map<Variable, Variable> substitution); | ||
12 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/literal/Literals.java b/subprojects/store/src/main/java/tools/refinery/store/query/literal/Literals.java deleted file mode 100644 index 2c7e893f..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/literal/Literals.java +++ /dev/null | |||
@@ -1,11 +0,0 @@ | |||
1 | package tools.refinery.store.query.literal; | ||
2 | |||
3 | public final class Literals { | ||
4 | private Literals() { | ||
5 | throw new IllegalStateException("This is a static utility class and should not be instantiated directly"); | ||
6 | } | ||
7 | |||
8 | public static <T extends PolarLiteral<T>> T not(PolarLiteral<T> literal) { | ||
9 | return literal.negate(); | ||
10 | } | ||
11 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/literal/PolarLiteral.java b/subprojects/store/src/main/java/tools/refinery/store/query/literal/PolarLiteral.java deleted file mode 100644 index 32523675..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/literal/PolarLiteral.java +++ /dev/null | |||
@@ -1,5 +0,0 @@ | |||
1 | package tools.refinery.store.query.literal; | ||
2 | |||
3 | public interface PolarLiteral<T extends PolarLiteral<T>> extends Literal { | ||
4 | T negate(); | ||
5 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/literal/RelationViewLiteral.java b/subprojects/store/src/main/java/tools/refinery/store/query/literal/RelationViewLiteral.java deleted file mode 100644 index 4718b550..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/literal/RelationViewLiteral.java +++ /dev/null | |||
@@ -1,24 +0,0 @@ | |||
1 | package tools.refinery.store.query.literal; | ||
2 | |||
3 | import tools.refinery.store.query.Variable; | ||
4 | import tools.refinery.store.query.view.AnyRelationView; | ||
5 | |||
6 | import java.util.List; | ||
7 | import java.util.Map; | ||
8 | |||
9 | public final class RelationViewLiteral extends CallLiteral<AnyRelationView> | ||
10 | implements PolarLiteral<RelationViewLiteral> { | ||
11 | public RelationViewLiteral(CallPolarity polarity, AnyRelationView target, List<Variable> arguments) { | ||
12 | super(polarity, target, arguments); | ||
13 | } | ||
14 | |||
15 | @Override | ||
16 | public RelationViewLiteral substitute(Map<Variable, Variable> substitution) { | ||
17 | return new RelationViewLiteral(getPolarity(), getTarget(), substituteArguments(substitution)); | ||
18 | } | ||
19 | |||
20 | @Override | ||
21 | public RelationViewLiteral negate() { | ||
22 | return new RelationViewLiteral(getPolarity().negate(), getTarget(), getArguments()); | ||
23 | } | ||
24 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/view/AnyRelationView.java b/subprojects/store/src/main/java/tools/refinery/store/query/view/AnyRelationView.java deleted file mode 100644 index 328cde3a..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/view/AnyRelationView.java +++ /dev/null | |||
@@ -1,24 +0,0 @@ | |||
1 | package tools.refinery.store.query.view; | ||
2 | |||
3 | import tools.refinery.store.model.Model; | ||
4 | import tools.refinery.store.query.FunctionalDependency; | ||
5 | import tools.refinery.store.representation.AnySymbol; | ||
6 | import tools.refinery.store.query.RelationLike; | ||
7 | |||
8 | import java.util.Set; | ||
9 | |||
10 | public sealed interface AnyRelationView extends RelationLike permits RelationView { | ||
11 | AnySymbol getSymbol(); | ||
12 | |||
13 | default Set<FunctionalDependency<Integer>> getFunctionalDependencies() { | ||
14 | return Set.of(); | ||
15 | } | ||
16 | |||
17 | default Set<RelationViewImplication> getImpliedRelationViews() { | ||
18 | return Set.of(); | ||
19 | } | ||
20 | |||
21 | boolean get(Model model, Object[] tuple); | ||
22 | |||
23 | Iterable<Object[]> getAll(Model model); | ||
24 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/view/FilteredRelationView.java b/subprojects/store/src/main/java/tools/refinery/store/query/view/FilteredRelationView.java deleted file mode 100644 index 64c601bb..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/view/FilteredRelationView.java +++ /dev/null | |||
@@ -1,49 +0,0 @@ | |||
1 | package tools.refinery.store.query.view; | ||
2 | |||
3 | import tools.refinery.store.tuple.Tuple; | ||
4 | import tools.refinery.store.representation.Symbol; | ||
5 | |||
6 | import java.util.Objects; | ||
7 | import java.util.function.BiPredicate; | ||
8 | import java.util.function.Predicate; | ||
9 | |||
10 | public class FilteredRelationView<T> extends TuplePreservingRelationView<T> { | ||
11 | private final BiPredicate<Tuple, T> predicate; | ||
12 | |||
13 | public FilteredRelationView(Symbol<T> symbol, String name, BiPredicate<Tuple, T> predicate) { | ||
14 | super(symbol, name); | ||
15 | this.predicate = predicate; | ||
16 | } | ||
17 | |||
18 | public FilteredRelationView(Symbol<T> symbol, BiPredicate<Tuple, T> predicate) { | ||
19 | super(symbol); | ||
20 | this.predicate = predicate; | ||
21 | } | ||
22 | |||
23 | public FilteredRelationView(Symbol<T> symbol, String name, Predicate<T> predicate) { | ||
24 | this(symbol, name, (k, v) -> predicate.test(v)); | ||
25 | } | ||
26 | |||
27 | public FilteredRelationView(Symbol<T> symbol, Predicate<T> predicate) { | ||
28 | this(symbol, (k, v) -> predicate.test(v)); | ||
29 | } | ||
30 | |||
31 | @Override | ||
32 | public boolean filter(Tuple key, T value) { | ||
33 | return this.predicate.test(key, value); | ||
34 | } | ||
35 | |||
36 | @Override | ||
37 | public boolean equals(Object o) { | ||
38 | if (this == o) return true; | ||
39 | if (o == null || getClass() != o.getClass()) return false; | ||
40 | if (!super.equals(o)) return false; | ||
41 | FilteredRelationView<?> that = (FilteredRelationView<?>) o; | ||
42 | return Objects.equals(predicate, that.predicate); | ||
43 | } | ||
44 | |||
45 | @Override | ||
46 | public int hashCode() { | ||
47 | return Objects.hash(super.hashCode(), predicate); | ||
48 | } | ||
49 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/view/FunctionalRelationView.java b/subprojects/store/src/main/java/tools/refinery/store/query/view/FunctionalRelationView.java deleted file mode 100644 index 3d278a8b..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/view/FunctionalRelationView.java +++ /dev/null | |||
@@ -1,71 +0,0 @@ | |||
1 | package tools.refinery.store.query.view; | ||
2 | |||
3 | import tools.refinery.store.model.Model; | ||
4 | import tools.refinery.store.query.FunctionalDependency; | ||
5 | import tools.refinery.store.representation.Symbol; | ||
6 | import tools.refinery.store.tuple.Tuple; | ||
7 | import tools.refinery.store.tuple.Tuple1; | ||
8 | |||
9 | import java.util.Set; | ||
10 | import java.util.stream.Collectors; | ||
11 | import java.util.stream.IntStream; | ||
12 | |||
13 | public final class FunctionalRelationView<T> extends RelationView<T> { | ||
14 | public FunctionalRelationView(Symbol<T> symbol, String name) { | ||
15 | super(symbol, name); | ||
16 | } | ||
17 | |||
18 | public FunctionalRelationView(Symbol<T> symbol) { | ||
19 | super(symbol); | ||
20 | } | ||
21 | |||
22 | @Override | ||
23 | public Set<FunctionalDependency<Integer>> getFunctionalDependencies() { | ||
24 | var arity = getSymbol().arity(); | ||
25 | var forEach = IntStream.range(0, arity).boxed().collect(Collectors.toUnmodifiableSet()); | ||
26 | var unique = Set.of(arity); | ||
27 | return Set.of(new FunctionalDependency<>(forEach, unique)); | ||
28 | } | ||
29 | |||
30 | @Override | ||
31 | public Set<RelationViewImplication> getImpliedRelationViews() { | ||
32 | var symbol = getSymbol(); | ||
33 | var impliedIndices = IntStream.range(0, symbol.arity()).boxed().toList(); | ||
34 | var keyOnlyRelationView = new KeyOnlyRelationView<>(symbol); | ||
35 | return Set.of(new RelationViewImplication(this, keyOnlyRelationView, impliedIndices)); | ||
36 | } | ||
37 | |||
38 | @Override | ||
39 | public boolean filter(Tuple key, T value) { | ||
40 | return true; | ||
41 | } | ||
42 | |||
43 | @Override | ||
44 | public Object[] forwardMap(Tuple key, T value) { | ||
45 | int size = key.getSize(); | ||
46 | Object[] result = new Object[size + 1]; | ||
47 | for (int i = 0; i < size; i++) { | ||
48 | result[i] = Tuple.of(key.get(i)); | ||
49 | } | ||
50 | result[key.getSize()] = value; | ||
51 | return result; | ||
52 | } | ||
53 | |||
54 | @Override | ||
55 | public boolean get(Model model, Object[] tuple) { | ||
56 | int[] content = new int[tuple.length - 1]; | ||
57 | for (int i = 0; i < tuple.length - 1; i++) { | ||
58 | content[i] = ((Tuple1) tuple[i]).value0(); | ||
59 | } | ||
60 | Tuple key = Tuple.of(content); | ||
61 | @SuppressWarnings("unchecked") | ||
62 | T valueInTuple = (T) tuple[tuple.length - 1]; | ||
63 | T valueInMap = model.getInterpretation(getSymbol()).get(key); | ||
64 | return valueInTuple.equals(valueInMap); | ||
65 | } | ||
66 | |||
67 | @Override | ||
68 | public int arity() { | ||
69 | return getSymbol().arity() + 1; | ||
70 | } | ||
71 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/view/KeyOnlyRelationView.java b/subprojects/store/src/main/java/tools/refinery/store/query/view/KeyOnlyRelationView.java deleted file mode 100644 index e1b2e45b..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/view/KeyOnlyRelationView.java +++ /dev/null | |||
@@ -1,36 +0,0 @@ | |||
1 | package tools.refinery.store.query.view; | ||
2 | |||
3 | import tools.refinery.store.representation.Symbol; | ||
4 | import tools.refinery.store.tuple.Tuple; | ||
5 | |||
6 | import java.util.Objects; | ||
7 | |||
8 | public final class KeyOnlyRelationView<T> extends TuplePreservingRelationView<T> { | ||
9 | public static final String VIEW_NAME = "key"; | ||
10 | |||
11 | private final T defaultValue; | ||
12 | |||
13 | public KeyOnlyRelationView(Symbol<T> symbol) { | ||
14 | super(symbol, VIEW_NAME); | ||
15 | defaultValue = symbol.defaultValue(); | ||
16 | } | ||
17 | |||
18 | @Override | ||
19 | public boolean filter(Tuple key, T value) { | ||
20 | return !Objects.equals(value, defaultValue); | ||
21 | } | ||
22 | |||
23 | @Override | ||
24 | public boolean equals(Object o) { | ||
25 | if (this == o) return true; | ||
26 | if (o == null || getClass() != o.getClass()) return false; | ||
27 | if (!super.equals(o)) return false; | ||
28 | KeyOnlyRelationView<?> that = (KeyOnlyRelationView<?>) o; | ||
29 | return Objects.equals(defaultValue, that.defaultValue); | ||
30 | } | ||
31 | |||
32 | @Override | ||
33 | public int hashCode() { | ||
34 | return Objects.hash(super.hashCode(), defaultValue); | ||
35 | } | ||
36 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/view/RelationView.java b/subprojects/store/src/main/java/tools/refinery/store/query/view/RelationView.java deleted file mode 100644 index 6accd27a..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/view/RelationView.java +++ /dev/null | |||
@@ -1,82 +0,0 @@ | |||
1 | package tools.refinery.store.query.view; | ||
2 | |||
3 | import tools.refinery.store.map.CursorAsIterator; | ||
4 | import tools.refinery.store.model.Model; | ||
5 | import tools.refinery.store.query.Variable; | ||
6 | import tools.refinery.store.query.literal.CallPolarity; | ||
7 | import tools.refinery.store.query.literal.RelationViewLiteral; | ||
8 | import tools.refinery.store.representation.Symbol; | ||
9 | import tools.refinery.store.tuple.Tuple; | ||
10 | |||
11 | import java.util.List; | ||
12 | import java.util.Objects; | ||
13 | import java.util.UUID; | ||
14 | |||
15 | /** | ||
16 | * Represents a view of a {@link Symbol} that can be queried. | ||
17 | * | ||
18 | * @param <T> | ||
19 | * @author Oszkar Semerath | ||
20 | */ | ||
21 | public abstract non-sealed class RelationView<T> implements AnyRelationView { | ||
22 | private final Symbol<T> symbol; | ||
23 | |||
24 | private final String name; | ||
25 | |||
26 | protected RelationView(Symbol<T> symbol, String name) { | ||
27 | this.symbol = symbol; | ||
28 | this.name = name; | ||
29 | } | ||
30 | |||
31 | protected RelationView(Symbol<T> representation) { | ||
32 | this(representation, UUID.randomUUID().toString()); | ||
33 | } | ||
34 | |||
35 | @Override | ||
36 | public Symbol<T> getSymbol() { | ||
37 | return symbol; | ||
38 | } | ||
39 | |||
40 | @Override | ||
41 | public String name() { | ||
42 | return symbol.name() + "#" + name; | ||
43 | } | ||
44 | |||
45 | public abstract boolean filter(Tuple key, T value); | ||
46 | |||
47 | public abstract Object[] forwardMap(Tuple key, T value); | ||
48 | |||
49 | @Override | ||
50 | public Iterable<Object[]> getAll(Model model) { | ||
51 | return (() -> new CursorAsIterator<>(model.getInterpretation(symbol).getAll(), this::forwardMap, this::filter)); | ||
52 | } | ||
53 | |||
54 | public RelationViewLiteral call(CallPolarity polarity, List<Variable> arguments) { | ||
55 | return new RelationViewLiteral(polarity, this, arguments); | ||
56 | } | ||
57 | |||
58 | public RelationViewLiteral call(CallPolarity polarity, Variable... arguments) { | ||
59 | return call(polarity, List.of(arguments)); | ||
60 | } | ||
61 | |||
62 | public RelationViewLiteral call(Variable... arguments) { | ||
63 | return call(CallPolarity.POSITIVE, arguments); | ||
64 | } | ||
65 | |||
66 | public RelationViewLiteral callTransitive(Variable left, Variable right) { | ||
67 | return call(CallPolarity.TRANSITIVE, List.of(left, right)); | ||
68 | } | ||
69 | |||
70 | @Override | ||
71 | public boolean equals(Object o) { | ||
72 | if (this == o) return true; | ||
73 | if (o == null || getClass() != o.getClass()) return false; | ||
74 | RelationView<?> that = (RelationView<?>) o; | ||
75 | return Objects.equals(symbol, that.symbol) && Objects.equals(name, that.name); | ||
76 | } | ||
77 | |||
78 | @Override | ||
79 | public int hashCode() { | ||
80 | return Objects.hash(symbol, name); | ||
81 | } | ||
82 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/view/RelationViewImplication.java b/subprojects/store/src/main/java/tools/refinery/store/query/view/RelationViewImplication.java deleted file mode 100644 index 2ba1fcc4..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/view/RelationViewImplication.java +++ /dev/null | |||
@@ -1,19 +0,0 @@ | |||
1 | package tools.refinery.store.query.view; | ||
2 | |||
3 | import java.util.List; | ||
4 | |||
5 | public record RelationViewImplication(AnyRelationView implyingRelationView, AnyRelationView impliedRelationView, | ||
6 | List<Integer> impliedIndices) { | ||
7 | public RelationViewImplication { | ||
8 | if (impliedIndices.size() != impliedRelationView.arity()) { | ||
9 | throw new IllegalArgumentException("Expected %d implied indices for %s, but %d are provided" | ||
10 | .formatted(impliedRelationView.arity(), impliedRelationView, impliedIndices.size())); | ||
11 | } | ||
12 | for (var index : impliedIndices) { | ||
13 | if (impliedRelationView.invalidIndex(index)) { | ||
14 | throw new IllegalArgumentException("%d is not a valid index for %s".formatted(index, | ||
15 | implyingRelationView)); | ||
16 | } | ||
17 | } | ||
18 | } | ||
19 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/view/TuplePreservingRelationView.java b/subprojects/store/src/main/java/tools/refinery/store/query/view/TuplePreservingRelationView.java deleted file mode 100644 index 8cc4986e..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/view/TuplePreservingRelationView.java +++ /dev/null | |||
@@ -1,44 +0,0 @@ | |||
1 | package tools.refinery.store.query.view; | ||
2 | |||
3 | import tools.refinery.store.model.Model; | ||
4 | import tools.refinery.store.tuple.Tuple; | ||
5 | import tools.refinery.store.tuple.Tuple1; | ||
6 | import tools.refinery.store.representation.Symbol; | ||
7 | |||
8 | public abstract class TuplePreservingRelationView<T> extends RelationView<T> { | ||
9 | protected TuplePreservingRelationView(Symbol<T> symbol, String name) { | ||
10 | super(symbol, name); | ||
11 | } | ||
12 | |||
13 | protected TuplePreservingRelationView(Symbol<T> symbol) { | ||
14 | super(symbol); | ||
15 | } | ||
16 | |||
17 | public Object[] forwardMap(Tuple key) { | ||
18 | Object[] result = new Object[key.getSize()]; | ||
19 | for (int i = 0; i < key.getSize(); i++) { | ||
20 | result[i] = Tuple.of(key.get(i)); | ||
21 | } | ||
22 | return result; | ||
23 | } | ||
24 | |||
25 | @Override | ||
26 | public Object[] forwardMap(Tuple key, T value) { | ||
27 | return forwardMap(key); | ||
28 | } | ||
29 | |||
30 | @Override | ||
31 | public boolean get(Model model, Object[] tuple) { | ||
32 | int[] content = new int[tuple.length]; | ||
33 | for (int i = 0; i < tuple.length; i++) { | ||
34 | content[i] = ((Tuple1) tuple[i]).value0(); | ||
35 | } | ||
36 | Tuple key = Tuple.of(content); | ||
37 | T value = model.getInterpretation(getSymbol()).get(key); | ||
38 | return filter(key, value); | ||
39 | } | ||
40 | |||
41 | public int arity() { | ||
42 | return this.getSymbol().arity(); | ||
43 | } | ||
44 | } | ||