private static ImmutableSet<Constant> extractIRITemplates(IQ definition) { return Optional.of(definition.getProjectionAtom().getPredicate()) .filter(p -> p instanceof RDFAtomPredicate) .map(p -> extractIRITemplates((RDFAtomPredicate) p, definition)) .orElseGet(ImmutableSet::of); }
@Override public boolean equals(Object otherObject) { return (otherObject instanceof IQ) && projectionAtom.equals(((IQ) otherObject).getProjectionAtom()) && tree.isEquivalentTo(((IQ) otherObject).getTree()); }
private Optional<Variable> getReplacedVar(IQ assertion, Position pos) { switch (pos) { case SUBJECT: return Optional.of(getVarFromRDFAtom(assertion.getProjectionAtom(), pos)); case OBJECT: return MappingTools.extractRDFPredicate(assertion).isClass() ? Optional.empty() : Optional.of(getVarFromRDFAtom(assertion.getProjectionAtom(), pos)); default: throw new UnexpectedPositionException(pos); } }
private ImmutableTable<RDFAtomPredicate, IRI, IQ> extractTable( ImmutableMap<IQ, MappingTools.RDFPredicateInfo> iqClassificationMap, boolean isClass) { return iqClassificationMap.entrySet().stream() .filter(e -> e.getValue().isClass() == isClass) .map(e -> Tables.immutableCell( (RDFAtomPredicate) e.getKey().getProjectionAtom().getPredicate(), e.getValue().getIri(), e.getKey())) .collect(ImmutableCollectors.toTable()); }
@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)); }
private ImmutableTable<RDFAtomPredicate, IRI, IQ> extractTable( ImmutableMap<IQ, MappingTools.RDFPredicateInfo> iqClassificationMap, boolean isClass) { ImmutableMultimap<Map.Entry<RDFAtomPredicate, IRI>, IQ> multimap = iqClassificationMap.entrySet().stream() .filter(e -> e.getValue().isClass() == isClass) .collect(ImmutableCollectors.toMultimap( e -> Maps.immutableEntry( (RDFAtomPredicate) e.getKey().getProjectionAtom().getPredicate(), e.getValue().getIri()), Map.Entry::getKey)); return multimap.asMap().entrySet().stream() .map(e -> Tables.immutableCell( e.getKey().getKey(), e.getKey().getValue(), mergeDefinitions(e.getValue()))) .collect(ImmutableCollectors.toTable()); }
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()); }
@Override public IQ optimize(IQ query) { IQTree newTree = optimize(query.getTree()); return iqFactory.createIQ(query.getProjectionAtom(), newTree); }
private static ImmutableSet<Constant> extractIRITemplates(RDFAtomPredicate predicate, IQ definition) { ImmutableList<Variable> projectedVariables = definition.getProjectionAtom().getArguments(); return Stream.of(predicate.getSubject(projectedVariables), predicate.getObject(projectedVariables)) .flatMap(v -> extractIRITemplates(v, definition.getTree())) .collect(ImmutableCollectors.toSet()); }
private static PredicateClassification classify(ImmutableSet<Constant> sameAsIriTemplates, IQ definition, RDFAtomPredicate rdfAtomPredicate, boolean isClass) { ImmutableList<Variable> variables = definition.getProjectionAtom().getArguments(); /* * Current limitation: is the object is concerned about SameAs rewriting, the subject is supposed also * concerned. * TODO: enrich the classification */ if (!isClass && extractIRITemplates(rdfAtomPredicate.getObject(variables), definition.getTree()) .anyMatch(sameAsIriTemplates::contains)) { return PredicateClassification.AT_LEAST_OBJECT; } return extractIRITemplates(rdfAtomPredicate.getSubject(variables), definition.getTree()) .filter(sameAsIriTemplates::contains) .findAny() .map(t -> PredicateClassification.SUBJECT_ONLY) .orElse(PredicateClassification.NONE); }
/** * */ 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); }
private void validateAssertion(IQ mappingAssertion, PPMappingAssertionProvenance provenance, Ontology ontology, ImmutableMultimap<IRI, Datatype> datatypeMap) throws MappingOntologyMismatchException { ImmutableList<Variable> projectedVariables = mappingAssertion.getProjectionAtom().getArguments(); MappingTools.RDFPredicateInfo predicateClassification = MappingTools.extractRDFPredicate(mappingAssertion); Optional<RDFTermType> tripleObjectType = predicateClassification.isClass() ? Optional.empty() : extractTripleObjectType(mappingAssertion); checkTripleObject(predicateClassification.getIri(), tripleObjectType, provenance, ontology, datatypeMap); }
/** * 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; } }
public static RDFPredicateInfo extractRDFPredicate(IQ mappingAssertion) { DistinctVariableOnlyDataAtom projectionAtom = mappingAssertion.getProjectionAtom(); RDFAtomPredicate rdfAtomPredicate = Optional.of(projectionAtom.getPredicate()) .filter(p -> p instanceof RDFAtomPredicate) .map(p -> (RDFAtomPredicate) p) .orElseThrow(() -> new MappingPredicateIRIExtractionException("The following mapping assertion " + "is not having a RDFAtomPredicate: " + mappingAssertion)); ImmutableSet<ImmutableList<? extends ImmutableTerm>> possibleSubstitutedArguments = mappingAssertion.getTree().getPossibleVariableDefinitions().stream() .map(s -> s.apply(projectionAtom.getArguments())) .collect(ImmutableCollectors.toSet()); IRI propertyIRI = extractIRI(possibleSubstitutedArguments, rdfAtomPredicate::getPropertyIRI); return propertyIRI.equals(RDF.TYPE) ? new RDFPredicateInfo(true, extractIRI(possibleSubstitutedArguments, rdfAtomPredicate::getClassIRI)) : new RDFPredicateInfo(false, propertyIRI); }
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 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; }
@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); } }
private IQ completeSameAsDefinition(IQ originalDefinition, RDFAtomPredicate rdfAtomPredicate) { ImmutableList<Variable> originalProjectedVariables = originalDefinition.getProjectionAtom().getArguments();
@Override public IntermediateQuery convert(IQ query, DBMetadata dbMetadata, ExecutorRegistry executorRegistry) throws EmptyQueryException { if (query.getTree().isDeclaredAsEmpty()) throw new EmptyQueryException(); IntermediateQueryBuilder queryBuilder = iqFactory.createIQBuilder(dbMetadata, executorRegistry); IQTree topTree = query.getTree(); QueryNode rootNode = topTree.getRootNode(); queryBuilder.init(query.getProjectionAtom(), rootNode); insertChildren(rootNode, topTree.getChildren(), queryBuilder); return queryBuilder.build(); }
/** * Does NOT look for intensional data nodes inside the definitions * */ private IQTree replaceIntensionalData(IntensionalDataNode dataNode, IQ definition) { InjectiveVar2VarSubstitution renamingSubstitution = substitutionFactory.generateNotConflictingRenaming( variableGenerator, definition.getTree().getKnownVariables()); IQ renamedIQ; if(renamingSubstitution.isEmpty()){ renamedIQ = definition; } else { QueryRenamer queryRenamer = transformerFactory.createRenamer(renamingSubstitution); renamedIQ = queryRenamer.transform(definition); } ImmutableSubstitution<VariableOrGroundTerm> descendingSubstitution = extractSubstitution( renamingSubstitution.applyToDistinctVariableOnlyDataAtom(renamedIQ.getProjectionAtom()), dataNode.getProjectionAtom()); return renamedIQ.getTree() .applyDescendingSubstitution(descendingSubstitution, Optional.empty()) .liftBinding(variableGenerator); }