Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
doerthe opened this issue Oct 23, 2024 · 19 comments
Open

Comments

@doerthe
Copy link

doerthe commented Oct 23, 2024

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.

@doerthe doerthe changed the title Collections and blank node property lists in triple terms Turtle Grammar: Collections and blank node property lists in triple terms Oct 23, 2024
@rubensworks
Copy link
Member

@doerthe
Copy link
Author

doerthe commented Oct 23, 2024

Thank you, I missed that.

@afs
Copy link
Contributor

afs commented Oct 23, 2024

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
Copy link
Author

doerthe commented Oct 23, 2024

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
Copy link
Contributor

afs commented Oct 23, 2024

Indeed, N3 is different.

In RDF:

<< :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 the outcome would 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.


Update - from below - apparently the request is asserting the triples, attaching them to a reifier them.

@josd
Copy link

josd commented Oct 23, 2024

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
Copy link
Member

gkellogg commented Oct 23, 2024

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 omit collections and blankNodePropertyLists in a reifying triple as the current grammar already does.

@josd
Copy link

josd commented Oct 23, 2024

@lisp
Copy link

lisp commented Oct 23, 2024

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
Copy link

josd commented Oct 23, 2024

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

@lisp
Copy link

lisp commented Oct 23, 2024

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?

@josd
Copy link

josd commented Oct 23, 2024

See https://www.w3.org/TR/rdf11-mt/#rdf-collections

RDF provides a vocabulary for describing collections, i.e.'list structures', in terms of head-tail links. Collections differ from containers in allowing branching structure and in having an explicit terminator, allowing applications to determine the exact set of items in the collection.

and you can't retract an asserted _:bnl_i rdf:rest rdf:nil. triple in RDF.

@TallTed
Copy link
Member

TallTed commented Oct 23, 2024

you can't retract an asserted _:bnl_i rdf:rest rdf:nil. triple in RDF

Really? I can't find anything that says I cannot do something like this —

DELETE {} WHERE { _:bnl_i rdf:rest rdf:nil } .
INSERT { _:bnl_i rdf:rest _:bn2_x } .
# etc.

@pchampin
Copy link
Contributor

As always, I dislike the syntactic restriction.

I sympathize with that, but I'm with @afs and @gkellogg on this: having constructs inside the << ... >> producing asserted triples seems rather counter-intuitive.

Note that the alternative, which is to generate more unasserted triple-terms, as suggested by @gkellogg here and by @lisp here, is also quite problematic, because it would not be consistent with the annotations syntax:

<< :functor log:isFunctorOf :argument1, :argument2 ~ :r >>.

would expand to

_:r rdf:reifies <<( :functor log:isFunctorOf :argument1 )>>.
_:r rdf:reifies <<( :functor log:isFunctorOf :argument2 )>>.
# :r reifies two triples

while

:functor log:isFunctorOf :argument1, :argument2 ~ :r.

would expand to

:functor log:isFunctorOf :argument1.
:functor log:isFunctorOf :argument2.
_:r rdf:reifies <<( :functor log:isFunctorOf :argument2 )>>.
# :r reifies one triple

unless of course we radically change the way the annotation syntax works, but doing that would be far from trivial (to specify and to implement) IMO.

So I would refrain from opening that pandora box, and keep the strict constraints on what can be used inside the << ... >> brackets.

@afs
Copy link
Contributor

afs commented Oct 24, 2024

(Some clarification for reading this issue later)

Despite the issue title, this discussion mostly has been about reifier triples (occurrences) not triple terms. They are connected by the expansion of occurrence syntax.

Turtle has rule rtSubject and rtObject for reifier triples, and ttSubject and ttObject for triple terms.

The TriG grammar is a little out of date.

@lisp
Copy link

lisp commented Oct 24, 2024

Note that the alternative, which is to generate more unasserted triple-terms, as suggested by @gkellogg #132 (comment) and by @lisp #132 (comment), is also quite problematic, because it would not be consistent with the annotations syntax

why should that necessarily be the case? they are distinctly different constructs.

@josd
Copy link

josd commented Oct 24, 2024

As always, I dislike the syntactic restriction.

I sympathize with that, but I'm with @afs and @gkellogg on this: having constructs inside the << ... >> producing asserted triples seems rather counter-intuitive.

Note that the alternative, which is to generate more unasserted triple-terms, as suggested by @gkellogg here and by @lisp here, is also quite problematic, because it would not be consistent with the annotations syntax:

<< :functor log:isFunctorOf :argument1, :argument2 ~ :r >>.

would expand to

_:r rdf:reifies <<( :functor log:isFunctorOf :argument1 )>>.
_:r rdf:reifies <<( :functor log:isFunctorOf :argument2 )>>.
# :r reifies two triples

while

:functor log:isFunctorOf :argument1, :argument2 ~ :r.

would expand to

:functor log:isFunctorOf :argument1.
:functor log:isFunctorOf :argument2.
_:r rdf:reifies <<( :functor log:isFunctorOf :argument2 )>>.
# :r reifies one triple

unless of course we radically change the way the annotation syntax works, but doing that would be far from trivial (to specify and to implement) IMO.

So I would refrain from opening that pandora box, and keep the strict constraints on what can be used inside the << ... >> brackets.

Fair enough, I will continue with https://github.com/eyereasoner/rdfproof

@doerthe
Copy link
Author

doerthe commented Oct 25, 2024

OK, I see that this discussion boils down to how to handle

<<( :functor log:isFunctorOf :argument1, :argument2 )>>
or also
<<( :functor log:isFunctorOf :argument1; log:isFunctorOf :argument2 )>>

I personally would expect that only the first triple is quoted, but I can see how intuitions differ (they always do) and I can see your "box of pandora" argument. Which of still leaves me unhappy with the syntactic restriction...

@rat10
Copy link
Contributor

rat10 commented Oct 28, 2024

As usual, I don't see the pandora box ;-) @pchampin 's example to illustrate a problem has a problem itself:

:functor log:isFunctorOf :argument1 , 
                         :argument2 ~ :r .

is equivalent to

:functor log:isFunctorOf :argument1 , 
                         :argument2 .
<<:functor log:isFunctorOf :argument2 ~:r >>

If the example used reifiers after each logical statement, i.e.

:functor log:isFunctorOf :argument1 ~ :r , 
                         :argument2 ~ :r .

everything would work as expected. I think this merely illustrates a possible pitfall of that specific syntax - namely that it seems to refer to multiple triples when in fact it doesn't -, and it should be discussed in a best practices section no matter how this issue here is resolved. Of course, better yet would be to introduce a syntax to group statements into graphs.

@gkellogg 's example above IMO captures best what should be assumed from a construct like << :s :p ( :o1 :o2 :o3) >>: the list is not asserted, and all statements generated by the collection's syntactic sugar are part of the same reification.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants