@Override public boolean composeFunctions(Function first, Function second) { // Basic case: if predicates are different or their arity is different, // then no unifier if ((first.getArity() != second.getArity() || !first.getFunctionSymbol().equals(second.getFunctionSymbol()))) { return false; } Function firstAtom = (Function) first.clone(); Function secondAtom = (Function) second.clone(); int arity = first.getArity(); // Computing the disagreement set for (int termidx = 0; termidx < arity; termidx++) { // Checking if there are already substitutions calculated for the // current terms. If there are any, then we have to take the // substituted terms instead of the original ones. Term term1 = firstAtom.getTerm(termidx); Term term2 = secondAtom.getTerm(termidx); if (!composeTerms(term1, term2)) return false; // Applying the newly computed substitution to the 'replacement' of // the existing substitutions SubstitutionUtilities.applySubstitution(firstAtom, this, termidx + 1); SubstitutionUtilities.applySubstitution(secondAtom, this, termidx + 1); } return true; }
private ImmutableList<Function> getHaving(List<Function> body) { for (Function atom : body) { if (atom.getFunctionSymbol() == DatalogAlgebraOperatorPredicates.SPARQL_HAVING) { return convert(atom.getTerms()); } } return ImmutableList.of(); }
private void deleteExplicitTypes(Term term, Function atom, int position) { if(term instanceof Function){ Function castTerm = (Function) term; IntStream.range(0, castTerm.getArity()) .forEach(i -> deleteExplicitTypes( castTerm.getTerm(i), castTerm, i )); if(castTerm.isDataTypeFunction()){ atom.setTerm(position, castTerm.getTerm(0)); } } }
private Function negation(Function arg) { return (arg.getFunctionSymbol() == ExpressionOperation.NOT) ? (Function) arg.getTerm(0) : termFactory.getFunctionNOT(arg); }
private Term evalIsLiteral(Function term) { Term innerTerm = term.getTerm(0); if (innerTerm instanceof Function) { Function function = (Function) innerTerm; return TERM_FACTORY.getBooleanConstant(function.isDataTypeFunction()); } else { return term; } }
List<Term> terms = atom.getTerms(); for (int i = 0; i < terms.size(); i++) { Term t = terms.get(i); if (t2.getFunctionSymbol() == ExpressionOperation.EQ && ! ((atom.getTerm(0) instanceof Function) && (atom.getTerm(1) instanceof Function))) { if (!mgu.composeTerms(t2.getTerm(0), t2.getTerm(1))) continue; if (t2.getFunctionSymbol() == ExpressionOperation.AND) { nestedEQSubstitutions(t2, mgu); if (t2.getTerms().isEmpty()) { terms.remove(i); i--; if (t2.getTerms().size() == 1) { atom.setTerm(i, t2.getTerm(0));
Predicate predicate = atom.getFunctionSymbol(); Predicate functionSymbol = function.getFunctionSymbol(); if (function.isDataTypeFunction() || (functionSymbol instanceof URITemplatePredicate) || (functionSymbol instanceof BNodePredicate)) { else if (function.isOperation()) { for (int i = 0; i < function.getArity(); i++) { insertVariableDataTyping(function.getTerm(i), function, i, termOccurenceIndex); "inferred " + "from the database"); atom.setTerm(position, newTerm); } else if (term instanceof ValueConstant) { Term newTerm = TERM_FACTORY.getTypedTerm(term, ((ValueConstant) term).getType()); atom.setTerm(position, newTerm); } else { throw new IllegalArgumentException("Unsupported subtype of: " + Term.class.getSimpleName());
/** * Collects (recursively) the set of variables that participate in data atoms * (either in this atom directly or in nested ones, excluding those on the * right-hand side of left joins. * * @param vars * @param atom * @return */ private void collectVariableReferencesWithLeftJoin(Set<Variable> vars, Function atom) { if (atom.isDataFunction()) { TermUtils.addReferencedVariablesTo(vars, atom); } else if (atom.isAlgebraFunction()) { Predicate functionSymbol = atom.getFunctionSymbol(); if (functionSymbol == DatalogAlgebraOperatorPredicates.SPARQL_JOIN) { // if it's a join, we need to collect all the variables of each nested atom convert(atom.getTerms()).stream() .filter(f -> !f.isOperation()) .forEach(f -> collectVariableReferencesWithLeftJoin(vars, f)); } else if (functionSymbol == DatalogAlgebraOperatorPredicates.SPARQL_LEFTJOIN) { // if it's a left join, only of the first data/algebra atom (the left atom) collectVariableReferencesWithLeftJoin(vars, (Function) atom.getTerm(0)); } } }
/** * updates * * @param rule */ public void updateRuleIndexByBodyPredicate(CQIE rule) { for (Function bodyAtom : rule.getBody()) { if (bodyAtom.isDataFunction()) { Predicate functionSymbol = bodyAtom.getFunctionSymbol(); if (!ruleIndexByBodyPredicate.containsEntry(functionSymbol, rule)){ ruleIndexByBodyPredicate.put(functionSymbol, rule); } } else if (bodyAtom.isAlgebraFunction() || bodyAtom.isOperation()) { updateRuleIndexByBodyPredicate_traverseBodyAtom(rule, bodyAtom); // BC: should we reintroduce arithmetic functions? //} else if (bodyAtom.isArithmeticFunction() || bodyAtom.isDataTypeFunction()){ } else if (bodyAtom.isDataTypeFunction()){ continue; } else { throw new IllegalStateException("Unknown Function"); } } }
/** * Returns a string with boolean conditions formed with the boolean atoms * found in the atoms list. */ private Set<String> getBooleanConditions(List<Function> atoms, AliasIndex index) { Set<String> conditions = new LinkedHashSet<>(); for (Function atom : atoms) { if (atom.isOperation()) { // Boolean expression if (atom.getFunctionSymbol() == ExpressionOperation.AND) { // flatten ANDs for (Term t : atom.getTerms()) { Set<String> arg = getBooleanConditions(ImmutableList.of((Function)t), index); conditions.addAll(arg); } } else { String condition = getSQLCondition(atom, index); conditions.add(condition); } } else if (atom.isDataTypeFunction()) { String condition = getSQLString(atom, index, false); conditions.add(condition); } } return conditions; }
private Term evalStr(Function term) { Term innerTerm = term.getTerm(0); if (innerTerm instanceof Function) { Function function = (Function) innerTerm; Predicate predicate = function.getFunctionSymbol(); Term parameter = function.getTerm(0); if (function.isDataTypeFunction()) { if (TYPE_FACTORY.isString(predicate) ) { // R: was datatype.equals(OBDAVocabulary.RDFS_LITERAL_URI) return TERM_FACTORY.getTypedTerm( TERM_FACTORY.getVariable(parameter.toString()), COL_TYPE.STRING); } else { return TERM_FACTORY.getTypedTerm( TERM_FACTORY.getFunctionCast(TERM_FACTORY.getVariable(parameter.toString()), TERM_FACTORY.getConstantLiteral(TYPE_FACTORY.getDatatypeURI(COL_TYPE.STRING).stringValue())), COL_TYPE.STRING); } } else if (predicate instanceof URITemplatePredicate) { return TERM_FACTORY.getTypedTerm(function.clone(), COL_TYPE.STRING); } else if (predicate instanceof BNodePredicate) { return TermConstants.NULL; } } return term; }
/** * check if the term is {@code URI("http://www.w3.org/1999/02/22-rdf-syntax-ns#type")} */ private static boolean isURIRDFType(Term term) { if (term instanceof Function) { Function func = (Function) term; if (func.getArity() == 1 && (func.getFunctionSymbol() instanceof URITemplatePredicate)) { Term t0 = func.getTerm(0); if (t0 instanceof ValueConstant) return ((ValueConstant) t0).getValue().equals(IriConstants.RDF_TYPE); } } return false; }
private Function getFreshAtom(Function a, String suffix) { List<Term> termscopy = new ArrayList<>(a.getArity()); for (Term t : a.getTerms()) { if (t instanceof Variable) { Variable v = (Variable)t; termscopy.add(termFactory.getVariable(v.getName() + suffix)); } else termscopy.add(t.clone()); } return termFactory.getFunction(a.getFunctionSymbol(), termscopy); }
/**** * Gets all the variables that are defined in this list of atoms, except in * atom i * * @param atoms * @return */ private static Set<Variable> getDefinedVariables(List<Term> atoms) { Set<Variable> currentLevelVariables = new HashSet<>(); for (Term l : atoms) { Function atom = (Function) l; if (atom.isOperation()) { continue; } else if (atom.isAlgebraFunction()) { currentLevelVariables.addAll(getDefinedVariables(atom.getTerms())); } else { TermUtils.addReferencedVariablesTo(currentLevelVariables, atom); } } return currentLevelVariables; }
private Term evalIsNumeric(Function term) { Term innerTerm = term.getTerm(0); if (innerTerm instanceof Function) { Function function = (Function) innerTerm; return termFactory.getBooleanConstant(function.isDataTypeFunction() && isNumeric(function.getFunctionSymbol())); } else { return term; } }
private Function replaceConstants(Function a, List<Function> filters) { Function atom = (Function)a.clone(); for (int i = 0; i < atom.getTerms().size(); i++) { Term term = atom.getTerm(i); if (term instanceof Constant) { // Found a constant, replacing with a fresh variable // and adding the new equality atom Constant c = (Constant)term; Variable var = valueMap.get(c); if (var == null) { freshVarCount++; var = termFactory.getVariable("?FreshVar" + freshVarCount); valueMap.put(c, var); filters.add(termFactory.getFunctionEQ(var, c)); } atom.setTerm(i, var); } } return atom; }
private Set<String> getEqConditionsForConstants(List<Function> atoms, AliasIndex index) { Set<String> equalities = new LinkedHashSet<>(); for (Function atom : atoms) { if (atom.isDataFunction()) { for (int i = 0; i < atom.getArity(); i++) { Term t = atom.getTerm(i); if (t instanceof Constant) { String value = getSQLString(t, index, false); QualifiedAttributeID column = index.getColumn(atom, i); equalities.add(String.format("(%s = %s)", column.getSQLRendering(), value)); } } } } return equalities; }
/** * Extracts all the data atoms (without preserving the algebraic structure) */ private static Stream<Function> extractDataAtoms(Collection<? extends Term> atoms) { return atoms.stream() .filter(t -> t instanceof Function) .map(f -> (Function) f) .flatMap(a -> { if (a.isDataFunction()) { return Stream.of(a); } else if (a.isAlgebraFunction()) { return extractDataAtoms(a.getTerms()); } else { return Stream.empty(); } }); }
private Term evalRegexSingleExpression(Term expr){ if (expr instanceof Function) { Function function1 = (Function) expr; Predicate predicate1 = function1.getFunctionSymbol(); if((predicate1 instanceof URITemplatePredicate) ||(predicate1 instanceof BNodePredicate)) { return TermConstants.FALSE; } if (!function1.isDataTypeFunction()){ return evalRegexSingleExpression( eval(expr)); } } return expr; }
/** * Determines if it is a unary function. */ private boolean isUnary(Function fun) { return fun.getArity() == 1; }