Temporal Relations

Danny Ayers has captured an interesting set of conversations relating to temporal relations and rdf. The subject is a tricky one, but one should not be frightened into thinking that this reveals a fundamental flaw in the Semantic Web. That would be close to saying that it reveals a problem with first order logic. No, as we know in the Java world, modelling is difficult. People who have good thoughts on those issues, such as Martin Folwer are very valuable. And in the Semantic Web area what we need are patterns for dealing with time better.

One thing to note is the difference between properties about graphs (that web page said so and so at that time) and saying something temporal about things.
A good rdf aggregator will need to keep track of where he gets information from. Sesame 2.0, cwm and more others are beginning to allow one to do this. This is the foundation stone for a Semantic web framework of trust.
Now a graph that one gets from a web page can contain information that is timeless, information about the future or the past. So knowing the date of validity of the graph does not give us a way of thinking temporally about the statements within it. This will require temporal ontologies of events, process and object time slices, as well as the ability to reason over those. And putting this together is not as easy as one may wish.[1]

Another good way to look at this, is to point out that this is a problem that also exists with our well loved relational databases. David Powell points to the Temporal database article in wikipedia. Indeed thinking about the example presented there can help me make my points a lot clearer. The wikipedia article distinguishes between valid time and transaction time.

Living in the Present

It is very easy to create relations that fail to take valid time into account. To use the example in the wikipedia article we could do this by extending foaf with the foaf:lives relation. We could then write that John Doe lives in Smallville by placing the following N3 on a server at the url http://people.gov.org/ssn/123456789 on 3rd April 1975

@prefix : ≤http://xmlns.com/foaf/0.1/≥ .

≤#JohnDoe≥ a :Person;
	:name "John Doe";
	:lives "SmallVille".

The above file is served until December 27, 1994, even though John Doe left smallville on 26 August 1993. That day John Doe remembers to update the file, which then says

@prefix : ≤http://xmlns.com/foaf/0.1/≥ .

≤#JohnDoe≥ a :Person;
	:name "John Doe";
	:lives "BigTown".

Clearly these two graphs should not be merged, as otherwise we would end up with a graph that would claim that John Doe lives both in BigTown and in SmallVille, which may have some serious tax implications. And so unsurprisingly when on the 1 April 2001 John Doe dies, his file is updated to

@prefix : ≤http://xmlns.com/foaf/0.1/≥ .

≤#JohnDoe≥ a :Person;
	:name "John Doe";
	:lives "hell".

Valid Time

In order to speak about the change of where John Doe lived over time one could create a foaf 2 ontology that had the concept of time slices of physical objects that have beginning and ends, using perhaps the time ontology in OWL. The intial file would then be

@prefix : ≤http://xmlns.com/foaf/0.1/≥ .
@prefix tr: ≤http://www.isi.edu/~pan/damltime/time-entry.owl#≥ .
≤#JohnDoe≥ a :Person;
	:name "John Doe";
	:born "3 April 1975"\^\^xsd:dateTime;
	:timeslice [ a :PersonSlice;
		tr:begins "3 April 1975"\^\^xsd:dateTime;
 		:lives "SmallVille" ] .

When in 1994 Jon updates his file, he can now make clear that he moved in 1993 with the following file

@prefix : ≤http://xmlns.com/foaf/0.1/≥ .
@prefix tr: ≤http://www.isi.edu/~pan/damltime/time-entry.owl#≥ .
≤#JohnDoe≥ a :Person;
	:name "John Doe";
	:born "3 April 1975"\^\^xsd:dateTime;
	:timeslice [ a :PersonSlice;
 		tr:begins "3 April 1975"\^\^xsd:dateTime;
 		tr:ends "26 August 1993"\^\^xsd:dateTime;
		:lives "SmallVille" ] ;
	:timeslice [ a :PersonSlice;
 		tr:begins "26 August 1993"\^\^xsd:dateTime;		
		:lives "BigTown" ] .

And when in 2001 John dies the file can be updated to

@prefix : ≤http://xmlns.com/foaf/0.1/≥ .
@prefix tr: ≤http://www.isi.edu/~pan/damltime/time-entry.owl#≥ .
≤#JohnDoe≥ a :Person;
	:name "John Doe";
	:born "3 April 1975"\^\^xsd:dateTime;
	:timeslice [ a :PersonSlice;
		tr:begins "3 April 1975"\^\^xsd:dateTime;
		tr:ends "26 August 1993"\^\^xsd:dateTime;
		:lives "SmallVille" ] ;
	:timeslice [ a :PersonSlice;
		tr:begins "26 August 1993"\^\^xsd:dateTime;
		tr:ends "1 April 2001"\^\^xsd:dateTime;
		:lives "BigTown" ] ;
	:dies "1 April 2001"\^\^xsd:dateTime .                     

There is an interesting question as to whether a Person object is not itself a PersonSlice, just the largest slice of the person there is, and what a good logic for this would be. Makes me think there may be some inspiration to be gained from mereology.

Transaction Time

So finally transaction time helps us keep track of what was said when. It is well agreed upon that a very good way of doing this is to be able to refer to graphs. As stated above a lot of modern tools such as cwm and Sesame 2.0 support graphs, and N3 in particular has a notation for it. So when an aggregator fetches all of the above he can always collect what was said at each point in a graph and give those graphs names and metadata. So an aggregator that kept track of all the statements made in our first ontology that only understand present tense statements could save them in a graph like this

 { ≤#JohnDoe≥ a :Person;
	:name "John Doe";
	:lives "SmallVille". } 
		:fetched [ :at "4 April 1975"\^\^xsd:dateTime;
			:from ≤http://people.gov.org/ssn/123456789≥ ] .
		
{ ≤#JohnDoe≥ a :Person;
	:name "John Doe";
	:lives "BigTown". } 
		:fetched [ :at "Dec 28 1993"\^\^xsd:dateTime;
			:from ≤http://people.gov.org/ssn/123456789≥ ] .

{ ≤#JohnDoe≥ a :Person;
	:name "John Doe";
	:lives "hell". } 
		:fetched [ :at "Dec 01 2001"\^\^xsd:dateTime;
			:from ≤http://people.gov.org/ssn/123456789≥ ] .	

If we could fetch this often enough we would have a complete representation of what the file said over long periods of time. Perhaps we could end up with something like this:

 { ≤#JohnDoe≥ a :Person;
	:name "John Doe";
	:lives "SmallVille". } 
		:believed [ tr:begins "3 April 1975"\^\^xsd:dateTime;
			tr:ends "27 December 1994"\^\^xsd:dateTime;
		                :by ≤http://people.gov.org/ssn/123456789≥ ] .
		
{ ≤#JohnDoe≥ a :Person;
	:name "John Doe";
	:lives "BigTown". } 
		:believed [ tr:begins "27 December 1994"\^\^xsd:dateTime;
			tr:ends "1 April 2001"\^\^xsd:dateTime;
			:by ≤http://people.gov.org/ssn/123456789≥ ] .

{ ≤#JohnDoe≥ a :Person;
	:name "John Doe";
	:lives "hell". } 
		:believed [ tr:begins "1 April 2001"\^\^xsd:dateTime;	
			:by ≤http://people.gov.org/ssn/123456789≥ ] .	

Now as I showed in a thread on the Semantic Web Mailing list it is possible to create rules to map from the above set of graphs to our final "Valid Time" graph, from temporal relations to a-temporal ones. But on closer consideration one will notice that this still won't give us the full story of where John Doe lived, as the data served was false for part of 1993 and 1994.

The wikipedia article adds a twist to its story that makes the difference between transaction time and valid time directly. Let us imagine then that from 1-Jun-1995 to 3-Sep-2000 John Doe moved to beachy. But, to avoid paying Beachy's exorbitant residence tax, he never reported it to the authorities. Later, it is discovered on 2-Feb-2001, during a tax investigation that he was in fact in Beachy during these dates, so they update the database as follows:

@prefix : ≤http://xmlns.com/foaf/0.1/≥ .
@prefix tr: ≤http://www.isi.edu/~pan/damltime/time-entry.owl#≥ .
≤#JohnDoe≥ a :Person;
	:name "John Doe";
	:born "3 April 1975"\^\^xsd:dateTime;
	:timeslice [ a :PersonSlice;
		tr:begins "3 April 1975"\^\^xsd:dateTime;
		tr:ends "26 August 1993"\^\^xsd:dateTime;
		:lives "SmallVille" ] ;
	:timeslice [ a :PersonSlice;
		tr:begins "26 August 1993"\^\^xsd:dateTime;
		tr:ends "1 June 1995"\^\^xsd:dateTime;
		:lives "BigTown" ] ;
	:timeslice [ a :PersonSlice;
		tr:begins "1 June 1995"\^\^xsd:dateTime;
		tr:ends "3 Sept 2000"\^\^xsd:dateTime;
		:lives "Beachy" ] ;
	:timeslice [ a :PersonSlice;
		tr:begins "3 Sept 2000"\^\^xsd:dateTime;
		tr:ends "1 April 2001"\^\^xsd:dateTime;
		:lives "BigTown" ] ;
	:dies "1 April 2001"\^\^xsd:dateTime .                     

This is good, but again it fails to take into account the fact that there was a lie at one point. This lack of clarity may be confusing in many other places in that deductions that were once made from the data that used to be may no longer make sense. So we still need transaction time. And again in RDF this requires the ability to quote graphs, which in N3 we can do with the { } notation.

How to go to Paradise

So how can John Doe in his file make sure that he himself states that his previous assertions were false? This would make it easier for an aggregator to know when to merge or not to merge graphs over a period of time. All John Does would need to do would be to state that the resource at which he placed the graph had stated something that was false over certain periods of time. I'll leave the details on how to do this as an exercise to the reader...

Notes

  1. witness the long discussion with Chris Mungall on sethladd's blog. If you read that conversation, keep in mind that doing the modelling in java would confront you with exactly the same problems. If you hava a Person object that needs to attend meetings, how would you explain that a Person only attended part of a meeting? Well if the libraries you are working with think of a Person as an unchanging thing, then you will not be able to use that class directly. You will need to create some Person slice or an event slice class. And there may be many ways of doing this.
Comments:

Great post. Thanks for translating the wiki page into RDF. However, you may be interested in the meta-commentary on that page: Andrew Warden comments on some of the errors in the original.

Posted by Neil Ernst on March 21, 2006 at 05:28 PM CET #

Post a Comment:
Comments are closed for this entry.
About

bblfish

Search

Archives
« April 2014
MonTueWedThuFriSatSun
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    
       
Today