1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
/*
* SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
*
* SPDX-License-Identifier: EPL-2.0
*/
package tools.refinery.store.reasoning.translator.typehierarchy;
import tools.refinery.store.dse.transition.Rule;
import tools.refinery.store.dse.transition.actions.ActionLiteral;
import tools.refinery.store.model.ModelStoreBuilder;
import tools.refinery.store.model.ModelStoreConfiguration;
import tools.refinery.store.query.dnf.Query;
import tools.refinery.store.reasoning.ReasoningBuilder;
import tools.refinery.store.reasoning.actions.PartialActionLiterals;
import tools.refinery.store.reasoning.literal.PartialLiterals;
import tools.refinery.store.reasoning.representation.PartialRelation;
import tools.refinery.store.reasoning.translator.PartialRelationTranslator;
import tools.refinery.store.reasoning.translator.multiobject.MultiObjectTranslator;
import tools.refinery.store.reasoning.translator.proxy.PartialRelationTranslatorProxy;
import tools.refinery.store.representation.Symbol;
import java.util.ArrayList;
import static tools.refinery.store.query.literal.Literals.not;
import static tools.refinery.store.reasoning.literal.PartialLiterals.candidateMust;
import static tools.refinery.store.reasoning.literal.PartialLiterals.may;
public class TypeHierarchyTranslator implements ModelStoreConfiguration {
private final Symbol<InferredType> typeSymbol = Symbol.of("TYPE", 1, InferredType.class, InferredType.UNTYPED);
private final TypeHierarchy typeHierarchy;
public TypeHierarchyTranslator(TypeHierarchy typeHierarchy) {
this.typeHierarchy = typeHierarchy;
}
@Override
public void apply(ModelStoreBuilder storeBuilder) {
if (typeHierarchy.isEmpty()) {
return;
}
storeBuilder.symbol(typeSymbol);
for (var entry : typeHierarchy.getPreservedTypes().entrySet()) {
storeBuilder.with(createPreservedTypeTranslator(entry.getKey(), entry.getValue()));
}
for (var entry : typeHierarchy.getEliminatedTypes().entrySet()) {
storeBuilder.with(createEliminatedTypeTranslator(entry.getKey(), entry.getValue()));
}
var reasoningBuilder = storeBuilder.getAdapter(ReasoningBuilder.class);
reasoningBuilder.initializer(new TypeHierarchyInitializer(typeHierarchy, typeSymbol));
}
private ModelStoreConfiguration createPreservedTypeTranslator(PartialRelation type, TypeAnalysisResult result) {
var may = Query.of(type.name() + "#partial#may", (builder, p1) -> {
if (!result.isAbstractType()) {
builder.clause(new MayTypeView(typeSymbol, type).call(p1));
}
for (var subtype : result.getDirectSubtypes()) {
builder.clause(may(subtype.call(p1)));
}
});
var must = Query.of(type.name() + "#partial#must", (builder, p1) -> builder.clause(
new MustTypeView(typeSymbol, type).call(p1)
));
var candidate = Query.of(type.name() + "#candidate", (builder, p1) -> {
if (!result.isAbstractType()) {
builder.clause(new CandidateTypeView(typeSymbol, type).call(p1));
}
for (var subtype : result.getDirectSubtypes()) {
builder.clause(PartialLiterals.candidateMust(subtype.call(p1)));
}
});
var translator = PartialRelationTranslator.of(type)
.may(may)
.must(must)
.candidate(candidate)
.refiner(InferredTypeRefiner.of(typeSymbol, result));
if (!result.isAbstractType()) {
var decision = Rule.of(type.name(), (builder, instance) -> builder
.clause(
may(type.call(instance)),
not(candidateMust(type.call(instance))),
not(MultiObjectTranslator.MULTI_VIEW.call(instance))
)
.action(() -> {
var actionLiterals = new ArrayList<ActionLiteral>();
actionLiterals.add(PartialActionLiterals.add(type, instance));
for (var subtype : result.getDirectSubtypes()) {
actionLiterals.add(PartialActionLiterals.remove(subtype, instance));
}
return actionLiterals;
}));
translator.decision(decision);
}
return translator;
}
private ModelStoreConfiguration createEliminatedTypeTranslator(
PartialRelation type, PartialRelation replacement) {
return new PartialRelationTranslatorProxy(type, replacement, true);
}
}
|