Skip to content

Commit c40ee80

Browse files
authored
Merge pull request #214 from dice-group/fix/issue-212-sparql-literal-translation
Fix #212: Incorrect SPARQL translation for OWLDataSomeValuesFrom with rdfs:Literal
2 parents fb9c89d + 2a7626b commit c40ee80

2 files changed

Lines changed: 44 additions & 2 deletions

File tree

owlapy/converter.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,10 @@ def _(self, ce: OWLObjectComplementOf):
270270
# the exclusion of "?x ?p ?o" results in the group graph pattern to just return true or false (not bindings)
271271
# as a result, we need to comment out the if-clause of the following line
272272
# if not self.in_intersection and self.modal_depth == 1:
273-
self.append_triple(subject, self.mapping.new_individual_variable(), self.mapping.new_individual_variable())
273+
# However, if the complement is directly inside an intersection at the top level,
274+
# the intersection already provides bindings, so we don't need the extra triple pattern
275+
if not (len(self.parent) > 0 and isinstance(self.parent[-1], OWLObjectIntersectionOf) and self.modal_depth == 1):
276+
self.append_triple(subject, self.mapping.new_individual_variable(), self.mapping.new_individual_variable())
274277

275278
self.append("FILTER NOT EXISTS { ")
276279
# process the concept after the ¬
@@ -555,7 +558,7 @@ def _(self, node: OWLDatatype):
555558
if node != TopOWLDatatype:
556559
self.append(f" FILTER ( DATATYPE ( {self.current_variable} ) = <{node.to_string_id()}> ) ")
557560
else:
558-
self.append(f" FILTER ( isLiteral ( {self.current_variable} ) ")
561+
self.append(f" FILTER ( isLiteral ( {self.current_variable} ) ) ")
559562

560563
@process.register
561564
def _(self, node: OWLDataOneOf):

tests/test_owlapy_owl2sparql_converter.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,5 +426,44 @@ def test_ConfusionMatrixQuery(self):
426426
self.assertEqual(int(sparql_results.bindings[0]["fp"]), 1)
427427
self.assertEqual(int(sparql_results.bindings[0]["tn"]), 1)
428428

429+
def test_DataSomeValuesFrom_with_TopOWLDatatype_in_Complement(self):
430+
"""Test for issue #212: Incorrect SPARQL translation for OWLDataSomeValuesFrom with rdfs:Literal"""
431+
from owlapy.class_expression import OWLClass, OWLObjectIntersectionOf, OWLObjectComplementOf, OWLDataSomeValuesFrom
432+
from owlapy.owl_property import OWLDataProperty
433+
from owlapy.owl_literal import TopOWLDatatype
434+
435+
# Create ((CONTEXT_POSITION_MARKER ⊓ ∃mouse_lymph.Literal) ⊓ ¬∃salmonella.Literal)
436+
ce = OWLObjectIntersectionOf((
437+
OWLObjectIntersectionOf((
438+
OWLClass(IRI('http://owlapy.internal/', 'CONTEXT_POSITION_MARKER')),
439+
OWLDataSomeValuesFrom(
440+
property=OWLDataProperty(IRI('http://dl-learner.org/carcinogenesis#', 'mouse_lymph')),
441+
filler=TopOWLDatatype
442+
)
443+
)),
444+
OWLObjectComplementOf(
445+
OWLDataSomeValuesFrom(
446+
property=OWLDataProperty(IRI('http://dl-learner.org/carcinogenesis#', 'salmonella')),
447+
filler=TopOWLDatatype
448+
)
449+
)
450+
))
451+
452+
converter = Owl2SparqlConverter()
453+
result = converter.convert('?pos', ce, True, False)
454+
sparql = "".join(result)
455+
456+
# Verify the SPARQL is valid and doesn't contain the incorrect ?pos ?s_X ?s_Y pattern
457+
# The bug was producing: ?pos ?s_2 ?s_3 . between the two FILTER statements
458+
self.assertNotIn('?pos ?s_2 ?s_3', sparql)
459+
460+
# Verify the correct patterns are present
461+
self.assertIn('?pos a <http://owlapy.internal/CONTEXT_POSITION_MARKER>', sparql)
462+
self.assertIn('?pos <http://dl-learner.org/carcinogenesis#mouse_lymph>', sparql)
463+
self.assertIn('FILTER ( isLiteral ( ?s_1 ) )', sparql)
464+
self.assertIn('FILTER NOT EXISTS', sparql)
465+
self.assertIn('<http://dl-learner.org/carcinogenesis#salmonella>', sparql)
466+
self.assertIn('FILTER ( isLiteral ( ?s_2 ) )', sparql) # Inside the FILTER NOT EXISTS
467+
429468
if __name__ == '__main__':
430469
unittest.main()

0 commit comments

Comments
 (0)