w3c / rdf-star-wg

RDF-star Working Group
Other
22 stars 8 forks source link

Turtle Grammar: Collections and blank node property lists in triple terms #132

Open doerthe opened 11 hours ago

doerthe commented 11 hours ago

Motivated by the other discussion (#131), I had a closer look at our turtle and TriG grammar (https://www.w3.org/TR/rdf12-turtle/#sec-grammar https://www.w3.org/TR/rdf12-trig/) and was surprised, that collections and blankNodePropertyLists are not allowed in triple terms (see: https://www.w3.org/TR/rdf12-trig/#:~:text=%5B34%5D-,ttObject,-%3A%3A%3D).

We discussed about triple terms in only object position (and you know my opinion :) ), but I do not remember that we discussed that issue. To me, that choice feels random, but maybe there are good reasons for that?

I know that this does not influence our abstract syntax, as collections and blankNodePropertyLists are only syntactic sugar, but I would like to at least know why we do not allow them.

rubensworks commented 11 hours ago

For reference, the same question was raised in https://github.com/w3c/rdf-tests/pull/144/files/0e7088f838bd130fab1792eb50cda9f21b86398b#diff-2393a6f31093e34f798eecfd5dc5b67a77238f1b8ee75e4a35a7c1d650320a68

doerthe commented 9 hours ago

Thank you, I missed that.

afs commented 6 hours ago

The idea is that the syntax for triple terms is an RDF term without adding triples into the graph.

RDF collections and predicateObjectLists generate triples. In SPARQL, it is possible to create terms without there being a graph.

<<:s :p :o >> rdfx:source <URL>

does not assert :s :p :o so << [:q :z] :p :o >> should not assert _:b :q :z .

It is possible to write out in full - but the shorthand syntax for keeps triple terms as terms.

The odd case is () which is a term and is not triples. If (1 2 3) isn't allowed, then not including the rdf:nil shorthand seems better when you can write rdf:nil.

In N-triples, the "one line, one triple" design means no side-effects; N-Triples is legal Turtle.

doerthe commented 5 hours ago

Mmm, I am not convinced (yet :) ).

I do not see a problem if << [:q :z] :p :o >> asserts _:b :q :z .as this was from my understanding how the syntactic sugar works.

I see the same for lists, If I write << :s :p (1 2 3) >> it should (according to me, so this is a weak "should") give as well

_:b0 rdf:first 1 .
_:b0 rdf:rest _:b1 .
_:b1 rdf:first 2 .
_:b1 rdf:rest _:b2 .
_:b2  rdf:first 3.
_:b2 rdf:rest rdf:nil.

As always, I dislike the syntactic restriction. I know that this does not influence the abstract syntax and that my usual argument that we are not able to express entailment results does not hold here, so I could be convinced, but currently this restriction feels random (and of course that restriction also causes difficulties for N3 as well, but that is a different story :) ).

afs commented 4 hours ago

Indeed, N3 is different.

<< :s :p [ :name "Alice" ; owl:sameAs <X> ; :purchased :car ] >>

would be

_:b  rdf:reifies <<( :s :p _:blank )>> .
_:blank :name "Alice" .
_:blank owl:sameAs <X> .
_:blank :purchased :car .

so (OWL) this holds:

<X> :name "Alice" .
<X> :purchased :car .

That's different to the outcome I think is asked for in email << functor log:isFunctorOf (arguments) >> where I think would be to include the arguments in a single reifier with the functor log:isFunctorOf.

The syntax can be widened later if/when a full multiple-triple form is worked out. As we have seen, there is a long road there. At the moment, the narrower form is safer - we can't start wider and reduce after publication. The new charter gives Q1 2025 for RDF documents.

josd commented 1 hour ago

I see the same for lists, If I write << :s :p (1 2 3) >> it should (according to me, so this is a weak "should") give as well

_:b0 rdf:first 1 .
_:b0 rdf:rest _:b1 .
_:b1 rdf:first 2 .
_:b1 rdf:rest _:b2 .
_:b2  rdf:first 3.
_:b2 rdf:rest rdf:nil.

Fully agreed @doerthe and is also what I replied in https://lists.w3.org/Archives/Public/public-rdf-star-wg/2024Oct/0047.html

gkellogg commented 52 minutes ago

As @afs said, I think having triples generated within << ... >> that aren't treated as triple terms is a problem; In the case of the list, having the reference to the list be not asserted, but the list entries be asserted is counter-intuitive. If we were to support this, I think that we would have the reifier reify all triples which are generated within the reifying triple. So, I'd prefer to see the following:

<< :s :p (1 2 3) >> .

# Generates

_:blank rdf:reifies
  <<(:s :p _:b0)>>,
  <<(_:b0 rdf:first 1)>>,
  <<(_:b0 rdf:rest _:b1)>>,
  <<(_:b1 rdf:first 2)>>,
  <<(_:b1 rdf:rest _:b2)>>,
  <<(_:b2 rdf:first 3)>>,
  <<(_:b2 rdf:rest rdf:nil)>> .

This, of course, get's much more complicated if there are embedded lists or blankNodePropertyLists.

Alternatively, keep the productions narrow and orbit collections and blankNodePropertyLists in a reifying triple as the current grammar already does.

josd commented 18 minutes ago

I do not see any harm nor counter-intuitiveness in asserting list triples on their own. Doing the test: https://github.com/eyereasoner/eye/blob/master/reasoning/rdflogic/socrates2.ttl works in the same way as https://github.com/eyereasoner/eye/blob/master/reasoning/rdflogic/socrates.ttl and gives the same answer https://github.com/eyereasoner/eye/blob/master/reasoning/rdflogic/output/socrates2.ttl

lisp commented 14 minutes ago

would it not be less a problem if the grammar were extended by permitting an (unannotated) object list of the respective type in each of the statement reification forms.
as in

<< functor log:isFunctorOf argument1, argument2 >>

=>

_:r rdf:reifies <<( functor log:isFunctorOf argument1 )>>.
_:r rdf:reifies <<( functor log:isFunctorOf argument2 )>>.
josd commented 8 minutes ago

Well, we must guarantee that the list of arguments is closed, hence the use of a collection.

lisp commented 3 minutes ago

Well, we must guarantee that the list of arguments is closed, hence the use of a collection.

given some collection, what prevents a process from replacing whatever statement form comprises the rdf:nil with statements which expand the collection?