Re: adding inline graphs to TriG

On Jul 17, 2013, at 5:21 PM, Sandro Hawke <> wrote:

> On 07/17/2013 07:42 PM, Eric Prud'hommeaux wrote:
>> * Gregg Kellogg <> [2013-07-17 11:36-0700]
>>> On Jul 16, 2013, at 5:53 PM, Sandro Hawke <> wrote:
>>>> I know this is going to seem to some people like it's going too far, but it seems to me like such a good idea, in good conscience I have to at least seriously propose it.    If there aren't at least three +1's for this email, I wont mention it again.
>>>> Right now, in TriG, you can say things like:
>>>> [ a :Patch;
>>>>   :deletes _:g1;
>>>>   :inserts _:g2 ].
>>>> GRAPH _:g1 { ... }
>>>> GRAPH _:g2 { ... }
>>>> I think it would make a whole lot of sense to allow a little syntactic sugar.  I'd like to allow this:
>>>> [ a :Patch;
>>>>    :delete { ... };
>>>>    :inserts { ... } ].
>>>> The mechanism for this would be exactly like the mechanism for square-bracket [ ... ] expressions.  Just like [ ... ] is syntactic sugar for a blank node that is "used" once, inline graphs would be syntactic sugar for a named graph that is "used" once.    Any TriG document with inline graphs could be re-written to not have inline graphs by just replacing the inline graph with a new blank node label, then adding to the end of the document a name-graph pair of that label and that graph.     Nested inline graphs work fine by this rule, with no special handling.
>>>> For example:
>>>> :alice :said { :bob :said { :charlie said { :spot a :Dog } } } }
>>>> is syntactic sugar for:
>>>> :alice :said _:u1.
>>>> GRAPH _:u1 { :bob :said _:u2 }
>>>> GRAPH _:u2 { :charlie said _:u3 }
>>>> GRAPH _:u3 { :spot a :Dog }
>>>> I'm unsure about whether to allow this in the subject position or just the object position.  It's probably hard to parse in the subject position; I'm not sure it can be done with an LL(1) grammar.   (Consider that "{s p o} s p o" is currently valid TriG, distinguishing that from "{s p o} p o" is tricky.)   I don't think it's hard in just the object position, and most of my use cases are fine with the object position.  If people like this idea in general, I'll investigate the grammar more.
>>> I couldn't get a bare graph to work in the subject position, but it works well in the object position. The modified EBNF I used was the following:
>> Yeah, I fiddled for a bit, but wasn't optimistic 'cause
>>   { <s1> <p1> <o1> } <p2> ...
>> could either be a wrappedDefault followed by a graph name or a subject graph and a predicate.
> Brainstorming a little on making inline graphs work as subjects....
> Could we forbid default graph triples being both wrapped and unwrapped in the same TriG file?
> Essentially:     trigDoc  ::=  unwrappedTrigDoc | wrappedTrigDoc
> and then in unwrappedTrigDoc your example text is clearly a subject graph + predicate, and in wrappedTrigDocument it's clearly a wrappedDefault followed by a graph name.
> It makes the grammar a lot bigger, as large sections have to be duplicated.   My intuition is it'll cause a performance hit for recursive decent parsers, but I could be wrong about that. yacc-style parsers should be fine with it.

Uhh, sounds like a nightmare of compromise. An extension which allows
graphs as objects is pretty simple and works well with the existing
grammar; graph subjects aren't important enough.

Alternatively, ignoring our charter, base the design on N3, removing
most of the syntactic sugar. This goes against the minimal TriG data
set design, but is more natural for making these kind if statements.

Unfortunately, it's too late in the game to be trying for too much,
and I suspect the support for even these relatively modest changes to
get wide support.


>      -- Sandro
>> If we want to work towards symmetry, we can deprecate wrappedDefault (which is how old Trig expressed the default graph) with the intent of commandeering the syntax some years in the future. I'd give a +1 on that. (The other approach is of course a rev'd media type and file extension.)
>>> [1g]   trigDoc               ::= (statement)*
>>> [2g]   statement             ::= directive | tripleOrBareGraph | graphword | wrappedDefault
>>> [3g]   tripleOrBareGraph     ::= graphName (wrappedDefault | PropertyListNotEmpty '.')
>>>                                | graphName1 (wrappedDefault | PropertyList '.')
>>>                                | collection PropertyListNotEmpty '.'
>>> [4g]   graphword             ::= GRAPH graphName wrappedDefault
>>> [5g]   wrappedDefault        ::= '{' TriplesTemplate? '}'
>>> [6g]   graphName             ::= iri | BlankNode
>>> [7g]   graphName1            ::= BlankNodePropertyList
>>> Plus, a modification to the "object" production:
>>> [12]   object                ::= iri | BlankNode | collection | BlankNodePropertyList | literal | wrappedDefault
>>> This should allow statements similar to what you suggested.
>>> Minor changes to the parser logic are to remember the current graph name when beginning to process object, and assign a new blank node as the graph name, if the next production is a wrappedDefault, restoring it afterwards. The wrappedDefault returns the current graph name as the resulting resource, which allows it to be used like anything else in the object production.
>>> Trying to allow wrappedDefault in the subject position creates conflicts.
>>> Gregg
>>>> People familiar with N3 will note this makes TriG even more like N3.  I'd say it brings TriG from being 85% of N3 to maybe 95% of N3.  This is probably a good thing.   (I'm measuring in terms of feature usage/importance, and excluding features that are really just RDF vocabulary.)
>>>> So, anyone else think it's worth fully spec'ing this and adding it as a TriG "Feature At Risk" for last call?
>>>> If not, I can just put it on my wishlist for the next turtle-like dataset syntax, someday.
>>>>       -- Sandro

Received on Thursday, 18 July 2013 01:16:03 UTC