[
https://issues.apache.org/jira/browse/JENA-2355?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17772251#comment-17772251
]
Jan Martin Keil commented on JENA-2355:
---------------------------------------
_Sorry for the delay._
Yes, the [XQuery/XPath
rules|https://www.w3.org/TR/xpath-functions/#numeric-functions] used in SPARQL
is the behavior I would have expected.
Also AddOne.java does not properly handle xsd:decimal (nor xsd:float and
xsd:double), but has some
un[documented|https://jena.apache.org/documentation/inference/#RULEbuiltins]
additional behavior (automatic argument switching). Should this undocumented
behavior of AddOne stay and become documented or get removed?
> Rule Math Builtins do not support xsd:decimal
> ---------------------------------------------
>
> Key: JENA-2355
> URL: https://issues.apache.org/jira/browse/JENA-2355
> Project: Apache Jena
> Issue Type: Bug
> Components: Reasoners
> Affects Versions: Jena 4.9.0
> Reporter: Jan Martin Keil
> Priority: Major
>
> The [builtin|https://jena.apache.org/documentation/inference/#RULEbuiltins]
> math functions of the rule reasoners do not properly support xsd:decimal. For
> example, sum(1.1, 1.1) = 2.0 (returned as integer) and quotient(0.1, 0.1)
> throws "ArithmeticException: / by zero". Here some detailed tests:
> {code:java}
> import org.apache.jena.rdf.model.*;
> import org.apache.jena.reasoner.rulesys.GenericRuleReasoner;
> import org.apache.jena.reasoner.rulesys.Rule;
> import org.apache.jena.riot.Lang;
> import org.apache.jena.riot.RDFParser;
> import org.junit.jupiter.api.Assertions;
> import org.junit.jupiter.api.Test;
> public class ApacheJenaRuleDecimalTest {
> Property a = ResourceFactory.createProperty("http://example/a");
> Property b = ResourceFactory.createProperty("http://example/b");
> Property sum = ResourceFactory.createProperty("http://example/sum");
> Property difference =
> ResourceFactory.createProperty("http://example/difference");
> Property product =
> ResourceFactory.createProperty("http://example/product");
> Property quotient =
> ResourceFactory.createProperty("http://example/quotient");
> String rules =
> "(?r <http://example/a> ?a) (?r <http://example/b> ?b) sum(?a,
> ?b, ?c) -> (?r <http://example/sum> ?c) ." +
> "(?r <http://example/a> ?a) (?r <http://example/b> ?b)
> difference(?a, ?b, ?c) -> (?r <http://example/difference> ?c) ." +
> "(?r <http://example/a> ?a) (?r <http://example/b> ?b)
> product(?a, ?b, ?c) -> (?r <http://example/product> ?c) ." +
> "(?r <http://example/a> ?a) (?r <http://example/b> ?b)
> quotient(?a, ?b, ?c) -> (?r <http://example/quotient> ?c) .";
> GenericRuleReasoner reasoner = new
> GenericRuleReasoner(Rule.parseRules(rules));
> @Test
> public void test1k0() {
> Model model = ModelFactory.createDefaultModel();
> RDFParser.fromString(
> "<http://example/decimal-decimal> <http://example/a>
> 1.0 ; <http://example/b> 1.0 ." +
> "<http://example/double-decimal>
> <http://example/a> 1.0e0 ; <http://example/b> 1.0 ." +
> "<http://example/decimal-double>
> <http://example/a> 1.0 ; <http://example/b> 1.0e0 ." +
> "<http://example/double-double>
> <http://example/a> 1.0e0 ; <http://example/b> 1.0e0 .")
> .lang(Lang.TTL).parse(model);
> System.out.println("Original Statement:");
> model.listStatements().forEach(s -> System.out.println(s));
> System.out.println("Deducted Statement:");
> InfModel infModel = ModelFactory.createInfModel(reasoner, model);
> infModel.getDeductionsModel().listStatements().forEach(s ->
> System.out.println(s));
> infModel.getDeductionsModel().listStatements(null, sum, (RDFNode)
> null)
> .forEach(s -> Assertions.assertEquals(s.getDouble(), 2.0,
> s.getSubject().getLocalName()));
> infModel.getDeductionsModel().listStatements(null, difference,
> (RDFNode) null)
> .forEach(s -> Assertions.assertEquals(s.getDouble(), 0.0,
> s.getSubject().getLocalName()));
> infModel.getDeductionsModel().listStatements(null, product, (RDFNode)
> null)
> .forEach(s -> Assertions.assertEquals(s.getDouble(), 1.0,
> s.getSubject().getLocalName()));
> infModel.getDeductionsModel().listStatements(null, quotient,
> (RDFNode) null)
> .forEach(s -> Assertions.assertEquals(s.getDouble(), 1.0,
> s.getSubject().getLocalName()));
> }
> @Test
> public void test1k1() {
> Model model = ModelFactory.createDefaultModel();
> RDFParser.fromString(
> "<http://example/decimal-decimal> <http://example/a>
> 1.1 ; <http://example/b> 1.1 ." +
> "<http://example/double-decimal>
> <http://example/a> 1.1e0 ; <http://example/b> 1.1 ." +
> "<http://example/decimal-double>
> <http://example/a> 1.1 ; <http://example/b> 1.1e0 ." +
> "<http://example/double-double>
> <http://example/a> 1.1e0 ; <http://example/b> 1.1e0 .")
> .lang(Lang.TTL).parse(model);
> System.out.println("Original Statement:");
> model.listStatements().forEach(s -> System.out.println(s));
> System.out.println("Deducted Statement:");
> InfModel infModel = ModelFactory.createInfModel(reasoner, model);
> infModel.getDeductionsModel().listStatements().forEach(s ->
> System.out.println(s));
> infModel.getDeductionsModel().listStatements(null, sum, (RDFNode)
> null)
> .forEach(s -> Assertions.assertEquals(s.getDouble(), 2.2,
> s.getSubject().getLocalName()));
> infModel.getDeductionsModel().listStatements(null, difference,
> (RDFNode) null)
> .forEach(s -> Assertions.assertEquals(s.getDouble(), 0.0,
> s.getSubject().getLocalName()));
> infModel.getDeductionsModel().listStatements(null, product, (RDFNode)
> null)
> .forEach(s -> Assertions.assertEquals(s.getDouble(), 1.21,
> s.getSubject().getLocalName()));
> infModel.getDeductionsModel().listStatements(null, quotient,
> (RDFNode) null)
> .forEach(s -> Assertions.assertEquals(s.getDouble(), 1.0,
> s.getSubject().getLocalName()));
> }
> @Test
> public void test0k1() {
> Model model = ModelFactory.createDefaultModel();
> RDFParser.fromString(
> "<http://example/decimal-decimal> <http://example/a>
> 0.1 ; <http://example/b> 0.1 ." +
> "<http://example/double-decimal>
> <http://example/a> 0.1e0 ; <http://example/b> 0.1 ." +
> "<http://example/decimal-double>
> <http://example/a> 0.1 ; <http://example/b> 0.1e0 ." +
> "<http://example/double-double>
> <http://example/a> 0.1e0 ; <http://example/b> 0.1e0 .")
> .lang(Lang.TTL).parse(model);
> System.out.println("Original Statement:");
> model.listStatements().forEach(s -> System.out.println(s));
> System.out.println("Deducted Statement:");
> InfModel infModel = ModelFactory.createInfModel(reasoner, model);
> infModel.getDeductionsModel().listStatements().forEach(s ->
> System.out.println(s));
> infModel.getDeductionsModel().listStatements(null, sum, (RDFNode)
> null)
> .forEach(s -> Assertions.assertEquals(s.getDouble(), 0.2,
> s.getSubject().getLocalName()));
> infModel.getDeductionsModel().listStatements(null, difference,
> (RDFNode) null)
> .forEach(s -> Assertions.assertEquals(s.getDouble(), 0.0,
> s.getSubject().getLocalName()));
> infModel.getDeductionsModel().listStatements(null, product, (RDFNode)
> null)
> .forEach(s -> Assertions.assertEquals(s.getDouble(), 0.01,
> s.getSubject().getLocalName()));
> infModel.getDeductionsModel().listStatements(null, quotient,
> (RDFNode) null)
> .forEach(s -> Assertions.assertEquals(s.getDouble(), 1.0,
> s.getSubject().getLocalName()));
> }
> }
> {code}
>
--
This message was sent by Atlassian Jira
(v8.20.10#820010)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]