
it.unibz.inf.ontop.iq.impl.IQTreeTools Maven / Gradle / Ivy
package it.unibz.inf.ontop.iq.impl;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import it.unibz.inf.ontop.exception.MinorOntopInternalBugException;
import it.unibz.inf.ontop.injection.IntermediateQueryFactory;
import it.unibz.inf.ontop.iq.IQTree;
import it.unibz.inf.ontop.iq.node.InnerJoinNode;
import it.unibz.inf.ontop.iq.node.QueryNode;
import it.unibz.inf.ontop.iq.node.UnaryOperatorNode;
import it.unibz.inf.ontop.model.term.*;
import it.unibz.inf.ontop.substitution.Substitution;
import it.unibz.inf.ontop.substitution.InjectiveSubstitution;
import it.unibz.inf.ontop.substitution.SubstitutionFactory;
import it.unibz.inf.ontop.utils.ImmutableCollectors;
import java.util.Optional;
import java.util.function.Supplier;
@Singleton
public class IQTreeTools {
private final IntermediateQueryFactory iqFactory;
@Inject
private IQTreeTools(IntermediateQueryFactory iqFactory) {
this.iqFactory = iqFactory;
}
/**
* Excludes the variables that are not projected by the IQTree
*
* If a "null" variable is propagated down, throws an UnsatisfiableDescendingSubstitutionException.
*
*/
public Optional> normalizeDescendingSubstitution(
IQTree tree, Substitution extends VariableOrGroundTerm> descendingSubstitution)
throws UnsatisfiableDescendingSubstitutionException {
Substitution extends VariableOrGroundTerm> reducedSubstitution = descendingSubstitution.restrictDomainTo(tree.getVariables());
if (reducedSubstitution.isEmpty())
return Optional.empty();
if (reducedSubstitution.rangeAnyMatch(ImmutableTerm::isNull)) {
throw new UnsatisfiableDescendingSubstitutionException();
}
return Optional.of(reducedSubstitution);
}
public ImmutableSet computeNewProjectedVariables(
Substitution extends ImmutableTerm> descendingSubstitution,
ImmutableSet projectedVariables) {
ImmutableSet newVariables = descendingSubstitution.restrictDomainTo(projectedVariables).getRangeVariables();
return Sets.union(newVariables, Sets.difference(projectedVariables, descendingSubstitution.getDomain())).immutableCopy();
}
public IQTree createConstructionNodeTreeIfNontrivial(IQTree child, Substitution> substitution, Supplier> projectedVariables) {
return substitution.isEmpty()
? child
: iqFactory.createUnaryIQTree(iqFactory.createConstructionNode(projectedVariables.get(), substitution), child);
}
public IQTree createConstructionNodeTreeIfNontrivial(IQTree child, ImmutableSet variables) {
return child.getVariables().equals(variables)
? child
: iqFactory.createUnaryIQTree(iqFactory.createConstructionNode(variables), child);
}
public ImmutableSet getChildrenVariables(ImmutableList children) {
return children.stream()
.flatMap(c -> c.getVariables().stream())
.collect(ImmutableCollectors.toSet());
}
public ImmutableSet getChildrenVariables(IQTree leftChild, IQTree rightChild) {
return Sets.union(leftChild.getVariables(), rightChild.getVariables()).immutableCopy();
}
public ImmutableSet getChildrenVariables(IQTree child, Variable newVariable) {
return Sets.union(child.getVariables(), ImmutableSet.of(newVariable)).immutableCopy();
}
public ImmutableSet extractChildVariables(ImmutableSet groupingVariables,
Substitution substitution) {
return Sets.union(groupingVariables, substitution.getRangeVariables()).immutableCopy();
}
public IQTree createOptionalUnaryIQTree(Optional extends UnaryOperatorNode> optionalNode, IQTree tree) {
return optionalNode
.map(n -> iqFactory.createUnaryIQTree(n, tree))
.orElse(tree);
}
public IQTree createAncestorsUnaryIQTree(ImmutableList extends UnaryOperatorNode> ancestors, IQTree tree) {
return ancestors.stream()
.reduce(tree,
(t, a) -> iqFactory.createUnaryIQTree(a, t),
(t1, t2) -> { throw new MinorOntopInternalBugException("No merge was expected"); });
}
public ImmutableList createUnaryOperatorChildren(UnaryOperatorNode node, IQTree child) {
return child.getChildren().stream()
.map(c -> iqFactory.createUnaryIQTree(node, c))
.collect(ImmutableCollectors.toList());
}
public InnerJoinNode createInnerJoinNode(Optional optionalExpression) {
return optionalExpression.map(iqFactory::createInnerJoinNode).orElseGet(iqFactory::createInnerJoinNode);
}
/**
* If the substitution is a fresh renaming, returns it as an injective substitution
*/
public Optional> extractFreshRenaming(Substitution extends ImmutableTerm> descendingSubstitution,
ImmutableSet projectedVariables) {
Substitution var2VarFragment = descendingSubstitution.restrictRangeTo(Variable.class);
int size = descendingSubstitution.getDomain().size();
if (var2VarFragment.getDomain().size() != size
|| Sets.difference(var2VarFragment.getRangeSet(), projectedVariables).size() != size)
return Optional.empty();
return Optional.of(var2VarFragment.injective());
}
/**
* Typically thrown when a "null" variable is propagated down
*
*/
public static class UnsatisfiableDescendingSubstitutionException extends Exception {
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy