@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(); }
private Optional<ConstructionNode> getIdleCn(IQTree tree) { QueryNode root = tree.getRootNode(); if (root instanceof ConstructionNode) { ConstructionNode cn = ((ConstructionNode) root); if (cn.getSubstitution().isEmpty()) { return Optional.of(cn); } } return Optional.empty(); }
@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()); }
/** * TODO: explain */ private static ImmutableSubstitution<ImmutableTerm> computeNewBindingSubstitution( ConstructionNode formerConstructionNode, ImmutableSet<Variable> variablesToRemove, ImmutableSubstitution<VariableOrGroundTerm> newBindings) { ImmutableMap.Builder<Variable, ImmutableTerm> mapBuilder = ImmutableMap.builder(); ImmutableMap<Variable, ImmutableTerm> formerSubstitutionMap = formerConstructionNode.getSubstitution().getImmutableMap(); for (Variable variable : formerSubstitutionMap.keySet()) { if (!variablesToRemove.contains(variable)) { mapBuilder.put(variable, formerSubstitutionMap.get(variable)); } } mapBuilder.putAll(newBindings.getImmutableMap()); return SUBSTITUTION_FACTORY.getSubstitution(mapBuilder.build()); }
private Optional<ExplicitVariableProjectionNode> getProjectorReplacementNode(ExplicitVariableProjectionNode replacedNode, ImmutableExpression expressionToPropagate) { if (expressionToPropagate.getVariables().size() == 0) { return Optional.empty(); } ImmutableSet.Builder<Variable> allProjectedVariablesBuilder = ImmutableSet.builder(); allProjectedVariablesBuilder.addAll(replacedNode.getVariables()); allProjectedVariablesBuilder.addAll(expressionToPropagate.getVariables()); if (replacedNode instanceof UnionNode) { return Optional.of(iqFactory.createUnionNode(allProjectedVariablesBuilder.build())); } if (replacedNode instanceof ConstructionNode) { return Optional.of(iqFactory.createConstructionNode(allProjectedVariablesBuilder.build(), ((ConstructionNode) replacedNode).getSubstitution())); } throw new IllegalStateException("Unsupported node type"); }
@Override public boolean hasAChildWithLiftableDefinition(Variable variable, ImmutableList<IQTree> children) { return children.stream() .anyMatch(c -> (c.getRootNode() instanceof ConstructionNode) && ((ConstructionNode) c.getRootNode()).getSubstitution().isDefining(variable)); }
/** * 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 Optional<ExplicitVariableProjectionNode> getProjectorReplacementNode(ExplicitVariableProjectionNode replacedNode, ImmutableExpression expressionToPropagate) { if (expressionToPropagate.getVariables().size() == 0) { return Optional.empty(); } ImmutableSet.Builder<Variable> allProjectedVariablesBuilder = ImmutableSet.builder(); allProjectedVariablesBuilder.addAll(replacedNode.getVariables()); allProjectedVariablesBuilder.addAll(expressionToPropagate.getVariables()); if (replacedNode instanceof UnionNode) { return Optional.of(iqFactory.createUnionNode(allProjectedVariablesBuilder.build())); } if (replacedNode instanceof ConstructionNode) { return Optional.of(iqFactory.createConstructionNode(allProjectedVariablesBuilder.build(), ((ConstructionNode) replacedNode).getSubstitution(), ((ConstructionNode) replacedNode).getOptionalModifiers())); } throw new IllegalStateException("Unsupported node type"); }
private ConstructionNode mergeCns(ConstructionNode parent, ConstructionNode child) { ImmutableSubstitution composition = child.getSubstitution() .composeWith(parent.getSubstitution()) .reduceDomainToIntersectionWith(parent.getVariables()); return iqFactory.createConstructionNode(parent.getVariables(), composition); }
private Push findPushInConstructionNodeRootedSubtree(IntermediateQuery query, ImmutableExpression expression, ConstructionNode subtreeRoot) { ImmutableList<QueryNode> children = query.getChildren(subtreeRoot); if (children.size() != 1) { throw new IllegalStateException("Exactly one child expected for " + subtreeRoot); } return new Push( new Recipient(children.get(0)), subtreeRoot.getSubstitution().applyToBooleanExpression(expression)); }
@Override public ConstructionNode transform(ConstructionNode constructionNode) { return iqFactory.createConstructionNode(renameProjectedVars(constructionNode.getVariables()), renameSubstitution(constructionNode.getSubstitution())); }
/** * Lifts the construction node above and updates the order comparators */ private IQTree liftChildConstructionNode(ConstructionNode newChildRoot, UnaryIQTree newChild, IQProperties liftedProperties) { UnaryIQTree newOrderByTree = iqFactory.createUnaryIQTree( applySubstitution(newChildRoot.getSubstitution()), newChild.getChild(), liftedProperties); return iqFactory.createUnaryIQTree(newChildRoot, newOrderByTree, liftedProperties); }
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); }
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); } }
@Override public ConstructionNode transform(ConstructionNode constructionNode) { return iqFactory.createConstructionNode(renameProjectedVars(constructionNode.getVariables()), renameSubstitution(constructionNode.getSubstitution()), renameOptionalModifiers(constructionNode.getOptionalModifiers()) ); }
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); } }
private IQTree getProjection(ImmutableSet<Variable> signature, IQTree tree) { QueryNode root = tree.getRootNode(); if (root instanceof ConstructionNode){ return iqFactory.createUnaryIQTree( iqFactory.createConstructionNode(signature, ((ConstructionNode)root).getSubstitution()), ((UnaryIQTree)tree).getChild() ); } return iqFactory.createUnaryIQTree( iqFactory.createConstructionNode(signature), tree ); } }
private IQTree liftBinding(ConstructionNode childConstructionNode, UnaryIQTree childIQ, IQProperties currentIQProperties) { AscendingSubstitutionNormalization ascendingNormalization = normalizeAscendingSubstitution( childConstructionNode.getSubstitution().composeWith(substitution), projectedVariables); ImmutableSubstitution<ImmutableTerm> newSubstitution = ascendingNormalization.getAscendingSubstitution(); IQTree grandChildIQTree = ascendingNormalization.normalizeChild(childIQ.getChild()); ConstructionNode newConstructionNode = iqFactory.createConstructionNode(projectedVariables, newSubstitution); return iqFactory.createUnaryIQTree(newConstructionNode, grandChildIQTree, currentIQProperties.declareLifted()); }
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); }