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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
/*
* SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
*
* SPDX-License-Identifier: EPL-2.0
*/
package tools.refinery.store.reasoning.translator.containment;
import tools.refinery.store.model.Interpretation;
import tools.refinery.store.reasoning.ReasoningAdapter;
import tools.refinery.store.reasoning.refinement.AbstractPartialInterpretationRefiner;
import tools.refinery.store.reasoning.refinement.PartialInterpretationRefiner;
import tools.refinery.store.reasoning.representation.PartialRelation;
import tools.refinery.store.reasoning.representation.PartialSymbol;
import tools.refinery.store.representation.Symbol;
import tools.refinery.store.representation.TruthValue;
import tools.refinery.store.tuple.Tuple;
import java.util.ArrayList;
import java.util.Set;
class ContainmentLinkRefiner extends AbstractPartialInterpretationRefiner<TruthValue, Boolean> {
private final Factory factory;
private final Interpretation<InferredContainment> interpretation;
private final PartialInterpretationRefiner<TruthValue, Boolean> sourceRefiner;
private final PartialInterpretationRefiner<TruthValue, Boolean> targetRefiner;
public ContainmentLinkRefiner(ReasoningAdapter adapter, PartialSymbol<TruthValue, Boolean> partialSymbol,
Factory factory) {
super(adapter, partialSymbol);
this.factory = factory;
interpretation = adapter.getModel().getInterpretation(factory.symbol);
sourceRefiner = adapter.getRefiner(factory.sourceType);
targetRefiner = adapter.getRefiner(factory.targetType);
}
@Override
public boolean merge(Tuple key, TruthValue value) {
var oldValue = interpretation.get(key);
var newValue = mergeLink(oldValue, value);
if (oldValue != newValue) {
interpretation.put(key, newValue);
}
if (value.must()) {
return sourceRefiner.merge(Tuple.of(key.get(0)), TruthValue.TRUE) &&
targetRefiner.merge(Tuple.of(key.get(1)), TruthValue.TRUE);
}
return true;
}
public InferredContainment mergeLink(InferredContainment oldValue, TruthValue toMerge) {
return switch (toMerge) {
case UNKNOWN -> oldValue;
case TRUE -> mustLink(oldValue);
case FALSE -> forbidLink(oldValue);
case ERROR -> errorLink(oldValue);
};
}
public InferredContainment mustLink(InferredContainment oldValue) {
var mustLinks = oldValue.mustLinks();
if (oldValue.contains().may() && mustLinks.isEmpty() && oldValue.forbiddenLinks().isEmpty()) {
return factory.trueLink;
}
if (mustLinks.contains(factory.linkType)) {
return oldValue;
}
return new InferredContainment(oldValue.contains().merge(TruthValue.TRUE),
addToSet(mustLinks, factory.linkType), oldValue.forbiddenLinks());
}
public InferredContainment forbidLink(InferredContainment oldValue) {
var forbiddenLinks = oldValue.forbiddenLinks();
if (oldValue.contains() == TruthValue.UNKNOWN && oldValue.mustLinks().isEmpty() && forbiddenLinks.isEmpty()) {
return factory.falseLinkUnknownContains;
}
if (forbiddenLinks.contains(factory.linkType)) {
return oldValue;
}
return new InferredContainment(oldValue.contains(), oldValue.mustLinks(),
addToSet(forbiddenLinks, factory.linkType));
}
public InferredContainment errorLink(InferredContainment oldValue) {
return new InferredContainment(TruthValue.ERROR, addToSet(oldValue.mustLinks(), factory.linkType),
addToSet(oldValue.forbiddenLinks(), factory.linkType));
}
private static Set<PartialRelation> addToSet(Set<PartialRelation> oldSet, PartialRelation linkType) {
if (oldSet.isEmpty()) {
return Set.of(linkType);
}
var newElements = new ArrayList<PartialRelation>(oldSet.size() + 1);
newElements.addAll(oldSet);
newElements.add(linkType);
return Set.copyOf(newElements);
}
public static PartialInterpretationRefiner.Factory<TruthValue, Boolean> of(
PartialRelation linkType, Symbol<InferredContainment> symbol, PartialRelation sourceType,
PartialRelation targetType) {
return new Factory(linkType, symbol, sourceType, targetType);
}
private static class Factory implements PartialInterpretationRefiner.Factory<TruthValue, Boolean> {
public final PartialRelation linkType;
public final Symbol<InferredContainment> symbol;
public final PartialRelation targetType;
public final PartialRelation sourceType;
public final InferredContainment trueLink;
public final InferredContainment falseLinkUnknownContains;
public Factory(PartialRelation linkType, Symbol<InferredContainment> symbol, PartialRelation sourceType,
PartialRelation targetType) {
this.linkType = linkType;
this.symbol = symbol;
this.sourceType = sourceType;
this.targetType = targetType;
trueLink = new InferredContainment(TruthValue.TRUE, Set.of(linkType), Set.of());
falseLinkUnknownContains = new InferredContainment(TruthValue.FALSE, Set.of(), Set.of(linkType));
}
@Override
public PartialInterpretationRefiner<TruthValue, Boolean> create(
ReasoningAdapter adapter, PartialSymbol<TruthValue, Boolean> partialSymbol) {
return new ContainmentLinkRefiner(adapter, partialSymbol, this);
}
}
}
|