diff options
Diffstat (limited to 'subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/PartialSymbolTranslator.java')
-rw-r--r-- | subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/PartialSymbolTranslator.java | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/PartialSymbolTranslator.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/PartialSymbolTranslator.java new file mode 100644 index 00000000..07d1d19b --- /dev/null +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/PartialSymbolTranslator.java | |||
@@ -0,0 +1,156 @@ | |||
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.translator; | ||
7 | |||
8 | import tools.refinery.store.model.ModelStoreBuilder; | ||
9 | import tools.refinery.store.reasoning.ReasoningBuilder; | ||
10 | import tools.refinery.store.reasoning.interpretation.PartialInterpretation; | ||
11 | import tools.refinery.store.reasoning.refinement.PartialInterpretationRefiner; | ||
12 | import tools.refinery.store.reasoning.refinement.PartialModelInitializer; | ||
13 | import tools.refinery.store.reasoning.refinement.StorageRefiner; | ||
14 | import tools.refinery.store.reasoning.representation.PartialSymbol; | ||
15 | import tools.refinery.store.reasoning.seed.Seed; | ||
16 | import tools.refinery.store.reasoning.seed.SeedInitializer; | ||
17 | import tools.refinery.store.representation.AnySymbol; | ||
18 | import tools.refinery.store.representation.Symbol; | ||
19 | |||
20 | @SuppressWarnings("UnusedReturnValue") | ||
21 | public abstract sealed class PartialSymbolTranslator<A, C> implements AnyPartialSymbolTranslator | ||
22 | permits PartialRelationTranslator { | ||
23 | private final PartialSymbol<A, C> partialSymbol; | ||
24 | private boolean configured = false; | ||
25 | protected PartialInterpretationRefiner.Factory<A, C> interpretationRefiner; | ||
26 | protected AnySymbol storageSymbol; | ||
27 | protected StorageRefiner.Factory<?> storageRefiner; | ||
28 | protected PartialInterpretation.Factory<A, C> interpretationFactory; | ||
29 | protected PartialModelInitializer initializer; | ||
30 | |||
31 | PartialSymbolTranslator(PartialSymbol<A, C> partialSymbol) { | ||
32 | this.partialSymbol = partialSymbol; | ||
33 | } | ||
34 | |||
35 | @Override | ||
36 | public PartialSymbol<A, C> getPartialSymbol() { | ||
37 | return partialSymbol; | ||
38 | } | ||
39 | |||
40 | @Override | ||
41 | public void apply(ModelStoreBuilder storeBuilder) { | ||
42 | storeBuilder.getAdapter(ReasoningBuilder.class).partialSymbol(this); | ||
43 | } | ||
44 | |||
45 | public boolean isConfigured() { | ||
46 | return configured; | ||
47 | } | ||
48 | |||
49 | protected void checkConfigured() { | ||
50 | if (!configured) { | ||
51 | throw new IllegalStateException("Partial symbol was not configured"); | ||
52 | } | ||
53 | } | ||
54 | |||
55 | protected void checkNotConfigured() { | ||
56 | if (configured) { | ||
57 | throw new IllegalStateException("Partial symbol was already configured"); | ||
58 | } | ||
59 | } | ||
60 | |||
61 | public PartialSymbolTranslator<A, C> symbol(AnySymbol storageSymbol) { | ||
62 | return symbol((Symbol<?>) storageSymbol, null); | ||
63 | } | ||
64 | |||
65 | public <T> PartialSymbolTranslator<A, C> symbol(Symbol<T> storageSymbol, | ||
66 | StorageRefiner.Factory<T> storageRefiner) { | ||
67 | checkNotConfigured(); | ||
68 | if (this.storageSymbol != null) { | ||
69 | throw new IllegalStateException("Representation symbol was already set"); | ||
70 | } | ||
71 | this.storageSymbol = storageSymbol; | ||
72 | this.storageRefiner = storageRefiner; | ||
73 | return this; | ||
74 | } | ||
75 | |||
76 | public PartialSymbolTranslator<A, C> interpretation(PartialInterpretation.Factory<A, C> interpretationFactory) { | ||
77 | checkNotConfigured(); | ||
78 | if (this.interpretationFactory != null) { | ||
79 | throw new IllegalStateException("Interpretation factory was already set"); | ||
80 | } | ||
81 | this.interpretationFactory = interpretationFactory; | ||
82 | return this; | ||
83 | } | ||
84 | |||
85 | public PartialSymbolTranslator<A, C> refiner(PartialInterpretationRefiner.Factory<A, C> interpretationRefiner) { | ||
86 | checkNotConfigured(); | ||
87 | if (this.interpretationRefiner != null) { | ||
88 | throw new IllegalStateException("Interpretation refiner was already set"); | ||
89 | } | ||
90 | this.interpretationRefiner = interpretationRefiner; | ||
91 | return this; | ||
92 | } | ||
93 | |||
94 | public PartialSymbolTranslator<A, C> initializer(PartialModelInitializer initializer) { | ||
95 | checkNotConfigured(); | ||
96 | if (this.initializer != null) { | ||
97 | throw new IllegalStateException("Initializer was already set"); | ||
98 | } | ||
99 | this.initializer = initializer; | ||
100 | return this; | ||
101 | } | ||
102 | |||
103 | public <T> PartialSymbolTranslator<A, C> seed(Seed<T> seed) { | ||
104 | if (storageSymbol == null) { | ||
105 | throw new IllegalArgumentException("Seed requires setting a storage symbol"); | ||
106 | } | ||
107 | if (!seed.valueType().equals(storageSymbol.valueType())) { | ||
108 | throw new IllegalArgumentException("Seed type %s does not match storage symbol type %s" | ||
109 | .formatted(seed.valueType(), storageSymbol.valueType())); | ||
110 | } | ||
111 | // The guard clause only allows a well-typed seed. | ||
112 | @SuppressWarnings("unchecked") | ||
113 | var typedStorageSymbol = (Symbol<T>) storageSymbol; | ||
114 | return initializer(new SeedInitializer<>(typedStorageSymbol, seed)); | ||
115 | } | ||
116 | |||
117 | @Override | ||
118 | public void configure(ModelStoreBuilder storeBuilder) { | ||
119 | checkNotConfigured(); | ||
120 | doConfigure(storeBuilder); | ||
121 | configured = true; | ||
122 | } | ||
123 | |||
124 | protected void doConfigure(ModelStoreBuilder storeBuilder) { | ||
125 | if (interpretationFactory == null) { | ||
126 | throw new IllegalArgumentException("Interpretation factory must be set"); | ||
127 | } | ||
128 | var reasoningBuilder = storeBuilder.getAdapter(ReasoningBuilder.class); | ||
129 | if (storageSymbol != null) { | ||
130 | storeBuilder.symbol(storageSymbol); | ||
131 | if (storageRefiner != null) { | ||
132 | registerStorageRefiner(reasoningBuilder, storageRefiner); | ||
133 | } | ||
134 | } | ||
135 | if (initializer != null) { | ||
136 | reasoningBuilder.initializer(initializer); | ||
137 | } | ||
138 | } | ||
139 | |||
140 | private <T> void registerStorageRefiner(ReasoningBuilder reasoningBuilder, StorageRefiner.Factory<T> factory) { | ||
141 | // The builder only allows setting a well-typed representation refiner. | ||
142 | @SuppressWarnings("unchecked") | ||
143 | var typedStorageSymbol = (Symbol<T>) storageSymbol; | ||
144 | reasoningBuilder.storageRefiner(typedStorageSymbol, factory); | ||
145 | } | ||
146 | |||
147 | public PartialInterpretation.Factory<A, C> getInterpretationFactory() { | ||
148 | checkConfigured(); | ||
149 | return interpretationFactory; | ||
150 | } | ||
151 | |||
152 | public PartialInterpretationRefiner.Factory<A, C> getInterpretationRefiner() { | ||
153 | checkConfigured(); | ||
154 | return interpretationRefiner; | ||
155 | } | ||
156 | } | ||