RDF OWL - Can a statement be used as object of another statement?

Viewed 134

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!

1 Answers

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
] .
Related