w3c / rdf-star

RDF-star specification
https://w3c.github.io/rdf-star/
Other
120 stars 23 forks source link

SPARQL* pattern with only a reified statement #76

Closed peterjohnlawrence closed 3 years ago

peterjohnlawrence commented 3 years ago

SPARQL* query question: Suppose I have the reified triples

:r1 rdf:subject :S1; rdf:predicate :P1; rdf:object :O1 .
:r2 rdf:subject :S2; rdf:predicate :P2; rdf:object :O2; a rdf:Statement .

and I want to discover the reified triples, I believe the following SPARQL* graph pattern would be syntactically incorrect:

select * { << :S1 :P1 ?O >> }

However this would be syntactically correct:

select * { << :S2 :P2 ?O >> a rdf:Statement }

So this means that :O1 cannot be matched using SPARQL*, but it can using SPARQL:

select * {:S1 ^rdf:subject [ rdf:predicate:P1; rdf:object ?o ] }

hartig commented 3 years ago

SPARQL* is not defined to match RDF reification triples such as the ones in your example.

SPARQL is an extension of SPARQL. The main new feature that SPARQL adds to SPARQL is the notion of nested triple patterns, which are meant to match nest triples that are possible with RDF*. Such nested triple patterns are not defined to match RDF reification triples as in your example.

If you want to match such reification triples, the features of SPARQL are sufficient; i.e., you do not need any SPARQL-specific features for that. In this sense, it is incorrect to say that SPARQL cannot do that; it can because it is an extension of SPARQL and, thus, has all the features of SPARQL.

peterjohnlawrence commented 3 years ago

So if I instantiated the reified triples as

<<:S1 :P1  :O1 >>
<<:S2 :P2  :O2 >>

would I not have the same problem with

select * { << :S1 :P1 ?O >> }

I am not trying to challenge RDF/SPARQL (I think it is a brilliant extension), however I am trying to understand this particular case.

hartig commented 3 years ago

So if I instantiated the reified triples as

<<:S1 :P1 :O1 >> <<:S2 :P2 :O2 >>

This is something you cannot do in Turtle (or, more generally, in RDF). Embedded triples cannot be used just by themselves. They are meant to be used in the subject position or the object position of another triple. For instance, you may have:

<<:S1 :P1 :O1 >>  :pp1  :oo1.
<<:S2 :P2 :O2 >>  :pp2  :oo2.

Now you can query for the objects of all embedded triples that have :S1 as their subject and :P1 as their predicate:

SELECT ?o WHERE {
    <<:S1 :P1 ?o >>  ?pp ?oo .
}
peterjohnlawrence commented 3 years ago

If I only had the reified triples (that is, no additional statements about the reified triples)

<< :S1 :P1 :O1 >>
<< :S2 :P2 :O2 >>

Does/will the SPARQL proposed standard still support this graph pattern? `select {:S1 ^rdf:subject [ rdf:predicate:P1; rdf:object ?o ] } returning :O1 Also, I guess what I am concluding is that <<:S1 :P1 ?o >> is not syntactic-sugar for a graph-pattern {:S1 ^rdf:subject [ rdf:predicate:P1; rdf:object ?o ] }` because the former is a node, whilst the latter is a graph-pattern

hartig commented 3 years ago

If I only had the reified triples (that is, no additional statements about the reified triples)

<< :S1 :P1 :O1 >> << :S2 :P2 :O2 >>

As mentioned in my previous comment, this is something you cannot do. A syntactic construct such as << :S1 :P1 :O1 >> (which is the Turtle* representation of an embedded triple) must be used in the subject position or in the object position of another triple.

Why would you want to have an embedded triple as if you want to make a statement about it, but then do not make any such statement?

Does/will the SPARQL proposed standard still support this graph pattern? `select {:S1 ^rdf:subject [ rdf:predicate:P1; rdf:object ?o ] }` returning :O1

Since this example query with its graph pattern is a valid expression in SPARQL, it is also a valid expression in SPARQL and it will behave exactly the same as it does in SPARQL. Again, SPARQL is an extension of SPARQL with additional features (new types of graph patterns); the meaning of the existing types of graph patterns is not changed by this extension.

So, your example query will return :O if it is executed over the RDF data in your initial post in this thread. In contrast, when executed over the RDF* data in my previous comment, the query result is empty.

Maybe to clarify further: Consider the following nested RDF triple (written in Turtle format).

<<:S1 :P1 :O1 >>  :pp1  :oo1.

Note that the subject of this triple is an embedded triple. Now, having this nested RDF* triple in your data does not mean that your data implicitly also contains any of the following triples.

:S1 :P1 :O1 . 
_:x  rdf:type  rdf:Statement .
_:x  rdf:subject  :S1 .
_:x  rdf:predicate  :P1 .
_:x  rdf:object  :O1 .
_:x  :pp1  :oo1.

Also, I guess what I am concluding is that <<:S1 :P1 ?o >> is not syntactic-sugar for a graph-pattern {:S1 ^rdf:subject [ rdf:predicate:P1; rdf:object ?o ] } because the former is a node, whilst the latter is a graph-pattern

Almost correct! ;-) The former is not "a node," but it is an embedded triple pattern.

In the same way as embedded triples have to be used in the subject position or in the object position of another triple, embedded triple patterns have to be used in the subject or the object of another triple pattern, as I have demonstrated in the SPARQL* query in my previous comment.

peterjohnlawrence commented 3 years ago

<<Why would you want to have an embedded triple as if you want to make a statement about it, but then do not make any such statement? >>

Because this is one step in the life cycle of the data triples:

Step 1: assert the following << :S1 :P1 :O1 >> such as << :Peter :marriedTo :Beth >> Step 2: Go and have some lunch or take a vacation somewhere and leave the data for someone else Step 3: (after returning from vacation) Assert the following << :Peter :marriedTo :Beth >> :at :Kelby .

In practice I cannot ensure that all triples are entered simultaneously: they will evolve over time. The situation I am discussing is when I am at Step 2 in the data's evolution.

Peter J. Lawrence inova8 Providing answers for users' information questions Mobile: +44 7546 095977 | +1 330 631 3772 | Phone: +44 1298 872375 | Skype: PeterJLawrence Email: peter.lawrence@inova8.com | Web: www.inova8.com LinkedIn:

http://www.linkedin.com/in/peterjohnlawrence http://www.linkedin.com/in/peterjohnlawrence

On Tue, 22 Dec 2020 at 12:53, Olaf Hartig notifications@github.com wrote:

If I only had the reified triples (that is, no additional statements about the reified triples)

<< :S1 :P1 :O1 >> << :S2 :P2 :O2 >>

As mentioned in my previous comment, this is something you cannot do. A syntactic construct such as << :S1 :P1 :O1 >> (which is the Turtle* representation of an embedded triple https://w3c.github.io/rdf-star/rdf-star-cg-spec.html#dfn-embedded) must be used in the subject position or in the object position of another triple.

Why would you want to have an embedded triple as if you want to make a statement about it, but then do not make any such statement?

Does/will the SPARQL proposed standard still support this graph pattern? select {:S1 ^rdf:subject [ rdf:predicate:P1; rdf:object ?o ] } returning :O1

Since this example query with its graph pattern is a valid expression in SPARQL, it is also a valid expression in SPARQL and it will behave exactly the same as it does in SPARQL. Again, SPARQL is an extension of SPARQL with additional features (new types of graph patterns); the meaning of the existing types of graph patterns is not changed by this extension.

So, your example query will return :O if it is executed over the RDF data in your initial post in this thread. In contrast, when executed over the RDF* data in my previous comment, the query result is empty.

Maybe to clarify further: Consider the following nested RDF triple (written in Turtle format).

<<:S1 :P1 :O1 >> :pp1 :oo1.

Note that the subject of this triple is an embedded triple. Now, having this nested RDF triple in your data does not mean that your data implicitly also contains any* of the following triples.

:S1 :P1 :O1 . :x rdf:type rdf:Statement . :x rdf:subject :S1 . :x rdf:predicate :P1 . :x rdf:object :O1 . _:x :pp1 :oo1.

Also, I guess what I am concluding is that <<:S1 :P1 ?o >> is not syntactic-sugar for a graph-pattern {:S1 ^rdf:subject [ rdf:predicate:P1; rdf:object ?o ] } because the former is a node, whilst the latter is a graph-pattern

Almost correct! ;-) The former is not "a node," but it is an embedded triple pattern https://w3c.github.io/rdf-star/rdf-star-cg-spec.html#dfn-embedded-triple-patterns .

In the same way as embedded triples have to be used in the subject position or in the object position of another triple, embedded triple patterns have to be used in the subject or the object of another triple pattern, as I have demonstrated in the SPARQL* query in my previous comment.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/w3c/rdf-star/issues/76#issuecomment-749525877, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAMJVMFN7BJGZUMSGQNEKUDSWCJGPANCNFSM4VFJ72FA .

hartig commented 3 years ago

Note that embedded triples are not asserted (unless the graph contains a corresponding triple with the same subject, the same predicate, and the same object as the embedded triple). So, if you want to assert that Peter is married to Beth, you can simply do so by adding a regular triple into your graph:

:Peter :marriedTo :Beth .

If you want to add statements about this triple later, no problem. Just come back from your lunch or vacation and extend your graph as follows.

:Peter :marriedTo :Beth .
<< :Peter :marriedTo :Beth >>  :at  :Kelby .

Notice that the current draft of the RDF/SPARQL spec now also introduces an additional annotation syntax for Turtle* with which you can write the previous two triples together in the following shorter form:

:Peter :marriedTo :Beth {| :at  :Kelby |} .

However, the latter is really just syntactic sugar for the two triples.

peterjohnlawrence commented 3 years ago

OK, I'm going to stick my neck out now with the full expectation that it will get chopped off for being presumptuous.

Within SPARQL it would be incredibly useful if the <<...>> notation could include an optional reified node as in <<?r ?s ?p ?o>> , with ?r optional Thus it would be syntactic sugar for ?r rdf:subject ?s ; rdf:predicate ?o ; rdf:object ?o . Thus ?r is the blank or otherwise node of the reified triple. This would allow SPARQL expressions such as this ludicrously simple example, but just to illustrate the idea that the reified triple could be fully realized as a node for use within any SPARQL graph pattern:

<< ?r :Peter :marriedTo :Beth >> :at Kelby .
?r :rdf:subject ?s .
FILTER ( ?s = :Peter)
afs commented 3 years ago

Within SPARQL it would be incredibly useful if the <<...>> notation could include an optional reified node as in <<?r ?s ?p ?o>> , with ?r optional Thus it would be syntactic sugar for ?r rdf:subject ?s ; rdf:predicate ?o ; rdf:object ?o .

History note: that was in early work within the Data Access Working Group (for SPARQL 1.0) before it was even called SPARQL. Both for three argument and four argument forms did make a brief appearance in WG discussions. This didn't happen (the WG had too much to do) and, as now, the large numbers of triples that are involved with reification and the possibility if partial refication (e.g. rdf:subject but no rdf:object) present issues.

The interesting avenue to follow is whether and how far the <<>> 3-argument form works as syntax over data that uses reification to encode <<>>, with the obvious alignment restrictions that a statement is reified only once and the reification is "well-formed" (complete, and no additional triples).

If we introduce a new RDF term into (extended) RDF, then there will naturally be related SPARQL functions. In the same way that DATATYPE and LANG access parts of a literal, SUBJECT, PROPERTY, OBJECT access the components of a concrete <<>>.

TallTed commented 3 years ago

@peterjohnlawrence --

First thing that comes to my mind is to ask how you (or a parser) would differentiate between << ?r ?s ?p ?o >> and << ?s ?p ?o ?g >> (which has also been suggested and discussed)?

Second thing is that I don't understand your "ludicrously simple example," I'm pretty sure you've left out some punctuation, and definitely a SPARQL verb, and maybe more. (I think you meant for the first line to be the source data, and for the other two lines to be a SELECT, but I think there's too much unsaid to simply act as if this were so.)

For discussions like this, where we're talking about some possibly-future-spec, it's difficult enough to understand some examples that include all nominally-optional elements coming from the current spec; leaving those elements out can make it impossible for readers to puzzle out the intended meaning.

peterjohnlawrence commented 3 years ago

<<First thing that comes to my mind is to ask how you (or a parser) would differentiate between << ?r ?s ?p ?o >> and << ?s ?p ?o ?g >> (which has also been suggested and discussed)?>>

I was not aware that had been discussed, however I agree it would be ambiguous

I have only just started looking at these threads in the past few weeks, so you will have to be tolerant of my naïve observations.

<< I'm pretty sure you've left out some punctuation, and definitely a SPARQL verb, and maybe more.>>

I am only guessing at the SPARQL syntax that you have been discussing. I had assumed that one would be able to reference a reified triple in SPARQL using the same <<...>> notation.

<< ?r :Peter :marriedTo :Beth >> :at Kelby .
?r :rdf:subject ?s .
FILTER ( ?s = :Peter)

would, I had assumed, be the syntactic equivalent of:

?r rdf:subject :Peter ; rdf:predicate :marriedTo ; rdf:object :Beth ;  :at Kelby .
?r :rdf:subject ?s .
FILTER ( ?s = :Peter)
TallTed commented 3 years ago

@peterjohnlawrence

I am still unable to interpret your example with certainty. Is that all meant to be the substance of a WHERE clause? That is, do you mean --

SELECT * 
WHERE
  { 
    << ?r :Peter :marriedTo :Beth >> :at         Kelby .
    ?r                               rdf:subject ?s    .
    FILTER ( ?s = :Peter)
  }

-- and that to be the syntactic equivalent of --

SELECT * 
WHERE
  { 
    ?r rdf:subject   :Peter     ; 
       rdf:predicate :marriedTo ; 
       rdf:object    :Beth      ;
       :at           Kelby      .
    ?r rdf:subject   ?s         .
    FILTER ( ?s = :Peter)
  }
peterjohnlawrence commented 3 years ago

Yes the first is a SPARQL graphPattern based on my assumptions regarding the syntax, whilst the second is its syntactical equivalent SPARQL graphPattern. I mistakenly thought the select {...} was superfluous.

gkellogg commented 3 years ago

OK, I'm going to stick my neck out now with the full expectation that it will get chopped off for being presumptuous.

Within SPARQL it would be incredibly useful if the <<...>> notation could include an optional reified node as in <<?r ?s ?p ?o>> , with ?r optional Thus it would be syntactic sugar for ?r rdf:subject ?s ; rdf:predicate ?o ; rdf:object ?o . Thus ?r is the blank or otherwise node of the reified triple.

Is this use case not handled with BIND/FIND?

SELECT * 
WHERE  {
  << ?s :marriedTo :Beth >> :at :Kelby .
  FILTER (?s = :Peter) .
}

If you want to refer to the triple itself, you can also bind it, but this may require using a sub-select to use ?r within the query.

SELECT * 
WHERE  {
  << ?s :marriedTo :Beth >> :at :Kelby .
  FILTER (?s = :Peter) .
  BIND (<< ?s :marriedTo :Beth >> as ?r) .
}
peterjohnlawrence commented 3 years ago

<< you can also bind it, but this may require using a sub-select to use ?r>> Good point

hartig commented 3 years ago

The query of @gkellogg can be simplified as follows.

SELECT * WHERE  {
  BIND (<< ?s :marriedTo :Beth >> as ?r) . 
  ?r :at :Kelby .
  FILTER (?s = :Peter) 
}

Additionally, I don't see the point of having the filter clause. We may get rid of it as well:

SELECT * WHERE  {
  BIND (<< :Peter :marriedTo :Beth >> as ?r) . 
  ?r :at :Kelby .
}

However, as I have mentioned earlier in this thread, such queries are not defined to match standard RDF reification triples.

afs commented 3 years ago

There are two different BIND being used here:

@gkellogg has BIND as assignment; SPARQL 1.,1 extended with <<>> terms as expressions. ?s is matched in the triple pattern and used in the expression <<>>.

@hartig has BIND as a different operator where it matches and does multiple-match, binding ?s and is a pattern operator.

pchampin commented 3 years ago

With the recent changes in the SPARQL-star section (#115) and the upcoming addition of built-in functions (#118), the query would now be

SELECT * {
  << ?s :marriedTo :Beth >> :at :Kelby.
  FILTER (?s = :Peter)
  BIND(Triple(?s, :marriedTo, :Beth) as ?r)
}

We are considering (#117) extending expressions to allow

SELECT * {
  << ?s :marriedTo :Beth >> :at :Kelby.
  FILTER (?s = :Peter)
  BIND(<< ?s :marriedTo :Beth >> as ?r)
}

as suggested by @gkellogg earlier in this thread.

@peterjohnlawrence the discussion somehow diverged from the initial question, but are you satisfied with the answers. Can we close this issue?

peterjohnlawrence commented 3 years ago

I look forward to seeing SPARQL*, thanks.