Copyright © 2014 W3C® (MIT, ERCIM, Keio, Beihang), All Rights Reserved. W3C liability, trademark and document use rules apply.
This document specifies a JSON representation for the PROV Data Model, called PROV-JSON. It provides a compact and faithful representation of PROV that supports fast data look-up and is particularly suitable for interchanging PROV documents between web services and clients.
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.
This document was published by the University of Southampton as a Member Submission. If you wish to make comments regarding this document, please send them to Trung Dong Huynh All comments are welcome.
Publication as a Member Submission does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.
This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.
PROV-JSON is a JSON representation for the PROV Data Model (PROV-DM). The PROV-JSON representation was designed for facilitating client-side manipulations of provenance information. It provides a compact and faithful representation of PROV that supports fast data look-up and is particularly suitable for interchanging PROV documents between web services and clients..
The development of the PROV-JSON representation has the following goals:
Section 2 provides an overview of the PROV-JSON representation.
Section 3 specifies the JSON encoding for all PROV expressions.
Appendix A provides a PROV-JSON example representation encoding the PROV-DM Example.
Appendix B defines the PROV-JSON mappings for Dictionary-related constructs [prov-dictionary].
All the elements, relations, reserved names and attributes used in this specification belong to the PROV namespace, which is http://www.w3.org/ns/prov#.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119].
A PROV document (see Document [prov-n]) is used to wrap PROV assertions and facilitate their interchange. It is represented in PROV-JSON as a top-level JSON object; each type of PROV assertions (e.g. entity, activity, generation, usage, etc.) is organised into a separate property with the same name in the top-level object as follows.
{ "entity": { // Map of entities by entities' IDs }, "activity": { // Map of activities by IDs }, "agent": { // Map of agents by IDs }, <relationName>: { // A map of relations of type relationName by their IDs }, ... "bundle": { // Map of named bundles by IDs } }
Each property itself is a JSON object, which is a map-like structure to hold all the PROV-JSON representation of assertions of the same type indexed by their identifiers. Hence, a PROV-JSON document is an indexed representation of a PROV document, in which PROV assertions are indexed by their types and by their identifiers. This allows fast look-up of specific assertions without the need to traverse the whole document.
In addition, the top-level object contains an additional object called prefix that defines all the namespaces referred in the document.
Prefixes can then be used to bind terms to specific namespaces. There is a special prefix called default
, which can be used to declare the default namespace to which all unprefixed terms will be bound.
Default prefixes: By default, the following prefixes are implicitly defined:
prov
: http://www.w3.org/ns/prov# (i.e. PROV namespace)xsd
: http://www.w3.org/2001/XMLSchema# (i.e. XML Schema Namespace [XMLSCHEMA11-2])Therefore, terms that are prefixed with prov:
or xsd:
will be implicitly bound to the relevant namespaces without the need for their explicit declarations.
{ "prefix": { "default": "http://example.org/default", "ex": "http://example.org/" ... }, ... }
An identifier in PROV-JSON, as in [prov-dm], is a qualified name. A qualified name can be mapped into an IRI by concatenating the IRI associated with the prefix and the local part.
Although identifiers of relations are optional in PROV, they are still required at all time in PROV-JSON in order to maintain the validity of a JSON structure (since they are keys in relevant relation map structures). In such cases, blank node identifiers MUST be created for such relations following the nodeID production in Turtle (e.g. _:A1
). It is up to the serialization algorithm to generate blank node identifiers that are internally unique to a PROV-JSON serialization.
Blank node identifiers do not carry any semantics and SHOULD be ignored by applications consuming PROV-JSON documents.
PROV literal values in PROV-JSON are represented in a JSON object with its data type explicitly provided. The value of a literal is stored in the object's special property $
, represented as a string; the data type in the type
property, given as a qualified name.
"prefix": { "ex": "http://example.org/" }, ... "entity": { "e1": { "ex:byteSize": { "$": "1034", "type": "xsd:positiveInteger" }, "ex:compression": { "$": "82.5e-2", "type": "xsd:double" }, "ex:content": { "$": "Y29udGVudCBoZXJl", "type": "xsd:base64Binary" } } }
xsd:decimal, xsd:string, and xsd:boolean values MAY be represented using the JSON native data types number, string, and boolean, respectively. However, if the xsd:string value has a language tag, the literal MUST be represented in a JSON object as specified above, the language tag in the lang
property and the type
property omitted.
... "entity": { "e1": { "ex:cityName": { "$": "Londres", "lang": "fr" } ... } }
Some keys in PROV-JSON may have more than one value. These MUST be represented as PROV-JSON literals as above and collated in to a JSON array, as in the example below.
"entity":{ "e1":{ "ex:values":[ { "$":"1034", "type":"xsd:positiveInteger" }, 2, { "$":"82.5", "type":"xsd:decimal" }, { "$":"Y29udGBudCBoZXJl", "type":"xsd:base64Binary" } ] } }
This section is non-normative.
A schema for PROV-JSON is provided, which defines all the valid PROV-JSON constructs described in this document. The schema was written using the schema language specified in [JSON-SCHEMA] (Version 4). It can be used for the purpose of validating PROV-JSON documents. A number of libraries for JSON schema validation are available at json-schema.org/implementations.html.
This section defines the JSON serialization mappings for PROV constructs (expressed in the PROV notation [prov-n]). The mappings are presented in the forms of examples (from Section 5 of the [prov-dm] document)
This section describes the JSON representations for all PROV elements: entity, activity, and agent. In the JSON container to which these elements belong, they are put into separate structures entity, activity, and agent, respectively.
Each entity is represented as a property in the entity object, identified by the entity's id. The property's value itself is an object structure containing the entity's attribute-values pairs.
The following entity expression◊, for example,entity(tr:WD-prov-dm-20111215, [ prov:type="document", ex:version="2" ])
... "entity": { "tr:WD-prov-dm-20111215": { "prov:type": "document", "ex:version": "2" } }, ...
Similarly, an agent expression◊ below.
agent(e1, [ex:employee="1234", ex:name="Alice", prov:type='prov:Person' ])
... "agent": { "e1": { "ex:employee": "1234", "ex:name": "Alice", "prov:type": { "$": "prov:Person", "type": "prov:QualifiedName" } } ... }, ...
Each activity is represented as a property in the activity object identified by the Activity's id. The property's value itself is an object structure containing the activity's properties and its other attribute-values pairs.
The following activity expression◊, for example,
activity(a1, 2011-11-16T16:05:00, 2011-11-16T16:06:00, [ ex:host="server.example.org", prov:type='ex:edit' ])
is serialized into:
... "activity": { "a1": { "prov:startTime": "2011-11-16T16:05:00", "prov:endTime": "2011-11-16T16:06:00", "ex:host": "server.example.org", "prov:type": { "$": "ex:edit", "type": "prov:QualifiedName" } } }, ...
The values of startTime and endTime MUST conform to xsd:dateTime [XMLSCHEMA11-2].
This section specifies how various PROV relations records are serialized in PROV-JSON.
In general, a PROV relation expression follows the following construct:
where identifier1 and identifier2 are identifiers to PROV elements
Relations are grouped by relationName in a PROV-JSON structure.... "activity": { ... }, relationName: { // relationName(identifier1, identifier2, ...) relationID: { attribute1: identifier1, attribute2: identifier2, ... }, // More relationID, identifier1, identifier2 structures here if there are more instances of relationName(...) }, anotherRelationName: { ... }, ...
The following sections provide more details on how each type of relation is serialized via typical examples.
The following Generation expressions◊
wasGeneratedBy(e1, a1, 2001-10-26T21:32:52, [ ex:port="p1" ]) wasGeneratedBy(ex:gen1; e2, a1, 2001-10-26T10:00:00, [ ex:port="p2" ])
are serialized as follows.
{ ... "wasGeneratedBy": { "_:wBG1": { "prov:entity": "e1", "prov:activity": "a1", "prov:time": "2001-10-26T21:32:52", "ex:port": "p1" }, "ex:gen1": { "prov:entity": "e2", "prov:activity": "a1", "prov:time": "2001-10-26T10:00:00", "ex:port": "p1" }, }, ... }
The following Usage expressions◊
used(a1,e1,2011-11-16T16:00:00,[ex:parameter="p1"]) used(ex:use1; a1,e2,2011-11-16T16:00:01,[ex:parameter="p2"])
are serialized in to PROV-JSON as follows.
{ ... "used": { "_:u1": { "prov:entity": "e1", "prov:activity": "a1", "ex:parameter": "p1", "prov:time": "2011-11-16T16:00:00" }, "ex:use1": { "prov:entity": "e2", "prov:activity": "a1", "ex:parameter": "p2", "prov:time": "2011-11-16T16:00:01" }, }, ... }
The following Communication example◊
activity(a1, [ prov:type="traffic regulations enforcing" ]) activity(a2, [ prov:type="fine paying" ]) wasInformedBy(a2, a1)
is serialized in to PROV-JSON as follows.
{ ... "activity": { "a1": { "prov:type": "traffic regulations enforcing" }, "a2": { "prov:type": "fine paying" } }, "wasInformedBy": { "_:Infm2": { "prov:informant": "a1", "prov:informed": "a2" } } ... }
entity(e1, [ prov:type="email message"] ) activity(a1, [ prov:type="Discuss" ]) wasStartedBy(a1, e1, -, 2011-11-16T16:05:00)
is serialized in to PROV-JSON as follows.
{ ... "entity": { "e1": { "prov:type": "email message" } }, "activity": { "a1": { "prov:type": "Discuss" } }, "wasStartedBy": { "_:wSB2": { "prov:activity": "a1", "prov:time": "2011-11-16T16:05:00", "prov:trigger": "e1" } } ... }
entity(e1, [ prov:type="approval document" ]) activity(a1, [ prov:type="Editing" ]) wasEndedBy(a1, e1, -, -)
is serialized in to PROV-JSON as follows.
{ ... "entity": { "e1": { "prov:type": "approval document" } }, "activity": { "a1": { "prov:type": "Editing" } }, "wasEndedBy": { "_:wEB1": { "prov:activity": "a1", "prov:trigger": "e1" } } ... }
The following Invalidation example◊
entity(ex:The-Painter) agent(ex:Picasso) wasAttributedTo(ex:The-Painter, ex:Picasso) activity(ex:crash) wasInvalidatedBy(ex:The-Painter, ex:crash, 1998-09-03T01:31:00, [ ex:circumstances="plane accident" ])
is serialized in to PROV-JSON as follows.
{ ... "entity": { "ex:The-Painter": { } }, "agent": { "ex:Picasso": { } }, "activity": { "ex:crash": { } }, "wasInvalidatedBy": { "_:wIB1": { "prov:activity": "ex:crash", "prov:time": "1998-09-03T01:31:00", "ex:circumstances": "plane accident", "prov:entity": "ex:The-Painter" } } ... }
The following Derivation example◊
wasDerivedFrom(e2, e1, a, g2, u1) wasGeneratedBy(g2; e2, a, -) used(u1; a, e1, -)
is serialized in to PROV-JSON as follows.
{ ... "wasGeneratedBy": { "g2": { "prov:activity": "a", "prov:entity": "e2" } }, "wasDerivedFrom": { "_:wDF1": { "prov:activity": "a", "prov:generatedEntity": "e2", "prov:usage": "u1", "prov:generation": "g2", "prov:usedEntity": "e1" } }, "used": { "u1": { "prov:activity": "a", "prov:entity": "e1" } } ... }
Since Revision, Quotation, and Primary Source are special cases of Derivation, they are represented in the same wasDerivedFrom JSON structure. For examples, the following Revision example◊
entity(tr:WD-prov-dm-20111215, [ prov:type='rec54:WD' ]) entity(tr:WD-prov-dm-20111018, [ prov:type='rec54:WD' ]) wasDerivedFrom(tr:WD-prov-dm-20111215, tr:WD-prov-dm-20111018, [ prov:type='prov:Revision' ])
is serialized in to PROV-JSON as follows.
{ ... "entity": { "tr:WD-prov-dm-20111215": { "prov:type": { "$": "rec54:WD", "type": "prov:QualifiedName" } }, "tr:WD-prov-dm-20111018": { "prov:type": { "$": "rec54:WD", "type": "prov:QualifiedName" } } }, "wasDerivedFrom": { "_:wDF21": { "prov:generatedEntity": "tr:WD-prov-dm-20111215", "prov:type": { "$": "prov:Revision", "type": "prov:QualifiedName" }, "prov:usedEntity": "tr:WD-prov-dm-20111018" } } ... }
The following Attribution example◊
agent(ex:Paolo, [ prov:type='prov:Person' ]) agent(ex:Simon, [ prov:type='prov:Person' ]) entity(tr:WD-prov-dm-20111215, [ prov:type='rec54:WD' ]) wasAttributedTo(tr:WD-prov-dm-20111215, ex:Paolo, [ prov:type="editorship" ]) wasAttributedTo(tr:WD-prov-dm-20111215, ex:Simon, [ prov:type="authorship" ])
is serialized in to PROV-JSON as follows.
{ ... "agent": { "ex:Simon": { "prov:type": { "$": "prov:Person", "type": "prov:QualifiedName" } }, "ex:Paolo": { "prov:type": { "$": "prov:Person", "type": "prov:QualifiedName" } } }, "entity": { "tr:WD-prov-dm-20111215": { "prov:type": { "$": "rec54:WD", "type": "prov:QualifiedName" } } }, "wasAttributedTo": { "_:wAT1": { "prov:type": "authorship", "prov:agent": "ex:Simon", "prov:entity": "tr:WD-prov-dm-20111215" }, "_:wAT2": { "prov:type": "editorship", "prov:agent": "ex:Paolo", "prov:entity": "tr:WD-prov-dm-20111215" } } ... }
The following Association example◊
activity(ex:a, [ prov:type="workflow execution" ]) wasAssociatedWith(ex:a, -, ex:wf) entity(ex:wf, [ prov:type='prov:Plan', ex:label="Workflow 1", ex:url="http://example.org/workflow1.bpel" %% xsd:anyURI])
is serialized in to PROV-JSON as follows.
{ ... "entity": { "ex:wf": { "prov:type": { "$": "prov:Plan", "type": "prov:QualifiedName" }, "ex:url": { "$": "http://example.org/workflow1.bpel", "type": "xsd:anyURI" }, "ex:label": "Workflow 1" } }, "activity": { "ex:a": { "prov:type": "workflow execution" } }, "wasAssociatedWith": { "_:wAW1": { "prov:activity": "ex:a", "prov:plan": "ex:wf" } } ... }
The following Delegation example◊
activity(a,[ prov:type="workflow" ]) agent(ag1, [ prov:type="programmer" ]) agent(ag2, [ prov:type="researcher" ]) agent(ag3, [ prov:type="funder" ]) wasAssociatedWith(a, ag1, [ prov:role="loggedInUser" ]) wasAssociatedWith(a, ag2) wasAssociatedWith(a, ag3) actedOnBehalfOf(ag1, ag2, a, [ prov:type="line-management" ]) actedOnBehalfOf(ag2, ag3, a, [ prov:type="contract" ])
is serialized in to PROV-JSON as follows.
{ ... "wasAssociatedWith": { "_:wAW14": { "prov:activity": "a", "prov:agent": "ag1" } }, "agent": { "ag1": { "prov:type": "programmer" }, "ag2": { "prov:type": "researcher" }, "ag3": { "prov:type": "funder" } }, "actedOnBehalfOf": { "_:aOBO7": { "prov:activity": "a", "prov:type": "contract", "prov:delegate": "ag2", "prov:responsible": "ag3" }, "_:aOBO6": { "prov:activity": "a", "prov:type": "line-management", "prov:delegate": "ag1", "prov:responsible": "ag2" } }, "activity": { "a": { "prov:type": "workflow" } } ... }
The following Influence example◊
wasInfluencedBy(tr:WD-prov-dm-20111215, w3:Consortium)
is serialized in to PROV-JSON as follows.
{ ... "wasInfluencedBy": { "_:wInf1": { "prov:influencer": "w3:Consortium", "prov:influencee": "tr:WD-prov-dm-20111215" } }, ... }
The following Specialization example◊
specializationOf(ex:bbcNews2012-03-23, bbc:news/)
is serialized in to PROV-JSON as follows.
{ ... "specializationOf": { "_:sO1": { "prov:generalEntity": "bbc:news/", "prov:specificEntity": "ex:bbcNews2012-03-23" } }, ... }
The following Alternate example◊
entity(bbc:news/science-environment-17526723, [ prov:type="a news item for desktop"]) entity(bbc:news/mobile/science-environment-17526723, [ prov:type="a news item for mobile devices"]) alternateOf(bbc:news/science-environment-17526723, bbc:news/mobile/science-environment-17526723)
is serialized in to PROV-JSON as follows.
{ ... "entity": { "bbc:news/science-environment-17526723": { "prov:type": "a news item for desktop" }, "bbc:news/mobile/science-environment-17526723": { "prov:type": "a news item for mobile devices" } }, "alternateOf": { "_:aO1": { "prov:alternate2": "bbc:news/science-environment-17526723", "prov:alternate1": "bbc:news/mobile/science-environment-17526723" } } ... }
The following Membership example◊
entity(e0) entity(e1) entity(e2) entity(c, [prov:type='prov:Collection' ]) // c is a collection, with unknown content hadMember(c, e0) hadMember(c, e1) hadMember(c, e2)
is serialized in to PROV-JSON as follows.
{ ... "entity": { "e0": { }, "e1": { }, "e2": { }, "c": { "prov:type": { "$": "prov:Collection", "type": "prov:QualifiedName" } } }, "hadMember": { "_:hM1": { "prov:collection": "c", "prov:entity": "e0" }, "_:hM2": { "prov:collection": "c", "prov:entity": "e1" }, "_:hM3": { "prov:collection": "c", "prov:entity": "e2" } } ... }
This section introduces the PROV-JSON representation for PROV bundles. A Bundle is a named set of provenance descriptions, which can contain any of the PROV expressions in previous sections. Therefore, a PROV bundle's content is represented as a normal PROV-JSON document with the exception that it MUST NOT contain another PROV bundle. The PROV-JSON bundle's content is then put into the bundle structure of the containing PROV-JSON document and indexed by its identifier.
For example, the following bundle example◊
entity(ex:report1, [ prov:type="report", ex:version=1 ]) wasGeneratedBy(ex:report1, -, 2012-05-24T10:00:01) entity(ex:report2, [ prov:type="report", ex:version=2]) wasGeneratedBy(ex:report2, -, 2012-05-25T11:00:01) wasDerivedFrom(ex:report2, ex:report1) bundle bob:bundle1 entity(ex:report1, [ prov:type="report", ex:version=1 ]) wasGeneratedBy(ex:report1, -, 2012-05-24T10:00:01) endBundle bundle alice:bundle2 entity(ex:report1) entity(ex:report2, [ prov:type="report", ex:version=2 ]) wasGeneratedBy(ex:report2, -, 2012-05-25T11:00:01) wasDerivedFrom(ex:report2, ex:report1) endBundle entity(bob:bundle1, [ prov:type='prov:Bundle' ]) wasGeneratedBy(bob:bundle1, -, 2012-05-24T10:30:00) wasAttributedTo(bob:bundle1, ex:Bob) entity(alice:bundle2, [ prov:type='prov:Bundle' ]) wasGeneratedBy(alice:bundle2, -, 2012-05-25T11:15:00) wasAttributedTo(alice:bundle2, ex:Alice)
is represented in PROV-JSON as follows.
{ "entity": { "ex:report2": { "prov:type": "report", "ex:version": 2 }, "ex:report1": { "prov:type": "report", "ex:version": 1 }, "alice:bundle2": { "prov:type": { "$": "prov:Bundle", "type": "prov:QualifiedName" } }, "bob:bundle1": { "prov:type": { "$": "prov:Bundle", "type": "prov:QualifiedName" } } }, "wasDerivedFrom": { "_:wDF1": { "prov:generatedEntity": "ex:report2", "prov:usedEntity": "ex:report1" } }, "wasGeneratedBy": { "_:wGB1": { "prov:time": "2012-05-24T10:00:01", "prov:entity": "ex:report1" }, "_:wGB2": { "prov:time": "2012-05-25T11:00:01", "prov:entity": "ex:report2" }, "_:wGB3": { "prov:time": "2012-05-24T10:30:00", "prov:entity": "bob:bundle1" }, "_:wGB4": { "prov:time": "2012-05-25T11:15:00", "prov:entity": "alice:bundle2" } }, "wasAttributedTo": { "_:wAT1": { "prov:agent": "ex:Alice", "prov:entity": "alice:bundle2" }, "_:wAT2": { "prov:agent": "ex:Bob", "prov:entity": "bob:bundle1" } }, "bundle": { "alice:bundle2": { "wasGeneratedBy": { "_:wGB29": { "prov:time": "2012-05-25T11:00:01", "prov:entity": "ex:report2" } }, "entity": { "ex:report2": { "prov:type": "report", "ex:version": 2 }, "ex:report1": { } }, "wasDerivedFrom": { "_:wDF25": { "prov:generatedEntity": "ex:report2", "prov:usedEntity": "ex:report1" } } }, "bob:bundle1": { "wasGeneratedBy": { "_:wGB28": { "prov:time": "2012-05-24T10:00:01", "prov:entity": "ex:report1" } }, "entity": { "ex:report1": { "prov:type": "report", "ex:version": 1 } } } } }
{ "prefix": { // Defining namespaces "ex": "http://example.org", "process": "http://www.w3.org/2005/10/Process-20051014/tr.html#", "rec54": "http://www.w3.org/2001/02pd/rec54#", "tr": "http://www.w3.org/TR/2011/", "w3": "http://www.w3.org/", "email": "https://lists.w3.org/Archives/Member/w3c-archive/" }, "entity": { // entity(tr:WD-prov-dm-20111215, [ prov:type='rec54:WD' ]) "tr:WD-prov-dm-20111215": { "prov:type": { "$": "rec54:WD", "type": "prov:QualifiedName" } } }, "activity": { // activity(ex:act2, [ prov:type="publish" ]) "ex:act2": { "prov:type": "publish" } }, "wasGeneratedBy": { // wasGeneratedBy(tr:WD-prov-dm-20111215, ex:act2, -) "_:wGB4": { "prov:activity": "ex:act2", "prov:entity": "tr:WD-prov-dm-20111215" } }, "wasDerivedFrom": { // wasDerivedFrom(tr:WD-prov-dm-20111215, tr:WD-prov-dm-20111018) "_:wDF2":{ "prov:generatedEntity": "tr:WD-prov-dm-20111215", "prov:usedEntity": "tr:WD-prov-dm-20111018" } }, "used": { // used(ex:act2, email:2011Dec/0111, -) "_:u2": { "prov:activity": "ex:act2", "prov:entity": "email:2011Dec/0111" } }, "wasAssociatedWith": { // wasAssociatedWith(ex:act2, w3:Consortium, process:rec-advance) "_:wAW6": { "prov:activity": "ex:act2", "prov:agent": "w3:Consortium", "prov:plan": "process:rec-advance" } } }
{ "prefix": { // Defining namespaces "ex": "http://example.org", "w3": "http://www.w3.org/", }, "bundle": { // bundle ex:author-view "ex:author-view": { "agent": { // agent(ex:Paolo, [ prov:type='prov:Person' ]) "ex:Paolo": { "prov:type": { "$": "prov:Person", "type": "prov:QualifiedName" } }, // agent(ex:Simon, [ prov:type='prov:Person' ]) "ex:Simon": { "prov:type": { "$": "prov:Person", "type": "prov:QualifiedName" } } }, // ... }, // bundle ex:author-view "ex:author-view": { "agent": { // agent(ex:Paolo, [ prov:type='prov:Person' ]) "w3:Consortium": { "prov:type": { "$": "prov:Organization", "type": "prov:QualifiedName" } }, // ... } }, // ... } }, "entity": { // entity(ex:author-view, [ prov:type='prov:Bundle' ]) "ex:author-view": { "prov:type": { "$": "prov:Bundle", "type": "prov:QualifiedName" } }, // entity(ex:process-view, [ prov:type='prov:Bundle' ]) "ex:process-view": { "prov:type": { "$": "prov:Bundle", "type": "prov:QualifiedName" } } }, "wasAttributedTo": { // wasAttributedTo(ex:author-view, ex:Simon) "_:wAT7": { "prov:agent": "ex:Simon", "prov:entity": "ex:author-view" }, // wasAttributedTo(ex:process-view, w3:Consortium) "_:wAT8": { "prov:agent": "w3:Consortium", "prov:entity": "ex:process-view" } } }
Dictionary [prov-dictionary] extends the PROV Collection construct to consist key-entity pairs. This section defines the PROV-JSON mappings for Dictionary-related constructs. As in previous sections, the mappings are presented by means of examples.
The following Dictionary Membership example◊
entity(d, [prov:type='prov:Dictionary' ]) // d is a dictionary, with (so far) unknown content entity(e1) entity(e2) prov:hadDictionaryMember(d, e1, "k1") prov:hadDictionaryMember(d, e2, "k2")
is serialized in to PROV-JSON as follows.
{ ... "entity": { "d": { "prov:type": { "$": "prov:Dictionary", "type": "prov:QualifiedName" } }, "e1": { }, "e2": { } }, "hadDictionaryMember": { "_:hDM1": { "prov:dictionary": "d", "prov:entity": "e1", "prov:key": "k1" }, "_:hDM2": { "prov:dictionary": "d", "prov:entity": "e2", "prov:key": "k2" } } ... }
The following Dictionary Insertion example◊
entity(d0, [prov:type='prov:EmptyDictionary' ]) // d0 is an empty dictionary entity(e1) entity(e2) entity(e3) entity(d1, [prov:type='prov:Dictionary' ]) entity(d2, [prov:type='prov:Dictionary' ]) prov:derivedByInsertionFrom(d1, d0, {("k1", e1), ("k2", e2)}) prov:derivedByInsertionFrom(d2, d1, {("k3", e3)}, [ dcterms:description ="A second insertion" ]) // an insertion with optional attribute dcterms:description
is serialized in to PROV-JSON as follows.
{ ... "entity": { "d0": { "prov:type": { "$": "prov:EmptyDictionary", "type": "prov:QualifiedName" } }, "e1": { }, "e2": { }, "e3": { }, "d1": { "prov:type": { "$": "prov:Dictionary", "type": "prov:QualifiedName" } }, "d2": { "prov:type": { "$": "prov:Dictionary", "type": "prov:QualifiedName" } } }, "derivedByInsertionFrom": { "_:dBIF1": { "prov:after": "d1", "prov:before": "d0", "prov:key-entity-set": [ { "key": "k1", "$": "e1" }, { "key": "k2", "$": "e2" } ] }, "_:dBIF2": { "prov:after": "d2", "prov:before": "d1", "prov:key-entity-set": [ { "key": "k3", "$": "e3" } ], "dcterms:description": "A second insertion" } } ... }
In the PROV-JSON serialization of a Dictionary Insertion relation, the set of all inserted key-entity pairs is represented as a list of JSON objects, each of which the representation of a key-entity pair. For each pair, the entity is given as a qualified name while the key a PROV literal, which can be of any data type. The encoding of the key in a key-entity pair follows the same data typing rules specified in Section 2.2. The following example demonstrates keys of different data types.
{ ... "derivedByInsertionFrom": { "ex:deriv1": { "prov:before": "ex:d1", "prov:after": "ex:d2", "prov:key-entity-set": [ { "key": "a", "$": "ex:e0" }, { "key": 1, "$": "ex:e1" }, { "key": { "$": "ex:a", "type": "prov:QualifiedName" }, "$": "ex:e2" } ] } } ... }
key-entity-set
MAY be represented a map structure, taking advantage of the native JSON object representation as follows.
{ ... "derivedByInsertionFrom": { "ex:deriv2": { "prov:before": "ex:d1", "prov:after": "ex:d2", "prov:key-datatype": "xsd:string", "prov:key-entity-set": { "a": "ex:e0", "b": "ex:e1", "c": "ex:e2" } } } ... }
In that case, the prov:key-datatype
property MUST be provided and MUST specify the data type of (all) the keys (i.e. xsd:string), which dictates how the keys should be interpreted.
The following Dictionary Removal example◊
entity(d0, [prov:type="prov:EmptyDictionary"]) // d0 is an empty dictionary entity(e1) entity(e2) entity(e3) entity(d1, [prov:type="prov:Dictionary"]) entity(d2, [prov:type="prov:Dictionary"]) entity(d3, [prov:type="prov:Dictionary"]) entity(d4, [prov:type="prov:Dictionary"]) prov:derivedByInsertionFrom(d1, d0, {("k1", e1), ("k2",e2)}) prov:derivedByInsertionFrom(d2, d1, {("k3", e3)}) prov:derivedByRemovalFrom(d3, d2, {"k1", "k3"}) prov:derivedByRemovalFrom(d4, d3, {"k1"})
is serialized in to PROV-JSON as follows.
{ ... "entity": { ... "d3": { "prov:type": { "$": "prov:Dictionary", "type": "prov:QualifiedName" } }, "d4": { "prov:type": { "$": "prov:Dictionary", "type": "prov:QualifiedName" } } }, "derivedByInsertionFrom": { ... }, "derivedByRemovalFrom": { "_:dBRF1": { "prov:after": "d3", "prov:before": "d2", "prov:key-set": [ "k1", "k3" ] }, "_:dBRF2": { "prov:after": "d4", "prov:before": "d3", "prov:key-set": [ "k1" ] } } ... }
In a Dictionary Removal relation, the key-set is represented as a list of keys. As in the previous section, keys are PROV literals and should be represented accordingly as specified in Section 2.2.
This specification was developed based on the PROV-DM Specification [prov-dm] and reused significant content therefrom to provide consistent mappings between the two documents.
This work was partly supported by funding from the UK Engineering and Physical Sciences Research Council for project Orchid, grant EP/I011587/1.