private IQTree liftInnerJoin(NaryIQTree queryTree, ImmutableList<IQTree> newChildren, VariableGenerator variableGenerator) { InnerJoinNode joinNode = (InnerJoinNode) queryTree.getRootNode(); NaryIQTree newQueryTree = newChildren.equals(queryTree.getChildren()) ? queryTree : iqFactory.createNaryIQTree(joinNode, newChildren); return extractCandidateVariables(queryTree, joinNode.getOptionalFilterCondition(), newChildren) .map(newQueryTree::liftIncompatibleDefinitions) .filter(t -> !t.equals(queryTree)) .findFirst() .orElse(newQueryTree) .liftBinding(variableGenerator); }
@Override public IQ liftBinding() { IQTree newTree = tree.liftBinding(getVariableGenerator()); return newTree == tree ? this : iqFactory.createIQ(projectionAtom, newTree); }
@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); } }
@Override public Stream<IQ> splitUnion(IQ query) { DistinctVariableOnlyDataAtom projectionAtom = query.getProjectionAtom(); VariableGenerator variableGenerator = query.getVariableGenerator(); IQTree tree = query.getTree(); return findFirstSplittableUnion(query) .map(unionTree -> unionTree.getChildren().stream() .map(c -> tree.replaceSubTree(unionTree, c)) .map(t -> t.liftBinding(variableGenerator)) .map(t -> iqFactory.createIQ(projectionAtom, t)) .map(IQ::liftBinding)) .orElseGet(() -> Stream.of(query)); }
private IQTree liftLJJoin(BinaryNonCommutativeIQTree queryTree, IQTree newLeftChild, IQTree newRightChild, VariableGenerator variableGenerator) { LeftJoinNode leftJoinNode = (LeftJoinNode) queryTree.getRootNode(); BinaryNonCommutativeIQTree newQueryTree = newLeftChild.equals(queryTree.getLeftChild()) && newRightChild.equals(queryTree.getRightChild()) ? queryTree : iqFactory.createBinaryNonCommutativeIQTree(leftJoinNode, newLeftChild, newRightChild); return extractCandidateVariables(queryTree, leftJoinNode.getOptionalFilterCondition(), ImmutableList.of(newLeftChild, newRightChild)) .filter(v -> newLeftChild.getVariables().contains(v)) .map(newQueryTree::liftIncompatibleDefinitions) .filter(t -> !t.equals(queryTree)) .findFirst() .orElse(newQueryTree) .liftBinding(variableGenerator); }
/** * */ private IQ liftUnionsInTree(IQ query) { VariableGenerator variableGenerator = query.getVariableGenerator(); // Non-final IQTree previousTree; IQTree newTree = query.getTree(); int i=0; do { previousTree = newTree; newTree = liftTree(previousTree, variableGenerator) .liftBinding(variableGenerator); } while (!newTree.equals(previousTree) && (++i < ITERATION_BOUND)); if (i >= ITERATION_BOUND) throw new MinorOntopInternalBugException(getClass().getName() + " did not converge after " + ITERATION_BOUND + " iterations"); return newTree.equals(query.getTree()) ? query : iqFactory.createIQ(query.getProjectionAtom(), newTree); }
@Override public IQTree liftBinding(IQTree child, VariableGenerator variableGenerator, IQProperties currentIQProperties) { IQTree newChild = child.liftBinding(variableGenerator); QueryNode newChildRoot = newChild.getRootNode(); if (newChildRoot instanceof ConstructionNode) return liftBindingConstructionChild(newChild, (ConstructionNode) newChildRoot, currentIQProperties); else if (newChildRoot instanceof DistinctNode) return newChild; else if (newChildRoot instanceof EmptyNode) return newChild; else return iqFactory.createUnaryIQTree(this, newChild, currentIQProperties.declareLifted()); }
VariableGenerator variableGenerator) throws EmptyIQException { ImmutableList<IQTree> liftedChildren = initialChildren.stream() .map(c -> c.liftBinding(variableGenerator)) .filter(c -> !(c.getRootNode() instanceof TrueNode)) .collect(ImmutableCollectors.toList());
@Override public IQTree liftBinding(IQTree childIQTree, VariableGenerator variableGenerator, IQProperties currentIQProperties) { IQTree newParentTree = propagateDownCondition(childIQTree, Optional.empty()); /* * If after propagating down the condition the root is still a filter node, goes to the next step */ if (newParentTree.getRootNode() instanceof FilterNodeImpl) { return ((FilterNodeImpl)newParentTree.getRootNode()) .liftBindingAfterPropagatingCondition(((UnaryIQTree)newParentTree).getChild(), variableGenerator, currentIQProperties); } else /* * Otherwise, goes back to the general method */ return newParentTree.liftBinding(variableGenerator); }
/** * Blocks substitutions */ @Override public IQTree liftBinding(IQTree child, VariableGenerator variableGenerator, IQProperties currentIQProperties) { IQTree newChild = child.liftBinding(variableGenerator); QueryNode newChildRoot = newChild.getRootNode(); if (newChildRoot instanceof SliceNode) return liftSliceChild((SliceNode) newChildRoot, newChild, currentIQProperties); else if (newChildRoot instanceof EmptyNode) return newChild; else return iqFactory.createUnaryIQTree(this, newChild, currentIQProperties.declareLifted()); }
private ChildLiftingState liftRightChild(ChildLiftingState state, VariableGenerator variableGenerator) { IQTree liftedRightChild = state.rightChild.liftBinding(variableGenerator); if (!(liftedRightChild.getRootNode() instanceof ConstructionNode)) { if (state.rightChild.equals(liftedRightChild)) return state; return new ChildLiftingState(state.leftChild, liftedRightChild, state.ljCondition.filter(c -> !liftedRightChild.isDeclaredAsEmpty()), state.ascendingSubstitution); } ConstructionNode rightConstructionNode = (ConstructionNode) liftedRightChild.getRootNode(); IQTree rightGrandChild = ((UnaryIQTree) liftedRightChild).getChild(); ImmutableSubstitution<ImmutableTerm> rightSubstitution = rightConstructionNode.getSubstitution(); return liftRightChild(state, rightGrandChild, rightSubstitution, variableGenerator); }
/** * TODO: explain */ @Override public IQTree liftBinding(ImmutableList<IQTree> initialChildren, VariableGenerator variableGenerator, IQProperties currentIQProperties) { IQTree newParentTree = propagateDownCondition(Optional.empty(), initialChildren); /* * If after propagating down the condition the root is still a join node, goes to the next step */ if (newParentTree.getRootNode() instanceof InnerJoinNodeImpl) { return ((InnerJoinNodeImpl)newParentTree.getRootNode()).liftBindingAfterPropagatingCondition( newParentTree.getChildren(), variableGenerator, currentIQProperties); } else /* * Otherwise, goes back to the general method */ return newParentTree.liftBinding(variableGenerator); }
private IQTree liftBindingAfterPropagatingCondition(IQTree childIQTree, VariableGenerator variableGenerator, IQProperties currentIQProperties) { IQTree liftedChildIQTree = childIQTree.liftBinding(variableGenerator); QueryNode childRoot = liftedChildIQTree.getRootNode(); if (childRoot instanceof ConstructionNode) return liftBinding((ConstructionNode) childRoot, (UnaryIQTree) liftedChildIQTree, currentIQProperties, variableGenerator); else if (liftedChildIQTree.isDeclaredAsEmpty()) { return liftedChildIQTree; } else return iqFactory.createUnaryIQTree(this, liftedChildIQTree, currentIQProperties.declareLifted()); }
@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); }
@Override public IQTree liftBinding(IQTree child, VariableGenerator variableGenerator, IQProperties currentIQProperties) { IQTree newChild = child.liftBinding(variableGenerator); QueryNode newChildRoot = newChild.getRootNode(); IQProperties liftedProperties = currentIQProperties.declareLifted(); if (newChildRoot instanceof ConstructionNode) return liftChildConstructionNode((ConstructionNode) newChildRoot, (UnaryIQTree) newChild, liftedProperties); else if (newChildRoot instanceof EmptyNode) return newChild; else if (newChildRoot instanceof DistinctNode) { return iqFactory.createUnaryIQTree( (DistinctNode) newChildRoot, iqFactory.createUnaryIQTree(this, ((UnaryIQTree)newChild).getChild(), liftedProperties), liftedProperties); } else return iqFactory.createUnaryIQTree(this, newChild, liftedProperties); }
/** * Does NOT look for intensional data nodes inside the definitions * */ private IQTree replaceIntensionalData(IntensionalDataNode dataNode, IQ definition) { InjectiveVar2VarSubstitution renamingSubstitution = substitutionFactory.generateNotConflictingRenaming( variableGenerator, definition.getTree().getKnownVariables()); IQ renamedIQ; if(renamingSubstitution.isEmpty()){ renamedIQ = definition; } else { QueryRenamer queryRenamer = transformerFactory.createRenamer(renamingSubstitution); renamedIQ = queryRenamer.transform(definition); } ImmutableSubstitution<VariableOrGroundTerm> descendingSubstitution = extractSubstitution( renamingSubstitution.applyToDistinctVariableOnlyDataAtom(renamedIQ.getProjectionAtom()), dataNode.getProjectionAtom()); return renamedIQ.getTree() .applyDescendingSubstitution(descendingSubstitution, Optional.empty()) .liftBinding(variableGenerator); }