Make the ShEx vocabulary and ShExR's renderings derived, and keep them in sync - #73
Open
ericprud wants to merge 6 commits into
Open
Make the ShEx vocabulary and ShExR's renderings derived, and keep them in sync#73ericprud wants to merge 6 commits into
ericprud wants to merge 6 commits into
Conversation
Ports Gregg Kellogg's mk_vocab.rb (shexspec.github.io/ns, dormant since 2018) to dependency-free Node, verified to reproduce its output byte-for-byte, and makes vocab.csv the source of truth for http://www.w3.org/ns/shex#. It lands here because this repo already carried two hand-maintained copies of that vocabulary and both had drifted: doc/ShExJ-context.jsonld is the @context of w3c/ns shex.jsonld, missing shex:extends; doc/ShExR.shex runs ahead of the published vocabulary, using sx:ShapeDecl, sx:abstract, sx:imports and sx:negated, which it never defined. doc/ShExJ-context.jsonld is now generated (npm run vocab). ShExR stays hand-maintained -- the CSV cannot express CLOSED, type arcs or the list shapes -- and npm run vocab-check reports the four missing terms instead. That check fails today, so it is deliberately not wired into npm test; adding the terms changes a published W3C namespace and is Eric's call. Also adds the shape-map terms (QueryMap, ShapeMap, node, shape, status, FOCUS, _) per https://shexspec.github.io/shape-map/. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
No definitions change: the generator reproduced all 70 existing keys exactly. Adds the 8 it was missing -- shex:extends, which drifted when EXTENDS was added to w3c/ns, and the seven shape-map terms. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
shexTest publishes Pages from main, but shex.html is only generated into w3c/ns, so vocab/shex.html never exists. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Closes the drift between doc/ShExR.shex and http://www.w3.org/ns/shex#, in both directions, and turns npm run vocab-check green so it can join npm test. Adds to vocab.csv the three terms ShExR had run ahead with -- sx:ShapeDecl, sx:abstract and sx:imports -- taken from doc/ShExJ.jsg. Following ShapeDeclList1Plus, sx:shapes now has range ShapeDecl rather than ShapeExpression, and sx:shapeExpr's domain widens to ShapeNot | ShapeDecl. Removes sx:negated, which pointed the other way. It was the ShEx 2.0 draft's `!` operator, removed from the language in 224c610 / spec d3f882d (Nov 2016) over shexSpec/shex#11 and replaced by {0,0} and ShapeNot. fe51e15 copied it back from ShExJ.jsg seven weeks later; e01f012 ("TripleConstraint -= negated:BOOL") cleaned the grammar in 2020 but not ShExR. It was never published, is not in the spec, and the ShExC parser has no `!` rule, so nothing could ever produce it. Gone from ShExR.{shex,ttl,json,ntriples}; in .ntriples the list cell was relinked and the orphaned subtree swept (13 triples). Also drops the same vintage of leftover from ShExV.jsg and the meta.ttl sameAbstractSyntaxAs line referencing two fixtures deleted in 2016. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…in sync doc/ShExR.shex is the hand-maintained source. The other three files in doc/ are the same schema in other syntaxes, hand-synced on the honour system, and they drifted. doc/ShExR.ntriples was the worst: last regenerated in 2017 (7a7da0d), 800 triples against ShExR.shex's 1341, predating ShapeDecl, abstract, imports and extends entirely. mkShExR.js parses ShExR.shex to ShExJ and expands that through doc/ShExJ-context.jsonld, since ShExJ + that context *is* ShExR. So this also exercises the context, which is generated from vocab/vocab.csv -- one edit to the vocabulary now has to stay consistent with the schema-of-schemas. ShExR.ttl and .ntriples are regenerated and byte-compared by CI. ShExR.json is compared as an AST instead, so its hand formatting survives -- it was already exactly what ShExR.shex parses to. The Turtle is pretty-printed rather than handed to N3.Writer, which labels every blank node and spells out all 265 rdf:first/rdf:rest triples. The ShExR graph is a tree, so blank nodes nest as [ ] and lists collapse to ( ), close to how the file was written by hand. Subject order comes from the rendered name, never a blank node label, so output does not depend on which parser produced the quads; the printer is idempotent. No content changed in ShExR.ttl: canonicalising the previously committed file yields the regenerated one exactly. The diff is formatting, and the nine years of catch-up in .ntriples. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Records the deltas found while deriving the ShExR renderings, with the evidence for each and links into the ShExC productions and the two grammars here. The substantive one is `start`. ShExC has `start ::= "start" '=' inlineShapeExpression` and ShExJ has `start:shapeExprOrRef?`, where shapeExpr cannot be a ShapeDecl since 2.1 moved id onto ShapeDecl. ShExR has `sx:start @<#shapeDeclOrExpr>`, which admits one. Verified against all three: an anonymous ShapeDecl at start is rejected by ShExJ.jsg and accepted by ShExR.shex, and no ShExC production denotes it. ShExR has no choice -- RDF cannot distinguish reference from containment, so `sx:start <S>` where <S> is a ShapeDecl is how `start = @<S>` must be encoded. Nor can it be tightened to IRI-only, because shapeDeclLabel admits BNODE. The same shapeDeclOrExpr sits under shapeExprs, shapeExpr, extends and valueExpr. Two lesser ones: an inline abstract ShapeDecl at start slips past the abstract-shape requirement, which is worded over shapeExprRefs; and the inlineShapeExpression restriction (no annotations or semantic actions without parentheses) exists only in ShExC, so a ShExJ->ShExC writer has to parenthesise or emit invalid ShExC -- shex.js's parser accepts the bare form regardless. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Six commits. The theme is that several files here were copies of each other maintained by hand, and they had drifted; this makes each one derived from a single source and adds checks to
npm testso they cannot drift again.vocab/— the source ofhttp://www.w3.org/ns/shexshex.ttl,shex.jsonldandshex.htmlat w3.org/ns are generated from avocab.csvby a script Gregg Kellogg (RIP) wrote for the purpose. That source had been sitting in the long-dormant shexspec.github.io repo. It now lives invocab/, ported from Ruby to dependency-free Node and verified to reproduce the Ruby's output byte-for-byte before any change was made.It lands in this repo because this repo already carried two hand-maintained copies of that vocabulary, and both had drifted:
doc/ShExJ-context.jsonldwas the@contextofshex.jsonld, copied. All 70 keys matched exactly; it was missing onlyshex:extends. It is now generated (npm run vocab).doc/ShExR.shexran ahead of the published vocabulary, usingsx:ShapeDecl,sx:abstract,sx:imports— none of which had ever been published — andsx:negated.npm run vocab-checkreports terms ShExR uses that the vocabulary does not define, and is part ofnpm test.The vocabulary side of this is w3c/ns#38, which adds those three terms plus the shape-map terms.
sx:negatedremovednegatedwas the ShEx 2.0 draft's!operator on TripleConstraint. It was removed from the language in November 2016 —224c610here,d3f882din spec — over the semantics problem in shexSpec/shex#11, and replaced by{0,0}cardinality andShapeNot. Seven weeks laterfe51e15("~ aligned with ShExJ.jsg") copied it back intodoc/ShExR.shexfrom the grammar, which had not been cleaned up yet.e01f012("TripleConstraint -= negated:BOOL") dropped it fromdoc/ShExJ.jsgin 2020 but left ShExR alone, so the RDF rendering kept a term the JSON rendering had deleted.It was never in the published namespace, is not in the spec, and the ShExC parser has no
!rule — nothing could produce it. Gone fromShExR.{shex,ttl,json,ntriples}, plusdoc/ShExV.jsgand theschemas/meta.ttlsameAbstractSyntaxAsline referencing two fixtures deleted in 2016. shexSpec/spec#(companion PR) and shex.js489a1a75cover the copies elsewhere.bin/mkShExR.js— ShExR's RDF renderings are now deriveddoc/ShExR.shexis the hand-maintained source; the other three files indoc/are the same schema in other syntaxes, hand-synced on the honour system.doc/ShExR.ntripleswas last regenerated in 2017 (7a7da0d) — 800 triples against ShExR.shex's 1341, predatingShapeDecl,abstract,importsandextendsentirely.bin/mkShExR.jsparses ShExR.shex to ShExJ and expands it throughdoc/ShExJ-context.jsonld, since ShExJ + that context is ShExR. So this also exercises the context, which is generated fromvocab/vocab.csv— the vocabulary and the schema-of-schemas are now chained together.ShExR.ttland.ntriplesare regenerated and byte-compared by CI (npm run shexr-check).ShExR.jsonis compared as an AST rather than regenerated, so its hand formatting survives. It was already exactly what ShExR.shex parses to.ShExR.ttl— canonicalising the previously committed file yields the regenerated one exactly. That diff is formatting; the.ntriplesdiff is nine years of catch-up.The Turtle is pretty-printed rather than handed to
N3.Writer, which labels every blank node and spells out all 265rdf:first/rdf:resttriples. The ShExR graph is a tree, so blank nodes nest as[ ]and lists collapse to( ). Subject order comes from the rendered name, never a blank node label, so output does not depend on which parser produced the quads; the printer is idempotent.doc/syntax-deltas.htmlRecords where ShExC, ShExJ and ShExR disagree, found while doing the above, with links into the ShExC productions and both grammars here. The substantive one: ShExR's
sx:start @<#shapeDeclOrExpr>admits aShapeDeclatstart, whichShExJ.jsgrejects and no ShExC production denotes — verified against all three. ShExR has no choice, since RDF cannot distinguish reference from containment, and it cannot even be narrowed to IRIs becauseshapeDeclLabeladmitsBNODE.Checks
npm testpasses.test-tsremains broken independently of this PR — it shells out tobin/makeTsTests.shand calls a baretscwith no typescript devDependency; it is excluded from CI for that reason and unchanged here.🤖 Generated with Claude Code