All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.aksw.jena_sparql_api.utils.ExprUtils Maven / Gradle / Ivy

The newest version!
package org.aksw.jena_sparql_api.utils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

import org.aksw.commons.collections.CollectionFromIterable;
import org.aksw.commons.collections.trees.Tree;
import org.aksw.commons.collections.trees.TreeImpl;
import org.aksw.commons.util.Pair;
import org.apache.jena.ext.com.google.common.collect.Maps;
import org.apache.jena.graph.Node;
import org.apache.jena.sparql.core.Var;
import org.apache.jena.sparql.expr.E_Equals;
import org.apache.jena.sparql.expr.E_LogicalAnd;
import org.apache.jena.sparql.expr.E_LogicalOr;
import org.apache.jena.sparql.expr.E_NotOneOf;
import org.apache.jena.sparql.expr.E_OneOf;
import org.apache.jena.sparql.expr.Expr;
import org.apache.jena.sparql.expr.ExprFunction;
import org.apache.jena.sparql.expr.ExprList;
import org.apache.jena.sparql.expr.ExprTransformer;
import org.apache.jena.sparql.expr.ExprVar;
import org.apache.jena.sparql.expr.FunctionLabel;
import org.apache.jena.sparql.expr.NodeValue;
import org.apache.jena.sparql.graph.NodeTransform;
import org.apache.jena.sparql.graph.NodeTransformExpr;
import org.apache.jena.sparql.graph.NodeTransformLib;


/**
 * @author Claus Stadler
 *         

* Date: 1/8/12 * Time: 6:18 PM */ public class ExprUtils { /** * Test whether a node and an expression represent the same value * * @param node * @param expr * @return */ public static boolean isSame(Node node, Expr expr) { boolean result = node.isVariable() ? expr.isVariable() && node.equals(expr.asVar()) : node.isConcrete() ? expr.isConstant() && node.equals(expr.getConstant().asNode()) : false; return result; } /** * Node transform version that * (a) handles blank nodes correctly; in constrast to Expr.applyNodeTransform * [disabled (b) treats null mappings as identity mapping] * * * * @return */ public static Expr applyNodeTransform(Expr expr, NodeTransform xform) { Expr result = ExprTransformer.transform(new NodeTransformExpr(node -> { Node r = xform.apply(node); //Node r = Optional.ofNullable(xform.apply(node)).orElse(node); return r; }), expr); return result; } /** * A variable-aware version of NodeValue.makeNode(Node node) * * @param node * @return */ public static Expr makeNode(Node node) { Expr result = node.isVariable() ? new ExprVar(node.getName()) : NodeValue.makeNode(node); return result; } public static E_OneOf oneOf(Node v, Iterable args) { ExprList el = new ExprList(); el.addAll(ExprListUtils.nodesToExprs(args)); Expr base = v.isVariable() ? new ExprVar(v) : NodeValue.makeNode(v); return new E_OneOf(base, el); } public static E_OneOf oneOf(Node v, Node ... args) { return oneOf(v, Arrays.asList(args)); } public static E_NotOneOf notOneOf(Node v, Collection args) { ExprList el = new ExprList(); el.addAll(ExprListUtils.nodesToExprs(args)); Expr base = v.isVariable() ? new ExprVar(v) : NodeValue.makeNode(v); return new E_NotOneOf(base, el); } public static E_NotOneOf notOneOf(Node v, Node ... args) { return notOneOf(v, Arrays.asList(args)); } public static Entry tryGetVarConst(Expr a, Expr b) { Var v = a.isVariable() ? a.asVar() // Hack to unwrap variables from NodeValue : Optional.of(a).filter(Expr::isConstant) .map(Expr::getConstant).map(NodeValue::asNode).filter(Node::isVariable).map(n -> (Var)n) .orElse(null) ; Entry result = v != null && b.isConstant() ? Maps.immutableEntry(v, b.getConstant().asNode()) : null ; return result; } public static Entry tryGetVarVar(Expr e) { Entry result = null; if(e.isFunction()) { ExprFunction fn = e.getFunction(); List args = fn.getArgs(); if(args.size() == 2) { Expr a = args.get(0); Expr b = args.get(1); result = tryGetVarVar(a, b); if(result == null) { result = tryGetVarVar(b, a); } } } return result; } public static Entry tryGetVarVar(Expr a, Expr b) { Entry result = a.isVariable() && b.isVariable() ? Maps.immutableEntry(a.asVar(), b.asVar()) : null; return result; } public static Entry tryGetVarConst(Expr e) { Entry result = null; if(e.isFunction()) { ExprFunction fn = e.getFunction(); List args = fn.getArgs(); if(args.size() == 2) { Expr a = args.get(0); Expr b = args.get(1); result = tryGetVarConst(a, b); if(result == null) { result = tryGetVarConst(b, a); } } } return result; } public static int classify(Expr e) { int result = e.isConstant() ? 0 : e.isVariable() ? 1 : e.isFunction() ? 2 : 3; return result; } public static int compare(Expr a, Expr b) { int ca = classify(a); int cb = classify(b); int r = cb - ca; if(r == 0) { switch(ca) { case 0: r = NodeValue.compare(a.getConstant(), b.getConstant()); break; case 1: r = a.getVarName().compareTo(b.getVarName()); break; case 2: r = a.getFunction().getFunctionIRI().compareTo(b.getFunction().getFunctionIRI()); break; default: throw new RuntimeException("should not come here"); } } return r; } public static Tree createTree(Expr root) { Tree result = TreeImpl.create(root, ExprUtils::getSubExprs); return result; } public static boolean isConstantsOnly(Iterable exprs) { for(Expr expr : exprs) { if(!expr.isConstant()) { return false; } } return true; } /** * Checks wtherer all arguments of the given function are constants (non-recursive). * * @param fn The function to test * @return True if all arguments are constants, false otherwise. */ public static boolean isConstantArgsOnly(ExprFunction fn) { if(fn == null) { throw new RuntimeException("Null argument should not happen here"); } boolean result = isConstantsOnly(fn.getArgs()); return result; } public static String getFunctionId(ExprFunction fn) { String result = null; result = fn.getOpName(); if(result != null) { return result; } result = fn.getFunctionIRI(); if(result != null) { return result; } FunctionLabel label = fn.getFunctionSymbol(); result = label == null ? null : label.getSymbol(); /* if(result != null) { return result; }*/ return result; } public static int countLeafs(T parent, Function> nodeToChildren) { Collection children = nodeToChildren.apply(parent); int result = children.isEmpty() ? 1 : children.stream() .mapToInt(c -> countLeafs(c, nodeToChildren)).sum(); return result; } public static int countLeafs(Expr expr) { int result = countLeafs(expr, ExprUtils::getSubExprs); return result; } /** * linearize any structure into a flat list * * @param op * @param stopMarker * @param getChildren * @return */ public static Stream linearizePrefix(T op, Collection stopMarker, Function> getChildren) { // boolean isIdentity = op == stopMarker || (stopMarker != null && stopMarker.equals(op)); Stream result; if(op == null) { result = Stream.empty(); } else { Iterable children = getChildren.apply(op); Stream x = StreamSupport.stream(children.spliterator(), false); //tmp = Stream.concat(x, stopMarker.stream()); // Stream.of(stopMarker) // tmp = Stream.concat(tmp, Stream.of(op)); result = Stream.concat( Stream.concat( StreamSupport.stream(children.spliterator(), false).flatMap(e -> linearizePrefix(e, stopMarker, getChildren)), stopMarker.stream() ), Stream.of(op) // Emit parent ); } return result; } /** * Traverse the expr * * @param expr * @return */ public static Stream linearizePrefix(Expr expr, Collection stopMarkers) { Stream result = linearizePrefix(expr, stopMarkers, ExprUtils::getSubExprs); return result; // boolean isIdentity = expr == identity || (identity != null && identity.equals(expr)); // Stream tmp; // if(isIdentity) { // tmp = Stream.empty(); // } else { // List children = getSubExprs(expr); // tmp = Stream.concat(children.stream(), Stream.of(identity)); // } // // Stream result = Stream.concat( // tmp.flatMap(e -> linearizePrefix(e, identity)), // Stream.of(expr)); // Emit parent); // // return result; } public static void main(String[] args) { // + ( +(?a ?b) (?c) ) System.out.println(linearizePrefix(org.apache.jena.sparql.util.ExprUtils.parse("?a + ?b + ?c"), null).collect(Collectors.toList())); } /** * Replace all variable names with the same variable (?a in this case). * Useful for checking whether two expressions are structurally equivalent. * * @param expr */ public static Expr signaturize(Expr expr) { NodeTransform nodeTransform = new NodeTransformSignaturize(); Expr result = NodeTransformLib.transform(nodeTransform, expr); return result; } public static Expr signaturize(Expr expr, Map nodeMap) { NodeTransform baseTransform = new NodeTransformRenameMap(nodeMap); NodeTransform nodeTransform = new NodeTransformSignaturize(baseTransform); Expr result = NodeTransformLib.transform(nodeTransform, expr); return result; } public static Expr applyNodeTransform(Expr expr, Map nodeMap) { NodeTransform nodeTransform = new NodeTransformRenameMap(nodeMap); Expr result = NodeTransformLib.transform(nodeTransform, expr); //Expr result = applyNodeTransform(expr, nodeTransform); return result; } // public static Expr applyNodeTransform(Expr expr, NodeTransform nodeTransform) { // ElementTransform elementTransform = new ElementTransformSubst2(nodeTransform); // ExprTransform exprTransform = new ExprTransformNodeElement(nodeTransform, elementTransform); // // Expr result = ExprTransformer.transform(exprTransform, expr); // return result; // } public static Expr andifyBalanced(Expr ... exprs) { return andifyBalanced(Arrays.asList(exprs)); } public static Expr orifyBalanced(Expr... exprs) { return orifyBalanced(Arrays.asList(exprs)); } public static List extractNames(Collection vars) { List result = new ArrayList(); for(Var var : vars) { result.add(var.getName()); } return result; } public static Expr andifyBalanced(Iterable exprs) { Expr result = opifyBalanced(exprs, (a, b) -> new E_LogicalAnd(a, b)); return result; } // todo: isn't that a ring structure? public static T distribute( List as, List bs, BinaryOperator innerJunctor, BinaryOperator outerJunctor) { List items = new ArrayList<>(bs.size()); for(T a : as) { for(T b : bs) { T item = innerJunctor.apply(a, b); items.add(item); } } T result = opifyBalanced(items, outerJunctor); return result; } public static Optional opify(Iterable exprs, BinaryOperator exprFactory) { Optional result; Iterator it = exprs.iterator(); if(!it.hasNext()) { result = Optional.empty(); } else { T tmp = it.next(); while(it.hasNext()) { T b = it.next(); tmp = exprFactory.apply(tmp, b); } result = Optional.of(tmp); } return result; } /** * Concatenates the sub exressions using a binary operator * * and(and(0, 1), and(2, 3)) * * @param exprs * @return */ public static T opifyBalanced(Iterable exprs, BiFunction exprFactory) {//BinaryOperator exprFactory) { if(exprs.iterator().hasNext() == false) { //isEmpty()) { return null; } List current = new ArrayList(CollectionFromIterable.wrap(exprs)); while(current.size() > 1) { List next = new ArrayList(); T left = null; for(T expr : current) { if(left == null) { left = expr; } else { T newExpr = exprFactory.apply(left, expr); next.add(newExpr); left = null; } } if(left != null) { next.add(left); } current.clear(); List tmp = current; current = next; next = tmp; } return current.get(0); } public static Expr orifyBalanced(Iterable exprs) { Expr result = opifyBalanced(exprs, (a, b) -> new E_LogicalOr(a, b)); return result; } public static Entry extractConstantConstraint(Expr expr) { if(expr instanceof E_Equals) { E_Equals e = (E_Equals)expr; return extractVarConstant(e.getArg1(), e.getArg2()); } return null; } public static Entry extractVarConstant(Expr expr) { Entry result = null; if(expr instanceof ExprFunction) { ExprFunction f = expr.getFunction(); if(f.numArgs() == 2) { Expr a = f.getArg(1); Expr b = f.getArg(2); result = extractVarConstant(a, b); } } return result; } public static Pair extractVarConstant(Expr a, Expr b) { Pair result = extractVarConstantDirected(a, b); if(result == null) { result = extractVarConstantDirected(b, a); } return result; } /* public static void extractConstantConstraints(Expr a, Expr b, EquiMap equiMap) { extractConstantConstraints(a, b, equiMap.getKeyToValue()); }*/ /** * If a is a variable and b is a constant, then a mapping of the variable to the * constant is put into the map, and true is returned. * Otherwise, nothing is changed, and false is returned. * * A mapping of a variable is set to null, if it is mapped to multiple constants * * * @param a * @param b * @return */ public static Pair extractVarConstantDirected(Expr a, Expr b) { if(!(a.isVariable() && b.isConstant())) { return null; } Var var = a.getExprVar().asVar(); NodeValue nodeValue = b.getConstant(); return Pair.create(var, nodeValue); } public static List getSubExprs(Expr expr) { List result = expr != null && expr.isFunction() ? expr.getFunction().getArgs() : Collections.emptyList() ; return result; } @Deprecated public static Collection getSubExpressions(Expr expr, boolean reflexive) { Set result = new HashSet(); if(reflexive) { result.add(expr); } getSubExpressions(expr, result); return result; } @Deprecated public static void getSubExpressions(Expr expr, Set result) { if(expr.isFunction()) { ExprFunction f = (ExprFunction)expr; for(int i = 1; i <= f.numArgs(); ++i) { Expr arg = f.getArg(i); if(!result.contains(arg)) { result.add(arg); getSubExpressions(arg, result); } } } } /* public static boolean extractConstantConstraintsDirected(Expr a, Expr b, EquiMap equiMap) { return extractConstantConstraintsDirected(a, b, equiMap.getKeyToValue()); }*/ }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy