Let's take the axiom
SubClassOf( DataAllValuesFrom( <d> xsd:boolean ) ObjectSomeValuesFrom( <o> owl:Thing ) Annotation( rdfs:comment "comm"^^xsd:string ) ).
What should this axiom look like in the form of RDF?
If I understand the specification correctly, there is one and only one way:
Example 1:
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
<o> a owl:ObjectProperty .
[ a owl:Axiom ;
rdfs:comment "comm" ;
owl:annotatedProperty rdfs:subClassOf ;
owl:annotatedSource [ a owl:Restriction ;
rdfs:subClassOf _:c2 ;
owl:allValuesFrom xsd:boolean ;
owl:onProperty <d>
] ;
owl:annotatedTarget _:c2
] .
<d> a owl:DatatypeProperty .
_:c2 a owl:Restriction ;
owl:onProperty <o> ;
owl:someValuesFrom owl:Thing .
But, it suddenly turned out that there are people who understand the specification in a different way. And the axiom above may or even must be written as follows:
Example 2:
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
<o> a owl:ObjectProperty .
<d> a owl:DatatypeProperty .
[ a owl:Axiom ;
rdfs:comment "comm" ;
owl:annotatedProperty rdfs:subClassOf ;
owl:annotatedSource [ a owl:Restriction ;
rdfs:subClassOf [ a owl:Restriction ;
owl:allValuesFrom owl:Thing ;
owl:onProperty <o>
] ;
owl:onProperty <d> ;
owl:someValuesFrom xsd:boolean
] ;
owl:annotatedTarget [ a owl:Restriction ;
owl:allValuesFrom owl:Thing ;
owl:onProperty <o>
]
] .
So, the question is, who is right? Which example is correct?
In my opinion, the second RDF (example 2) violates understanding of RDF reification and data connectivity.
But I could not convey this to the opponent.
I have arguments based on the specification
(that may be offered as an answer later),
but these arguments turned out to be untenable in his eyes,
so I appeal to a wide range of specialists here to get new arguments,
or, maybe, to improve my own vision of the concept:
nobody (with except of me) has said yet that the example 1 is the only correct way.
So it would be nice, having the specification, obtain a proof that the first (or the second) example is correct.
If I understood correctly, my opponent appeals to the following phrase from the specification:
In the mapping, each generated blank node (i.e., each blank node that does not correspond to an anonymous individual) is fresh in each application of a mapping rule..
Which, he thinks, means that super-class ObjectSomeValuesFrom( <o> owl:Thing ) must get b-node twice while writing to RDF.
How to proof that this is not true (or true)?
Thank you.
So, since no answers yet, here is my own, which is based on my understanding of the official specification https://www.w3.org/TR/owl2-mapping-to-rdf/. Any comments and improvements are welcome.
1. Introduction
The spec defines only the operators
T(E)andTANN(ann, y), whereannisAnnotation( AP av ),Eandyare some objects. The spec also says:The definition of the operator T uses the operator TANN in order to translate annotations.For the operations that are described in the section2.1 Translation of Axioms without Annotationsand the section2.3 Translation of Axioms with Annotationsthere are no own names. The operatorTANNis defined inTable 2, section2.2 Translation of Annotations, but it is annotation for annotation, which is producing a b-node with root triple_:x rdf:type owl:Annotation. The operator that creates top-level annotations with the root triple_: x rdf: type owl: Axiomis described in the section2.3.1 Axioms that Generate a Main Triple, but also does not have a proper name. And, in sake of demonstration, I'm going to introduce a new name for this "operator":ANN. Note 1: do not confuse it with the functionANNfrom the section3.2.2 Parsing of Annotations- we don't need that last thing; this answer is only about mapping, not parsing. Note 2: I am not writing my own spec, I am just trying to explain my vision using the new abbreviation. In general case this injection may not be correct, but for demonstration purposes, I think it is OK.Also, let's consider the axiom
SubClassOfas an operator with two operands. It is described in theTable 1from the section2.1 Translation of Axioms without Annotationslike this:Let's also consider an overloaded operator
SubClassOfwith two operands and vararg of annotations. TheSubClassOf( CE1 CE2 annotations { n > 1 } )is defined in the section2.3.1 Axioms that Generate a Main Triplelike the following:For simplicity let's dwell on one case when there is only one top-level annotation. So, that operator is
SubClassOf( CE1, CE2, ann)and it looks like this:This is a new operator
ANN, which is similar toTANN, but accepts two operands, annotation and constant, that defines the predicate. It produces the root triple_:x rdf:type owl:Axiomand all other triples are similar to the triples for the operatorTANNin the example above, soANN(s, xlt, p, ann)is :2. An ontology without annotations.
Now lets consider the example from the question where the first operand is
DataAllValuesFromand the second isObjectSomeValuesFrom:In TURTLE it would look like this:
Or the same ontology in NTRIPLES syntax:
SubClassOfis an axiom that generate a main triple (see the section2.3.1 Axioms that Generate a Main Triple). So, the main triple (s p xlt) here is_:c1 <http://www.w3.org/2000/01/rdf-schema#subClassOf> _:c2, wheres(the subject, in the exampleDataAllValuesFrom( <d> xsd:boolean )) is_:c1,p(the predicate) isrdfs:subClassOf, andxlt(xltstands for a blank node, an IRI, or a literal, here it is the object, in the exampleObjectSomeValuesFrom( <o> owl:Thing )) is_:c2.Note, in ONT-API such TURTLE can be generated by the following code:
3. Behaving of the operator
T.The spec says:
In the mapping, each generated blank node (i.e., each blank node that does not correspond to an anonymous individual) is fresh in each application of a mapping rule.. I believe this is only about the operatorT. This statement is roughly matched what is said in the Parsing OWL, Structure Sharing, OWL1 spec:In practice, this means that blank nodes (i.e. those with no name) which are produced during the transformation and represent arbitrary expressions in the abstract syntax form should not be "re-used".. In ordinary case it is not a problem neither for ONT-API nor OWL-API, all these things behave similarly. The following code produces identical RDF both for OWL-API (default impl) and ONT-API (with the OWL-API interfaces used):For the two equal class expressions
ObjectComplementOf( owl:Thing )which are operands ofSubClassOf( CE1, CE2 )there would be two different b-nodes. So, nobody disputes the fact that in OWL there is no objects sharing.But, in my opinion, this must not be apply to the relationship between the axiom and its annotations, which is the case of the operator
ANN, see the next paragraph.4.1 An annotated axiom that generate a main triple. Reification with
SPO.Now lets add an annotation
Annotation( rdfs:comment "comm" )to theSubClassOf( DataAllValuesFrom( <d> xsd:boolean ) ObjectSomeValuesFrom( <o> owl:Thing ) )(see previous paragraph 2) in a manner that I think is the only true. Remember, that the operatorSubClassOf(CE1, CE2, ann)generates the following ttl:or
Here, the triple
s p xltis the result of applying the operatorSubClassOf(CE1, CE2). From theTable 2, section2.2 Translation of Annotations, the operatorTANN(Annotation( AP av ), _:x)forAnnotation( rdfs:comment "comm"^^xsd:string )will give the triple_:x rdfs:comment "comm"^^xsd:string, so we have (SubClassOf(CE1, CE2, Annotation( rdfs:comment "comm"^^xsd:string ))):The triple
s p xlthere is_:c1 rdfs:subClassOf _:c2(see paragraph 2); so finally we get the following annotated axiom:The full ontology (without ontology id) in NTRIPLES syntax would look like this:
Or the same in TURTLE:
The triple
_:c1 rdfs:subClassOf _:c2(SPO) is present in the graph and has its reification:Note, that this ontology can be generated by the following code:
4.2 An annotated axiom that generate a main triple. Reification with
(S*)P(O*).Well, the spec also says that
In the mapping, each generated blank node (i.e., each blank node that does not correspond to an anonymous individual) is fresh in each application of a mapping rule. This is about the operatorT, but not for the operatorsTANN,ANN,SubClassOf(CE1, CE2)orSubClassOf(CE1, CE2, ann). ButSubClassOfoperators consist ofTandANN(TANN), so they must also implicitly generate a blank node for each operands. I remind that the operatorSubClassOf(CE1, CE2, ann)originally (see p.1) looks like following:But it is still not fully clear what should actually happen with its second part - the operator
ANN(CE1, CE2, rdfs:subClassOf, ann). Let's take my opponent's assumption (as far as I understand it), that the class expressions must not be shared even within a whole axiom including all its hierarchy-tree of annotations. This is definitely true for the operatorSubClassOf(CE1, CE2), and wrong for the operatorTANN, and the subject of controversy for the operatorANN(that includesTANN). But for a sake of experiment lets assume that the rule also must be applicable to theANNoperands. So, theSubClassOf(CE1, CE2, ann)is now defined as follows:or
The
SubClassOf(CE1, CE2)will give the following NTRIPLES (see p.2):Here, the b-node
_:c1corresponds to the class expressionDataAllValuesFrom( <d> xsd:boolean ), and the b-node_:c2corresponds to theObjectSomeValuesFrom( <o> owl:Thing ).Then we do
TinANNfor the subject (the first operandT(CE1)):and for the object (the second operand
T(CE2)):And print
ANNitself:Notice, that now we have fresh b-nodes for
CE1andCE2(_:b1and_:b2- respectively), and have a reference in annotation (_:x) for these two nodes. Inside the annotation graph-structure there are_:b1,_:b2, not_:c1,_:c2, just because we first apply the operatorTto the input class expression, and only then pass the result further into the operatorANN.The full ontology would be as the following (just concatenate all parts above) (NTRIPLES):
Or the same in TURTLE:
As you can see, the triple
_:c1 rdfs:subClassOf _:c2(SPO) is present in the graph, but has no reification. Instead, there is a reification for the triple_:b1 rdfs:subClassOf _:b2((S*)P(O*)), which does not actually exist in the graph:Since the triple
_:b1 rdfs:subClassOf _:b2does not exist, then, in my opinion, this exercise demonstrates invalid behavior.4.3 An annotated axiom that generate a main triple by OWL-API. Reification with
SP(O*).As you might guess, my opponent defends the current behavior of OWL-API (v5.1.11). So let's see what OWL-API does. The code to generate:
NTRIPLES (the Ontology ID is omitted):
The original TURTLE:
And the reformatted TURTLE (again, without ontology id):
As you can see, the triple
_:c1 rdfs:subClassOf _:c2(SPO) is present in the graph, but has no reification, just like in the previous paragraph (p4.2). Instead, there is a reification for the triple_:c1 rdfs:subClassOf _:u(SP(O*)), which does not actually exist in the graph:Also note, for this example, the operator
SubClassOf(CE1, CE2, ann)must be as follows:here, the first operand is passed as is, but for the second there is
T-transformation, which produces a fresh b-node.Since the triple
_:c1 rdfs:subClassOf _:udoes not exist in the whole graph, this example also demonstrates wrong behavior. So, in my opinion OWL-API (v5.1.11) does not produce correct RDF in the case an annotated axiom consists of anonymous expressions.5. Conclusion and notes.
SubClassOf(CE1, CE2, ann)from the example 4.3 is unsymmetric. There are no any clues in the spec which may lead to such an unbalanced outcome. Why there is a transformationTfor the second operand, but not for the first - this is a question.