-
Notifications
You must be signed in to change notification settings - Fork 20
Framing blank node unnamed graphs #27
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
Comments
Note that the frame will need to have It should do more than that, although my implementation doesn't quite get there. Use the following frame in my distiller: {
"@context": {
"@version": 1.1,
"id": "@id",
"claim": {"@id": "ex:claim"},
"name": "ex:name",
"proof": {"@id": "ex:proof", "@type": "@id"},
"signer": {"@id": "ex:signer", "@type": "@id"},
"subject": {"@id": "ex:subject", "@type": "@id"},
"knows": {"@id": "ex:knows", "@type": "@id"}
},
"@graph": {
"subject": {
"@embed": "@always"
},
"proof": {}
}
} I get the following output: {
"@context": {
"@version": 1.1,
"id": "@id",
"claim": {
"@id": "ex:claim"
},
"name": "ex:name",
"proof": {
"@id": "ex:proof",
"@type": "@id"
},
"signer": {
"@id": "ex:signer",
"@type": "@id"
},
"subject": {
"@id": "ex:subject",
"@type": "@id"
},
"knows": {
"@id": "ex:knows",
"@type": "@id"
}
},
"@graph": [
{
"ex:proof": {
"@graph": [
{
"@type": "ex:Proof",
"name": "the proof",
"signer": "ex:subject"
},
{
"id": "ex:subject",
"name": "something different"
}
]
},
"id": "ex:cred",
"subject": {
"id": "ex:subject",
"knows": {
"id": "ex:issuer",
"name": "Someone else"
},
"name": "the subject"
}
}
]
} The JavaScript implementation doesn't quite do this, and generates an error in any case using this frame. I'll need to see why the The step at 4.4.1 in the Framing Algorithm should handle finding the graph and embed it. It should also work on the merged graph, I think, but doesn't seem to for me. I need to see if these are implementation issues, or if the algorithm is missing something. Help appreciated if you can look at it from your end. |
This issue was discussed in a meeting.
View the transcriptFraming blank node unnamed graphsRob Sanderson: ref: #27 Gregg Kellogg: how can SHeX validate verifiable claims? … there was no reasonable way for SHeX to figure out where to start in that graph to begin validation. Why not just reuse the blank node as the default subject of the graph? Ivan Herman: I remember, and I am opposed to this. Rob Sanderson: if it was not a blank node, does the problem go away? Gregg Kellogg: if it had an identity, it wouldn’t get to this point. Gregg Kellogg: if you use a graph container, should we use the blank node as the default subject for the graph? Ivan Herman: that’s semantically wrong. Rob Sanderson: is this a RDF problem? Ivan Herman: no. A blank node for the graph and a blank node within the graph are two different things. Gregg Kellogg: JSON people have a tree-based view, and graphs are not required to have a root. … so it’s not unreasonable to add a property to indicate in the root. Gregg Kellogg: this is used in framing, where the top node has a id Harold Solbrig: I object to bnode, because if there’s not a stake in the ground, having magic to b-nodes… Gregg Kellogg: fragment identifiers would be a better solution. Proposed resolution: close framing#27 wontfix, as there’s no justification for the required RDF layer requirement that the blank node identity of the named graph is the default subject of the triples in the graph (Rob Sanderson) Gregg Kellogg: +1 Rob Sanderson: +1 David Newbury: +1 Ivan Herman: +1 Harold Solbrig: +1! David I. Lehn: +1 Jeff Mixter: +1 Adam Soroka: +0 Resolution #15: close framing#27 wontfix, as there’s no justification for the required RDF layer requirement that the blank node identity of the named graph is the default subject of the triples in the graph {: #resolution15 .resolution} |
The conversation doesn't seem to apply to this issue but rather to this other one about SHeX and blank node identifier reuse: Was the wrong issue closed? |
This issue has to do with a bug in either the framing algorithm or the spec (or both) ... it is unrelated to SHeX or reusing blank nodes with named graph subjects/etc. |
@dlongley I just did what the resolution said in the minutes... @azaroth42, has there been a mistake in the minutes? (I am on my way to the airport, I cannot check it now.) |
Yes, this is an issue we didn’t discuss and needs to be reopened. |
Can somebody send me the changes on the minutes? Better: do the changes? |
For the records: #27 (comment) is indeed unrelated to this issue. Change happened on the minutes on 2019-02-15. |
This issue was discussed in a meeting.
View the transcript4. Framing blank node unnamed graphs (Issue frame27)Rob Sanderson: the issue is about Framing blank node unnamed graphs Rob Sanderson: #27 Dave Longley: I have an example of a document with a graph container, … and couldn’t to get the same document as my input using framing. … It seems to defeat the purpose of framing. Gregg Kellogg: It is true that this should be possible, … but I doubt we can address that problem before the next publication. Rob Sanderson: should there be a note in the next WD about that issue? Proposed resolution: Leave framing 27 open, and to investigate the cause. Record open issue in the next PWD of Framing. (Rob Sanderson) Gregg Kellogg: this would appear in the list of open issue that we append to each WD Simon Steyskal: +1 Pierre-Antoine Champin: +1 Rob Sanderson: +1 Dave Longley: +1 Adam Soroka: +1 Harold Solbrig: +1 Ivan Herman: +1 David Newbury: +1 Benjamin Young: +1 Rob Sanderson: given the low number of open issue, I would prefer some editor text to make the issue more visible David I. Lehn: +1 Resolution #2: Leave framing 27 open, and to investigate the cause. Record open issue in the next PWD of Framing. {: #resolution2 .resolution} Gregg Kellogg: +1 Dave Longley: once we get sealed contexts working the way we need we might be able to look into addressing this one next Dave Longley: (we == Digital Bazaar) |
So, I re-tried this with the following frame: {
"@context": {
"@version": 1.1,
"id": "@id",
"claim": {"@id": "ex:claim"},
"name": "ex:name",
"proof": {"@id": "ex:proof", "@type": "@id", "@container": "@graph"},
"signer": {"@id": "ex:signer", "@type": "@id"},
"subject": {"@id": "ex:subject", "@type": "@id"},
"knows": {"@id": "ex:knows", "@type": "@id"}
},
"@graph": {
"subject": {
"@embed": "@always"
},
"proof": {}
}
} I do get mostly the expected results: {
"@context": {
"@version": 1.1,
"id": "@id",
"claim": {
"@id": "ex:claim"
},
"name": "ex:name",
"proof": {
"@id": "ex:proof",
"@type": "@id",
"@container": "@graph"
},
"signer": {
"@id": "ex:signer",
"@type": "@id"
},
"subject": {
"@id": "ex:subject",
"@type": "@id"
},
"knows": {
"@id": "ex:knows",
"@type": "@id"
}
},
"id": "ex:cred",
"subject": {
"id": "ex:subject",
"name": "the subject",
"knows": {
"id": "ex:issuer",
"name": "Someone else"
}
},
"proof": [
{
"@type": "ex:Proof",
"name": "the proof",
"signer": {
"id": "ex:subject",
"name": "something different"
}
},
"ex:subject"
]
} The The playground still doesn't generate the right output, however, but it seems that the algorithm is (mostly) correct. |
Actually, the only oddity here is that "proof" contains two items, the second of which is "ex:subject", and I'm not sure where that comes from. |
This is because an added restriction is necessary to get a single item, which is done in #63. |
So while the output in #63 looks right to me, I don't understand why adding the |
This issue was discussed in a meeting.
View the transcriptRob Sanderson: See Framing #27Dave Longley: See a particular comment Dave Longley: I raised this issue while trying to frame VC-like data, … asked if other implementations had the same issue. … This example generate a strange artifact (“ex:subject” at the bottom). Gregg Kellogg: this artifact does not produce any triple, … we can remove it by filtering on type. But is the output still correct? … The issue may not be in framing, but somewhere else (maybe compaction?). Rob Sanderson: to try and summarize: in the original data, there is exactly one named graph. … inside that is a proof which is a graph container. … The frame generates the subject as a separate graph? Gregg Kellogg: (something about this behavior being legitimate with other data) Dave Longley: may be this could be solved with @include? Gregg Kellogg: there might be other holes in framing which we have not seen yet… … We should try to flesh out the test suite further. |
Some observations:
|
…efaulting to false, and set to true when recursing into node objects. Add tests to not add node at top level if embedded is false and it has already been serialized, and also use the check on `@embed: @never` to make that happen only when in an embedded node object. Update test g010 to not use `@type` in framing. For #27.
Would this make it impossible to use Input: {
"@graph": [{
"@id": "ex:foo1",
"@type": "ex:Foo"
}, {
"@id": "ex:foo2",
"@type": "ex:Foo"
}, {
"@id": "ex:bar",
"@type": "ex:Bar"
}]
} Frame: {
"@type": "ex:Foo",
"@embed": "@never"
} Output: {
"@graph": [
{
"@id": "ex:foo1"
},
{
"@id": "ex:foo2"
}
]
} I don't know if that's a use case or not -- but I suppose it could be. I think that's my only potential concern with the approach. So here are my thoughts on the two options: My first thought was that seeing However, on second thought, I think it would be odd to make it impossible to compact to an So, I think using Also, I didn't quite understand this comment (emphasis mine):
I may be misunderstanding what you're saying here, but it wouldn't be arbitrary nor would I think it would affect compaction because So we'd get something like this from framing: // top level
"@graph": [{
// will be come a `@graph: @container`
// post compaction
"ex:proof": [{
// first blank node named graph
"@graph": [{
// two matches at the graph root level
"@included": [{
"@id": "ex:foo1",
"@type": ["ex:Foo"]
}, {
"@id": "ex:foo2"
"@type": ["ex:Foo"]
}]
}]
}, {
// second blank node named graph
"@graph": [{
// just one match at the graph root level
"@id": "ex:bar1",
"@type": ["ex:Bar"]
}]
}]
}] Compaction would just run normally on that and produce: // top level
"@context": {
"proof": {"@id": "ex:proof", "@container": "@graph"}
},
"@graph": [{
"proof": [{
// first blank node named graph
// two matches at the root graph level
"@included": [{
"@id": "ex:foo1",
"@type": "ex:Foo"
}, {
"@id": "ex:foo2"
"@type": "ex:Foo"
}]
}, {
// second blank node named graph
// just one match at the root graph level
"@id": "ex:bar1",
"@type": "ex:Bar"
}]
}] So, framing would handle injecting In fact, maybe we could get away with always outputting
I thought |
Yes, this wouldn't be supported, but that's not embedding. The From the syntax doc:
(As an aside, the algorithm should probably also display node references as immediate values of |
👍
But we have many cases where you can't compact using a term which doesn't match. I think it's in perfect keeping with the spirit of term selection (as challenging as it may be) to only match when the value pattern allows it to be expressed using this term, otherwise a more appropriate term could be selected.
👎
So, putting // top level
"@context": {
"proof": {"@id": "ex:proof", "@container": "@graph"}
},
"@graph": [{
"proof": [{
// First node exists as value of _proof_
"@id": "ex:foo1",
"@type": "ex:Foo"
"@included": [{
// Second node _included_ within first node.
"@id": "ex:foo2"
"@type": "ex:Foo"
}]
}, {
// second blank node named graph
// just one match at the root graph level
"@id": "ex:bar1",
"@type": "ex:Bar"
}]
}] This is more in keeping of the sprit of
If we were to do so, this step would most likely be handled by compaction, as framing just results in an expanded output, in which there is no I think the mechanism I showed is more natural, but unless ordering, the selection of the first node may be arbitrary, but this is a corner-case. This could be something done in the compaction algorithm, when the term has
In expanded form, named graphs are serialized like the following: {
"@graph": [{
"ex:proof": [
{"@id": "_:b1"},
{"@id": "_:b2"}
]
}, {
"@graph": [{
"@id": "ex:foo2",
"@type": "ex:Foo"
}, {
"@id": "ex:foo1",
"@type": "ex:Foo"
}]
}, {
"@graph": [{
"@id": "ex:bar1",
"@type": "ex:Bar"
}]
}]
} This falls out of the current way RDF would serialize quads to JSON-LD. Of course, you could always frame with
The issue came to light when creating a trivial frame with With The |
Can I get clarity on what you think should be a match and what shouldn't? For example: Would this roundtrip ( "@context": {
"proof": {"@id": "ex:proof", "@container": "@graph"}
},
"proof": {
"@id": "ex:foo1",
"@type": "ex:Foo"
"@included": {
"@id": "ex:foo2"
"@type": "ex:Foo"
}
} What about this? "@context": {
"proof": {"@id": "ex:proof", "@container": "@graph"}
},
"proof": {
"@included": [{
"@id": "ex:foo1",
"@type": "ex:Foo"
}, {
"@id": "ex:foo2"
"@type": "ex:Foo"
}]
} If you think both of these should be matches, can you give an example of something that wouldn't roundtrip? If you think the first should round trip but not the second, don't you think that will be confusing/inconsistent? I would think it would special case I'd rather people framing things have to consider cases where their specified matches might produce multiple results at the root level of a graph. That's already a thing they have to do with the default graph when It seems to me that the rule for whether or not |
👍 |
Yes, because when selecting "proof", you have a value with just a single node definition. The contents of
Yes, that would match too, because there is still just a single member (
Look how each expands: [{
"ex:proof": [{
"@graph": [{
"@id": "ex:foo1",
"@type": ["ex:Foo"],
"@included": [{
"@id": "ex:foo2",
"@type": ["ex:Foo"]
}]
}]
}]
}] and [{
"ex:proof": [{
"@graph": [{
"@included": [{
"@id": "ex:foo1",
"@type": ["ex:Foo"]
}, {
"@id": "ex:foo2",
"@type": ["ex:Foo"]
}]
}]
}]
}] If, instead, you had the following expanded: [{
"ex:proof": [{
"@graph": [{
"@id": "ex:foo1",
"@type": ["ex:Foo"]
}, {
"@id": "ex:foo2",
"@type": ["ex:Foo"]
}]
}]
}] it would not select "proof", as the value to compact has two members. You can address this in framing through the use of
Well, I won't stand in the way of this, but in that case, I'd say that the compaction algorithm should insert the {
"@context": {
"@version": 1.1,
"proof": {"@id": "ex:proof", "@container": "@graph"}
},
"proof": {
"@id": "ex:foo1",
"@type": "ex:Foo",
"@included": {
"@id": "ex:foo2",
"@type": "ex:Foo"
}
}
} |
Note that this discussion is really about w3c/json-ld-api#143. If we agree what the framing algorithm should do, as indicated by this PR, we can close it. The only change I'll make is to also consider values of |
…efaulting to false, and set to true when recursing into node objects. Add tests to not add node at top level if embedded is false and it has already been serialized, and also use the check on `@embed: @never` to make that happen only when in an embedded node object. Update test g010 to not use `@type` in framing. For #27.
Should have a formal resolution to close. |
This issue was discussed in a meeting.
View the transcriptFraming blank nodesRob Sanderson: last discussion we agreed that we couldn’t solve it on a call … so gkellog and dlongley went off to look at it Gregg Kellogg: we found a problem in a framing test where @container : @graph got mangled in re-expansion… a bug in the compaction algo … if the value is an array, it puts them in an @included block… i tried [s solution] but it turned out not to be defined well enough Rob Sanderson: all of that is solved and merged? Gregg Kellogg: yep Gregg Kellogg: See API PR #146 Gregg Kellogg: See API PR #145 Proposed resolution: Close framing #27 as not being the issue, and the real issues being addressed is api #143, solved by api PRs # 145 and #146 (Rob Sanderson) Rob Sanderson: +1 Benjamin Young: +1 Dave Longley: +1 Gregg Kellogg: +1 Ivan Herman: +1 Adam Soroka: +1 Pierre-Antoine Champin: +1 Ruben Taelman: +1 Rob Sanderson: RESOLVE: Close framing #27 as not being the issue, and the real issues being addressed is api #143, solved by api PRs # 145 and #146 Proposed resolution: Close api #143 as resolved by api PR #145 and #146 (Rob Sanderson) Rob Sanderson: +1 Ivan Herman: +1 Ruben Taelman: +1 Gregg Kellogg: +1 Adam Soroka: +1 Pierre-Antoine Champin: +1 Benjamin Young: +1 Dave Longley: +1 Resolution #2: Close api #143 as resolved by api PR #145 and #146 |
I'm trying to create an "identity frame" for some data that uses
"@container": "@graph"
. The data looks like this:And the frame like this:
A link to the playground is here: http://tinyurl.com/yaewmkk5
The goal is for the output to match the input, but it does not. Does anyone know what tweaks are necessary to accomplish this? Do we have proper support for framing blank node named graphs? From looking at the jsonld.js implementation, it seemed like only non-blank node named graphs were supported... and the spec doesn't seem to give any examples with blank nodes. It seems we have both a spec and an implementation gap here. If not, could someone share a working example?
The text was updated successfully, but these errors were encountered: