/* ---- This file is part of SECONDO. Copyright (C) 2007, Faculty of Mathematics and Computer Science, Database Systems for New Applications. SECONDO is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. SECONDO is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with SECONDO; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ---- */ #include "dfa.h" #include "GenericTC.h" #include "GenOps.h" #include "Algebra.h" #include "Algebras/FText/FTextAlgebra.h" #include "ListUtils.h" #include "Algebras/Spatial/SpatialAlgebra.h" #include "Algebras/Spatial/Point.h" #include "MTopRelAlgs.h" #include "Algebras/Temporal/TemporalAlgebra.h" #include "StandardTypes.h" #include "Algebras/Relation-C++/RelationAlgebra.h" #include "Symbols.h" using namespace std; using namespace datetime; namespace temporalalgebra{ /* 1 Type Constructor */ GenTC topreldfa; /* 2 Operators 1.1 createdfa Operator for creating a topreldfa from a pridicategroup and a text. */ int createDfaVM( Word* args, Word& result, int message, Word& local, Supplier s ){ result = qp->ResultStorage(s); toprel::PredicateGroup* pg = static_cast(args[0].addr); FText* regex = static_cast(args[1].addr); TopRelDfa* res = static_cast(result.addr); if(!pg->IsDefined() || !regex->IsDefined()){ res->SetDefined(false); return 0; } string r = regex->GetValue(); res->setTo( r, *pg); return 0; } const string createDfaSpec = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" )" "( predicategroup x text -> mtoprel " "createDfa(_,_)" "Creates an mtoprel object" "query createDfa(stdpgroup(), 'inside meet disjoint'" ") )"; Operator createDfa( "createDfa", createDfaSpec, createDfaVM, Operator::SimpleSelect, TypeMap2); /* 2. Operator toprelseq This operator takes a spatial type and an moving spatial type and produces a stream of tuples comptaining an time interval (represented as attributes Start, End, LC, RC, and an int9m representing the topological relationship between the arguments within this time interval. */ ListExpr toprelseqTM(ListExpr args){ string err = "expected point x upoint | " " point x mpoint | " " upoint x upoint |" " upoint x mpoint |" " mpoint x mpoint |" " region x upoint |" " region x mpoint |" " upoint x point |" " mpoint x point |" " mpoint x upoint |" " upoint x region |" " mpoint x region " ; int len = nl->ListLength(args); if((len!=2) ){ return listutils::typeError(err); } ListExpr arg1 = nl->First(args); ListExpr arg2 = nl->Second(args); bool ok = false; ok = ok || (listutils::isSymbol(arg1, Point::BasicType()) && listutils::isSymbol(arg2, UPoint::BasicType())); ok = ok || (listutils::isSymbol(arg1, Point::BasicType()) && listutils::isSymbol(arg2, MPoint::BasicType())); ok = ok || (listutils::isSymbol(arg1, UPoint::BasicType()) && listutils::isSymbol(arg2, UPoint::BasicType())); ok = ok || (listutils::isSymbol(arg1, UPoint::BasicType()) && listutils::isSymbol(arg2, MPoint::BasicType())); ok = ok || (listutils::isSymbol(arg1, MPoint::BasicType()) && listutils::isSymbol(arg2, MPoint::BasicType())); ok = ok || (listutils::isSymbol(arg1, Region::BasicType()) && listutils::isSymbol(arg2, UPoint::BasicType())); ok = ok || (listutils::isSymbol(arg1, Region::BasicType()) && listutils::isSymbol(arg2, MPoint::BasicType())); ok = ok || (listutils::isSymbol(arg1, UPoint::BasicType()) && listutils::isSymbol(arg2, Point::BasicType())); ok = ok || (listutils::isSymbol(arg1, MPoint::BasicType()) && listutils::isSymbol(arg2, Point::BasicType())); ok = ok || (listutils::isSymbol(arg1, MPoint::BasicType()) && listutils::isSymbol(arg2, UPoint::BasicType())); ok = ok || (listutils::isSymbol(arg1, UPoint::BasicType()) && listutils::isSymbol(arg2, Region::BasicType())); ok = ok || (listutils::isSymbol(arg1, MPoint::BasicType()) && listutils::isSymbol(arg2, Region::BasicType())); if(ok){ ListExpr attrList = nl->FiveElemList( nl->TwoElemList( nl->SymbolAtom("Start"), nl->SymbolAtom(DateTime::BasicType())), nl->TwoElemList( nl->SymbolAtom("End"), nl->SymbolAtom(DateTime::BasicType())), nl->TwoElemList( nl->SymbolAtom("LeftClosed"), nl->SymbolAtom(CcBool::BasicType())), nl->TwoElemList( nl->SymbolAtom("RightClosed"), nl->SymbolAtom(CcBool::BasicType())), nl->TwoElemList( nl->SymbolAtom("TopRel"), nl->SymbolAtom(toprel::Int9M::BasicType()))); return nl->TwoElemList(nl->SymbolAtom(Symbol::STREAM()), nl->TwoElemList( nl->SymbolAtom(Tuple::BasicType()), attrList)); } return listutils::typeError(err); } const string toprelseqSpec = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" )" "( point x {upoint, mpoint} | " " upoint x upoint | " " upoint x mpoint | " " mpoint x mpoint | " " region x upoint | " " region x point |" " upoint x point |" " mpoint x point |" " mpoint x upoint |" " upoint x region |" " mpoint x region " "-> stream(tuple(Start " "instant, End instant, " "LeftClosed bool, RightClosed bool, TopRel int9m)) " "toprelseq(_,_)" "Returns the stream of topological relationships" " together with time intervals" "query toprelseq(p, up) tconsume" ") )"; template class toprelseq_LocalInfo{ public: toprelseq_LocalInfo(const A1* a1, const A2* a2, const ListExpr tt){ tupleType = new TupleType(tt); proc = new Proc(a1,a2); } toprelseq_LocalInfo(const A1* a1, const A2* a2, const toprel::PredicateGroup* pg, ListExpr tt){ tupleType = new TupleType(tt); proc = new Proc(a1,a2,pg); } ~toprelseq_LocalInfo(){ tupleType->DeleteIfAllowed(); delete proc; } Tuple* nextTopRelTuple(){ if(!proc->hasNext()){ return 0; } Tuple* tuple = new Tuple(tupleType); pair, toprel::Int9M> p = proc->next(); storeIntervalIntoTuple(tuple, p.first); tuple->PutAttribute(4, new toprel::Int9M(p.second)); return tuple; } Tuple* nextClusterTuple(){ if(!proc->hasNextCluster()){ return 0; } Tuple* tuple = new Tuple(tupleType); pair, toprel::Cluster> p = proc->nextCluster(); storeIntervalIntoTuple(tuple, p.first); tuple->PutAttribute(4, new toprel::Cluster(p.second)); return tuple; } private: TupleType* tupleType; Proc* proc; /* ~storeIntervalIntoTuple~ stores the interval at the first 4 positions of the tuple. */ void storeIntervalIntoTuple(Tuple* tuple, Interval& interval){ tuple->PutAttribute(0, new DateTime(interval.start)); tuple->PutAttribute(1, new DateTime(interval.end)); tuple->PutAttribute(2, new CcBool(true,interval.lc)); tuple->PutAttribute(3, new CcBool(true, interval.rc)); } }; int toprelseqSelect(ListExpr args){ ListExpr arg1 = nl->First(args); ListExpr arg2 = nl->Second(args); if(listutils::isSymbol(arg1, Point::BasicType()) && listutils::isSymbol(arg2, UPoint::BasicType())){ return 0; } if(listutils::isSymbol(arg1, Point::BasicType()) && listutils::isSymbol(arg2, MPoint::BasicType())){ return 1; } if(listutils::isSymbol(arg1, UPoint::BasicType()) && listutils::isSymbol(arg2, UPoint::BasicType())){ return 2; } if(listutils::isSymbol(arg1, UPoint::BasicType()) && listutils::isSymbol(arg2, MPoint::BasicType())){ return 3; } if(listutils::isSymbol(arg1, MPoint::BasicType()) && listutils::isSymbol(arg2, MPoint::BasicType())){ return 4; } if(listutils::isSymbol(arg1, Region::BasicType()) && listutils::isSymbol(arg2, UPoint::BasicType())){ return 5; } if(listutils::isSymbol(arg1, Region::BasicType()) && listutils::isSymbol(arg2, MPoint::BasicType())){ return 6; } if(listutils::isSymbol(arg1, UPoint::BasicType()) && listutils::isSymbol(arg2, Point::BasicType())){ return 7; } if(listutils::isSymbol(arg1, MPoint::BasicType()) && listutils::isSymbol(arg2, Point::BasicType())){ return 8; } if(listutils::isSymbol(arg1, MPoint::BasicType()) && listutils::isSymbol(arg2, UPoint::BasicType())){ return 9; } if(listutils::isSymbol(arg1, UPoint::BasicType()) && listutils::isSymbol(arg2, Region::BasicType())){ return 10; } if(listutils::isSymbol(arg1, MPoint::BasicType()) && listutils::isSymbol(arg2, Region::BasicType())){ return 11; } return -1; } template int toprelseq_fun(Word* args, Word& result, int message, Word& local, Supplier s){ switch(message){ case OPEN: { if(local.addr){ toprelseq_LocalInfo* li = static_cast*>(local.addr); delete li; } const A1* a1; const A2* a2; if(!sym){ a1 = static_cast(args[0].addr); a2 = static_cast(args[1].addr); } else { a1 = static_cast(args[1].addr); a2 = static_cast(args[0].addr); } ListExpr tt = GetTupleResultType(s); local.addr = new toprelseq_LocalInfo(a1,a2,nl->Second(tt)); return 0; } case REQUEST: { toprelseq_LocalInfo* li = static_cast*>(local.addr); result.addr = li->nextTopRelTuple(); return result.addr? YIELD: CANCEL; } case CLOSE:{ if(local.addr){ toprelseq_LocalInfo* li = static_cast*>(local.addr); delete li; local.addr = 0; } return 0; } } return -1; } /* ValueMapping toprelseqVM[] = { toprelseq_fun, toprelseq_fun, toprelseq_fun, toprelseq_fun, toprelseq_fun, toprelseq_fun, toprelseq_fun, toprelseq_fun, toprelseq_fun, toprelseq_fun, toprelseq_fun, toprelseq_fun }; Operator toprelseq( "toprelseq", toprelseqSpec, 12, toprelseqVM, toprelseqSelect, toprelseqTM); */ /* 3. Operator clusterseq 3.2 Type Mapping */ ListExpr clusterseqTM(ListExpr args){ string err = "expected point x {upoint, mpoint} x predicategroup | " " upoint x upoint x predicategroup | " " upoint x mpoint x predicategroup |" " mpoint x mpoint x predicategroup |" " region x upoint x predicategroup |" " region x mpoint x predicategroup |" " upoint x point x predicategroup |" " mpoint x point x predicategroup |" " mpoint x upoint x predicategroup |" " upoint x region x predicategroup |" " mpoint x region x predicategroup "; int len = nl->ListLength(args); if((len!=3) ){ return listutils::typeError(err); } ListExpr arg1 = nl->First(args); ListExpr arg2 = nl->Second(args); ListExpr arg3 = nl->Third(args); // the third argument must be a predicategroup if(!listutils::isSymbol(arg3,toprel::PredicateGroup::BasicType())){ return listutils::typeError(err); } bool ok = false; ok = ok || (listutils::isSymbol(arg1, Point::BasicType()) && listutils::isSymbol(arg2, UPoint::BasicType())); ok = ok || (listutils::isSymbol(arg1, Point::BasicType()) && listutils::isSymbol(arg2, MPoint::BasicType())); ok = ok || (listutils::isSymbol(arg1, UPoint::BasicType()) && listutils::isSymbol(arg2, UPoint::BasicType())); ok = ok || (listutils::isSymbol(arg1, UPoint::BasicType()) && listutils::isSymbol(arg2, MPoint::BasicType())); ok = ok || (listutils::isSymbol(arg1, MPoint::BasicType()) && listutils::isSymbol(arg2, MPoint::BasicType())); ok = ok || (listutils::isSymbol(arg1, Region::BasicType()) && listutils::isSymbol(arg2, UPoint::BasicType())); ok = ok || (listutils::isSymbol(arg1, Region::BasicType()) && listutils::isSymbol(arg2, MPoint::BasicType())); ok = ok || (listutils::isSymbol(arg1, UPoint::BasicType()) && listutils::isSymbol(arg2, Point::BasicType())); ok = ok || (listutils::isSymbol(arg1, MPoint::BasicType()) && listutils::isSymbol(arg2, Point::BasicType())); ok = ok || (listutils::isSymbol(arg1, MPoint::BasicType()) && listutils::isSymbol(arg2, UPoint::BasicType())); ok = ok || (listutils::isSymbol(arg1, UPoint::BasicType()) && listutils::isSymbol(arg2, Region::BasicType())); ok = ok || (listutils::isSymbol(arg1, MPoint::BasicType()) && listutils::isSymbol(arg2, Region::BasicType())); if(ok){ ListExpr attrList = nl->FiveElemList( nl->TwoElemList( nl->SymbolAtom("Start"), nl->SymbolAtom(DateTime::BasicType())), nl->TwoElemList( nl->SymbolAtom("End"), nl->SymbolAtom(DateTime::BasicType())), nl->TwoElemList( nl->SymbolAtom("LeftClosed"), nl->SymbolAtom(CcBool::BasicType())), nl->TwoElemList( nl->SymbolAtom("RightClosed"), nl->SymbolAtom(CcBool::BasicType())), nl->TwoElemList( nl->SymbolAtom("Cluster"), nl->SymbolAtom(toprel::Cluster::BasicType()))); return nl->TwoElemList(nl->SymbolAtom(Symbol::STREAM()), nl->TwoElemList( nl->SymbolAtom(Tuple::BasicType()), attrList)); } return listutils::typeError(err); } /* 3.1 Value Mapping We use the localInfo of the topredseq value mapping function. */ template int clusterseq_fun(Word* args, Word& result, int message, Word& local, Supplier s){ switch(message){ case OPEN: { if(local.addr){ toprelseq_LocalInfo* li = static_cast*>(local.addr); delete li; } const A1* a1; const A2* a2; if(!sym){ a1 = static_cast(args[0].addr); a2 = static_cast(args[1].addr); } else { a1 = static_cast(args[1].addr); a2 = static_cast(args[0].addr); } const toprel::PredicateGroup* pg= static_cast(args[2].addr); ListExpr tt = GetTupleResultType(s); local.addr = new toprelseq_LocalInfo(a1, a2,pg,nl->Second(tt)); return 0; } case REQUEST: { toprelseq_LocalInfo* li = static_cast*>(local.addr); result.addr = li->nextClusterTuple(); return result.addr? YIELD: CANCEL; } case CLOSE:{ if(local.addr){ toprelseq_LocalInfo* li = static_cast*>(local.addr); delete li; local.addr = 0; } return 0; } } return -1; } /* 3.3 Array of Value Mapping functions and selection function As selection function, we use the same as for toprelseq. Thus, only the value mapping array is defined. */ ValueMapping clusterseqVM[] = { clusterseq_fun, clusterseq_fun, clusterseq_fun, clusterseq_fun, clusterseq_fun, clusterseq_fun, clusterseq_fun, clusterseq_fun, clusterseq_fun, clusterseq_fun, clusterseq_fun, clusterseq_fun, }; /* 3.4 Operator Specification */ const string clusterseqSpec = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" )" "( point x {upoint, mpoint} x predicategroup | " " upoint x upoint x predicategroup | " " upoint x mpoint x predicategroup | " " mpoint x mpoint x predicategroup |" " region x upoint x predicategroup |" " region x mpoint x predicategroup |" " upoint x point x predicategroup |" " mpoint x point x predicategroup |" " mpoint x upoint x predicategroup |" " upoint x region x predicategroup |" " mpoint x region x predicategroup" " -> " "stream(tuple(Start instant, End instant," " LeftClosed bool, RightClosed bool, TopRel cluster)) " "toprelseq(_,_)" "Returns the stream of topological " "relationships together with time intervals" "query clusterseq(p, up) tconsume" ") )"; /* 3.5 Operator instance */ Operator clusterseq( "clusterseq", clusterseqSpec, 12, clusterseqVM, toprelseqSelect, clusterseqTM); /* 4 Operator checkTopRel 4.1 Type Mapping The type mapping is stream(cluster) x dfa -> bool */ ListExpr checkTopRelTM(ListExpr args){ string err = "stream(cluster) x dfa expected"; if(nl->ListLength(args)!=2){ return listutils::typeError(err); } ListExpr stream = nl->First(args); ListExpr dfa = nl->Second(args); if((nl->ListLength(stream) != 2) || !listutils::isSymbol(nl->First(stream), Symbol::STREAM()) || !listutils::isSymbol(nl->Second(stream), toprel::Cluster::BasicType())){ return listutils::typeError(err); } if(!listutils::isSymbol(dfa,TopRelDfa::BasicType())){ return listutils::typeError(err); } return nl->SymbolAtom(CcBool::BasicType()); } /* 4.2 Value Mapping */ int checkTopRelVM(Word* args, Word& result, int message, Word& local, Supplier s){ result = qp->ResultStorage(s); CcBool* res = static_cast(result.addr); TopRelDfa* dfa = static_cast(args[1].addr); if(!dfa->isUsuable()){ res->Set(false,false); return 0; } bool done = false; qp->Open(args[0].addr); Word clusterW; dfa->start(); qp->Request(args[0].addr,clusterW); while(qp->Received(args[0].addr) && !done){ toprel::Cluster* c = static_cast(clusterW.addr); done = !dfa->next(*c); if(!done){ done = dfa->isError() || dfa->acceptsAll(); } c->DeleteIfAllowed(); if(!done){ qp->Request(args[0].addr,clusterW); } } res->Set(true, dfa->isFinal()); qp->Close(args[0].addr); return 0; } /* 4.3 Specification */ const string checkTopRelSpec = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" )" "( " " stream(cluster) x dfa -> bool " " " " _ checktoprel[_] " "Checks whether the finite automaton " "accepts the stream of clusters" "query clusterseq(thecenter, train7,stdpgroup())" " projecttransformstream[Cluster] checkTopRel[ createDfa(stdpgroup()," " 'disjoint meet .* disjoint')]" ") )"; /* 4.4 Operator instance */ Operator checkTopRel( "checkTopRel", checkTopRelSpec, checkTopRelVM, Operator::SimpleSelect, checkTopRelTM); /* 5 Operator ~mtoppred~ This operator gets two objects (spatial, at least one moving and an TopRelDfa and checks whether the dfa accepts the topological relationships between these objects. If one of the arguments is undefined, also the result is undefined. 5.1 Type Mapping */ ListExpr mtoppredTM(ListExpr args){ string err = "expected " " point x upoint x mtoprel [x bool] | " " point x mpoint x mtoprel [x bool] | " " upoint x upoint x mtoprel [x bool] | " " upoint x mpoint x mtoprel [x bool] |" " mpoint x mpoint x mtoprel [x bool] |" " region x upoint x mtoprel [x bool] |" " region x mpoint x mtoprel |x bool] |" " upoint x point x mtoprel [x bool] | " " mpoint x point x mtoprel [x bool] | " " mpoint x upoint x mtoprel [x bool] | " " upoint x region x mtoprel [x bool] | " " mpoint x region x mtoprel [x bool] | " ; int len = nl->ListLength(args); if((len!=3) && (len!=4) ){ return listutils::typeError(err); } if((len==4) && !listutils::isSymbol(nl->Fourth(args),CcBool::BasicType())){ return listutils::typeError(err); } ListExpr arg1 = nl->First(args); ListExpr arg2 = nl->Second(args); ListExpr arg3 = nl->Third(args); // the third argument must be a predicategroup if(!listutils::isSymbol(arg3,TopRelDfa::BasicType())){ return listutils::typeError(err); } bool ok = false; ok = ok || (listutils::isSymbol(arg1, Point::BasicType()) && listutils::isSymbol(arg2, UPoint::BasicType())); ok = ok || (listutils::isSymbol(arg1, Point::BasicType()) && listutils::isSymbol(arg2, MPoint::BasicType())); ok = ok || (listutils::isSymbol(arg1, UPoint::BasicType()) && listutils::isSymbol(arg2, UPoint::BasicType())); ok = ok || (listutils::isSymbol(arg1, UPoint::BasicType()) && listutils::isSymbol(arg2, MPoint::BasicType())); ok = ok || (listutils::isSymbol(arg1, MPoint::BasicType()) && listutils::isSymbol(arg2, MPoint::BasicType())); ok = ok || (listutils::isSymbol(arg1, Region::BasicType()) && listutils::isSymbol(arg2, UPoint::BasicType())); ok = ok || (listutils::isSymbol(arg1, Region::BasicType()) && listutils::isSymbol(arg2, MPoint::BasicType())); ok = ok || (listutils::isSymbol(arg1, UPoint::BasicType()) && listutils::isSymbol(arg2, Point::BasicType())); ok = ok || (listutils::isSymbol(arg1, MPoint::BasicType()) && listutils::isSymbol(arg2, Point::BasicType())); ok = ok || (listutils::isSymbol(arg1, MPoint::BasicType()) && listutils::isSymbol(arg2, UPoint::BasicType())); ok = ok || (listutils::isSymbol(arg1, UPoint::BasicType()) && listutils::isSymbol(arg2, Region::BasicType())); ok = ok || (listutils::isSymbol(arg1, MPoint::BasicType()) && listutils::isSymbol(arg2, Region::BasicType())); if(ok){ return nl->SymbolAtom(CcBool::BasicType()); } return listutils::typeError(err); } /* 5.2 Value Mapping 5.2.1 Value Mapping function */ template int mtoppredFun(Word* args, Word& result, int message, Word& local, Supplier s){ result = qp->ResultStorage(s); CcBool* res = static_cast(result.addr); const T1* arg1; const T2* arg2; if(!sym){ arg1 = static_cast(args[0].addr); arg2 = static_cast(args[1].addr); } else { arg1 = static_cast(args[1].addr); arg2 = static_cast(args[0].addr); } TopRelDfa* dfa = static_cast(args[2].addr); if(!arg1->IsDefined() || !arg2->IsDefined() || !dfa->IsDefined()){ res->SetDefined(false); return 0; } bool iter = false; bool step = false; if(qp->GetNoSons(s)==4){ iter = true; CcBool* arg4 = static_cast(args[3].addr); if(!arg4->IsDefined()){ res->SetDefined(false); return 0; } else { step = arg4->GetBoolval(); } } if(!dfa->isUsuable()){ res->SetDefined(false); return 0; } Proc proc(arg1, arg2, dfa->getPredicateGroup()); pair, toprel::Cluster> p(Interval(), toprel::Cluster(1)); if(!iter){ dfa->start(); bool done = dfa->acceptsAll() || dfa->isError(); while(proc.hasNextCluster() && !done){ p = proc.nextCluster(); done = ! dfa->next(p.second); if(!done){ done = dfa->acceptsAll() || dfa->isError(); } } res->Set(true,dfa->isFinal()); return 0; } else { set states; states.insert(dfa->getStartState()); bool done = false; while(proc.hasNextCluster() && !done){ p = proc.nextCluster(); if(p.second.IsDefined()){ // ignore undefined clusters done = ! dfa->next(p.second, states, step && (p.first.start == p.first.end)); } } res->Set(true,dfa->isFinal(states)); return 0; } } /* 5.2.2 Value Mapping Array */ ValueMapping mtoppredVM[] = { mtoppredFun, mtoppredFun, mtoppredFun, mtoppredFun, mtoppredFun, mtoppredFun, mtoppredFun, mtoppredFun, mtoppredFun, mtoppredFun, mtoppredFun, mtoppredFun }; /* 5.3 Selection Function */ int mtoppredSelect(ListExpr args){ ListExpr arg1 = nl->First(args); ListExpr arg2 = nl->Second(args); if(listutils::isSymbol(arg1, Point::BasicType()) && listutils::isSymbol(arg2, UPoint::BasicType())){ return 0; } if(listutils::isSymbol(arg1, Point::BasicType()) && listutils::isSymbol(arg2, MPoint::BasicType())){ return 1; } if(listutils::isSymbol(arg1, UPoint::BasicType()) && listutils::isSymbol(arg2, UPoint::BasicType())){ return 2; } if(listutils::isSymbol(arg1, UPoint::BasicType()) && listutils::isSymbol(arg2, MPoint::BasicType())){ return 3; } if(listutils::isSymbol(arg1, MPoint::BasicType()) && listutils::isSymbol(arg2, MPoint::BasicType())){ return 4; } if(listutils::isSymbol(arg1, Region::BasicType()) && listutils::isSymbol(arg2, UPoint::BasicType())){ return 5; } if(listutils::isSymbol(arg1, Region::BasicType()) && listutils::isSymbol(arg2, MPoint::BasicType())){ return 6; } if(listutils::isSymbol(arg1, UPoint::BasicType()) && listutils::isSymbol(arg2, Point::BasicType())){ return 7; } if(listutils::isSymbol(arg1, MPoint::BasicType()) && listutils::isSymbol(arg2, Point::BasicType())){ return 8; } if(listutils::isSymbol(arg1, MPoint::BasicType()) && listutils::isSymbol(arg2, UPoint::BasicType())){ return 9; } if(listutils::isSymbol(arg1, UPoint::BasicType()) && listutils::isSymbol(arg2, Region::BasicType())){ return 10; } if(listutils::isSymbol(arg1, MPoint::BasicType()) && listutils::isSymbol(arg2, Region::BasicType())){ return 11; } return -1; } /* 5.4 Specification */ const string mtoppredSpec = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" )" "( " " point x upoint x mtoprel [x bool] | " " point x mpoint x mtoprel [x bool] | " " upoint x upoint x mtoprel [x bool] | " " upoint x mpoint x mtoprel [x bool] | " " mpoint x mpoint x mtoprel [x bool] |" " region x upoint x mtoprel [x bool] |" " region x mpoint x mtoprel [x bool] |" " upoint x point x mtoprel [x bool] |" " mpoint x point x mtoprel [x bool] |" " mpoint x upoint x mtoprel [x bool] |" " upoint x region x mtoprel [x bool] |" " mpoint x region x mtoprel [x bool]" " -> bool " "" " mtoppred(_,_,_) " "Checks whether the first two parameters " " have one of moving topological relationship as " " defined in the third argument." "If the boolean parameter is omittet, the automaton works like an " "usual deterministic automaton. So a moving point defined for " "a connected interval witch is disjoint over its lifespan, will " "not be accepted by an automaton defined by 'disjoint disjoint'." "If the boolean parameter is present and set to be FALSE, " "The automaton works like an non-deterministic automaton. " "For an transition all states are the new states which are reachable " "by a sequence of simple transitions using the current symbol." "If the boolean parameter is set to be TRUE, the automaton works " "similar to a FALSE value of this argument. The only difference is " "that such sequence transistions are only made, if the interval of " "where the topological relationship holds is longer than a single " "instant." "" " query mtoppred(thecenter, train7, " "createDfa(stdpgroup(), 'disjoint meet .*'))" ") )"; /* 3.5 Operator instance */ Operator mtoppred( "mtoppred", mtoppredSpec, 12, mtoppredVM, mtoppredSelect, mtoppredTM); /* 3 Algebra definition */ class MTopRelAlgebra: public Algebra{ public: MTopRelAlgebra(){ AddTypeConstructor( &topreldfa ); topreldfa.AssociateKind(Kind::DATA()); // add operators AddOperator(&createDfa); // AddOperator(&toprelseq); AddOperator(&clusterseq); AddOperator(&checkTopRel); AddOperator(&mtoppred); } ~MTopRelAlgebra() {}; }; } // end of namepsace /* 3 Initialization of the Algebra */ extern "C" Algebra* InitializeMTopRelAlgebra( NestedList* nlRef, QueryProcessor* qpRef ) { nl = nlRef; qp = qpRef; return (new temporalalgebra::MTopRelAlgebra()); }