fix: repair no_multiple_inverse_properties.sparql (#490) (#817)

This commit is contained in:
SHANMUKH SAI
2026-03-25 12:06:30 -04:00
committed by GitHub
parent c6d6f93ccf
commit 70328ca5d7
2 changed files with 158 additions and 10 deletions

View File

@@ -5,21 +5,23 @@
# Severity:
# Error
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
SELECT ?property1 ?property2 ?error
SELECT DISTINCT ?property ?inverse1 ?inverse2 ?error
WHERE
{
{
?property owl:inverseOf ?property1.
?property owl:inverseOf ?property2.
FILTER (?property1 != ?property2)
{ ?property owl:inverseOf ?inverse1 }
UNION
{ ?inverse1 owl:inverseOf ?property }
}
UNION
{
?property1 owl:inverseOf ?property.
?property2 owl:inverseOf ?property.
FILTER (?property1 != ?property2)
{ ?property owl:inverseOf ?inverse2 }
UNION
{ ?inverse2 owl:inverseOf ?property }
}
FILTER (?inverse1 != ?inverse2)
FILTER (STR(?inverse1) < STR(?inverse2))
BIND (concat("ERROR: Object property ", str(?property), " has more than one inverse.") AS ?error)
}
}
ORDER BY ?property

View File

@@ -0,0 +1,146 @@
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix test: <https://example.org/test#> .
<https://example.org/test>
rdf:type owl:Ontology ;
rdfs:label "Toy ontology for no_multiple_inverse_properties.sparql" .
# -----------------------------------------------------------------------
# SHOULD TRIGGER — property declared as inverseOf two distinct properties
test:parentOf
rdf:type owl:ObjectProperty ;
owl:inverseOf test:childOf ;
owl:inverseOf test:hasParent ;
rdfs:label "parent of" .
test:childOf
rdf:type owl:ObjectProperty ;
rdfs:label "child of" .
test:hasParent
rdf:type owl:ObjectProperty ;
rdfs:label "has parent" .
# -----------------------------------------------------------------------
# SHOULD TRIGGER — mixed direction: one inverse forward, one backward
# test:teaches owl:inverseOf test:learnedBy (forward)
# test:taughtBy owl:inverseOf test:teaches (backward, so teaches also has taughtBy as an inverse)
test:teaches
rdf:type owl:ObjectProperty ;
owl:inverseOf test:learnedBy ;
rdfs:label "teaches" .
test:taughtBy
rdf:type owl:ObjectProperty ;
owl:inverseOf test:teaches ;
rdfs:label "taught by" .
test:learnedBy
rdf:type owl:ObjectProperty ;
rdfs:label "learned by" .
# -----------------------------------------------------------------------
# SHOULD TRIGGER — both inverses declared backward
# test:wasBuiltBy owl:inverseOf test:builds (backward)
# test:wasCreatedBy owl:inverseOf test:builds (backward)
# => test:builds has two inverses: wasBuiltBy and wasCreatedBy
test:builds
rdf:type owl:ObjectProperty ;
rdfs:label "builds" .
test:wasBuiltBy
rdf:type owl:ObjectProperty ;
owl:inverseOf test:builds ;
rdfs:label "was built by" .
test:wasCreatedBy
rdf:type owl:ObjectProperty ;
owl:inverseOf test:builds ;
rdfs:label "was created by" .
# -----------------------------------------------------------------------
# SHOULD TRIGGER — three inverses declared forward (produces 3 violation pairs)
test:contains
rdf:type owl:ObjectProperty ;
owl:inverseOf test:isIn ;
owl:inverseOf test:isInsideOf ;
owl:inverseOf test:isEncompassedBy ;
rdfs:label "contains" .
test:isIn
rdf:type owl:ObjectProperty ;
rdfs:label "is in" .
test:isInsideOf
rdf:type owl:ObjectProperty ;
rdfs:label "is inside of" .
test:isEncompassedBy
rdf:type owl:ObjectProperty ;
rdfs:label "is encompassed by" .
# -----------------------------------------------------------------------
# SHOULD NOT TRIGGER — property with exactly one inverse (forward only)
test:employs
rdf:type owl:ObjectProperty ;
owl:inverseOf test:employedBy ;
rdfs:label "employs" .
test:employedBy
rdf:type owl:ObjectProperty ;
rdfs:label "employed by" .
# -----------------------------------------------------------------------
# SHOULD NOT TRIGGER — property with no declared inverse
test:likes
rdf:type owl:ObjectProperty ;
rdfs:label "likes" .
# -----------------------------------------------------------------------
# SHOULD NOT TRIGGER — single inverse declared backward only
# test:isOwnedBy declares itself as owl:inverseOf test:owns, so
# test:owns has exactly one inverse (test:isOwnedBy)
test:owns
rdf:type owl:ObjectProperty ;
rdfs:label "owns" .
test:isOwnedBy
rdf:type owl:ObjectProperty ;
owl:inverseOf test:owns ;
rdfs:label "is owned by" .
# -----------------------------------------------------------------------
# SHOULD NOT TRIGGER — self-inverse (symmetric property)
# isSiblingOf owl:inverseOf isSiblingOf: both ?inv1 and ?inv2 resolve to
# isSiblingOf, so FILTER(?inv1 != ?inv2) eliminates the row
test:isSiblingOf
rdf:type owl:ObjectProperty ;
owl:inverseOf test:isSiblingOf ;
rdfs:label "is sibling of" .
# -----------------------------------------------------------------------
# SHOULD NOT TRIGGER — inverse declared redundantly in both directions
# isRelatedTo owl:inverseOf isAssociatedWith
# isAssociatedWith owl:inverseOf isRelatedTo
# These are the same single inverse pair stated twice; each property has
# exactly one inverse
test:isRelatedTo
rdf:type owl:ObjectProperty ;
owl:inverseOf test:isAssociatedWith ;
rdfs:label "is related to" .
test:isAssociatedWith
rdf:type owl:ObjectProperty ;
owl:inverseOf test:isRelatedTo ;
rdfs:label "is associated with" .