Representing Time in RDF Part 4

<h2>Approach 3: Reified Relations</h2>

In this approach I reify every triple that is time-dependent. That means every triple is split out into its constituent parts which will obviously lead to an explosion of triples.

Scenario 1

In this scenario I use thing:maria to refer to Maria, and I state the fact of her being a foaf:Person as a piece of timeless information. Facts about her name are reified and time interval information is attached. The URIs thing:mariaUnmarried and thing:mariaMarried represent the reified triples holding her name before and after marriage:

@prefix bio: <http://purl.org/vocab/bio/0.1/> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix time: <http://www.w3.org/2006/time#> .
@prefix ex: <http://example.org/ex#> .
@prefix thing: <http://example.org/thing#> .

thing:maria a foaf:Person .

thing:mariaUnmarried
  ex:subject thing:maria ;
  ex:property foaf:name ;
  ex:value "Maria Smith" ;
  time:start "1867" ;
  time:end "1888" .

thing:mariaMarried 
  ex:subject thing:maria ;
  ex:property foaf:name ;
  ex:value "Maria Johnson" ;
  time:start "1888" ;
  time:end "9999" .

Original file: a3s1.ttl

Facts about her name are reified using custom reification predicates, not the standard RDF ones. I do this to allow more flexibility in the use of these predicates without requiring that their subject is always an RDF statement. Potentially I could have multiple occurrences of ex:subject, ex:property or ex:value which would allow more compact descriptions to be created. For example I could have a description where multiple objects are included for the same predicate and subject.

The query in this case is straighforward and quite similar to the query for Approach 1.

prefix bio: <http://purl.org/vocab/bio/0.1/> 
prefix foaf: <http://xmlns.com/foaf/0.1/> 
prefix time: <http://www.w3.org/2006/time#> 
prefix xsd:  <http://www.w3.org/2001/XMLSchema#>
prefix ex: <http://example.org/ex#> 
prefix thing: <http://example.org/thing#> 

select ?name where {
  ?p ex:subject thing:maria .
  ?p ex:property foaf:name .
  ?p time:start ?start .
  ?p time:end ?end .
  ?p ex:value ?name .
  filter (xsd:integer(?start) <= 1891 && xsd:integer(?end) >= 1891) .
}

Original file: a3s1.sq

I simply search for resources that represent reified triples that hold in 1891. Then I select the ex:value of the resulting resource.

Scenario 2

For simplicity I start of by treating the place name information as timeless, only reifying the information about relationships between the places:

@prefix bio: <http://purl.org/vocab/bio/0.1/> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix time: <http://www.w3.org/2006/time#> .
@prefix ex: <http://example.org/ex#> .
@prefix thing: <http://example.org/thing#> .

thing:oxfordshire 
  a ex:County ;
  foaf:name "Oxfordshire" .

thing:gloucestershire 
  a ex:County ;
  foaf:name "Gloucestershire" .

thing:widford 
  a ex:Parish ;
  foaf:name "Widford" .
  
thing:widfordInGloucestershire 
  ex:subject thing:widford ;
  ex:property ex:partOf ;
  ex:value thing:gloucestershire ;
  time:start "1837" ;
  time:end "1844" .

thing:widfordInOxfordshire 
  ex:subject thing:widford ;
  ex:property ex:partOf ;
  ex:value thing:oxfordshire ;
  time:start "1844" ;
  time:end "9999" .

Original file: a3s2.ttl

The query is again very simple and reminiscent of Approach 1:

prefix bio: <http://purl.org/vocab/bio/0.1/> 
prefix foaf: <http://xmlns.com/foaf/0.1/> 
prefix time: <http://www.w3.org/2006/time#> 
prefix xsd:  <http://www.w3.org/2001/XMLSchema#>
prefix ex: <http://example.org/ex#> 
prefix thing: <http://example.org/thing#> 

select ?name where {
  ?p ex:subject thing:widford .
  ?p ex:property ex:partOf .
  ?p time:start ?start .
  ?p time:end ?end .
  ?p ex:value ?x .
  ?x foaf:name ?name
  filter (xsd:integer(?start) <= 1841 && xsd:integer(?end) >= 1841) .
}

Original file: a3s2.sq

However, a more realistic approach would be to model the names of the places as time-dependent triples which means reifying them. I introduce some new resources thing:widfordName, thing:oxfordshireName and thing:gloucestershireName to represent the reified forms of those triples. Now the data is much more verbose:

@prefix bio: <http://purl.org/vocab/bio/0.1/> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix time: <http://www.w3.org/2006/time#> .
@prefix ex: <http://example.org/ex#> .
@prefix thing: <http://example.org/thing#> .

thing:oxfordshire a ex:County .

thing:gloucestershire a ex:County .

thing:widford a ex:Parish .
  
thing:widfordInGloucestershire 
  ex:subject thing:widford ;
  ex:property ex:partOf ;
  ex:value thing:gloucestershire ;
  time:start "1837" ;
  time:end "1844" .

thing:widfordInOxfordshire 
  ex:subject thing:widford ;
  ex:property ex:partOf ;
  ex:value thing:oxfordshire ;
  time:start "1844" ;
  time:end "9999" .

thing:widfordName 
  ex:subject thing:widford ;
  ex:property foaf:name ;
  ex:value "Widford" ;
  time:start "1837" ;
  time:end "9999" .
  
thing:oxfordshireName 
  ex:subject thing:oxfordshire ;
  ex:property foaf:name ;
  ex:value "Oxfordshire" ;
  time:start "1837" ;
  time:end "9999" . 
  
thing:gloucestershireName 
  ex:subject thing:gloucestershire ;
  ex:property foaf:name ;
  ex:value "Gloucestershire" ;
  time:start "1837" ;
  time:end "9999" .

Original file: a3s2a.ttl

Also the query becomes more complex:

prefix bio: <http://purl.org/vocab/bio/0.1/> 
prefix foaf: <http://xmlns.com/foaf/0.1/> 
prefix time: <http://www.w3.org/2006/time#> 
prefix xsd:  <http://www.w3.org/2001/XMLSchema#>
prefix ex: <http://example.org/ex#> 
prefix thing: <http://example.org/thing#> 

select ?name where {
  ?p ex:subject thing:widford .
  ?p ex:property ex:partOf .
  ?p time:start ?start .
  ?p time:end ?end .
  ?p ex:value ?x .
  filter (xsd:integer(?start) <= 1841 && xsd:integer(?end) >= 1841) .

  ?p2 ex:subject ?x .
  ?p2 ex:property foaf:name .
  ?p2 time:start ?start2 .
  ?p2 time:end ?end2 .
  ?p2 ex:value ?name .
  filter (xsd:integer(?start2) <= 1841 && xsd:integer(?end2) >= 1841) .
}

Original file: a3s2a.sq

Each triple being selected requires its time interval information to be specified sepearately which is reminiscent of Approach 2

Scenario 3

Once again for simplicity I keep the place name information timeless. I introduce new resources for the reified statements about the residence of the person over time:

@prefix bio: <http://purl.org/vocab/bio/0.1/> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix time: <http://www.w3.org/2006/time#> .
@prefix ex: <http://example.org/ex#> .
@prefix thing: <http://example.org/thing#> .

thing:lymeRegis 
  a ex:Town ;
  foaf:name "Lyme Regis" .

thing:charmouth 
  a ex:Town ;
  foaf:name "Charmouth" .

thing:hastings
  a ex:Town ;
  foaf:name "Hastings" .
  

thing:anon a foaf:Person .

thing:anonInLymeRegis 
  ex:subject thing:anon ;
  ex:property ex:residence ;
  ex:value thing:lymeRegis ;
  time:intervalBefore thing:anonInCharmouth ;
  time:intervalContains "1844" .

thing:anonInCharmouth 
  ex:subject thing:anon ;
  ex:property ex:residence ;
  ex:value thing:charmouth ;
  time:intervalAfter thing:anonInLymeRegis ;
  time:intervalBefore thing:anonInHastings ;
  time:intervalContains "1871" .

thing:anonInHastings 
  ex:subject thing:anon ;
  ex:property ex:residence ;
  ex:value thing:hastings ;
  time:intervalAfter thing:anonInCharmouth ;
  time:intervalContains "1881" .

Original file: a3s3.ttl

The query is straightforward although quite verbose. If the place name triples were also reified then this query would suddenly become much more complex:

prefix bio: <http://purl.org/vocab/bio/0.1/> 
prefix foaf: <http://xmlns.com/foaf/0.1/> 
prefix time: <http://www.w3.org/2006/time#> 
prefix xsd:  <http://www.w3.org/2001/XMLSchema#>
prefix ex: <http://example.org/ex#> 
prefix thing: <http://example.org/thing#> 

select ?nameBefore ?nameAfter where {
  ?pBefore ex:subject thing:anon .
  ?pBefore ex:property ex:residence .
  ?pBefore ex:value ?placeBefore .
  ?placeBefore foaf:name ?nameBefore .

  ?pBefore time:intervalContains ?dateBefore .
  filter (xsd:integer(?dateBefore) <= 1874) .

  ?pAfter ex:subject thing:anon .
  ?pAfter ex:property ex:residence .
  ?pAfter ex:value ?placeAfter .
  ?placeAfter foaf:name ?nameAfter .

  ?pAfter time:intervalContains ?dateAfter .
  filter (xsd:integer(?dateAfter) > 1874) .

  ?pBefore time:intervalBefore ?pAfter .
}

Original file: a3s3.sq

Approach 3 Conclusions

Approach 3 avoids the domain and range problem experienced by Approach 1 where the conditions were being used with properties whose domains were foaf:Agents. In Approach 3, properties are used with the appropriate resource types when they are timeless and never actually asserted when they are time-dependent. However, this approach is tedious for large quantities of data. The semantics are all locked away behind the reified triples. Once again I don't know of any reasoners that could work with this kind of data.

This post is part 4 of a series about representing time in RDF. All posts in this series: part 1, part 2, part 3, part 4, part 5 and part 6

Permalink: http://blog.iandavis.com/2009/08/representing-time-in-rdf-part-4/


Other posts tagged as data, genealogy, history, modelling, projects, rdf, technology, time, time-in-rdf

Earlier Posts