/** * Check if query cq1 is contained in cq2, syntactically. That is, if the * head of cq1 and cq2 are equal according to toString().equals and each * atom in cq2 is also in the body of cq1 (also by means of toString().equals(). */ private static boolean isContainedIn(CQIE cq1, CQIE cq2) { if (!cq2.getHead().equals(cq1.getHead())) return false; for (Function atom : cq2.getBody()) if (!cq1.getBody().contains(atom)) return false; return true; }
/** * This method will return a new query, resulting from the application of * the substitution function to the original query q. To do this, we will call the clone() * method of the original query and then will call applySubstitution to each atom * of the cloned query. * * @param q * @param substitution * @return */ public CQIE applySubstitution(CQIE q, Substitution substitution, boolean clone) { CQIE newq; if (clone) newq = q.clone(); else newq = q; Function head = newq.getHead(); applySubstitution(head, substitution); for (Function bodyatom : newq.getBody()) applySubstitution(bodyatom, substitution); return newq; }
/** * Rule-level variable generator. */ public VariableGenerator(CQIE initialRule) { count = 0; knownVariables = initialRule.getReferencedVariables(); }
public CQIE create() { //get the canonical version of the uri and useful columns CQIE canonicalMapping = uriMappingMap.get(templateURI); Function canonHead = canonicalMapping.getHead(); final Function templateCanURI = (Function) canonHead.getTerm(0); //get templateuri Function target = (Function) canonHead.getTerm(1); //get substitution Substitution subs = UnifierUtilities.getMGU(uriTerm, target); CQIE newMapping = SubstitutionUtilities.applySubstitution(mapping, subs, true); Function currentHead = newMapping.getHead(); currentHead.setTerm(termPosition.getPosition(), templateCanURI); List<Function> newURIBody = new ArrayList<>(); newURIBody.addAll(canonicalMapping.getBody()); //get body values from the new mapping that have not been added already from the body of the canonical mapping newURIBody.addAll(newMapping.getBody().stream() .filter(m -> !newURIBody.contains(m)) .collect(Collectors.toList())); newMapping.updateBody(newURIBody); return newMapping; } }
@Override public void removeRules(Collection<CQIE> rs) { for (CQIE rule : rs) { this.rules.remove(rule); Predicate predicate = rule.getHead().getFunctionSymbol(); List<CQIE> indexedRules = this.predicateIndex.get(predicate); if (indexedRules != null) indexedRules.remove(rule); } }
/** * High-level method. * * Returns a new normalized rule. */ @Override public CQIE normalizeByPullingOutEqualities(final CQIE initialRule) { CQIE newRule = initialRule.clone(); // Mutable object final VariableDispatcher variableDispatcher = new VariableDispatcher(initialRule); /** * Result for the top atoms of the rule. */ PullOutEqLocalNormResult result = normalizeSameLevelAtoms(List.iterableList(newRule.getBody()), variableDispatcher); newRule.updateBody(new ArrayList(result.getAllAtoms().toCollection())); return newRule; }
private void analyzeCanonicalIRIMappings(List<CQIE> rules) { for (CQIE rule : rules) { Function head = rule.getHead(); Predicate predicate = head.getFunctionSymbol(); if (predicate.isCanonicalIRIProperty()) { // we check for ontop:is_canonical_iri //rename all the variables to avoid conflicts while merging the mappings Set<Variable> variables = rule.getReferencedVariables(); Function headURI = (Function) head.getTerm(0); ValueConstant canonicalIRIName = (ValueConstant) headURI.getTerm(0); Function objectTerm = (Function) head.getTerm(1); ValueConstant objectURIName = (ValueConstant) objectTerm.getTerm(0); //get or assign a suffix for each canonicalIRI String rename = canIriVariablesSuffix.get(canonicalIRIName); if(rename ==null){ rename = "_canonical"+ canIriVariablesSuffix.size(); canIriVariablesSuffix.put(canonicalIRIName, rename); } final String finalRename = rename; Map<Variable, Term> map = variables.stream() .collect(Collectors.toMap( var -> var, var -> TERM_FACTORY.getVariable(var.getName() + finalRename))); //apply substitution for variables renaming Substitution substitution = new SubstitutionImpl(map); CQIE canonicalMapping = SubstitutionUtilities.applySubstitution(rule, substitution, true); //store the renamed mapping uriMappingMap.put(objectURIName, canonicalMapping); } } }
@Override public DatalogProgram clone() { DatalogProgramImpl clone = new DatalogProgramImpl(); for (CQIE query : rules) { clone.appendRule(query.clone()); } clone.modifiers = modifiers.clone(); return clone; }
public static boolean isBoolean(CQIE query) { return query.getHead().getArity() == 0; }
@Override public DatalogProgram clone() { DatalogProgramImpl clone = new DatalogProgramImpl(); for (CQIE query : rules) { clone.appendRule(query.clone()); } clone.modifiers = modifiers.clone(); return clone; }
/** * Check if query cq1 is contained in cq2, syntactically. That is, if the * head of cq1 and cq2 are equal according to toString().equals and each * atom in cq2 is also in the body of cq1 (also by means of toString().equals(). */ @Override public boolean isContainedIn(CQIE cq1, CQIE cq2) { if (!cq2.getHead().equals(cq1.getHead())) return false; for (Function atom : cq2.getBody()) if (!cq1.getBody().contains(atom)) return false; return true; }
/** * This method will return a new query, resulting from the application of * the substitution function to the original query q. To do this, we will call the clone() * method of the original query and then will call applySubstitution to each atom * of the cloned query. * * @param q * @param substitution * @return */ public static CQIE applySubstitution(CQIE q, Substitution substitution, boolean clone) { CQIE newq; if (clone) newq = q.clone(); else newq = q; Function head = newq.getHead(); applySubstitution(head, substitution); for (Function bodyatom : newq.getBody()) applySubstitution(bodyatom, substitution); return newq; }
public static boolean isBoolean(CQIE query) { return query.getHead().getArity() == 0; }
public AliasIndex(CQIE query, ImmutableMap<Predicate, FromItem> subQueryDefinitions) { for (Function atom : query.getBody()) { // This will be called recursively if necessary generateViewsIndexVariables(atom, subQueryDefinitions); } }
private IQ preProcess(InternalSparqlQuery translation) throws OntopInvalidInputQueryException, EmptyQueryException { DatalogProgram program = translation.getProgram(); log.debug("Datalog program translated from the SPARQL query: \n{}", program); if(settings.isSameAsInMappingsEnabled()){ program = sameAsRewriter.getSameAsRewriting(program); log.debug("Datalog program after SameAs rewriting \n{}", program); } log.debug("Replacing equivalences..."); DatalogProgram newprogramEq = datalogFactory.getDatalogProgram(program.getQueryModifiers()); for (CQIE query : program.getRules()) { CQIE rule = query.clone(); // EQNormalizer cannot be removed because it is used in NULL propagation in OPTIONAL eqNormalizer.enforceEqualities(rule); newprogramEq.appendRule(rule); } if (newprogramEq.getRules().isEmpty()) throw new OntopInvalidInputQueryException("Error, the translation of the query generated 0 rules. " + "This is not possible for any SELECT query (other queries are not supported by the translator)."); return datalogConverter.convertDatalogProgram(newprogramEq, ImmutableList.of(), translation.getSignature()); }
private Substitution computeHomomorphism(CQIE query) { SubstitutionBuilder sb = new SubstitutionBuilder(termFactory); // get the substitution for the head first // it will ensure that all answer variables are mapped either to constants or // to answer variables in the base (but not to the labelled nulls generated by the chase) boolean headResult = extendHomomorphism(sb, query.getHead(), head); if (!headResult) return null; Substitution sub = computeSomeHomomorphism(sb, query.getBody(), factMap); return sub; } }