v0.2.0
Fixed: unbounded memory growth in WL refinement
wl_blank_node_labels built each refinement round's signature by concatenating a node's own signature with those of all its neighbours, and never hashed in between. Signature length therefore grew by roughly a factor of the average degree every round. On a 100-blank-node, OWL-restriction-shaped graph:
| round | total signature bytes |
|---|---|
| 0 | 14,690 |
| 4 | 1,040,270 |
| 8 | 58,179,070 |
| 10 | 434,280,830 |
| 11 | MemoryError |
Any caller raising iterations past ~8 exhausted memory on an otherwise small graph. The final label is hashed either way, so label width could not reveal this — the symptom was memory alone.
Each round is now hashed, which bounds every signature to a constant size while inducing exactly the same partition of the blank nodes.
Changed: iterations now refines to the fixpoint
With growth bounded, the round count no longer has to be rationed — and it should not be guessed either. Stopping early leaves structurally distinct blank nodes sharing a signature, and those ties are broken by a counter assigned in RDFC-1.0 c14nN order, reintroducing precisely the global instability the labels exist to remove.
iterations now defaults to None, meaning refine until the partition stops changing. Refinement is monotone, so a stable class count proves a stable partition, and a partition of n nodes can refine at most n times.
Impact
Adding one class to a 78-class LinkML schema, counting changed lines:
| generator | file size | RDFC-1.0 only | + WL (0.1.0) | + WL (0.2.0) |
|---|---|---|---|---|
| SHACL | 497 lines | 291 changed | 13 | 13 (22x) |
| OWL | 2245 lines | 2091 changed | 253 | 17 (123x) |
Compatibility
Blank-node labels differ from 0.1.0, both from the per-round hash and the deeper refinement, so consumers see a one-time re-labelling. Output remains deterministic and isomorphic; only the choice of label changes.
Notes
Labels derive from a node's whole connected blank-node structure, so an edit inside one large connected structure can relabel all of it. Diff stability isolates unrelated regions of a graph from each other, not parts of a single interconnected one.
Full details in #7.