diff options
Diffstat (limited to 'subprojects/store-reasoning/src/main')
2 files changed, 27 insertions, 13 deletions
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/DirectedCrossReferenceRefiner.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/DirectedCrossReferenceRefiner.java index 0700f9f7..2e804b44 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/DirectedCrossReferenceRefiner.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/DirectedCrossReferenceRefiner.java | |||
@@ -15,15 +15,17 @@ import tools.refinery.store.representation.TruthValue; | |||
15 | import tools.refinery.store.tuple.Tuple; | 15 | import tools.refinery.store.tuple.Tuple; |
16 | 16 | ||
17 | class DirectedCrossReferenceRefiner extends ConcreteSymbolRefiner<TruthValue, Boolean> { | 17 | class DirectedCrossReferenceRefiner extends ConcreteSymbolRefiner<TruthValue, Boolean> { |
18 | private final PartialRelation targetType; | ||
18 | private final PartialInterpretationRefiner<TruthValue, Boolean> sourceRefiner; | 19 | private final PartialInterpretationRefiner<TruthValue, Boolean> sourceRefiner; |
19 | private final PartialInterpretationRefiner<TruthValue, Boolean> targetRefiner; | 20 | private PartialInterpretationRefiner<TruthValue, Boolean> targetRefiner; |
20 | 21 | ||
21 | public DirectedCrossReferenceRefiner(ReasoningAdapter adapter, PartialSymbol<TruthValue, Boolean> partialSymbol, | 22 | public DirectedCrossReferenceRefiner(ReasoningAdapter adapter, PartialSymbol<TruthValue, Boolean> partialSymbol, |
22 | Symbol<TruthValue> concreteSymbol, PartialRelation sourceType, | 23 | Symbol<TruthValue> concreteSymbol, PartialRelation sourceType, |
23 | PartialRelation targetType) { | 24 | PartialRelation targetType) { |
24 | super(adapter, partialSymbol, concreteSymbol); | 25 | super(adapter, partialSymbol, concreteSymbol); |
26 | this.targetType = targetType; | ||
27 | // Source is always a class, so we can rely on the fact that it is always constructed before this refiner. | ||
25 | sourceRefiner = adapter.getRefiner(sourceType); | 28 | sourceRefiner = adapter.getRefiner(sourceType); |
26 | targetRefiner = adapter.getRefiner(targetType); | ||
27 | } | 29 | } |
28 | 30 | ||
29 | @Override | 31 | @Override |
@@ -32,6 +34,10 @@ class DirectedCrossReferenceRefiner extends ConcreteSymbolRefiner<TruthValue, Bo | |||
32 | return false; | 34 | return false; |
33 | } | 35 | } |
34 | if (value.must()) { | 36 | if (value.must()) { |
37 | if (targetRefiner == null) { | ||
38 | // Access the target refinery lazily, since it may be constructed after this refiner. | ||
39 | targetRefiner = getAdapter().getRefiner(targetType); | ||
40 | } | ||
35 | return sourceRefiner.merge(Tuple.of(key.get(0)), TruthValue.TRUE) && | 41 | return sourceRefiner.merge(Tuple.of(key.get(0)), TruthValue.TRUE) && |
36 | targetRefiner.merge(Tuple.of(key.get(1)), TruthValue.TRUE); | 42 | targetRefiner.merge(Tuple.of(key.get(1)), TruthValue.TRUE); |
37 | } | 43 | } |
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/metamodel/MetamodelBuilder.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/metamodel/MetamodelBuilder.java index ad0288ed..74022fc6 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/metamodel/MetamodelBuilder.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/metamodel/MetamodelBuilder.java | |||
@@ -153,15 +153,11 @@ public class MetamodelBuilder { | |||
153 | return; | 153 | return; |
154 | } | 154 | } |
155 | var sourceType = info.sourceType(); | 155 | var sourceType = info.sourceType(); |
156 | var targetType = info.targetType(); | ||
157 | if (typeHierarchyBuilder.isInvalidType(sourceType)) { | 156 | if (typeHierarchyBuilder.isInvalidType(sourceType)) { |
158 | throw new TranslationException(linkType, "Source type %s of %s is not in type hierarchy" | 157 | throw new TranslationException(linkType, "Source type %s of %s is not in type hierarchy" |
159 | .formatted(sourceType, linkType)); | 158 | .formatted(sourceType, linkType)); |
160 | } | 159 | } |
161 | if (typeHierarchyBuilder.isInvalidType(targetType)) { | 160 | var targetType = info.targetType(); |
162 | throw new TranslationException(linkType, "Target type %s of %s is not in type hierarchy" | ||
163 | .formatted(targetType, linkType)); | ||
164 | } | ||
165 | var opposite = info.opposite(); | 161 | var opposite = info.opposite(); |
166 | Multiplicity targetMultiplicity = UnconstrainedMultiplicity.INSTANCE; | 162 | Multiplicity targetMultiplicity = UnconstrainedMultiplicity.INSTANCE; |
167 | if (opposite != null) { | 163 | if (opposite != null) { |
@@ -185,18 +181,30 @@ public class MetamodelBuilder { | |||
185 | oppositeReferences.put(opposite, linkType); | 181 | oppositeReferences.put(opposite, linkType); |
186 | } | 182 | } |
187 | if (info.containment()) { | 183 | if (info.containment()) { |
188 | if (!UnconstrainedMultiplicity.INSTANCE.equals(targetMultiplicity)) { | 184 | processContainmentInfo(linkType, info, targetMultiplicity); |
189 | throw new TranslationException(opposite, "Invalid opposite %s with multiplicity %s of containment %s" | ||
190 | .formatted(opposite, targetMultiplicity, linkType)); | ||
191 | } | ||
192 | containedTypes.add(targetType); | ||
193 | containmentHierarchy.put(linkType, new ContainmentInfo(sourceType, info.multiplicity(), targetType)); | ||
194 | return; | 185 | return; |
195 | } | 186 | } |
196 | directedCrossReferences.put(linkType, new DirectedCrossReferenceInfo(sourceType, info.multiplicity(), | 187 | directedCrossReferences.put(linkType, new DirectedCrossReferenceInfo(sourceType, info.multiplicity(), |
197 | targetType, targetMultiplicity)); | 188 | targetType, targetMultiplicity)); |
198 | } | 189 | } |
199 | 190 | ||
191 | private void processContainmentInfo(PartialRelation linkType, ReferenceInfo info, | ||
192 | Multiplicity targetMultiplicity) { | ||
193 | var sourceType = info.sourceType(); | ||
194 | var targetType = info.targetType(); | ||
195 | var opposite = info.opposite(); | ||
196 | if (typeHierarchyBuilder.isInvalidType(targetType)) { | ||
197 | throw new TranslationException(linkType, "Target type %s of %s is not in type hierarchy" | ||
198 | .formatted(targetType, linkType)); | ||
199 | } | ||
200 | if (!UnconstrainedMultiplicity.INSTANCE.equals(targetMultiplicity)) { | ||
201 | throw new TranslationException(opposite, "Invalid opposite %s with multiplicity %s of containment %s" | ||
202 | .formatted(opposite, targetMultiplicity, linkType)); | ||
203 | } | ||
204 | containedTypes.add(targetType); | ||
205 | containmentHierarchy.put(linkType, new ContainmentInfo(sourceType, info.multiplicity(), targetType)); | ||
206 | } | ||
207 | |||
200 | private static void validateOpposite(PartialRelation linkType, ReferenceInfo info, PartialRelation opposite, | 208 | private static void validateOpposite(PartialRelation linkType, ReferenceInfo info, PartialRelation opposite, |
201 | ReferenceInfo oppositeInfo) { | 209 | ReferenceInfo oppositeInfo) { |
202 | var sourceType = info.sourceType(); | 210 | var sourceType = info.sourceType(); |