diff --git a/RDFSharp.Test/Model/RDFGraphTest.cs b/RDFSharp.Test/Model/RDFGraphTest.cs index 6972979d..cb0d5667 100644 --- a/RDFSharp.Test/Model/RDFGraphTest.cs +++ b/RDFSharp.Test/Model/RDFGraphTest.cs @@ -1925,14 +1925,19 @@ public void ShouldRaiseExceptionOnImportingFromRelativeUri() [TestMethod] public void ShouldExtractDatatypeDefinitionsFromGraph() { - RDFDatatype exLength6 = new RDFDatatype(new Uri("ex:length6"), RDFModelEnums.RDFDatatypes.XSD_STRING, [ new RDFLengthFacet(6) ]); + RDFDatatype exLength6 = new RDFDatatype(new Uri("ex:length6"), RDFModelEnums.RDFDatatypes.XSD_STRING, [ new RDFLengthFacet(6) ]); RDFDatatype exMinLength6 = new RDFDatatype(new Uri("ex:minlength6"), RDFModelEnums.RDFDatatypes.XSD_STRING, [ new RDFMinLengthFacet(6) ]); RDFDatatype exMaxLength6 = new RDFDatatype(new Uri("ex:maxlength6"), RDFModelEnums.RDFDatatypes.XSD_STRING, [ new RDFMaxLengthFacet(6) ]); RDFDatatype exMaxInclusive6 = new RDFDatatype(new Uri("ex:maxinclusive6"), RDFModelEnums.RDFDatatypes.XSD_DOUBLE, [new RDFMaxInclusiveFacet(6)]); RDFDatatype exMinInclusive6 = new RDFDatatype(new Uri("ex:mininclusive6"), RDFModelEnums.RDFDatatypes.XSD_DOUBLE, [new RDFMinInclusiveFacet(6)]); RDFDatatype exMaxExclusive6 = new RDFDatatype(new Uri("ex:maxexclusive6"), RDFModelEnums.RDFDatatypes.XSD_DOUBLE, [new RDFMaxExclusiveFacet(6)]); RDFDatatype exMinExclusive6 = new RDFDatatype(new Uri("ex:minexclusive6"), RDFModelEnums.RDFDatatypes.XSD_DOUBLE, [new RDFMinExclusiveFacet(6)]); - RDFDatatype exPatternEx = new RDFDatatype(new Uri("ex:patternex"), RDFModelEnums.RDFDatatypes.XSD_STRING, [ new RDFPatternFacet("^ex") ]); + RDFDatatype exMaxInclusive6R = new RDFDatatype(new Uri("ex:maxinclusive6R"), RDFModelEnums.RDFDatatypes.OWL_RATIONAL, [new RDFMaxInclusiveFacet(6)]); + RDFDatatype exMinInclusive6R = new RDFDatatype(new Uri("ex:mininclusive6R"), RDFModelEnums.RDFDatatypes.OWL_RATIONAL, [new RDFMinInclusiveFacet(6)]); + RDFDatatype exMaxExclusive6R = new RDFDatatype(new Uri("ex:maxexclusive6R"), RDFModelEnums.RDFDatatypes.OWL_RATIONAL, [new RDFMaxExclusiveFacet(6)]); + RDFDatatype exMinExclusive6R = new RDFDatatype(new Uri("ex:minexclusive6R"), RDFModelEnums.RDFDatatypes.OWL_RATIONAL, [new RDFMinExclusiveFacet(6)]); + RDFDatatype aliasRational = new RDFDatatype(new Uri("ex:aliasRational"), RDFModelEnums.RDFDatatypes.OWL_RATIONAL, null); + RDFDatatype exPatternEx = new RDFDatatype(new Uri("ex:patternex"), RDFModelEnums.RDFDatatypes.XSD_STRING, [ new RDFPatternFacet("^ex") ]); RDFDatatype exInteger = new RDFDatatype(new Uri("ex:integer"), RDFModelEnums.RDFDatatypes.XSD_INTEGER, null); RDFGraph graph = new RDFGraph() .AddDatatype(exLength6) @@ -1942,6 +1947,11 @@ public void ShouldExtractDatatypeDefinitionsFromGraph() .AddDatatype(exMinInclusive6) .AddDatatype(exMaxExclusive6) .AddDatatype(exMinExclusive6) + .AddDatatype(exMaxInclusive6R) + .AddDatatype(exMinInclusive6R) + .AddDatatype(exMaxExclusive6R) + .AddDatatype(exMinExclusive6R) + .AddDatatype(aliasRational) .AddDatatype(exPatternEx) .AddDatatype(exInteger); List datatypes = graph.ExtractDatatypeDefinitions(); @@ -1974,6 +1984,25 @@ public void ShouldExtractDatatypeDefinitionsFromGraph() && dt.TargetDatatype == RDFModelEnums.RDFDatatypes.XSD_DOUBLE && dt.Facets.Single() is RDFMinExclusiveFacet minexclusiveFacet && minexclusiveFacet.ExclusiveLowerBound == 6)); + Assert.IsTrue(datatypes.Any(dt => string.Equals(dt.URI.ToString(), "ex:maxinclusive6R") + && dt.TargetDatatype == RDFModelEnums.RDFDatatypes.OWL_RATIONAL + && dt.Facets.Single() is RDFMaxInclusiveFacet maxinclusiveFacet + && maxinclusiveFacet.InclusiveUpperBound == 6)); + Assert.IsTrue(datatypes.Any(dt => string.Equals(dt.URI.ToString(), "ex:mininclusive6R") + && dt.TargetDatatype == RDFModelEnums.RDFDatatypes.OWL_RATIONAL + && dt.Facets.Single() is RDFMinInclusiveFacet mininclusiveFacet + && mininclusiveFacet.InclusiveLowerBound == 6)); + Assert.IsTrue(datatypes.Any(dt => string.Equals(dt.URI.ToString(), "ex:maxexclusive6R") + && dt.TargetDatatype == RDFModelEnums.RDFDatatypes.OWL_RATIONAL + && dt.Facets.Single() is RDFMaxExclusiveFacet maxexclusiveFacet + && maxexclusiveFacet.ExclusiveUpperBound == 6)); + Assert.IsTrue(datatypes.Any(dt => string.Equals(dt.URI.ToString(), "ex:minexclusive6R") + && dt.TargetDatatype == RDFModelEnums.RDFDatatypes.OWL_RATIONAL + && dt.Facets.Single() is RDFMinExclusiveFacet minexclusiveFacet + && minexclusiveFacet.ExclusiveLowerBound == 6)); + Assert.IsTrue(datatypes.Any(dt => string.Equals(dt.URI.ToString(), "ex:aliasRational") + && dt.TargetDatatype == RDFModelEnums.RDFDatatypes.OWL_RATIONAL + && dt.Facets.Count == 0)); Assert.IsTrue(datatypes.Any(dt => string.Equals(dt.URI.ToString(), "ex:patternex") && dt.TargetDatatype == RDFModelEnums.RDFDatatypes.XSD_STRING && dt.Facets.Single() is RDFPatternFacet patternFacet diff --git a/RDFSharp.Test/Model/RDFModelUtilitiesTest.cs b/RDFSharp.Test/Model/RDFModelUtilitiesTest.cs index c238c40c..3ad046fb 100644 --- a/RDFSharp.Test/Model/RDFModelUtilitiesTest.cs +++ b/RDFSharp.Test/Model/RDFModelUtilitiesTest.cs @@ -1558,6 +1558,7 @@ public void ShouldNotGetGraphNamespaces() [DataRow("http://www.w3.org/2001/XMLSchema#NCName", RDFModelEnums.RDFDatatypes.XSD_NCNAME)] [DataRow("http://www.w3.org/2001/XMLSchema#ID", RDFModelEnums.RDFDatatypes.XSD_ID)] [DataRow("http://www.w3.org/2002/07/owl#real", RDFModelEnums.RDFDatatypes.OWL_REAL)] + [DataRow("http://www.w3.org/2002/07/owl#rational", RDFModelEnums.RDFDatatypes.OWL_RATIONAL)] [DataRow("http://www.opengis.net/ont/geosparql#gmlLiteral", RDFModelEnums.RDFDatatypes.GEOSPARQL_GML)] [DataRow("http://www.opengis.net/ont/geosparql#wktLiteral", RDFModelEnums.RDFDatatypes.GEOSPARQL_WKT)] [DataRow("http://www.w3.org/2006/time#generalDay", RDFModelEnums.RDFDatatypes.TIME_GENERALDAY)] @@ -1612,6 +1613,7 @@ public void ShouldGetDatatypeFromEnum(string expected, RDFModelEnums.RDFDatatype [DataRow("http://www.w3.org/2001/XMLSchema#NCName", RDFModelEnums.RDFDatatypes.XSD_NCNAME)] [DataRow("http://www.w3.org/2001/XMLSchema#ID", RDFModelEnums.RDFDatatypes.XSD_ID)] [DataRow("http://www.w3.org/2002/07/owl#real", RDFModelEnums.RDFDatatypes.OWL_REAL)] + [DataRow("http://www.w3.org/2002/07/owl#rational", RDFModelEnums.RDFDatatypes.OWL_RATIONAL)] [DataRow("http://www.opengis.net/ont/geosparql#gmlLiteral", RDFModelEnums.RDFDatatypes.GEOSPARQL_GML)] [DataRow("http://www.opengis.net/ont/geosparql#wktLiteral", RDFModelEnums.RDFDatatypes.GEOSPARQL_WKT)] [DataRow("http://www.w3.org/2006/time#generalDay", RDFModelEnums.RDFDatatypes.TIME_GENERALDAY)] diff --git a/RDFSharp.Test/Model/RDFTypedLiteralTest.cs b/RDFSharp.Test/Model/RDFTypedLiteralTest.cs index 9f7e568c..846ecbf6 100644 --- a/RDFSharp.Test/Model/RDFTypedLiteralTest.cs +++ b/RDFSharp.Test/Model/RDFTypedLiteralTest.cs @@ -305,6 +305,10 @@ public void ShouldCreateTypedLiteralOfDatetimeCategory(string value, RDFModelEnu [DataRow("1", RDFModelEnums.RDFDatatypes.XSD_POSITIVEINTEGER)] [DataRow(" 1 ", RDFModelEnums.RDFDatatypes.XSD_POSITIVEINTEGER)] [DataRow("4", RDFModelEnums.RDFDatatypes.OWL_REAL)] + [DataRow("4", RDFModelEnums.RDFDatatypes.OWL_RATIONAL)] + [DataRow("4/9", RDFModelEnums.RDFDatatypes.OWL_RATIONAL)] + [DataRow("-4", RDFModelEnums.RDFDatatypes.OWL_RATIONAL)] + [DataRow("-4/9", RDFModelEnums.RDFDatatypes.OWL_RATIONAL)] public void ShouldCreateTypedLiteralOfDecimalCategory(string value, RDFModelEnums.RDFDatatypes datatype) { RDFTypedLiteral tl = new RDFTypedLiteral(value, datatype); @@ -631,6 +635,17 @@ public void ShouldNotCreateTypedLiteralOfDatetimeCategory(string value, RDFModel [DataRow("", RDFModelEnums.RDFDatatypes.OWL_REAL)] [DataRow(null, RDFModelEnums.RDFDatatypes.OWL_REAL)] [DataRow("4,00", RDFModelEnums.RDFDatatypes.OWL_REAL)] + [DataRow("4/", RDFModelEnums.RDFDatatypes.OWL_RATIONAL)] + [DataRow("4/0", RDFModelEnums.RDFDatatypes.OWL_RATIONAL)] + [DataRow("4/-9", RDFModelEnums.RDFDatatypes.OWL_RATIONAL)] + [DataRow("-4/", RDFModelEnums.RDFDatatypes.OWL_RATIONAL)] + [DataRow("-4/0", RDFModelEnums.RDFDatatypes.OWL_RATIONAL)] + [DataRow("/", RDFModelEnums.RDFDatatypes.OWL_RATIONAL)] + [DataRow("-/", RDFModelEnums.RDFDatatypes.OWL_RATIONAL)] + [DataRow("/-", RDFModelEnums.RDFDatatypes.OWL_RATIONAL)] + [DataRow("/9", RDFModelEnums.RDFDatatypes.OWL_RATIONAL)] + [DataRow("/-9", RDFModelEnums.RDFDatatypes.OWL_RATIONAL)] + [DataRow("4/02", RDFModelEnums.RDFDatatypes.OWL_RATIONAL)] public void ShouldNotCreateTypedLiteralOfDecimalCategory(string value, RDFModelEnums.RDFDatatypes datatype) => Assert.ThrowsException(() => new RDFTypedLiteral(value, datatype)); diff --git a/RDFSharp.Test/Query/Mirella/Algebra/Aggregators/RDFSumAggregatorTest.cs b/RDFSharp.Test/Query/Mirella/Algebra/Aggregators/RDFSumAggregatorTest.cs index 554129a4..395c673a 100644 --- a/RDFSharp.Test/Query/Mirella/Algebra/Aggregators/RDFSumAggregatorTest.cs +++ b/RDFSharp.Test/Query/Mirella/Algebra/Aggregators/RDFSumAggregatorTest.cs @@ -75,7 +75,7 @@ public void ShouldApplyModifierWithSumAggregator() table.Columns.Add("?B", typeof(string)); table.Columns.Add("?C", typeof(string)); DataRow row0 = table.NewRow(); - row0["?A"] = new RDFTypedLiteral("27", RDFModelEnums.RDFDatatypes.XSD_FLOAT).ToString(); + row0["?A"] = new RDFTypedLiteral("54/2", RDFModelEnums.RDFDatatypes.OWL_RATIONAL).ToString(); row0["?B"] = new RDFPlainLiteral("hello", "en-US").ToString(); row0["?C"] = new RDFResource("ex:value1").ToString(); table.Rows.Add(row0); diff --git a/RDFSharp.Test/Query/Mirella/Algebra/Expressions/RDFAbsExpressionTest.cs b/RDFSharp.Test/Query/Mirella/Algebra/Expressions/RDFAbsExpressionTest.cs index 5fd0371f..f5f9679e 100644 --- a/RDFSharp.Test/Query/Mirella/Algebra/Expressions/RDFAbsExpressionTest.cs +++ b/RDFSharp.Test/Query/Mirella/Algebra/Expressions/RDFAbsExpressionTest.cs @@ -15,7 +15,6 @@ limitations under the License. */ using Microsoft.VisualStudio.TestTools.UnitTesting; -using System.Collections.Generic; using System.Data; using RDFSharp.Model; using RDFSharp.Query; @@ -67,7 +66,7 @@ public void ShouldApplyExpressionWithExpressionAndCalculateResult() table.Columns.Add("?A", typeof(string)); table.Columns.Add("?B", typeof(string)); DataRow row = table.NewRow(); - row["?A"] = new RDFTypedLiteral("5.1", RDFModelEnums.RDFDatatypes.XSD_DOUBLE).ToString(); + row["?A"] = new RDFTypedLiteral("10/2", RDFModelEnums.RDFDatatypes.OWL_RATIONAL).ToString(); row["?B"] = new RDFTypedLiteral("25", RDFModelEnums.RDFDatatypes.XSD_INT).ToString(); table.Rows.Add(row); table.AcceptChanges(); @@ -77,7 +76,7 @@ public void ShouldApplyExpressionWithExpressionAndCalculateResult() RDFPatternMember expressionResult = expression.ApplyExpression(table.Rows[0]); Assert.IsNotNull(expressionResult); - Assert.IsTrue(expressionResult.Equals(new RDFTypedLiteral("19.9", RDFModelEnums.RDFDatatypes.XSD_DOUBLE))); + Assert.IsTrue(expressionResult.Equals(new RDFTypedLiteral("20", RDFModelEnums.RDFDatatypes.XSD_DOUBLE))); } [TestMethod] diff --git a/RDFSharp.Test/Query/Mirella/Algebra/Expressions/RDFAddExpressionTest.cs b/RDFSharp.Test/Query/Mirella/Algebra/Expressions/RDFAddExpressionTest.cs index ae93b36b..dbc54ee9 100644 --- a/RDFSharp.Test/Query/Mirella/Algebra/Expressions/RDFAddExpressionTest.cs +++ b/RDFSharp.Test/Query/Mirella/Algebra/Expressions/RDFAddExpressionTest.cs @@ -15,7 +15,6 @@ limitations under the License. */ using Microsoft.VisualStudio.TestTools.UnitTesting; -using System.Collections.Generic; using System.Data; using RDFSharp.Model; using RDFSharp.Query; @@ -173,7 +172,7 @@ public void ShouldApplyExpressionWithEEAndCalculateResult() table.Columns.Add("?A", typeof(string)); table.Columns.Add("?B", typeof(string)); DataRow row = table.NewRow(); - row["?A"] = new RDFTypedLiteral("5.1", RDFModelEnums.RDFDatatypes.XSD_DOUBLE).ToString(); + row["?A"] = new RDFTypedLiteral("10/2", RDFModelEnums.RDFDatatypes.OWL_RATIONAL).ToString(); row["?B"] = new RDFTypedLiteral("25", RDFModelEnums.RDFDatatypes.XSD_INT).ToString(); table.Rows.Add(row); table.AcceptChanges(); @@ -184,7 +183,7 @@ public void ShouldApplyExpressionWithEEAndCalculateResult() RDFPatternMember expressionResult = expression.ApplyExpression(table.Rows[0]); Assert.IsNotNull(expressionResult); - Assert.IsTrue(expressionResult.Equals(new RDFTypedLiteral("60.2", RDFModelEnums.RDFDatatypes.XSD_DOUBLE))); + Assert.IsTrue(expressionResult.Equals(new RDFTypedLiteral("60", RDFModelEnums.RDFDatatypes.XSD_DOUBLE))); } [TestMethod] @@ -195,7 +194,7 @@ public void ShouldApplyExpressionWithEEAndCalculateResult2() table.Columns.Add("?B", typeof(string)); DataRow row = table.NewRow(); row["?A"] = new RDFTypedLiteral("5.1", RDFModelEnums.RDFDatatypes.XSD_DOUBLE).ToString(); - row["?B"] = new RDFTypedLiteral("25", RDFModelEnums.RDFDatatypes.XSD_INT).ToString(); + row["?B"] = new RDFTypedLiteral("50/2", RDFModelEnums.RDFDatatypes.OWL_RATIONAL).ToString(); table.Rows.Add(row); table.AcceptChanges(); diff --git a/RDFSharp.Test/Query/Mirella/Algebra/Expressions/RDFCeilExpressionTest.cs b/RDFSharp.Test/Query/Mirella/Algebra/Expressions/RDFCeilExpressionTest.cs index 22a9d81e..4fa99a5e 100644 --- a/RDFSharp.Test/Query/Mirella/Algebra/Expressions/RDFCeilExpressionTest.cs +++ b/RDFSharp.Test/Query/Mirella/Algebra/Expressions/RDFCeilExpressionTest.cs @@ -15,7 +15,6 @@ limitations under the License. */ using Microsoft.VisualStudio.TestTools.UnitTesting; -using System.Collections.Generic; using System.Data; using RDFSharp.Model; using RDFSharp.Query; @@ -68,7 +67,7 @@ public void ShouldApplyExpressionWithExpressionAndCalculateResult() table.Columns.Add("?B", typeof(string)); DataRow row = table.NewRow(); row["?A"] = new RDFTypedLiteral("5.1", RDFModelEnums.RDFDatatypes.XSD_DOUBLE).ToString(); - row["?B"] = new RDFTypedLiteral("25", RDFModelEnums.RDFDatatypes.XSD_INT).ToString(); + row["?B"] = new RDFTypedLiteral("50/2", RDFModelEnums.RDFDatatypes.OWL_RATIONAL).ToString(); table.Rows.Add(row); table.AcceptChanges(); @@ -87,7 +86,7 @@ public void ShouldApplyExpressionWithVariableAndCalculateResult() table.Columns.Add("?A", typeof(string)); table.Columns.Add("?B", typeof(string)); DataRow row = table.NewRow(); - row["?A"] = new RDFTypedLiteral("5.1", RDFModelEnums.RDFDatatypes.XSD_DOUBLE).ToString(); + row["?A"] = new RDFTypedLiteral("11/2", RDFModelEnums.RDFDatatypes.OWL_RATIONAL).ToString(); row["?B"] = new RDFTypedLiteral("25", RDFModelEnums.RDFDatatypes.XSD_INT).ToString(); table.Rows.Add(row); table.AcceptChanges(); diff --git a/RDFSharp.Test/Query/Mirella/Algebra/Expressions/RDFComparisonExpressionTest.cs b/RDFSharp.Test/Query/Mirella/Algebra/Expressions/RDFComparisonExpressionTest.cs index 72ea0a98..56c9ea6b 100644 --- a/RDFSharp.Test/Query/Mirella/Algebra/Expressions/RDFComparisonExpressionTest.cs +++ b/RDFSharp.Test/Query/Mirella/Algebra/Expressions/RDFComparisonExpressionTest.cs @@ -15,7 +15,6 @@ limitations under the License. */ using Microsoft.VisualStudio.TestTools.UnitTesting; -using System.Collections.Generic; using System.Data; using RDFSharp.Model; using RDFSharp.Query; @@ -402,7 +401,7 @@ public void ShouldApplyExpressionWithEEAndCalculateResultTrue() table.Columns.Add("?B", typeof(string)); DataRow row = table.NewRow(); row["?A"] = new RDFTypedLiteral("5.1", RDFModelEnums.RDFDatatypes.XSD_DOUBLE).ToString(); - row["?B"] = new RDFTypedLiteral("25", RDFModelEnums.RDFDatatypes.XSD_INT).ToString(); + row["?B"] = new RDFTypedLiteral("50/2", RDFModelEnums.RDFDatatypes.OWL_RATIONAL).ToString(); table.Rows.Add(row); table.AcceptChanges(); @@ -422,7 +421,7 @@ public void ShouldApplyExpressionWithEEAndCalculateResultFalse() table.Columns.Add("?A", typeof(string)); table.Columns.Add("?B", typeof(string)); DataRow row = table.NewRow(); - row["?A"] = new RDFTypedLiteral("5.1", RDFModelEnums.RDFDatatypes.XSD_DOUBLE).ToString(); + row["?A"] = new RDFTypedLiteral("10/2", RDFModelEnums.RDFDatatypes.OWL_RATIONAL).ToString(); row["?B"] = new RDFTypedLiteral("25", RDFModelEnums.RDFDatatypes.XSD_INT).ToString(); table.Rows.Add(row); table.AcceptChanges(); diff --git a/RDFSharp.Test/Query/Mirella/Algebra/Expressions/RDFFloorExpressionTest.cs b/RDFSharp.Test/Query/Mirella/Algebra/Expressions/RDFFloorExpressionTest.cs index 4c650ed5..10d23b4f 100644 --- a/RDFSharp.Test/Query/Mirella/Algebra/Expressions/RDFFloorExpressionTest.cs +++ b/RDFSharp.Test/Query/Mirella/Algebra/Expressions/RDFFloorExpressionTest.cs @@ -15,7 +15,6 @@ limitations under the License. */ using Microsoft.VisualStudio.TestTools.UnitTesting; -using System.Collections.Generic; using System.Data; using RDFSharp.Model; using RDFSharp.Query; @@ -67,8 +66,8 @@ public void ShouldApplyExpressionWithExpressionAndCalculateResult() table.Columns.Add("?A", typeof(string)); table.Columns.Add("?B", typeof(string)); DataRow row = table.NewRow(); - row["?A"] = new RDFTypedLiteral("5.1", RDFModelEnums.RDFDatatypes.XSD_DOUBLE).ToString(); - row["?B"] = new RDFTypedLiteral("25", RDFModelEnums.RDFDatatypes.XSD_INT).ToString(); + row["?A"] = new RDFTypedLiteral("10/2", RDFModelEnums.RDFDatatypes.OWL_RATIONAL).ToString(); + row["?B"] = new RDFTypedLiteral("25.1", RDFModelEnums.RDFDatatypes.XSD_DOUBLE).ToString(); table.Rows.Add(row); table.AcceptChanges(); @@ -88,16 +87,16 @@ public void ShouldApplyExpressionWithVariableAndCalculateResult() table.Columns.Add("?B", typeof(string)); DataRow row = table.NewRow(); row["?A"] = new RDFTypedLiteral("5.1", RDFModelEnums.RDFDatatypes.XSD_DOUBLE).ToString(); - row["?B"] = new RDFTypedLiteral("25", RDFModelEnums.RDFDatatypes.XSD_INT).ToString(); + row["?B"] = new RDFTypedLiteral("50/2", RDFModelEnums.RDFDatatypes.OWL_RATIONAL).ToString(); table.Rows.Add(row); table.AcceptChanges(); RDFFloorExpression expression = new RDFFloorExpression( - new RDFVariable("?A")); + new RDFVariable("?B")); RDFPatternMember expressionResult = expression.ApplyExpression(table.Rows[0]); Assert.IsNotNull(expressionResult); - Assert.IsTrue(expressionResult.Equals(new RDFTypedLiteral("5", RDFModelEnums.RDFDatatypes.XSD_DOUBLE))); + Assert.IsTrue(expressionResult.Equals(new RDFTypedLiteral("25", RDFModelEnums.RDFDatatypes.XSD_DOUBLE))); } [TestMethod] diff --git a/RDFSharp.Test/Query/Mirella/Algebra/Expressions/RDFRoundExpressionTest.cs b/RDFSharp.Test/Query/Mirella/Algebra/Expressions/RDFRoundExpressionTest.cs index ef94bcd6..368609a3 100644 --- a/RDFSharp.Test/Query/Mirella/Algebra/Expressions/RDFRoundExpressionTest.cs +++ b/RDFSharp.Test/Query/Mirella/Algebra/Expressions/RDFRoundExpressionTest.cs @@ -15,7 +15,6 @@ limitations under the License. */ using Microsoft.VisualStudio.TestTools.UnitTesting; -using System.Collections.Generic; using System.Data; using RDFSharp.Model; using RDFSharp.Query; @@ -68,7 +67,7 @@ public void ShouldApplyExpressionWithExpressionAndCalculateResult() table.Columns.Add("?B", typeof(string)); DataRow row = table.NewRow(); row["?A"] = new RDFTypedLiteral("5.1", RDFModelEnums.RDFDatatypes.XSD_DOUBLE).ToString(); - row["?B"] = new RDFTypedLiteral("25", RDFModelEnums.RDFDatatypes.XSD_INT).ToString(); + row["?B"] = new RDFTypedLiteral("50/2", RDFModelEnums.RDFDatatypes.OWL_RATIONAL).ToString(); table.Rows.Add(row); table.AcceptChanges(); @@ -87,7 +86,7 @@ public void ShouldApplyExpressionWithVariableAndCalculateResult() table.Columns.Add("?A", typeof(string)); table.Columns.Add("?B", typeof(string)); DataRow row = table.NewRow(); - row["?A"] = new RDFTypedLiteral("5.7", RDFModelEnums.RDFDatatypes.XSD_DOUBLE).ToString(); + row["?A"] = new RDFTypedLiteral("11/4", RDFModelEnums.RDFDatatypes.OWL_RATIONAL).ToString(); row["?B"] = new RDFTypedLiteral("25", RDFModelEnums.RDFDatatypes.XSD_INT).ToString(); table.Rows.Add(row); table.AcceptChanges(); @@ -97,7 +96,7 @@ public void ShouldApplyExpressionWithVariableAndCalculateResult() RDFPatternMember expressionResult = expression.ApplyExpression(table.Rows[0]); Assert.IsNotNull(expressionResult); - Assert.IsTrue(expressionResult.Equals(new RDFTypedLiteral("6", RDFModelEnums.RDFDatatypes.XSD_DOUBLE))); + Assert.IsTrue(expressionResult.Equals(new RDFTypedLiteral("3", RDFModelEnums.RDFDatatypes.XSD_DOUBLE))); } [TestMethod] diff --git a/RDFSharp.Test/Query/Mirella/Algebra/Filters/RDFComparisonFilterTest.cs b/RDFSharp.Test/Query/Mirella/Algebra/Filters/RDFComparisonFilterTest.cs index dedab822..c154ceb4 100644 --- a/RDFSharp.Test/Query/Mirella/Algebra/Filters/RDFComparisonFilterTest.cs +++ b/RDFSharp.Test/Query/Mirella/Algebra/Filters/RDFComparisonFilterTest.cs @@ -188,7 +188,7 @@ public void ShouldCreateComparisonFilterWithVariableVsVariableAndKeepRow1() table.Columns.Add("?A", typeof(string)); table.Columns.Add("?B", typeof(string)); DataRow row = table.NewRow(); - row["?A"] = new RDFTypedLiteral("27.7", RDFModelEnums.RDFDatatypes.XSD_FLOAT).ToString(); + row["?A"] = new RDFTypedLiteral("54/2", RDFModelEnums.RDFDatatypes.OWL_RATIONAL).ToString(); row["?B"] = new RDFTypedLiteral("30", RDFModelEnums.RDFDatatypes.XSD_INT).ToString(); table.Rows.Add(row); table.AcceptChanges(); @@ -207,7 +207,25 @@ public void ShouldCreateComparisonFilterWithVariableVsVariableAndKeepRow2() table.Columns.Add("?B", typeof(string)); DataRow row = table.NewRow(); row["?A"] = new RDFTypedLiteral("27.7", RDFModelEnums.RDFDatatypes.XSD_FLOAT).ToString(); - row["?B"] = new RDFTypedLiteral("30", RDFModelEnums.RDFDatatypes.XSD_INT).ToString(); + row["?B"] = new RDFTypedLiteral("60/2", RDFModelEnums.RDFDatatypes.OWL_RATIONAL).ToString(); + table.Rows.Add(row); + table.AcceptChanges(); + + RDFComparisonFilter filter = new RDFComparisonFilter(RDFQueryEnums.RDFComparisonFlavors.GreaterOrEqualThan, new RDFVariable("?B"), new RDFVariable("?A")); + bool keepRow = filter.ApplyFilter(table.Rows[0], false); + + Assert.IsTrue(keepRow); + } + + [TestMethod] + public void ShouldCreateComparisonFilterWithVariableVsVariablehavingOwlRationalsAndKeepRow2() + { + DataTable table = new DataTable(); + table.Columns.Add("?A", typeof(string)); + table.Columns.Add("?B", typeof(string)); + DataRow row = table.NewRow(); + row["?A"] = new RDFTypedLiteral("2/5", RDFModelEnums.RDFDatatypes.OWL_RATIONAL).ToString(); + row["?B"] = new RDFTypedLiteral("1/2", RDFModelEnums.RDFDatatypes.OWL_RATIONAL).ToString(); table.Rows.Add(row); table.AcceptChanges(); diff --git a/RDFSharp/Model/RDFModelEnums.cs b/RDFSharp/Model/RDFModelEnums.cs index 430181a5..8b60c7d9 100644 --- a/RDFSharp/Model/RDFModelEnums.cs +++ b/RDFSharp/Model/RDFModelEnums.cs @@ -315,7 +315,12 @@ public enum RDFDatatypes /// http://www.w3.org/2002/07/owl#real /// [Description("http://www.w3.org/2002/07/owl#real")] - OWL_REAL = 49 + OWL_REAL = 49, + /// + /// http://www.w3.org/2002/07/owl#rational + /// + [Description("http://www.w3.org/2002/07/owl#rational")] + OWL_RATIONAL = 50 }; /// diff --git a/RDFSharp/Model/RDFModelUtilities.cs b/RDFSharp/Model/RDFModelUtilities.cs index 99fcb830..995d1411 100644 --- a/RDFSharp/Model/RDFModelUtilities.cs +++ b/RDFSharp/Model/RDFModelUtilities.cs @@ -68,6 +68,10 @@ public static long CreateHash(string input) /// Regex to catch xsd:hexBinary typed literals /// internal static readonly Lazy hexBinary = new Lazy(() => new Regex(@"^([0-9a-fA-F]{2})*$", RegexOptions.Compiled)); + /// + /// Regex to catch owl:rational typed literals + /// + internal static readonly Lazy owlRational = new Lazy(() => new Regex(@"^(-)?([0-9])+(/([1-9])+([0-9])*)?$", RegexOptions.Compiled)); /// /// Alternative representations of boolean True @@ -187,8 +191,8 @@ internal static string EscapeControlCharsForXML(string data) internal static string TrimEnd(this string source, string value) { if (string.IsNullOrEmpty(source) - || string.IsNullOrEmpty(value) - || !source.EndsWith(value)) + || string.IsNullOrEmpty(value) + || !source.EndsWith(value)) return source; return source.Remove(source.LastIndexOf(value)); @@ -344,17 +348,35 @@ public static List ExtractDatatypeDefinitions(this RDFGraph graph) } //xsd:maxExclusive if (graph[facet, RDFVocabulary.XSD.MAX_EXCLUSIVE, null, null].FirstOrDefault()?.Object is RDFTypedLiteral facetMaxExclusive - && facetMaxExclusive.HasDecimalDatatype() && double.TryParse(facetMaxExclusive.Value, NumberStyles.Integer | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out double facetMaxExclusiveValue)) + && facetMaxExclusive.HasDecimalDatatype()) { - targetFacets.Add(new RDFMaxExclusiveFacet(facetMaxExclusiveValue)); - continue; + //owl:rational needs parsing and evaluation before being compared + if (facetMaxExclusive.Datatype.TargetDatatype == RDFModelEnums.RDFDatatypes.OWL_RATIONAL) + { + targetFacets.Add(new RDFMaxExclusiveFacet(Convert.ToDouble(ComputeOWLRationalValue(facetMaxExclusive), CultureInfo.InvariantCulture))); + continue; + } + if (double.TryParse(facetMaxExclusive.Value, NumberStyles.Integer | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out double facetMaxExclusiveValue)) + { + targetFacets.Add(new RDFMaxExclusiveFacet(facetMaxExclusiveValue)); + continue; + } } //xsd:maxInclusive if (graph[facet, RDFVocabulary.XSD.MAX_INCLUSIVE, null, null].FirstOrDefault()?.Object is RDFTypedLiteral facetMaxInclusive - && facetMaxInclusive.HasDecimalDatatype() && double.TryParse(facetMaxInclusive.Value, NumberStyles.Integer | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out double facetMaxInclusiveValue)) + && facetMaxInclusive.HasDecimalDatatype()) { - targetFacets.Add(new RDFMaxInclusiveFacet(facetMaxInclusiveValue)); - continue; + //owl:rational needs parsing and evaluation before being compared + if (facetMaxInclusive.Datatype.TargetDatatype == RDFModelEnums.RDFDatatypes.OWL_RATIONAL) + { + targetFacets.Add(new RDFMaxInclusiveFacet(Convert.ToDouble(ComputeOWLRationalValue(facetMaxInclusive), CultureInfo.InvariantCulture))); + continue; + } + if (double.TryParse(facetMaxInclusive.Value, NumberStyles.Integer | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out double facetMaxInclusiveValue)) + { + targetFacets.Add(new RDFMaxInclusiveFacet(facetMaxInclusiveValue)); + continue; + } } //xsd:maxLength if (graph[facet, RDFVocabulary.XSD.MAX_LENGTH, null, null].FirstOrDefault()?.Object is RDFTypedLiteral facetMaxLength @@ -365,17 +387,35 @@ public static List ExtractDatatypeDefinitions(this RDFGraph graph) } //xsd:minExclusive if (graph[facet, RDFVocabulary.XSD.MIN_EXCLUSIVE, null, null].FirstOrDefault()?.Object is RDFTypedLiteral facetMinExclusive - && facetMinExclusive.HasDecimalDatatype() && double.TryParse(facetMinExclusive.Value, NumberStyles.Integer | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out double facetMinExclusiveValue)) + && facetMinExclusive.HasDecimalDatatype()) { - targetFacets.Add(new RDFMinExclusiveFacet(facetMinExclusiveValue)); - continue; + //owl:rational needs parsing and evaluation before being compared + if (facetMinExclusive.Datatype.TargetDatatype == RDFModelEnums.RDFDatatypes.OWL_RATIONAL) + { + targetFacets.Add(new RDFMinExclusiveFacet(Convert.ToDouble(ComputeOWLRationalValue(facetMinExclusive), CultureInfo.InvariantCulture))); + continue; + } + if (double.TryParse(facetMinExclusive.Value, NumberStyles.Integer | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out double facetMinExclusiveValue)) + { + targetFacets.Add(new RDFMinExclusiveFacet(facetMinExclusiveValue)); + continue; + } } //xsd:minInclusive if (graph[facet, RDFVocabulary.XSD.MIN_INCLUSIVE, null, null].FirstOrDefault()?.Object is RDFTypedLiteral facetMinInclusive - && facetMinInclusive.HasDecimalDatatype() && double.TryParse(facetMinInclusive.Value, NumberStyles.Integer | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out double facetMinInclusiveValue)) + && facetMinInclusive.HasDecimalDatatype()) { - targetFacets.Add(new RDFMinInclusiveFacet(facetMinInclusiveValue)); - continue; + //owl:rational needs parsing and evaluation before being compared + if (facetMinInclusive.Datatype.TargetDatatype == RDFModelEnums.RDFDatatypes.OWL_RATIONAL) + { + targetFacets.Add(new RDFMinInclusiveFacet(Convert.ToDouble(ComputeOWLRationalValue(facetMinInclusive), CultureInfo.InvariantCulture))); + continue; + } + if (double.TryParse(facetMinInclusive.Value, NumberStyles.Integer | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out double facetMinInclusiveValue)) + { + targetFacets.Add(new RDFMinInclusiveFacet(facetMinInclusiveValue)); + continue; + } } //xsd:minLength if (graph[facet, RDFVocabulary.XSD.MIN_LENGTH, null, null].FirstOrDefault()?.Object is RDFTypedLiteral facetMinLength @@ -822,6 +862,10 @@ internal static (bool,string) ValidateTypedLiteral(string literalValue, RDFModel else return (false, literalValue); + case RDFModelEnums.RDFDatatypes.OWL_RATIONAL: + bool isValidOwlRational = owlRational.Value.Match(literalValue).Success; + return (isValidOwlRational, literalValue); + case RDFModelEnums.RDFDatatypes.XSD_DOUBLE: if (double.TryParse(literalValue, NumberStyles.Float, CultureInfo.InvariantCulture, out double outDouble)) return (true, Convert.ToString(outDouble, CultureInfo.InvariantCulture)); @@ -930,6 +974,15 @@ internal static (bool,string) ValidateTypedLiteral(string literalValue, RDFModel #endregion } } + + /// + /// Gets the numeric value of the given owl:rational typed literal + /// + internal static decimal ComputeOWLRationalValue(RDFTypedLiteral typedLiteral) + { + string[] owlRationalParts = typedLiteral.Value.Split('/'); + return decimal.Parse(owlRationalParts[0]) / decimal.Parse(owlRationalParts[1]); + } #endregion } } \ No newline at end of file diff --git a/RDFSharp/Model/RDFTypedLiteral.cs b/RDFSharp/Model/RDFTypedLiteral.cs index 1b246021..32fc6a58 100644 --- a/RDFSharp/Model/RDFTypedLiteral.cs +++ b/RDFSharp/Model/RDFTypedLiteral.cs @@ -181,6 +181,7 @@ public bool HasDecimalDatatype() case RDFModelEnums.RDFDatatypes.XSD_POSITIVEINTEGER: case RDFModelEnums.RDFDatatypes.XSD_NONPOSITIVEINTEGER: case RDFModelEnums.RDFDatatypes.OWL_REAL: + case RDFModelEnums.RDFDatatypes.OWL_RATIONAL: return true; default: return false; } diff --git a/RDFSharp/Query/Mirella/Algebra/Expressions/Abstractions/RDFMathExpression.cs b/RDFSharp/Query/Mirella/Algebra/Expressions/Abstractions/RDFMathExpression.cs index 2d1ee9db..470095ef 100644 --- a/RDFSharp/Query/Mirella/Algebra/Expressions/Abstractions/RDFMathExpression.cs +++ b/RDFSharp/Query/Mirella/Algebra/Expressions/Abstractions/RDFMathExpression.cs @@ -180,22 +180,26 @@ internal override RDFPatternMember ApplyExpression(DataRow row) #region Calculate Result if (leftArgumentPMember is RDFTypedLiteral leftArgumentTypedLiteral && leftArgumentTypedLiteral.HasDecimalDatatype() - && rightArgumentPMember is RDFTypedLiteral rightArgumentTypedLiteral - && rightArgumentTypedLiteral.HasDecimalDatatype()) + && rightArgumentPMember is RDFTypedLiteral rightArgumentTypedLiteral + && rightArgumentTypedLiteral.HasDecimalDatatype()) { - if (double.TryParse(leftArgumentTypedLiteral.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out double leftArgumentNumericValue) - && double.TryParse(rightArgumentTypedLiteral.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out double rightArgumentNumericValue)) - { - //Execute the arithmetical expression's comparison logics - if (this is RDFAddExpression) - expressionResult = new RDFTypedLiteral(Convert.ToString(leftArgumentNumericValue + rightArgumentNumericValue, CultureInfo.InvariantCulture), RDFModelEnums.RDFDatatypes.XSD_DOUBLE); - else if (this is RDFSubtractExpression) - expressionResult = new RDFTypedLiteral(Convert.ToString(leftArgumentNumericValue - rightArgumentNumericValue, CultureInfo.InvariantCulture), RDFModelEnums.RDFDatatypes.XSD_DOUBLE); - else if (this is RDFMultiplyExpression) - expressionResult = new RDFTypedLiteral(Convert.ToString(leftArgumentNumericValue * rightArgumentNumericValue, CultureInfo.InvariantCulture), RDFModelEnums.RDFDatatypes.XSD_DOUBLE); - else if (this is RDFDivideExpression && rightArgumentNumericValue != 0d) - expressionResult = new RDFTypedLiteral(Convert.ToString(leftArgumentNumericValue / rightArgumentNumericValue, CultureInfo.InvariantCulture), RDFModelEnums.RDFDatatypes.XSD_DOUBLE); - } + double? leftArgumentNumericValueFinal = null; + double? rightArgumentNumericValueFinal = null; + + //owl:rational needs parsing and evaluation before being compared (LEFT) + if (leftArgumentTypedLiteral.Datatype.TargetDatatype == RDFModelEnums.RDFDatatypes.OWL_RATIONAL) + leftArgumentNumericValueFinal = Convert.ToDouble(RDFModelUtilities.ComputeOWLRationalValue(leftArgumentTypedLiteral), CultureInfo.InvariantCulture); + //owl:rational needs parsing and evaluation before being compared (RIGHT) + if (rightArgumentTypedLiteral.Datatype.TargetDatatype == RDFModelEnums.RDFDatatypes.OWL_RATIONAL) + rightArgumentNumericValueFinal = Convert.ToDouble(RDFModelUtilities.ComputeOWLRationalValue(rightArgumentTypedLiteral), CultureInfo.InvariantCulture); + + //Compute the arithmetical expression if we have valid double values from the arguments + if (!leftArgumentNumericValueFinal.HasValue && double.TryParse(leftArgumentTypedLiteral.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out double leftArgumentNumericValue)) + leftArgumentNumericValueFinal = leftArgumentNumericValue; + if (!rightArgumentNumericValueFinal.HasValue && double.TryParse(rightArgumentTypedLiteral.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out double rightArgumentNumericValue)) + rightArgumentNumericValueFinal = rightArgumentNumericValue; + if (leftArgumentNumericValueFinal.HasValue && rightArgumentNumericValueFinal.HasValue) + expressionResult = EvaluateMathExpression(leftArgumentNumericValueFinal.Value, rightArgumentNumericValueFinal.Value); } #endregion } @@ -203,6 +207,23 @@ internal override RDFPatternMember ApplyExpression(DataRow row) return expressionResult; } + + /// + /// Compute the arithmetical expression on the given numeric parameters + /// + private RDFTypedLiteral EvaluateMathExpression(double leftArgumentNumericValue, double rightArgumentNumericValue) + { + if (this is RDFAddExpression) + return new RDFTypedLiteral(Convert.ToString(leftArgumentNumericValue + rightArgumentNumericValue, CultureInfo.InvariantCulture), RDFModelEnums.RDFDatatypes.XSD_DOUBLE); + else if (this is RDFSubtractExpression) + return new RDFTypedLiteral(Convert.ToString(leftArgumentNumericValue - rightArgumentNumericValue, CultureInfo.InvariantCulture), RDFModelEnums.RDFDatatypes.XSD_DOUBLE); + else if (this is RDFMultiplyExpression) + return new RDFTypedLiteral(Convert.ToString(leftArgumentNumericValue * rightArgumentNumericValue, CultureInfo.InvariantCulture), RDFModelEnums.RDFDatatypes.XSD_DOUBLE); + else if (this is RDFDivideExpression && rightArgumentNumericValue != 0d) + return new RDFTypedLiteral(Convert.ToString(leftArgumentNumericValue / rightArgumentNumericValue, CultureInfo.InvariantCulture), RDFModelEnums.RDFDatatypes.XSD_DOUBLE); + //Just to keep the compiler happy... + else return null; + } #endregion } } \ No newline at end of file diff --git a/RDFSharp/Query/Mirella/Algebra/Expressions/RDFAbsExpression.cs b/RDFSharp/Query/Mirella/Algebra/Expressions/RDFAbsExpression.cs index 3b083321..df7bb361 100644 --- a/RDFSharp/Query/Mirella/Algebra/Expressions/RDFAbsExpression.cs +++ b/RDFSharp/Query/Mirella/Algebra/Expressions/RDFAbsExpression.cs @@ -90,8 +90,13 @@ internal override RDFPatternMember ApplyExpression(DataRow row) if (leftArgumentPMember is RDFTypedLiteral leftArgumentTypedLiteral && leftArgumentTypedLiteral.HasDecimalDatatype()) { - if (double.TryParse(leftArgumentTypedLiteral.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out double leftArgumentNumericValue)) - expressionResult = new RDFTypedLiteral(Convert.ToString(Math.Abs(leftArgumentNumericValue), CultureInfo.InvariantCulture), RDFModelEnums.RDFDatatypes.XSD_DOUBLE); + //owl:rational needs parsing and evaluation before being compared + if (leftArgumentTypedLiteral.Datatype.TargetDatatype == RDFModelEnums.RDFDatatypes.OWL_RATIONAL) + expressionResult = new RDFTypedLiteral( + Convert.ToString(Math.Abs(RDFModelUtilities.ComputeOWLRationalValue(leftArgumentTypedLiteral)), CultureInfo.InvariantCulture), RDFModelEnums.RDFDatatypes.XSD_DOUBLE); + else if (double.TryParse(leftArgumentTypedLiteral.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out double leftArgumentNumericValue)) + expressionResult = new RDFTypedLiteral( + Convert.ToString(Math.Abs(leftArgumentNumericValue), CultureInfo.InvariantCulture), RDFModelEnums.RDFDatatypes.XSD_DOUBLE); } #endregion } diff --git a/RDFSharp/Query/Mirella/Algebra/Expressions/RDFCeilExpression.cs b/RDFSharp/Query/Mirella/Algebra/Expressions/RDFCeilExpression.cs index bc0481f4..514e40e5 100644 --- a/RDFSharp/Query/Mirella/Algebra/Expressions/RDFCeilExpression.cs +++ b/RDFSharp/Query/Mirella/Algebra/Expressions/RDFCeilExpression.cs @@ -90,8 +90,13 @@ internal override RDFPatternMember ApplyExpression(DataRow row) if (leftArgumentPMember is RDFTypedLiteral leftArgumentTypedLiteral && leftArgumentTypedLiteral.HasDecimalDatatype()) { - if (double.TryParse(leftArgumentTypedLiteral.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out double leftArgumentNumericValue)) - expressionResult = new RDFTypedLiteral(Convert.ToString(Math.Ceiling(leftArgumentNumericValue), CultureInfo.InvariantCulture), RDFModelEnums.RDFDatatypes.XSD_DOUBLE); + //owl:rational needs parsing and evaluation before being compared + if (leftArgumentTypedLiteral.Datatype.TargetDatatype == RDFModelEnums.RDFDatatypes.OWL_RATIONAL) + expressionResult = new RDFTypedLiteral( + Convert.ToString(Math.Ceiling(RDFModelUtilities.ComputeOWLRationalValue(leftArgumentTypedLiteral)), CultureInfo.InvariantCulture), RDFModelEnums.RDFDatatypes.XSD_DOUBLE); + else if (double.TryParse(leftArgumentTypedLiteral.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out double leftArgumentNumericValue)) + expressionResult = new RDFTypedLiteral( + Convert.ToString(Math.Ceiling(leftArgumentNumericValue), CultureInfo.InvariantCulture), RDFModelEnums.RDFDatatypes.XSD_DOUBLE); } #endregion } diff --git a/RDFSharp/Query/Mirella/Algebra/Expressions/RDFFloorExpression.cs b/RDFSharp/Query/Mirella/Algebra/Expressions/RDFFloorExpression.cs index b3af669b..26117bb7 100644 --- a/RDFSharp/Query/Mirella/Algebra/Expressions/RDFFloorExpression.cs +++ b/RDFSharp/Query/Mirella/Algebra/Expressions/RDFFloorExpression.cs @@ -90,8 +90,13 @@ internal override RDFPatternMember ApplyExpression(DataRow row) if (leftArgumentPMember is RDFTypedLiteral leftArgumentTypedLiteral && leftArgumentTypedLiteral.HasDecimalDatatype()) { - if (double.TryParse(leftArgumentTypedLiteral.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out double leftArgumentNumericValue)) - expressionResult = new RDFTypedLiteral(Convert.ToString(Math.Floor(leftArgumentNumericValue), CultureInfo.InvariantCulture), RDFModelEnums.RDFDatatypes.XSD_DOUBLE); + //owl:rational needs parsing and evaluation before being compared + if (leftArgumentTypedLiteral.Datatype.TargetDatatype == RDFModelEnums.RDFDatatypes.OWL_RATIONAL) + expressionResult = new RDFTypedLiteral( + Convert.ToString(Math.Floor(RDFModelUtilities.ComputeOWLRationalValue(leftArgumentTypedLiteral)), CultureInfo.InvariantCulture), RDFModelEnums.RDFDatatypes.XSD_DOUBLE); + else if (double.TryParse(leftArgumentTypedLiteral.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out double leftArgumentNumericValue)) + expressionResult = new RDFTypedLiteral( + Convert.ToString(Math.Floor(leftArgumentNumericValue), CultureInfo.InvariantCulture), RDFModelEnums.RDFDatatypes.XSD_DOUBLE); } #endregion } diff --git a/RDFSharp/Query/Mirella/Algebra/Expressions/RDFRoundExpression.cs b/RDFSharp/Query/Mirella/Algebra/Expressions/RDFRoundExpression.cs index 9fa3cf61..f418a71a 100644 --- a/RDFSharp/Query/Mirella/Algebra/Expressions/RDFRoundExpression.cs +++ b/RDFSharp/Query/Mirella/Algebra/Expressions/RDFRoundExpression.cs @@ -90,8 +90,13 @@ internal override RDFPatternMember ApplyExpression(DataRow row) if (leftArgumentPMember is RDFTypedLiteral leftArgumentTypedLiteral && leftArgumentTypedLiteral.HasDecimalDatatype()) { - if (double.TryParse(leftArgumentTypedLiteral.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out double leftArgumentNumericValue)) - expressionResult = new RDFTypedLiteral(Convert.ToString(Math.Round(leftArgumentNumericValue), CultureInfo.InvariantCulture), RDFModelEnums.RDFDatatypes.XSD_DOUBLE); + //owl:rational needs parsing and evaluation before being compared + if (leftArgumentTypedLiteral.Datatype.TargetDatatype == RDFModelEnums.RDFDatatypes.OWL_RATIONAL) + expressionResult = new RDFTypedLiteral( + Convert.ToString(Math.Round(RDFModelUtilities.ComputeOWLRationalValue(leftArgumentTypedLiteral)), CultureInfo.InvariantCulture), RDFModelEnums.RDFDatatypes.XSD_DOUBLE); + else if (double.TryParse(leftArgumentTypedLiteral.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out double leftArgumentNumericValue)) + expressionResult = new RDFTypedLiteral( + Convert.ToString(Math.Round(leftArgumentNumericValue), CultureInfo.InvariantCulture), RDFModelEnums.RDFDatatypes.XSD_DOUBLE); } #endregion } diff --git a/RDFSharp/Query/Mirella/Algebra/Filters/RDFIsNumericFilter.cs b/RDFSharp/Query/Mirella/Algebra/Filters/RDFIsNumericFilter.cs index 10e836c4..ddd70db6 100644 --- a/RDFSharp/Query/Mirella/Algebra/Filters/RDFIsNumericFilter.cs +++ b/RDFSharp/Query/Mirella/Algebra/Filters/RDFIsNumericFilter.cs @@ -74,8 +74,8 @@ internal override bool ApplyFilter(DataRow row, bool applyNegation) //Successful match if a numeric typed literal can be created with the variable value RDFPatternMember variableValuePMember = RDFQueryUtilities.ParseRDFPatternMember(variableValue); if (variableValuePMember is RDFResource - || variableValuePMember is RDFPlainLiteral - || (variableValuePMember is RDFTypedLiteral variableValuePMemberTLit && !variableValuePMemberTLit.HasDecimalDatatype())) + || variableValuePMember is RDFPlainLiteral + || (variableValuePMember is RDFTypedLiteral variableValuePMemberTLit && !variableValuePMemberTLit.HasDecimalDatatype())) keepRow = false; //Apply the eventual negation diff --git a/RDFSharp/Query/Mirella/Algebra/RDFAggregator.cs b/RDFSharp/Query/Mirella/Algebra/RDFAggregator.cs index d8193b6d..93328315 100644 --- a/RDFSharp/Query/Mirella/Algebra/RDFAggregator.cs +++ b/RDFSharp/Query/Mirella/Algebra/RDFAggregator.cs @@ -15,6 +15,7 @@ limitations under the License. */ using RDFSharp.Model; +using System; using System.Collections.Generic; using System.Data; using System.Globalization; @@ -105,7 +106,10 @@ internal double GetRowValueAsNumber(DataRow tableRow) //Only numeric typedliterals are suitable for processing if (rowAggregatorValue is RDFTypedLiteral rowAggregatorValueTLit && rowAggregatorValueTLit.HasDecimalDatatype()) { - if (double.TryParse(rowAggregatorValueTLit.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out double result)) + //owl:rational needs parsing and evaluation before being compared + if (rowAggregatorValueTLit.Datatype.TargetDatatype == RDFModelEnums.RDFDatatypes.OWL_RATIONAL) + return Convert.ToDouble(RDFModelUtilities.ComputeOWLRationalValue(rowAggregatorValueTLit), CultureInfo.InvariantCulture); + else if (double.TryParse(rowAggregatorValueTLit.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out double result)) return result; } } diff --git a/RDFSharp/Query/RDFQueryUtilities.cs b/RDFSharp/Query/RDFQueryUtilities.cs index 140504a2..35a200df 100644 --- a/RDFSharp/Query/RDFQueryUtilities.cs +++ b/RDFSharp/Query/RDFQueryUtilities.cs @@ -154,8 +154,17 @@ internal static int CompareRDFPatternMembers(RDFPatternMember left, RDFPatternMe { if (((RDFTypedLiteral)right).HasDecimalDatatype()) { - decimal leftValueDecimal = decimal.Parse(((RDFTypedLiteral)left).Value, CultureInfo.InvariantCulture); - decimal rightValueDecimal = decimal.Parse(((RDFTypedLiteral)right).Value, CultureInfo.InvariantCulture); + decimal leftValueDecimal, rightValueDecimal; + //owl:rational needs parsing and evaluation before being compared (LEFT) + if (((RDFTypedLiteral)left).Datatype.TargetDatatype == RDFModelEnums.RDFDatatypes.OWL_RATIONAL) + leftValueDecimal = RDFModelUtilities.ComputeOWLRationalValue((RDFTypedLiteral)left); + else + leftValueDecimal = decimal.Parse(((RDFTypedLiteral)left).Value, CultureInfo.InvariantCulture); + //owl:rational needs parsing and evaluation before being compared (RIGHT) + if (((RDFTypedLiteral)right).Datatype.TargetDatatype == RDFModelEnums.RDFDatatypes.OWL_RATIONAL) + rightValueDecimal = RDFModelUtilities.ComputeOWLRationalValue((RDFTypedLiteral)right); + else + rightValueDecimal = decimal.Parse(((RDFTypedLiteral)right).Value, CultureInfo.InvariantCulture); return leftValueDecimal.CompareTo(rightValueDecimal); } return -99; //Type Error