Skip to content

v0.2.0

Choose a tag to compare

@jdsika jdsika released this 08 Sep 15:59
· 56 commits to main since this release
1f1c559

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.