diff options
author | Kristóf Marussy <kristof@marussy.com> | 2023-09-09 12:57:49 +0200 |
---|---|---|
committer | Kristóf Marussy <kristof@marussy.com> | 2023-09-09 12:57:49 +0200 |
commit | 0bdb400deef88cb2a7c0b8c90afebf84b29c04d5 (patch) | |
tree | d8cf379d3f1321cb1e3e44e19226c48634ae97f2 /subprojects/store-reasoning/src/main | |
parent | refactor(store): neighborhood optimization (diff) | |
download | refinery-0bdb400deef88cb2a7c0b8c90afebf84b29c04d5.tar.gz refinery-0bdb400deef88cb2a7c0b8c90afebf84b29c04d5.tar.zst refinery-0bdb400deef88cb2a7c0b8c90afebf84b29c04d5.zip |
feat: integrate DSE with partial interpretation
Diffstat (limited to 'subprojects/store-reasoning/src/main')
10 files changed, 174 insertions, 39 deletions
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/actions/CleanupActionLiteral.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/actions/CleanupActionLiteral.java new file mode 100644 index 00000000..62c35cee --- /dev/null +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/actions/CleanupActionLiteral.java | |||
@@ -0,0 +1,43 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.reasoning.actions; | ||
7 | |||
8 | import tools.refinery.store.dse.transition.actions.AbstractActionLiteral; | ||
9 | import tools.refinery.store.dse.transition.actions.BoundActionLiteral; | ||
10 | import tools.refinery.store.model.Model; | ||
11 | import tools.refinery.store.query.term.NodeVariable; | ||
12 | import tools.refinery.store.reasoning.ReasoningAdapter; | ||
13 | import tools.refinery.store.tuple.Tuple; | ||
14 | |||
15 | import java.util.List; | ||
16 | |||
17 | public class CleanupActionLiteral extends AbstractActionLiteral { | ||
18 | private final NodeVariable node; | ||
19 | |||
20 | public CleanupActionLiteral(NodeVariable node) { | ||
21 | this.node = node; | ||
22 | } | ||
23 | |||
24 | public NodeVariable getNode() { | ||
25 | return node; | ||
26 | } | ||
27 | |||
28 | @Override | ||
29 | public List<NodeVariable> getInputVariables() { | ||
30 | return List.of(node); | ||
31 | } | ||
32 | |||
33 | @Override | ||
34 | public List<NodeVariable> getOutputVariables() { | ||
35 | return List.of(); | ||
36 | } | ||
37 | |||
38 | @Override | ||
39 | public BoundActionLiteral bindToModel(Model model) { | ||
40 | var reasoningAdapter = model.getAdapter(ReasoningAdapter.class); | ||
41 | return tuple -> reasoningAdapter.cleanup(tuple.get(0)) ? Tuple.of() : null; | ||
42 | } | ||
43 | } | ||
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/actions/PartialActionLiterals.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/actions/PartialActionLiterals.java index 990d11e5..f36fde44 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/actions/PartialActionLiterals.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/actions/PartialActionLiterals.java | |||
@@ -35,4 +35,8 @@ public final class PartialActionLiterals { | |||
35 | public static FocusActionLiteral focus(NodeVariable parent, NodeVariable child) { | 35 | public static FocusActionLiteral focus(NodeVariable parent, NodeVariable child) { |
36 | return new FocusActionLiteral(parent, child); | 36 | return new FocusActionLiteral(parent, child); |
37 | } | 37 | } |
38 | |||
39 | public static CleanupActionLiteral cleanup(NodeVariable node) { | ||
40 | return new CleanupActionLiteral(node); | ||
41 | } | ||
38 | } | 42 | } |
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/internal/ReasoningBuilderImpl.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/internal/ReasoningBuilderImpl.java index d2cd2eb0..722458c8 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/internal/ReasoningBuilderImpl.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/internal/ReasoningBuilderImpl.java | |||
@@ -18,18 +18,19 @@ import tools.refinery.store.query.dnf.Query; | |||
18 | import tools.refinery.store.query.dnf.RelationalQuery; | 18 | import tools.refinery.store.query.dnf.RelationalQuery; |
19 | import tools.refinery.store.reasoning.ReasoningBuilder; | 19 | import tools.refinery.store.reasoning.ReasoningBuilder; |
20 | import tools.refinery.store.reasoning.interpretation.PartialInterpretation; | 20 | import tools.refinery.store.reasoning.interpretation.PartialInterpretation; |
21 | import tools.refinery.store.reasoning.refinement.DefaultStorageRefiner; | ||
22 | import tools.refinery.store.reasoning.translator.AnyPartialSymbolTranslator; | ||
23 | import tools.refinery.store.reasoning.translator.PartialRelationTranslator; | ||
24 | import tools.refinery.store.reasoning.lifting.DnfLifter; | 21 | import tools.refinery.store.reasoning.lifting.DnfLifter; |
25 | import tools.refinery.store.reasoning.literal.Concreteness; | 22 | import tools.refinery.store.reasoning.literal.Concreteness; |
26 | import tools.refinery.store.reasoning.literal.Modality; | 23 | import tools.refinery.store.reasoning.literal.Modality; |
24 | import tools.refinery.store.reasoning.refinement.DefaultStorageRefiner; | ||
27 | import tools.refinery.store.reasoning.refinement.PartialInterpretationRefiner; | 25 | import tools.refinery.store.reasoning.refinement.PartialInterpretationRefiner; |
28 | import tools.refinery.store.reasoning.refinement.PartialModelInitializer; | 26 | import tools.refinery.store.reasoning.refinement.PartialModelInitializer; |
29 | import tools.refinery.store.reasoning.refinement.StorageRefiner; | 27 | import tools.refinery.store.reasoning.refinement.StorageRefiner; |
30 | import tools.refinery.store.reasoning.representation.AnyPartialSymbol; | 28 | import tools.refinery.store.reasoning.representation.AnyPartialSymbol; |
29 | import tools.refinery.store.reasoning.translator.AnyPartialSymbolTranslator; | ||
30 | import tools.refinery.store.reasoning.translator.PartialRelationTranslator; | ||
31 | import tools.refinery.store.representation.AnySymbol; | 31 | import tools.refinery.store.representation.AnySymbol; |
32 | import tools.refinery.store.representation.Symbol; | 32 | import tools.refinery.store.representation.Symbol; |
33 | import tools.refinery.store.statecoding.StateCoderBuilder; | ||
33 | 34 | ||
34 | import java.util.*; | 35 | import java.util.*; |
35 | 36 | ||
@@ -109,6 +110,8 @@ public class ReasoningBuilderImpl extends AbstractModelAdapterBuilder<ReasoningS | |||
109 | @Override | 110 | @Override |
110 | protected void doConfigure(ModelStoreBuilder storeBuilder) { | 111 | protected void doConfigure(ModelStoreBuilder storeBuilder) { |
111 | storeBuilder.symbols(ReasoningAdapterImpl.NODE_COUNT_SYMBOL); | 112 | storeBuilder.symbols(ReasoningAdapterImpl.NODE_COUNT_SYMBOL); |
113 | storeBuilder.tryGetAdapter(StateCoderBuilder.class) | ||
114 | .ifPresent(stateCoderBuilder -> stateCoderBuilder.exclude(ReasoningAdapterImpl.NODE_COUNT_SYMBOL)); | ||
112 | for (var translator : translators.values()) { | 115 | for (var translator : translators.values()) { |
113 | translator.configure(storeBuilder); | 116 | translator.configure(storeBuilder); |
114 | if (translator instanceof PartialRelationTranslator relationConfiguration) { | 117 | if (translator instanceof PartialRelationTranslator relationConfiguration) { |
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/internal/ReasoningStoreAdapterImpl.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/internal/ReasoningStoreAdapterImpl.java index 8eb5a034..9ef6fb16 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/internal/ReasoningStoreAdapterImpl.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/internal/ReasoningStoreAdapterImpl.java | |||
@@ -5,6 +5,7 @@ | |||
5 | */ | 5 | */ |
6 | package tools.refinery.store.reasoning.internal; | 6 | package tools.refinery.store.reasoning.internal; |
7 | 7 | ||
8 | import tools.refinery.store.dse.propagation.PropagationAdapter; | ||
8 | import tools.refinery.store.model.Model; | 9 | import tools.refinery.store.model.Model; |
9 | import tools.refinery.store.model.ModelStore; | 10 | import tools.refinery.store.model.ModelStore; |
10 | import tools.refinery.store.query.ModelQueryAdapter; | 11 | import tools.refinery.store.query.ModelQueryAdapter; |
@@ -103,6 +104,11 @@ class ReasoningStoreAdapterImpl implements ReasoningStoreAdapter { | |||
103 | for (var initializer : initializers) { | 104 | for (var initializer : initializers) { |
104 | initializer.initialize(model, modelSeed); | 105 | initializer.initialize(model, modelSeed); |
105 | } | 106 | } |
107 | model.tryGetAdapter(PropagationAdapter.class).ifPresent(propagationAdapter -> { | ||
108 | if (propagationAdapter.propagate().isRejected()) { | ||
109 | throw new IllegalArgumentException("Inconsistent initial mode: propagation failed"); | ||
110 | } | ||
111 | }); | ||
106 | model.getAdapter(ModelQueryAdapter.class).flushChanges(); | 112 | model.getAdapter(ModelQueryAdapter.class).flushChanges(); |
107 | return model; | 113 | return model; |
108 | } | 114 | } |
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/refinement/RefinementResult.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/refinement/RefinementResult.java deleted file mode 100644 index 1bc537d1..00000000 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/refinement/RefinementResult.java +++ /dev/null | |||
@@ -1,24 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.reasoning.refinement; | ||
7 | |||
8 | public enum RefinementResult { | ||
9 | UNCHANGED, | ||
10 | REFINED, | ||
11 | REJECTED; | ||
12 | |||
13 | public RefinementResult andThen(RefinementResult next) { | ||
14 | return switch (this) { | ||
15 | case UNCHANGED -> next; | ||
16 | case REFINED -> next == REJECTED ? REJECTED : REFINED; | ||
17 | case REJECTED -> REJECTED; | ||
18 | }; | ||
19 | } | ||
20 | |||
21 | public boolean isRejected() { | ||
22 | return this == REJECTED; | ||
23 | } | ||
24 | } | ||
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/containment/ContainmentHierarchyTranslator.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/containment/ContainmentHierarchyTranslator.java index 5c3298ac..61037be3 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/containment/ContainmentHierarchyTranslator.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/containment/ContainmentHierarchyTranslator.java | |||
@@ -243,7 +243,7 @@ public class ContainmentHierarchyTranslator implements ModelStoreConfiguration { | |||
243 | MultiObjectTranslator.MULTI_VIEW.call(multi), | 243 | MultiObjectTranslator.MULTI_VIEW.call(multi), |
244 | not(may(CONTAINED_SYMBOL.call(multi))) | 244 | not(may(CONTAINED_SYMBOL.call(multi))) |
245 | ) | 245 | ) |
246 | .clause((container) -> List.of( | 246 | .clause(container -> List.of( |
247 | MultiObjectTranslator.MULTI_VIEW.call(multi), | 247 | MultiObjectTranslator.MULTI_VIEW.call(multi), |
248 | must(CONTAINS_SYMBOL.call(container, multi)), | 248 | must(CONTAINS_SYMBOL.call(container, multi)), |
249 | not(MultiObjectTranslator.MULTI_VIEW.call(container)) | 249 | not(MultiObjectTranslator.MULTI_VIEW.call(container)) |
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/containment/InferredContainment.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/containment/InferredContainment.java index 90802864..8df23d9a 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/containment/InferredContainment.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/containment/InferredContainment.java | |||
@@ -8,18 +8,23 @@ package tools.refinery.store.reasoning.translator.containment; | |||
8 | import tools.refinery.store.reasoning.representation.PartialRelation; | 8 | import tools.refinery.store.reasoning.representation.PartialRelation; |
9 | import tools.refinery.store.representation.TruthValue; | 9 | import tools.refinery.store.representation.TruthValue; |
10 | 10 | ||
11 | import java.util.Objects; | ||
11 | import java.util.Set; | 12 | import java.util.Set; |
12 | 13 | ||
13 | record InferredContainment(TruthValue contains, Set<PartialRelation> mustLinks, | 14 | final class InferredContainment { |
14 | Set<PartialRelation> forbiddenLinks) { | ||
15 | public static final InferredContainment UNKNOWN = new InferredContainment( | 15 | public static final InferredContainment UNKNOWN = new InferredContainment( |
16 | TruthValue.UNKNOWN, Set.of(), Set.of()); | 16 | TruthValue.UNKNOWN, Set.of(), Set.of()); |
17 | private final TruthValue contains; | ||
18 | private final Set<PartialRelation> mustLinks; | ||
19 | private final Set<PartialRelation> forbiddenLinks; | ||
20 | private final int hashCode; | ||
17 | 21 | ||
18 | public InferredContainment(TruthValue contains, Set<PartialRelation> mustLinks, | 22 | public InferredContainment(TruthValue contains, Set<PartialRelation> mustLinks, |
19 | Set<PartialRelation> forbiddenLinks) { | 23 | Set<PartialRelation> forbiddenLinks) { |
20 | this.contains = adjustContains(contains, mustLinks, forbiddenLinks); | 24 | this.contains = adjustContains(contains, mustLinks, forbiddenLinks); |
21 | this.mustLinks = mustLinks; | 25 | this.mustLinks = mustLinks; |
22 | this.forbiddenLinks = forbiddenLinks; | 26 | this.forbiddenLinks = forbiddenLinks; |
27 | hashCode = Objects.hash(contains, mustLinks, forbiddenLinks); | ||
23 | } | 28 | } |
24 | 29 | ||
25 | private static TruthValue adjustContains(TruthValue contains, Set<PartialRelation> mustLinks, | 30 | private static TruthValue adjustContains(TruthValue contains, Set<PartialRelation> mustLinks, |
@@ -34,4 +39,39 @@ record InferredContainment(TruthValue contains, Set<PartialRelation> mustLinks, | |||
34 | } | 39 | } |
35 | return result; | 40 | return result; |
36 | } | 41 | } |
42 | |||
43 | public TruthValue contains() { | ||
44 | return contains; | ||
45 | } | ||
46 | |||
47 | public Set<PartialRelation> mustLinks() { | ||
48 | return mustLinks; | ||
49 | } | ||
50 | |||
51 | public Set<PartialRelation> forbiddenLinks() { | ||
52 | return forbiddenLinks; | ||
53 | } | ||
54 | |||
55 | @Override | ||
56 | public boolean equals(Object obj) { | ||
57 | if (obj == this) return true; | ||
58 | if (obj == null || obj.getClass() != this.getClass()) return false; | ||
59 | var that = (InferredContainment) obj; | ||
60 | return Objects.equals(this.contains, that.contains) && | ||
61 | Objects.equals(this.mustLinks, that.mustLinks) && | ||
62 | Objects.equals(this.forbiddenLinks, that.forbiddenLinks); | ||
63 | } | ||
64 | |||
65 | @Override | ||
66 | public int hashCode() { | ||
67 | return hashCode; | ||
68 | } | ||
69 | |||
70 | @Override | ||
71 | public String toString() { | ||
72 | return "InferredContainment[" + | ||
73 | "contains=" + contains + ", " + | ||
74 | "mustLinks=" + mustLinks + ", " + | ||
75 | "forbiddenLinks=" + forbiddenLinks + ']'; | ||
76 | } | ||
37 | } | 77 | } |
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/MultiObjectTranslator.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/MultiObjectTranslator.java index 05704096..bad96a66 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/MultiObjectTranslator.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/MultiObjectTranslator.java | |||
@@ -5,17 +5,21 @@ | |||
5 | */ | 5 | */ |
6 | package tools.refinery.store.reasoning.translator.multiobject; | 6 | package tools.refinery.store.reasoning.translator.multiobject; |
7 | 7 | ||
8 | import tools.refinery.store.dse.propagation.PropagationBuilder; | ||
9 | import tools.refinery.store.dse.transition.Rule; | ||
8 | import tools.refinery.store.dse.transition.objectives.Criteria; | 10 | import tools.refinery.store.dse.transition.objectives.Criteria; |
9 | import tools.refinery.store.dse.transition.objectives.Objectives; | 11 | import tools.refinery.store.dse.transition.objectives.Objectives; |
10 | import tools.refinery.store.model.ModelStoreBuilder; | 12 | import tools.refinery.store.model.ModelStoreBuilder; |
11 | import tools.refinery.store.model.ModelStoreConfiguration; | 13 | import tools.refinery.store.model.ModelStoreConfiguration; |
12 | import tools.refinery.store.query.dnf.Query; | 14 | import tools.refinery.store.query.dnf.Query; |
15 | import tools.refinery.store.query.literal.Literals; | ||
13 | import tools.refinery.store.query.term.Variable; | 16 | import tools.refinery.store.query.term.Variable; |
14 | import tools.refinery.store.query.term.int_.IntTerms; | 17 | import tools.refinery.store.query.term.int_.IntTerms; |
15 | import tools.refinery.store.query.term.uppercardinality.UpperCardinalityTerms; | 18 | import tools.refinery.store.query.term.uppercardinality.UpperCardinalityTerms; |
16 | import tools.refinery.store.query.view.AnySymbolView; | 19 | import tools.refinery.store.query.view.AnySymbolView; |
17 | import tools.refinery.store.reasoning.ReasoningAdapter; | 20 | import tools.refinery.store.reasoning.ReasoningAdapter; |
18 | import tools.refinery.store.reasoning.ReasoningBuilder; | 21 | import tools.refinery.store.reasoning.ReasoningBuilder; |
22 | import tools.refinery.store.reasoning.actions.PartialActionLiterals; | ||
19 | import tools.refinery.store.reasoning.representation.PartialFunction; | 23 | import tools.refinery.store.reasoning.representation.PartialFunction; |
20 | import tools.refinery.store.reasoning.translator.PartialRelationTranslator; | 24 | import tools.refinery.store.reasoning.translator.PartialRelationTranslator; |
21 | import tools.refinery.store.reasoning.translator.RoundingMode; | 25 | import tools.refinery.store.reasoning.translator.RoundingMode; |
@@ -66,6 +70,11 @@ public class MultiObjectTranslator implements ModelStoreConfiguration { | |||
66 | LOWER_CARDINALITY_VIEW.call(p1, lower), | 70 | LOWER_CARDINALITY_VIEW.call(p1, lower), |
67 | check(greaterEq(lower, constant(1))) | 71 | check(greaterEq(lower, constant(1))) |
68 | )))) | 72 | )))) |
73 | .candidate(Query.of("exists#candidate", (builder, p1) -> builder | ||
74 | .clause( | ||
75 | LOWER_CARDINALITY_VIEW.call(p1, Variable.of(Integer.class)), | ||
76 | Literals.not(MULTI_VIEW.call(p1)) | ||
77 | ))) | ||
69 | .roundingMode(RoundingMode.PREFER_FALSE) | 78 | .roundingMode(RoundingMode.PREFER_FALSE) |
70 | .refiner(ExistsRefiner.of(COUNT_STORAGE)) | 79 | .refiner(ExistsRefiner.of(COUNT_STORAGE)) |
71 | .exclude(null) | 80 | .exclude(null) |
@@ -82,5 +91,17 @@ public class MultiObjectTranslator implements ModelStoreConfiguration { | |||
82 | var reasoningBuilder = storeBuilder.getAdapter(ReasoningBuilder.class); | 91 | var reasoningBuilder = storeBuilder.getAdapter(ReasoningBuilder.class); |
83 | reasoningBuilder.initializer(new MultiObjectInitializer(COUNT_STORAGE)); | 92 | reasoningBuilder.initializer(new MultiObjectInitializer(COUNT_STORAGE)); |
84 | reasoningBuilder.storageRefiner(COUNT_STORAGE, MultiObjectStorageRefiner::new); | 93 | reasoningBuilder.storageRefiner(COUNT_STORAGE, MultiObjectStorageRefiner::new); |
94 | |||
95 | storeBuilder.tryGetAdapter(PropagationBuilder.class) | ||
96 | .ifPresent(propagationBuilder -> propagationBuilder.rule( | ||
97 | Rule.of("exists#cleanup", (builder, node) -> builder | ||
98 | .clause(UpperCardinality.class, upper -> List.of( | ||
99 | UPPER_CARDINALITY_VIEW.call(node, upper), | ||
100 | check(UpperCardinalityTerms.less(upper, | ||
101 | UpperCardinalityTerms.constant(UpperCardinalities.ONE))) | ||
102 | )) | ||
103 | .action( | ||
104 | PartialActionLiterals.cleanup(node) | ||
105 | )))); | ||
85 | } | 106 | } |
86 | } | 107 | } |
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/InferredType.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/InferredType.java index 1ae94ae1..9a0c2b0f 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/InferredType.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/InferredType.java | |||
@@ -8,17 +8,22 @@ package tools.refinery.store.reasoning.translator.typehierarchy; | |||
8 | import tools.refinery.store.reasoning.representation.PartialRelation; | 8 | import tools.refinery.store.reasoning.representation.PartialRelation; |
9 | 9 | ||
10 | import java.util.Collections; | 10 | import java.util.Collections; |
11 | import java.util.Objects; | ||
11 | import java.util.Set; | 12 | import java.util.Set; |
12 | 13 | ||
13 | record InferredType(Set<PartialRelation> mustTypes, Set<PartialRelation> mayConcreteTypes, | 14 | public final class InferredType { |
14 | PartialRelation candidateType) { | ||
15 | public static final InferredType UNTYPED = new InferredType(Set.of(), Set.of(), null); | 15 | public static final InferredType UNTYPED = new InferredType(Set.of(), Set.of(), null); |
16 | private final Set<PartialRelation> mustTypes; | ||
17 | private final Set<PartialRelation> mayConcreteTypes; | ||
18 | private final PartialRelation candidateType; | ||
19 | private final int hashCode; | ||
16 | 20 | ||
17 | public InferredType(Set<PartialRelation> mustTypes, Set<PartialRelation> mayConcreteTypes, | 21 | public InferredType(Set<PartialRelation> mustTypes, Set<PartialRelation> mayConcreteTypes, |
18 | PartialRelation candidateType) { | 22 | PartialRelation candidateType) { |
19 | this.mustTypes = Collections.unmodifiableSet(mustTypes); | 23 | this.mustTypes = Collections.unmodifiableSet(mustTypes); |
20 | this.mayConcreteTypes = Collections.unmodifiableSet(mayConcreteTypes); | 24 | this.mayConcreteTypes = Collections.unmodifiableSet(mayConcreteTypes); |
21 | this.candidateType = candidateType; | 25 | this.candidateType = candidateType; |
26 | hashCode = Objects.hash(mustTypes, mayConcreteTypes, candidateType); | ||
22 | } | 27 | } |
23 | 28 | ||
24 | public boolean isConsistent() { | 29 | public boolean isConsistent() { |
@@ -32,4 +37,40 @@ record InferredType(Set<PartialRelation> mustTypes, Set<PartialRelation> mayConc | |||
32 | public boolean isMayConcrete(PartialRelation partialRelation) { | 37 | public boolean isMayConcrete(PartialRelation partialRelation) { |
33 | return mayConcreteTypes.contains(partialRelation); | 38 | return mayConcreteTypes.contains(partialRelation); |
34 | } | 39 | } |
40 | |||
41 | |||
42 | public Set<PartialRelation> mustTypes() { | ||
43 | return mustTypes; | ||
44 | } | ||
45 | |||
46 | public Set<PartialRelation> mayConcreteTypes() { | ||
47 | return mayConcreteTypes; | ||
48 | } | ||
49 | |||
50 | public PartialRelation candidateType() { | ||
51 | return candidateType; | ||
52 | } | ||
53 | |||
54 | @Override | ||
55 | public boolean equals(Object o) { | ||
56 | if (this == o) return true; | ||
57 | if (o == null || getClass() != o.getClass()) return false; | ||
58 | InferredType that = (InferredType) o; | ||
59 | return Objects.equals(mustTypes, that.mustTypes) && | ||
60 | Objects.equals(mayConcreteTypes, that.mayConcreteTypes) && | ||
61 | Objects.equals(candidateType, that.candidateType); | ||
62 | } | ||
63 | |||
64 | @Override | ||
65 | public int hashCode() { | ||
66 | return hashCode; | ||
67 | } | ||
68 | |||
69 | @Override | ||
70 | public String toString() { | ||
71 | return "InferredType[" + | ||
72 | "mustTypes=" + mustTypes + ", " + | ||
73 | "mayConcreteTypes=" + mayConcreteTypes + ", " + | ||
74 | "candidateType=" + candidateType + ']'; | ||
75 | } | ||
35 | } | 76 | } |
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/TypeHierarchyTranslator.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/TypeHierarchyTranslator.java index dc8a1d36..37ea1448 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/TypeHierarchyTranslator.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/TypeHierarchyTranslator.java | |||
@@ -26,7 +26,8 @@ import static tools.refinery.store.reasoning.literal.PartialLiterals.candidateMu | |||
26 | import static tools.refinery.store.reasoning.literal.PartialLiterals.may; | 26 | import static tools.refinery.store.reasoning.literal.PartialLiterals.may; |
27 | 27 | ||
28 | public class TypeHierarchyTranslator implements ModelStoreConfiguration { | 28 | public class TypeHierarchyTranslator implements ModelStoreConfiguration { |
29 | private final Symbol<InferredType> typeSymbol = Symbol.of("TYPE", 1, InferredType.class, InferredType.UNTYPED); | 29 | public static final Symbol<InferredType> TYPE_SYMBOL = Symbol.of("TYPE", 1, InferredType.class, |
30 | InferredType.UNTYPED); | ||
30 | private final TypeHierarchy typeHierarchy; | 31 | private final TypeHierarchy typeHierarchy; |
31 | 32 | ||
32 | public TypeHierarchyTranslator(TypeHierarchy typeHierarchy) { | 33 | public TypeHierarchyTranslator(TypeHierarchy typeHierarchy) { |
@@ -39,7 +40,7 @@ public class TypeHierarchyTranslator implements ModelStoreConfiguration { | |||
39 | return; | 40 | return; |
40 | } | 41 | } |
41 | 42 | ||
42 | storeBuilder.symbol(typeSymbol); | 43 | storeBuilder.symbol(TYPE_SYMBOL); |
43 | 44 | ||
44 | for (var entry : typeHierarchy.getPreservedTypes().entrySet()) { | 45 | for (var entry : typeHierarchy.getPreservedTypes().entrySet()) { |
45 | storeBuilder.with(createPreservedTypeTranslator(entry.getKey(), entry.getValue())); | 46 | storeBuilder.with(createPreservedTypeTranslator(entry.getKey(), entry.getValue())); |
@@ -50,13 +51,13 @@ public class TypeHierarchyTranslator implements ModelStoreConfiguration { | |||
50 | } | 51 | } |
51 | 52 | ||
52 | var reasoningBuilder = storeBuilder.getAdapter(ReasoningBuilder.class); | 53 | var reasoningBuilder = storeBuilder.getAdapter(ReasoningBuilder.class); |
53 | reasoningBuilder.initializer(new TypeHierarchyInitializer(typeHierarchy, typeSymbol)); | 54 | reasoningBuilder.initializer(new TypeHierarchyInitializer(typeHierarchy, TYPE_SYMBOL)); |
54 | } | 55 | } |
55 | 56 | ||
56 | private ModelStoreConfiguration createPreservedTypeTranslator(PartialRelation type, TypeAnalysisResult result) { | 57 | private ModelStoreConfiguration createPreservedTypeTranslator(PartialRelation type, TypeAnalysisResult result) { |
57 | var may = Query.of(type.name() + "#partial#may", (builder, p1) -> { | 58 | var may = Query.of(type.name() + "#partial#may", (builder, p1) -> { |
58 | if (!result.isAbstractType()) { | 59 | if (!result.isAbstractType()) { |
59 | builder.clause(new MayTypeView(typeSymbol, type).call(p1)); | 60 | builder.clause(new MayTypeView(TYPE_SYMBOL, type).call(p1)); |
60 | } | 61 | } |
61 | for (var subtype : result.getDirectSubtypes()) { | 62 | for (var subtype : result.getDirectSubtypes()) { |
62 | builder.clause(may(subtype.call(p1))); | 63 | builder.clause(may(subtype.call(p1))); |
@@ -64,12 +65,12 @@ public class TypeHierarchyTranslator implements ModelStoreConfiguration { | |||
64 | }); | 65 | }); |
65 | 66 | ||
66 | var must = Query.of(type.name() + "#partial#must", (builder, p1) -> builder.clause( | 67 | var must = Query.of(type.name() + "#partial#must", (builder, p1) -> builder.clause( |
67 | new MustTypeView(typeSymbol, type).call(p1) | 68 | new MustTypeView(TYPE_SYMBOL, type).call(p1) |
68 | )); | 69 | )); |
69 | 70 | ||
70 | var candidate = Query.of(type.name() + "#candidate", (builder, p1) -> { | 71 | var candidate = Query.of(type.name() + "#candidate", (builder, p1) -> { |
71 | if (!result.isAbstractType()) { | 72 | if (!result.isAbstractType()) { |
72 | builder.clause(new CandidateTypeView(typeSymbol, type).call(p1)); | 73 | builder.clause(new CandidateTypeView(TYPE_SYMBOL, type).call(p1)); |
73 | } | 74 | } |
74 | for (var subtype : result.getDirectSubtypes()) { | 75 | for (var subtype : result.getDirectSubtypes()) { |
75 | builder.clause(PartialLiterals.candidateMust(subtype.call(p1))); | 76 | builder.clause(PartialLiterals.candidateMust(subtype.call(p1))); |
@@ -80,7 +81,7 @@ public class TypeHierarchyTranslator implements ModelStoreConfiguration { | |||
80 | .may(may) | 81 | .may(may) |
81 | .must(must) | 82 | .must(must) |
82 | .candidate(candidate) | 83 | .candidate(candidate) |
83 | .refiner(InferredTypeRefiner.of(typeSymbol, result)); | 84 | .refiner(InferredTypeRefiner.of(TYPE_SYMBOL, result)); |
84 | 85 | ||
85 | if (!result.isAbstractType()) { | 86 | if (!result.isAbstractType()) { |
86 | var decision = Rule.of(type.name(), (builder, instance) -> builder | 87 | var decision = Rule.of(type.name(), (builder, instance) -> builder |