@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()); }
@Override public ConstructionNode transform(ConstructionNode constructionNode) { return constructionNode.clone(); }
@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<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 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(); }
DataAtom projectionAtom = Optional.ofNullable( subQueryProjectionAtoms.get(constructionNode)) .orElseGet(() -> generateProjectionAtom(constructionNode.getVariables())); heads.add(new RuleHead(constructionNode.getSubstitution(), projectionAtom, te.getFirstChild(constructionNode))); subQueryProjectionAtoms.put(constructionNode, projectionAtom); Function mutAt = ImmutabilityTools.convertToMutableFunction(projectionAtom); freshHeadAtom = generateProjectionAtom(parentNode.get().getChildVariables()); } else { freshHeadAtom = generateProjectionAtom(((UnionNode) node).getVariables()); Optional<QueryNode> grandChild = te.getFirstChild(cn); subQueryProjectionAtoms.put(cn, freshHeadAtom); heads.add(new RuleHead(cn.getSubstitution(), freshHeadAtom, grandChild)); } else { ConstructionNode cn = iqFactory.createConstructionNode(((UnionNode) node).getVariables()); subQueryProjectionAtoms.put(cn, freshHeadAtom); heads.add(new RuleHead(cn.getSubstitution(), freshHeadAtom, Optional.ofNullable(child)));
/** * Projects away variables only for child construction nodes */ private IQTree projectAwayUnnecessaryVariables(IQTree child, IQProperties currentIQProperties) { if (child.getRootNode() instanceof ConstructionNode) { ConstructionNode constructionNode = (ConstructionNode) child.getRootNode(); AscendingSubstitutionNormalization normalization = normalizeAscendingSubstitution( constructionNode.getSubstitution(), projectedVariables); Optional<ConstructionNode> proposedConstructionNode = normalization.generateTopConstructionNode(); if (proposedConstructionNode .filter(c -> c.isSyntacticallyEquivalentTo(constructionNode)) .isPresent()) return child; IQTree grandChild = normalization.normalizeChild(((UnaryIQTree) child).getChild()); return proposedConstructionNode .map(c -> (IQTree) iqFactory.createUnaryIQTree(c, grandChild, currentIQProperties.declareLifted())) .orElse(grandChild); } else return child; }
UnionNode updatedUnion = iqFactory.createUnionNode(bufferNode.getVariables()); bufferNode.clone(), Optional.of(updatedUnion), sourceQuery,
@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); }
@Override public void visit(ConstructionNode constructionNode) { if (query.getChildren(constructionNode).size() != 1) { throw new InvalidIntermediateQueryException("CONSTRUCTION node " + constructionNode + " must have ONE and ONLY ONE child.\n" + query); } ImmutableSet<Variable> requiredChildVariables = constructionNode.getChildVariables(); for (QueryNode child : query.getChildren(constructionNode)) { ImmutableSet<Variable> childProjectedVariables = query.getVariables(child); if (!childProjectedVariables.containsAll(requiredChildVariables)) { throw new InvalidIntermediateQueryException("This child " + child + " does not project all the variables " + "required by the CONSTRUCTION node (" + requiredChildVariables + ")\n" + query); } } }
static Optional<DataNodeAndSubstitution> extract(ConstructionNode rightChild, IntermediateQuery query) { /* * Not supported */ if (rightChild.getOptionalModifiers().isPresent()) return Optional.empty(); QueryNode grandChild = query.getFirstChild(rightChild).get(); if (grandChild instanceof DataNode) return Optional.of(new DataNodeAndSubstitution((DataNode) grandChild, Optional.empty(), Optional.of(rightChild))); else if (grandChild instanceof FilterNode) { FilterNode filterNode = (FilterNode) grandChild; return query.getFirstChild(grandChild) .filter(n -> n instanceof DataNode) .map(n -> (DataNode)n) .map(n -> new DataNodeAndSubstitution(n, Optional.of(filterNode), Optional.of(rightChild))); } else return Optional.empty(); }
@Override public IQTree transformConstruction(IQTree tree, ConstructionNode rootNode, IQTree child) { return transformUnaryNode(rootNode.acceptNodeTransformer(nodeTransformer), child); }
/** * 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()); }
if (castChild.getSubstitution().isEmpty()) { Optional<ImmutableQueryModifiers> combinedModifiers = combineModifiers( modifiers, castChild.getOptionalModifiers() ); if (combinedModifiers.isPresent()) { constructionNodeChainRoot.getSubstitution().isEmpty() && !isMandatoryRoot(constructionNodeChainRoot, query);
ImmutableSet<Variable> unionVariables = newRootNode.getChildVariables(); UnionNode newUnionNode = iqFactory.createUnionNode(unionVariables);
@Override protected Optional<ConstructionNodeCleaningProposal> evaluateNode(QueryNode node, IntermediateQuery query) { if (node instanceof ConstructionNode) { ConstructionNode castNode = (ConstructionNode) node; Optional<ImmutableQueryModifiers> optModifiers = castNode.getOptionalModifiers(); ImmutableQueryModifiers modifiers = optModifiers.isPresent() ? optModifiers.get() : new ImmutableQueryModifiersImpl( false, -1, -1, ImmutableList.of() ); return makeProposal( query, castNode, modifiers, castNode, query.getFirstChild(castNode) ); } return Optional.empty(); }
private ConstructionNode mergeCns(ConstructionNode parent, ConstructionNode child) { ImmutableSubstitution composition = child.getSubstitution() .composeWith(parent.getSubstitution()) .reduceDomainToIntersectionWith(parent.getVariables()); return iqFactory.createConstructionNode(parent.getVariables(), composition); }
@Override public ConstructionNode transform(ConstructionNode constructionNode) { return iqFactory.createConstructionNode(renameProjectedVars(constructionNode.getVariables()), renameSubstitution(constructionNode.getSubstitution()), renameOptionalModifiers(constructionNode.getOptionalModifiers()) ); }
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"); }
((ConstructionNode) focusNode).getSubstitution().getImmutableMap().entrySet().stream(). filter(e -> retainedVariables.contains(e.getKey())) .collect(ImmutableCollectors.toMap()); retainedVariables, SUBSTITUTION_FACTORY.getSubstitution(shrinkedMap), ((ConstructionNode) focusNode).getOptionalModifiers() ); treeComponent.replaceNode(focusNode, replacingNode);