Content-Description: 

#include <iostream.h>
#include <math.h>
#include <string>



class TemporalTransTable {
private:
  int table[13][13];
  void setTable();

protected:
  int getIndex(int relation);

public:  
  const int NOINFO = 0;
  const int EQUALS = 1;
  const int BEFORE = 2;
  const int AFTER  = 4;
  const int DURING = 8;
  const int CONTAINS = 16;
  const int OVERLAPS = 32;
  const int OVERLAPPEDBY = 64;
  const int MEETS = 128;
  const int METBY = 256;
  const int STARTS = 512;
  const int STARTEDBY = 1024;
  const int FINISHES = 2048;
  const int FINISHEDBY = 4096;
  const int NOCONSTRAINTS = 8191;
  TemporalTransTable() { setTable(); }
  string toString(int);
  int intersection(int,int);
  int table_union(int,int);  // note name change to avoid conflict with
                             // C++ reserved word 'union'
};


int TemporalTransTable::getIndex (int relation)
{
  return ((int) log((double) relation)/log(2.0));
}

int TemporalTransTable::intersection (int relationA, int relationB)
{
  return (relationA & relationB);
}

int TemporalTransTable::table_union (int relationA, int relationB)
{
  return (relationA | relationB);
}

string TemporalTransTable::toString (int relation)
{
  string s = "";

  if ((relation & EQUALS) == EQUALS)
    s = s + "equals ";
  if ((relation & BEFORE) == BEFORE)
    s = s + "before ";
  if ((relation & AFTER) == AFTER)
    s = s + "after ";
  if ((relation & DURING) == DURING)
    s = s + "during ";
  if ((relation & CONTAINS) == CONTAINS)
    s = s + "contains ";
  if ((relation & OVERLAPS) == OVERLAPS)
    s = s + "overlaps ";
  if ((relation & OVERLAPPEDBY) == OVERLAPPEDBY) 
    s = s + "overlappedBy ";
  if ((relation & MEETS) == MEETS)
    s = s + "meets ";
  if ((relation & METBY) == METBY)
    s = s + "metBy ";
  if ((relation & STARTS) == STARTS)
    s = s + "starts ";
  if ((relation & STARTEDBY) == STARTEDBY)
    s = s + "startedBy ";
  if ((relation & FINISHES) == FINISHES)
    s = s + "finishes ";
  if ((relation & FINISHEDBY) == FINISHEDBY)
    s = s + "finishedBy ";
  if (s == "")  
    s = s + "noInfo ";

  return (s);
}

void TemporalTransTable::setTable ()
{
  table[getIndex(EQUALS)][getIndex(EQUALS)] = EQUALS;
  table[getIndex(EQUALS)][getIndex(BEFORE)] = BEFORE;
  table[getIndex(EQUALS)][getIndex(AFTER)] = AFTER;
  table[getIndex(EQUALS)][getIndex(DURING)] = DURING;
  table[getIndex(EQUALS)][getIndex(CONTAINS)] = CONTAINS;
  table[getIndex(EQUALS)][getIndex(OVERLAPS)] = OVERLAPS;
  table[getIndex(EQUALS)][getIndex(OVERLAPPEDBY)] = OVERLAPPEDBY;
  table[getIndex(EQUALS)][getIndex(MEETS)] = MEETS;
  table[getIndex(EQUALS)][getIndex(METBY)] = METBY;
  table[getIndex(EQUALS)][getIndex(STARTS)] = STARTS;
  table[getIndex(EQUALS)][getIndex(STARTEDBY)] = STARTEDBY;
  table[getIndex(EQUALS)][getIndex(FINISHES)] = FINISHES;
  table[getIndex(EQUALS)][getIndex(FINISHEDBY)] = FINISHEDBY;
  table[getIndex(BEFORE)][getIndex(EQUALS)] = BEFORE;
  table[getIndex(BEFORE)][getIndex(BEFORE)] = BEFORE;
  table[getIndex(BEFORE)][getIndex(AFTER)] = NOINFO;
  table[getIndex(BEFORE)][getIndex(DURING)] = (
					       BEFORE | 
					       OVERLAPS | 
					       MEETS | 
					       DURING | 
					       STARTS);
  table[getIndex(BEFORE)][getIndex(CONTAINS)] = BEFORE;
  table[getIndex(BEFORE)][getIndex(OVERLAPS)] = BEFORE;
  table[getIndex(BEFORE)][getIndex(OVERLAPPEDBY)] = (
						     BEFORE |
						     OVERLAPS |
						     MEETS |
						     DURING |
						     STARTS);
  table[getIndex(BEFORE)][getIndex(MEETS)] = BEFORE;
  table[getIndex(BEFORE)][getIndex(METBY)] = (
					      BEFORE |
					      OVERLAPS |
					      MEETS |
					      DURING |
					      STARTS);
  table[getIndex(BEFORE)][getIndex(STARTS)] = BEFORE;
  table[getIndex(BEFORE)][getIndex(STARTEDBY)] = BEFORE;
  table[getIndex(BEFORE)][getIndex(FINISHES)] = (
						 BEFORE |
						 OVERLAPS |
						 MEETS |
						 DURING |
						 STARTS);
  table[getIndex(BEFORE)][getIndex(FINISHEDBY)] = BEFORE;
  
  table[getIndex(AFTER)][getIndex(EQUALS)] = AFTER;
  table[getIndex(AFTER)][getIndex(BEFORE)] = NOINFO;
  table[getIndex(AFTER)][getIndex(AFTER)] = AFTER;
  table[getIndex(AFTER)][getIndex(DURING)] = (
					      AFTER |
					      OVERLAPPEDBY |
					      METBY |
					      DURING |
					      FINISHES);
  table[getIndex(AFTER)][getIndex(CONTAINS)] = AFTER;
  table[getIndex(AFTER)][getIndex(OVERLAPS)] = (
						AFTER |
						OVERLAPPEDBY |
						METBY |
						DURING |
						FINISHES);
  table[getIndex(AFTER)][getIndex(OVERLAPPEDBY)] = AFTER;
  table[getIndex(AFTER)][getIndex(MEETS)] = (
					     AFTER |
					     OVERLAPPEDBY |
					     METBY |
					     DURING |
					     FINISHES);
  table[getIndex(AFTER)][getIndex(METBY)] = AFTER;
  table[getIndex(AFTER)][getIndex(STARTS)] = (
					      AFTER | 
					      OVERLAPPEDBY |
					      METBY |
					      DURING |
					      FINISHES);
  table[getIndex(AFTER)][getIndex(STARTEDBY)] = AFTER;
  table[getIndex(AFTER)][getIndex(FINISHES)] = AFTER;
  table[getIndex(AFTER)][getIndex(FINISHEDBY)] = AFTER;
  table[getIndex(DURING)][getIndex(EQUALS)] = DURING;
  table[getIndex(DURING)][getIndex(BEFORE)] = BEFORE;
  table[getIndex(DURING)][getIndex(AFTER)] = AFTER;
  table[getIndex(DURING)][getIndex(DURING)] = DURING;
  table[getIndex(DURING)][getIndex(CONTAINS)] = NOINFO;
  table[getIndex(DURING)][getIndex(OVERLAPS)] = (
						 BEFORE |
						 OVERLAPS |
						 MEETS |
						 DURING |
						 STARTS);
  table[getIndex(DURING)][getIndex(OVERLAPPEDBY)] = (
						     AFTER |
						     OVERLAPPEDBY |
						     METBY |
						     DURING |
						     FINISHES);
  table[getIndex(DURING)][getIndex(MEETS)] = BEFORE;
  table[getIndex(DURING)][getIndex(METBY)] = AFTER;
  table[getIndex(DURING)][getIndex(STARTS)] = DURING;
  table[getIndex(DURING)][getIndex(STARTEDBY)] = ( 
						  AFTER | 
						  OVERLAPPEDBY |
						  METBY |
						  DURING |
						  FINISHES);
  table[getIndex(DURING)][getIndex(FINISHES)] = DURING;
  table[getIndex(DURING)][getIndex(FINISHEDBY)] = (
						   BEFORE |
						   OVERLAPS |
						   MEETS |
						   DURING |
						   STARTS);
  table[getIndex(CONTAINS)][getIndex(EQUALS)] = CONTAINS;
  table[getIndex(CONTAINS)][getIndex(BEFORE)] = (
						 BEFORE |
						 OVERLAPS |
						 MEETS |
						 CONTAINS |
						 FINISHEDBY);
  table[getIndex(CONTAINS)][getIndex(AFTER)] = (
						AFTER |
						OVERLAPPEDBY |
						CONTAINS |
						METBY |
						STARTEDBY);
  table[getIndex(CONTAINS)][getIndex(DURING)] = (
						 OVERLAPS |
						 OVERLAPPEDBY |
						 DURING |
						 CONTAINS |
						 EQUALS |
	 					 STARTS |
						 STARTEDBY |
						 FINISHES |
						 FINISHEDBY);
  table[getIndex(CONTAINS)][getIndex(CONTAINS)] = CONTAINS;
  table[getIndex(CONTAINS)][getIndex(OVERLAPS)] = (
						   OVERLAPS |
						   CONTAINS |
						   FINISHEDBY);
  table[getIndex(CONTAINS)][getIndex(OVERLAPPEDBY)] = (
						       OVERLAPPEDBY |
						       CONTAINS |
						       STARTEDBY);
  table[getIndex(CONTAINS)][getIndex(MEETS)] = ( 
						OVERLAPS |
						CONTAINS |
						FINISHEDBY);
  table[getIndex(CONTAINS)][getIndex(METBY)] = (
						OVERLAPPEDBY |
						CONTAINS |
						STARTEDBY);
  table[getIndex(CONTAINS)][getIndex(STARTS)] = (
						 CONTAINS |
						 FINISHEDBY |
						 OVERLAPS);
  table[getIndex(CONTAINS)][getIndex(STARTEDBY)] = CONTAINS;
  table[getIndex(CONTAINS)][getIndex(FINISHES)] = (
						   CONTAINS |
						   STARTEDBY |
						   OVERLAPPEDBY);
  table[getIndex(CONTAINS)][getIndex(FINISHEDBY)] = CONTAINS;
  table[getIndex(OVERLAPS)][getIndex(EQUALS)] = OVERLAPS;
  table[getIndex(OVERLAPS)][getIndex(BEFORE)] = BEFORE;
  table[getIndex(OVERLAPS)][getIndex(AFTER)] = (
						AFTER |
						CONTAINS |
						OVERLAPPEDBY |
						METBY |
						STARTEDBY);
  table[getIndex(OVERLAPS)][getIndex(DURING)] = ( 
						 OVERLAPS |
						 DURING |
						 STARTS);
  table[getIndex(OVERLAPS)][getIndex(CONTAINS)] = (
						   BEFORE |
						   OVERLAPS |
						   MEETS |
						   CONTAINS |
						   FINISHEDBY 
						   );
  table[getIndex(OVERLAPS)][getIndex(OVERLAPS)] = (
						   OVERLAPS |
						   BEFORE |
						   MEETS);
  table[getIndex(OVERLAPS)][getIndex(OVERLAPPEDBY)] = (
						       OVERLAPS |
						       OVERLAPPEDBY |
						       DURING |
						       CONTAINS |
						       EQUALS | 
						       STARTS |
						       STARTEDBY |
						       FINISHES |
						       FINISHEDBY );
  table[getIndex(OVERLAPS)][getIndex(MEETS)] = BEFORE;
  table[getIndex(OVERLAPS)][getIndex(METBY)] = (
						OVERLAPPEDBY |
						CONTAINS |
						STARTEDBY);
  table[getIndex(OVERLAPS)][getIndex(STARTS)] = OVERLAPS;
  table[getIndex(OVERLAPS)][getIndex(STARTEDBY)] = (
						    CONTAINS |
						    FINISHEDBY |
						    OVERLAPS);
  table[getIndex(OVERLAPS)][getIndex(FINISHES)] = (
						   CONTAINS |
						   FINISHEDBY |
						   OVERLAPS);
  table[getIndex(OVERLAPS)][getIndex(FINISHEDBY)] = (
						     BEFORE |
						     OVERLAPS |
						     MEETS);
  table[getIndex(OVERLAPPEDBY)][getIndex(EQUALS)] = OVERLAPPEDBY;
  table[getIndex(OVERLAPPEDBY)][getIndex(BEFORE)] = (
						     BEFORE |
						     OVERLAPS |
						     MEETS |
						     CONTAINS |
						     FINISHEDBY);
  table[getIndex(OVERLAPPEDBY)][getIndex(AFTER)] = AFTER;
  table[getIndex(OVERLAPPEDBY)][getIndex(DURING)] = (
						     OVERLAPPEDBY |
						     DURING |
						     FINISHES);
  table[getIndex(OVERLAPPEDBY)][getIndex(CONTAINS)] = (
						       OVERLAPPEDBY |
						       AFTER |
						       METBY |
						       CONTAINS |
						       STARTEDBY);
  table[getIndex(OVERLAPPEDBY)][getIndex(OVERLAPS)] = (
						       OVERLAPS |
						       DURING |
						       CONTAINS |
						       EQUALS |
						       OVERLAPPEDBY | 
						       STARTS |
						       STARTEDBY |
				  		       FINISHES |
						       FINISHEDBY);
  table[getIndex(OVERLAPPEDBY)][getIndex(OVERLAPPEDBY)] = (
							   OVERLAPPEDBY |
							   METBY |
							   AFTER);
  table[getIndex(OVERLAPPEDBY)][getIndex(MEETS)] = (
						    OVERLAPS |
						    CONTAINS |
						    FINISHEDBY);
  table[getIndex(OVERLAPPEDBY)][getIndex(METBY)] = AFTER;
  table[getIndex(OVERLAPPEDBY)][getIndex(STARTS)] = (
						     OVERLAPPEDBY |
						     DURING |
						     FINISHES);
  table[getIndex(OVERLAPPEDBY)][getIndex(STARTEDBY)] = (
							OVERLAPPEDBY |
							AFTER |
							METBY);
  table[getIndex(OVERLAPPEDBY)][getIndex(FINISHES)] = OVERLAPPEDBY;
  table[getIndex(OVERLAPPEDBY)][getIndex(FINISHEDBY)] = (
							 OVERLAPPEDBY |
							 CONTAINS |
							 STARTEDBY);
  table[getIndex(MEETS)][getIndex(EQUALS)] = MEETS;
  table[getIndex(MEETS)][getIndex(BEFORE)] = BEFORE;
  table[getIndex(MEETS)][getIndex(AFTER)] = (
					     AFTER |
					     OVERLAPPEDBY |
					     METBY |
					     CONTAINS |
					     STARTEDBY);
  table[getIndex(MEETS)][getIndex(DURING)] = (
					      OVERLAPS |
					      DURING |
					      STARTS);
  table[getIndex(MEETS)][getIndex(CONTAINS)] = BEFORE;
  table[getIndex(MEETS)][getIndex(OVERLAPS)] = BEFORE;
  table[getIndex(MEETS)][getIndex(OVERLAPPEDBY)] = (
						    OVERLAPS |
						    DURING |
						    STARTS);
  table[getIndex(MEETS)][getIndex(MEETS)] = BEFORE;
  table[getIndex(MEETS)][getIndex(METBY)] = (
					     FINISHES |
					     FINISHEDBY |
					     EQUALS);
  table[getIndex(MEETS)][getIndex(STARTS)] = MEETS;
  table[getIndex(MEETS)][getIndex(STARTEDBY)] = MEETS;
  table[getIndex(MEETS)][getIndex(FINISHES)] = (
						DURING |
						STARTS |
						OVERLAPS);
  table[getIndex(MEETS)][getIndex(FINISHEDBY)] = BEFORE;
  table[getIndex(METBY)][getIndex(EQUALS)] = METBY;
  table[getIndex(METBY)][getIndex(BEFORE)] = (
					      BEFORE |
					      OVERLAPS |
					      CONTAINS |
					      MEETS |
					      FINISHEDBY);
  table[getIndex(METBY)][getIndex(AFTER)] = AFTER;
  table[getIndex(METBY)][getIndex(DURING)] = (
					      OVERLAPPEDBY |
					      DURING |
					      FINISHES);
  table[getIndex(METBY)][getIndex(CONTAINS)] = AFTER;
  table[getIndex(METBY)][getIndex(OVERLAPS)] = (
						OVERLAPPEDBY |
						DURING |
						FINISHES);
  table[getIndex(METBY)][getIndex(OVERLAPPEDBY)] = AFTER;
  table[getIndex(METBY)][getIndex(MEETS)] = (
					     STARTS |
					     STARTEDBY |
					     EQUALS);
  table[getIndex(METBY)][getIndex(METBY)] = AFTER;
  table[getIndex(METBY)][getIndex(STARTS)] = (
					      DURING |
					      FINISHES |
					      OVERLAPPEDBY);
  table[getIndex(METBY)][getIndex(STARTEDBY)] = AFTER;
  table[getIndex(METBY)][getIndex(FINISHES)] = METBY;
  table[getIndex(METBY)][getIndex(FINISHEDBY)] = METBY;
  table[getIndex(STARTS)][getIndex(EQUALS)] = STARTS;
  table[getIndex(STARTS)][getIndex(BEFORE)] = BEFORE;
  table[getIndex(STARTS)][getIndex(AFTER)] = AFTER;
  table[getIndex(STARTS)][getIndex(DURING)] = DURING;
  table[getIndex(STARTS)][getIndex(CONTAINS)] = (
						 BEFORE |
						 OVERLAPS |
						 MEETS |
						 CONTAINS |
						 FINISHEDBY);
  table[getIndex(STARTS)][getIndex(OVERLAPS)] = (
						 BEFORE |
						 OVERLAPS |
						 MEETS);
  table[getIndex(STARTS)][getIndex(OVERLAPPEDBY)] = (
						     OVERLAPPEDBY |
						     DURING |
						     FINISHES);
  table[getIndex(STARTS)][getIndex(MEETS)] = BEFORE;
  table[getIndex(STARTS)][getIndex(METBY)] = METBY;
  table[getIndex(STARTS)][getIndex(STARTS)] = STARTS;
  table[getIndex(STARTS)][getIndex(STARTEDBY)] = (
						  STARTS |
						  STARTEDBY |
						  EQUALS);
  table[getIndex(STARTS)][getIndex(FINISHES)] = DURING;
  table[getIndex(STARTS)][getIndex(FINISHEDBY)] = (
						   BEFORE |
						   MEETS |
						   OVERLAPS);
  table[getIndex(STARTEDBY)][getIndex(EQUALS)] = STARTEDBY; 
  table[getIndex(STARTEDBY)][getIndex(BEFORE)] = (
						  BEFORE |
						  OVERLAPS |
						  MEETS |
						  CONTAINS |
						  FINISHEDBY); 
  table[getIndex(STARTEDBY)][getIndex(AFTER)] = AFTER; 
  table[getIndex(STARTEDBY)][getIndex(DURING)] = (
						  OVERLAPPEDBY |
						  DURING |
						  FINISHES); 
  table[getIndex(STARTEDBY)][getIndex(CONTAINS)] = CONTAINS; 
  table[getIndex(STARTEDBY)][getIndex(OVERLAPS)] = (
						    OVERLAPS |
						    CONTAINS |
						    FINISHEDBY); 
  table[getIndex(STARTEDBY)][getIndex(OVERLAPPEDBY)] = OVERLAPPEDBY; 
  table[getIndex(STARTEDBY)][getIndex(MEETS)] = (
						 OVERLAPS |
						 CONTAINS |
						 FINISHEDBY); 
  table[getIndex(STARTEDBY)][getIndex(METBY)] = METBY; 
  table[getIndex(STARTEDBY)][getIndex(STARTS)] = (
						  STARTS |
						  STARTEDBY |
						  EQUALS); 
  table[getIndex(STARTEDBY)][getIndex(STARTEDBY)] = STARTEDBY; 
  table[getIndex(STARTEDBY)][getIndex(FINISHES)] = OVERLAPPEDBY; 
  table[getIndex(STARTEDBY)][getIndex(FINISHEDBY)] = CONTAINS; 
  table[getIndex(FINISHES)][getIndex(EQUALS)] = FINISHES; 
  table[getIndex(FINISHES)][getIndex(BEFORE)] = BEFORE; 
  table[getIndex(FINISHES)][getIndex(AFTER)] = AFTER; 
  table[getIndex(FINISHES)][getIndex(DURING)] = DURING; 
  table[getIndex(FINISHES)][getIndex(CONTAINS)] = (
						   AFTER |
						   OVERLAPPEDBY |
						   METBY |
						   CONTAINS |
						   STARTEDBY); 
  table[getIndex(FINISHES)][getIndex(OVERLAPS)] = (
						   OVERLAPS |
						   DURING |
						   STARTS);
  table[getIndex(FINISHES)][getIndex(OVERLAPPEDBY)] = (
						       AFTER |
						       OVERLAPPEDBY |
						       METBY); 
  table[getIndex(FINISHES)][getIndex(MEETS)] = MEETS;
  table[getIndex(FINISHES)][getIndex(METBY)] = AFTER; 
  table[getIndex(FINISHES)][getIndex(STARTS)] = DURING; 
  table[getIndex(FINISHES)][getIndex(STARTEDBY)] = (
						    AFTER |
						    OVERLAPPEDBY |
						    METBY); 
  table[getIndex(FINISHES)][getIndex(FINISHES)] = FINISHES; 
  table[getIndex(FINISHES)][getIndex(FINISHEDBY)] = (
						     FINISHES |
						     FINISHEDBY |
						     EQUALS); 
  table[getIndex(FINISHEDBY)][getIndex(EQUALS)] = FINISHEDBY; 
  table[getIndex(FINISHEDBY)][getIndex(BEFORE)] = BEFORE; 
  table[getIndex(FINISHEDBY)][getIndex(AFTER)] = (
						  AFTER |
						  OVERLAPPEDBY |
						  METBY |
						  CONTAINS |
						  STARTEDBY); 
  table[getIndex(FINISHEDBY)][getIndex(DURING)] = (
						   OVERLAPS |
						   DURING |
						   STARTS);
  table[getIndex(FINISHEDBY)][getIndex(CONTAINS)] = CONTAINS; 
  table[getIndex(FINISHEDBY)][getIndex(OVERLAPS)] = OVERLAPS; 
  table[getIndex(FINISHEDBY)][getIndex(OVERLAPPEDBY)] = (
							 OVERLAPPEDBY |
							 CONTAINS |
							 STARTEDBY);
  table[getIndex(FINISHEDBY)][getIndex(MEETS)] = MEETS; 
  table[getIndex(FINISHEDBY)][getIndex(METBY)] = (
						  STARTEDBY |
						  OVERLAPPEDBY |
						  CONTAINS); 
  table[getIndex(FINISHEDBY)][getIndex(STARTS)] = OVERLAPS; 
  table[getIndex(FINISHEDBY)][getIndex(STARTEDBY)] = CONTAINS; 
  table[getIndex(FINISHEDBY)][getIndex(FINISHES)] = (
						     FINISHEDBY |
						     FINISHES |
						     EQUALS); 
  table[getIndex(FINISHEDBY)][getIndex(FINISHEDBY)] = FINISHEDBY; 
}

