private IntermediateQuery reshape(IntermediateQuery query) { Optional<GroundTermRemovalFromDataNodeProposal> optionalProposal = makeProposal(query); if (optionalProposal.isPresent()) { GroundTermRemovalFromDataNodeProposal proposal = optionalProposal.get(); try { query.applyProposal(proposal); return query; } catch (EmptyQueryException e) { throw new IllegalStateException("Inconsistency: GroundTermRemovalFromDataNodeReshaper should empty the query "); } } else { return query; } }
/** * Uses the index of TrueNodes in the current query, instead of the inherited tree traversal method * NodeCentricDepthFirstOptimizer.optimizeQuery() */ @Override protected IntermediateQuery optimizeQuery(IntermediateQuery intermediateQuery) throws EmptyQueryException { boolean iterate = true; while (iterate) { List<TrueNode> trueNodes = intermediateQuery.getTrueNodes().collect(Collectors.toList()); iterate = false; for (TrueNode trueNode : trueNodes) { Optional<TrueNodeRemovalProposal> optionalProposal = evaluateNode(trueNode, intermediateQuery); if (optionalProposal.isPresent()) { intermediateQuery.applyProposal(optionalProposal.get()); iterate = true; } } } return intermediateQuery; } }
/** * Applies the substitution from the topNode. * * NB: the topNode can be a JoinLikeNode, a replacing FilterNode or the replacing child */ private static <T extends QueryNode> NodeCentricOptimizationResults<T> propagateSubstitution( IntermediateQuery query, Optional<ImmutableSubstitution<VariableOrGroundTerm>> optionalSubstitution, T topNode) throws EmptyQueryException { if (optionalSubstitution.isPresent()) { // TODO: filter the non-bound variables from the substitution before propagating!!! SubstitutionPropagationProposal<T> propagationProposal = new SubstitutionPropagationProposalImpl<>( topNode, optionalSubstitution.get(), false); // Forces the use of an internal executor (the treeComponent must remain the same). return query.applyProposal(propagationProposal, true); } /* * No substitution to propagate */ else { return new NodeCentricOptimizationResultsImpl<>(query, topNode); } }
/** * Applies the substitution from the topNode. * * NB: the topNode can be a JoinLikeNode, a replacing FilterNode or the replacing child */ private static <T extends QueryNode> NodeCentricOptimizationResults<T> propagateSubstitution( IntermediateQuery query, Optional<ImmutableSubstitution<VariableOrGroundTerm>> optionalSubstitution, T topNode) throws EmptyQueryException { if (optionalSubstitution.isPresent()) { // TODO: filter the non-bound variables from the substitution before propagating!!! SubstitutionPropagationProposal<T> propagationProposal = new SubstitutionPropagationProposalImpl<>( topNode, optionalSubstitution.get(), false); // Forces the use of an internal executor (the treeComponent must remain the same). return query.applyProposal(propagationProposal, true); } /* * No substitution to propagate */ else { return new NodeCentricOptimizationResultsImpl<>(query, topNode); } }
private NextNodeAndQuery liftUnionToMatchingVariable(IntermediateQuery currentQuery, UnionNode currentUnionNode, ImmutableSet<Variable> unionVariables) throws EmptyQueryException { Optional<QueryNode> parentNode = lifter.chooseLiftLevel(currentQuery, currentUnionNode, unionVariables); if(parentNode.isPresent()){ UnionLiftProposal proposal = new UnionLiftProposalImpl(currentUnionNode, parentNode.get()); NodeCentricOptimizationResults<UnionNode> results = currentQuery.applyProposal(proposal); currentUnionNode = results.getOptionalNewNode().orElseThrow(() -> new IllegalStateException( "The focus node has to be a union node and be present")); return liftBindingsAndUnion(currentQuery, currentUnionNode); } //no parent with the given variable, I don't lift for the moment return new NextNodeAndQuery(getDepthFirstNextNode(currentQuery, currentUnionNode), currentQuery); }
/** * Can be optimized by reducing after each iteration the set of union nodes to be reviewed */ private IntermediateQuery pushAboveUnions(IntermediateQuery query) throws EmptyQueryException { boolean fixPointReached; do { fixPointReached = true; for (QueryNode node : query.getNodesInTopDownOrder()) { if (node instanceof UnionNode) { Optional<PushUpBooleanExpressionProposal> proposal = makeProposalForUnionNode((UnionNode) node, query); if (proposal.isPresent()) { query = ((PushUpBooleanExpressionResults) query.applyProposal(proposal.get())).getResultingQuery(); fixPointReached = false; } } } } while (!fixPointReached); return query; }
/** * Can be optimized by reducing after each iteration the set of union nodes to be reviewed */ private IntermediateQuery pushAboveUnions(IntermediateQuery query) throws EmptyQueryException { boolean fixPointReached; do { fixPointReached = true; for (QueryNode node : query.getNodesInTopDownOrder()) { if (node instanceof UnionNode) { Optional<PushUpBooleanExpressionProposal> proposal = makeProposalForUnionNode((UnionNode) node, query); if (proposal.isPresent()) { query = ((PushUpBooleanExpressionResults) query.applyProposal(proposal.get())).getResultingQuery(); fixPointReached = false; } } } } while (!fixPointReached); return query; }
/** * Lifts the substitution in the absence of a LJ condition */ private LeftJoinNode liftSubstitution(LeftJoinNode normalizedLeftJoin, ImmutableSubstitution<ImmutableTerm> remainingRightSubstitution, IntermediateQuery query) { SubstitutionPropagationProposal<LeftJoinNode> proposal = new SubstitutionPropagationProposalImpl<>( normalizedLeftJoin, remainingRightSubstitution); try { NodeCentricOptimizationResults<LeftJoinNode> results = query.applyProposal(proposal, true); return results .getNewNodeOrReplacingChild() // The LJ is expected to be the child of a construction node .flatMap(query::getFirstChild) .filter(n -> n instanceof LeftJoinNode) .map(n -> (LeftJoinNode) n) .orElseThrow(() -> new MinorOntopInternalBugException("Was expected to insert a construction node " + "followed by a LJ")); } catch (EmptyQueryException e) { throw new MinorOntopInternalBugException("This substitution propagation was not expected " + "to make the query be empty"); } }
/** * TODO: explain * */ private NextNodeAndQuery optimizeDataNode(IntermediateQuery currentQuery, DataNode currentNode) throws EmptyQueryException { Optional<PullVariableOutOfDataNodeProposal> optionalProposal = buildProposal(currentNode, new HashSet<>()); if (optionalProposal.isPresent()) { PullVariableOutOfDataNodeProposal proposal = optionalProposal.get(); NodeCentricOptimizationResults<DataNode> results = currentQuery.applyProposal(proposal); return getNextNodeAndQuery(currentQuery, results); } else { // NB: a DataNode is not expected to have a child return new NextNodeAndQuery(getDepthFirstNextNode(currentQuery, currentNode), currentQuery); } } }
private IntermediateQuery optimizeSubtree(QueryNode focusNode, IntermediateQuery query, ImmutableSet<Variable> retainedVariables) { Optional<ProjectionShrinkingProposal> optionalProposal = Optional.empty(); if (focusNode instanceof UnionNode || focusNode instanceof ConstructionNode) { optionalProposal = makeProposal((ExplicitVariableProjectionNode) focusNode, query, retainedVariables); } if (focusNode instanceof JoinOrFilterNode) { retainedVariables = updateRetainedVariables((JoinOrFilterNode) focusNode, query, retainedVariables); } else if (focusNode instanceof ConstructionNode) { retainedVariables = updateRetainedVariables((ConstructionNode) focusNode, query, retainedVariables); } if (optionalProposal.isPresent()) { NodeCentricOptimizationResults<ExplicitVariableProjectionNode> optimizationResults; try { optimizationResults = query.applyProposal(optionalProposal.get()); } catch (EmptyQueryException e) { throw new IllegalStateException("The projection shrinker should not empty the query"); } focusNode = optimizationResults.getNewNodeOrReplacingChild().orElseThrow( () -> new IllegalStateException("A replacing node should be generated")); } for (QueryNode childNode : query.getChildren(focusNode)) { query = optimizeSubtree(childNode, query, retainedVariables); } return query; }
protected IntermediateQuery optimizeQuery(IntermediateQuery initialQuery) throws EmptyQueryException { // Non-final Optional<QueryNode> optionalNextNode = Optional.of(initialQuery.getRootNode()); // Non-final IntermediateQuery currentQuery = initialQuery; while (optionalNextNode.isPresent()) { QueryNode currentNode = optionalNextNode.get(); Optional<P> optionalProposal = evaluateNode(currentNode,currentQuery); if (optionalProposal.isPresent()) { NodeCentricOptimizationResults<? extends QueryNode> optimizationResults = currentQuery.applyProposal( optionalProposal.get()); NextNodeAndQuery nextNodeAndQuery = getNextNodeAndQuery(currentQuery, optimizationResults); currentQuery = nextNodeAndQuery.getNextQuery(); optionalNextNode = nextNodeAndQuery.getOptionalNextNode(); } else { optionalNextNode = getDepthFirstNextNode(currentQuery, currentNode); } } return currentQuery; }
private IntermediateQuery optimizeSubtree(QueryNode focusNode, IntermediateQuery query, ImmutableSet<Variable> retainedVariables) { Optional<ProjectionShrinkingProposal> optionalProposal = Optional.empty(); if (focusNode instanceof UnionNode || focusNode instanceof ConstructionNode) { optionalProposal = makeProposal((ExplicitVariableProjectionNode) focusNode, retainedVariables); } if (focusNode instanceof JoinOrFilterNode) { retainedVariables = updateRetainedVariables((JoinOrFilterNode) focusNode, query, retainedVariables); } else if (focusNode instanceof ConstructionNode) { retainedVariables = updateRetainedVariables((ConstructionNode) focusNode); } if (optionalProposal.isPresent()) { NodeCentricOptimizationResults<ExplicitVariableProjectionNode> optimizationResults; try { optimizationResults = query.applyProposal(optionalProposal.get()); } catch (EmptyQueryException e) { throw new IllegalStateException("The projection shrinker should not empty the query"); } focusNode = optimizationResults.getNewNodeOrReplacingChild().orElseThrow( () -> new IllegalStateException("A replacing node should be generated")); } for (QueryNode childNode : query.getChildren(focusNode)) { query = optimizeSubtree(childNode, query, retainedVariables); } return query; }
protected IntermediateQuery optimizeQuery(IntermediateQuery initialQuery) throws EmptyQueryException { // Non-final Optional<QueryNode> optionalNextNode = Optional.of(initialQuery.getRootNode()); // Non-final IntermediateQuery currentQuery = initialQuery; while (optionalNextNode.isPresent()) { QueryNode currentNode = optionalNextNode.get(); Optional<P> optionalProposal = evaluateNode(currentNode,currentQuery); if (optionalProposal.isPresent()) { NodeCentricOptimizationResults<? extends QueryNode> optimizationResults = currentQuery.applyProposal( optionalProposal.get()); NextNodeAndQuery nextNodeAndQuery = getNextNodeAndQuery(currentQuery, optimizationResults); currentQuery = nextNodeAndQuery.getNextQuery(); optionalNextNode = nextNodeAndQuery.getOptionalNextNode(); } else { optionalNextNode = getDepthFirstNextNode(currentQuery, currentNode); } } return currentQuery; }
/** * Lifts the substitution in the absence of a LJ condition */ private LeftJoinNode liftSubstitution(LeftJoinNode normalizedLeftJoin, ImmutableSubstitution<ImmutableTerm> remainingRightSubstitution, IntermediateQuery query) { SubstitutionPropagationProposal<LeftJoinNode> proposal = new SubstitutionPropagationProposalImpl<>( normalizedLeftJoin, remainingRightSubstitution); try { return query.applyProposal(proposal, true) .getOptionalNewNode() .orElseThrow(() -> new MinorOntopInternalBugException("Was not expected to modify the LJ node")); } catch (EmptyQueryException e) { throw new MinorOntopInternalBugException("This substitution propagation was not expected " + "to make the query be empty"); } }
private IntermediateQuery pushUpFromSubtree(QueryNode subtreeRoot, IntermediateQuery query) throws EmptyQueryException { if (subtreeRoot instanceof CommutativeJoinOrFilterNode) { Optional<PushUpBooleanExpressionProposal> proposal = makeNodeCentricProposal((CommutativeJoinOrFilterNode) subtreeRoot, query); if (proposal.isPresent()) { PushUpBooleanExpressionResults optimizationResults = (PushUpBooleanExpressionResults) query.applyProposal(proposal.get()); query = optimizationResults.getResultingQuery(); QueryNode nextNode = optimizationResults.getExpressionProviderReplacingNodes().iterator().next(); return pushUpFromSubtree(nextNode, query); } } Optional<QueryNode> optNextNode = QueryNodeNavigationTools.getDepthFirstNextNode(query, subtreeRoot); return optNextNode.isPresent() ? pushUpFromSubtree(optNextNode.get(), query) : query; }
private IntermediateQuery pushUpFromSubtree(QueryNode subtreeRoot, IntermediateQuery query) throws EmptyQueryException { if (subtreeRoot instanceof CommutativeJoinOrFilterNode) { Optional<PushUpBooleanExpressionProposal> optionalProposal = makeNodeCentricProposal((CommutativeJoinOrFilterNode) subtreeRoot, query); if (optionalProposal.isPresent()) { PushUpBooleanExpressionResults optimizationResults = (PushUpBooleanExpressionResults) query.applyProposal(optionalProposal.get()); query = optimizationResults.getResultingQuery(); QueryNode nextNode = optimizationResults.getExpressionProviderReplacingNodes().iterator().next(); return pushUpFromSubtree(nextNode, query); } } Optional<QueryNode> optNextNode = QueryNodeNavigationTools.getDepthFirstNextNode(query, subtreeRoot); return optNextNode.isPresent() ? pushUpFromSubtree(optNextNode.get(), query) : query; }
/** * Returns results centered on the removed node. */ private static NodeTrackingResults<EmptyNode> reactToEmptinessDeclaration( IntermediateQuery query, QueryNode currentAncestor, QueryTreeComponent treeComponent, Optional<NodeTracker> optionalAncestryTracker) throws EmptyQueryException { ImmutableSet<Variable> nullVariables = query.getVariables(currentAncestor); EmptyNode replacingEmptyNode = query.getFactory().createEmptyNode(nullVariables); treeComponent.replaceSubTree(currentAncestor, replacingEmptyNode); RemoveEmptyNodeProposal proposal = optionalAncestryTracker.isPresent() ? new RemoveEmptyNodeProposalImpl(replacingEmptyNode, optionalAncestryTracker.get()) : new RemoveEmptyNodeProposalImpl(replacingEmptyNode, false); return query.applyProposal(proposal, true); } }
/** * Main method */ @Override public ProposalResults apply(QueryMergingProposal proposal, IntermediateQuery mainQuery, QueryTreeComponent treeComponent) throws InvalidQueryOptimizationProposalException, EmptyQueryException { Optional<IntermediateQuery> optionalSubQuery = proposal.getSubQuery(); if (optionalSubQuery.isPresent()) { mergeSubQuery(treeComponent, optionalSubQuery.get(), proposal.getIntensionalNode()); } else { removeUnsatisfiedNode(treeComponent, proposal.getIntensionalNode()); } // Non-final Optional<EmptyNode> nextEmptyNode = treeComponent.getEmptyNodes().stream() .findFirst(); while (nextEmptyNode.isPresent()) { // Removes the empty nodes (in-place operation) RemoveEmptyNodeProposal cleaningProposal = new RemoveEmptyNodeProposalImpl(nextEmptyNode.get(), false); mainQuery.applyProposal(cleaningProposal); nextEmptyNode = treeComponent.getEmptyNodes().stream().findFirst(); } return new ProposalResultsImpl(); }
new SubstitutionPropagationProposalImpl<>(currentConstructionNode, optionalSubstitution.get()); NodeCentricOptimizationResults<QueryNode> results = currentQuery.applyProposal(proposal); return getNextNodeAndQuery(currentQuery, results);
private NodeCentricOptimizationResults<InnerJoinNode> removeSubTree(IntermediateQuery query, QueryTreeComponent treeComponent, InnerJoinNode topJoinNode) throws EmptyQueryException { /* * Replaces by an EmptyNode */ EmptyNode emptyNode = iqFactory.createEmptyNode(query.getVariables(topJoinNode)); treeComponent.replaceSubTree(topJoinNode, emptyNode); /* * Removes the empty node * (may throw an EmptyQuery) */ RemoveEmptyNodeProposal removalProposal = new RemoveEmptyNodeProposalImpl(emptyNode, false); NodeTrackingResults<EmptyNode> removalResults = query.applyProposal(removalProposal); /* * If the query is not empty, changes the type of the results */ return new NodeCentricOptimizationResultsImpl<>(query, removalResults.getOptionalNextSibling(), removalResults.getOptionalClosestAncestor()); }