@Override public IQ liftBinding() { IQTree newTree = tree.liftBinding(getVariableGenerator()); return newTree == tree ? this : iqFactory.createIQ(projectionAtom, newTree); }
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); }
@Override public Stream<IQ> splitUnion(IQ query) { DistinctVariableOnlyDataAtom projectionAtom = query.getProjectionAtom(); VariableGenerator variableGenerator = query.getVariableGenerator(); IQTree tree = query.getTree(); return findFirstSplittableUnion(query) .map(unionTree -> unionTree.getChildren().stream() .map(c -> tree.replaceSubTree(unionTree, c)) .map(t -> t.liftBinding(variableGenerator)) .map(t -> iqFactory.createIQ(projectionAtom, t)) .map(IQ::liftBinding)) .orElseGet(() -> Stream.of(query)); }
@Override public IQ optimize(IQ query) { IQTree newTree = optimize(query.getTree()); return iqFactory.createIQ(query.getProjectionAtom(), newTree); }
@Override public IQ convert(IntermediateQuery query) { IQTree tree = convertTree(query, query.getRootNode()); return iqFactory.createIQ(query.getProjectionAtom(), tree); }
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()); } }
private ImmutableList<IQ> normalizeIQ(IQ query) { IQTree tree = query.getTree(); while(tree.getRootNode() instanceof QueryModifierNode){ tree = ((UnaryIQTree)tree).getChild(); } return splitRootUnion(tree) .map(t -> enforceRootCn(t, query.getProjectionAtom().getVariables())) .map(t -> iqFactory.createIQ(query.getProjectionAtom(), t)) .collect(ImmutableCollectors.toList()); }
/** * */ private IQ liftUnionsInTree(IQ query) { VariableGenerator variableGenerator = query.getVariableGenerator(); // Non-final IQTree previousTree; IQTree newTree = query.getTree(); int i=0; do { previousTree = newTree; newTree = liftTree(previousTree, variableGenerator) .liftBinding(variableGenerator); } while (!newTree.equals(previousTree) && (++i < ITERATION_BOUND)); if (i >= ITERATION_BOUND) throw new MinorOntopInternalBugException(getClass().getName() + " did not converge after " + ITERATION_BOUND + " iterations"); return newTree.equals(query.getTree()) ? query : iqFactory.createIQ(query.getProjectionAtom(), newTree); }
@Override public IQ rewrite(IQ query) throws EmptyQueryException { return iqFactory.createIQ(query.getProjectionAtom(), query.getTree().acceptTransformer(new BasicGraphPatternTransformer(iqFactory) { @Override protected ImmutableList<IntensionalDataNode> transformBGP(ImmutableList<IntensionalDataNode> triplePatterns) { // optimise with Sigma ABox dependencies ArrayList<IntensionalDataNode> list = new ArrayList<>(triplePatterns); // this loop has to remain sequential (no streams) for (int i = 0; i < list.size(); i++) { ImmutableSet<DataAtom> derived = inclusionDependencyTools.chaseAtom(list.get(i).getProjectionAtom(), sigma); if (!derived.isEmpty()) { for (int j = 0; j < list.size(); j++) if (i != j && derived.contains(list.get(j).getProjectionAtom())) { list.remove(j); j--; } } } return ImmutableList.copyOf(list); } })); } }
/** * TODO: why a fix point? */ @Override public IQ optimize(IQ query) { TreeTransformer treeTransformer = new TreeTransformer(query.getVariableGenerator()); IQ prev; do { prev = query; query = iqFactory.createIQ( query.getProjectionAtom(), query.getTree().acceptTransformer(treeTransformer) ); } while (!prev.equals(query)); return query; } }
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); } }
.orElse(unionTree); return Optional.of(iqFactory.createIQ(projectionAtom, tree));
@Override public IQ transform(IQ originalQuery) { QueryNodeRenamer nodeTransformer = new QueryNodeRenamer(iqFactory, renamingSubstitution, atomFactory); HomogeneousIQTreeVisitingTransformer iqTransformer = new HomogeneousIQTreeVisitingTransformer(nodeTransformer, iqFactory); IQTree newIQTree = originalQuery.getTree().acceptTransformer(iqTransformer); DistinctVariableOnlyDataAtom newProjectionAtom = transformProjectionAtom(originalQuery.getProjectionAtom()); return iqFactory.createIQ(newProjectionAtom, newIQTree); } }
IQ result = iqFactory.createIQ(convertedIQ.getProjectionAtom(), optimisedTree);
private IQ normalizeIQ(IntermediateQuery intermediateQuery) { // Trick for pushing down expressions under unions: // - there the context may be concrete enough for evaluating certain expressions // - useful for dealing with SPARQL EBVs for instance IntermediateQuery pushedDownQuery = pushDownExpressionOptimizer.optimize(intermediateQuery); log.debug("New query after pushing down the boolean expressions (temporary): \n" + pushedDownQuery); IQ flattenIQ = unionFlattener.optimize(iqConverter.convert(pushedDownQuery)); log.debug("New query after flattening the union: \n" + flattenIQ); IQTree treeAfterPullOut = optimizerFactory.createEETransformer(flattenIQ.getVariableGenerator()).transform(flattenIQ.getTree()); log.debug("Query tree after pulling out equalities: \n" + treeAfterPullOut); // Pulling up is needed when filtering conditions appear above a data atom on the left // (causes problems to the IQ2DatalogConverter) try { IntermediateQuery queryAfterPullUp = pullUpExpressionOptimizer.optimize(iqConverter.convert( iqFactory.createIQ(flattenIQ.getProjectionAtom(), treeAfterPullOut), intermediateQuery.getDBMetadata(), intermediateQuery.getExecutorRegistry())); log.debug("New query after pulling up the boolean expressions: \n" + queryAfterPullUp); return iqConverter.convert(queryAfterPullUp); } catch (EmptyQueryException e) { // Not expected throw new MinorOntopInternalBugException(e.getMessage()); } }
newTree = iqFactory.createUnaryIQTree(ancestors.pop(), newTree); return iqFactory.createIQ(iq.getProjectionAtom(), newTree);
private IQ canonizeWithJoin(IQ assertion, IntensionalQueryMerger intensionalQueryMerger, Position pos) { Optional<Variable> replacedVar = getReplacedVar(assertion, pos); if (replacedVar.isPresent()) { Variable newVariable = createFreshVariable(assertion, intensionalQueryMerger, replacedVar.get()); IntensionalDataNode idn = getIDN(replacedVar.get(), newVariable); RDFAtomPredicate pred = getRDFAtomPredicate(assertion.getProjectionAtom()); DistinctVariableOnlyDataAtom projAtom = atomFactory.getDistinctVariableOnlyDataAtom( pred, replaceProjVars( pred, assertion.getProjectionAtom().getArguments(), pos, newVariable)); IQ intensionalCanonizedQuery = iqFactory.createIQ( projAtom, getIntensionalCanonizedTree(assertion, projAtom, idn)); IQ canonizedQuery = intensionalQueryMerger.optimize(intensionalCanonizedQuery) .liftBinding(); return canonizedQuery.getTree().isDeclaredAsEmpty() // No matching canonical IRI template ? assertion : canonizedQuery; } return assertion; }
IQ inversedDefinition = iqFactory.createIQ(newProjectionAtom, queryRenamer.transform(originalDefinition).getTree());