Description
RDF Dataset Canonicalization, RDFC-1.0.
Two datasets that differ only in their blank node labels denote the same thing, and nothing built so far can tell you that: the dataset compares labelled statements, and the round-trip tests deliberately claim less than isomorphism because they had no way to decide it. Canonicalization is what decides it. It assigns every blank node a label derived from its position in the graph rather than from what it was called, so two isomorphic datasets canonicalize to identical bytes.
The algorithm has a documented adversarial case. Distinguishing blank nodes that look alike from every direction requires trying permutations, and a dataset can be built specifically to make that combinatorial. This implementation therefore takes a work bound and reports reaching it as a result rather than running until something else gives out.
Canonicalize
procedure Canonicalize
(Value : Datasets.Dataset;
Output : out Ada.Strings.Unbounded.Unbounded_String;
Labels : out Label_Maps.Map;
Status : out Result_Status;
Maximum_Work : Positive := Default_Maximum_Work;
Algorithm : Hash_Algorithm := SHA_256)
Canonicalize, and report which identifier each blank node was issued.
Parameters
- Value
Dataset to canonicalize
- Output
Canonical N-Quads, meaningful only when Canonicalized
- Labels
Input label to issued identifier, empty when not Canonicalized
- Status
Whether canonicalization completed
- Maximum_Work
Bound on permutation and recursion work
- Algorithm
Which digest to use
Canonicalize
procedure Canonicalize
(Value : Datasets.Dataset;
Output : out Ada.Strings.Unbounded.Unbounded_String;
Status : out Result_Status;
Maximum_Work : Positive := Default_Maximum_Work;
Algorithm : Hash_Algorithm := SHA_256)
Canonicalize, reporting rather than raising.
Parameters
- Value
Dataset to canonicalize
- Output
Canonical N-Quads, meaningful only when Canonicalized
- Status
Whether canonicalization completed
- Maximum_Work
Bound on permutation and recursion work
- Algorithm
Which digest to canonicalize with
Default_Maximum_Work
Default_Maximum_Work : constant := 1_000_000;
Default bound on permutation and recursion work.
Ordinary data does not approach this: the bound exists for datasets designed to be expensive, not for large ones.
Hash_Algorithm
subtype Hash_Algorithm is Digests.Hash_Algorithm;
Which digest to canonicalize with. RDFC-1.0 names SHA-256 and admits SHA-384, and the labels a processor issues differ between them, so this is part of the request rather than a tuning knob.
Is_Isomorphic
function Is_Isomorphic
(Left, Right : Datasets.Dataset;
Maximum_Work : Positive := Default_Maximum_Work;
Algorithm : Hash_Algorithm := SHA_256) return Boolean
Report whether two datasets denote the same thing.
This is isomorphism: equal apart from a consistent renaming of blank nodes. It is what a round-trip test wants when the serialization it passed through was entitled to rename them.
Parameters
- Left
First dataset
- Right
Second dataset
- Maximum_Work
Bound applied to each canonicalization
- Algorithm
Which digest to canonicalize with
Return value
True when the two canonicalize identically
Raised exceptions
- Work_Limit_Error
The bound was reached
Label_Maps
package Label_Maps is new Ada.Containers.Indefinite_Ordered_Maps
(Key_Type => String, Element_Type => String);
The canonical identifier issued to each blank node, keyed by the label the input used. RDFC-1.0 specifies this map, and it is the only way to say which node in the output was which node in the input.
Result_Status
type Result_Status is (Canonicalized, Work_Limit_Reached);
Outcome of a canonicalization attempt.
Enumeration literals
- Canonicalized
The dataset was canonicalized
- Work_Limit_Reached
The bound was hit before finishing, so the output is not usable
SHA_256
SHA_256 : constant Hash_Algorithm := Digests.SHA_256;
The digest RDFC-1.0 names.
SHA_384
SHA_384 : constant Hash_Algorithm := Digests.SHA_384;
The one alternative it admits.
To_Canonical_NQuads
function To_Canonical_NQuads
(Value : Datasets.Dataset;
Maximum_Work : Positive := Default_Maximum_Work;
Algorithm : Hash_Algorithm := SHA_256) return String
Canonicalize into canonical N-Quads.
Blank nodes are labelled c14n0, c14n1, and so on, in an order derived from the graph rather than from the input.
Parameters
- Value
Dataset to canonicalize
- Maximum_Work
Bound on permutation and recursion work
- Algorithm
Which digest to canonicalize with
Return value
The canonical N-Quads serialization
Raised exceptions
- Work_Limit_Error
The bound was reached
Work_Limit_Error
Work_Limit_Error : exception;
Raised by the function form when the work bound is reached.