#### import stuff
# terms from W3C Recommenations
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.
@prefix dt: <http://www.w3.org/2001/XMLSchema#>.
@prefix owl: <http://www.w3.org/2002/07/owl#>.
@prefix s: <http://www.w3.org/2000/01/rdf-schema#>.

# community vocabularies: RDF Calendar, GEO, Cyc
@prefix c: <http://www.w3.org/2002/12/cal/icaltzd#>.
c:uri s:range owl:Thing.

@prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>.
geo:lat a owl:DatatypeProperty; s:domain geo:SpatialThing.
geo:long a owl:DatatypeProperty; s:domain geo:SpatialThing.
geo:SpatialThing a owl:Class.

@prefix foaf: <http://xmlns.com/foaf/0.1/>.
foaf:mbox a owl:InverseFunctionalProperty;
  s:domain foaf:Agent; s:range owl:Thing.
foaf:name a owl:DatatypeProperty.
foaf:Agent a owl:Class.
foaf:Person a owl:Class; s:subClassOf foaf:Agent.

@prefix cyc: <http://www.cyc.com/2004/06/04/cyc#>.
cyc:SpatialThing a owl:Class; owl:equivalentClass geo:SpatialThing.
cyc:inRegion
 s:domain cyc:SpatialThing;
 s:range cyc:SpatialThing.
cyc:TemporalThing a owl:Class.
cyc:CalendarDate s:subClassOf cyc:TemporalThing.
cyc:Event a owl:Class.
cyc:eventOccursAt s:domain cyc:Event; s:range cyc:TemporalThing.
cyc:City a owl:Class.
cyc:temporallyIntersects s:domain cyc:TemporalThing;
 s:range cyc:TemporalThing.
cyc:startingDate s:subPropertyOf cyc:temporallyIntersects.
cyc:temporallySubsumes s:subPropertyOf cyc:temporallyIntersects.
cyc:nameOfAgent a owl:DatatypeProperty.
cyc:Entity a owl:Class.
cyc:subAbstrac s:domain cyc:Entity; s:range cyc:Entity.
cyc:Agent a owl:Class; owl:equivalentClass foaf:Agent.
cyc:socialParticipants s:range cyc:Agent.

# cwm/N3 utility terms
@prefix str: <http://www.w3.org/2000/10/swap/string#>.
@prefix log: <http://www.w3.org/2000/10/swap/log#>.
@prefix m: <http://www.w3.org/2000/10/swap/math#>.

###### end imports ######

@prefix : <calbg#>.
@keywords is, of, a.

<> owl:versionInfo "$Id: calbg.n3,v 1.6 2006/09/11 14:11:24 connolly Exp $".


# Modelling assumption: on a given day, a person can only be in one city
PersonDay a owl:Class; s:subClassOf cyc:Entity;
 s:subClassOf [ owl:onProperty _city; owl:maxCardinality 1 ].

# Infer the person/agent implicit in the iCalendar attendee construct
{ [ c:calAddress ?MBOX ] } => { [] foaf:mbox ?MBOX }.

{ ?E c:attendee [ c:calAddress ?MBOX ]. ?WHO foaf:mbox ?MBOX. }
 => { ?E cyc:socialParticipants ?WHO }.
{ ?E cyc:socialParticipants ?WHO;
     c:attendee [ c:calAddress [ is foaf:mbox of ?WHO]; c:cn ?N ];
} => { ?WHO foaf:name ?N }.


# Infer the place implicit in the iCalendar geo and location properties
# Modelling assumption: iCalendar events occur in cities
{  ?E c:geo (?LAT ?LONG)
} => { ?E cyc:eventOccursAt [ geo:lat ?LAT; geo:long ?LONG] }.
{  ?E c:location ?PLACENAME; cyc:eventOccursAt ?WHERE
} => {
  ?WHERE cyc:nameOfAgent ?PLACENAME;
    s:label ?PLACENAME;
    cyc:inRegion [ a cyc:City ].
}.

# Relate events to cyc:CalendarDates
{ ?E c:dtstart ?DATE.
  ?WHEN a cyc:CalendarDate; rdf:value ?DATE.
} => { ?E cyc:startingDate ?WHEN }.
{ ?E c:dtend ?DATE.
  ?WHEN a cyc:CalendarDate; rdf:value ?DATE.
} => { ?E cyc:endingDate ?WHEN }.

# Modelling assumption: all iCalendar events intersect every day
# btween their startingDate and their endingDate
{
  ?E a c:Vevent;
     c:dtstart [ str:notGreaterThan ?DATE ];
     c:dtend [ str:greaterThan ?DATE ].
  ?WHEN a cyc:CalendarDate; rdf:value ?DATE.
} => { ?E cyc:temporallyIntersects ?WHEN }.


# make a cyc:subAbstrac for each person on each day
{
  ?E cyc:socialParticipants ?WHO;
     cyc:temporallyIntersects ?WHEN.
  ?WHEN a cyc:CalendarDate.
} => {
 ?WHO cyc:subAbstrac _:whowhen.
 ?WHEN cyc:temporallySubsumes _:whowhen.
 _:whowhen a PersonDay.
}.

{ ?E cyc:socialParticipants ?WHO;
     cyc:temporallyIntersects ?WHEN;
     cyc:eventOccursAt [ cyc:inRegion ?C].
  ?C a cyc:City.
  ?WHO cyc:subAbstrac ?WHOWHEN.
  ?WHEN cyc:temporallySubsumes ?WHOWHEN.
} => { ?WHOWHEN _city ?C }.

# cities containing points far from each other are distinct
{
  ?C1 a cyc:City; is cyc:inRegion of [geo:lat ?X1; geo:long ?Y1 ].
  ?C2 a cyc:City; is cyc:inRegion of [geo:lat ?X2; geo:long ?Y2 ].
  ?X1 m:notLessThan ?X2.

  # DSQ = (X1-X2)^2 + (Y1-Y2)^2
  (((?X2 ?X1).m:difference 2).m:exponentiation
   ((?Y2 ?Y1).m:difference 2).m:exponentiation) m:sum ?DSQ.

 # There's got to be some bound on the great circle distance
 # based on this formula. I'm not going to work it out just now.
 # When using zip codes of different parts of kansas city,
 # it comes to .05. So .2 should indicate different cities.
  ?DSQ m:greaterThan 0.2.
} => { ?C1 owl:differentFrom ?C2 }.


# utility data
oct1 a cyc:CalendarDate; rdf:value "2005-10-01"^^dt:date.
oct2 a cyc:CalendarDate; rdf:value "2005-10-02"^^dt:date.
oct3 a cyc:CalendarDate; rdf:value "2005-10-03"^^dt:date.
oct4 a cyc:CalendarDate; rdf:value "2005-10-04"^^dt:date.
oct5 a cyc:CalendarDate; rdf:value "2005-10-05"^^dt:date.
oct6 a cyc:CalendarDate; rdf:value "2005-10-06"^^dt:date.
oct7 a cyc:CalendarDate; rdf:value "2005-10-07"^^dt:date.
oct8 a cyc:CalendarDate; rdf:value "2005-10-08"^^dt:date.
oct9 a cyc:CalendarDate; rdf:value "2005-10-09"^^dt:date.


