Repository: jena
Updated Branches:
  refs/heads/master 84f3b6734 -> bfee7682d


JENA-1155: Add math: functions.


Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/f7a23ef7
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/f7a23ef7
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/f7a23ef7

Branch: refs/heads/master
Commit: f7a23ef79b543d3a7b69edf94593f49ec3e9fc96
Parents: 106aae5
Author: Andy Seaborne <[email protected]>
Authored: Tue Mar 8 15:45:19 2016 +0000
Committer: Andy Seaborne <[email protected]>
Committed: Tue Mar 8 18:49:26 2016 +0000

----------------------------------------------------------------------
 .../org/apache/jena/sparql/ARQConstants.java    |   4 +
 .../org/apache/jena/sparql/expr/NodeValue.java  |   1 +
 .../jena/sparql/expr/nodevalue/XSDFuncOp.java   |  14 +-
 .../jena/sparql/function/StandardFunctions.java | 162 ++++++++++++++++++-
 .../sparql/function/library/Math_atan2.java     |  37 +++++
 .../jena/sparql/function/library/Math_exp.java  |  32 ++++
 .../sparql/function/library/Math_exp10.java     |  48 ++++++
 .../jena/sparql/function/library/Math_log.java  |  31 ++++
 .../sparql/function/library/Math_log10.java     |  31 ++++
 .../jena/sparql/function/library/Math_pow.java  |  59 +++++++
 .../sparql/function/library/evenInteger.java    |   1 -
 .../org/apache/jena/sparql/graph/NodeConst.java |   1 +
 .../apache/jena/sparql/expr/LibTestExpr.java    | 114 +++++++++++++
 .../org/apache/jena/sparql/expr/TS_Expr.java    |   2 +-
 .../jena/sparql/expr/TestExpressions2.java      |   6 +-
 .../jena/sparql/expr/TestExpressionsMath.java   |  95 +++++++++++
 .../sparql/expr/TestLeviathanFunctions.java     | 123 ++++----------
 .../apache/jena/sparql/expr/TestXSDFuncOp.java  |   7 +-
 18 files changed, 648 insertions(+), 120 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jena/blob/f7a23ef7/jena-arq/src/main/java/org/apache/jena/sparql/ARQConstants.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/ARQConstants.java 
b/jena-arq/src/main/java/org/apache/jena/sparql/ARQConstants.java
index 4a46d21..d5cf1cc 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/ARQConstants.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/ARQConstants.java
@@ -37,6 +37,9 @@ public class ARQConstants
     /** The prefix of XQuery/Xpath functions and operator */
     public static final String fnPrefix = 
"http://www.w3.org/2005/xpath-functions#"; ;
     
+    /** The prefix of XQuery/Xpath functions and operator math: */
+    public static final String mathPrefix = 
"http://www.w3.org/2005/xpath-functions/math#"; ;
+    
     /** RDF namespace prefix */
     public static final String rdfPrefix = RDF.getURI() ;
 
@@ -102,6 +105,7 @@ public class ARQConstants
         globalPrefixMap.setNsPrefix("xsd",  xsdPrefix) ;
         globalPrefixMap.setNsPrefix("owl" , owlPrefix) ;
         globalPrefixMap.setNsPrefix("fn" ,  fnPrefix) ; 
+        globalPrefixMap.setNsPrefix("math" ,  mathPrefix) ;
         globalPrefixMap.setNsPrefix("afn",  ARQFunctionLibraryURI) ;
         globalPrefixMap.setNsPrefix("apf",  ARQPropertyFunctionLibraryURI) ;
     }

http://git-wip-us.apache.org/repos/asf/jena/blob/f7a23ef7/jena-arq/src/main/java/org/apache/jena/sparql/expr/NodeValue.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/NodeValue.java 
b/jena-arq/src/main/java/org/apache/jena/sparql/expr/NodeValue.java
index 4267345..dd149d6 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/NodeValue.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/NodeValue.java
@@ -128,6 +128,7 @@ public abstract class NodeValue extends ExprNode
     
     public static final NodeValue nvZERO = 
NodeValue.makeNode(NodeConst.nodeZero) ;
     public static final NodeValue nvONE  = 
NodeValue.makeNode(NodeConst.nodeOne) ;
+    public static final NodeValue nvTEN  = 
NodeValue.makeNode(NodeConst.nodeTen) ;
     
     public static final NodeValue nvNaN     = NodeValue.makeNode("NaN", 
XSDdouble) ;
     public static final NodeValue nvINF     = NodeValue.makeNode("INF", 
XSDdouble) ;

http://git-wip-us.apache.org/repos/asf/jena/blob/f7a23ef7/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/XSDFuncOp.java
----------------------------------------------------------------------
diff --git 
a/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/XSDFuncOp.java 
b/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/XSDFuncOp.java
index ce55719..7d95c12 100644
--- 
a/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/XSDFuncOp.java
+++ 
b/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/XSDFuncOp.java
@@ -328,19 +328,7 @@ public class XSDFuncOp
     }
 
     public static NodeValue sqrt(NodeValue v) {
-        switch (classifyNumeric("sqrt", v)) {
-            case OP_INTEGER :
-            case OP_DECIMAL :
-                double dec = v.getDecimal().doubleValue() ;
-                return NodeValue.makeDecimal(Math.sqrt(dec)) ;
-            case OP_FLOAT :
-                // NB - returns a double
-                return NodeValue.makeDouble(Math.sqrt(v.getDouble())) ;
-            case OP_DOUBLE :
-                return NodeValue.makeDouble(Math.sqrt(v.getDouble())) ;
-            default :
-                throw new ARQInternalErrorException("Unrecognized numeric 
operation : " + v) ;
-        }
+        return NodeValue.makeDouble(Math.sqrt(v.getDouble())) ;
     }
    
     // NB Java string start from zero and uses start/end

http://git-wip-us.apache.org/repos/asf/jena/blob/f7a23ef7/jena-arq/src/main/java/org/apache/jena/sparql/function/StandardFunctions.java
----------------------------------------------------------------------
diff --git 
a/jena-arq/src/main/java/org/apache/jena/sparql/function/StandardFunctions.java 
b/jena-arq/src/main/java/org/apache/jena/sparql/function/StandardFunctions.java
index ac0dbe1..5f78fcc 100644
--- 
a/jena-arq/src/main/java/org/apache/jena/sparql/function/StandardFunctions.java
+++ 
b/jena-arq/src/main/java/org/apache/jena/sparql/function/StandardFunctions.java
@@ -21,6 +21,8 @@ package org.apache.jena.sparql.function;
 import org.apache.jena.datatypes.xsd.XSDDatatype ;
 import org.apache.jena.sparql.ARQConstants ;
 import org.apache.jena.sparql.function.library.* ;
+import org.apache.jena.sparql.function.library.sqrt ;
+import org.apache.jena.sparql.function.library.leviathan.* ;
 
 /** Standard function library. */
 
@@ -29,6 +31,7 @@ public class StandardFunctions
     public static void loadStdDefs(FunctionRegistry registry)
     {
         String xfn = ARQConstants.fnPrefix ;
+        String math = ARQConstants.mathPrefix ;
         String sparqlfn = ARQConstants.fnSparql ;
         
         // See http://www.w3.org/TR/xpath-datamodel/#types-hierarchy
@@ -71,30 +74,63 @@ public class StandardFunctions
         addCastTemporal(registry, XSDDatatype.XSDgDay) ;
 
         //TODO op:numeric-greater-than etc.
+        //TODO sparql:* for al the SPARQL builtins.
         
-        add(registry, xfn+"boolean",        FN_BEV.class) ;
-        add(registry, xfn+"not",            FN_Not.class) ;
+        // Sections refer to XQ/XP Expression 3.1
+        // https://www.w3.org/TR/xpath-functions-3/
 
-        add(registry, xfn+"matches",        FN_Matches.class) ;
-        add(registry, xfn+"string-length",  FN_StrLength.class) ;
+//      5.4.1 fn:concat
+//      5.4.3 fn:substring
+//      5.4.4 fn:string-length
+//      5.4.5 fn:normalize-space
+//      5.4.6 fn:normalize-unicode
+//      5.4.7 fn:upper-case
+//      5.4.8 fn:lower-case
+//      5.5.1 fn:contains
+//      5.5.2 fn:starts-with
+//      5.5.3 fn:ends-with
+//      5.5.4 fn:substring-before
+//      5.5.5 fn:substring-after
+        
         //add(registry, xfn+"string-join",   FN_StrJoin.class) ;    // Works 
fn:string-join works on a sequence.
         add(registry, xfn+"concat",         FN_StrConcat.class) ;
         add(registry, xfn+"substring",      FN_StrSubstring.class) ;
-        add(registry, xfn+"starts-with",    FN_StrStartsWith.class) ;
-        
-        add(registry, xfn+"lower-case",     FN_StrLowerCase.class) ;
+        add(registry, xfn+"string-length",  FN_StrLength.class) ;
+        // fn:normalize-space
+        // fn:normalize-unicode
         add(registry, xfn+"upper-case",     FN_StrUpperCase.class) ;
-        
+        add(registry, xfn+"lower-case",     FN_StrLowerCase.class) ;
         add(registry, xfn+"contains",       FN_StrContains.class) ;
+        add(registry, xfn+"starts-with",    FN_StrStartsWith.class) ;
         add(registry, xfn+"ends-with",      FN_StrEndsWith.class) ;
 
         add(registry, xfn+"substring-before",   FN_StrBefore.class) ;
         add(registry, xfn+"substring-after",    FN_StrAfter.class) ;
+
+//      5.6.2 fn:matches
+//      5.6.3 fn:replace c.d. SPARQL REPLACE.
+//      Not 5.6.4 fn:tokenize - rturns a sequence.
+        add(registry, xfn+"matches",        FN_Matches.class) ;
+        // fn:replace
+        // fn:tokenize
         
+//        4.7.2 fn:format-number
+
+//        4.4.1 fn:abs
+//        4.4.2 fn:ceiling
+//        4.4.3 fn:floor
+//        4.4.4 fn:round
+//        4.4.5 fn:round-half-to-even
         add(registry, xfn+"abs",            FN_Abs.class) ;
         add(registry, xfn+"ceiling",        FN_Ceiling.class) ;
         add(registry, xfn+"floor",          FN_Floor.class) ;
         add(registry, xfn+"round",          FN_Round.class) ;
+        //fn:round-half-to-even
+        
+//        6.1 fn:resolve-uri        -- Two argument form makes sense.
+//        6.2 fn:encode-for-uri
+//        6.3 fn:iri-to-uri         -- meaningless in SPARQL.
+//        6.4 fn:escape-html-uri
         
         add(registry, xfn+"encode-for-uri", FN_StrEncodeForURI.class) ;
 
@@ -112,6 +148,116 @@ public class StandardFunctions
         add(registry, xfn+"hours-from-duration",    
FN_HoursFromDuration.class) ;
         add(registry, xfn+"minutes-from-duration",  
FN_MinutesFromDuration.class) ;
         add(registry, xfn+"seconds-from-duration",  
FN_SecondsFromDuration.class) ;
+        
+//      7.3.1 fn:boolean
+//      7.3.2 fn:not
+      add(registry, xfn+"boolean",        FN_BEV.class) ;
+      add(registry, xfn+"not",            FN_Not.class) ;
+        
+        // XQ/XP 3.
+//        9.6.1 fn:adjust-dateTime-to-timezone
+//        9.6.2 fn:adjust-date-to-timezone
+//        9.6.3 fn:adjust-time-to-timezone
+//        9.8.1 fn:format-dateTime
+//        9.8.2 fn:format-date
+//        9.8.3 fn:format-time
+        
+        // math:
+//        4.8 Trigonometric and exponential functions
+//        4.8.1 math:pi
+//        4.8.2 math:exp
+//        4.8.3 math:exp10
+//        4.8.4 math:log
+//        4.8.5 math:log10
+//        4.8.6 math:pow
+//        4.8.7 math:sqrt
+//        4.8.8 math:sin
+//        4.8.9 math:cos
+//        4.8.10 math:tan
+//        4.8.11 math:asin
+//        4.8.12 math:acos
+//        4.8.13 math:atan
+//        4.8.14 math:atan2
+        
+        // check.
+        add(registry, math+"pi",        pi.class) ;        
+        add(registry, math+"exp",       Math_exp.class) ;      // -> XSDFuncOp
+        add(registry, math+"exp10",     Math_exp10.class) ;    // -> XSDFuncOp
+        // Levianthan "log" is a function which takes one or two arguments.  
+        add(registry, math+"log",       Math_log.class) ;      // -> XSDFuncOp 
  ln.class?
+        add(registry, math+"log10",     Math_log10.class) ;    // -> XSDFuncOp 
                // - rename
+
+        // math_pow : integer preserving, otherwise doubles. 
+        add(registry, math+"pow",       Math_pow.class) ;      // -> XSDFuncOp
+        add(registry, math+"sqrt",      sqrt.class) ;
+    
+        // From leviathan, with math: naming.
+        add(registry, math+"sin",       sin.class) ;
+        add(registry, math+"cos",       cos.class) ;
+        add(registry, math+"tan",       tan.class) ;
+        add(registry, math+"asin",      sin1.class) ;
+        add(registry, math+"acos",      cos1.class) ;
+        add(registry, math+"atan",      tan1.class) ;
+        
+        add(registry, math+"atan2",     Math_atan2.class) ;
+        
+        // And add op:'s
+//        4.2.1 op:numeric-add
+//        4.2.2 op:numeric-subtract
+//        4.2.3 op:numeric-multiply
+//        4.2.4 op:numeric-divide
+//        4.2.5 op:numeric-integer-divide
+//        4.2.6 op:numeric-mod
+//        4.2.7 op:numeric-unary-plus
+//        4.2.8 op:numeric-unary-minus
+//        4.3.1 op:numeric-equal
+//        4.3.2 op:numeric-less-than
+//        4.3.3 op:numeric-greater-than
+//        7.2.1 op:boolean-equal
+//        7.2.2 op:boolean-less-than
+//        7.2.3 op:boolean-greater-than
+//        8.2.1 op:yearMonthDuration-less-than
+//        8.2.2 op:yearMonthDuration-greater-than
+//        8.2.3 op:dayTimeDuration-less-than
+//        8.2.4 op:dayTimeDuration-greater-than
+//        8.2.5 op:duration-equal
+//        8.4.1 op:add-yearMonthDurations
+//        8.4.2 op:subtract-yearMonthDurations
+//        8.4.3 op:multiply-yearMonthDuration
+//        8.4.4 op:divide-yearMonthDuration
+//        8.4.5 op:divide-yearMonthDuration-by-yearMonthDuration
+//        8.4.6 op:add-dayTimeDurations
+//        8.4.7 op:subtract-dayTimeDurations
+//        8.4.8 op:multiply-dayTimeDuration
+//        8.4.9 op:divide-dayTimeDuration
+//        8.4.10 op:divide-dayTimeDuration-by-dayTimeDuration
+//        9.4.1 op:dateTime-equal
+//        9.4.2 op:dateTime-less-than
+//        9.4.3 op:dateTime-greater-than
+//        9.4.4 op:date-equal
+//        9.4.5 op:date-less-than
+//        9.4.6 op:date-greater-than
+//        9.4.7 op:time-equal
+//        9.4.8 op:time-less-than
+//        9.4.9 op:time-greater-than
+//        9.4.10 op:gYearMonth-equal
+//        9.4.11 op:gYear-equal
+//        9.4.12 op:gMonthDay-equal
+//        9.4.13 op:gMonth-equal
+//        9.4.14 op:gDay-equal
+//        9.7.2 op:subtract-dateTimes
+//        9.7.3 op:subtract-dates
+//        9.7.4 op:subtract-times
+//        9.7.5 op:add-yearMonthDuration-to-dateTime
+//        9.7.6 op:add-dayTimeDuration-to-dateTime
+//        9.7.7 op:subtract-yearMonthDuration-from-dateTime
+//        9.7.8 op:subtract-dayTimeDuration-from-dateTime
+//        9.7.9 op:add-yearMonthDuration-to-date
+//        9.7.10 op:add-dayTimeDuration-to-date
+//        9.7.11 op:subtract-yearMonthDuration-from-date
+//        9.7.12 op:subtract-dayTimeDuration-from-date
+//        9.7.13 op:add-dayTimeDuration-to-time
+//        9.7.14 op:subtract-dayTimeDuration-from-time
     }
     
     private static void addCastXSD(FunctionRegistry registry, XSDDatatype dt)

http://git-wip-us.apache.org/repos/asf/jena/blob/f7a23ef7/jena-arq/src/main/java/org/apache/jena/sparql/function/library/Math_atan2.java
----------------------------------------------------------------------
diff --git 
a/jena-arq/src/main/java/org/apache/jena/sparql/function/library/Math_atan2.java
 
b/jena-arq/src/main/java/org/apache/jena/sparql/function/library/Math_atan2.java
new file mode 100644
index 0000000..28c1f29
--- /dev/null
+++ 
b/jena-arq/src/main/java/org/apache/jena/sparql/function/library/Math_atan2.java
@@ -0,0 +1,37 @@
+/*
+ * 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 org.apache.jena.sparql.function.library;
+
+import org.apache.jena.sparql.expr.NodeValue ;
+import org.apache.jena.sparql.function.FunctionBase2 ;
+
+//Summary
+// Returns the angle in radians subtended at the origin by
+// the point on a plane with coordinates (x, y) and the positive x-axis,
+// the result being in the range -π to +π.
+// math:atan2($y as xs:double, $x as xs:double) as xs:double
+
+public class Math_atan2 extends FunctionBase2 {
+
+    @Override
+    public NodeValue exec(NodeValue v1, NodeValue v2) {
+        double d = Math.atan2(v1.getDouble(), v2.getDouble()) ; 
+        return NodeValue.makeDouble(d) ;
+    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/f7a23ef7/jena-arq/src/main/java/org/apache/jena/sparql/function/library/Math_exp.java
----------------------------------------------------------------------
diff --git 
a/jena-arq/src/main/java/org/apache/jena/sparql/function/library/Math_exp.java 
b/jena-arq/src/main/java/org/apache/jena/sparql/function/library/Math_exp.java
new file mode 100644
index 0000000..dd9aa00
--- /dev/null
+++ 
b/jena-arq/src/main/java/org/apache/jena/sparql/function/library/Math_exp.java
@@ -0,0 +1,32 @@
+/*
+ * 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 org.apache.jena.sparql.function.library;
+
+import org.apache.jena.sparql.expr.NodeValue ;
+import org.apache.jena.sparql.function.FunctionBase1 ;
+
+// Returns the value of e^x.
+public class Math_exp extends FunctionBase1 {
+
+    @Override
+    public NodeValue exec(NodeValue v) {
+        return NodeValue.makeDouble(Math.exp(v.getDouble())) ;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/f7a23ef7/jena-arq/src/main/java/org/apache/jena/sparql/function/library/Math_exp10.java
----------------------------------------------------------------------
diff --git 
a/jena-arq/src/main/java/org/apache/jena/sparql/function/library/Math_exp10.java
 
b/jena-arq/src/main/java/org/apache/jena/sparql/function/library/Math_exp10.java
new file mode 100644
index 0000000..de83140
--- /dev/null
+++ 
b/jena-arq/src/main/java/org/apache/jena/sparql/function/library/Math_exp10.java
@@ -0,0 +1,48 @@
+/*
+ * 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 org.apache.jena.sparql.function.library;
+
+import java.math.BigInteger ;
+
+import org.apache.jena.sparql.ARQInternalErrorException ;
+import org.apache.jena.sparql.expr.NodeValue ;
+import org.apache.jena.sparql.expr.nodevalue.XSDFuncOp ;
+import org.apache.jena.sparql.function.FunctionBase1 ;
+
+// Returns the value of natural log(x)
+public class Math_exp10 extends FunctionBase1 {
+    
+    @Override
+    public NodeValue exec(NodeValue v) {
+        switch (XSDFuncOp.classifyNumeric("exp10", v))
+        {
+            case OP_INTEGER:
+                int x = v.getInteger().intValue() ;
+                if ( x >= 0 )
+                    return NodeValue.makeInteger(BigInteger.TEN.pow(x)) ;
+                // Anything else -> double
+            case OP_DECIMAL:
+            case OP_FLOAT:
+            case OP_DOUBLE:
+                return NodeValue.makeDouble(Math.pow(10, v.getDouble())) ;
+            default:
+                throw new ARQInternalErrorException("Unrecognized numeric 
operation : "+ v) ;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/f7a23ef7/jena-arq/src/main/java/org/apache/jena/sparql/function/library/Math_log.java
----------------------------------------------------------------------
diff --git 
a/jena-arq/src/main/java/org/apache/jena/sparql/function/library/Math_log.java 
b/jena-arq/src/main/java/org/apache/jena/sparql/function/library/Math_log.java
new file mode 100644
index 0000000..ac779cd
--- /dev/null
+++ 
b/jena-arq/src/main/java/org/apache/jena/sparql/function/library/Math_log.java
@@ -0,0 +1,31 @@
+/*
+ * 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 org.apache.jena.sparql.function.library;
+
+import org.apache.jena.sparql.expr.NodeValue ;
+import org.apache.jena.sparql.function.FunctionBase1 ;
+
+// Returns the natural log of x.
+public class Math_log extends FunctionBase1 {
+
+    @Override
+    public NodeValue exec(NodeValue v) {
+        return NodeValue.makeDouble(Math.log(v.getDouble()));
+    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/f7a23ef7/jena-arq/src/main/java/org/apache/jena/sparql/function/library/Math_log10.java
----------------------------------------------------------------------
diff --git 
a/jena-arq/src/main/java/org/apache/jena/sparql/function/library/Math_log10.java
 
b/jena-arq/src/main/java/org/apache/jena/sparql/function/library/Math_log10.java
new file mode 100644
index 0000000..a775385
--- /dev/null
+++ 
b/jena-arq/src/main/java/org/apache/jena/sparql/function/library/Math_log10.java
@@ -0,0 +1,31 @@
+/*
+ * 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 org.apache.jena.sparql.function.library;
+
+import org.apache.jena.sparql.expr.NodeValue ;
+import org.apache.jena.sparql.function.FunctionBase1 ;
+
+// Returns the value of 10^x.
+public class Math_log10 extends FunctionBase1 {
+
+    @Override
+    public NodeValue exec(NodeValue v) {
+        return NodeValue.makeDouble(Math.log10(v.getDouble())) ;
+    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/f7a23ef7/jena-arq/src/main/java/org/apache/jena/sparql/function/library/Math_pow.java
----------------------------------------------------------------------
diff --git 
a/jena-arq/src/main/java/org/apache/jena/sparql/function/library/Math_pow.java 
b/jena-arq/src/main/java/org/apache/jena/sparql/function/library/Math_pow.java
new file mode 100644
index 0000000..d420403
--- /dev/null
+++ 
b/jena-arq/src/main/java/org/apache/jena/sparql/function/library/Math_pow.java
@@ -0,0 +1,59 @@
+/*
+ * 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 org.apache.jena.sparql.function.library;
+
+import java.math.BigInteger ;
+
+import org.apache.jena.sparql.ARQInternalErrorException ;
+import org.apache.jena.sparql.expr.NodeValue ;
+import org.apache.jena.sparql.expr.nodevalue.XSDFuncOp ;
+import org.apache.jena.sparql.function.FunctionBase2 ;
+
+// math:pow($x as xs:double?, $y as xs:numeric) as xs:double?
+//    except pow(integer,+ve integer) is an integer 
+public class Math_pow extends FunctionBase2 {
+
+    @Override
+    public NodeValue exec(NodeValue v1, NodeValue v2) {
+        switch (XSDFuncOp.classifyNumeric("pow", v1, v2))
+        {
+            case OP_INTEGER:
+                BigInteger x = v1.getInteger();
+                int y = v2.getInteger().intValue() ;
+                if ( y >= 0 )
+                    return NodeValue.makeInteger( x.pow(y)) ;
+            // Anything else -> double
+            case OP_DECIMAL:
+            case OP_FLOAT:
+            case OP_DOUBLE:
+                double d1 = v1.getDouble() ;
+                double d2 = v2.getDouble() ;
+                if ( d1 == 1 && d2 == Double.POSITIVE_INFINITY ) {
+                    if ( v1.isInteger() )
+                        return NodeValue.nvONE ;
+                    else
+                        return NodeValue.makeDouble(1) ;
+                }
+                return NodeValue.makeDouble( Math.pow(v1.getDouble(), 
v2.getDouble()) ) ;
+            default:
+                throw new ARQInternalErrorException("Unrecognized numeric 
operation : "+ v1) ;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/f7a23ef7/jena-arq/src/main/java/org/apache/jena/sparql/function/library/evenInteger.java
----------------------------------------------------------------------
diff --git 
a/jena-arq/src/main/java/org/apache/jena/sparql/function/library/evenInteger.java
 
b/jena-arq/src/main/java/org/apache/jena/sparql/function/library/evenInteger.java
index 14dfe1f..a329c1b 100644
--- 
a/jena-arq/src/main/java/org/apache/jena/sparql/function/library/evenInteger.java
+++ 
b/jena-arq/src/main/java/org/apache/jena/sparql/function/library/evenInteger.java
@@ -18,7 +18,6 @@
 
 package org.apache.jena.sparql.function.library;
 
-//import org.apache.commons.logging.*;
 import org.apache.jena.sparql.expr.ExprEvalException ;
 import org.apache.jena.sparql.expr.NodeValue ;
 import org.apache.jena.sparql.function.FunctionBase1 ;

http://git-wip-us.apache.org/repos/asf/jena/blob/f7a23ef7/jena-arq/src/main/java/org/apache/jena/sparql/graph/NodeConst.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/graph/NodeConst.java 
b/jena-arq/src/main/java/org/apache/jena/sparql/graph/NodeConst.java
index ea89816..b089de2 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/graph/NodeConst.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/graph/NodeConst.java
@@ -41,6 +41,7 @@ public class NodeConst
     public static final Node nodeZero       = literal("0",     
XSDDatatype.XSDinteger) ;
     public static final Node nodeOne        = literal("1",     
XSDDatatype.XSDinteger) ;
     public static final Node nodeTwo        = literal("2",     
XSDDatatype.XSDinteger) ;
+    public static final Node nodeTen        = literal("10",    
XSDDatatype.XSDinteger) ;
     public static final Node nodeMinusOne   = literal("-1",    
XSDDatatype.XSDinteger) ;
     public static final Node emptyString    = NodeFactory.createLiteral("") ;
     

http://git-wip-us.apache.org/repos/asf/jena/blob/f7a23ef7/jena-arq/src/test/java/org/apache/jena/sparql/expr/LibTestExpr.java
----------------------------------------------------------------------
diff --git 
a/jena-arq/src/test/java/org/apache/jena/sparql/expr/LibTestExpr.java 
b/jena-arq/src/test/java/org/apache/jena/sparql/expr/LibTestExpr.java
new file mode 100644
index 0000000..20dec1c
--- /dev/null
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/expr/LibTestExpr.java
@@ -0,0 +1,114 @@
+/*
+ * 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 org.apache.jena.sparql.expr;
+import static org.junit.Assert.* ;
+import org.apache.jena.graph.Node ;
+import org.apache.jena.shared.PrefixMapping ;
+import org.apache.jena.shared.impl.PrefixMappingImpl ;
+import org.apache.jena.sparql.ARQConstants ;
+import org.apache.jena.sparql.function.FunctionEnvBase ;
+import org.apache.jena.sparql.function.library.leviathan.LeviathanConstants ;
+import org.apache.jena.sparql.util.ExprUtils ;
+import org.apache.jena.sparql.util.NodeFactoryExtra ;
+
+public class LibTestExpr {
+
+
+    private static PrefixMapping pmap = new PrefixMappingImpl();
+    static {
+        pmap.setNsPrefixes(ARQConstants.getGlobalPrefixMap());
+        pmap.setNsPrefix("lfn", 
LeviathanConstants.LeviathanFunctionLibraryURI);
+    }
+    
+    static void testExpr(String exprExpected, String expectedResult) {
+        NodeValue actual = eval(exprExpected) ;
+        NodeValue expected = eval(expectedResult) ;
+        assertEquals(exprExpected, expected, actual) ; 
+    }
+
+    static Expr parse(String exprString) {
+        return ExprUtils.parse(exprString, pmap);
+    }
+        
+    static NodeValue eval(String exprString) {
+        Expr expr = ExprUtils.parse(exprString, pmap);
+        NodeValue result = expr.eval(null, new FunctionEnvBase());
+        return result ;
+    }
+        
+    
+    static void test(String exprString, String result) {
+        Node r = NodeFactoryExtra.parseNode(result);
+        test(exprString, r);
+    }
+    
+    static void test(String exprString, Node result) {
+        Expr expr = ExprUtils.parse(exprString, pmap);
+        NodeValue actual = expr.eval(null, new FunctionEnvBase());
+        NodeValue expected = NodeValue.makeNode(result);
+        assertTrue("Expected = " + expected + " : Actual = " + actual, 
NodeValue.sameAs(expected, actual)) ;
+    }
+
+    static void testDouble(String exprString, String result, double delta) {
+        Node r = NodeFactoryExtra.parseNode(result);
+        testDouble(exprString, r, delta);
+    }
+
+    static void testDouble(String exprString, Node result, double delta) {
+        Expr expr = ExprUtils.parse(exprString, pmap);
+        NodeValue actual = expr.eval(null, new FunctionEnvBase());
+        NodeValue expected = NodeValue.makeNode(result);
+        // Note that we don't test lexical form because we can get mismatches
+        // between how things like doubles are expressed
+        if (NodeValue.sameAs(expected, actual))
+            return;
+
+        testDouble(exprString, expected.getDouble(), delta); ;
+    }
+    
+    static void testDouble(String exprString, double expected, double delta) {
+        Expr expr = ExprUtils.parse(exprString, pmap);
+        NodeValue actual = expr.eval(null, new FunctionEnvBase());
+        assertTrue("Not a double: "+actual, actual.isDouble() ) ; 
+        double result = actual.getDouble() ;
+        
+        // Because Java floating point calculations are woefully imprecise we
+        // are in many cases simply testing that the differences between the
+        // values are within a given delta
+        if ( Double.isInfinite(expected) ) {
+            assertTrue("Expected INF: Got "+result, Double.isInfinite(result)) 
;
+            return ;
+        }
+        
+        if ( Double.isNaN(expected) ) {
+            assertTrue("Expected NaN: Got "+result, Double.isNaN(result)) ;
+            return ;
+        }
+
+        double difference = Math.abs(result - expected);
+        assertTrue("Values not within given delta " + delta + ": Expected = " 
+ expected + " : Actual = " + actual,
+                difference <= delta);
+    }
+
+    
+    static void testError(String exprString) {
+        Expr expr = ExprUtils.parse(exprString, pmap);
+        expr.eval(null, new FunctionEnvBase());
+    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/f7a23ef7/jena-arq/src/test/java/org/apache/jena/sparql/expr/TS_Expr.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TS_Expr.java 
b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TS_Expr.java
index bf0ae6d..4958771 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TS_Expr.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TS_Expr.java
@@ -34,7 +34,7 @@ import org.junit.runners.Suite.SuiteClasses ;
     , TestExpressions3.class
     , TestCastXSD.class
     , TestNodeFunctions.class
-    , TestExpressions2.class
+    , TestExpressionsMath.class
     , TestFunctions.class
     , TestFunctions2.class
     , TestLeviathanFunctions.class

http://git-wip-us.apache.org/repos/asf/jena/blob/f7a23ef7/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestExpressions2.java
----------------------------------------------------------------------
diff --git 
a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestExpressions2.java 
b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestExpressions2.java
index 3dfc53d..9f08dd6 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestExpressions2.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestExpressions2.java
@@ -143,13 +143,13 @@ public class TestExpressions2 extends BaseTest
     
     // ---- Workers
     
-    private static void eval(String string)
+    /*package*/ static void eval(String string)
     { 
         eval(string, true) ;
     }
     
-    // It's easier to write tests that simple are expected to return 
true/false 
-    private static void eval(String string, boolean result)
+    // It's easier to write tests that simply are expected to return 
true/false 
+    /*package*/ static void eval(String string, boolean result)
     {
         Expr expr = ExprUtils.parse(string) ;
         NodeValue nv = expr.eval(null, FunctionEnvBase.createTest()) ;

http://git-wip-us.apache.org/repos/asf/jena/blob/f7a23ef7/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestExpressionsMath.java
----------------------------------------------------------------------
diff --git 
a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestExpressionsMath.java 
b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestExpressionsMath.java
new file mode 100644
index 0000000..a339fb6
--- /dev/null
+++ 
b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestExpressionsMath.java
@@ -0,0 +1,95 @@
+/*
+ * 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 org.apache.jena.sparql.expr;
+
+import static org.apache.jena.sparql.expr.LibTestExpr.* ;
+
+import org.apache.jena.atlas.junit.BaseTest ;
+import org.apache.jena.sparql.ARQException ;
+import org.junit.Test ;
+
+/** Expression evaluation involving math: */
+public class TestExpressionsMath extends BaseTest
+{
+    @Test public void pi_01()           { testDouble("math:pi()", "3.1415926", 
0.00001) ; }
+    @Test(expected=ARQException.class)
+    public void pi_02()           { testDouble("math:pi(1)", "3.1415926", 
0.00001) ; }
+
+    @Test public void exp_01()          { testDouble("math:exp(2)", 
Math.exp(2.0e0), 0.00001) ; }
+    @Test public void exp_02()          { testDouble("math:exp(2.0)", 
Math.exp(2.0e0), 0.00001) ; }
+    @Test public void exp_03()          { testDouble("math:exp(-2e1)", 
Math.exp(-2e1), 0.00001) ; }
+    @Test public void exp_04()          { test("math:exp(1e0/0)", 
"'INF'^^xsd:double") ; }
+    @Test public void exp_05()          { test("math:exp('INF'^^xsd:double)", 
"'INF'^^xsd:double") ; }
+    @Test public void exp_06()          { test("math:exp('-INF'^^xsd:double)", 
"'0.0e0'^^xsd:double") ; }
+    @Test public void exp_07()          { test("math:exp('NaN'^^xsd:double)", 
"'NaN'^^xsd:double") ; }
+
+    @Test public void exp10_01()        { test("math:exp10(2)", "100") ; }
+    @Test public void exp10_02()        { testDouble("math:exp10(-1)", 0.1, 
0.00001) ; }
+    @Test public void exp10_03()        { testDouble("math:exp10(2.0)", 100, 
0.00001) ; }
+    @Test public void exp10_04()        { test("math:exp10(0)", "1") ; }
+    @Test public void exp10_05()        { 
testDouble("math:exp10('NaN'^^xsd:double)", Double.NaN, 0.0000001 ) ; }
+    
+    @Test public void log_01()          { testDouble("math:log(1)", 
Math.log(1), 0.0000001 ) ; }
+    @Test public void log_02()          { 
testDouble("math:log('NaN'^^xsd:double)", Double.NaN, 0.0000001 ) ; }
+    @Test public void log_03()          { test("math:log('INF'^^xsd:double)", 
"'INF'^^xsd:double") ; }
+    @Test public void log_04()          { test("math:log(0)", 
"'-INF'^^xsd:double") ; }
+    @Test public void log_05()          { test("math:exp('INF'^^xsd:double)", 
"'INF'^^xsd:double") ; }
+    @Test public void log_06()          { test("math:exp('-INF'^^xsd:double)", 
"'0.0e0'^^xsd:double") ; }
+    @Test public void log_07()          { test("math:exp('NaN'^^xsd:double)", 
"'NaN'^^xsd:double") ; }
+    
+    @Test public void pow_01()          { test("math:pow(2,2)", "4") ; } 
+    @Test public void pow_02()          { testDouble("math:pow(2,-2)", 0.25, 
0.00001) ; }
+    @Test public void pow_03()          { test("math:pow(2,0)", "1") ; }
+    
+    @Test public void pow_10()          { test("math:pow('INF'^^xsd:double, 
1)", "'INF'^^xsd:double") ; }
+    @Test public void pow_11()          { test("math:pow(1, 
'INF'^^xsd:double)", "1") ; }
+    @Test public void pow_12()          { test("math:pow(1e0, 
'INF'^^xsd:double)", "'1.0e0'^^xsd:double") ; }
+    
+    @Test public void pow_13()          { 
test("math:pow('INF'^^xsd:double,0)", "'1.0e0'^^xsd:double") ; }
+    @Test public void pow_14()          { test("math:pow('-INF'^^xsd:double, 
0)", "'1.0e0'^^xsd:double") ; }
+    @Test public void pow_15()          { test("math:pow('NaN'^^xsd:double, 
1)", "'NaN'^^xsd:double") ; }
+    @Test public void pow_16()          { test("math:pow(1, 
'NaN'^^xsd:double)", "'NaN'^^xsd:double") ; }
+    
+    @Test public void sqrt_01()         { test("math:sqrt(1)", 
"'1.0e0'^^xsd:double") ; }
+    @Test public void sqrt_02()         { testDouble("math:sqrt(2)", 
Math.sqrt(2), 0.000001) ; }
+    @Test public void sqrt_03()         { test("math:sqrt(-2)", 
"'NaN'^^xsd:double") ; }
+    
+    @Test(expected=ARQException.class)
+    public void sqrt_04()               { test("math:sqrt('TWO')", "'dummy'") 
; }
+    
+    @Test public void sqrt_10()         { test("math:sqrt('INF'^^xsd:double)", 
"'INF'^^xsd:double") ; }
+    @Test public void sqrt_11()         { 
test("math:sqrt('-INF'^^xsd:double)", "'NaN'^^xsd:double") ; }
+    @Test public void sqrt_12()         { test("math:sqrt('NaN'^^xsd:double)", 
"'NaN'^^xsd:double") ; }
+
+    //  4.8.7 math:sqrt
+//  4.8.8 math:sin
+//  4.8.9 math:cos
+//  4.8.10 math:tan
+//  4.8.11 math:asin
+//  4.8.12 math:acos
+//  4.8.13 math:atan
+//  4.8.14 math:atan2
+    
+    
+    // Yes - atan uses (Y,X)
+    @Test public void atan2_01()        { testDouble("math:atan2(0,1)", 
"0.0e0", 0.00001) ; }
+    @Test public void atan2_02()        { testDouble("math:atan2(1,0)", 
Math.PI/2, 0.00001) ; }
+    @Test public void atan2_03()        { testDouble("math:atan2(2.0,0.0)", 
Math.PI/2, 0.00001) ; }
+    @Test public void atan2_04()        { testDouble("math:atan2(-2.0e1, 
0.0)", - Math.PI/2, 0.00001) ; } 
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/f7a23ef7/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestLeviathanFunctions.java
----------------------------------------------------------------------
diff --git 
a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestLeviathanFunctions.java
 
b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestLeviathanFunctions.java
index 80bc653..0b93bbb 100644
--- 
a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestLeviathanFunctions.java
+++ 
b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestLeviathanFunctions.java
@@ -18,17 +18,11 @@
 
 package org.apache.jena.sparql.expr;
 
+import static org.apache.jena.sparql.expr.LibTestExpr.test ;
+import static org.apache.jena.sparql.expr.LibTestExpr.testDouble ;
+import static org.apache.jena.sparql.expr.LibTestExpr.testError ;
+
 import org.apache.jena.atlas.junit.BaseTest;
-import org.apache.jena.graph.Node ;
-import org.apache.jena.shared.PrefixMapping ;
-import org.apache.jena.shared.impl.PrefixMappingImpl ;
-import org.apache.jena.sparql.ARQConstants ;
-import org.apache.jena.sparql.expr.Expr ;
-import org.apache.jena.sparql.expr.ExprEvalException ;
-import org.apache.jena.sparql.expr.NodeValue ;
-import org.apache.jena.sparql.function.FunctionEnvBase ;
-import org.apache.jena.sparql.function.library.leviathan.LeviathanConstants ;
-import org.apache.jena.sparql.util.ExprUtils ;
 import org.apache.jena.sparql.util.NodeFactoryExtra ;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
@@ -50,40 +44,34 @@ public class TestLeviathanFunctions extends BaseTest {
         NodeValue.VerboseWarnings = warnOnBadLexicalForms;
     }
 
-    private static PrefixMapping pmap = new PrefixMappingImpl();
-    static {
-        pmap.setNsPrefixes(ARQConstants.getGlobalPrefixMap());
-        pmap.setNsPrefix("lfn", 
LeviathanConstants.LeviathanFunctionLibraryURI);
-    }
-
     @Test
     public void sq_01() {
-        test("lfn:sq(2)", "4");
+        LibTestExpr.test("lfn:sq(2)", "4");
     }
 
     @Test
     public void sq_02() {
-        test("lfn:sq(3)", "9");
+        LibTestExpr.test("lfn:sq(3)", "9");
     }
 
     @Test
     public void sq_03() {
-        test("lfn:sq(0.5)", "0.25");
+        LibTestExpr.test("lfn:sq(0.5)", "0.25");
     }
 
     @Test
     public void cube_01() {
-        test("lfn:cube(2)", "8");
+        LibTestExpr.test("lfn:cube(2)", "8");
     }
 
     @Test
     public void cube_02() {
-        test("lfn:cube(3)", "27");
+        LibTestExpr.test("lfn:cube(3)", "27");
     }
 
     @Test
     public void cube_03() {
-        test("lfn:cube(0.5)", "0.125");
+        LibTestExpr.test("lfn:cube(0.5)", "0.125");
     }
 
     @Test
@@ -93,32 +81,32 @@ public class TestLeviathanFunctions extends BaseTest {
 
     @Test
     public void pow_01() {
-        test("lfn:pow(2, 4)", "16");
+        LibTestExpr.test("lfn:pow(2, 4)", "16");
     }
 
     @Test
     public void pow_02() {
-        test("lfn:pow(0.5, 3)", "0.125");
+        LibTestExpr.test("lfn:pow(0.5, 3)", "0.125");
     }
 
     @Test
     public void factorial_01() {
-        test("lfn:factorial(0)", "1");
+        LibTestExpr.test("lfn:factorial(0)", "1");
     }
 
     @Test
     public void factorial_02() {
-        test("lfn:factorial(1)", "1");
+        LibTestExpr.test("lfn:factorial(1)", "1");
     }
 
     @Test
     public void factorial_03() {
-        test("lfn:factorial(3)", "6");
+        LibTestExpr.test("lfn:factorial(3)", "6");
     }
 
     @Test
     public void factorial_04() {
-        test("lfn:factorial(5)", "120");
+        LibTestExpr.test("lfn:factorial(5)", "120");
     }
 
     @Test(expected = ExprEvalException.class)
@@ -133,12 +121,12 @@ public class TestLeviathanFunctions extends BaseTest {
 
     @Test
     public void log_01() {
-        test("lfn:log(1)", "0");
+        LibTestExpr.test("lfn:log(1)", "0");
     }
 
     @Test
     public void log_02() {
-        test("lfn:log(10)", "1");
+        LibTestExpr.test("lfn:log(10)", "1");
     }
 
     @Test
@@ -148,42 +136,42 @@ public class TestLeviathanFunctions extends BaseTest {
 
     @Test
     public void log_04() {
-        test("lfn:log(4, 2)", "2");
+        LibTestExpr.test("lfn:log(4, 2)", "2");
     }
 
     @Test
     public void log_05() {
-        test("lfn:log(4, 16)", "0.5");
+        LibTestExpr.test("lfn:log(4, 16)", "0.5");
     }
 
     @Test
     public void log_06() {
-        test("lfn:log(16, 4)", "2");
+        LibTestExpr.test("lfn:log(16, 4)", "2");
     }
 
     @Test
     public void reciprocal_01() {
-        test("lfn:reciprocal(1)", "1");
+        LibTestExpr.test("lfn:reciprocal(1)", "1");
     }
 
     @Test
     public void reciprocal_02() {
-        test("lfn:reciprocal(2)", "0.5");
+        LibTestExpr.test("lfn:reciprocal(2)", "0.5");
     }
 
     @Test
     public void reciprocal_03() {
-        test("lfn:reciprocal(lfn:reciprocal(2))", "2");
+        LibTestExpr.test("lfn:reciprocal(lfn:reciprocal(2))", "2");
     }
 
     @Test
     public void root_01() {
-        test("lfn:root(4,2)", "2");
+        LibTestExpr.test("lfn:root(4,2)", "2");
     }
 
     @Test
     public void root_02() {
-        test("lfn:root(2,1)", "2");
+        LibTestExpr.test("lfn:root(2,1)", "2");
     }
 
     @Test
@@ -193,37 +181,37 @@ public class TestLeviathanFunctions extends BaseTest {
 
     @Test
     public void sqrt_01() {
-        test("lfn:sqrt(4)", "2");
+        LibTestExpr.test("lfn:sqrt(4)", "2");
     }
 
     @Test
     public void sqrt_02() {
-        test("lfn:sqrt(144)", "12");
+        LibTestExpr.test("lfn:sqrt(144)", "12");
     }
 
     @Test
     public void cartesian_01() {
-        test("lfn:cartesian(0, 0, 0, 0)", "0");
+        LibTestExpr.test("lfn:cartesian(0, 0, 0, 0)", "0");
     }
 
     @Test
     public void cartesian_02() {
-        test("lfn:cartesian(0, 0, 3, 4)", "5");
+        LibTestExpr.test("lfn:cartesian(0, 0, 3, 4)", "5");
     }
 
     @Test
     public void cartesian_03() {
-        test("lfn:cartesian(0, 0, 0, 3, 4, 0)", "5");
+        LibTestExpr.test("lfn:cartesian(0, 0, 0, 3, 4, 0)", "5");
     }
 
     @Test
     public void cartesian_04() {
-        test("lfn:cartesian(0, 0, 0, 0, 3, 4)", "5");
+        LibTestExpr.test("lfn:cartesian(0, 0, 0, 0, 3, 4)", "5");
     }
 
     @Test
     public void cartesian_05() {
-        test("lfn:cartesian(0, 0, 0, 3, 0, 4)", "5");
+        LibTestExpr.test("lfn:cartesian(0, 0, 0, 3, 0, 4)", "5");
     }
 
     @Test
@@ -235,49 +223,4 @@ public class TestLeviathanFunctions extends BaseTest {
     public void acos_01() {
         
testDouble("lfn:radians-to-degrees(lfn:cos-1(lfn:cos(lfn:degrees-to-radians(60))))",
 "60", DELTA);
     }
-
-    private static void test(String exprString, String result) {
-        Node r = NodeFactoryExtra.parseNode(result);
-        test(exprString, r);
-    }
-
-    private static void test(String exprString, Node result) {
-        Expr expr = ExprUtils.parse(exprString, pmap);
-        NodeValue actual = expr.eval(null, new FunctionEnvBase());
-        NodeValue expected = NodeValue.makeNode(result);
-
-        // Note that we don't test lexical form because we can get mismatches
-        // between how things like doubles are expressed
-        assertTrue("Not same value: Expected = " + expected + " : Actual = " + 
actual,
-                NodeValue.sameAs(expected, actual));
-    }
-
-    private static void testDouble(String exprString, String result, double 
delta) {
-        Node r = NodeFactoryExtra.parseNode(result);
-        testDouble(exprString, r, delta);
-    }
-
-    private static void testDouble(String exprString, Node result, double 
delta) {
-        Expr expr = ExprUtils.parse(exprString, pmap);
-        NodeValue actual = expr.eval(null, new FunctionEnvBase());
-        NodeValue expected = NodeValue.makeNode(result);
-
-        // Note that we don't test lexical form because we can get mismatches
-        // between how things like doubles are expressed
-        if (NodeValue.sameAs(expected, actual))
-            return;
-
-        // Because Java floating point calculations are woefully imprecise we
-        // are in many cases simply testing that the differences between the
-        // values are within a given delta
-        double difference = Math.abs(actual.getDouble() - 
expected.getDouble());
-        assertTrue("Values not within given delta " + delta + ": Expected = " 
+ expected + " : Actual = " + actual,
-                difference <= delta);
-    }
-
-    private static void testError(String exprString) {
-        Expr expr = ExprUtils.parse(exprString, pmap);
-        expr.eval(null, new FunctionEnvBase());
-    }
-
 }

http://git-wip-us.apache.org/repos/asf/jena/blob/f7a23ef7/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestXSDFuncOp.java
----------------------------------------------------------------------
diff --git 
a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestXSDFuncOp.java 
b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestXSDFuncOp.java
index 8d46cb5..a869e28 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestXSDFuncOp.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestXSDFuncOp.java
@@ -833,10 +833,11 @@ public class TestXSDFuncOp extends BaseTest
     @Test public void testSqrt1()
     {
         NodeValue four = NodeValue.makeInteger(4) ;
-        NodeValue two = NodeValue.makeInteger(2) ;
+        NodeValue two = NodeValue.makeDouble(2) ;
         NodeValue result = XSDFuncOp.sqrt( four ) ;
         
-        assertTrue(result.isDecimal()) ;
+        assertTrue(result.isDouble()) ;
+        assertFalse(result.isDecimal()) ;
         assertTrue( NodeValue.sameAs( two, result)) ;
         assertTrue( two.asNode().sameValueAs(result.asNode()) ) ;
     }
@@ -851,8 +852,6 @@ public class TestXSDFuncOp extends BaseTest
         assertTrue( NodeValue.sameAs( two, result)) ;
         
         assertNotNull(result.asNode()) ;
-        
-        //assertTrue( two.asNode().sameValueAs(result.asNode()) ) ;
     }
     
     // All compatible - no timezone.

Reply via email to