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.
