W3C W3C Member Submission

The PROV-JSON Serialization

A JSON Representation for the PROV Data Model

W3C Member Submission 24 April 2013

This version:
http://www.w3.org/Submission/2013/SUBM-prov-json-20130424/
Latest published version:
http://www.w3.org/Submission/prov-json/
Latest editor's draft:
http://provenance.ecs.soton.ac.uk/prov-json/
Authors:
Trung Dong Huynh, University of Southampton
Michael O. Jewell, University of Southampton
Amir Sezavar Keshavarz, University of Southampton
Danius T. Michaelides, University of Southampton
Huanjia Yang, University of Southampton
Luc Moreau, University of Southampton

Abstract

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.

Status of This Document

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 can be found in the W3C technical reports index at http://www.w3.org/TR/.

By publishing this document, W3C acknowledges that the Submitting Members have made a formal Submission request to W3C for discussion. Publication of this document by W3C indicates no endorsement of its content by W3C, nor that W3C has, is, or will be allocating any resources to the issues addressed by it. This document is not the product of a chartered W3C group, but is published as potential input to the W3C Process. A W3C Team Comment has been published in conjunction with this Member Submission. Publication of acknowledged Member Submissions at the W3C site is one of the benefits of W3C Membership. Please consult the requirements associated with Member Submissions of section 3.3 of the W3C Patent Policy. Please consult the complete list of acknowledged W3C Member Submissions.

Table of Contents

1. Introduction

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..

1.1 Design considerations

The development of the PROV-JSON representation has the following goals:

1.2 Structure of this Document

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].

1.3 Namespace

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#.

1.4 Conventions

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].

2. Overview

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:

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/"
        ...
    },
    ...
}

2.1 Identifiers

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.

Note
It is possible that there are two (or more) qualified names that resolves to the same IRI. PROV-JSON makes no provision to ensure that records referred by equivalent identifiers will be merged. It is the responsibility of the application consuming PROV-JSON to deal with such cases properly. However, it is recommended that applications producing PROV-JSON make an effort to prevent those cases from occurring.

Blank node identifiers

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.

2.2 JSON Data Typing

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.

Example 1
"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.

Example 2
...
"entity": {
    "e1": {
        "ex:cityName": {
            "$": "Londres",
            "lang": "fr"
        }
        ...
    }
}

Properties with multiple values

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.

Example 3
"entity":{
   "e1":{
      "ex:values":[
         {
            "$":"1034",
            "type":"xsd:positiveInteger"
         },
         2,
         {
            "$":"82.5",
            "type":"xsd:decimal"
         },
         {
            "$":"Y29udGBudCBoZXJl",
            "type":"xsd:base64Binary"
         }
      ]
   }
}

2.3 Validating PROV-JSON Documents

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.

3. Representing PROV in JSON

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)

3.1 Elements

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.

3.1.1 Entity

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,
Example 4
entity(tr:WD-prov-dm-20111215, [ prov:type="document", ex:version="2" ])
is serialized into the following structure
Example 5
...
"entity": {
    "tr:WD-prov-dm-20111215": {
        "prov:type": "document",
        "ex:version": "2"
    }
},
...
Note
Since a Collection is a special case of Entity, it is represented in the same entity structure as above.

3.1.2 Agent

Similarly, an agent expression below.

Example 6
agent(e1, [ex:employee="1234", ex:name="Alice", prov:type='prov:Person' ])
is encoded into:
Example 7
...
"agent": {
    "e1": {
        "ex:employee": "1234",
        "ex:name": "Alice",
        "prov:type": {
            "$": "prov:Person",
            "type": "xsd:QName"
        }
    }
    ...
},
...

3.1.3 Activity

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,

Example 8
activity(a1, 2011-11-16T16:05:00, 2011-11-16T16:06:00,
    [ ex:host="server.example.org", prov:type='ex:edit' ])

is serialized into:

Example 9
...
"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": "xsd:QName"
        }
    }
},
...
Note
Extra attribute-value pairs of an activity expression are put at the same level with other properties in an activity JSON structure.

The values of startTime and endTime MUST conform to xsd:dateTime [XMLSCHEMA11-2].

3.2 Relations

This section specifies how various PROV relations records are serialized in PROV-JSON.

In general, a PROV relation expression follows the following construct:

relationExpression := relationName (relationID; identifier1, identifier2, [additionalProperties])

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: {
        ...
    },
    ...
Any values of additionalProperties are specified alongside the identifier pairs in above structure.

The following sections provide more details on how each type of relation is serialized via typical examples.

3.2.1 Generation

The following Generation expressions

Example 10
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.

Example 11
{
    ...
    "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"
        },
    },
    ...
}

3.2.2 Usage

The following Usage expressions

Example 12
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.

Example 13
{
    ...
    "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"
        },
    },
    ...
}

3.2.3 Communication

The following Communication example

Example 14
activity(a1, [ prov:type="traffic regulations enforcing" ])
activity(a2, [ prov:type="fine paying" ])
wasInformedBy(a2, a1)

is serialized in to PROV-JSON as follows.

Example 15
{
    ...
    "activity": {
        "a1": {
            "prov:type": "traffic regulations enforcing"
        },
        "a2": {
            "prov:type": "fine paying"
        }
    },
    "wasInformedBy": {
        "_:Infm2": {
            "prov:informant": "a1",
            "prov:informed": "a2"
        }
    }
    ...
}

3.2.4 Start

The following Start example

Example 16
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.

Example 17
{
    ...
    "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"
        }
    }
    ...
}

3.2.5 End

The following End example

Example 18
entity(e1, [ prov:type="approval document" ])
activity(a1, [ prov:type="Editing" ])
wasEndedBy(a1, e1, -, -)

is serialized in to PROV-JSON as follows.

Example 19
{
    ...
    "entity": {
        "e1": {
            "prov:type": "approval document"
        }
    },
    "activity": {
        "a1": {
            "prov:type": "Editing"
        }
    },
    "wasEndedBy": {
        "_:wEB1": {
            "prov:activity": "a1",
            "prov:trigger": "e1"
        }
    }
    ...
}

3.2.6 Invalidation

The following Invalidation example

Example 20
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.

Example 21
{
    ...
    "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"
        }
    }
    ...
}

3.2.7 Derivation

The following Derivation example

Example 22
wasDerivedFrom(e2, e1, a, g2, u1)
wasGeneratedBy(g2; e2, a, -)
used(u1; a, e1, -)

is serialized in to PROV-JSON as follows.

Example 23
{
    ...
    "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

Example 24
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.

Example 25
{
    ...
    "entity": {
        "tr:WD-prov-dm-20111215": {
            "prov:type": {
                "$": "rec54:WD",
                "type": "xsd:QName"
            }
        },
        "tr:WD-prov-dm-20111018": {
            "prov:type": {
                "$": "rec54:WD",
                "type": "xsd:QName"
            }
        }
    },
    "wasDerivedFrom": {
        "_:wDF21": {
            "prov:generatedEntity": "tr:WD-prov-dm-20111215",
            "prov:type": {
                "$": "prov:Revision",
                "type": "xsd:QName"
            },
            "prov:usedEntity": "tr:WD-prov-dm-20111018"
        }
    }
    ...
}

3.2.8 Attribution

The following Attribution example

Example 26
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.

Example 27
{
    ...
    "agent": {
        "ex:Simon": {
              "prov:type": {
                "$": "prov:Person",
                "type": "xsd:QName"
            }
        },
        "ex:Paolo": {
              "prov:type": {
                "$": "prov:Person",
                "type": "xsd:QName"
            }
        }
    },
    "entity": {
        "tr:WD-prov-dm-20111215": {
              "prov:type": {
                "$": "rec54:WD",
                "type": "xsd:QName"
            }
        }
    },
    "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"
        }
    }
    ...
}

3.2.9 Association

The following Association example

Example 28
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.

Example 29
{
    ...
    "entity": {
        "ex:wf": {
            "prov:type": {
                "$": "prov:Plan",
                "type": "xsd:QName"
            },
            "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"
        }
    }
    ...
}

3.2.10 Delegation

The following Delegation example

Example 30
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.

Example 31
{
    ...
    "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"
        }
    }
    ...
}

3.2.11 Influence

The following Influence example

Example 32
wasInfluencedBy(tr:WD-prov-dm-20111215, w3:Consortium)

is serialized in to PROV-JSON as follows.

Example 33
{
    ...
    "wasInfluencedBy": {
        "_:wInf1": {
            "prov:influencer": "w3:Consortium",
            "prov:influencee": "tr:WD-prov-dm-20111215"
        }
    },
    ...
}

3.2.12 Specialization

The following Specialization example

Example 34
specializationOf(ex:bbcNews2012-03-23, bbc:news/)

is serialized in to PROV-JSON as follows.

Example 35
{
    ...
    "specializationOf": {
        "_:sO1": {
            "prov:generalEntity": "bbc:news/",
            "prov:specificEntity": "ex:bbcNews2012-03-23"
        }
    },
    ...
}

3.2.13 Alternate

The following Alternate example

Example 36
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.

Example 37
{
    ...
    "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"
        }
    }
    ...
}

3.2.14 Membership

The following Membership example

Example 38
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.

Example 39
{
    ...
    "entity": {
        "e0": {
        },
        "e1": {
        },
        "e2": {
        },
        "c": {
            "prov:type": {
                "$": "prov:Collection",
                "type": "xsd:QName"
            }
        }
    },
    "hadMember": {
        "_:hM1": {
            "prov:collection": "c",
            "prov:entity": "e0"
        },
        "_:hM2": {
            "prov:collection": "c",
            "prov:entity": "e1"
        },
        "_:hM3": {
            "prov:collection": "c",
            "prov:entity": "e2"
        }
    }
    ...
}

3.3 Bundles

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

Example 40
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.

Example 41
{
    "entity": {
        "ex:report2": {
            "prov:type": "report",
            "ex:version": 2
        },
        "ex:report1": {
            "prov:type": "report",
            "ex:version": 1
        },
        "alice:bundle2": {
            "prov:type": {
                "$": "prov:Bundle",
                "type": "xsd:QName"
            }
        },
        "bob:bundle1": {
            "prov:type": {
                "$": "prov:Bundle",
                "type": "xsd:QName"
            }
        }
    },
    "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
                }
            }
        }
    }
}

A. PROV-JSON Serialization Example

In order to illustrate the use of PROV-JSON in a real-world scenario, this section provides the PROV-JSON representation for the document publishing example [PROV-DM]: the authors view, the process view, and attribution of provenance.

A.1 Example: The Authors View

Example 42
{
    "prefix": {
        // Defining namespaces
        "ex": "http://example.org",
        "w3": "http://www.w3.org/",
        "tr": "http://www.w3.org/TR/2011/"
    },
    "entity": {
        // entity(tr:WD-prov-dm-20111215, [ prov:type="document", ex:version="2" ])
        "tr:WD-prov-dm-20111215": {
            "prov:type": "document",
            "ex:version": "2"
        }
    },
    "activity": {
        // activity(ex:edit1, [ prov:type="edit" ])
        "ex:edit1": {
            "prov:type": "edit"
        }
    },
    "wasGeneratedBy": {
        // wasGeneratedBy(tr:WD-prov-dm-20111215, ex:edit1, -)
        "_:wGB1": {
            "prov:activity": "ex:edit1",
            "prov:entity": "tr:WD-prov-dm-20111215"
        }
    },
    "agent": {
        // agent(ex:Paolo, [ prov:type='prov:Person' ])
        "ex:Paolo": {
            "prov:type": {
                "$": "prov:Person",
                "type": "xsd:QName"
            }
        },
        // agent(ex:Simon, [ prov:type='prov:Person' ])
        "ex:Simon": {
            "prov:type": {
                "$": "prov:Person",
                "type": "xsd:QName"
            }
        }
    },
    "wasAssociatedWith": {
        // wasAssociatedWith(ex:edit1, ex:Paolo, -, [ prov:role="editor" ])
        "_:wAW1": {
            "prov:activity": "ex:edit1",
            "prov:agent": "ex:Paolo",
            "prov:role": "editor"
        },
        // wasAssociatedWith(ex:edit1, ex:Simon, -, [ prov:role="contributor" ])
        "_:wAW2": {
            "prov:activity": "ex:edit1",
            "prov:agent": "ex:Simon",
            "prov:role": "contributor"
        }
    }
}

A.2 Example: The Process View

Example 43
{
    "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": "xsd:QName"
            }
        }
    },
    "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"
        }
    }
}

A.3 Example: Attribution of Provenance

Example 44
{
    "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": "xsd:QName"
                    }
                },
                // agent(ex:Simon, [ prov:type='prov:Person' ])
                "ex:Simon": {
                    "prov:type": {
                        "$": "prov:Person",
                        "type": "xsd:QName"
                    }
                }
            },
            // ...
        },
        // bundle ex:author-view
        "ex:author-view": {
            "agent": {
                // agent(ex:Paolo, [ prov:type='prov:Person' ])
                "w3:Consortium": {
                    "prov:type": {
                        "$": "prov:Organization",
                        "type": "xsd:QName"
                    }
                },
                // ...
                }
            },
            // ...
        }
    },
    "entity": {
        // entity(ex:author-view, [ prov:type='prov:Bundle' ])
        "ex:author-view": {
            "prov:type": {
                "$": "prov:Bundle",
                "type": "xsd:QName"
            }
        },
        // entity(ex:process-view, [ prov:type='prov:Bundle' ])
        "ex:process-view": {
            "prov:type": {
                "$": "prov:Bundle",
                "type": "xsd:QName"
            }
        }
    },
    "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"
        }
    }
}

B. PROV-JSON Representation for PROV-Dictionary

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.

B.1 Dictionary Membership

The following Dictionary Membership example

Example 45
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.

Example 46
{
    ...
    "entity": {
        "d": {
            "prov:type": {
                "$": "prov:Dictionary",
                "type": "xsd:QName"
            }
        },
        "e1": {
        },
        "e2": {
        }
    },
    "hadDictionaryMember": {
        "_:hDM1": {
            "prov:dictionary": "d",
            "prov:entity": "e1",
            "prov:key": "k1"
        },
        "_:hDM2": {
            "prov:dictionary": "d",
            "prov:entity": "e2",
            "prov:key": "k2"
        }
    }
    ...
}

B.2 Dictionary Insertion

The following Dictionary Insertion example

Example 47
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.

Example 48
{
    ...
    "entity": {
        "d0": {
            "prov:type": {
                "$": "prov:EmptyDictionary",
                "type": "xsd:QName"
            }
        },
        "e1": {
        },
        "e2": {
        },
        "e3": {
        },
        "d1": {
            "prov:type": {
                "$": "prov:Dictionary",
                "type": "xsd:QName"
            }
        },
        "d2": {
            "prov:type": {
                "$": "prov:Dictionary",
                "type": "xsd:QName"
            }
        }
    },
    "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.

Example 49
{
    ...
    "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": "xsd:QName"
                    },
                    "$": "ex:e2"
                }
            ]
        }
    }
    ...
}
In the special case where the keys of all the key-entity pairs in a Dictionary Insertion relation are of the same data type, the key-entity-set MAY be represented a map structure, taking advantage of the native JSON object representation as follows.
Example 50
{
    ...
    "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.

B.3 Dictionary Removal

The following Dictionary Removal example

Example 51
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.

Example 52
{
    ...
    "entity": {
        ...
        "d3": {
            "prov:type": {
                "$": "prov:Dictionary",
                "type": "xsd:QName"
            }
        },
        "d4": {
            "prov:type": {
                "$": "prov:Dictionary",
                "type": "xsd:QName"
            }
        }
    },
    "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.

C. Acknowledgements

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.

D. References

D.1 Informative references

[JSON-SCHEMA]
Francis Galiegue, Kris Zyp, and Gary Court JSON Schema: core definitions and terminology. 2013, Draft 4. URL: http://tools.ietf.org/html/draft-zyp-json-schema-04
[PROV-DICTIONARY]
Tom De Nies; Sam Coppens; eds. PROV Dictionary: Modeling Provenance for Dictionary Data Structures. 30 April 2013, W3C Note. URL: http://www.w3.org/TR/2013/NOTE-prov-dictionary-20130430/
[PROV-DM]
Luc Moreau; Paolo Missier; eds. PROV-DM: The PROV Data Model. 30 April 2013, W3C Recommendation. URL: http://www.w3.org/TR/2013/REC-prov-dm-20130430/
[PROV-N]
Luc Moreau; Paolo Missier; eds. PROV-N: The Provenance Notation. 30 April 2013, W3C Recommendation. URL: http://www.w3.org/TR/2013/REC-prov-n-20130430/
[PROV-O]
Timothy Lebo; Satya Sahoo; Deborah McGuinness; eds. PROV-O: The PROV Ontology. 30 April 2013, W3C Recommendation. URL: http://www.w3.org/TR/2013/REC-prov-o-20130430/
[PROV-XML]
Hook Hua; Curt Tilmes; Stephan Zednik; eds. PROV-XML: The PROV XML Schema. 30 April 2013, W3C Note. URL: http://www.w3.org/TR/2013/NOTE-prov-xml-20130430/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Internet RFC 2119. URL: http://www.ietf.org/rfc/rfc2119.txt
[XMLSCHEMA11-2]
Henry S. Thompson et al. W3C XML Schema Definition Language (XSD) 1.1 Part 2: Datatypes. 5 April 2012. W3C Recommendation. URL: http://www.w3.org/TR/2012/REC-xmlschema11-2-20120405/