Meilleure pratique pour définir les propriétés?
Mon problème avec OWL / RDFS est qu'en définissant plusieurs plages et domaines, le raisonneur classera les instances (qui sont définies comme domaine ou plage) en tant que type de toutes les classes définies pour le domaine ou la plage de cette propriété.
Quelles sont les solutions possibles pour surmonter ce problème?
- Une façon serait d'utiliser SHACL. Mais maintenant, les outils de visualisation ne fonctionnent plus.
petit exemple:
:ClassA a owl:Class .
:ClassB a owl:Class .
:ClassC a owl:Class .
:hasClassC a owl:ObjectProperty ;
rdfs:domain :ClassA, :ClassB;
rdfs:range :ClassC .
:instanceA a :ClassA ;
:hasClassC instanceC .
:instanceC a :ClassC .
Problème: sortie raisonnée:
:instanceA a :ClassB .
Solution de contournement avec SHACL:
:ClassA a owl:Class, sh:NodeShape ;
sh:property :ClassA-hasClassC .
:ClassA-hasClassC rdf:type sh:PropertyShape ;
sh:path :hasClassC ;
sh:class :ClassC .
:ClassB a owl:Class, sh:NodeShape ;
sh:property :ClassB-hasClassC .
:ClassB-hasClassC rdf:type sh:PropertyShape ;
sh:path :hasClassC ;
sh:class :ClassC .
Réponses
La façon dont vous avez résolu cela dans SHACL est d'avoir 2 formes différentes: une pour quand ClassA
est le domaine et une pour quand ClassB
est le domaine.
Pour obtenir quelque chose de similaire dans OWL, vous aurez besoin de 2 propriétés d'objet: une pour quand ClassA
est le domaine et une pour quand ClassB
est le domaine.
:classAHasClassC a owl:ObjectProperty ;
rdfs:domain :ClassA;
rdfs:range :ClassC .
:classBHasClassC a owl:ObjectProperty ;
rdfs:domain :ClassB;
rdfs:range :ClassC .
:instanceA a :ClassA ;
:classAHasClassC instanceC .
Pour que cela soit encore plus clair, vous pouvez ajouter une propriété parent et de l' état que les propriétés classAHasClassC
et classBHasClassC
sont disjoints:
:hasClassC a owl:ObjectProperty
:classAHasClassC a owl:ObjectProperty ;
rdfs:subPropertyOf :hasClassC;
rdfs:domain :ClassA;
rdfs:range :ClassC .
:classBHasClassC a owl:ObjectProperty ;
rdfs:subPropertyOf :hasClassC;
owl:propertyDisjointWith :classAHasClassC
rdfs:domain :ClassB;
rdfs:range :ClassC .
Enfin, une erreur courante est de penser que si vous avez ClassA, ClassB
comme domaine de hasClassC
, cela signifie que le domaine est l'union de ClassA
et ClassB
. Au lieu de cela, ce qui ClassA, ClassB
signifie est que le domaine est l' intersection de ClassA
et ClassB
. Pour spécifier que l'union doit être utilisée, il faut utiliser ce qui suit:
rdfs:domain [ rdf:type owl:Class ;
owl:unionOf (:ClassA
:ClassB
)
] ;