private IQ insertFilter(IQ originalQuery, ImmutableSet<ImmutableSet<Variable>> nullableVariables) { FilterNode filterNode = iQFactory.createFilterNode(computeFilterExpression(nullableVariables)); UnaryIQTree newTree = iQFactory.createUnaryIQTree(filterNode, originalQuery.getTree()); // TODO: normalize it return iQFactory.createIQ(originalQuery.getProjectionAtom(), newTree); } }
private IQTree getIntensionalCanonizedTree(IQ assertion, DistinctVariableOnlyDataAtom projAtom, IntensionalDataNode intensionalDataNode) { return iqFactory.createUnaryIQTree( iqFactory.createConstructionNode(projAtom.getVariables()), iqFactory.createNaryIQTree( iqFactory.createInnerJoinNode(), ImmutableList.of( assertion.getTree(), intensionalDataNode ))); }
@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 static IQ createFact(ConstructionNode topConstructionNode, Optional<ImmutableQueryModifiers> optionalModifiers, DistinctVariableOnlyDataAtom projectionAtom, IntermediateQueryFactory iqFactory) { IQTree constructionTree = iqFactory.createUnaryIQTree(topConstructionNode, iqFactory.createTrueNode()); IQTree tree = optionalModifiers .map(m -> m.insertAbove(constructionTree, iqFactory)) .orElse(constructionTree); return iqFactory.createIQ(projectionAtom, tree); }
private JoinOrFilterNode getRecipientReplacementNode(JoinOrFilterNode replacedNode, ImmutableExpression expressionToPropagate) { ImmutableExpression combinedExpression = getCombinedExpression(expressionToPropagate, replacedNode); if (replacedNode instanceof InnerJoinNode) return iqFactory.createInnerJoinNode(Optional.of(combinedExpression)); if (replacedNode instanceof LeftJoinNode) return iqFactory.createLeftJoinNode(Optional.of(combinedExpression)); if (replacedNode instanceof FilterNode) return iqFactory.createFilterNode(combinedExpression); throw new IllegalStateException("Invalid proposal: A CommutativeJoinOrFilterNode must be a commutative join or filter node"); }
@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 IQ liftBinding() { IQTree newTree = tree.liftBinding(getVariableGenerator()); return newTree == tree ? this : iqFactory.createIQ(projectionAtom, newTree); }
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 ); } }
@Override public IQTree liftIncompatibleDefinitions(Variable variable, IQTree child) { if (!childVariables.contains(variable)) { return iqFactory.createUnaryIQTree(this, child); } IQTree newChild = child.liftIncompatibleDefinitions(variable); QueryNode newChildRoot = newChild.getRootNode(); /* * Lift the union above the construction node */ if ((newChildRoot instanceof UnionNode) && ((UnionNode) newChildRoot).hasAChildWithLiftableDefinition(variable, newChild.getChildren())) { ImmutableList<IQTree> grandChildren = newChild.getChildren(); ImmutableList<IQTree> newChildren = grandChildren.stream() .map(c -> (IQTree) iqFactory.createUnaryIQTree(this, c)) .collect(ImmutableCollectors.toList()); UnionNode newUnionNode = iqFactory.createUnionNode(getVariables()); return iqFactory.createNaryIQTree(newUnionNode, newChildren); } return iqFactory.createUnaryIQTree(this, newChild); }
@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 IQTree createJoinSubtree(int childIndex, IQTree unionGrandChild, ImmutableList<IQTree> initialChildren) { return iqFactory.createNaryIQTree(this, IntStream.range(0, initialChildren.size()) .boxed() .map(i -> i == childIndex ? unionGrandChild : initialChildren.get(i)) .collect(ImmutableCollectors.toList())); }
private IQ createDefinition(ConstructionNode topConstructionNode, Optional<ImmutableQueryModifiers> optionalModifiers, DistinctVariableOnlyDataAtom projectionAtom, Collection<Predicate> tablePredicates, List<Function> bodyAtoms, IntermediateQueryFactory iqFactory) throws DatalogProgram2QueryConverterImpl.InvalidDatalogProgramException { try { IQTree bodyTree = convertAtoms(bodyAtoms, tablePredicates, iqFactory); IQTree constructionTree = iqFactory.createUnaryIQTree(topConstructionNode, bodyTree); IQTree tree = optionalModifiers .map(m -> m.insertAbove(constructionTree, iqFactory)) .orElse(constructionTree); return iqFactory.createIQ(projectionAtom, tree); } catch (IntermediateQueryBuilderException e) { throw new DatalogProgram2QueryConverterImpl.InvalidDatalogProgramException(e.getMessage()); } }
@Override public IQTree liftIncompatibleDefinitions(Variable variable, IQTree leftChild, IQTree rightChild) { if (leftChild.getVariables().contains(variable)) { IQTree liftedLeftChild = leftChild.liftIncompatibleDefinitions(variable); QueryNode leftChildRoot = liftedLeftChild.getRootNode(); if (leftChildRoot instanceof UnionNode && ((UnionNode) leftChildRoot).hasAChildWithLiftableDefinition(variable, leftChild.getChildren())) { UnionNode newUnionNode = iqFactory.createUnionNode( Stream.of(leftChild, rightChild) .flatMap(c -> c.getVariables().stream()) .collect(ImmutableCollectors.toSet())); return iqFactory.createNaryIQTree(newUnionNode, liftedLeftChild.getChildren().stream() .map(unionChild -> (IQTree) iqFactory.createBinaryNonCommutativeIQTree(this, unionChild, rightChild)) .collect(ImmutableCollectors.toList())); } } // By default, nothing lifted return iqFactory.createBinaryNonCommutativeIQTree(this, leftChild, rightChild); }
private Optional<CommutativeJoinOrFilterNode> getProviderReplacementNode(CommutativeJoinOrFilterNode providerNode, Optional<ImmutableExpression> nonPropagatedExpression) { if (providerNode instanceof InnerJoinNode) { return Optional.of(iqFactory.createInnerJoinNode(nonPropagatedExpression)); } if (providerNode instanceof FilterNode) { if (nonPropagatedExpression.isPresent()) { return Optional.of(iqFactory.createFilterNode(nonPropagatedExpression.get())); } return Optional.empty(); } throw new IllegalStateException("Invalid proposal: A CommutativeJoinOrFilterNode must be a commutative " + "join or filter node"); } }
private IQTree transformIntoInnerJoinTree(IQTree leftChild, IQTree rightChild) { return iqFactory.createNaryIQTree( iqFactory.createInnerJoinNode(getOptionalFilterCondition()), ImmutableList.of(leftChild, rightChild)); }
@Override public IQTree applyDescendingSubstitutionWithoutOptimizing( ImmutableSubstitution<? extends VariableOrGroundTerm> descendingSubstitution, ImmutableList<IQTree> children) { ImmutableSet<Variable> updatedProjectedVariables = constructionTools.computeNewProjectedVariables( descendingSubstitution, projectedVariables); ImmutableList<IQTree> updatedChildren = children.stream() .map(c -> c.applyDescendingSubstitutionWithoutOptimizing(descendingSubstitution)) .collect(ImmutableCollectors.toList()); UnionNode newRootNode = iqFactory.createUnionNode(updatedProjectedVariables); return iqFactory.createNaryIQTree(newRootNode, updatedChildren); }
@Override public EmptyNode clone() { return iqFactory.createEmptyNode(projectedVariables); }
@Override public IQTree applyDescendingSubstitution(ImmutableSubstitution<? extends VariableOrGroundTerm> descendingSubstitution, Optional<ImmutableExpression> constraint, IQTree child) { return iqFactory.createUnaryIQTree(this, child.applyDescendingSubstitution(descendingSubstitution, constraint)); }
@Override public IQTree applyDescendingSubstitutionWithoutOptimizing( ImmutableSubstitution<? extends VariableOrGroundTerm> descendingSubstitution, IQTree child) { FilterNode newFilterNode = iqFactory.createFilterNode( descendingSubstitution.applyToBooleanExpression(getFilterCondition())); return iqFactory.createUnaryIQTree(newFilterNode, child.applyDescendingSubstitutionWithoutOptimizing(descendingSubstitution)); }
/** * TODO: explain */ public static DataNode createDataNode(IntermediateQueryFactory iqFactory, DataAtom dataAtom, Collection<Predicate> tablePredicates) { if (tablePredicates.contains(dataAtom.getPredicate())) { return iqFactory.createExtensionalDataNode(dataAtom); } return iqFactory.createIntensionalDataNode(dataAtom); }