@@ -311,6 +311,40 @@ Other examples
311311 translation of Biolink schema to OWL
312312
313313
314+ Deterministic output
315+ ^^^^^^^^^^^^^^^^^^^^
316+
317+ Generated Turtle can differ between runs — blank-node identifiers and
318+ statement order depend on Python dict ordering and rdflib serialization
319+ internals — which makes version-controlled artifacts show large spurious
320+ diffs. Use ``--deterministic `` for byte-identical output across invocations:
321+
322+ .. code :: bash
323+
324+ gen-owl --deterministic schema.yaml
325+
326+ The pipeline has three phases:
327+
328+ 1. `RDFC-1.0 <https://www.w3.org/TR/rdf-canon/ >`_ canonicalization (via
329+ `pyoxigraph <https://pypi.org/project/pyoxigraph/ >`_), so isomorphic
330+ inputs produce identical triple sets;
331+ 2. Weisfeiler–Lehman structural hashing replaces the sequential ``_:c14nN ``
332+ labels with content-derived ones, so adding or removing a triple only
333+ renames the directly involved blank nodes (diff-stable output);
334+ 3. re-serialization with rdflib recovers idiomatic Turtle — inline blank
335+ nodes (`Turtle §2.7 <https://www.w3.org/TR/turtle/#BNodes >`_), collection
336+ syntax (`§2.8 <https://www.w3.org/TR/turtle/#collections >`_) — and only
337+ declares prefixes actually used in the graph.
338+
339+ All triples are preserved; only the syntactic form is normalised. Unordered
340+ collections such as ``owl:oneOf `` items are additionally sorted. The option
341+ is available on ``gen-owl ``, ``gen-shacl ``, ``gen-jsonld ``, and
342+ ``gen-jsonld-context `` (for JSON output it deep-sorts objects instead).
343+
344+ ``pyoxigraph >= 0.4.0 `` is required and imported lazily — it is only needed
345+ when the flag is used and is deliberately not a core dependency.
346+
347+
314348Docs
315349----
316350
0 commit comments