/** * Renames the projected variables */ private DistinctVariableOnlyDataAtom transformProjectionAtom(DistinctVariableOnlyDataAtom atom) { ImmutableList<Variable> newArguments = atom.getArguments().stream() .map(renamingSubstitution::applyToVariable) .collect(ImmutableCollectors.toList()); return atomFactory.getDistinctVariableOnlyDataAtom(atom.getPredicate(), newArguments); }
private void validateProjectedVariables() throws InvalidIntermediateQueryException { ImmutableSet<Variable> projectedVariables = tree.getVariables(); if (!projectedVariables.equals(projectionAtom.getVariables())) { throw new InvalidIntermediateQueryException("The variables projected by the root node" + projectedVariables + " do not match the projection atom " + projectionAtom.getVariables()); } }
/** * When such substitution DO NOT EXIST, returns an EMPTY OPTIONAL. * When NO renaming is NEEDED returns an EMPTY SUBSTITUTION. * */ private static Optional<InjectiveVar2VarSubstitution> computeRenamingSubstitution( DistinctVariableOnlyDataAtom sourceProjectionAtom, DistinctVariableOnlyDataAtom targetProjectionAtom) { int arity = sourceProjectionAtom.getEffectiveArity(); if (!sourceProjectionAtom.getPredicate().equals(targetProjectionAtom.getPredicate()) || (arity != targetProjectionAtom.getEffectiveArity())) { return Optional.empty(); } else { ImmutableMap<Variable, Variable> newMap = FunctionalTools.zip( sourceProjectionAtom.getArguments(), targetProjectionAtom.getArguments()).stream() .distinct() .filter(e -> !e.getKey().equals(e.getValue())) .collect(ImmutableCollectors.toMap()); return Optional.of(SUBSTITUTION_FACTORY.getInjectiveVar2VarSubstitution(newMap)); } }
@Override public Optional<IRI> getPredicateIRI() { return Optional.of(atom.getPredicate()) .filter(p -> p instanceof RDFAtomPredicate) .map(p -> (RDFAtomPredicate) p) .flatMap(p -> p.getPredicateIRI(getSubstitutedTerms())); }
@Override public ImmutableList<ImmutableTerm> getSubstitutedTerms() { return atom.getArguments().stream() .map(substitution::apply) .collect(ImmutableCollectors.toList()); }
@Override public ImmutableTerm getSubstitutedTerm(int index) { return substitution.apply(atom.getTerm(index)); }
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); }
private Optional<Variable> extractTripleObjectVariable(IntermediateQuery mappingAssertion) throws TripleObjectTypeInferenceException { ImmutableList<Variable> projectedVariables = mappingAssertion.getProjectionAtom().getArguments(); switch (projectedVariables.size()) { // Class case 1: return Optional.empty(); // Property case 2: return Optional.of(projectedVariables.get(1)); // Triple predicate case 3: return Optional.of(projectedVariables.get(2)); default: throw new TripleObjectTypeInferenceException(mappingAssertion, "Unexpected arity of the projection atom"); } }
@Override public TargetAtom getTripleTargetAtom(ImmutableTerm subject, ImmutableTerm pred, ImmutableTerm object) { DistinctVariableOnlyDataAtom projectionAtom = atomFactory.getDistinctTripleAtom( (subject instanceof Variable) ? (Variable) subject : s, (pred instanceof Variable) && (!pred.equals(subject)) ? (Variable) pred : p, (object instanceof Variable) && (!object.equals(subject)) && (!object.equals(pred)) ? (Variable) object : o); ImmutableList<ImmutableTerm> initialTerms = ImmutableList.of(subject, pred, object); ImmutableSubstitution<ImmutableTerm> substitution = substitutionFactory.getSubstitution( IntStream.range(0, 3) .boxed() .map(i -> Maps.immutableEntry(projectionAtom.getTerm(i), initialTerms.get(i))) .filter(e -> !e.getKey().equals(e.getValue())) .collect(ImmutableCollectors.toMap())); return new TargetAtomImpl(projectionAtom, substitution); }
/** * Renames the projected variables */ @Override protected DistinctVariableOnlyDataAtom transformProjectionAtom(DistinctVariableOnlyDataAtom atom) { ImmutableList<Variable> newArguments = atom.getArguments().stream() .map(renamingSubstitution::applyToVariable) .collect(ImmutableCollectors.toList()); return ATOM_FACTORY.getDistinctVariableOnlyDataAtom(atom.getPredicate(), newArguments); } }
/** * When such substitution DO NOT EXIST, returns an EMPTY OPTIONAL. * When NO renaming is NEEDED returns an EMPTY SUBSTITUTION. * */ private Optional<InjectiveVar2VarSubstitution> computeRenamingSubstitution( DistinctVariableOnlyDataAtom sourceProjectionAtom, DistinctVariableOnlyDataAtom targetProjectionAtom) { int arity = sourceProjectionAtom.getEffectiveArity(); if (!sourceProjectionAtom.getPredicate().equals(targetProjectionAtom.getPredicate()) || (arity != targetProjectionAtom.getEffectiveArity())) { return Optional.empty(); } else { ImmutableMap<Variable, Variable> newMap = FunctionalTools.zip( sourceProjectionAtom.getArguments(), targetProjectionAtom.getArguments()).stream() .distinct() .filter(e -> !e.getKey().equals(e.getValue())) .collect(ImmutableCollectors.toMap()); return Optional.of(substitutionFactory.getInjectiveVar2VarSubstitution(newMap)); } } }
private String extractPredicateIRI(IntermediateQuery mappingAssertion) { AtomPredicate projectionAtomPredicate = mappingAssertion.getProjectionAtom().getPredicate(); if (projectionAtomPredicate.equals(PredicateImpl.QUEST_TRIPLE_PRED)) throw new RuntimeException("TODO: extract the RDF predicate from a triple atom"); else return projectionAtomPredicate.getName(); }
/** * Hacked logic: because of ORDER conditions that are expected to use signature variables, * this method DOES NOT look for conflicts between signature variables and variables only appearing in the sub-tree. * * See the history for a better logic breaking this ugly hack. * * TODO: after getting rid of Datalog for encoding SPARQL queries, could try to clean it */ private IQ enforceSignature(IQ iq, ImmutableList<Variable> signature) { ImmutableList<Variable> projectedVariables = iq.getProjectionAtom().getArguments(); if (projectedVariables.equals(signature)) return iq; if (projectedVariables.size() != signature.size()) throw new IllegalArgumentException("The arity of the signature does not match the iq"); InjectiveVar2VarSubstitution renamingSubstitution = substitutionFactory.getInjectiveVar2VarSubstitution( IntStream.range(0, projectedVariables.size()) .boxed() .map(i -> Maps.immutableEntry(projectedVariables.get(i), signature.get(i))) .filter(e -> !e.getKey().equals(e.getValue())) .collect(ImmutableCollectors.toMap())); return queryTransformerFactory.createRenamer(renamingSubstitution) .transform(iq); }
@Override public void init(DistinctVariableOnlyDataAtom projectionAtom, QueryNode rootNode){ if (tree != null) throw new IllegalArgumentException("Already initialized IntermediateQueryBuilder."); if ((rootNode instanceof ExplicitVariableProjectionNode) && !projectionAtom.getVariables().equals(((ExplicitVariableProjectionNode)rootNode).getVariables())) { throw new IllegalArgumentException("The root node " + rootNode + " is not consistent with the projection atom " + projectionAtom); } // TODO: use Guice to construct this tree tree = new DefaultTree(rootNode); this.projectionAtom = projectionAtom; canEdit = true; }
@Override public DistinctVariableOnlyDataAtom applyToDistinctVariableOnlyDataAtom(DistinctVariableOnlyDataAtom dataAtom) throws ConversionException { ImmutableList<? extends ImmutableTerm> newArguments = apply(dataAtom.getArguments()); if (!newArguments.stream().allMatch(t -> t instanceof Variable)) { throw new ConversionException("The substitution applied to a DistinctVariableOnlyDataAtom has " + " produced some non-Variable arguments " + newArguments); } ImmutableList<Variable> variableArguments = (ImmutableList<Variable>) newArguments; if (variableArguments.size() == ImmutableSet.copyOf(variableArguments).size()) return atomFactory.getDistinctVariableOnlyDataAtom(dataAtom.getPredicate(), variableArguments); else { throw new ConversionException("The substitution applied a DistinctVariableOnlyDataAtom has introduced" + " redundant variables: " + newArguments); } }
private static ImmutableSubstitution<VariableOrGroundTerm> extractSubstitution(DistinctVariableOnlyDataAtom sourceAtom, DataAtom targetAtom) { if (!sourceAtom.getPredicate().equals(targetAtom.getPredicate())) { throw new IllegalStateException("Incompatible predicates"); } else if (sourceAtom.getEffectiveArity() != targetAtom.getEffectiveArity()) { throw new IllegalStateException("Different arities"); } ImmutableMap<Variable, VariableOrGroundTerm> newMap = FunctionalTools.zip( sourceAtom.getArguments(), (ImmutableList<VariableOrGroundTerm>) targetAtom.getArguments()).stream() .collect(ImmutableCollectors.toMap()); return SUBSTITUTION_FACTORY.getSubstitution(newMap); }
@Override public Optional<IntermediateQuery> getDefinition(AtomPredicate predicate) { IntermediateQuery query = definitions.get(predicate); return query != null && query.getProjectionAtom().getPredicate().getArity() == predicate.getArity()? Optional.of(query): Optional.empty(); }
private Variable getVarFromRDFAtom(DistinctVariableOnlyDataAtom atom, Position position) { switch (position) { case SUBJECT: return getRDFAtomPredicate(atom).getSubject(atom.getArguments()); case OBJECT: return getRDFAtomPredicate(atom).getObject(atom.getArguments()); case PROPERTY: return getRDFAtomPredicate(atom).getProperty(atom.getArguments()); default: throw new UnexpectedPositionException(position); } }
@Override public void init(DistinctVariableOnlyDataAtom projectionAtom, QueryNode rootNode){ if (tree != null) throw new IllegalArgumentException("Already initialized IntermediateQueryBuilder."); if ((rootNode instanceof ExplicitVariableProjectionNode) && !projectionAtom.getVariables().equals(((ExplicitVariableProjectionNode)rootNode).getVariables())) { throw new IllegalArgumentException("The root node " + rootNode + " is not consistent with the projection atom " + projectionAtom); } // TODO: use Guice to construct this tree tree = new DefaultTree(rootNode); this.projectionAtom = projectionAtom; canEdit = true; }
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); }