¿Mejores prácticas para definir propiedades?
Mi problema con OWL / RDFS es que al definir múltiples rangos y dominios, el razonador clasificará las instancias (que se definen como dominio o rango) como el tipo de todas las clases definidas para el dominio o rango de esa propiedad.
¿Cuáles son las posibles soluciones para superar ese problema?
- Una forma sería usar SHACL. Pero ahora, las herramientas de visualización ya no funcionan.
breve ejemplo:
: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 .
Problema: salida del razonador:
:instanceA a :ClassB .
Solución alternativa con 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 .
Respuestas
La forma en que ha resuelto esto en SHACL es teniendo 2 formas diferentes: una para cuándo ClassAes el dominio y otra para cuándo ClassBes el dominio.
Para lograr algo similar en OWL, necesitará 2 propiedades de objeto: una para cuándo ClassAes el dominio y otra para cuándo ClassBes el dominio.
: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 .
Para que esto sea aún más claro, es posible que desee agregar una propiedad principal e indicar que las propiedades classAHasClassCy classBHasClassCson disjuntas:
: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 .
Por último, un error común que se comete es pensar que si tiene ClassA, ClassBcomo dominio de hasClassC, significa que el dominio es la unión de ClassAy ClassB. En cambio, lo que ClassA, ClassBsignifica es que el dominio es la intersección de ClassAy ClassB. Para especificar que se debe usar la unión, se debe usar lo siguiente:
rdfs:domain [ rdf:type owl:Class ;
owl:unionOf (:ClassA
:ClassB
)
] ;