[ 
https://issues.apache.org/jira/browse/JENA-2355?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17772480#comment-17772480
 ] 

Andy Seaborne commented on JENA-2355:
-------------------------------------

The XSD rules only promote to float/double if one of the arguments is already 
float/double.

This finds the closest match for a pair of operands to the signature of the 
function and a 2-argument function is one of:

operation(integer, integer)
operation(decimal, decimal)
operation(double, double)
operation(float, float)

So the difference to Util#compare is that it does double->decimal, which isn't 
always possible (INF, NaN).

> Should this be changed too?

IMO Yes.


> 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]

Reply via email to