You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by rv...@apache.org on 2014/01/30 01:44:07 UTC

svn commit: r1562658 - in /jena/trunk/jena-arq/src: main/java/com/hp/hpl/jena/sparql/algebra/optimize/ main/java/com/hp/hpl/jena/sparql/expr/ test/java/com/hp/hpl/jena/sparql/algebra/ test/java/com/hp/hpl/jena/sparql/algebra/optimize/

Author: rvesse
Date: Thu Jan 30 00:44:06 2014
New Revision: 1562658

URL: http://svn.apache.org/r1562658
Log:
Add an experimental ExprTransformConstantFold which is an expression transformer that folds constants to simplify expressions (JENA-630)

This commit includes a change to ExprFunctionN to make the copy() method public to align with the other ExprFunction classes e.g. ExprFunction1.  It also fixes the logic for copySubstitute() for this class to try and fold the whole expression where possible.

Added:
    jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/optimize/ExprTransformConstantFold.java
    jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/algebra/optimize/TestTransformConstantFolding.java
Modified:
    jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_BNode.java
    jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_Call.java
    jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_Coalesce.java
    jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_Function.java
    jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_FunctionDynamic.java
    jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_NotOneOf.java
    jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_OneOf.java
    jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_Regex.java
    jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_StrConcat.java
    jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_StrReplace.java
    jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_StrSubstring.java
    jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/ExprFunctionN.java
    jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/algebra/TS_Algebra.java

Added: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/optimize/ExprTransformConstantFold.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/optimize/ExprTransformConstantFold.java?rev=1562658&view=auto
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/optimize/ExprTransformConstantFold.java (added)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/optimize/ExprTransformConstantFold.java Thu Jan 30 00:44:06 2014
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.hp.hpl.jena.sparql.algebra.optimize;
+
+import com.hp.hpl.jena.sparql.algebra.Op;
+import com.hp.hpl.jena.sparql.algebra.TransformCopy;
+import com.hp.hpl.jena.sparql.algebra.Transformer;
+import com.hp.hpl.jena.sparql.engine.binding.Binding;
+import com.hp.hpl.jena.sparql.expr.Expr;
+import com.hp.hpl.jena.sparql.expr.ExprFunction1;
+import com.hp.hpl.jena.sparql.expr.ExprFunction2;
+import com.hp.hpl.jena.sparql.expr.ExprFunction3;
+import com.hp.hpl.jena.sparql.expr.ExprFunctionN;
+import com.hp.hpl.jena.sparql.expr.ExprFunctionOp;
+import com.hp.hpl.jena.sparql.expr.ExprList;
+import com.hp.hpl.jena.sparql.expr.ExprTransformCopy;
+
+/**
+ * An expression transform that simplifies expressions by constant folding
+ * wherever possible
+ * 
+ */
+public class ExprTransformConstantFold extends ExprTransformCopy {
+
+    private Binding b = null;
+
+    @Override
+    public Expr transform(ExprFunction1 func, Expr expr1) {
+        return func.copySubstitute(this.b, true);
+    }
+
+    @Override
+    public Expr transform(ExprFunction2 func, Expr expr1, Expr expr2) {
+        return func.copySubstitute(this.b, true);
+    }
+
+    @Override
+    public Expr transform(ExprFunction3 func, Expr expr1, Expr expr2, Expr expr3) {
+        return func.copySubstitute(this.b, true);
+    }
+
+    @Override
+    public Expr transform(ExprFunctionN func, ExprList args) {
+        return func.copySubstitute(this.b, true);
+    }
+
+    @Override
+    public Expr transform(ExprFunctionOp funcOp, ExprList args, Op opArg) {
+        return funcOp.copySubstitute(this.b, true);
+    }
+
+}

Modified: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_BNode.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_BNode.java?rev=1562658&r1=1562657&r2=1562658&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_BNode.java (original)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_BNode.java Thu Jan 30 00:44:06 2014
@@ -89,7 +89,7 @@ public class E_BNode extends ExprFunctio
     { throw new ARQInternalErrorException() ; }
 
     @Override
-    protected Expr copy(ExprList newArgs)
+    public Expr copy(ExprList newArgs)
     {
         if ( newArgs.size() == 0 )
             return new E_BNode() ;

Modified: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_Call.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_Call.java?rev=1562658&r1=1562657&r2=1562658&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_Call.java (original)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_Call.java Thu Jan 30 00:44:06 2014
@@ -75,7 +75,7 @@ public class E_Call extends ExprFunction
      
     
     @Override
-    protected Expr copy(ExprList newArgs)       { return new E_Call(newArgs) ; }
+    public Expr copy(ExprList newArgs)       { return new E_Call(newArgs) ; }
 
     @Override
     public NodeValue eval(List<NodeValue> args, FunctionEnv env) {

Modified: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_Coalesce.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_Coalesce.java?rev=1562658&r1=1562657&r2=1562658&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_Coalesce.java (original)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_Coalesce.java Thu Jan 30 00:44:06 2014
@@ -50,7 +50,7 @@ public class E_Coalesce extends ExprFunc
     }
     
     @Override
-    protected Expr copy(ExprList newArgs)
+    public Expr copy(ExprList newArgs)
     {
         return new E_Coalesce(newArgs) ;
     }

Modified: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_Function.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_Function.java?rev=1562658&r1=1562657&r2=1562658&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_Function.java (original)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_Function.java Thu Jan 30 00:44:06 2014
@@ -130,7 +130,7 @@ public class E_Function extends ExprFunc
 
 
     @Override
-    protected Expr copy(ExprList newArgs)
+    public Expr copy(ExprList newArgs)
     {
         return new E_Function(getFunctionIRI(), newArgs) ;
     }

Modified: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_FunctionDynamic.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_FunctionDynamic.java?rev=1562658&r1=1562657&r2=1562658&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_FunctionDynamic.java (original)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_FunctionDynamic.java Thu Jan 30 00:44:06 2014
@@ -39,5 +39,5 @@ public class E_FunctionDynamic extends E
     }
     
     @Override
-    protected Expr copy(ExprList newArgs)       { return new E_FunctionDynamic(newArgs) ; }
+    public Expr copy(ExprList newArgs)       { return new E_FunctionDynamic(newArgs) ; }
 }

Modified: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_NotOneOf.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_NotOneOf.java?rev=1562658&r1=1562657&r2=1562658&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_NotOneOf.java (original)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_NotOneOf.java Thu Jan 30 00:44:06 2014
@@ -51,7 +51,7 @@ public class E_NotOneOf extends E_OneOfB
     { throw new ARQInternalErrorException() ; }
 
     @Override
-    protected Expr copy(ExprList newArgs)
+    public Expr copy(ExprList newArgs)
     {
         return new E_NotOneOf(newArgs) ;
     }

Modified: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_OneOf.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_OneOf.java?rev=1562658&r1=1562657&r2=1562658&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_OneOf.java (original)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_OneOf.java Thu Jan 30 00:44:06 2014
@@ -52,7 +52,7 @@ public class E_OneOf extends E_OneOfBase
     { throw new ARQInternalErrorException() ; }
     
     @Override
-    protected Expr copy(ExprList newArgs)
+    public Expr copy(ExprList newArgs)
     {
         return new E_OneOf(newArgs) ;
     }

Modified: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_Regex.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_Regex.java?rev=1562658&r1=1562657&r2=1562658&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_Regex.java (original)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_Regex.java Thu Jan 30 00:44:06 2014
@@ -121,7 +121,7 @@ public class E_Regex extends ExprFunctio
 //    public final Expr getFlags() { return expr3 ; }
 
     @Override
-    protected Expr copy(ExprList newArgs)
+    public Expr copy(ExprList newArgs)
     {
         if ( newArgs.size() == 2 )
             return new E_Regex(newArgs.get(0), newArgs.get(1), null) ; 

Modified: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_StrConcat.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_StrConcat.java?rev=1562658&r1=1562657&r2=1562658&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_StrConcat.java (original)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_StrConcat.java Thu Jan 30 00:44:06 2014
@@ -35,7 +35,7 @@ public class E_StrConcat extends ExprFun
     }
 
     @Override
-    protected Expr copy(ExprList newArgs)
+    public Expr copy(ExprList newArgs)
     {
         return new E_StrConcat(newArgs) ;
     }

Modified: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_StrReplace.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_StrReplace.java?rev=1562658&r1=1562657&r2=1562658&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_StrReplace.java (original)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_StrReplace.java Thu Jan 30 00:44:06 2014
@@ -57,7 +57,7 @@ public class E_StrReplace extends ExprFu
     }
 
     @Override
-    protected Expr copy(ExprList newArgs)
+    public Expr copy(ExprList newArgs)
     {
         if ( newArgs.size() == 3 )
             return new E_StrReplace(newArgs.get(0), newArgs.get(1), newArgs.get(2), null) ;

Modified: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_StrSubstring.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_StrSubstring.java?rev=1562658&r1=1562657&r2=1562658&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_StrSubstring.java (original)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_StrSubstring.java Thu Jan 30 00:44:06 2014
@@ -43,7 +43,7 @@ public class E_StrSubstring extends Expr
     }
 
     @Override
-    protected Expr copy(ExprList newArgs)
+    public Expr copy(ExprList newArgs)
     {
         if ( newArgs.size() == 2 )
             return new E_StrSubstring(newArgs.get(0), newArgs.get(1), null) ; 

Modified: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/ExprFunctionN.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/ExprFunctionN.java?rev=1562658&r1=1562657&r2=1562658&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/ExprFunctionN.java (original)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/ExprFunctionN.java Thu Jan 30 00:44:06 2014
@@ -21,6 +21,8 @@ package com.hp.hpl.jena.sparql.expr;
 import java.util.ArrayList ;
 import java.util.List ;
 
+import org.apache.jena.atlas.lib.ListUtils;
+
 import com.hp.hpl.jena.sparql.engine.binding.Binding ;
 import com.hp.hpl.jena.sparql.function.FunctionEnv ;
 import com.hp.hpl.jena.sparql.graph.NodeTransform ;
@@ -77,7 +79,24 @@ public abstract class ExprFunctionN exte
             e = e.copySubstitute(binding, foldConstants) ;
             newArgs.add(e) ;
         }
-        return copy(newArgs) ;
+        
+        if (!foldConstants) 
+            return copy(newArgs);
+        
+        // Can we fold the whole expression?
+        List<NodeValue> values = new ArrayList<NodeValue>();
+        for (Expr e : newArgs) {
+            // Can't fold if anything is null/non-constant
+            if (e == null || !e.isConstant()) return copy(newArgs);
+            values.add(e.getConstant());
+        }
+        
+        try {
+            // Try to fold whole expression
+            return eval(values);
+        } catch (ExprEvalException ex) {
+            return copy(newArgs);
+        }
     }
 
     @Override
@@ -116,7 +135,7 @@ public abstract class ExprFunctionN exte
 
     protected abstract NodeValue eval(List<NodeValue> args) ;
 
-    protected abstract Expr copy(ExprList newArgs) ;
+    public abstract Expr copy(ExprList newArgs) ;
     
     @Override
     public void visit(ExprVisitor visitor) { visitor.visit(this) ; }

Modified: jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/algebra/TS_Algebra.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/algebra/TS_Algebra.java?rev=1562658&r1=1562657&r2=1562658&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/algebra/TS_Algebra.java (original)
+++ jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/algebra/TS_Algebra.java Thu Jan 30 00:44:06 2014
@@ -33,6 +33,7 @@ import org.junit.runners.Suite ;
     , TestClassify.class
     , TestTransformFilters.class
     , TestTransformFilterPlacement.class
+    , TestTransformConstantFolding.class
     , TestTransformQuads.class
     , TestSemanticEquivalence.class
 

Added: jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/algebra/optimize/TestTransformConstantFolding.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/algebra/optimize/TestTransformConstantFolding.java?rev=1562658&view=auto
==============================================================================
--- jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/algebra/optimize/TestTransformConstantFolding.java (added)
+++ jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/algebra/optimize/TestTransformConstantFolding.java Thu Jan 30 00:44:06 2014
@@ -0,0 +1,85 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.hp.hpl.jena.sparql.algebra.optimize;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.hp.hpl.jena.sparql.algebra.Op;
+import com.hp.hpl.jena.sparql.algebra.TransformCopy;
+import com.hp.hpl.jena.sparql.algebra.Transformer;
+import com.hp.hpl.jena.sparql.expr.ExprTransform;
+import com.hp.hpl.jena.sparql.sse.SSE;
+
+/**
+ * Tests for the {@link ExprTransformConstantFold}
+ */
+public class TestTransformConstantFolding {
+    
+    private ExprTransform transform = new ExprTransformConstantFold();
+    
+    private void test(String input, ExprTransform transform) {
+        test(input, null, transform);
+    }
+    
+    private void test(String input, String expected, ExprTransform transform) {
+        Op opOrig = SSE.parseOp(input);
+        Op opExpected = SSE.parseOp(expected != null ? expected : input);
+        
+        Op opOptimized = Transformer.transform(new TransformCopy(), transform, opOrig);
+        
+        Assert.assertEquals(opExpected, opOptimized);
+    }
+    
+    @Test
+    public void constant_fold_extend_01() {
+        test("(extend (?x (+ 1 2)) (table unit))", "(extend (?x 3) (table unit))", transform);
+    }
+    
+    @Test
+    public void constant_fold_extend_02() {
+        test("(extend (?x (+ (+ 1 2) 3)) (table unit))", "(extend (?x 6) (table unit))", transform);
+    }
+    
+    @Test
+    public void constant_fold_extend_03() {
+        test("(extend (?x (/ 1 2)) (table unit))", "(extend (?x 0.5) (table unit))", transform);
+    }
+    
+    @Test
+    public void constant_fold_extend_04() {
+        // When an error occurs we don't fold
+        test("(extend (?x (/ 1 0)) (table unit))", "(extend (?x (/ 1 0)) (table unit))", transform);
+    }
+    
+    @Test
+    public void constant_fold_extend_05() {
+        test("(extend (?x (abs -1)) (table unit))", "(extend (?x 1) (table unit))", transform);
+    }
+    
+    @Test
+    public void constant_fold_extend_06() {
+        test("(extend (?x (regex 'something' 'thing')) (table unit))", "(extend (?x true) (table unit))", transform);
+    }
+    
+    @Test
+    public void constant_fold_extend_07() {
+        test("(extend (?x (coalesce (/ 1 0) 0)) (table unit))", transform);
+    }
+}