2

I'm learning about semantic web, and I'm trying to have a clear understanding of the possibilities and limitations of such a technology, and so far it looks very interesting !!

I was wondering about a use case, but not sure if it is possible to model it with RDF and if it still make sense in regards of the RDF and OWL principles. Is it possible to use a statement as the object of another statement? Here is a basic schema:

enter image description here

And pseudo triples:

A hasValue B.
C hasValue <A hasValue B>.

My goal here is not to describe that "C has the value B" but that "C has the value that A has".

From what I understood the issue here is that statements are not resources so they do not have IRIs hence they cannot be used as objects in statements. RDF seems to allow the description of the statement as a resource (https://www.w3.org/TR/rdf-schema/#ch_statement). If my understanding of this is correct, here is what it would look like:

rel a rdf:Statement;
    rdf:subject A;
    rdf:predicate hasValue;
    rdf:object B.
C hasValue rel.

This does not seem to be convenient: either all the relationships are modeled as statement resources (so they can potentially be later be used as an object in another statement), either they are declared literally (as in my pseudo triples above) but they should be switched to a statement resource later.

Finally, beyond the description in RDF, is it possible to use OWL to define an ontology that would support this kind of situation?

Edit 19/11/2020:

I'm adding some details to provide a better description of what I would like to achieve.

In the example above I want A to have a value B, and C to have the same value as A. As the statement describing the value of C is not directly using B as an object, I know that the final value of B will have to be inferred from multiple statements.

What I would like to achieve is to be able to later edit the statement about the value of A, but still want C to have the same value as A (its value would be inferred again).

Here is a better example (I hope) of what I have in mind:

  • With the following statements, I would like to able to infer that the value of C is B:
rel a rdf:Statement;
    rdf:subject A;
    rdf:predicate hasValue;
    rdf:object B.
C hasValue rel.
  • Then if I edit the statement that defines the value of A as following, I would like that inferring the value of C give a different result (B1):
rel rdf:object B1.

Is it something that can be achieved with RDF?

Many thanks!

Erick Hupin
  • 162
  • 7
  • 1
    to make statements about statements in RDF you can either use standard reification as you already did or use RDF* of your RDF engine and SPARQL engine do support this: https://blog.liu.se/olafhartig/tag/reification/ – UninformedUser Nov 18 '20 at 07:48
  • in OWL you can annotate axioms but it sounds more like you want n-ary relations: https://www.w3.org/TR/swbp-n-aryRelations/ – UninformedUser Nov 18 '20 at 07:49
  • Thank you for your quick answer! Regarding RDF*, my understanding of it is that a statement can be written in another statement, using double angle brackets. However, the "embedded" statement has no IRI, so it cannot be referenced elsewhere. Is that right? Let say I have a resource D (that like C "has the value that A has") the statement A->B could not be referenced twice (first as an embedded object of the statement describing the value that C has, and then the same to describe the value that D would have). As I'm still new with RDF I might be wrong on this, but does this makes sense? – Erick Hupin Nov 19 '20 at 00:28
  • Not sure if I understand correctly, but the statement identifier is just the statement itself. "the value that A has" - what you cannot do in RDF is to make statements that refer to other statements generically, you simply have to write the same RDF resource. Like you can't say `B isBornIn X` and `A isBornIn {where_B_isBornIn}` - if you mean this. Generic statements about factual data can be done via schema axioms in RDFS or OWL + you can use rule languages like SWRL. – UninformedUser Nov 19 '20 at 06:59
  • Thank again for spending time on this, as RDF is not as popular as other techs, your answers are really precious to me :) Regarding the initial question, I added more details in the original post, so I can better explain what I'm trying to achieve. – Erick Hupin Nov 20 '20 at 01:09
  • Then, when you are saying that `the statement identifier is just the statement itself`, is the "identifier" you are talking about the IRI that can be used to identify ressources? If so, I do agree that RDF litteral statements, and in RDF* embedded statements do not have identifier, hence cannot be referenced. – Erick Hupin Nov 20 '20 at 01:09
  • However, if the statement is described using `rdf:Statement`, my understanding is that this statement has an identifier hence it can be referenced in another statement. But when you are saying that `what you cannot do in RDF is to make statements that refer to other statements generically, you simply have to write the same RDF resource`, I feel like my assumption is wrong. Is that correct? – Erick Hupin Nov 20 '20 at 01:09

1 Answers1

0

Reification (the process of turning a triple into an instance of rdf:Statement) is not something that I feel would be useful in this case. Rather I think blank nodes are perfectly sufficient:

:A :hasValue _:b .
:C :hasValue _:b .

Even without any ontology, RDF has a small bit of logic built into it: blank nodes. You can talk about a specific entity (via its IRI) or a specific piece of data (as a literal), but you can also talk about some resource. This is commonly used for "anonymous" resources (like structured values where you don't want to come up with specific IRIs), but it also has this existential meaning.

These two statements specify that there is some resource that is a value of both A and C. The resource is not explicitly identified, and these two statements can be "satisfied" once it is explicitly provided (which would make the blank node redundant):

:A :hasValue :B .
:C :hasValue :B .

So what if the value is specified only for one of the resources?

:A :hasValue :B .

Note that without additional information of hasValue, it cannot be inferred that _:b is actually B, since A can have mutliple values and only one of them could be the value of C. This could be easily specified with OWL:

:hasValue owl:FunctionalProperty .

This implies that :B and _:b must refer to the same individual, since A cannot have more than one value.


If A can have more than one value however, you will either have to describe it via the blank node in a way that can select it (like you would in a query), or you have to identify that particular value somehow. The easiest option is to use owl:sameAs:

:A :hasValue :valueOfA .
:C :hasValue :valueOfA .

:valueOfA owl:sameAs :B .

You can use reification (and OWL 2) for that, if you want, but I don't think it's worth it:

:hasValueObjectOf a owl:ObjectProperty ;
  rdfs:range [
    a owl:Restriction ;
    owl:onProperty rdf:predicate ;
    owl:hasValue :hasValue
  ] .

[
  a owl:ObjectProperty ;
  owl:propertyChainAxiom ( :hasValueObjectOf rdf:object ) .
] rdfs:subPropertyOf :hasValue .


:rel a rdf:Statement ;
  rdf:predicate :hasValue ;
  rdf:object :B .

:A :hasValueObjectOf :rel .
:C :hasValueObjectOf :rel .

You can in essence identify this incomplete statement of "having a specific value" and "dereify" it so that it actually implies :hasValue.


And lastly, you can specify that all values of A are also values of C:

:isValueOf owl:inverseOf :hasValue .

[
  a owl:Restriction ;
  owl:onProperty :isValueOf ;
  owl:hasValue :A
] rdfs:subClassOf [
  a owl:Restriction ;
  owl:onProperty :isValueOf ;
  owl:hasValue :C
] .
IS4
  • 11,945
  • 2
  • 47
  • 86