@Override public EmptyNode clone() { return iqFactory.createEmptyNode(projectedVariables); }
@Override protected IQTree handleIntensionalWithoutDefinition(IntensionalDataNode dataNode) { return iqFactory.createEmptyNode(dataNode.getVariables()); } }
@Override public IQTree applyDescendingSubstitutionWithoutOptimizing( ImmutableSubstitution<? extends VariableOrGroundTerm> descendingSubstitution) { return iqFactory.createEmptyNode( constructionNodeTools.computeNewProjectedVariables(descendingSubstitution, projectedVariables)); }
@Override public IQTree propagateDownConstraint(ImmutableExpression constraint, IQTree child) { try { Optional<ImmutableExpression> childConstraint = computeChildConstraint(substitution, Optional.of(constraint)); IQTree newChild = childConstraint .map(child::propagateDownConstraint) .orElse(child); return iqFactory.createUnaryIQTree(this, newChild); } catch (EmptyTreeException e) { return iqFactory.createEmptyNode(projectedVariables); } }
private void removeUnsatisfiedNode(QueryTreeComponent treeComponent, IntensionalDataNode intensionalNode) { EmptyNode emptyNode = iqFactory.createEmptyNode(intensionalNode.getVariables()); treeComponent.replaceSubTree(intensionalNode, emptyNode); }
/** * NB: the constraint is irrelevant here */ @Override public final IQTree applyDescendingSubstitution( ImmutableSubstitution<? extends VariableOrGroundTerm> descendingSubstitution, Optional<ImmutableExpression> constraint) { try { return iqTreeTools.normalizeDescendingSubstitution(this, descendingSubstitution) .map(this::applyDescendingSubstitutionWithoutOptimizing) .orElse(this); } catch (IQTreeTools.UnsatisfiableDescendingSubstitutionException e) { return iqFactory.createEmptyNode(iqTreeTools.computeNewProjectedVariables(descendingSubstitution, getVariables())); } }
@Override public IQTree liftBinding(ImmutableList<IQTree> children, VariableGenerator variableGenerator, IQProperties currentIQProperties) { ImmutableList<IQTree> liftedChildren = children.stream() .map(c -> c.liftBinding(variableGenerator)) .filter(c -> !c.isDeclaredAsEmpty()) .map(c -> projectAwayUnnecessaryVariables(c, currentIQProperties)) .collect(ImmutableCollectors.toList()); switch (liftedChildren.size()) { case 0: return iqFactory.createEmptyNode(projectedVariables); case 1: return liftedChildren.get(0); default: return liftBindingFromLiftedChildren(liftedChildren, variableGenerator, currentIQProperties); } }
private NodeCentricOptimizationResults<InnerJoinNode> declareSubTreeAsEmpty(IntermediateQuery query, QueryTreeComponent treeComponent, InnerJoinNode topJoinNode) { /* * Replaces by an EmptyNode */ EmptyNode emptyNode = iqFactory.createEmptyNode(query.getVariables(topJoinNode)); treeComponent.replaceSubTree(topJoinNode, emptyNode); /* * If the query is not empty, changes the type of the results */ return new NodeCentricOptimizationResultsImpl<>(query, Optional.of(emptyNode)); }
@Override public IQTree applyDescendingSubstitution( ImmutableSubstitution<? extends VariableOrGroundTerm> descendingSubstitution, Optional<ImmutableExpression> constraint) { try { return normalizeDescendingSubstitution(descendingSubstitution) .map(s -> getRootNode().applyDescendingSubstitution(s, constraint, leftChild, rightChild)) .orElseGet(() -> constraint .map(this::propagateDownConstraint) .orElse(this)); } catch (IQTreeTools.UnsatisfiableDescendingSubstitutionException e) { return iqFactory.createEmptyNode(iqTreeTools.computeNewProjectedVariables(descendingSubstitution, getVariables())); } }
@Override public IQTree applyDescendingSubstitution( ImmutableSubstitution<? extends VariableOrGroundTerm> descendingSubstitution, Optional<ImmutableExpression> constraint) { try { return normalizeDescendingSubstitution(descendingSubstitution) .map(s -> getRootNode().applyDescendingSubstitution(s, constraint, getChildren())) .orElseGet(() -> constraint .map(this::propagateDownConstraint) .orElse(this)); } catch (IQTreeTools.UnsatisfiableDescendingSubstitutionException e) { return iqFactory.createEmptyNode(iqTreeTools.computeNewProjectedVariables(descendingSubstitution, getVariables())); } }
@Override public IQTree applyDescendingSubstitutionWithoutOptimizing(ImmutableSubstitution<? extends VariableOrGroundTerm> descendingSubstitution) { try { return normalizeDescendingSubstitution(descendingSubstitution) .map(s -> getRootNode().applyDescendingSubstitutionWithoutOptimizing(s, leftChild, rightChild)) .orElse(this); } catch (IQTreeTools.UnsatisfiableDescendingSubstitutionException e) { return iqFactory.createEmptyNode(iqTreeTools.computeNewProjectedVariables(descendingSubstitution, getVariables())); } }
@Override public IQTree applyDescendingSubstitution( ImmutableSubstitution<? extends VariableOrGroundTerm> descendingSubstitution, Optional<ImmutableExpression> constraint) { try { return normalizeDescendingSubstitution(descendingSubstitution) .map(s -> getRootNode().applyDescendingSubstitution(s, constraint, getChild())) .orElseGet(() -> constraint .map(this::propagateDownConstraint) .orElse(this)); } catch (IQTreeTools.UnsatisfiableDescendingSubstitutionException e) { return iqFactory.createEmptyNode(iqTreeTools.computeNewProjectedVariables(descendingSubstitution, getVariables())); } }
@Override public IQTree applyDescendingSubstitution(ImmutableSubstitution<? extends VariableOrGroundTerm> descendingSubstitution, Optional<ImmutableExpression> constraint, ImmutableList<IQTree> children) { ImmutableSet<Variable> updatedProjectedVariables = constructionTools.computeNewProjectedVariables( descendingSubstitution, projectedVariables); ImmutableList<IQTree> updatedChildren = children.stream() .map(c -> c.applyDescendingSubstitution(descendingSubstitution, constraint)) .filter(c -> !c.isDeclaredAsEmpty()) .collect(ImmutableCollectors.toList()); switch (updatedChildren.size()) { case 0: return iqFactory.createEmptyNode(updatedProjectedVariables); case 1: return updatedChildren.get(0); default: UnionNode newRootNode = iqFactory.createUnionNode(updatedProjectedVariables); return iqFactory.createNaryIQTree(newRootNode, updatedChildren); } }
private static EmptyNode replaceByEmptyNode(QueryNode rejectedNode, ImmutableSubstitution descendingSubstitution, IntermediateQuery query, Optional<NodeTracker> optionalTracker) { optionalTracker.ifPresent(tr -> tr.recordUpcomingRemoval(query, rejectedNode)); /** * The new set of projected variables have to take into account * the changes proposed by the descending substitution. */ ImmutableSet<Variable> newProjectedVariables = query.getVariables(rejectedNode).stream() .flatMap(v -> descendingSubstitution.apply(v).getVariableStream()) .collect(ImmutableCollectors.toSet()); return query.getFactory().createEmptyNode(newProjectedVariables); }
@Override public IQTree applyDescendingSubstitutionWithoutOptimizing(ImmutableSubstitution<? extends VariableOrGroundTerm> descendingSubstitution) { try { return normalizeDescendingSubstitution(descendingSubstitution) .map(s -> getRootNode().applyDescendingSubstitutionWithoutOptimizing(s, getChildren())) .orElse(this); } catch (IQTreeTools.UnsatisfiableDescendingSubstitutionException e) { return iqFactory.createEmptyNode(iqTreeTools.computeNewProjectedVariables(descendingSubstitution, getVariables())); } }
@Override public IQTree applyDescendingSubstitutionWithoutOptimizing(ImmutableSubstitution<? extends VariableOrGroundTerm> descendingSubstitution) { try { return normalizeDescendingSubstitution(descendingSubstitution) .map(s -> getRootNode().applyDescendingSubstitutionWithoutOptimizing(s, getChild())) .orElse(this); } catch (IQTreeTools.UnsatisfiableDescendingSubstitutionException e) { return iqFactory.createEmptyNode(iqTreeTools.computeNewProjectedVariables(descendingSubstitution, getVariables())); } }
/** * Returns results centered on the removed node. */ private static NodeTrackingResults<EmptyNode> reactToEmptinessDeclaration( IntermediateQuery query, QueryNode currentAncestor, QueryTreeComponent treeComponent, Optional<NodeTracker> optionalAncestryTracker) throws EmptyQueryException { ImmutableSet<Variable> nullVariables = query.getVariables(currentAncestor); EmptyNode replacingEmptyNode = query.getFactory().createEmptyNode(nullVariables); treeComponent.replaceSubTree(currentAncestor, replacingEmptyNode); RemoveEmptyNodeProposal proposal = optionalAncestryTracker.isPresent() ? new RemoveEmptyNodeProposalImpl(replacingEmptyNode, optionalAncestryTracker.get()) : new RemoveEmptyNodeProposalImpl(replacingEmptyNode, false); return query.applyProposal(proposal, true); } }
@Override public IQTree liftBinding(IQTree childIQTree, VariableGenerator variableGenerator, IQProperties currentIQProperties) { IQTree liftedChildIQTree = childIQTree.liftBinding(variableGenerator); QueryNode liftedChildRoot = liftedChildIQTree.getRootNode(); if (liftedChildRoot instanceof ConstructionNode) return liftBinding((ConstructionNode) liftedChildRoot, (UnaryIQTree) liftedChildIQTree, currentIQProperties); else if (liftedChildIQTree.isDeclaredAsEmpty()) { return iqFactory.createEmptyNode(projectedVariables); } else return iqFactory.createUnaryIQTree(this, liftedChildIQTree, currentIQProperties.declareLifted()); }
@Override public IQTree liftBinding(IQTree initialLeftChild, IQTree initialRightChild, VariableGenerator variableGenerator, IQProperties currentIQProperties) { ImmutableSet<Variable> projectedVariables = Stream.of(initialLeftChild, initialRightChild) .flatMap(c -> c.getVariables().stream()) .collect(ImmutableCollectors.toSet()); IQTree liftedLeftChild = initialLeftChild.liftBinding(variableGenerator); if (liftedLeftChild.isDeclaredAsEmpty()) return iqFactory.createEmptyNode(projectedVariables); // Non-final ChildLiftingState liftingState = liftLeftChild(liftedLeftChild, initialRightChild, getOptionalFilterCondition(), variableGenerator); boolean hasConverged = false; int i = 0; while ((!hasConverged) && (i++ < MAX_ITERATIONS)) { ChildLiftingState newLiftingState = liftRightChild( optimizeLeftJoinCondition(liftingState, variableGenerator), variableGenerator); hasConverged = liftingState.equals(newLiftingState); liftingState = newLiftingState; } if (i >= MAX_ITERATIONS) throw new MinorOntopInternalBugException("LJ.liftBinding() did not converge after " + i); return convertResults2IQTree(projectedVariables, liftingState, currentIQProperties); }
private NodeCentricOptimizationResults<InnerJoinNode> removeSubTree(IntermediateQuery query, QueryTreeComponent treeComponent, InnerJoinNode topJoinNode) throws EmptyQueryException { /* * Replaces by an EmptyNode */ EmptyNode emptyNode = iqFactory.createEmptyNode(query.getVariables(topJoinNode)); treeComponent.replaceSubTree(topJoinNode, emptyNode); /* * Removes the empty node * (may throw an EmptyQuery) */ RemoveEmptyNodeProposal removalProposal = new RemoveEmptyNodeProposalImpl(emptyNode, false); NodeTrackingResults<EmptyNode> removalResults = query.applyProposal(removalProposal); /* * If the query is not empty, changes the type of the results */ return new NodeCentricOptimizationResultsImpl<>(query, removalResults.getOptionalNextSibling(), removalResults.getOptionalClosestAncestor()); }