@Override public boolean isSyntacticallyEquivalentTo(QueryNode node) { return Optional.of(node) .filter(n -> n instanceof ConstructionNode) .map(n -> (ConstructionNode) n) .filter(n -> n.getVariables().equals(projectedVariables)) .filter(n -> n.getSubstitution().equals(substitution)) .isPresent(); }
@Override public boolean isSyntacticallyEquivalentTo(QueryNode node) { return Optional.of(node) .filter(n -> n instanceof ConstructionNode) .map(n -> (ConstructionNode) n) .filter(n -> n.getVariables().equals(projectedVariables)) .filter(n -> n.getSubstitution().equals(substitution)) .filter(n -> n.getOptionalModifiers().equals(optionalModifiers)) .isPresent(); }
@Override public boolean isEquivalentTo(QueryNode queryNode) { if (!(queryNode instanceof ConstructionNode)) return false; ConstructionNode node = (ConstructionNode) queryNode; return projectedVariables.equals(node.getVariables()) && substitution.equals(node.getSubstitution()); }
/** * Extract the bindings from the construction node, searching recursively for bindings in its children */ private Stream<Map.Entry<Variable, ImmutableTerm>> extractBindingsFromConstructionNode(IntermediateQuery query, ConstructionNode currentNode) { Stream<Map.Entry<Variable, ImmutableTerm>> localBindings = currentNode.getSubstitution() .getImmutableMap().entrySet().stream(); // Recursive Stream<Map.Entry<Variable, ImmutableTerm>> childBindings = query.getChildren(currentNode).stream() .flatMap(c -> extractBindings(query, c).getMergedBindings()); return Stream.concat(localBindings, childBindings) .filter(e -> currentNode.getVariables().contains(e.getKey())); }
private ConstructionNode mergeCns(ConstructionNode parent, ConstructionNode child) { ImmutableSubstitution composition = child.getSubstitution() .composeWith(parent.getSubstitution()) .reduceDomainToIntersectionWith(parent.getVariables()); return iqFactory.createConstructionNode(parent.getVariables(), composition); }
/** * TODO: explain * */ private static ImmutableSet<Variable> extractVariablesToRemove(ConstructionNode formerConstructionNode, ImmutableSubstitution<ImmutableTerm> bindingsToRemove) throws InconsistentBindingException { ImmutableSet<Variable> allVariablesToRemove = bindingsToRemove.getImmutableMap().keySet(); // Mutable Set<Variable> localVariablesToRemove = new HashSet<>(allVariablesToRemove); localVariablesToRemove.retainAll(formerConstructionNode.getSubstitution().getImmutableMap().keySet()); /** * Checks that no projected but not-bound variable was proposed to be removed. */ ImmutableSet<Variable> projectedVariables = formerConstructionNode.getVariables(); for (Variable variable : allVariablesToRemove) { if ((!localVariablesToRemove.contains(variable)) && projectedVariables.contains(variable)) { throw new InconsistentBindingException("The variable to remove " + variable + " is projected but" + "not bound!"); } } return ImmutableSet.copyOf(localVariablesToRemove); }
public static ConstructionNode merge(ConstructionNode parentConstructionNode, ConstructionNode childConstructionNode, IntermediateQueryFactory iqFactory) { ImmutableSubstitution<ImmutableTerm> composition = childConstructionNode.getSubstitution().composeWith( parentConstructionNode.getSubstitution()); ImmutableSet<Variable> projectedVariables = parentConstructionNode.getVariables(); ImmutableSubstitution<ImmutableTerm> newSubstitution = projectedVariables.containsAll( childConstructionNode.getVariables()) ? composition : SUBSTITUTION_FACTORY.getSubstitution( composition.getImmutableMap().entrySet().stream() .filter(e -> !projectedVariables.contains(e.getKey())) .collect(ImmutableCollectors.toMap())); if (parentConstructionNode.getOptionalModifiers().isPresent() && childConstructionNode.getOptionalModifiers().isPresent()) { // TODO: find a better exception throw new RuntimeException("TODO: support combination of modifiers"); } // TODO: should update the modifiers? Optional<ImmutableQueryModifiers> optionalModifiers = parentConstructionNode.getOptionalModifiers() .map(Optional::of) .orElseGet(childConstructionNode::getOptionalModifiers); return iqFactory.createConstructionNode(projectedVariables, newSubstitution, optionalModifiers); }
@Override public ConstructionNode transform(ConstructionNode constructionNode) { return iqFactory.createConstructionNode(renameProjectedVars(constructionNode.getVariables()), renameSubstitution(constructionNode.getSubstitution())); }
throws InconsistentBindingException { ImmutableSet<Variable> projectedVariables = formerConstructionNode.getVariables();
private NodeCentricOptimizationResults<ConstructionNode> flattenConstructionNodeChain(IntermediateQuery query, QueryTreeComponent treeComponent, ConstructionNode focusNode, QueryNode childSubtreeRoot) { IntermediateQuery snapshot = query.createSnapshot(); ConstructionNode replacingNode = iqFactory.createConstructionNode( focusNode.getVariables(), focusNode.getSubstitution()); treeComponent.replaceSubTree(focusNode, replacingNode); treeComponent.addChild(replacingNode, childSubtreeRoot, Optional.empty(), false); treeComponent.addSubTree(snapshot, childSubtreeRoot, childSubtreeRoot); return new NodeCentricOptimizationResultsImpl<>(query, replacingNode); } }
ImmutableSet<Variable> projectedVariables = constructionNode.getVariables();
private NodeCentricOptimizationResults<ConstructionNode> flattenConstructionNodeChain(IntermediateQuery query, QueryTreeComponent treeComponent, ConstructionNode focusNode, QueryNode childSubtreeRoot, Optional<ImmutableQueryModifiers> modifiers) { IntermediateQuery snapshot = query.createSnapshot(); ConstructionNode replacingNode = iqFactory.createConstructionNode( focusNode.getVariables(), focusNode.getSubstitution(), modifiers ); treeComponent.replaceSubTree(focusNode, replacingNode); treeComponent.addChild(replacingNode, childSubtreeRoot, Optional.empty(), false); treeComponent.addSubTree(snapshot, childSubtreeRoot, childSubtreeRoot); return new NodeCentricOptimizationResultsImpl<>(query, replacingNode); } }
@Override public ConstructionNode transform(ConstructionNode constructionNode) { return iqFactory.createConstructionNode(renameProjectedVars(constructionNode.getVariables()), renameSubstitution(constructionNode.getSubstitution()), renameOptionalModifiers(constructionNode.getOptionalModifiers()) ); }
@Override public IQTree transformConstruction(IQTree tree, ConstructionNode rootCn, IQTree child) { IQTree transformedChild = child.acceptTransformer(this); QueryNode transformedChildRoot = transformedChild.getRootNode(); // if the child is a union, lift it if (transformedChildRoot instanceof UnionNode) { return iqFactory.createNaryIQTree( iqFactory.createUnionNode(rootCn.getVariables()), transformedChild.getChildren().stream() .map(t -> iqFactory.createUnaryIQTree(rootCn, t)) .collect(ImmutableCollectors.toList()) ); } // if the child is a construction node, merge it if (transformedChildRoot instanceof ConstructionNode) { return rootCn.liftBinding( transformedChild, variableGenerator, iqFactory.createIQProperties() ); } return iqFactory.createUnaryIQTree(rootCn, transformedChild); }
DataAtom projectionAtom = Optional.ofNullable( subQueryProjectionAtoms.get(constructionNode)) .orElseGet(() -> generateProjectionAtom(constructionNode.getVariables()));
return iqFactory.createEmptyNode(childConstructionNode.getVariables());
DataAtom projectionAtom = Optional.ofNullable( subQueryProjectionAtoms.get(constructionNode)) .orElseGet(() -> generateProjectionAtom(constructionNode.getVariables()));
/** * TODO: find a better name */ private IQTree updateChild(UnaryIQTree liftedChildTree, ImmutableSubstitution<ImmutableTerm> mergedSubstitution, ImmutableSet<Variable> projectedVariables) { ConstructionNode constructionNode = (ConstructionNode) liftedChildTree.getRootNode(); ConstructionNodeTools.NewSubstitutionPair substitutionPair = constructionTools.traverseConstructionNode( mergedSubstitution, constructionNode.getSubstitution(), constructionNode.getVariables(), projectedVariables); // NB: this is expected to be ok given that the expected compatibility of the merged substitution with // this construction node ImmutableSubstitution<? extends VariableOrGroundTerm> descendingSubstitution = substitutionFactory.getSubstitution( (ImmutableMap<Variable, ? extends VariableOrGroundTerm>)(ImmutableMap<Variable, ?>) substitutionPair.propagatedSubstitution.getImmutableMap()); IQTree newChild = liftedChildTree.getChild() .applyDescendingSubstitution(descendingSubstitution, Optional.empty()); ConstructionNode newConstructionNode = iqFactory.createConstructionNode(projectedVariables, substitutionPair.bindings); return substitutionPair.bindings.isEmpty() ? newChild : iqFactory.createUnaryIQTree(newConstructionNode, newChild); }
UnionNode updatedUnion = iqFactory.createUnionNode(bufferNode.getVariables());
private IQTree enforceRootCn(IQTree tree, ImmutableSet<Variable> projectedVariables) { if (tree.getRootNode() instanceof ConstructionNode) { ConstructionNode currentRootNode = (ConstructionNode) tree.getRootNode(); if (currentRootNode.getVariables().equals(projectedVariables)) return tree; ConstructionNode newRootNode = iqFactory.createConstructionNode(projectedVariables, currentRootNode.getSubstitution() .reduceDomainToIntersectionWith(projectedVariables)); return iqFactory.createUnaryIQTree(newRootNode, ((UnaryIQTree) tree).getChild()); } else return iqFactory.createUnaryIQTree( iqFactory.createConstructionNode(projectedVariables), tree); }