aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/store
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2023-02-20 20:23:27 +0100
committerLibravatar Kristóf Marussy <kristof@marussy.com>2023-02-20 20:23:27 +0100
commitb3f7c4d7707435803921c4fec2c4d95b3dd45c53 (patch)
tree18a90112efe3ece8678709db322dddcefafaace1 /subprojects/store
parentfeat: type inference for class hierarchies (diff)
downloadrefinery-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')
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/partial/PartialInterpretation.java19
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/partial/PartialInterpretationAdapter.java9
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/partial/PartialInterpretationBuilder.java9
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/partial/PartialInterpretationStoreAdapter.java9
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/partial/internal/PartialInterpretationAdapterImpl.java24
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/partial/internal/PartialInterpretationBuilderImpl.java17
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/partial/internal/PartialInterpretationStoreAdapterImpl.java23
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/partial/literal/ModalDnfCallLiteral.java30
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/partial/literal/ModalLiteral.java45
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/partial/literal/ModalRelationLiteral.java31
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/partial/literal/Modality.java31
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/partial/literal/PartialLiterals.java33
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/partial/literal/PartialRelationLiteral.java27
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/partial/representation/AnyPartialFunction.java4
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/partial/representation/AnyPartialSymbol.java11
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/partial/representation/PartialFunction.java32
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/partial/representation/PartialRelation.java66
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/partial/representation/PartialSymbol.java12
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/partial/translator/typehierarchy/EliminatedType.java6
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/partial/translator/typehierarchy/ExtendedTypeInfo.java101
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/partial/translator/typehierarchy/InferredType.java30
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/partial/translator/typehierarchy/PreservedType.java136
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/partial/translator/typehierarchy/TypeAnalysisResult.java4
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/partial/translator/typehierarchy/TypeAnalyzer.java202
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/partial/translator/typehierarchy/TypeInfo.java46
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/Dnf.java187
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/DnfClause.java9
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/DnfUtils.java24
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/FunctionalDependency.java15
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/ModelQuery.java11
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/ModelQueryAdapter.java13
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/ModelQueryBuilder.java23
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/ModelQueryStoreAdapter.java16
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/RelationLike.java11
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/ResultSet.java25
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/Variable.java58
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/literal/CallLiteral.java66
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/literal/CallPolarity.java32
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/literal/ConstantLiteral.java19
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/literal/DnfCallLiteral.java23
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/literal/EquivalenceLiteral.java27
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/literal/Literal.java12
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/literal/Literals.java11
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/literal/PolarLiteral.java5
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/literal/RelationViewLiteral.java24
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/view/AnyRelationView.java24
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/view/FilteredRelationView.java49
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/view/FunctionalRelationView.java71
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/view/KeyOnlyRelationView.java36
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/view/RelationView.java82
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/view/RelationViewImplication.java19
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/view/TuplePreservingRelationView.java44
-rw-r--r--subprojects/store/src/test/java/tools/refinery/store/partial/translator/typehierarchy/InferredTypeTest.java32
-rw-r--r--subprojects/store/src/test/java/tools/refinery/store/partial/translator/typehierarchy/TypeAnalyzerExampleHierarchyTest.java203
-rw-r--r--subprojects/store/src/test/java/tools/refinery/store/partial/translator/typehierarchy/TypeAnalyzerTest.java200
-rw-r--r--subprojects/store/src/test/java/tools/refinery/store/partial/translator/typehierarchy/TypeAnalyzerTester.java51
56 files changed, 0 insertions, 2379 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 @@
1package tools.refinery.store.partial;
2
3import tools.refinery.store.adapter.ModelAdapterBuilderFactory;
4import tools.refinery.store.model.ModelStoreBuilder;
5import tools.refinery.store.partial.internal.PartialInterpretationBuilderImpl;
6
7public 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 @@
1package tools.refinery.store.partial;
2
3import tools.refinery.store.adapter.ModelAdapter;
4
5public 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 @@
1package tools.refinery.store.partial;
2
3import tools.refinery.store.adapter.ModelAdapterBuilder;
4import tools.refinery.store.model.ModelStore;
5
6public 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 @@
1package tools.refinery.store.partial;
2
3import tools.refinery.store.adapter.ModelStoreAdapter;
4import tools.refinery.store.model.Model;
5
6public 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 @@
1package tools.refinery.store.partial.internal;
2
3import tools.refinery.store.model.Model;
4import tools.refinery.store.partial.PartialInterpretationAdapter;
5
6public 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 @@
1package tools.refinery.store.partial.internal;
2
3import tools.refinery.store.adapter.AbstractModelAdapterBuilder;
4import tools.refinery.store.model.ModelStore;
5import tools.refinery.store.model.ModelStoreBuilder;
6import tools.refinery.store.partial.PartialInterpretationBuilder;
7
8public 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 @@
1package tools.refinery.store.partial.internal;
2
3import tools.refinery.store.model.Model;
4import tools.refinery.store.model.ModelStore;
5import tools.refinery.store.partial.PartialInterpretationStoreAdapter;
6
7public 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 @@
1package tools.refinery.store.partial.literal;
2
3import tools.refinery.store.query.Dnf;
4import tools.refinery.store.query.Variable;
5import tools.refinery.store.query.literal.CallPolarity;
6import tools.refinery.store.query.literal.DnfCallLiteral;
7import tools.refinery.store.query.literal.PolarLiteral;
8
9import java.util.List;
10import java.util.Map;
11
12public 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 @@
1package tools.refinery.store.partial.literal;
2
3import tools.refinery.store.query.RelationLike;
4import tools.refinery.store.query.Variable;
5import tools.refinery.store.query.literal.CallLiteral;
6import tools.refinery.store.query.literal.CallPolarity;
7
8import java.util.List;
9import java.util.Objects;
10
11public 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 @@
1package tools.refinery.store.partial.literal;
2
3import tools.refinery.store.partial.representation.PartialRelation;
4import tools.refinery.store.query.Variable;
5import tools.refinery.store.query.literal.CallPolarity;
6import tools.refinery.store.query.literal.PolarLiteral;
7
8import java.util.List;
9import java.util.Map;
10
11public 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 @@
1package tools.refinery.store.partial.literal;
2
3import tools.refinery.store.query.literal.CallPolarity;
4
5import java.util.Locale;
6
7public 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 @@
1package tools.refinery.store.partial.literal;
2
3import tools.refinery.store.query.literal.DnfCallLiteral;
4
5public 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 @@
1package tools.refinery.store.partial.literal;
2
3import tools.refinery.store.partial.representation.PartialRelation;
4import tools.refinery.store.query.Variable;
5import tools.refinery.store.query.literal.CallLiteral;
6import tools.refinery.store.query.literal.CallPolarity;
7import tools.refinery.store.query.literal.PolarLiteral;
8
9import java.util.List;
10import java.util.Map;
11
12public 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 @@
1package tools.refinery.store.partial.representation;
2
3public 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 @@
1package tools.refinery.store.partial.representation;
2
3import tools.refinery.store.representation.AnyAbstractDomain;
4
5public 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 @@
1package tools.refinery.store.partial.representation;
2
3import tools.refinery.store.representation.AbstractDomain;
4
5public 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 @@
1package tools.refinery.store.partial.representation;
2
3import tools.refinery.store.partial.literal.ModalRelationLiteral;
4import tools.refinery.store.partial.literal.PartialRelationLiteral;
5import tools.refinery.store.query.RelationLike;
6import tools.refinery.store.query.Variable;
7import tools.refinery.store.query.literal.CallPolarity;
8import tools.refinery.store.partial.literal.Modality;
9import tools.refinery.store.representation.AbstractDomain;
10import tools.refinery.store.representation.TruthValue;
11import tools.refinery.store.representation.TruthValueDomain;
12
13import java.util.List;
14
15public 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 @@
1package tools.refinery.store.partial.representation;
2
3import tools.refinery.store.representation.AbstractDomain;
4
5public 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 @@
1package tools.refinery.store.partial.translator.typehierarchy;
2
3import tools.refinery.store.partial.representation.PartialRelation;
4
5record 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 @@
1package tools.refinery.store.partial.translator.typehierarchy;
2
3import org.jetbrains.annotations.NotNull;
4import tools.refinery.store.partial.representation.PartialRelation;
5
6import java.util.HashSet;
7import java.util.LinkedHashSet;
8import java.util.Objects;
9import java.util.Set;
10
11final 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 @@
1package tools.refinery.store.partial.translator.typehierarchy;
2
3import tools.refinery.store.partial.representation.PartialRelation;
4
5import java.util.Collections;
6import java.util.Set;
7
8record 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 @@
1package tools.refinery.store.partial.translator.typehierarchy;
2
3import tools.refinery.store.partial.representation.PartialRelation;
4import tools.refinery.store.representation.TruthValue;
5
6import java.util.*;
7
8final 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 @@
1package tools.refinery.store.partial.translator.typehierarchy;
2
3sealed 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 @@
1package tools.refinery.store.partial.translator.typehierarchy;
2
3import tools.refinery.store.partial.representation.PartialRelation;
4
5import java.util.*;
6
7class 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 @@
1package tools.refinery.store.partial.translator.typehierarchy;
2
3import tools.refinery.store.partial.representation.PartialRelation;
4
5import java.util.*;
6
7public 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 @@
1package tools.refinery.store.query;
2
3import tools.refinery.store.query.literal.CallPolarity;
4import tools.refinery.store.query.literal.DnfCallLiteral;
5import tools.refinery.store.query.literal.Literal;
6
7import java.util.*;
8
9public 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 @@
1package tools.refinery.store.query;
2
3import tools.refinery.store.query.literal.Literal;
4
5import java.util.List;
6import java.util.Set;
7
8public 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 @@
1package tools.refinery.store.query;
2
3import java.util.Map;
4import java.util.UUID;
5
6public 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 @@
1package tools.refinery.store.query;
2
3import java.util.HashSet;
4import java.util.Set;
5
6public 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 @@
1package tools.refinery.store.query;
2
3import tools.refinery.store.adapter.ModelAdapterType;
4
5public 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 @@
1package tools.refinery.store.query;
2
3import tools.refinery.store.adapter.ModelAdapter;
4
5public 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 @@
1package tools.refinery.store.query;
2
3import tools.refinery.store.adapter.ModelAdapterBuilder;
4import tools.refinery.store.model.ModelStore;
5
6import java.util.Collection;
7import java.util.List;
8
9public 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 @@
1package tools.refinery.store.query;
2
3import tools.refinery.store.adapter.ModelStoreAdapter;
4import tools.refinery.store.model.Model;
5import tools.refinery.store.query.view.AnyRelationView;
6
7import java.util.Collection;
8
9public 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 @@
1package tools.refinery.store.query;
2
3public 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 @@
1package tools.refinery.store.query;
2
3import tools.refinery.store.tuple.Tuple;
4import tools.refinery.store.tuple.TupleLike;
5
6import java.util.Optional;
7import java.util.stream.Stream;
8
9public 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 @@
1package tools.refinery.store.query;
2
3import tools.refinery.store.query.literal.ConstantLiteral;
4import tools.refinery.store.query.literal.EquivalenceLiteral;
5
6import java.util.Objects;
7
8public 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 @@
1package tools.refinery.store.query.literal;
2
3import tools.refinery.store.query.DnfUtils;
4import tools.refinery.store.query.RelationLike;
5import tools.refinery.store.query.Variable;
6
7import java.util.List;
8import java.util.Map;
9import java.util.Objects;
10import java.util.Set;
11
12public 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 @@
1package tools.refinery.store.query.literal;
2
3public 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 @@
1package tools.refinery.store.query.literal;
2
3import tools.refinery.store.query.DnfUtils;
4import tools.refinery.store.query.Variable;
5
6import java.util.Map;
7import java.util.Set;
8
9public 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 @@
1package tools.refinery.store.query.literal;
2
3import tools.refinery.store.query.Dnf;
4import tools.refinery.store.query.Variable;
5
6import java.util.List;
7import java.util.Map;
8
9public 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 @@
1package tools.refinery.store.query.literal;
2
3import tools.refinery.store.query.DnfUtils;
4import tools.refinery.store.query.Variable;
5
6import java.util.Map;
7import java.util.Set;
8
9public 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 @@
1package tools.refinery.store.query.literal;
2
3import tools.refinery.store.query.Variable;
4
5import java.util.Map;
6import java.util.Set;
7
8public 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 @@
1package tools.refinery.store.query.literal;
2
3public 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 @@
1package tools.refinery.store.query.literal;
2
3public 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 @@
1package tools.refinery.store.query.literal;
2
3import tools.refinery.store.query.Variable;
4import tools.refinery.store.query.view.AnyRelationView;
5
6import java.util.List;
7import java.util.Map;
8
9public 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 @@
1package tools.refinery.store.query.view;
2
3import tools.refinery.store.model.Model;
4import tools.refinery.store.query.FunctionalDependency;
5import tools.refinery.store.representation.AnySymbol;
6import tools.refinery.store.query.RelationLike;
7
8import java.util.Set;
9
10public 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 @@
1package tools.refinery.store.query.view;
2
3import tools.refinery.store.tuple.Tuple;
4import tools.refinery.store.representation.Symbol;
5
6import java.util.Objects;
7import java.util.function.BiPredicate;
8import java.util.function.Predicate;
9
10public 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 @@
1package tools.refinery.store.query.view;
2
3import tools.refinery.store.model.Model;
4import tools.refinery.store.query.FunctionalDependency;
5import tools.refinery.store.representation.Symbol;
6import tools.refinery.store.tuple.Tuple;
7import tools.refinery.store.tuple.Tuple1;
8
9import java.util.Set;
10import java.util.stream.Collectors;
11import java.util.stream.IntStream;
12
13public 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 @@
1package tools.refinery.store.query.view;
2
3import tools.refinery.store.representation.Symbol;
4import tools.refinery.store.tuple.Tuple;
5
6import java.util.Objects;
7
8public 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 @@
1package tools.refinery.store.query.view;
2
3import tools.refinery.store.map.CursorAsIterator;
4import tools.refinery.store.model.Model;
5import tools.refinery.store.query.Variable;
6import tools.refinery.store.query.literal.CallPolarity;
7import tools.refinery.store.query.literal.RelationViewLiteral;
8import tools.refinery.store.representation.Symbol;
9import tools.refinery.store.tuple.Tuple;
10
11import java.util.List;
12import java.util.Objects;
13import 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 */
21public 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 @@
1package tools.refinery.store.query.view;
2
3import java.util.List;
4
5public 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 @@
1package tools.refinery.store.query.view;
2
3import tools.refinery.store.model.Model;
4import tools.refinery.store.tuple.Tuple;
5import tools.refinery.store.tuple.Tuple1;
6import tools.refinery.store.representation.Symbol;
7
8public 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}
diff --git a/subprojects/store/src/test/java/tools/refinery/store/partial/translator/typehierarchy/InferredTypeTest.java b/subprojects/store/src/test/java/tools/refinery/store/partial/translator/typehierarchy/InferredTypeTest.java
deleted file mode 100644
index 9efa76ef..00000000
--- a/subprojects/store/src/test/java/tools/refinery/store/partial/translator/typehierarchy/InferredTypeTest.java
+++ /dev/null
@@ -1,32 +0,0 @@
1package tools.refinery.store.partial.translator.typehierarchy;
2
3import org.junit.jupiter.api.Test;
4import tools.refinery.store.partial.representation.PartialRelation;
5
6import java.util.Set;
7
8import static org.hamcrest.MatcherAssert.assertThat;
9import static org.hamcrest.Matchers.is;
10
11class InferredTypeTest {
12 private final PartialRelation c1 = new PartialRelation("C1", 1);
13 private final PartialRelation c2 = new PartialRelation("C2", 1);
14
15 @Test
16 void untypedIsConsistentTest() {
17 var sut = new InferredType(Set.of(), Set.of(c1, c2), null);
18 assertThat(sut.isConsistent(), is(true));
19 }
20
21 @Test
22 void typedIsConsistentTest() {
23 var sut = new InferredType(Set.of(c1), Set.of(c1, c2), c1);
24 assertThat(sut.isConsistent(), is(true));
25 }
26
27 @Test
28 void typedIsInconsistentTest() {
29 var sut = new InferredType(Set.of(c1), Set.of(), null);
30 assertThat(sut.isConsistent(), is(false));
31 }
32}
diff --git a/subprojects/store/src/test/java/tools/refinery/store/partial/translator/typehierarchy/TypeAnalyzerExampleHierarchyTest.java b/subprojects/store/src/test/java/tools/refinery/store/partial/translator/typehierarchy/TypeAnalyzerExampleHierarchyTest.java
deleted file mode 100644
index 5f528328..00000000
--- a/subprojects/store/src/test/java/tools/refinery/store/partial/translator/typehierarchy/TypeAnalyzerExampleHierarchyTest.java
+++ /dev/null
@@ -1,203 +0,0 @@
1package tools.refinery.store.partial.translator.typehierarchy;
2
3import org.junit.jupiter.api.BeforeEach;
4import org.junit.jupiter.api.Test;
5import tools.refinery.store.partial.representation.PartialRelation;
6import tools.refinery.store.representation.TruthValue;
7
8import java.util.LinkedHashMap;
9import java.util.Set;
10
11import static org.hamcrest.MatcherAssert.assertThat;
12import static org.hamcrest.Matchers.is;
13import static org.junit.jupiter.api.Assertions.assertAll;
14
15class TypeAnalyzerExampleHierarchyTest {
16 private final PartialRelation a1 = new PartialRelation("A1", 1);
17 private final PartialRelation a2 = new PartialRelation("A2", 1);
18 private final PartialRelation a3 = new PartialRelation("A3", 1);
19 private final PartialRelation a4 = new PartialRelation("A4", 1);
20 private final PartialRelation a5 = new PartialRelation("A5", 1);
21 private final PartialRelation c1 = new PartialRelation("C1", 1);
22 private final PartialRelation c2 = new PartialRelation("C2", 1);
23 private final PartialRelation c3 = new PartialRelation("C3", 1);
24 private final PartialRelation c4 = new PartialRelation("C4", 1);
25
26 private TypeAnalyzer sut;
27 private TypeAnalyzerTester tester;
28
29 @BeforeEach
30 void beforeEach() {
31 var typeInfoMap = new LinkedHashMap<PartialRelation, TypeInfo>();
32 typeInfoMap.put(a1, TypeInfo.builder().abstractType().build());
33 typeInfoMap.put(a2, TypeInfo.builder().abstractType().build());
34 typeInfoMap.put(a3, TypeInfo.builder().abstractType().build());
35 typeInfoMap.put(a4, TypeInfo.builder().abstractType().build());
36 typeInfoMap.put(a5, TypeInfo.builder().abstractType().build());
37 typeInfoMap.put(c1, TypeInfo.builder().supertypes(a1, a4).build());
38 typeInfoMap.put(c2, TypeInfo.builder().supertypes(a1, a2, a3, a4).build());
39 typeInfoMap.put(c3, TypeInfo.builder().supertype(a3).build());
40 typeInfoMap.put(c4, TypeInfo.builder().supertype(a4).build());
41 sut = new TypeAnalyzer(typeInfoMap);
42 tester = new TypeAnalyzerTester(sut);
43 }
44
45 @Test
46 void analysisResultsTest() {
47 assertAll(
48 () -> tester.assertAbstractType(a1, c1, c2),
49 () -> tester.assertEliminatedType(a2, c2),
50 () -> tester.assertAbstractType(a3, c2, c3),
51 () -> tester.assertAbstractType(a4, c1, c2, c4),
52 () -> tester.assertVacuousType(a5),
53 () -> tester.assertConcreteType(c1),
54 () -> tester.assertConcreteType(c2),
55 () -> tester.assertConcreteType(c3),
56 () -> tester.assertConcreteType(c4)
57 );
58 }
59
60 @Test
61 void inferredTypesTest() {
62 assertAll(
63 () -> assertThat(sut.getUnknownType(), is(new InferredType(Set.of(), Set.of(c1, c2, c3, c4), null))),
64 () -> assertThat(tester.getInferredType(a1), is(new InferredType(Set.of(a1, a4), Set.of(c1, c2), c1))),
65 () -> assertThat(tester.getInferredType(a3), is(new InferredType(Set.of(a3), Set.of(c2, c3), c2))),
66 () -> assertThat(tester.getInferredType(a4), is(new InferredType(Set.of(a4), Set.of(c1, c2, c4), c1))),
67 () -> assertThat(tester.getInferredType(a5), is(new InferredType(Set.of(a5), Set.of(), null))),
68 () -> assertThat(tester.getInferredType(c1), is(new InferredType(Set.of(a1, a4, c1), Set.of(c1), c1))),
69 () -> assertThat(tester.getInferredType(c2),
70 is(new InferredType(Set.of(a1, a3, a4, c2), Set.of(c2), c2))),
71 () -> assertThat(tester.getInferredType(c3), is(new InferredType(Set.of(a3, c3), Set.of(c3), c3))),
72 () -> assertThat(tester.getInferredType(c4), is(new InferredType(Set.of(a4, c4), Set.of(c4), c4)))
73 );
74 }
75
76 @Test
77 void consistentMustTest() {
78 var a1Result = tester.getPreservedType(a1);
79 var a3Result = tester.getPreservedType(a3);
80 var expected = new InferredType(Set.of(a1, a3, a4, c2), Set.of(c2), c2);
81 assertAll(
82 () -> assertThat(a1Result.merge(a3Result.asInferredType(), TruthValue.TRUE), is(expected)),
83 () -> assertThat(a3Result.merge(a1Result.asInferredType(), TruthValue.TRUE), is(expected)),
84 () -> assertThat(a1Result.merge(sut.getUnknownType(), TruthValue.TRUE), is(a1Result.asInferredType())),
85 () -> assertThat(a3Result.merge(sut.getUnknownType(), TruthValue.TRUE), is(a3Result.asInferredType())),
86 () -> assertThat(a1Result.merge(a1Result.asInferredType(), TruthValue.TRUE),
87 is(a1Result.asInferredType()))
88 );
89 }
90
91 @Test
92 void consistentMayNotTest() {
93 var a1Result = tester.getPreservedType(a1);
94 var a3Result = tester.getPreservedType(a3);
95 var a4Result = tester.getPreservedType(a4);
96 assertAll(
97 () -> assertThat(a1Result.merge(a3Result.asInferredType(), TruthValue.FALSE),
98 is(new InferredType(Set.of(a3, c3), Set.of(c3), c3))),
99 () -> assertThat(a3Result.merge(a1Result.asInferredType(), TruthValue.FALSE),
100 is(new InferredType(Set.of(a1, a4, c1), Set.of(c1), c1))),
101 () -> assertThat(a4Result.merge(a3Result.asInferredType(), TruthValue.FALSE),
102 is(new InferredType(Set.of(a3, c3), Set.of(c3), c3))),
103 () -> assertThat(a3Result.merge(a4Result.asInferredType(), TruthValue.FALSE),
104 is(new InferredType(Set.of(a4), Set.of(c1, c4), c1))),
105 () -> assertThat(a1Result.merge(sut.getUnknownType(), TruthValue.FALSE),
106 is(new InferredType(Set.of(), Set.of(c3, c4), null))),
107 () -> assertThat(a3Result.merge(sut.getUnknownType(), TruthValue.FALSE),
108 is(new InferredType(Set.of(), Set.of(c1, c4), null))),
109 () -> assertThat(a4Result.merge(sut.getUnknownType(), TruthValue.FALSE),
110 is(new InferredType(Set.of(), Set.of(c3), null)))
111 );
112 }
113
114 @Test
115 void consistentErrorTest() {
116 var c1Result = tester.getPreservedType(c1);
117 var a4Result = tester.getPreservedType(a4);
118 var expected = new InferredType(Set.of(c1, a1, a4), Set.of(), null);
119 assertAll(
120 () -> assertThat(c1Result.merge(a4Result.asInferredType(), TruthValue.ERROR), is(expected)),
121 () -> assertThat(a4Result.merge(c1Result.asInferredType(), TruthValue.ERROR), is(expected))
122 );
123 }
124
125 @Test
126 void consistentUnknownTest() {
127 var c1Result = tester.getPreservedType(c1);
128 var a4Result = tester.getPreservedType(a4);
129 assertAll(
130 () -> assertThat(c1Result.merge(a4Result.asInferredType(), TruthValue.UNKNOWN),
131 is(a4Result.asInferredType())),
132 () -> assertThat(a4Result.merge(c1Result.asInferredType(), TruthValue.UNKNOWN),
133 is(c1Result.asInferredType()))
134 );
135 }
136
137 @Test
138 void inconsistentMustTest() {
139 var a1Result = tester.getPreservedType(a1);
140 var c3Result = tester.getPreservedType(c3);
141 assertAll(
142 () -> assertThat(a1Result.merge(c3Result.asInferredType(), TruthValue.TRUE),
143 is(new InferredType(Set.of(a1, a3, c3), Set.of(), null))),
144 () -> assertThat(c3Result.merge(a1Result.asInferredType(), TruthValue.TRUE),
145 is(new InferredType(Set.of(a1, a3, a4, c3), Set.of(), null)))
146 );
147 }
148
149 @Test
150 void inconsistentMayNotTest() {
151 var a1Result = tester.getPreservedType(a1);
152 var a4Result = tester.getPreservedType(a4);
153 var c1Result = tester.getPreservedType(c1);
154 assertAll(
155 () -> assertThat(a4Result.merge(a1Result.asInferredType(), TruthValue.FALSE),
156 is(new InferredType(Set.of(a1, a4), Set.of(), null))),
157 () -> assertThat(a1Result.merge(c1Result.asInferredType(), TruthValue.FALSE),
158 is(new InferredType(Set.of(a1, a4, c1), Set.of(), null))),
159 () -> assertThat(a4Result.merge(c1Result.asInferredType(), TruthValue.FALSE),
160 is(new InferredType(Set.of(a1, a4, c1), Set.of(), null))),
161 () -> assertThat(a1Result.merge(a1Result.asInferredType(), TruthValue.FALSE),
162 is(new InferredType(Set.of(a1, a4), Set.of(), null)))
163 );
164 }
165
166 @Test
167 void vacuousMustTest() {
168 var c1Result = tester.getPreservedType(c1);
169 var a5Result = tester.getPreservedType(a5);
170 assertAll(
171 () -> assertThat(c1Result.merge(a5Result.asInferredType(), TruthValue.TRUE),
172 is(new InferredType(Set.of(a1, a4, a5, c1), Set.of(), null))),
173 () -> assertThat(a5Result.merge(c1Result.asInferredType(), TruthValue.TRUE),
174 is(new InferredType(Set.of(a1, a4, a5, c1), Set.of(), null)))
175 );
176 }
177
178 @Test
179 void vacuousMayNotTest() {
180 var c1Result = tester.getPreservedType(c1);
181 var a5Result = tester.getPreservedType(a5);
182 assertAll(
183 () -> assertThat(c1Result.merge(a5Result.asInferredType(), TruthValue.FALSE),
184 is(a5Result.asInferredType())),
185 () -> assertThat(a5Result.merge(c1Result.asInferredType(), TruthValue.FALSE),
186 is(c1Result.asInferredType()))
187 );
188 }
189
190 @Test
191 void vacuousErrorTest() {
192 var c1Result = tester.getPreservedType(c1);
193 var a5Result = tester.getPreservedType(a5);
194 assertAll(
195 () -> assertThat(c1Result.merge(a5Result.asInferredType(), TruthValue.ERROR),
196 is(new InferredType(Set.of(a1, a4, a5, c1), Set.of(), null))),
197 () -> assertThat(a5Result.merge(c1Result.asInferredType(), TruthValue.ERROR),
198 is(new InferredType(Set.of(a1, a4, a5, c1), Set.of(), null))),
199 () -> assertThat(a5Result.merge(a5Result.asInferredType(), TruthValue.ERROR),
200 is(a5Result.asInferredType()))
201 );
202 }
203}
diff --git a/subprojects/store/src/test/java/tools/refinery/store/partial/translator/typehierarchy/TypeAnalyzerTest.java b/subprojects/store/src/test/java/tools/refinery/store/partial/translator/typehierarchy/TypeAnalyzerTest.java
deleted file mode 100644
index 02903026..00000000
--- a/subprojects/store/src/test/java/tools/refinery/store/partial/translator/typehierarchy/TypeAnalyzerTest.java
+++ /dev/null
@@ -1,200 +0,0 @@
1package tools.refinery.store.partial.translator.typehierarchy;
2
3import org.junit.jupiter.api.Test;
4import tools.refinery.store.partial.representation.PartialRelation;
5import tools.refinery.store.representation.TruthValue;
6
7import java.util.LinkedHashMap;
8import java.util.Set;
9
10import static org.hamcrest.MatcherAssert.assertThat;
11import static org.hamcrest.Matchers.is;
12import static org.junit.jupiter.api.Assertions.assertAll;
13import static org.junit.jupiter.api.Assertions.assertThrows;
14
15class TypeAnalyzerTest {
16 @Test
17 void directSupertypesTest() {
18 var c1 = new PartialRelation("C1", 1);
19 var c2 = new PartialRelation("C2", 1);
20 var c3 = new PartialRelation("C3", 1);
21 var typeInfoMap = new LinkedHashMap<PartialRelation, TypeInfo>();
22 typeInfoMap.put(c1, TypeInfo.builder().supertypes(c2, c3).build());
23 typeInfoMap.put(c2, TypeInfo.builder().supertype(c3).build());
24 typeInfoMap.put(c3, TypeInfo.builder().build());
25
26 var sut = new TypeAnalyzer(typeInfoMap);
27 var tester = new TypeAnalyzerTester(sut);
28
29 assertAll(
30 () -> tester.assertConcreteType(c1),
31 () -> tester.assertConcreteType(c2, c1),
32 () -> tester.assertConcreteType(c3, c2)
33 );
34 }
35
36 @Test
37 void typeEliminationAbstractToConcreteTest() {
38 var c1 = new PartialRelation("C1", 1);
39 var c2 = new PartialRelation("C2", 1);
40 var a11 = new PartialRelation("A11", 1);
41 var a12 = new PartialRelation("A12", 1);
42 var a21 = new PartialRelation("A21", 1);
43 var a22 = new PartialRelation("A22", 1);
44 var a3 = new PartialRelation("A3", 1);
45 var typeInfoMap = new LinkedHashMap<PartialRelation, TypeInfo>();
46 typeInfoMap.put(a3, TypeInfo.builder().abstractType().build());
47 typeInfoMap.put(a21, TypeInfo.builder().abstractType().supertype(a3).build());
48 typeInfoMap.put(a22, TypeInfo.builder().abstractType().supertype(a3).build());
49 typeInfoMap.put(a11, TypeInfo.builder().abstractType().supertypes(a21, a22).build());
50 typeInfoMap.put(a12, TypeInfo.builder().abstractType().supertypes(a21, a22).build());
51 typeInfoMap.put(c1, TypeInfo.builder().supertypes(a11, a12).build());
52 typeInfoMap.put(c2, TypeInfo.builder().supertype(a3).build());
53
54 var sut = new TypeAnalyzer(typeInfoMap);
55 var tester = new TypeAnalyzerTester(sut);
56
57 assertAll(
58 () -> tester.assertConcreteType(c1),
59 () -> tester.assertConcreteType(c2),
60 () -> tester.assertEliminatedType(a11, c1),
61 () -> tester.assertEliminatedType(a12, c1),
62 () -> tester.assertEliminatedType(a21, c1),
63 () -> tester.assertEliminatedType(a22, c1),
64 () -> tester.assertAbstractType(a3, c1, c2)
65 );
66 }
67
68 @Test
69 void typeEliminationConcreteToAbstractTest() {
70 var c1 = new PartialRelation("C1", 1);
71 var c2 = new PartialRelation("C2", 1);
72 var a11 = new PartialRelation("A11", 1);
73 var a12 = new PartialRelation("A12", 1);
74 var a21 = new PartialRelation("A21", 1);
75 var a22 = new PartialRelation("A22", 1);
76 var a3 = new PartialRelation("A3", 1);
77 var typeInfoMap = new LinkedHashMap<PartialRelation, TypeInfo>();
78 typeInfoMap.put(c1, TypeInfo.builder().supertypes(a11, a12).build());
79 typeInfoMap.put(c2, TypeInfo.builder().supertype(a3).build());
80 typeInfoMap.put(a11, TypeInfo.builder().abstractType().supertypes(a21, a22).build());
81 typeInfoMap.put(a12, TypeInfo.builder().abstractType().supertypes(a21, a22).build());
82 typeInfoMap.put(a21, TypeInfo.builder().abstractType().supertype(a3).build());
83 typeInfoMap.put(a22, TypeInfo.builder().abstractType().supertype(a3).build());
84 typeInfoMap.put(a3, TypeInfo.builder().abstractType().build());
85
86 var sut = new TypeAnalyzer(typeInfoMap);
87 var tester = new TypeAnalyzerTester(sut);
88
89 assertAll(
90 () -> tester.assertConcreteType(c1),
91 () -> tester.assertConcreteType(c2),
92 () -> tester.assertEliminatedType(a11, c1),
93 () -> tester.assertEliminatedType(a12, c1),
94 () -> tester.assertEliminatedType(a21, c1),
95 () -> tester.assertEliminatedType(a22, c1),
96 () -> tester.assertAbstractType(a3, c1, c2)
97 );
98 }
99
100 @Test
101 void preserveConcreteTypeTest() {
102 var c1 = new PartialRelation("C1", 1);
103 var a1 = new PartialRelation("A1", 1);
104 var c2 = new PartialRelation("C2", 1);
105 var a2 = new PartialRelation("A2", 1);
106 var typeInfoMap = new LinkedHashMap<PartialRelation, TypeInfo>();
107 typeInfoMap.put(c1, TypeInfo.builder().supertype(a1).build());
108 typeInfoMap.put(a1, TypeInfo.builder().abstractType().supertype(c2).build());
109 typeInfoMap.put(c2, TypeInfo.builder().supertype(a2).build());
110 typeInfoMap.put(a2, TypeInfo.builder().abstractType().build());
111
112 var sut = new TypeAnalyzer(typeInfoMap);
113 var tester = new TypeAnalyzerTester(sut);
114
115 assertAll(
116 () -> tester.assertConcreteType(c1),
117 () -> tester.assertEliminatedType(a1, c1),
118 () -> tester.assertConcreteType(c2, c1),
119 () -> tester.assertEliminatedType(a2, c2)
120 );
121 }
122
123 @Test
124 void mostGeneralCurrentTypeTest() {
125 var c1 = new PartialRelation("C1", 1);
126 var c2 = new PartialRelation("C2", 1);
127 var c3 = new PartialRelation("C3", 1);
128 var typeInfoMap = new LinkedHashMap<PartialRelation, TypeInfo>();
129 typeInfoMap.put(c1, TypeInfo.builder().supertype(c3).build());
130 typeInfoMap.put(c2, TypeInfo.builder().supertype(c3).build());
131 typeInfoMap.put(c3, TypeInfo.builder().build());
132
133 var sut = new TypeAnalyzer(typeInfoMap);
134 var tester = new TypeAnalyzerTester(sut);
135 var c3Result = tester.getPreservedType(c3);
136
137 var expected = new InferredType(Set.of(c3), Set.of(c1, c2, c3), c3);
138 assertAll(
139 () -> assertThat(tester.getInferredType(c3), is(expected)),
140 () -> assertThat(c3Result.merge(sut.getUnknownType(), TruthValue.TRUE), is(expected))
141 );
142 }
143
144 @Test
145 void preferFirstConcreteTypeTest() {
146 var a1 = new PartialRelation("A1", 1);
147 var c1 = new PartialRelation("C1", 1);
148 var c2 = new PartialRelation("C2", 1);
149 var c3 = new PartialRelation("C3", 1);
150 var c4 = new PartialRelation("C4", 1);
151 var typeInfoMap = new LinkedHashMap<PartialRelation, TypeInfo>();
152 typeInfoMap.put(c1, TypeInfo.builder().supertype(a1).build());
153 typeInfoMap.put(c2, TypeInfo.builder().supertype(a1).build());
154 typeInfoMap.put(c3, TypeInfo.builder().supertype(a1).build());
155 typeInfoMap.put(c4, TypeInfo.builder().supertype(c3).build());
156 typeInfoMap.put(a1, TypeInfo.builder().abstractType().build());
157
158 var sut = new TypeAnalyzer(typeInfoMap);
159 var tester = new TypeAnalyzerTester(sut);
160 var c1Result = tester.getPreservedType(c1);
161 var a1Result = tester.getPreservedType(a1);
162
163 assertThat(c1Result.merge(a1Result.asInferredType(), TruthValue.FALSE),
164 is(new InferredType(Set.of(a1), Set.of(c2, c3, c4), c2)));
165 }
166
167 @Test
168 void preferFirstMostGeneralConcreteTypeTest() {
169 var a1 = new PartialRelation("A1", 1);
170 var c1 = new PartialRelation("C1", 1);
171 var c2 = new PartialRelation("C2", 1);
172 var c3 = new PartialRelation("C3", 1);
173 var c4 = new PartialRelation("C4", 1);
174 var typeInfoMap = new LinkedHashMap<PartialRelation, TypeInfo>();
175 typeInfoMap.put(c4, TypeInfo.builder().supertype(c3).build());
176 typeInfoMap.put(c3, TypeInfo.builder().supertype(a1).build());
177 typeInfoMap.put(c2, TypeInfo.builder().supertype(a1).build());
178 typeInfoMap.put(c1, TypeInfo.builder().supertype(a1).build());
179 typeInfoMap.put(a1, TypeInfo.builder().abstractType().build());
180
181 var sut = new TypeAnalyzer(typeInfoMap);
182 var tester = new TypeAnalyzerTester(sut);
183 var c1Result = tester.getPreservedType(c1);
184 var a1Result = tester.getPreservedType(a1);
185
186 assertThat(c1Result.merge(a1Result.asInferredType(), TruthValue.FALSE),
187 is(new InferredType(Set.of(a1), Set.of(c2, c3, c4), c3)));
188 }
189
190 @Test
191 void circularTypeHierarchyTest() {
192 var c1 = new PartialRelation("C1", 1);
193 var c2 = new PartialRelation("C2", 1);
194 var typeInfoMap = new LinkedHashMap<PartialRelation, TypeInfo>();
195 typeInfoMap.put(c1, TypeInfo.builder().supertype(c2).build());
196 typeInfoMap.put(c2, TypeInfo.builder().supertype(c1).build());
197
198 assertThrows(IllegalArgumentException.class, () -> new TypeAnalyzer(typeInfoMap));
199 }
200}
diff --git a/subprojects/store/src/test/java/tools/refinery/store/partial/translator/typehierarchy/TypeAnalyzerTester.java b/subprojects/store/src/test/java/tools/refinery/store/partial/translator/typehierarchy/TypeAnalyzerTester.java
deleted file mode 100644
index ce600ea6..00000000
--- a/subprojects/store/src/test/java/tools/refinery/store/partial/translator/typehierarchy/TypeAnalyzerTester.java
+++ /dev/null
@@ -1,51 +0,0 @@
1package tools.refinery.store.partial.translator.typehierarchy;
2
3import tools.refinery.store.partial.representation.PartialRelation;
4
5import static org.hamcrest.MatcherAssert.assertThat;
6import static org.hamcrest.Matchers.*;
7import static org.hamcrest.Matchers.is;
8
9class TypeAnalyzerTester {
10 private final TypeAnalyzer sut;
11
12 public TypeAnalyzerTester(TypeAnalyzer sut) {
13 this.sut = sut;
14 }
15
16 public void assertAbstractType(PartialRelation partialRelation, PartialRelation... directSubtypes) {
17 assertPreservedType(partialRelation, true, false, directSubtypes);
18 }
19
20 public void assertVacuousType(PartialRelation partialRelation) {
21 assertPreservedType(partialRelation, true, true);
22 }
23
24 public void assertConcreteType(PartialRelation partialRelation, PartialRelation... directSubtypes) {
25 assertPreservedType(partialRelation, false, false, directSubtypes);
26 }
27
28 private void assertPreservedType(PartialRelation partialRelation, boolean isAbstract, boolean isVacuous,
29 PartialRelation... directSubtypes) {
30 var result = sut.getAnalysisResults().get(partialRelation);
31 assertThat(result, is(instanceOf(PreservedType.class)));
32 var preservedResult = (PreservedType) result;
33 assertThat(preservedResult.isAbstractType(), is(isAbstract));
34 assertThat(preservedResult.isVacuous(), is(isVacuous));
35 assertThat(preservedResult.getDirectSubtypes(), hasItems(directSubtypes));
36 }
37
38 public void assertEliminatedType(PartialRelation partialRelation, PartialRelation replacement) {
39 var result = sut.getAnalysisResults().get(partialRelation);
40 assertThat(result, is(instanceOf(EliminatedType.class)));
41 assertThat(((EliminatedType) result).replacement(), is(replacement));
42 }
43
44 public PreservedType getPreservedType(PartialRelation partialRelation) {
45 return (PreservedType) sut.getAnalysisResults().get(partialRelation);
46 }
47
48 public InferredType getInferredType(PartialRelation partialRelation) {
49 return getPreservedType(partialRelation).asInferredType();
50 }
51}