/* * SPDX-FileCopyrightText: 2023-2024 The Refinery Authors * * 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.PartialSymbol; import tools.refinery.store.representation.Symbol; import tools.refinery.logic.term.truthvalue.TruthValue; import tools.refinery.store.tuple.Tuple; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; class ContainsRefiner extends AbstractPartialInterpretationRefiner { private static final Map EMPTY_VALUES; static { var values = TruthValue.values(); EMPTY_VALUES = LinkedHashMap.newLinkedHashMap(values.length); for (var value : values) { EMPTY_VALUES.put(value, new InferredContainment(value, Set.of(), Set.of())); } } private final Interpretation interpretation; private final PartialInterpretationRefiner containedRefiner; private ContainsRefiner(ReasoningAdapter adapter, PartialSymbol partialSymbol, Symbol containsStorage) { super(adapter, partialSymbol); interpretation = adapter.getModel().getInterpretation(containsStorage); containedRefiner = adapter.getRefiner(ContainmentHierarchyTranslator.CONTAINED_SYMBOL); } @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 containedRefiner.merge(Tuple.of(key.get(1)), TruthValue.TRUE); } return true; } public InferredContainment mergeLink(InferredContainment oldValue, TruthValue toMerge) { var newContains = oldValue.contains().meet(toMerge); if (newContains.equals(oldValue.contains())) { return oldValue; } var mustLinks = oldValue.mustLinks(); var forbiddenLinks = oldValue.forbiddenLinks(); if (mustLinks.isEmpty() && forbiddenLinks.isEmpty()) { return EMPTY_VALUES.get(newContains); } return new InferredContainment(newContains, mustLinks, forbiddenLinks); } public static PartialInterpretationRefiner.Factory of(Symbol symbol) { return (adapter, partialSymbol) -> new ContainsRefiner(adapter, partialSymbol, symbol); } }