/* ---- This file is part of SECONDO. Copyright (C) 2004, University in Hagen, Department of 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 ---- TemporalLiftedAlgebra Juni 2006: Original implementation by J[ue]rgen Schmidt December 2006: Christian D[ue]ntgen added operator ~intersection: mpoint x mpoint [->] mpoint~. December 2006: Christian D[ue]ntgen corrected code for ~SolvePoly(...)~ and separated the solver methods to its own header file called ~PolySolver.h~ within the SECONDO ~include~ directory. September 2009 Simone Jandt: Changed TU\_VM\_ComparePredicateValue\_UReal to use new member function ~CompUReal~ of ~UReal~. 1 Overview This implementation offers a subset of operators of the ~TemporalAlgebra~, For this it leans on Lema, Forlizzi, G[ue]ting, Nardelli, Schneider: ~Algorithms for Moving Objects Databases~, the Computer Journal, 2003. 1 Includes */ #include #include #include "TemporalLiftedAlgebra.h" #include "NestedList.h" #include "QueryProcessor.h" #include "Algebra.h" #include "StandardTypes.h" #include "PolySolver.h" #include "DateTime.h" #include "Algebras/Spatial/SpatialAlgebra.h" #include "Algebras/Temporal/TemporalAlgebra.h" #include "Algebras/MovingRegion/MovingRegionAlgebra.h" #include "Algebras/TemporalExt/TemporalExtAlgebra.h" #include "Algebras/Temporal/RefinementStream.h" using namespace datetime; using namespace std; extern NestedList* nl; extern QueryProcessor* qp; namespace temporalalgebra{ /* Set ~TLA\_DEBUG~ to ~true~ for debug output. Please note that debug output is very verbose and has significant negative input on the algebra's performance. Only enable debug output if you know what you are doing! */ const bool TLA_DEBUG = false; //const bool TLA_DEBUG = true; /* 1 Class template ~RefinementPartitionLift~ This implementation was renamed ~RefinementPartition~ and moved to ~TemporalAlgebra.h~. 1 Methods used by the ValueMapping-Functions 1.1 Method ~MPerimeter()~ calculates the perimeter of a MRegion and returns the MReal value as result. */ void MPerimeter(MRegion& reg, MReal& res) { if(TLA_DEBUG) cout<< "MPerimeter() called" << endl; res.Clear(); if( !reg.IsDefined() ){ res.SetDefined( false ); return; } res.SetDefined( true ); int nocomponents = reg.GetNoComponents(); res.Resize(nocomponents); res.StartBulkLoad(); for(int n = 0; n < nocomponents; n++){ URegionEmb ur; UReal ures(true); double start = 0.0, end = 0.0; reg.Get(n, ur); if(!ur.IsValid()) continue; if(TLA_DEBUG){ cout<<"URegion # "< ures.timeInterval.start) ? (end - start) / (ures.timeInterval.end.ToDouble() - ures.timeInterval.start.ToDouble()) : 0.0; ures.c = start; ures.r = false; if(TLA_DEBUG) cout<<" ends with: a "<= 0 ) ures.c = ct; else ures.c = -ct; ures.r = false; if(TLA_DEBUG){ cout<<" ends with: a "<p0.GetX()<p0.GetY()<p1.GetX()<p1.GetY()<constValue.GetIntval()<=; 2: >. */ template bool CompareValue( const ConstTemporalUnit& n, const ConstTemporalUnit& i, int vers ) { if(TLA_DEBUG) cout<<"ConstTemporalUnit CompareValue "<= return (n.constValue.Compare( &i.constValue ) >= 0); if (vers == 2) //< return (n.constValue.Compare( &i.constValue ) > 0); //should not be reached return false; } /* 1.1 Method ~CompareValue~ Returns true if the value of this TemporalUnit holds the comparison holds with the value of i. The comparisons are -3: \#; -2: <; -1: <=; 0: =; 1: >=; 2: >. */ template bool CompareValue(const ConstTemporalUnit& n, const Alpha& i, int vers ) { if(TLA_DEBUG) cout<<"ConstTemporalUnit CompareValue "<= return (n.constValue.Compare( &i ) >= 0); if (vers == 2) //< return (n.constValue.Compare( &i ) > 0); //should not be reached return false; } /* 1.1 Method ~DistanceMPoint~ Returns the distance between two MPoints as MReal */ void DistanceMPoint( const MPoint& p1, const MPoint& p2, MReal& result) { if(TLA_DEBUG) cout<<"DistanceMPoint called"< rs(&p1,&p2); int i1; int i2; Interval iv; UPoint u1; UPoint u2; UReal ur; while(rs.hasNext()){ rs.getNext(iv,i1,i2); if((i1>=0) && (i2>=0)){ p1.Get(i1,u1); p2.Get(i2,u2); u1.Distance(u2,ur); result.MergeAdd(ur); } } result.EndBulkLoad(); } /* 1.1 Method ~FindEqualTimes4Real~ Function FindEqualTimes4Real to find all times where u1 and u2 are equal, gives them back in t and returns their number. u1 and u2 must have the same timeIntervals (use ShiftUReal to get this) */ int FindEqualTimes4Real(const UReal& u1, const UReal& u2, Instant t[4]){ assert(u1.IsDefined() ); assert(u2.IsDefined() ); int number; double sol2[2]; double sol4[4]; if(TLA_DEBUG){ cout<<"FindEqualTimes4Real called with"< remove"<=; 2: >. \#: u1 is somewhere != u1 within uBool.timeInterval <: u1 is always < u2 during uBool.timeInterval <=: u1 is always <= u2 during uBool.timeInterval =: u1 and u2 are equal during all uBool.timeInterval >=: u1 is always >= u2 during uBool.timeInterval >: u1 is always > u2 during uBool.timeInterval */ static void CompareUReal(const UReal& u1, const UReal& u2, UBool& uBool, int op) { assert( u1.IsDefined() ); assert( u1.IsValid() ); assert( u2.IsDefined() ); assert( u2.IsValid() ); assert( uBool.IsDefined() ); assert( uBool.IsValid() ); if(TLA_DEBUG){ cout<<"CompareUReal "<= -1 && op <= 1) uBool.constValue.Set(true,true); // all equal else uBool.constValue.Set(true,false); } else if( (value1start.Compare(&value2start) == -1) // all u1 && (value1mid.Compare(&value2start) == -1) // are && (value1start.Compare(&value2start) == -1)) { // smaller if (op < 0) uBool.constValue.Set(true,true); else uBool.constValue.Set(true,false); } else if( (value1start.Compare(&value2start) == 1) // all u1 && (value1mid.Compare(&value2mid) == 1) // are && (value1end.Compare(&value2end) == 1) ){ // larger if (op > 0 || op == -3) uBool.constValue.Set(true,true); else uBool.constValue.Set(true,false); } else { if (op == -3) uBool.constValue.Set(true,true); else uBool.constValue.Set(true,false); } if(TLA_DEBUG) cout<<"return with "< rp(op1, op2); if(TLA_DEBUG) cout<<"Refinement finished, rp.size: "< iv; int u1Pos; int u2Pos; UReal u1transfer; UReal u2transfer; UReal u1(true); UReal u2(true); int numPartRes = 0; vector partResVector; //bool resultIsValid = true; rp.Get(i, iv, u1Pos, u2Pos); if (u1Pos == -1 || u2Pos == -1) continue; if(TLA_DEBUG){ cout<<"Both operators existant in interval iv #"<=; 2: >. Implemetation changed because of missing implementation parts. Now we use new UReal::CompUReal -Member function for computing. The opcodes have to be mapped to the enumeration of that memberfunction, which uses different opcode opcode == 0 = opcode == 1 \# opcode == 2 < opcode == 3 > opcode == 4 <= opcode == 5 >= Because the function is called from many other parts we have to map the opcodes inside the function instead of changing all calling parts. */ static void MovingRealCompareMM2(const MReal& op1, const MReal& op2, MBool& result, int op) { result.Clear(); if( !op1.IsDefined() || !op2.IsDefined() ){ result.SetDefined( false ); return; } result.SetDefined( true ); int opcode = 0; switch(op) { case -3: opcode = 1; break; case -2: opcode = 2; break; case -1: opcode = 4; break; case 0: opcode = 0; break; case 1: opcode = 5; break; case 2: opcode = 3; break; default: break; //should never been reached } RefinementPartition rp(op1, op2); result.Resize(rp.Size()); result.StartBulkLoad(); for(unsigned int i = 0; i < rp.Size(); i++) { vector uv; uv.clear(); Interval iv; int u1Pos; int u2Pos; rp.Get(i, iv, u1Pos, u2Pos); if (u1Pos == -1 || u2Pos == -1) continue; UReal u1; UReal u2; op1.Get(u1Pos, u1); op2.Get(u2Pos, u2); if(!(u1.IsDefined() || !u2.IsDefined())) { cerr << __PRETTY_FUNCTION__ << " encountered undefined unit within a mapping:" << endl; continue; } u1.CompUReal(u2, opcode, uv); for (size_t i = 0;i < uv.size();i++) result.MergeAdd(uv[i]); uv.clear(); } result.EndBulkLoad(false); } /* static void MovingRealCompareMM2(MReal& op1, MReal& op2, MBool& result, int op) { if(TLA_DEBUG) cout<<"MovingRealCompareMM called"< rp(op1, op2); if(TLA_DEBUG) cout<<"Refinement finished, rp.size: "< iv; int u1Pos; int u2Pos; const UReal *u1transfer; const UReal *u2transfer; UReal u1(true); UReal u2(true); rp.Get(i, iv, u1Pos, u2Pos); if (u1Pos == -1 || u2Pos == -1) continue; if(TLA_DEBUG) cout<<"Both operators existant in interval iv # "<IsDefined() && u2transfer->IsDefined())) continue; u1 = *u1transfer; u2 = *u2transfer; ShiftUReal(u1, iv.start); ShiftUReal(u2, iv.tart); u1.timeInterval = iv; u2.timeInterval = iv; //new Periods p(2); UBool uBool(true); CcReal u1real, u2real; Interval ivt; //cout << u1.a << " " << u1.b << " " << u1.c << endl; //cout << u2.a << " " << u2.b << " " << u2.c << endl; //if ( (u1.a == u2.a) && (u1.b == u2.b) && (u1.c == u2.c) ) if ( u1 == u2 ) { if(TLA_DEBUG) cout << "equalureal" << endl; uBool.timeInterval.start = iv.start; uBool.timeInterval.end = iv.end; uBool.timeInterval.lc = iv.lc; uBool.timeInterval.rc = iv.rc; if ( (op == 0) || (op == -1) ||(op == 1) ) uBool.constValue.Set(true, true); else uBool.constValue.Set(true, false); result.MergeAdd(uBool); } else { int number2 = u1.PeriodsAtEqual( u2, p); //cout << "number2= " << number2 << endl; //cout << "iv.lc= " << iv.lc << endl; //cout << "iv.rc= " << iv.rc << endl; //const Interval* iv2; //p.Get(0, iv2); //cout << "iv2end " << iv2->end.ToString() << endl; //cout << "iv2start " << iv2->start.ToString() << endl; //cout << "ivend " << iv.end.ToString() << endl; //cout << "ivstart " << iv.start.ToString() << endl; uBool.timeInterval.start = iv.start; uBool.timeInterval.lc = iv.lc; if ( number2 > 0 ) { p.Get(0, ivt); //cout << "number > 2 " << ivt.lc << endl; if ( !(((ivt.end == iv.end) && (iv.rc == false)) || ( (ivt.end == iv.start) && (iv.lc == true))) ) { //cout << "number > 2 (inner)" << endl; uBool.timeInterval.end = ivt.start; uBool.timeInterval.rc = false; if ( op == 0 ) uBool.constValue.Set(true, false); if (op == -3 ) uBool.constValue.Set(true, true); if ( (op == -2) || (op == -1) ) { u1.TemporalFunction(iv.start, u1real); u2.TemporalFunction(iv.start, u2real); if ( u1real.GetRealval() < u2real.GetRealval() ) uBool.constValue.Set(true, true); else uBool.constValue.Set(true, false); } if ( (op == 2) || (op == 1) ) { u1.TemporalFunction(iv.start, u1real); u2.TemporalFunction(iv.start, u2real); if ( u1real.GetRealval() > u2real.GetRealval() ) uBool.constValue.Set(true, true); else uBool.constValue.Set(true, false); } result.MergeAdd(uBool); uBool.timeInterval.start = ivt.start; uBool.timeInterval.end = ivt.end; uBool.timeInterval.lc = true; uBool.timeInterval.rc = true; if ( (op == 0) || (op == -1) || (op == 1) ) uBool.constValue.Set(true, true); if ( (op == -3) || (op == -2) || (op == 2) ) uBool.constValue.Set(true, false); result.MergeAdd(uBool); if ( number2 > 1 ) { //not yet implemented assert(true); } uBool.timeInterval.start = ivt.end; uBool.timeInterval.lc = false; } } //if number2 > 0 uBool.timeInterval.end = iv.end; uBool.timeInterval.rc = iv.rc; if ( op == 0 ) uBool.constValue.Set(true, false); if (op == -3 ) uBool.constValue.Set(true, true); //vector vureal; if ( (op == -2) || (op == -1) ) { //u1.AtMin(vureal); //cout << "was i here ? " << endl; u1.TemporalFunction(iv.end, u1real, true); u2.TemporalFunction(iv.end, u2real, true); //cout << u1real.GetRealval() << " < " << u2real.GetRealval() << endl; if ( u1real.GetRealval() < u2real.GetRealval() ) uBool.constValue.Set(true, true); else uBool.constValue.Set(true, false); } if ( (op == 2) || (op == 1) ) { u1.TemporalFunction(iv.end, u1real, true); u2.TemporalFunction(iv.end, u2real, true); if ( u1real.GetRealval() > u2real.GetRealval() ) uBool.constValue.Set(true, true); else uBool.constValue.Set(true, false); } result.MergeAdd(uBool); //cout << ivt.start.ToString() << endl; //cout << ivt.end.ToString() << endl; } } result.EndBulkLoad(false); } */ /* 1.1 Method ~MovingRealCompareMM~ Returns true if the value of these two mReals holds the comparison. The comparisons are -3: \#; -2: <; -1: <=; 0: =; 1: >=; 2: >. */ /*static void MovingRealCompareMM(MReal& op1, MReal& op2, MBool& result, int op) { if(TLA_DEBUG) cout<<"MovingRealCompareMM called"< rp(op1, op2); if(TLA_DEBUG) cout<<"Refinement finished, rp.size: "< iv; int u1Pos; int u2Pos; const UReal *u1transfer; const UReal *u2transfer; UReal u1(true); UReal u2(true); rp.Get(i, iv, u1Pos, u2Pos); if (u1Pos == -1 || u2Pos == -1) continue; if(TLA_DEBUG) cout<<"Both operators existant in interval iv # "<IsDefined() && u2transfer->IsDefined())) continue; u1 = *u1transfer; u2 = *u2transfer; ShiftUReal(u1, iv.start); ShiftUReal(u2, iv.start); u1.timeInterval = *iv; u2.timeInterval = *iv; Instant t[4]; Instant middle; int counter = 0; int number = FindEqualTimes4Real(u1, u2, t); //new Periods p(2); UBool uBool2(true); CcReal u1real, u2real; const Interval* ivt; int number2 = u1.PeriodsAtEqual( u2, p); uBool2.timeInterval.start = iv.start; uBool2.timeInterval.lc = true; if ( number2 > 0 ) { p.Get(0, ivt); uBool2.timeInterval.end = ivt->start; uBool2.timeInterval.rc = false; if ( op == 0 ) uBool2.constValue.Set(true, false); if (op == -3 ) uBool2.constValue.Set(true, true); if ( (op == -2) || (op == -1) ) { u1.TemporalFunction(iv.start, u1real); u2.TemporalFunction(iv.start, u2real); if ( u1real.GetRealval() < u2real.GetRealval() ) uBool2.constValue.Set(true, true); else uBool2.constValue.Set(true, false); } if ( (op == 2) || (op == 1) ) { u1.TemporalFunction(iv.start, u1real); u2.TemporalFunction(iv.start, u2real); if ( u1real.GetRealval() < u2real.GetRealval() ) uBool2.constValue.Set(true, false); else uBool2.constValue.Set(true, true); } result.MergeAdd(uBool2); uBool2.timeInterval.start = ivt->start; uBool2.timeInterval.end = ivt->end; uBool2.timeInterval.lc = true; uBool2.timeInterval.rc = true; if ( (op == 0) || (op == -1) || (op == 1) ) uBool2.constValue.Set(true, true); if ( (op == -3) || (op == -2) || (op == 2) ) uBool2.constValue.Set(true, false); result.MergeAdd(uBool2); if ( number2 > 1 ) { } uBool2.timeInterval.start = ivt->start; uBool2.timeInterval.lc = false; } uBool2.timeInterval.end = iv.end; uBool2.timeInterval.rc = true; if ( op == 0 ) uBool2.constValue.Set(true, false); if (op == -3 ) uBool2.constValue.Set(true, true); if ( (op == -2) || (op == -1) ) { u1.TemporalFunction(iv.end, u1real); u2.TemporalFunction(iv.end, u2real); if ( u1real.GetRealval() < u2real.GetRealval() ) uBool2.constValue.Set(true, true); else uBool2.constValue.Set(true, false); } if ( (op == 2) || (op == 1) ) { u1.TemporalFunction(iv.end, u1real); u2.TemporalFunction(iv.end, u2real); if ( u1real.GetRealval() < u2real.GetRealval() ) uBool2.constValue.Set(true, false); else uBool2.constValue.Set(true, true); } result.MergeAdd(uBool2); cout << ivt->start.ToString() << endl; cout << ivt->end.ToString() << endl; // for (int m = 0; m < number; m++) { t[m].SetType(instanttype); if ((*iv).Contains(t[m])) { if(TLA_DEBUG) cout< rp(op1, op2); if(TLA_DEBUG) cout<<"Refinement finished, rp.size: "< iv; int u1Pos; int u2Pos; UReal u1transfer; UReal u2transfer; UReal u1(true); UReal u2(true); rp.Get(i, iv, u1Pos, u2Pos); if (u1Pos == -1 || u2Pos == -1 ) continue; else { if(TLA_DEBUG) cout<<"Both operators existant in interval iv #"< iv.start || iv.lc) && (t[m] < iv.end || iv.rc)){ if(TLA_DEBUG) cout<<"add point"< iv.start){ un = u1; un.timeInterval = iv; un.timeInterval.end = t[0]; un.timeInterval.rc = false; if(TLA_DEBUG) cout<<"add first interval ["<=; 2: >. */ static void MovingRealCompareMS(const MReal& op1, const CcReal& op2, MBool& result, int op, bool ms) { if(TLA_DEBUG) cout<<"MovingRealCompareMS called"<Resize(op1.GetNoComponents()); mop2->StartBulkLoad(); for (int i = 0; i < op1.GetNoComponents(); i++) { op1.Get(i, up1); if(!(up1.IsDefined() && op2.IsDefined())) continue; UReal *up2 = new UReal(up1.timeInterval, 0.0, 0.0, up1.r ? pow(op2.GetRealval(),2) : op2.GetRealval(), up1.r); mop2->Add(*up2); delete up2; } mop2->EndBulkLoad(false); if ( ms ) MovingRealCompareMM2(op1, *mop2, result, op); else MovingRealCompareMM2(*mop2, op1, result, op); mop2->DeleteIfAllowed(); } /* 1.1 Method ~MPointInsideLine~ calcultates the periods where the given MPoint lies inside the given Line. It return the existing intervals in a Periods-Object. */ static void MPointInsideLine(const MPoint& mp, const Line& ln, Periods& pResult) { if(TLA_DEBUG) cout<<"MPointLineInside called"< newper; //part of the result for( int i = 0; i < mp.GetNoComponents(); i++) { mp.Get(i, up); if(TLA_DEBUG){ cout<<"UPoint # "<("<("< continue"< up.p0.GetX() && l.GetLeftPoint().GetX() > up.p1.GetX()) || (l.GetRightPoint().GetY() < up.p0.GetY() && l.GetRightPoint().GetY() < up.p1.GetY() && (l.GetLeftPoint().GetY() < up.p0.GetY() && l.GetLeftPoint().GetY() < up.p1.GetY())) || (l.GetRightPoint().GetY() > up.p0.GetY() && l.GetRightPoint().GetY() > up.p1.GetY() && (l.GetLeftPoint().GetY() > up.p0.GetY() && l.GetLeftPoint().GetY() > up.p1.GetY()))) { if(TLA_DEBUG) cout<<"Bounding Boxes not crossing!"< l.GetRightPoint().GetY() && up.p0.GetY() > l.GetRightPoint().GetY()){ if(TLA_DEBUG) cout<<"uPoint higher as linesegment"<= l.GetLeftPoint().GetY()){ if(TLA_DEBUG) cout<<"uPoint starts below linesegemet"<= l.GetLeftPoint().GetY()){ if(TLA_DEBUG) cout<<"uPoint ends below linesegemet"<= l.GetRightPoint().GetY()){ if(TLA_DEBUG) cout<<"uPoint ends above linesegemet"<= l.GetRightPoint().GetY()){ if(TLA_DEBUG) cout<<"uPoint starts above linesegemet"<= l.GetLeftPoint().GetY()){ if(TLA_DEBUG) cout<<"uPoint starts inside linesegemet"<= l.GetLeftPoint().GetY()){ if(TLA_DEBUG) cout<<"uPoint ends inside linesegemet"< t|| up.timeInterval.end < t){ if(TLA_DEBUG) cout<<"up outside line"< l.GetRightPoint().GetX() || (pt.GetY() < l.GetLeftPoint().GetY() && pt.GetY() < l.GetRightPoint().GetY()) || (pt.GetY() > l.GetLeftPoint().GetY() && pt.GetY() > l.GetRightPoint().GetY())){ if(TLA_DEBUG) cout<<"pt outside up!"< t|| up.timeInterval.end < t){ if(TLA_DEBUG) cout<<"up outside line"< l.GetRightPoint().GetX() || (pt.GetY() < l.GetLeftPoint().GetY() && pt.GetY() < l.GetRightPoint().GetY()) || (pt.GetY() > l.GetLeftPoint().GetY() && pt.GetY() > l.GetRightPoint().GetY())){ if(TLA_DEBUG) cout<<"pt outside up!"<= l.GetLeftPoint().GetX()){ if(TLA_DEBUG) cout<<"uPoint starts left of linesegemet"<= l.GetLeftPoint().GetX()){ if(TLA_DEBUG) cout<<"uPoint ends left of linesegemet"<= l.GetRightPoint().GetX()){ if(TLA_DEBUG) cout<<"uPoint ends right of linesegemet"<= l.GetRightPoint().GetX()){ if(TLA_DEBUG) cout<<"uPoint starts right of linesegemet"<= l.GetLeftPoint().GetX()){ if(TLA_DEBUG) cout<<"uPoint starts inside linesegemet"<= l.GetLeftPoint().GetX()){ if(TLA_DEBUG) cout<<"uPoint ends inside linesegemet"< t|| up.timeInterval.end < t){ if(TLA_DEBUG) cout<<"up outside line"< l.GetRightPoint().GetX() || (pt.GetY() < l.GetLeftPoint().GetY() && pt.GetY() < l.GetRightPoint().GetY()) || (pt.GetY() > l.GetLeftPoint().GetY() && pt.GetY() > l.GetRightPoint().GetY())){ if(TLA_DEBUG) cout<<"pt outside up!"<Clear(); period->StartBulkLoad(); period->Add(newper); period->EndBulkLoad(false); if (!pResult.IsEmpty()) { between->Clear(); period->Union(pResult, *between); pResult.Clear(); pResult.CopyFrom(between); } else pResult.CopyFrom(period); } } between->DeleteIfAllowed(); period->DeleteIfAllowed(); } /* 1.1 Method ~MPointInMPoint~ Checks whether the two mpoints are crossing. It returns -1.0 if the mpoints are not crossing and 2.0 if both mpoints are equal all the time. In all other cases it returns the fraction of iv when mpoints are crossing (0.0 .. 1.0). */ double MPointInMPoint(double startx1, double starty1, double endx1, double endy1, double startx2, double starty2, double endx2, double endy2){ if(AlmostEqual(startx1, startx2) && AlmostEqual(starty1, starty2) && AlmostEqual(endx1, endx2) && AlmostEqual(endy1, endy2)) return 2.0; else if(AlmostEqual(startx1, startx2) && AlmostEqual(starty1, starty2)) return 0.0; else if(AlmostEqual(endx1, endx2) && AlmostEqual(endy1, endy2)) return 1.0; else { double dx = endx1 - startx1 - endx2 + startx2; double dy = endy1 - starty1 - endy2 + starty2; double tx = 0.0; double ty = 0.0; bool vert = false; bool hor = false; if (dx == 0.0) vert = true; else tx = (startx2 - startx1) / dx; if (dy == 0.0) hor = true; else ty = (starty2 - starty1) / dy; if (hor) { if ((starty1 <= starty2 && starty1 >= endy2) || (starty1 <= endy2 && starty1 >= starty2) || (endy1 <= starty2 && endy1 >= endy2) || (endy1 <= endy2 && endy1 >= starty2) || (starty2 <= starty1 && starty2 >= endy1) || (starty2 <= endy1 && starty2 >= starty1) || (endy2 <= starty1 && endy2 >= endy1) || (endy2 <= endy1 && endy2 >= starty1)) ty = tx; else ty = -1.0; } else if (vert) { if ((startx1 <= startx2 && startx1 >= endx2) || (startx1 <= endx2 && startx1 >= startx2) || (endx1 <= startx2 && endx1 >= endx2) || (endx1 <= endx2 && endx1 >= startx2) || (startx2 <= startx1 && startx2 >= endx1) || (startx2 <= endx1 && startx2 >= startx1) || (endx2 <= startx1 && endx2 >= endx1) || (endx2 <= endx1 && endx2 >= startx1)) tx = ty; else tx = -1.0; } if(AlmostEqual(tx, ty) && tx > 0.0 && tx < 1.0) return tx; else return -1.0; } return -1.0; //should not be reached! } /* 1.1 Auxiliary function for comparing two mobing points */ enum deltaInterpretation {VALUE, ALWAYS, NEVER}; struct deltaV{ deltaV(deltaInterpretation i, double v): value(v), delta(i){} double value; deltaInterpretation delta; }; deltaV computeDelta(const double a1, const double a2, const double b1, const double b2){ // computes delta for // a1 + delta*(a2-a1) = b1 + delta*(b2-b1) // this holds ever, never or for a certain value double da = a2 - a1; double db = b2 - b1; double fdelta = da-db; double r = b1 - a1; if(AlmostEqual(fdelta,0.0)){ if(AlmostEqual(r,0.0)){ return deltaV(ALWAYS,0.0); } else { return deltaV(NEVER,0.0); } } else { return deltaV(VALUE, r/fdelta); } } deltaV merge(const deltaV& d1, const deltaV& d2){ switch(d1.delta){ case ALWAYS : return d2; case NEVER : return d1; case VALUE : switch(d2.delta){ case ALWAYS : return d1; case NEVER : return d2; case VALUE : if(AlmostEqual(d1.value,d2.value)){ return d1; } else { return deltaV(NEVER,0.0); } default : assert(false); } default : assert(false); } assert(false); return d1; } ostream& operator<<(ostream& o, const deltaInterpretation& i){ switch(i){ case ALWAYS : o << "always" ; break; case NEVER : o << "never" ; break; case VALUE : o << "value" ; break; } return o; } ostream& operator<<(ostream& o, const deltaV& d){ o << d.delta; if(d.delta==VALUE){ o << ":" << d.value; } return o; } void computeMEquality(const Interval& iv, const Point& p1_start, const Point& p1_end, const Point& p2_start, const Point& p2_end, MBool& result, const bool compValue){ result.Clear(); result.SetDefined(true); result.Resize(3); deltaV xd = computeDelta(p1_start.GetX(), p1_end.GetX(), p2_start.GetX(), p2_end.GetX()); deltaV yd = computeDelta(p1_start.GetY(), p1_end.GetY(), p2_start.GetY(), p2_end.GetY()); deltaV delta = merge(xd,yd); switch(delta.delta){ case ALWAYS : result.Add(UBool(iv, CcBool(true,compValue))); break; case NEVER : result.Add(UBool(iv,CcBool(true,!compValue))); break; case VALUE : { DateTime dur = iv.end - iv.start; dur.Mul(delta.value); DateTime ip(datetime::instanttype); ip = iv.start + dur; if( (ip < iv.start) || (ip > iv.end) || (ip==iv.start && !iv.lc) || (ip==iv.end && !iv.rc)){ // intersection outside time interval result. Add(UBool(iv,CcBool(true,!compValue))); } else if(ip==iv.start && ip==iv.end){ // intersection covers the whole interval result. Add(UBool(iv,CcBool(true,compValue))); } else if(ip==iv.start){ // common start Interval iv1(ip,ip,true,true); Interval iv2(ip,iv.end,false,iv.rc); result. Add(UBool(iv1,CcBool(true,compValue))); result. Add(UBool(iv2,CcBool(true,!compValue))); } else if(ip==iv.end){ Interval iv1(iv.start,ip, iv.lc,false); Interval iv2(ip,ip, true,true); result. Add(UBool(iv1,CcBool(true,!compValue))); result. Add(UBool(iv2,CcBool(true,compValue))); } else { // ip inside iv Interval iv1(iv.start,ip, iv.lc,false); Interval iv2(ip,ip,true,true); Interval iv3(ip,iv.end, false,iv.rc); result. Add(UBool(iv1,CcBool(true,!compValue))); result. Add(UBool(iv2,CcBool(true,compValue))); result. Add(UBool(iv3,CcBool(true,!compValue))); } } break; default : assert(false); } } /* 1.1 Method ~MovingPointCompareMM~ For Operators ~=~ , ~\#~ for MovingPoint/MovingPoint */ void MovingPointCompareMM( const MPoint& p1, const MPoint& p2, MBool& result, int op) { result.Clear(); if(!p1.IsDefined() || !p2.IsDefined()){ result.SetDefined(false); return; } RefinementStream rs(&p1,&p2); Interval iv; int pos1; int pos2; UPoint unit1(false); UPoint unit2(false); MBool tmp(3); Point p1_start(true,0,0); Point p1_end(true,0,0); Point p2_start(true,0,0); Point p2_end(true,0,0); bool compValue = op==0?true:false; UBool unit; result.StartBulkLoad(); while(rs.hasNext()){ rs.getNext(iv,pos1,pos2); if(pos1>=0 && pos2>=0){ p1.Get(pos1,unit1); p2.Get(pos2,unit2); unit1.TemporalFunction(iv.start,p1_start,true); unit1.TemporalFunction(iv.end,p1_end,true); unit2.TemporalFunction(iv.start,p2_start,true); unit2.TemporalFunction(iv.end,p2_end,true); computeMEquality(iv, p1_start,p1_end, p2_start, p2_end, tmp, compValue); for(int i=0;i iv; UPoint u1; p1.Get(i, u1); if(!(u1.IsDefined() && p2.IsDefined())) continue; iv = u1.timeInterval; if(TLA_DEBUG){ cout<< "Compare interval #"<< i<< ": "<< iv.start.ToString()<< " " << iv.end.ToString()<< " "<< iv.lc<< endl;} Point rp0, rp1; double t = MPointInMPoint(u1.p0.GetX(), u1.p0.GetY(), u1.p1.GetX(), u1.p1.GetY(), p2.GetX(), p2.GetY(), p2.GetX(), p2.GetY()); if(TLA_DEBUG) cout<<"t "< 0.0 && t < 1.0) { Instant time(instanttype); time.ReadFrom(t * (iv.end.ToDouble() - iv.start.ToDouble()) + iv.start.ToDouble()); time.SetType(instanttype); if (iv.Contains(time)) { uBool.timeInterval = iv; uBool.timeInterval.rc = false; uBool.timeInterval.end = time; uBool.constValue.Set(true, op == 0 ? false : true); if(uBool.IsValid()) result.MergeAdd( uBool ); uBool.timeInterval.rc = true; uBool.timeInterval.start = time; uBool.timeInterval.lc = true; uBool.constValue.Set(true, op == 0 ? true : false); result.MergeAdd( uBool ); uBool.timeInterval.lc = false; uBool.timeInterval.rc = iv.rc; uBool.timeInterval.end = iv.end; uBool.constValue.Set(true, op == 0 ? false : true); if(uBool.IsValid()) result.MergeAdd( uBool ); } else{ uBool.timeInterval = iv; uBool.constValue.Set(true, op == 0 ? false : true); result.MergeAdd( uBool ); } } else { uBool.timeInterval = iv; uBool.constValue.Set(true, op == 0 ? false : true); result.MergeAdd( uBool ); } } result.EndBulkLoad( false ); } /* 1.1 Method ~MovingRegionCompareMS~ For Operators ~=~, ~\#~ and ~minus~ forMovingRegion/Region */ void MovingRegionCompareMS( MRegion *mr, const Region *r, MBool *result, int op) { assert( mr ); assert( r ); assert( result ); result->Clear(); if( !mr->IsDefined() || !r->IsDefined() ) { result->SetDefined( false ); } result->SetDefined( true ); URegionEmb ur; UBool uBool(true); //Part of the result result->StartBulkLoad(); if(TLA_DEBUG) cout<<"MovingRegionCompareMS called"<GetNoComponents(); i++){ mr->Get(i, ur); if(!(ur.IsValid() && r->IsDefined())) continue; int number = ur.GetSegmentsNum(); if(TLA_DEBUG){ cout<<"URegion # "<Size(); int middle; while(!found && left != right){ middle = (left + right) / 2; r->Get(middle, mid); if(mid == *nHS) found = true; else if(mid < *nHS){ left = middle; } else{ right = middle; } } if(!found){ if(TLA_DEBUG) cout<<"no matching Halfsegment -> Unit not equal!!"< Unit is equal!!"<MergeAdd(uBool); } else if(finish){ uBool.timeInterval = ur.timeInterval; uBool.constValue.Set(true, (op == 0) ? false : true); if(TLA_DEBUG){ cout<<"a static s with no matching HS -> unit not equal!" <MergeAdd(uBool); } else{ //the complicate way with not static mregions HalfSegment chs; Periods* period = new Periods(0); Periods* between = new Periods(0); Periods* pResult = new Periods(0); Interval newper; //part of the result for(int i = 0 ;i < r->Size(); i++){ r->Get(i, chs); double tsd = MPointInMPoint(dms.GetInitialStartX(), dms.GetInitialStartY(), dms.GetFinalStartX(), dms.GetFinalStartY(), chs.GetDomPoint().GetX(), chs.GetDomPoint().GetY(), chs.GetDomPoint().GetX(), chs.GetDomPoint().GetY()); double ted = MPointInMPoint(dms.GetInitialEndX(), dms.GetInitialEndY(), dms.GetFinalEndX(), dms.GetFinalEndY(), chs.GetDomPoint().GetX(), chs.GetDomPoint().GetY(), chs.GetDomPoint().GetX(), chs.GetDomPoint().GetY()); double tss = MPointInMPoint(dms.GetInitialStartX(), dms.GetInitialStartY(), dms.GetFinalStartX(), dms.GetFinalStartY(), chs.GetSecPoint().GetX(), chs.GetSecPoint().GetY(), chs.GetSecPoint().GetX(), chs.GetSecPoint().GetY()); double tes = MPointInMPoint(dms.GetInitialEndX(), dms.GetInitialEndY(), dms.GetFinalEndX(), dms.GetFinalEndY(), chs.GetSecPoint().GetX(), chs.GetSecPoint().GetY(), chs.GetSecPoint().GetX(), chs.GetSecPoint().GetY()); double tpoint = -1.0; if(tsd >= 0.0 && tes >= 0.0){ if(TLA_DEBUG) cout<<"start through dominant, end through subdominat"<= 0.0 && ted >= 0.0){ if(TLA_DEBUG) cout<<"start through subdominant, end through dominat"< 0.0 && tpoint < 1.0) || (tpoint == 0.0 && ur.timeInterval.lc) || (tpoint == 1.0 && ur.timeInterval.rc)){ Instant t(instanttype); t.ReadFrom((ur.timeInterval.end.ToDouble() - ur.timeInterval.start.ToDouble()) * tpoint + ur.timeInterval.start.ToDouble()); t.SetType(instanttype); newper.start = t; newper.end = t; newper.lc = true; newper.rc = true; if(TLA_DEBUG) cout<<"newper ["<< newper.start.ToString() <<" " <Clear(); period->StartBulkLoad(); period->Add(newper); period->EndBulkLoad(false); if (!pResult->IsEmpty()) { between->Clear(); period->Union(*pResult, *between); pResult->Clear(); pResult->CopyFrom(between); } else pResult->CopyFrom(period); } } period->DeleteIfAllowed(); between->DeleteIfAllowed(); Interval per; for(int i = 0; i < pResult->GetNoComponents(); i++){ Region snapshot(0); if(TLA_DEBUG) cout<<"add interval # "<Get(i, per); ur.TemporalFunction(mr->GetMSegmentData(), per.start, snapshot, true); if(*r == snapshot){ if(TLA_DEBUG) cout<<"r == snapshot!"< ur.timeInterval.start){ uBool.timeInterval.start = ur.timeInterval.start; uBool.timeInterval.lc = ur.timeInterval.lc; uBool.timeInterval.end = per.start; uBool.timeInterval.rc = !per.rc; uBool.constValue.Set(true, (op == 0) ? false : true); if(TLA_DEBUG) cout<<"uBool "<MergeAdd(uBool); } uBool.timeInterval = per; uBool.constValue.Set(true, (op == 0) ? true : false); if(TLA_DEBUG) cout<<"uBool "<MergeAdd(uBool); if(per.end < ur.timeInterval.end){ uBool.timeInterval.start = per.end; uBool.timeInterval.lc = !per.lc; uBool.timeInterval.end = ur.timeInterval.end; uBool.timeInterval.rc = ur.timeInterval.rc; uBool.constValue.Set(true, (op == 0) ? false : true); if(TLA_DEBUG) cout<<"uBool "<MergeAdd(uBool); } } else if(TLA_DEBUG) cout<<"r != snapshot"<DeleteIfAllowed(); } } result->EndBulkLoad(false); } /* 1.1 Method ~MovingRegionCompareMM~ For Operators ~=~ and ~\#~ and MovingRegion/Region */ void MovingRegionCompareMM( MRegion *mr1, MRegion *mr2, MBool *result, int op) { assert( mr1 ); assert( mr2 ); assert( result ); if(TLA_DEBUG) cout<<"MovingRegionCompareMM called"<Clear(); if( !mr1->IsDefined() || !mr2->IsDefined() ) { result->SetDefined( false ); } result->SetDefined( true ); RefinementPartition rp(*mr1, *mr2); if(TLA_DEBUG) cout<<"RefimentPartiion done with size "< iv; int reg1Pos; int reg2Pos; UBool uBool(true); result->Resize(rp.Size()); result->StartBulkLoad(); for( unsigned int i = 0; i < rp.Size(); i++ ){ rp.Get(i, iv, reg1Pos, reg2Pos); if(TLA_DEBUG) cout<<"interval # "<Get(reg1Pos, ureg1); mr2->Get(reg2Pos, ureg2); if(!(ureg1.IsValid() && ureg2.IsValid())) continue; if(ureg1.GetSegmentsNum() != ureg1.GetSegmentsNum()){ uBool.timeInterval = iv; uBool.constValue.Set(true, op == 0 ? false : true); if(TLA_DEBUG){ cout<<"uregions have different numbers of segments -> iv not equal"; cout<MergeAdd(uBool); continue; } if((ureg1.GetSegmentsNum() == 0)&&(ureg1.GetSegmentsNum() == 0)){ uBool.timeInterval = iv; uBool.constValue.Set(true, op == 0 ? true : false); if(TLA_DEBUG){ cout<<"both uregions have no segments -> iv equal"<MergeAdd(uBool); continue; } //find possible times of equality MSegmentData dms1; Periods* period = new Periods(0); Periods* between = new Periods(0); Periods* pResult = new Periods(0); Interval newper; //part of the result bool uregionPerhapsEqual = false; MSegmentData rdms1; ureg1.GetSegment(mr1->GetMSegmentData(), 0, dms1); dms1.restrictToInterval(ureg1.timeInterval, iv, rdms1); pResult->Clear(); for(int n = 0; n < ureg2.GetSegmentsNum(); n++){ MSegmentData dms2; MSegmentData rdms2; ureg2.GetSegment(mr2->GetMSegmentData(), n, dms2); dms2.restrictToInterval(ureg2.timeInterval, iv, rdms2); double ts = MPointInMPoint( rdms1.GetInitialStartX(), rdms1.GetInitialStartY(), rdms1.GetFinalStartX(), rdms1.GetFinalStartY(), rdms2.GetInitialStartX(), rdms2.GetInitialStartY(), rdms2.GetFinalStartX(), rdms2.GetFinalStartY()); double te = MPointInMPoint( rdms1.GetInitialEndX(), rdms1.GetInitialEndY(), rdms1.GetFinalEndX(), rdms1.GetFinalEndY(), rdms2.GetInitialEndX(), rdms2.GetInitialEndY(), rdms2.GetFinalEndX(), rdms2.GetFinalEndY()); if(ts == 2.0 && te == 2.0){ if(TLA_DEBUG) cout<<"uregions are possibly totaly equal"<=0.0) && (ts <= 1.0) && AlmostEqual(ts, te)) || (ts == 2.0 && (te >=0.0) && (te <= 1.0)) || (te == 2.0 && (ts >=0.0) && (ts <= 1.0))){ if(TLA_DEBUG) cout<<"equality found at t "<=0.0) && (te <= 1.0)) ts = te; if((ts == 0.0 && !iv.lc) || (ts == 1.0 && !iv.rc)) continue; Instant t(instanttype); t.ReadFrom((iv.end.ToDouble() - iv.start.ToDouble()) * ts + iv.start.ToDouble()); t.SetType(instanttype); newper.start = t; newper.end = t; newper.lc = true; newper.rc = true; if(TLA_DEBUG){ cout<<"newper ["<< newper.start.ToString()<<" "<Clear(); period->StartBulkLoad(); period->Add(newper); period->EndBulkLoad(false); if (!pResult->IsEmpty()) { between->Clear(); period->Union(*pResult, *between); pResult->Clear(); pResult->CopyFrom(between); } else pResult->CopyFrom(period); } } period->DeleteIfAllowed(); between->DeleteIfAllowed(); if(uregionPerhapsEqual){ /* test for eaquality of total uregion. This can not be done at start and end of interval,because they are probably not inside the interval. So it is used the 10 and 90 percent time of the uregion. */ Region snapshot1(0); Region snapshot2(0); if(TLA_DEBUG) cout<<"uregions are possibly equal. Create snapshots"<GetMSegmentData(), time, snapshot1, true); ureg2.TemporalFunction(mr2->GetMSegmentData(), time, snapshot2, true); if(snapshot1 == snapshot2){ if(TLA_DEBUG) cout<<"snapshots of iv->start are equal"<GetMSegmentData(), time, snapshot1, true); ureg2.TemporalFunction(mr2->GetMSegmentData(), time, snapshot2, true); if(snapshot1 == snapshot2){ uBool.timeInterval = iv; uBool.constValue.Set(true, op == 0 ? true : false); if(TLA_DEBUG){ cout<<"snapshots of iv->end are equal, too."<MergeAdd(uBool); continue; } else if(TLA_DEBUG){ cout<<"snapshots of iv->end are not equal," <<" uregions are not equal"<start are not equal," <<" uregegions are not equal"< per; bool finished = false; for(int i = 0; i < pResult->GetNoComponents(); i++){ Region snapshot1(0); Region snapshot2(0); pResult->Get(i, per); if(TLA_DEBUG) cout<<"test time # "<GetMSegmentData(),per.start,snapshot1,true); ureg2.TemporalFunction(mr2->GetMSegmentData(),per.start,snapshot2,true); if(snapshot1 == snapshot2){ if(TLA_DEBUG) cout<<"snapshot equal!"< iv.start){ uBool.timeInterval.start = iv.start; uBool.timeInterval.lc = iv.lc; uBool.timeInterval.end = per.start; uBool.timeInterval.rc = !per.rc; uBool.constValue.Set(true, (op == 0) ? false : true); if(TLA_DEBUG){ cout<<"uBool "<MergeAdd(uBool); } uBool.timeInterval = per; uBool.constValue.Set(true, (op == 0) ? true : false); if(TLA_DEBUG){ cout<<"uBool "<MergeAdd(uBool); if(per.end < iv.end){ uBool.timeInterval.start = per.end; uBool.timeInterval.lc = !per.lc; uBool.timeInterval.end = iv.end; uBool.timeInterval.rc = iv.rc; uBool.constValue.Set(true, (op == 0) ? false : true); if(TLA_DEBUG){ cout<<"uBool "<MergeAdd(uBool); } finished = true; break; } else if(TLA_DEBUG) cout<<"snapshot not equal"<DeleteIfAllowed(); if(!finished){ uBool.timeInterval = iv; uBool.constValue.Set(true, (op == 0) ? false : true); if(TLA_DEBUG){ cout<<"uBool "<MergeAdd(uBool); } } result->EndBulkLoad(false); } /* 1.1 Method ~CompletePeriods2MBool~ Completes a Periods-value to a MBool-value. For this it puts the intervals in pResult as uBool with value ~true~ and adds the difference to the MPoint- intervals with ~false~. */ static void CompletePeriods2MBool( const MPoint* mp, const Periods* pResult, MBool* endResult){ assert( mp ); assert( pResult ); assert( endResult ); endResult->Clear(); if( !mp->IsDefined() || !pResult->IsDefined() ){ endResult->SetDefined( false ); return; } endResult->SetDefined( true ); endResult->StartBulkLoad(); Interval per; UPoint up; UBool uBool(true); int m = 0; bool pfinished = (pResult->GetNoComponents() == 0); for ( int i = 0; i < mp->GetNoComponents(); i++) { mp->Get(i, up); if(!up.IsDefined()) continue; if(TLA_DEBUG){ cout<<"UPoint # "<(" <Get(m, per); if(TLA_DEBUG){ cout<<"per "<MergeAdd(uBool); } else { if(TLA_DEBUG) cout<<"per not after before up"<MergeAdd(uBool); uBool.timeInterval = per; } else { if(TLA_DEBUG) cout<<"per starts before or with up"<MergeAdd(uBool); break; } else { uBool.timeInterval.end = per.end; uBool.timeInterval.rc = per.rc; if(TLA_DEBUG){ cout<<"per ends inside up"<MergeAdd(uBool); } uBool.timeInterval.start = per.end; uBool.timeInterval.lc = !per.rc; if(m == pResult->GetNoComponents() - 1){ pfinished = true; } else { pResult->Get(++m, per); if(TLA_DEBUG){ cout<<"per "<MergeAdd(uBool); uBool.timeInterval.start = per.start; uBool.timeInterval.lc = per.lc; } else { if(TLA_DEBUG) cout<<"next interval after up -> finish up"< uBool.timeInterval.start || (uBool.timeInterval.rc && uBool.timeInterval.lc)) { if(TLA_DEBUG){ cout<<"MergeAdd5 "<MergeAdd(uBool); } break; } } //while } } endResult->EndBulkLoad(false); } /* 1.1 Method ~CompletePeriods2MPoint~ Completes a Periods-value to a MPoint-value. For this it adds the starting and end points. */ static void CompletePeriods2MPoint( const MPoint* mp, const Periods* pResult, MPoint* endResult){ if(TLA_DEBUG) cout<<"CompletePeriods2MPoint called"<Clear(); if( !mp->IsDefined() || !pResult->IsDefined() ){ endResult->SetDefined( false ); return; } endResult->SetDefined( true ); UPoint up; endResult->StartBulkLoad(); Interval per; UPoint newUp(true); Point pt; int m = 0; bool pfinished = (pResult->GetNoComponents() == 0); for ( int i = 0; i < mp->GetNoComponents(); i++) { mp->Get(i, up); if(!up.IsDefined()) continue; if(TLA_DEBUG){ cout<<"UPoint # "<(" <Get(m, per); if(TLA_DEBUG){ cout<<"per "<("<Add(newUp); break; } else { if(TLA_DEBUG) cout<<"per ends inside up"<("<Add(newUp); } if(m == pResult->GetNoComponents() - 1){ if(TLA_DEBUG) cout<<"last per"<Get(++m, per); if(TLA_DEBUG){ cout<<"per "< finish up"<EndBulkLoad(false); } /* 1.1 Method ~MPointInsidePoints~ Calcultates the periods where the given MPoint lies inside the given Points. It return the existing intervals in a Periods-Object. */ static void MPointInsidePoints( const MPoint& mp, const Points& ps, Periods& pResult) { if(TLA_DEBUG) cout<<"MPointPointsInside called"< newper; //part of the result bool newtime; for( int i = 0; i < mp.GetNoComponents(); i++) { mp.Get(i, up); if(!up.IsDefined()) continue; for( int n = 0; n < ps.Size(); n++) { newtime = false; ps.Get(n, p); if(!p.IsDefined()) continue; double time = MPointInMPoint(up.p0.GetX(), up.p0.GetY(), up.p1.GetX(), up.p1.GetY(), p.GetX(), p.GetY(), p.GetX(), p.GetY()); if(time == 2.0){ newper = up.timeInterval; newtime = true; } else if((time > 0.0 && time < 1.0) || (time == 0.0 && up.timeInterval.lc) || (time == 1.0 && up.timeInterval.rc)){ Instant t(instanttype); t.ReadFrom((up.timeInterval.end.ToDouble() - up.timeInterval.start.ToDouble()) * time + up.timeInterval.start.ToDouble()); t.SetType(instanttype); newper.start = t; newper.end = t; newper.lc = true; newper.rc = true; newtime = true; } if(TLA_DEBUG){ cout<<"newper ["<< newper.start.ToString()<<" " <Clear(); period->StartBulkLoad(); period->Add(newper); period->EndBulkLoad(false); if (!pResult.IsEmpty()) { between->Clear(); period->Union(pResult, *between); pResult.Clear(); pResult.CopyFrom(between); } else pResult.CopyFrom(period); } } } between->DeleteIfAllowed(); period->DeleteIfAllowed(); } /* 1.1 Method ~TransformMBool2MPoint~ Completes a MBool to a MPoint-value for the ~minus~ operator. For this it adds the starting and end points to every interval when mBool is not true, even when there is no mBool at all. */ static void TransformMBool2MPoint( const MPoint *mp, const MBool *mBool, MPoint *endResult) { assert( mp ); assert( mBool ); assert( endResult ); endResult->Clear(); if( !mp->IsDefined() || !mBool->IsDefined() ){ endResult->SetDefined( false ); return; } endResult->SetDefined( true ); UPoint up; endResult->Resize(mBool->GetNoComponents()); endResult->StartBulkLoad(); UBool ub; UPoint newUp(true); Point pt; int pos = 0; if(TLA_DEBUG) cout<<"TransformMBool2MPoint1 called"<GetNoComponents(); i++) { mBool->Get(i, ub); if(!ub.IsDefined()) continue; if(TLA_DEBUG) { cout<<"UBool # "<Get(pos, up); if(TLA_DEBUG) { cout<<"UPoint # "< ub.timeInterval.start || (up.timeInterval.end == ub.timeInterval.start && up.timeInterval.rc && ub.timeInterval.lc)) && pos < mp->GetNoComponents()) { pos++; mp->Get(pos, up); if(TLA_DEBUG) { cout<<"UPoint # "< ub.timeInterval.end) { //upoint ends after ubool newUp.timeInterval = ub.timeInterval; up.TemporalFunction(newUp.timeInterval.start, pt, true); newUp.p0 = pt; up.TemporalFunction(newUp.timeInterval.end, pt, true); newUp.p1 = pt; if(TLA_DEBUG) { cout<<"Add1 (" <("<Add(newUp); } else { // upoint ends inside of ubool newUp.timeInterval.start = ub.timeInterval.start; newUp.timeInterval.lc = ub.timeInterval.lc; newUp.timeInterval.end = up.timeInterval.end; newUp.timeInterval.rc = up.timeInterval.rc; up.TemporalFunction(newUp.timeInterval.start, pt, true); newUp.p0 = pt; up.TemporalFunction(newUp.timeInterval.end, pt, true); newUp.p1 = pt; if(TLA_DEBUG) { cout<<"Add2 (" <("<Add(newUp); pos++; if(pos < mp->GetNoComponents()) mp->Get(pos, up); else continue; if(TLA_DEBUG) { cout<<"UPoint # "<GetNoComponents()) { //upoint end before ubool newUp.timeInterval = up.timeInterval; newUp.p0 = up.p0; newUp.p1 = up.p1; if(TLA_DEBUG) { cout<<"Add3 (" <("<Add(newUp); pos++; if(pos < mp->GetNoComponents()) mp->Get(pos, up); else continue; if(TLA_DEBUG) { cout<<"UPoint # "<EndBulkLoad(false); } /* 1.1 Method ~TransformMBool2MPoint~ Completes a MBool to a MPoint-value for the ~minus~ operator. For this it adds the starting and end points to every interval when mBool is not true, even when there is no mBool at all. */ static void TransformMBool2MPoint( const Point *p, const MBool *mBool, MPoint *endResult) { assert( p ); assert( mBool ); assert( endResult ); endResult->Clear(); if( !p->IsDefined() || !mBool->IsDefined() ){ endResult->SetDefined( false ); return; } endResult->SetDefined( true ); endResult->Resize(mBool->GetNoComponents()); endResult->StartBulkLoad(); UBool ub; UPoint newUp(true); if(TLA_DEBUG) cout<<"TransformMBool2MPoint2 called"<GetNoComponents(); i++) { mBool->Get(i, ub); if(!ub.IsDefined()) continue; if(TLA_DEBUG){ cout<<"UBool # "<("< newUp.timeInterval.start || (newUp.timeInterval.end == newUp.timeInterval.start && newUp.timeInterval.lc && newUp.timeInterval.rc)) endResult->Add(newUp); } } endResult->EndBulkLoad(false); } /* 1.1 Method ~MovingBoolMMOperators~ Compares the two operators in the given way: The comparisons are 1: AND; 2: OR. */ static void MovingBoolMMOperators( const MBool& op1, const MBool& op2, MBool& result, int op ) { if(TLA_DEBUG) cout<<"MovingBoolMMOperators called"< rp(op1, op2); if(TLA_DEBUG) cout<<"Refinement finished, rp.size: "< iv; int u1Pos; int u2Pos; UBool u1transfer; UBool u2transfer; UBool u1(true); UBool u2(true); rp.Get(i, iv, u1Pos, u2Pos); if(TLA_DEBUG){ cout<< "and/or interval #"<< i<< ": "<< iv.start.ToString()<< " " << iv.end.ToString()<< " "<< iv.lc<< " "<< iv.rc<< " " << u1Pos<< " "<< u2Pos<< endl;} if (u1Pos == -1 || u2Pos == -1) continue; else { if(TLA_DEBUG) cout<<"Both operators existant in interval iv #"<Clear(); if( !op1->IsDefined() || !op2->IsDefined()){ result->SetDefined( false ); return; } result->SetDefined( true ); UInt uin(true), ures(true); //part of the Result int val2= op2->GetIntval() * op; result->Resize(op1->GetNoComponents()); result->StartBulkLoad(); for( int i = 0; i < op1->GetNoComponents(); i++) { op1->Get(i, uin); if(!(uin.IsDefined() && op2->IsDefined())) continue; ures.timeInterval.CopyFrom(uin.timeInterval); ures.constValue.Set(true, uin.constValue.GetIntval() + val2); result->MergeAdd(ures); } result->EndBulkLoad(false); } void MovingAddMIR(MInt* op1, CcReal* op2, MReal* result, int op) { if(TLA_DEBUG) cout<<"MovingAddMIR called"<Clear(); if( !op1->IsDefined() || !op2->IsDefined()){ result->SetDefined( false ); return; } result->SetDefined( true ); UInt uin(true); UReal ures(true); //part of the Result double val2= op2->GetRealval() * op; result->Resize(op1->GetNoComponents()); result->StartBulkLoad(); for( int i = 0; i < op1->GetNoComponents(); i++) { op1->Get(i, uin); if(!(uin.IsDefined() && op2->IsDefined())) continue; ures.timeInterval.CopyFrom(uin.timeInterval); ures.a= 0; ures.b= 0; ures.c= uin.constValue.GetIntval() + val2; ures.r= false; ures.SetDefined(true); result->MergeAdd(ures); } result->EndBulkLoad(false); } void MovingAddMRR(MReal* op1, CcReal* op2, MReal* result, int op) { if(TLA_DEBUG) cout<<"MovingAddMRR called"<Clear(); if( !op1->IsDefined() || !op2->IsDefined()){ result->SetDefined( false ); return; } result->SetDefined( true ); UReal uin(true), ures(true); //part of the Result double val2= op2->GetRealval() * op; result->Resize(op1->GetNoComponents()); result->StartBulkLoad(); for( int i = 0; i < op1->GetNoComponents(); i++) { op1->Get(i, uin); if(!(uin.IsDefined() && op2->IsDefined() && !uin.r)) continue; ures.timeInterval.CopyFrom(uin.timeInterval); ures.a= uin.a; ures.b= uin.b; ures.c= uin.c + val2; ures.r= uin.r; ures.SetDefined(true); result->MergeAdd(ures); } result->EndBulkLoad(false); } void MovingAddMRI(MReal* op1, CcInt* op2, MReal* result, int op) { if(TLA_DEBUG) cout<<"MovingAddMRI called"<Clear(); if( !op1->IsDefined() || !op2->IsDefined()){ result->SetDefined( false ); return; } result->SetDefined( true ); UReal uin(true), ures(true); //part of the Result int val2= op2->GetIntval() * op; result->Resize(op1->GetNoComponents()); result->StartBulkLoad(); for( int i = 0; i < op1->GetNoComponents(); i++) { op1->Get(i, uin); if(!(uin.IsDefined() && op2->IsDefined() && !uin.r)) continue; ures.timeInterval.CopyFrom(uin.timeInterval); ures.a= uin.a; ures.b= uin.b; ures.c= uin.c + val2; ures.r= uin.r; ures.SetDefined(true); result->MergeAdd(ures); } result->EndBulkLoad(false); } void MovingAddIMI(CcInt* op1, MInt* op2, MInt* result, int op) { if(TLA_DEBUG) cout<<"MovingAddIMI called"<Clear(); if( !op1->IsDefined() || !op2->IsDefined()){ result->SetDefined( false ); return; } result->SetDefined( true ); UInt uin(true), ures(true); //part of the Result int val1= op1->GetIntval(); result->Resize(op2->GetNoComponents()); result->StartBulkLoad(); for( int i = 0; i < op2->GetNoComponents(); i++) { op2->Get(i, uin); if(!(uin.IsDefined() && op1->IsDefined())) continue; ures.timeInterval.CopyFrom(uin.timeInterval); ures.constValue.Set(true, val1 + op * uin.constValue.GetIntval()); result->MergeAdd(ures); } result->EndBulkLoad(false); } void MovingAddRMI(CcReal* op1, MInt* op2, MReal* result, int op) { if(TLA_DEBUG) cout<<"MovingAddRMI called"<Clear(); if( !op1->IsDefined() || !op2->IsDefined()){ result->SetDefined( false ); return; } result->SetDefined( true ); UInt uin(true); UReal ures(true); //part of the Result double val1= op1->GetRealval(); result->Resize(op2->GetNoComponents()); result->StartBulkLoad(); for( int i = 0; i < op2->GetNoComponents(); i++) { op2->Get(i, uin); if(!(uin.IsDefined() && op2->IsDefined() )) continue; ures.timeInterval.CopyFrom(uin.timeInterval); ures.a= 0; ures.b= 0; ures.c= op * val1 - uin.constValue.GetIntval(); ures.r= false; ures.SetDefined(true); result->MergeAdd(ures); } result->EndBulkLoad(false); } void MovingAddRMR(CcReal* op1, MReal* op2, MReal* result, int op) { if(TLA_DEBUG) cout<<"MovingAddRMR called"<Clear(); if( !op1->IsDefined() || !op2->IsDefined()){ result->SetDefined( false ); return; } result->SetDefined( true ); UReal uin(true); UReal ures(true); //part of the Result double val1= op1->GetRealval(); result->Resize(op2->GetNoComponents()); result->StartBulkLoad(); for( int i = 0; i < op2->GetNoComponents(); i++) { op2->Get(i, uin); if(!(uin.IsDefined() && op2->IsDefined() && !uin.r )) continue; ures.timeInterval.CopyFrom(uin.timeInterval); ures.a= uin.a; ures.b= uin.b; ures.c= val1 + op * uin.c; ures.r= false; ures.SetDefined(true); result->MergeAdd(ures); } result->EndBulkLoad(false); } void MovingAddIMR(CcInt* op1, MReal* op2, MReal* result,int op) { if(TLA_DEBUG) cout<<"MovingAddIMR called"<Clear(); if( !op1->IsDefined() || !op2->IsDefined()){ result->SetDefined( false ); return; } result->SetDefined( true ); UReal uin(true); UReal ures(true); //part of the Result int val1= op1->GetIntval(); result->Resize(op2->GetNoComponents()); result->StartBulkLoad(); for( int i = 0; i < op2->GetNoComponents(); i++) { op2->Get(i, uin); if(!(uin.IsDefined() && op2->IsDefined() && !uin.r )) continue; ures.timeInterval.CopyFrom(uin.timeInterval); ures.a= uin.a; ures.b= uin.b; ures.c= val1 + op * uin.c; ures.r= false; ures.SetDefined(true); result->MergeAdd(ures); } result->EndBulkLoad(false); } void MovingAddMIMI(MInt* op1, MInt* op2, MInt* result, int op) { if(TLA_DEBUG) cout<<"MovingAddMIMI called"<IsDefined() || !op2->IsDefined() ){ result->SetDefined( false ); return; } result->SetDefined( true ); UInt uInt(true); //part of the Result RefinementPartition rp(*op1, *op2); result->Clear(); result->StartBulkLoad(); for(unsigned int i = 0; i < rp.Size(); i++) { Interval iv; int u1Pos; int u2Pos; UInt u1; UInt u2; rp.Get(i, iv, u1Pos, u2Pos); if (u1Pos == -1 || u2Pos == -1) continue; else { if(TLA_DEBUG) cout<<"Both operators existant in interval iv #"<Get(u1Pos, u1); op2->Get(u2Pos, u2); if(!(u1.IsDefined() && u2.IsDefined())) continue; } uInt.timeInterval = iv; uInt.constValue.Set(true, u1.constValue.GetIntval() + op * u2.constValue.GetIntval()); result->MergeAdd(uInt); } result->EndBulkLoad(false); } void MovingAddMIMR(MInt* op1, MReal* op2, MReal* result, int op) { if(TLA_DEBUG) cout<<"MovingAddMIMR called"<IsDefined() || !op2->IsDefined() ){ result->SetDefined( false ); return; } result->SetDefined( true ); UReal uReal(true); //part of the Result RefinementPartition rp(*op1, *op2); result->Clear(); result->StartBulkLoad(); for(unsigned int i = 0; i < rp.Size(); i++) { Interval iv; int u1Pos; int u2Pos; UInt u1; UReal u2; rp.Get(i, iv, u1Pos, u2Pos); if (u1Pos == -1 || u2Pos == -1) continue; else { if(TLA_DEBUG) cout<<"Both operators existant in interval iv #"<Get(u1Pos, u1); op2->Get(u2Pos, u2); if(!(u1.IsDefined() && u2.IsDefined() && !u2.r)) continue; } uReal.timeInterval = iv; uReal.a= op * u2.a; uReal.b= op * u2.b; uReal.c= u1.constValue.GetIntval() + op * u2.c; uReal.SetDefined(true); result->MergeAdd(uReal); } result->EndBulkLoad(false); } void MovingAddMRMR(MReal* op1, MReal* op2, MReal* result,int op) { if(TLA_DEBUG) cout<<"MovingAddMRMR called"<IsDefined() || !op2->IsDefined() ){ result->SetDefined( false ); return; } result->SetDefined( true ); UReal uReal(true); //part of the Result uReal.r= false; RefinementPartition rp(*op1, *op2); result->Clear(); result->StartBulkLoad(); for(unsigned int i = 0; i < rp.Size(); i++) { Interval iv; int u1Pos; int u2Pos; UReal u1; UReal u2; rp.Get(i, iv, u1Pos, u2Pos); if (u1Pos == -1 || u2Pos == -1) continue; else { if(TLA_DEBUG) cout<<"Both operators existant in interval iv #"<Get(u1Pos, u1); op2->Get(u2Pos, u2); if(!(u1.IsDefined() && u2.IsDefined() && !u1.r && !u2.r)) continue; } uReal.timeInterval = iv; uReal.a= u1.a + op * u2.a; uReal.b= u1.a + op * u2.b; uReal.c= u1.c + op * u2.c; uReal.SetDefined(true); result->MergeAdd(uReal); } result->EndBulkLoad(false); } void MovingAddMRMI(MReal* op1, MInt* op2, MReal* result, int op) { if(TLA_DEBUG) cout<<"MovingAddMIMR called"<IsDefined() || !op2->IsDefined() ){ result->SetDefined( false ); return; } result->SetDefined( true ); UReal uReal(true); //part of the Result RefinementPartition rp(*op1, *op2); result->Clear(); result->StartBulkLoad(); for(unsigned int i = 0; i < rp.Size(); i++) { Interval iv; int u1Pos; int u2Pos; UReal u1; UInt u2; rp.Get(i, iv, u1Pos, u2Pos); if (u1Pos == -1 || u2Pos == -1) continue; else { if(TLA_DEBUG) cout<<"Both operators existant in interval iv #"<Get(u1Pos, u1); op2->Get(u2Pos, u2); if(!(u1.IsDefined() && u2.IsDefined() && !u1.r)) continue; } uReal.timeInterval = iv; uReal.a= u1.a; uReal.b= u1.b; uReal.c= u1.c + op * u2.constValue.GetIntval(); uReal.SetDefined(true); result->MergeAdd(uReal); } result->EndBulkLoad(false); } void MovingMultiplyMII(MInt* op1, CcInt* op2, MInt* result) { if(TLA_DEBUG) cout<<"MovingMultiplyMII called"<Clear(); if( !op1->IsDefined() || !op2->IsDefined()){ result->SetDefined( false ); return; } result->SetDefined( true ); UInt uin(true), ures(true); //part of the Result int val2= op2->GetIntval(); result->Resize(op1->GetNoComponents()); result->StartBulkLoad(); for( int i = 0; i < op1->GetNoComponents(); i++) { op1->Get(i, uin); if(!(uin.IsDefined() && op2->IsDefined())) continue; ures.timeInterval.CopyFrom(uin.timeInterval); ures.constValue.Set(true, uin.constValue.GetIntval() * val2); result->MergeAdd(ures); } result->EndBulkLoad(false); } void MovingMultiplyMIR( MInt* op1, CcReal* op2, MReal* result, bool inverseSecond) { if(TLA_DEBUG) cout<<"MovingMultiplyMIR called"<Clear(); if( !op1->IsDefined() || !op2->IsDefined() || (inverseSecond && AlmostEqual(op2->GetRealval(), 0))){ result->SetDefined( false ); return; } result->SetDefined( true ); UInt uin(true); UReal ures(true); //part of the Result double val2; if(inverseSecond) val2= 1.0 / op2->GetRealval() ; else val2= op2->GetRealval() ; result->Resize(op1->GetNoComponents()); result->StartBulkLoad(); for( int i = 0; i < op1->GetNoComponents(); i++) { op1->Get(i, uin); if(!(uin.IsDefined() && op2->IsDefined())) continue; ures.timeInterval.CopyFrom(uin.timeInterval); ures.a= 0; ures.b= 0; ures.c= uin.constValue.GetIntval() * val2; ures.r= false; ures.SetDefined(true); result->MergeAdd(ures); } result->EndBulkLoad(false); } void MovingMultiplyMRR( MReal* op1, CcReal* op2, MReal* result, bool inverseSecond) { if(TLA_DEBUG) cout<<"MovingMultiplyMRR called"<Clear(); if( !op1->IsDefined() || !op2->IsDefined()|| (inverseSecond && AlmostEqual(op2->GetRealval(), 0))){ result->SetDefined( false ); return; } result->SetDefined( true ); UReal uin(true), ures(true); //part of the Result double val2; if(inverseSecond) val2= 1.0 / op2->GetRealval() ; else val2= op2->GetRealval() ; double sval2 = val2*val2; result->Resize(op1->GetNoComponents()); result->StartBulkLoad(); for( int i = 0; i < op1->GetNoComponents(); i++) { op1->Get(i, uin); if(uin.r && val2<0){ continue; } double val3 = uin.r?sval2:val2; ures.timeInterval.CopyFrom(uin.timeInterval); ures.a= uin.a * val3; ures.b= uin.b * val3; ures.c= uin.c * val3; ures.r= uin.r; ures.SetDefined(true); result->MergeAdd(ures); } result->EndBulkLoad(false); } void MovingMultiplyMRI( MReal* op1, CcInt* op2, MReal* result, bool inverseSecond) { if(TLA_DEBUG) cout<<"MovingMultiplyMRI called"<Clear(); if( !op1->IsDefined() || !op2->IsDefined() || (inverseSecond && (op2->GetIntval() == 0) )){ result->SetDefined( false ); return; } result->SetDefined( true ); UReal uin(true), ures(true); //part of the Result double val2; if(inverseSecond) val2= 1.0 / op2->GetIntval(); else val2= op2->GetIntval(); result->Resize(op1->GetNoComponents()); result->StartBulkLoad(); for( int i = 0; i < op1->GetNoComponents(); i++) { op1->Get(i, uin); if(!(uin.IsDefined() && op2->IsDefined() && !uin.r)) continue; ures.timeInterval.CopyFrom(uin.timeInterval); ures.a= uin.a * val2; ures.b= uin.b * val2; ures.c= uin.c * val2; ures.r= uin.r; ures.SetDefined(true); result->MergeAdd(ures); } result->EndBulkLoad(false); } void MovingMultiplyIMI(CcInt* op1, MInt* op2, MInt* result) { if(TLA_DEBUG) cout<<"MovingMultiplyIMI called"<Clear(); if( !op1->IsDefined() || !op2->IsDefined()){ result->SetDefined( false ); return; } result->SetDefined( true ); UInt uin(true), ures(true); //part of the Result int val1= op1->GetIntval(); result->Resize(op2->GetNoComponents()); result->StartBulkLoad(); for( int i = 0; i < op2->GetNoComponents(); i++) { op2->Get(i, uin); if(!(uin.IsDefined() && op1->IsDefined())) continue; ures.timeInterval.CopyFrom(uin.timeInterval); ures.constValue.Set(true, val1 * uin.constValue.GetIntval()); result->MergeAdd(ures); } result->EndBulkLoad(false); } void MovingMultiplyRMI( CcReal* op1, MInt* op2, MReal* result, bool inverseSecond) { if(TLA_DEBUG) cout<<"MovingMultiplyRMI called"<Clear(); if( !op1->IsDefined() || !op2->IsDefined()){ result->SetDefined( false ); return; } result->SetDefined( true ); UInt uin(true); UReal ures(true); //part of the Result double val1= op1->GetRealval(); result->Resize(op2->GetNoComponents()); result->StartBulkLoad(); for( int i = 0; i < op2->GetNoComponents(); i++) { op2->Get(i, uin); if(!(uin.IsDefined() && op2->IsDefined() )) continue; ures.timeInterval.CopyFrom(uin.timeInterval); ures.a= 0; ures.b= 0; if(inverseSecond) { if(uin.constValue.GetIntval() == 0) ures.SetDefined(false); else { ures.c= val1 / uin.constValue.GetIntval(); ures.SetDefined(true); } } else { ures.c= val1 * uin.constValue.GetIntval(); ures.SetDefined(true); } ures.r= false; if(ures.IsDefined()) result->MergeAdd(ures); } result->EndBulkLoad(false); } void MovingMultiplyRMR(CcReal* op1, MReal* op2, MReal* result) { if(TLA_DEBUG) cout<<"MovingMultiplyRMR called"<Clear(); if( !op1->IsDefined() || !op2->IsDefined()){ result->SetDefined( false ); return; } result->SetDefined( true ); UReal uin(true); UReal ures(true); //part of the Result double val1= op1->GetRealval(); result->Resize(op2->GetNoComponents()); result->StartBulkLoad(); for( int i = 0; i < op2->GetNoComponents(); i++) { op2->Get(i, uin); if(!(uin.IsDefined() && op2->IsDefined() && !uin.r )) continue; ures.timeInterval.CopyFrom(uin.timeInterval); ures.a= val1 * uin.a; ures.b= val1 * uin.b; ures.c= val1 * uin.c; ures.r= false; ures.SetDefined(true); result->MergeAdd(ures); } result->EndBulkLoad(false); } void MovingMultiplyIMR(CcInt* op1, MReal* op2, MReal* result) { if(TLA_DEBUG) cout<<"MovingMultiplyIMR called"<Clear(); if( !op1->IsDefined() || !op2->IsDefined()){ result->SetDefined( false ); return; } result->SetDefined( true ); UReal uin(true); UReal ures(true); //part of the Result int val1= op1->GetIntval(); result->Resize(op2->GetNoComponents()); result->StartBulkLoad(); for( int i = 0; i < op2->GetNoComponents(); i++) { op2->Get(i, uin); if(!(uin.IsDefined() && op2->IsDefined() && !uin.r )) continue; ures.timeInterval.CopyFrom(uin.timeInterval); ures.a= val1 * uin.a; ures.b= val1 * uin.b; ures.c= val1 * uin.c; ures.r= false; ures.SetDefined(true); result->MergeAdd(ures); } result->EndBulkLoad(false); } void MovingMultiplyMIMI(MInt* op1, MInt* op2, MInt* result) { if(TLA_DEBUG) cout<<"MovingMultiplyMIMI called"<IsDefined() || !op2->IsDefined() ){ result->SetDefined( false ); return; } result->SetDefined( true ); UInt uInt(true); //part of the Result RefinementPartition rp(*op1, *op2); result->Clear(); result->StartBulkLoad(); for(unsigned int i = 0; i < rp.Size(); i++) { Interval iv; int u1Pos; int u2Pos; UInt u1; UInt u2; rp.Get(i, iv, u1Pos, u2Pos); if (u1Pos == -1 || u2Pos == -1) continue; else { if(TLA_DEBUG) cout<<"Both operators existant in interval iv #"<Get(u1Pos, u1); op2->Get(u2Pos, u2); if(!(u1.IsDefined() && u2.IsDefined())) continue; } uInt.timeInterval = iv; uInt.constValue.Set(true, u1.constValue.GetIntval() * u2.constValue.GetIntval()); result->MergeAdd(uInt); } result->EndBulkLoad(false); } void MovingMultiplyMIMR(MInt* op1, MReal* op2, MReal* result) { if(TLA_DEBUG) cout<<"MovingMultiplyMIMR called"<IsDefined() || !op2->IsDefined() ){ result->SetDefined( false ); return; } result->SetDefined( true ); UReal uReal(true); //part of the Result RefinementPartition rp(*op1, *op2); result->Clear(); result->StartBulkLoad(); for(unsigned int i = 0; i < rp.Size(); i++) { Interval iv; int u1Pos; int u2Pos; UInt u1; UReal u2; rp.Get(i, iv, u1Pos, u2Pos); if (u1Pos == -1 || u2Pos == -1) continue; else { if(TLA_DEBUG) cout<<"Both operators existant in interval iv #"<Get(u1Pos, u1); op2->Get(u2Pos, u2); if(!(u1.IsDefined() && u2.IsDefined() && !u2.r)) continue; } uReal.timeInterval = iv; uReal.a= u1.constValue.GetIntval() * u2.a; uReal.b= u1.constValue.GetIntval() * u2.b; uReal.c= u1.constValue.GetIntval() * u2.c; uReal.SetDefined(true); result->MergeAdd(uReal); } result->EndBulkLoad(false); } void MovingMultiplyMRMI( MReal* op1, MInt* op2, MReal* result, bool inverseSecond) { if(TLA_DEBUG) cout<<"MovingMultiplyMIMR called"<IsDefined() || !op2->IsDefined() ){ result->SetDefined( false ); return; } result->SetDefined( true ); UReal uReal(true); //part of the Result RefinementPartition rp(*op1, *op2); result->Clear(); result->StartBulkLoad(); for(unsigned int i = 0; i < rp.Size(); i++) { Interval iv; int u1Pos; int u2Pos; UReal u1; UInt u2; rp.Get(i, iv, u1Pos, u2Pos); if (u1Pos == -1 || u2Pos == -1) continue; else { if(TLA_DEBUG) cout<<"Both operators existant in interval iv #"<Get(u1Pos, u1); op2->Get(u2Pos, u2); if(!(u1.IsDefined() && u2.IsDefined() && !u1.r)) continue; } uReal.timeInterval = iv; if(inverseSecond) { if(AlmostEqual(u2.constValue.GetIntval(), 0)) uReal.SetDefined(false); else { uReal.SetDefined(true); uReal.a= u1.a / u2.constValue.GetIntval(); uReal.b= u1.b / u2.constValue.GetIntval(); uReal.c= u1.c / u2.constValue.GetIntval(); uReal.r = false; } } else { uReal.a= u1.a * u2.constValue.GetIntval(); uReal.b= u1.b * u2.constValue.GetIntval(); uReal.c= u1.c * u2.constValue.GetIntval(); uReal.r = false; uReal.SetDefined(true); } if(uReal.IsDefined()) result->MergeAdd(uReal); } result->EndBulkLoad(false); } /* 1.1 Methods to compute ~/~ of MInt, MReal */ void MovingDivideMII(MInt* op1, CcInt* op2, MReal* result) { if(TLA_DEBUG) cout<<"MovingDivideMII called"<Clear(); if( !op1->IsDefined() || !op2->IsDefined()){ result->SetDefined( false ); return; } result->SetDefined( true ); UInt uin(true); UReal ures(true); //part of the Result int val2= op2->GetIntval(); result->Resize(op1->GetNoComponents()); result->StartBulkLoad(); for( int i = 0; i < op1->GetNoComponents(); i++) { op1->Get(i, uin); if(!(uin.IsDefined() && op2->IsDefined())) continue; ures.timeInterval.CopyFrom(uin.timeInterval); ures.a= 0; ures.b= 0; ures.c= static_cast(uin.constValue.GetIntval()) / val2; ures.SetDefined(true); result->MergeAdd(ures); } result->EndBulkLoad(false); } void MovingDivideIMI(CcInt* op1, MInt* op2, MReal* result) { if(TLA_DEBUG) cout<<"MovingDivideIMI called"<Clear(); if( !op1->IsDefined() || !op2->IsDefined()){ result->SetDefined( false ); return; } result->SetDefined( true ); UInt uin(true); UReal ures(true); //part of the Result int val1= op1->GetIntval(); result->Resize(op2->GetNoComponents()); result->StartBulkLoad(); for( int i = 0; i < op2->GetNoComponents(); i++) { op2->Get(i, uin); if(!(uin.IsDefined() && op2->IsDefined())) continue; ures.timeInterval.CopyFrom(uin.timeInterval); ures.a= 0; ures.b= 0; if(uin.constValue.GetIntval() == 0) ures.SetDefined(false); else { ures.c= static_cast(val1) / uin.constValue.GetIntval(); ures.SetDefined(true); } if(ures.IsDefined()) result->MergeAdd(ures); } result->EndBulkLoad(false); } void MovingDivideMIMI( MInt* op1, MInt* op2, MReal* result) { if(TLA_DEBUG) cout<<"MovingMultiplyMIMR called"<IsDefined() || !op2->IsDefined() ){ result->SetDefined( false ); return; } result->SetDefined( true ); UReal uReal(true); //part of the Result RefinementPartition rp(*op1, *op2); result->Clear(); result->StartBulkLoad(); for(unsigned int i = 0; i < rp.Size(); i++) { Interval iv; int u1Pos; int u2Pos; UInt u1; UInt u2; rp.Get(i, iv, u1Pos, u2Pos); if (u1Pos == -1 || u2Pos == -1) continue; else { if(TLA_DEBUG) cout<<"Both operators existant in interval iv #"<Get(u1Pos, u1); op2->Get(u2Pos, u2); if(!(u1.IsDefined() && u2.IsDefined())) continue; } uReal.timeInterval = iv; if(u2.constValue.GetIntval() == 0) uReal.SetDefined(false); else { uReal.SetDefined(true); uReal.a= static_cast( u2.constValue.GetIntval()) / u2.constValue.GetIntval(); uReal.b= static_cast( u2.constValue.GetIntval()) / u2.constValue.GetIntval(); uReal.c= static_cast( u2.constValue.GetIntval()) / u2.constValue.GetIntval(); } if(uReal.IsDefined()) result->MergeAdd(uReal); } result->EndBulkLoad(false); } /* 1.1 Method ~MovingCompareBoolMM~ Compares the two operators in the given way: The comparisons are -3: \#; -2: <; -1: <=; 0: =; 1: >=; 2: >. */ template static void MovingCompareBoolMM( const Mapping1& op1, const Mapping2& op2, MBool& result, int op ) { if(TLA_DEBUG) cout<<"MovingCompareBoolMM called"< rp(op1, op2); if(TLA_DEBUG) cout<<"Refinement finished, rp.size: "< iv; int u1Pos; int u2Pos; Unit1 u1; Unit2 u2; rp.Get(i, iv, u1Pos, u2Pos); if(TLA_DEBUG){ cout<< "Compare interval #"<< i<< ": "<< iv.start.ToString()<< " " << iv.end.ToString()<< " "<< iv.lc<< " "<< iv.rc<< " " << u1Pos<< " "<< u2Pos<< endl;} if (u1Pos == -1 || u2Pos == -1) continue; else { if(TLA_DEBUG) cout<<"Both operators existant in interval iv #"< static void MovingIntersectionMM( const Mapping1& op1, const Mapping2& op2, Mapping1& result, int op) { if(TLA_DEBUG) cout<<"MovingIntersectionMM called"< rp(op1, op2); if(TLA_DEBUG) cout<<"Refinement finished, rp.size: "< iv; int u1Pos; int u2Pos; Unit1 u1(true); Unit2 u2(true); Unit1 u1transfer; Unit2 u2transfer; rp.Get(i, iv, u1Pos, u2Pos); if (u1Pos == -1 || u2Pos == -1 ) continue; else { if(TLA_DEBUG) cout<<"Both operands existant in interval iv #"<=; 2: >. */ template static void MovingCompareBoolMS( const Mapping1& op1, const Operator2& op2, MBool& result, int op ) { if(TLA_DEBUG) cout<<"MovingCompareBoolMS called"< static void MovingAddMS( const Op1M* op1, const Op2S* op2, ResM* result, int op ) { if(TLA_DEBUG) cout<<"MovingAddMS called"<Clear(); if( !op1->IsDefined() || !op2->IsDefined()){ result->SetDefined( false ); return; } result->SetDefined( true ); ResU uRes(true); //part of the Result Op1U u1; Op1S val1; ResS valRes; result->Resize(op1->GetNoComponents()); result->StartBulkLoad(); for(int i = 0; i < op1->GetNoComponents(); i++) { op1->Get(i, u1); if(!(u1.IsDefined() && op2->IsDefined())) continue; uRes.timeInterval = u1.timeInterval; val1= u1.constValue.GetValue(); uRes.constValue.Set(true, val1 + op * op2->GetValue()); if(TLA_DEBUG){ uRes.Print(cout); cout<<"\n";} result->MergeAdd(uRes); } result->EndBulkLoad(false); } /* 1.1 Method ~MRealABS~ Calculates the absolut value of a mReal. */ static void MRealABS( const MReal& op, MReal& result) { result.Clear(); if( !op.IsDefined() ){ result.SetDefined( false ); return; } result.SetDefined( true ); vector partResult; int numPartResult = 0; result.Resize(op.GetNoComponents()); result.StartBulkLoad(); for(int i = 0; i < op.GetNoComponents(); i++) { UReal u1; op.Get(i, u1); numPartResult = u1.Abs(partResult); for(int j=0; jDeleteIfAllowed(); } /* 1.1 Method ~copyMRegionMPoint~ copies the MRegion to result and restrics it to deftime(mpoint). Method is not implemented complete, because ~restrictMRegion2periods~ is not implemented yet. */ void copyMRegionMPoint(const MRegion& reg, const MPoint& pt, MRegion& result) { result.Clear(); if( !reg.IsDefined() || !pt.IsDefined() ){ result.SetDefined( false ); return; } result.SetDefined( true ); RefinementPartition rp(reg,pt); Interval iv; int regPos; int ptPos; Periods* per = new Periods(rp.Size()); Interval newper; per->Clear(); per->StartBulkLoad(); for( unsigned int i = 0; i < rp.Size(); i++ ){ rp.Get(i, iv, regPos, ptPos); if(regPos == -1 || ptPos == -1) continue; if(TLA_DEBUG){ cout<<"bothoperators in iv # "<Add(newper); } per->EndBulkLoad(0); Periods* pers = new Periods(0); pers->Clear(); per->Merge(*pers); per->DeleteIfAllowed(); result.Clear(); //restrictMRegion2periods(reg, pers, result); //not possible, because it is not implemented yet. pers->DeleteIfAllowed(); } /* 1 TypeMapping-Functions 10.1 Type mapping function "MBoolTypeMapMBool" This type mapping function is used for the ~not~ operator. */ ListExpr MBoolTypeMapMBool( ListExpr args ) { ListExpr arg1; if ( nl->ListLength( args ) == 1 ) { arg1 = nl->First( args ); if( nl->IsEqual( arg1, MBool::BasicType() ) ) return (nl->SymbolAtom( MBool::BasicType() )); } return nl->SymbolAtom( Symbol::TYPEERROR() ); } /* 10.1 Type mapping function "AndOrTypeMapMBool" This type mapping function is used for the ~and~ and ~or~ operator. */ ListExpr AndOrTypeMapMBool( ListExpr args ) { ListExpr arg1, arg2; if ( nl->ListLength( args ) == 2 ) { arg1 = nl->First( args ); arg2 = nl->Second( args ); if( nl->IsEqual( arg1, MBool::BasicType() ) && nl->IsEqual( arg2, MBool::BasicType() ) ) return (nl->SymbolAtom( MBool::BasicType() )); if( nl->IsEqual( arg1, MBool::BasicType() ) && nl->IsEqual( arg2, CcBool::BasicType() ) ) return (nl->SymbolAtom( MBool::BasicType() )); if( nl->IsEqual( arg1, CcBool::BasicType() ) && nl->IsEqual( arg2, MBool::BasicType() ) ) return (nl->SymbolAtom( MBool::BasicType() )); } return nl->SymbolAtom( Symbol::TYPEERROR() ); } /* 10.1 Type mapping function "MovingEqualTypeMapMBool" This type mapping function is used for the ~\=~ and ~\#~ operator. */ ListExpr MovingEqualTypeMapMBool( ListExpr args ) { ListExpr arg1, arg2; if(TLA_DEBUG) cout<<"MovingEqualTypeMapMBool called"<ListLength( args ) == 2 ) { arg1 = nl->First( args ); arg2 = nl->Second( args ); if( nl->IsEqual( arg1, MBool::BasicType() ) && nl->IsEqual( arg2, MBool::BasicType() ) ) return (nl->SymbolAtom( MBool::BasicType() )); if( nl->IsEqual( arg1, MBool::BasicType() ) && nl->IsEqual( arg2, CcBool::BasicType() ) ) return (nl->SymbolAtom( MBool::BasicType() )); if( nl->IsEqual( arg1, CcBool::BasicType() ) && nl->IsEqual( arg2, MBool::BasicType() ) ) return (nl->SymbolAtom( MBool::BasicType() )); if( nl->IsEqual( arg1, MInt::BasicType() ) && nl->IsEqual( arg2, MInt::BasicType() ) ) return (nl->SymbolAtom( MBool::BasicType() )); if( nl->IsEqual( arg1, MInt::BasicType() ) && nl->IsEqual( arg2, CcInt::BasicType() ) ) return (nl->SymbolAtom( MBool::BasicType() )); if( nl->IsEqual( arg1, CcInt::BasicType() ) && nl->IsEqual( arg2, MInt::BasicType() ) ) return (nl->SymbolAtom( MBool::BasicType() )); if( nl->IsEqual( arg1, MString::BasicType() ) && nl->IsEqual( arg2, MString::BasicType() ) ) return (nl->SymbolAtom( MBool::BasicType() )); if( nl->IsEqual( arg1, MString::BasicType() ) && nl->IsEqual( arg2, CcString::BasicType() ) ) return (nl->SymbolAtom( MBool::BasicType() )); if( nl->IsEqual( arg1, CcString::BasicType() ) && nl->IsEqual( arg2, MString::BasicType() ) ) return (nl->SymbolAtom( MBool::BasicType() )); if( nl->IsEqual( arg1, MReal::BasicType() ) && nl->IsEqual( arg2, MReal::BasicType() ) ) return (nl->SymbolAtom( MBool::BasicType() )); if( nl->IsEqual( arg1, MReal::BasicType() ) && nl->IsEqual( arg2, CcReal::BasicType() ) ) return (nl->SymbolAtom( MBool::BasicType() )); if( nl->IsEqual( arg1, CcReal::BasicType() ) && nl->IsEqual( arg2, MReal::BasicType() ) ) return (nl->SymbolAtom( MBool::BasicType() )); if( nl->IsEqual( arg1, MPoint::BasicType() ) && nl->IsEqual( arg2, MPoint::BasicType() ) ) return (nl->SymbolAtom( MBool::BasicType() )); if( nl->IsEqual( arg1, MPoint::BasicType() ) && nl->IsEqual( arg2, Point::BasicType() ) ) return (nl->SymbolAtom( MBool::BasicType() )); if( nl->IsEqual( arg1, Point::BasicType() ) && nl->IsEqual( arg2, MPoint::BasicType() ) ) return (nl->SymbolAtom( MBool::BasicType() )); if( nl->IsEqual( arg1, MRegion::BasicType() ) && nl->IsEqual( arg2, Region::BasicType() ) ) return (nl->SymbolAtom( MBool::BasicType() )); if( nl->IsEqual( arg1, Region::BasicType() ) && nl->IsEqual( arg2, MRegion::BasicType() ) ) return (nl->SymbolAtom( MBool::BasicType() )); if( nl->IsEqual( arg1, MRegion::BasicType() ) && nl->IsEqual( arg2, MRegion::BasicType() ) ) return (nl->SymbolAtom( MBool::BasicType() )); } return nl->SymbolAtom( Symbol::TYPEERROR() ); } /* 10.1 Type mapping function "MovingCompareTypeMapMBool" This type mapping function is used for the ~<~, ~<=~, ~<~ and ~>=~ operator. */ ListExpr MovingCompareTypeMapMBool( ListExpr args ) { ListExpr arg1, arg2; if ( nl->ListLength( args ) == 2 ) { arg1 = nl->First( args ); arg2 = nl->Second( args ); if( nl->IsEqual( arg1, MBool::BasicType() ) && nl->IsEqual( arg2, MBool::BasicType() ) ) return (nl->SymbolAtom( MBool::BasicType() )); if( nl->IsEqual( arg1, MBool::BasicType() ) && nl->IsEqual( arg2, CcBool::BasicType() ) ) return (nl->SymbolAtom( MBool::BasicType() )); if( nl->IsEqual( arg1, CcBool::BasicType() ) && nl->IsEqual( arg2, MBool::BasicType() ) ) return (nl->SymbolAtom( MBool::BasicType() )); if( nl->IsEqual( arg1, MInt::BasicType() ) && nl->IsEqual( arg2, MInt::BasicType() ) ) return (nl->SymbolAtom( MBool::BasicType() )); if( nl->IsEqual( arg1, MInt::BasicType() ) && nl->IsEqual( arg2, CcInt::BasicType() ) ) return (nl->SymbolAtom( MBool::BasicType() )); if( nl->IsEqual( arg1, CcInt::BasicType() ) && nl->IsEqual( arg2, MInt::BasicType() ) ) return (nl->SymbolAtom( MBool::BasicType() )); if( nl->IsEqual( arg1, MReal::BasicType() ) && nl->IsEqual( arg2, MReal::BasicType() ) ) return (nl->SymbolAtom( MBool::BasicType() )); if( nl->IsEqual( arg1, MReal::BasicType() ) && nl->IsEqual( arg2, CcReal::BasicType() ) ) return (nl->SymbolAtom( MBool::BasicType() )); if( nl->IsEqual( arg1, CcReal::BasicType() ) && nl->IsEqual( arg2, MReal::BasicType() ) ) return (nl->SymbolAtom( MBool::BasicType() )); if( nl->IsEqual( arg1, MString::BasicType() ) && nl->IsEqual( arg2, MString::BasicType() ) ) return (nl->SymbolAtom( MBool::BasicType() )); if( nl->IsEqual( arg1, MString::BasicType() ) && nl->IsEqual( arg2, CcString::BasicType() ) ) return (nl->SymbolAtom( MBool::BasicType() )); if( nl->IsEqual( arg1, CcString::BasicType() ) && nl->IsEqual( arg2, MString::BasicType() ) ) return (nl->SymbolAtom( MBool::BasicType() )); } return nl->SymbolAtom( Symbol::TYPEERROR() ); } /* 10.1 Type mapping function "MovingAddTypeMap" This type mapping function is used for the ~-~, ~+~ operators. */ ListExpr MovingAddTypeMap( ListExpr args ) { ListExpr arg1, arg2; if ( nl->ListLength( args ) == 2 ) { arg1 = nl->First( args ); arg2 = nl->Second( args ); if( nl->IsEqual( arg1, MInt::BasicType() ) && nl->IsEqual( arg2, CcInt::BasicType() ) ) return (nl->SymbolAtom( MInt::BasicType() )); if( nl->IsEqual( arg1, MInt::BasicType() ) && nl->IsEqual( arg2, CcReal::BasicType() ) ) return (nl->SymbolAtom( MReal::BasicType() )); if( nl->IsEqual( arg1, MReal::BasicType() ) && nl->IsEqual( arg2, CcReal::BasicType() ) ) return (nl->SymbolAtom( MReal::BasicType() )); if( nl->IsEqual( arg1, MReal::BasicType() ) && nl->IsEqual( arg2, CcInt::BasicType() ) ) return (nl->SymbolAtom( MReal::BasicType() )); if( nl->IsEqual( arg1, CcInt::BasicType() ) && nl->IsEqual( arg2, MInt::BasicType() ) ) return (nl->SymbolAtom( MInt::BasicType() )); if( nl->IsEqual( arg1, CcReal::BasicType() ) && nl->IsEqual( arg2, MInt::BasicType() ) ) return (nl->SymbolAtom( MReal::BasicType() )); if( nl->IsEqual( arg1, CcReal::BasicType() ) && nl->IsEqual( arg2, MReal::BasicType() ) ) return (nl->SymbolAtom( MReal::BasicType() )); if( nl->IsEqual( arg1, CcInt::BasicType() ) && nl->IsEqual( arg2, MReal::BasicType() ) ) return (nl->SymbolAtom( MReal::BasicType() )); if( nl->IsEqual( arg1, MInt::BasicType() ) && nl->IsEqual( arg2, MInt::BasicType() ) ) return (nl->SymbolAtom( MInt::BasicType() )); if( nl->IsEqual( arg1, MInt::BasicType() ) && nl->IsEqual( arg2, MReal::BasicType() ) ) return (nl->SymbolAtom( MReal::BasicType() )); if( nl->IsEqual( arg1, MReal::BasicType() ) && nl->IsEqual( arg2, MReal::BasicType() ) ) return (nl->SymbolAtom( MReal::BasicType() )); if( nl->IsEqual( arg1, MReal::BasicType() ) && nl->IsEqual( arg2, MInt::BasicType() ) ) return (nl->SymbolAtom( MReal::BasicType() )); } return nl->SymbolAtom( Symbol::TYPEERROR() ); } /* 10.1 Type mapping function "MovingMultiplyTypeMap" This type mapping function is used for the ~multiplication~ operator. */ ListExpr MovingMultiplyTypeMap( ListExpr args ) { ListExpr arg1, arg2; if ( nl->ListLength( args ) == 2 ) { arg1 = nl->First( args ); arg2 = nl->Second( args ); if( nl->IsEqual( arg1, MInt::BasicType() ) && nl->IsEqual( arg2, CcInt::BasicType() ) ) return (nl->SymbolAtom( MInt::BasicType() )); if( nl->IsEqual( arg1, MInt::BasicType() ) && nl->IsEqual( arg2, CcReal::BasicType() ) ) return (nl->SymbolAtom( MReal::BasicType() )); if( nl->IsEqual( arg1, MReal::BasicType() ) && nl->IsEqual( arg2, CcReal::BasicType() ) ) return (nl->SymbolAtom( MReal::BasicType() )); if( nl->IsEqual( arg1, MReal::BasicType() ) && nl->IsEqual( arg2, CcInt::BasicType() ) ) return (nl->SymbolAtom( MReal::BasicType() )); if( nl->IsEqual( arg1, CcInt::BasicType() ) && nl->IsEqual( arg2, MInt::BasicType() ) ) return (nl->SymbolAtom( MInt::BasicType() )); if( nl->IsEqual( arg1, CcReal::BasicType() ) && nl->IsEqual( arg2, MInt::BasicType() ) ) return (nl->SymbolAtom( MReal::BasicType() )); if( nl->IsEqual( arg1, CcReal::BasicType() ) && nl->IsEqual( arg2, MReal::BasicType() ) ) return (nl->SymbolAtom( MReal::BasicType() )); if( nl->IsEqual( arg1, CcInt::BasicType() ) && nl->IsEqual( arg2, MReal::BasicType() ) ) return (nl->SymbolAtom( MReal::BasicType() )); if( nl->IsEqual( arg1, MInt::BasicType() ) && nl->IsEqual( arg2, MInt::BasicType() ) ) return (nl->SymbolAtom( MInt::BasicType() )); if( nl->IsEqual( arg1, MInt::BasicType() ) && nl->IsEqual( arg2, MReal::BasicType() ) ) return (nl->SymbolAtom( MReal::BasicType() )); if( nl->IsEqual( arg1, MReal::BasicType() ) && nl->IsEqual( arg2, MInt::BasicType() ) ) return (nl->SymbolAtom( MReal::BasicType() )); } return nl->SymbolAtom( Symbol::TYPEERROR() ); } /* 10.1 Type mapping function "MovingDivideTypeMap" This type mapping function is used for the ~/~ operator. */ ListExpr MovingDivideTypeMap( ListExpr args ) { ListExpr arg1, arg2; if ( nl->ListLength( args ) == 2 ) { arg1 = nl->First( args ); arg2 = nl->Second( args ); if( nl->IsEqual( arg1, MInt::BasicType() ) && nl->IsEqual( arg2, CcInt::BasicType() ) ) return (nl->SymbolAtom( MReal::BasicType() )); if( nl->IsEqual( arg1, MInt::BasicType() ) && nl->IsEqual( arg2, CcReal::BasicType() ) ) return (nl->SymbolAtom( MReal::BasicType() )); if( nl->IsEqual( arg1, MReal::BasicType() ) && nl->IsEqual( arg2, CcReal::BasicType() ) ) return (nl->SymbolAtom( MReal::BasicType() )); if( nl->IsEqual( arg1, MReal::BasicType() ) && nl->IsEqual( arg2, CcInt::BasicType() ) ) return (nl->SymbolAtom( MReal::BasicType() )); if( nl->IsEqual( arg1, CcInt::BasicType() ) && nl->IsEqual( arg2, MInt::BasicType() ) ) return (nl->SymbolAtom( MReal::BasicType() )); if( nl->IsEqual( arg1, CcReal::BasicType() ) && nl->IsEqual( arg2, MInt::BasicType() ) ) return (nl->SymbolAtom( MReal::BasicType() )); if( nl->IsEqual( arg1, MInt::BasicType() ) && nl->IsEqual( arg2, MInt::BasicType() ) ) return (nl->SymbolAtom( MReal::BasicType() )); if( nl->IsEqual( arg1, MReal::BasicType() ) && nl->IsEqual( arg2, MInt::BasicType() ) ) return (nl->SymbolAtom( MReal::BasicType() )); } return nl->SymbolAtom( Symbol::TYPEERROR() ); } /* 16.1 Type mapping function ~MovingTypeMapeIntime~ It is for the operators ~distance~. */ ListExpr MovingDistanceTypeMapMReal( ListExpr args ) { if ( nl->ListLength( args ) == 2 ) { ListExpr arg1 = nl->First( args ), arg2 = nl->Second( args ); if( nl->IsEqual( arg1, MPoint::BasicType() ) && nl->IsEqual( arg2, MPoint::BasicType() ) ) return nl->SymbolAtom( MReal::BasicType() ); if( nl->IsEqual( arg1, MReal::BasicType() ) && nl->IsEqual( arg2, MReal::BasicType() ) ) return nl->SymbolAtom( MReal::BasicType() ); if( nl->IsEqual( arg1, MReal::BasicType() ) && nl->IsEqual( arg2, CcReal::BasicType() ) ) return nl->SymbolAtom( MReal::BasicType() ); if( nl->IsEqual( arg1, CcReal::BasicType() ) && nl->IsEqual( arg2, MReal::BasicType() ) ) return nl->SymbolAtom( MReal::BasicType() ); if(UPoint::checkType(arg1) && UPoint::checkType(arg2)) return nl->SymbolAtom( MReal::BasicType() ); if(UPoint::checkType(arg1) && Point::checkType(arg2)) return nl->SymbolAtom( MReal::BasicType() ); if(Point::checkType(arg1) && UPoint::checkType(arg2)) return nl->SymbolAtom( MReal::BasicType() ); } return nl->SymbolAtom( Symbol::TYPEERROR() ); } /* \subsection{Type mapping function ~MPointMPointMapReal~} It is for the operators ~frechetdistance~. */ ListExpr MPointMPointMapReal(ListExpr args) { if (nl->HasLength(args, 2) || nl->HasLength(args, 3)) { if (MPoint::checkType(nl->First(args)) && MPoint::checkType(nl->Second(args))) { if (nl->HasLength(args, 3)) { if (Geoid::checkType(nl->Third(args))) { return nl->SymbolAtom(CcReal::BasicType()); } } return nl->SymbolAtom(CcReal::BasicType()); } } return listutils::typeError("2 or 3 arguments expected"); } /* 16.1 Type mapping function ~MovingIntersectionTypeMap~ It is for the operator ~intersection~. */ ListExpr MovingIntersectionTypeMap( ListExpr args ) { if ( nl->ListLength( args ) == 2 ) { ListExpr arg1 = nl->First( args ), arg2 = nl->Second( args ); if( nl->IsEqual( arg1, MBool::BasicType() ) && nl->IsEqual( arg2, MBool::BasicType() ) ) return nl->SymbolAtom( MBool::BasicType() ); if( nl->IsEqual( arg1, MBool::BasicType() ) && nl->IsEqual( arg2, CcBool::BasicType() ) ) return nl->SymbolAtom( MBool::BasicType() ); if( nl->IsEqual( arg1, CcBool::BasicType() ) && nl->IsEqual( arg2, MBool::BasicType() ) ) return nl->SymbolAtom( MBool::BasicType() ); if( nl->IsEqual( arg1, MInt::BasicType() ) && nl->IsEqual( arg2, MInt::BasicType() ) ) return nl->SymbolAtom( MInt::BasicType() ); if( nl->IsEqual( arg1, MInt::BasicType() ) && nl->IsEqual( arg2, CcInt::BasicType() ) ) return nl->SymbolAtom( MInt::BasicType() ); if( nl->IsEqual( arg1, CcInt::BasicType() ) && nl->IsEqual( arg2, MInt::BasicType() ) ) return nl->SymbolAtom( MInt::BasicType() ); if( nl->IsEqual( arg1, MReal::BasicType() ) && nl->IsEqual( arg2, MReal::BasicType() ) ) return nl->SymbolAtom( MReal::BasicType() ); if( nl->IsEqual( arg1, MReal::BasicType() ) && nl->IsEqual( arg2, CcReal::BasicType() ) ) return nl->SymbolAtom( MReal::BasicType() ); if( nl->IsEqual( arg1, CcReal::BasicType() ) && nl->IsEqual( arg2, MReal::BasicType() ) ) return nl->SymbolAtom( MReal::BasicType() ); if( nl->IsEqual( arg1, MPoint::BasicType() ) && nl->IsEqual( arg2, Points::BasicType() ) ) return nl->SymbolAtom( MPoint::BasicType() ); if( nl->IsEqual( arg1, MPoint::BasicType() ) && nl->IsEqual( arg2, Line::BasicType() ) ) return nl->SymbolAtom( MPoint::BasicType() ); if( nl->IsEqual( arg1, Points::BasicType() ) && nl->IsEqual( arg2, MPoint::BasicType() ) ) return nl->SymbolAtom( MPoint::BasicType() ); if( nl->IsEqual( arg1, MPoint::BasicType() ) && nl->IsEqual( arg2, MPoint::BasicType() ) ) return nl->SymbolAtom( MPoint::BasicType() ); if( nl->IsEqual( arg1, Line::BasicType() ) && nl->IsEqual( arg2, MPoint::BasicType() ) ) return nl->SymbolAtom( MPoint::BasicType() ); if( nl->IsEqual( arg1, MString::BasicType() ) && nl->IsEqual( arg2, MString::BasicType() ) ) return nl->SymbolAtom( MString::BasicType() ); if( nl->IsEqual( arg1, MString::BasicType() ) && nl->IsEqual( arg2, CcString::BasicType() ) ) return nl->SymbolAtom( MString::BasicType() ); if( nl->IsEqual( arg1, CcString::BasicType() ) && nl->IsEqual( arg2, MString::BasicType() ) ) return nl->SymbolAtom( MString::BasicType() ); } return nl->SymbolAtom( Symbol::TYPEERROR() ); } /* 16.1 Type mapping function ~MovingMinusTypeMap~ It is for the operator ~minus~. */ ListExpr MovingMinusTypeMap( ListExpr args ) { if ( nl->ListLength( args ) == 2 ) { ListExpr arg1 = nl->First( args ), arg2 = nl->Second( args ); if( nl->IsEqual( arg1, MBool::BasicType() ) && nl->IsEqual( arg2, MBool::BasicType() ) ) return nl->SymbolAtom( MBool::BasicType() ); if( nl->IsEqual( arg1, MBool::BasicType() ) && nl->IsEqual( arg2, CcBool::BasicType() ) ) return nl->SymbolAtom( MBool::BasicType() ); if( nl->IsEqual( arg1, CcBool::BasicType() ) && nl->IsEqual( arg2, MBool::BasicType() ) ) return nl->SymbolAtom( MBool::BasicType() ); if( nl->IsEqual( arg1, MInt::BasicType() ) && nl->IsEqual( arg2, MInt::BasicType() ) ) return nl->SymbolAtom( MInt::BasicType() ); if( nl->IsEqual( arg1, MInt::BasicType() ) && nl->IsEqual( arg2, CcInt::BasicType() ) ) return nl->SymbolAtom( MInt::BasicType() ); if( nl->IsEqual( arg1, CcInt::BasicType() ) && nl->IsEqual( arg2, MInt::BasicType() ) ) return nl->SymbolAtom( MInt::BasicType() ); if( nl->IsEqual( arg1, MReal::BasicType() ) && nl->IsEqual( arg2, MReal::BasicType() ) ) return nl->SymbolAtom( MReal::BasicType() ); if( nl->IsEqual( arg1, MReal::BasicType() ) && nl->IsEqual( arg2, CcReal::BasicType() ) ) return nl->SymbolAtom( MReal::BasicType() ); if( nl->IsEqual( arg1, CcReal::BasicType() ) && nl->IsEqual( arg2, MReal::BasicType() ) ) return nl->SymbolAtom( MReal::BasicType() ); if( nl->IsEqual( arg1, MPoint::BasicType() ) && nl->IsEqual( arg2, MPoint::BasicType() ) ) return nl->SymbolAtom( MPoint::BasicType() ); if( nl->IsEqual( arg1, MPoint::BasicType() ) && nl->IsEqual( arg2, Point::BasicType() ) ) return nl->SymbolAtom( MPoint::BasicType() ); if( nl->IsEqual( arg1, Point::BasicType() ) && nl->IsEqual( arg2, MPoint::BasicType() ) ) return nl->SymbolAtom( MPoint::BasicType() ); if(nl->IsEqual(nl->First(args), Region::BasicType()) && nl->IsEqual(nl->Second(args), MPoint::BasicType())) return nl->SymbolAtom(MRegion::BasicType()); if(nl->IsEqual(nl->First(args), MRegion::BasicType()) && nl->IsEqual(nl->Second(args), Point::BasicType())) return nl->SymbolAtom(MRegion::BasicType()); if(nl->IsEqual(nl->First(args), MRegion::BasicType()) && nl->IsEqual(nl->Second(args), MPoint::BasicType())) return nl->SymbolAtom(MRegion::BasicType()); if(nl->IsEqual(nl->First(args), MRegion::BasicType()) && nl->IsEqual(nl->Second(args), Points::BasicType())) return nl->SymbolAtom(MRegion::BasicType()); if(nl->IsEqual(nl->First(args), MRegion::BasicType()) && nl->IsEqual(nl->Second(args), Line::BasicType())) return nl->SymbolAtom(MRegion::BasicType()); if( nl->IsEqual( arg1, MString::BasicType() ) && nl->IsEqual( arg2, MString::BasicType() ) ) return nl->SymbolAtom( MString::BasicType() ); if( nl->IsEqual( arg1, MString::BasicType() ) && nl->IsEqual( arg2, CcString::BasicType() ) ) return nl->SymbolAtom( MString::BasicType() ); if( nl->IsEqual( arg1, CcString::BasicType() ) && nl->IsEqual( arg2, MString::BasicType() ) ) return nl->SymbolAtom( MString::BasicType() ); } return nl->SymbolAtom( Symbol::TYPEERROR() ); } /* 16.1 Type mapping function ~InsideTypeMapMBool~ It is for the operator ~inside~ */ ListExpr InsideTypeMapMBool( ListExpr args ) { if ( nl->ListLength( args ) == 2 ) { ListExpr arg1 = nl->First( args ), arg2 = nl->Second( args ); if ((nl->IsEqual( arg1, MPoint::BasicType() ) && nl->IsEqual( arg2, Points::BasicType() ))) return nl->SymbolAtom( MBool::BasicType() ); if ((nl->IsEqual( arg1, MPoint::BasicType() ) && nl->IsEqual( arg2, Line::BasicType() ))) return nl->SymbolAtom( MBool::BasicType() ); if(nl->IsEqual( arg1, MRegion::BasicType()) && nl->IsEqual( arg2, Points::BasicType())) return nl->SymbolAtom(MBool::BasicType()); if(nl->IsEqual( arg1, MRegion::BasicType()) && nl->IsEqual( arg2, Line::BasicType())) return nl->SymbolAtom(MBool::BasicType()); } return nl->SymbolAtom( Symbol::TYPEERROR() ); } /* 16.1 Type mapping function ~PerimeterTypeMap~ Used by ~perimeter~ and ~area~ */ static ListExpr PerimeterTypeMap(ListExpr args) { if (nl->ListLength(args) == 1 && nl->IsEqual(nl->First(args), MRegion::BasicType())) return nl->SymbolAtom(MReal::BasicType()); else return nl->SymbolAtom(Symbol::TYPEERROR()); } /* 16.1 Type mapping function ~RCenterTypeMap~ Used by ~rough\_center~ */ static ListExpr RCenterTypeMap(ListExpr args) { if (nl->ListLength(args) == 1 && nl->IsEqual(nl->First(args), MRegion::BasicType())) return nl->SymbolAtom(MPoint::BasicType()); else return nl->SymbolAtom(Symbol::TYPEERROR()); } /* 16.1 Type mapping function ~NComponentsTypeMap~ Used by ~no\_components~ */ static ListExpr NComponentsTypeMap(ListExpr args) { if (nl->ListLength(args) == 1 && nl->IsEqual(nl->First(args), MRegion::BasicType())) return nl->SymbolAtom(MInt::BasicType()); else return nl->SymbolAtom(Symbol::TYPEERROR()); } /* 16.1 Type mapping function ~UnionTypeMap~ Used by ~union~: */ static ListExpr UnionTypeMap(ListExpr args) { if (nl->ListLength(args) == 2){ if(nl->IsEqual(nl->First(args), MPoint::BasicType()) && nl->IsEqual(nl->Second(args), Region::BasicType())) return nl->SymbolAtom(MRegion::BasicType()); if(nl->IsEqual(nl->First(args), MPoint::BasicType()) && nl->IsEqual(nl->Second(args), MRegion::BasicType())) return nl->SymbolAtom(MRegion::BasicType()); if(nl->IsEqual(nl->First(args), Point::BasicType()) && nl->IsEqual(nl->Second(args), MRegion::BasicType())) return nl->SymbolAtom(MRegion::BasicType()); else return nl->SymbolAtom(Symbol::TYPEERROR()); } else return nl->SymbolAtom(Symbol::TYPEERROR()); } /* 16.1 Type mapping function ~TemporalLiftIsemptyTypeMap~ Used by ~isempty~: */ static ListExpr TemporalLiftIsemptyTypeMap(ListExpr args) { if (nl->ListLength(args) == 1){ if(nl->IsEqual(nl->First(args), MRegion::BasicType())) return nl->SymbolAtom(MBool::BasicType()); if(nl->IsEqual(nl->First(args), MBool::BasicType())) return nl->SymbolAtom(MBool::BasicType()); if(nl->IsEqual(nl->First(args), MInt::BasicType())) return nl->SymbolAtom(MBool::BasicType()); if(nl->IsEqual(nl->First(args), MReal::BasicType())) return nl->SymbolAtom(MBool::BasicType()); if(nl->IsEqual(nl->First(args), MPoint::BasicType())) return nl->SymbolAtom(MBool::BasicType()); if(nl->IsEqual(nl->First(args), MString::BasicType())) return nl->SymbolAtom(MBool::BasicType()); if (CMPoint::checkType(nl->First(args))) { return nl->SymbolAtom(MBool::BasicType()); } else return nl->SymbolAtom(Symbol::TYPEERROR()); } else return nl->SymbolAtom(Symbol::TYPEERROR()); } /* 16.1 Type mapping function ~periods2mint~ Signature: periods [ x periods] -> mint */ static ListExpr periods2mintTM(ListExpr args) { string err = "periods [ x periods] expected"; int len = nl->ListLength(args); if((len!=1) && (len!=2)){ return listutils::typeError(err); } if(!Periods::checkType(nl->First(args))){ return listutils::typeError(err); } if((len==2) && !Periods::checkType(nl->Second(args))){ return listutils::typeError(err); } return nl->SymbolAtom(MInt::BasicType()); } /* 16.1 Type Mapping function ~createmint~ Signature: periods x int -> mint */ static ListExpr createmintTM(ListExpr args){ string err = "periods x int expected"; if(!nl->HasLength(args,2)){ return listutils::typeError(err + " ( wrong number of arguments)"); } if(!Periods::checkType(nl->First(args)) || !CcInt::checkType(nl->Second(args))){ return listutils::typeError(err ); } return nl->SymbolAtom(MInt::BasicType()); } /* 16.1 Type mapping function ~TemporalPlusTypeMap~ Used by ~+~: */ static ListExpr TemporalPlusTypeMap(ListExpr args) { if (nl->ListLength(args) == 2 && nl->IsEqual(nl->First(args), MInt::BasicType()) && nl->IsEqual(nl->Second(args), MInt::BasicType())) return nl->SymbolAtom(MInt::BasicType()); else return nl->SymbolAtom(Symbol::TYPEERROR()); } /* 16.1 Type mapping function ~TemporalZeroTypeMap~ Used by ~zero~: */ static ListExpr TemporalZeroTypeMap(ListExpr args) {; if (nl->ListLength(args) == 0) return nl->SymbolAtom(MInt::BasicType()); else return nl->SymbolAtom(Symbol::TYPEERROR()); } /* 16.1 Type mapping function ~TemporalConcatTypeMap~ Used by ~concat~: */ static ListExpr TemporalConcatTypeMap(ListExpr args) { if (nl->ListLength(args) == 2 && nl->IsEqual(nl->First(args), MPoint::BasicType()) && nl->IsEqual(nl->Second(args), MPoint::BasicType()) ) return nl->SymbolAtom(MPoint::BasicType()); else return nl->SymbolAtom(Symbol::TYPEERROR()); } /* 16.1 Type mapping function ~ABSTypeMap~ It is for the operator ~abs~ */ ListExpr ABSTypeMap( ListExpr args ) { if ( nl->ListLength( args ) == 1 ) { ListExpr arg1 = nl->First( args ); if( nl->IsEqual( arg1, MReal::BasicType() )) return nl->SymbolAtom( MReal::BasicType() ); } return nl->SymbolAtom( Symbol::TYPEERROR() ); } /* 1 Selection-Functions 16.2 Selection function ~MovingAndOrSelect~ Is used for the ~and~ and ~or~ operations. */ int MovingAndOrSelect( ListExpr args ) { ListExpr arg1 = nl->First( args ), arg2 = nl->Second( args ); if( nl->SymbolValue( arg1 ) == MBool::BasicType() && nl->SymbolValue( arg2 ) == MBool::BasicType() ) return 0; if( nl->SymbolValue( arg1 ) == MBool::BasicType() && nl->SymbolValue( arg2 ) == CcBool::BasicType() ) return 1; if( nl->SymbolValue( arg1 ) == CcBool::BasicType() && nl->SymbolValue( arg2 ) == MBool::BasicType() ) return 2; return -1; // This point should never be reached } /* 16.2 Selection function ~MovingEqualSelect~ Is used for the ~mequal~ and ~mnotequal~ operations. */ int MovingEqualSelect( ListExpr args ) { ListExpr arg1 = nl->First( args ), arg2 = nl->Second( args ); if( nl->SymbolValue( arg1 ) == MBool::BasicType() && nl->SymbolValue( arg2 ) == MBool::BasicType() ) return 0; if( nl->SymbolValue( arg1 ) == MBool::BasicType() && nl->SymbolValue( arg2 ) == CcBool::BasicType() ) return 1; if( nl->SymbolValue( arg1 ) == CcBool::BasicType() && nl->SymbolValue( arg2 ) == MBool::BasicType() ) return 2; if( nl->SymbolValue( arg1 ) == MInt::BasicType() && nl->SymbolValue( arg2 ) == MInt::BasicType() ) return 3; if( nl->SymbolValue( arg1 ) == MInt::BasicType() && nl->SymbolValue( arg2 ) == CcInt::BasicType() ) return 4; if( nl->SymbolValue( arg1 ) == CcInt::BasicType() && nl->SymbolValue( arg2 ) == MInt::BasicType() ) return 5; if( nl->SymbolValue( arg1 ) == MString::BasicType() && nl->SymbolValue( arg2 ) == MString::BasicType() ) return 6; if( nl->SymbolValue( arg1 ) == MString::BasicType() && nl->SymbolValue( arg2 ) == CcString::BasicType() ) return 7; if( nl->SymbolValue( arg1 ) == CcString::BasicType() && nl->SymbolValue( arg2 ) == MString::BasicType() ) return 8; if( nl->SymbolValue( arg1 ) == MReal::BasicType() && nl->SymbolValue( arg2 ) == MReal::BasicType() ) return 9; if( nl->SymbolValue( arg1 ) == MReal::BasicType() && nl->SymbolValue( arg2 ) == CcReal::BasicType() ) return 10; if( nl->SymbolValue( arg1 ) == CcReal::BasicType() && nl->SymbolValue( arg2 ) == MReal::BasicType() ) return 11; if( nl->SymbolValue( arg1 ) == MPoint::BasicType() && nl->SymbolValue( arg2 ) == MPoint::BasicType() ) return 12; if( nl->SymbolValue( arg1 ) == MPoint::BasicType() && nl->SymbolValue( arg2 ) == Point::BasicType() ) return 13; if( nl->SymbolValue( arg1 ) == Point::BasicType() && nl->SymbolValue( arg2 ) == MPoint::BasicType() ) return 14; if( nl->SymbolValue( arg1 ) == MRegion::BasicType() && nl->SymbolValue( arg2 ) == Region::BasicType() ) return 15; if( nl->SymbolValue( arg1 ) == Region::BasicType() && nl->SymbolValue( arg2 ) == MRegion::BasicType() ) return 16; if( nl->SymbolValue( arg1 ) == MRegion::BasicType() && nl->SymbolValue( arg2 ) == MRegion::BasicType() ) return 17; return -1; // This point should never be reached } /* 16.2 Selection function ~MovingCompareSelect~ Is used for the ~mequal~ and ~mnotequal~ operations. */ int MovingCompareSelect( ListExpr args ) { ListExpr arg1 = nl->First( args ), arg2 = nl->Second( args ); if( nl->SymbolValue( arg1 ) == MBool::BasicType() && nl->SymbolValue( arg2 ) == MBool::BasicType() ) return 0; if( nl->SymbolValue( arg1 ) == MBool::BasicType() && nl->SymbolValue( arg2 ) == CcBool::BasicType() ) return 1; if( nl->SymbolValue( arg1 ) == CcBool::BasicType() && nl->SymbolValue( arg2 ) == MBool::BasicType() ) return 2; if( nl->SymbolValue( arg1 ) == MInt::BasicType() && nl->SymbolValue( arg2 ) == MInt::BasicType() ) return 3; if( nl->SymbolValue( arg1 ) == MInt::BasicType() && nl->SymbolValue( arg2 ) == CcInt::BasicType() ) return 4; if( nl->SymbolValue( arg1 ) == CcInt::BasicType() && nl->SymbolValue( arg2 ) == MInt::BasicType() ) return 5; if( nl->SymbolValue( arg1 ) == MReal::BasicType() && nl->SymbolValue( arg2 ) == MReal::BasicType() ) return 6; if( nl->SymbolValue( arg1 ) == MReal::BasicType() && nl->SymbolValue( arg2 ) == CcReal::BasicType() ) return 7; if( nl->SymbolValue( arg1 ) == CcReal::BasicType() && nl->SymbolValue( arg2 ) == MReal::BasicType() ) return 8; if( nl->SymbolValue( arg1 ) == MString::BasicType() && nl->SymbolValue( arg2 ) == MString::BasicType() ) return 9; if( nl->SymbolValue( arg1 ) == MString::BasicType() && nl->SymbolValue( arg2 ) == CcString::BasicType() ) return 10; if( nl->SymbolValue( arg1 ) == CcString::BasicType() && nl->SymbolValue( arg2 ) == MString::BasicType() ) return 11; return -1; // This point should never be reached } /* 16.2 Selection function ~MovingAddSelect~ Is used for the ~-~ and ~+~ operations. */ int MovingAddSelect( ListExpr args ) { ListExpr arg1 = nl->First( args ), arg2 = nl->Second( args ); if( nl->SymbolValue( arg1 ) == MInt::BasicType() && nl->SymbolValue( arg2 ) == CcInt::BasicType() ) return 0; if( nl->SymbolValue( arg1 ) == MInt::BasicType() && nl->SymbolValue( arg2 ) == CcReal::BasicType() ) return 1; if( nl->SymbolValue( arg1 ) == MReal::BasicType() && nl->SymbolValue( arg2 ) == CcReal::BasicType() ) return 2; if( nl->SymbolValue( arg1 ) == MReal::BasicType() && nl->SymbolValue( arg2 ) == CcInt::BasicType() ) return 3; if( nl->SymbolValue( arg1 ) == CcInt::BasicType() && nl->SymbolValue( arg2 ) == MInt::BasicType() ) return 4; if( nl->SymbolValue( arg1 ) == CcReal::BasicType() && nl->SymbolValue( arg2 ) == MInt::BasicType() ) return 5; if( nl->SymbolValue( arg1 ) == CcReal::BasicType() && nl->SymbolValue( arg2 ) == MReal::BasicType() ) return 6; if( nl->SymbolValue( arg1 ) == CcInt::BasicType() && nl->SymbolValue( arg2 ) == MReal::BasicType() ) return 7; if( nl->SymbolValue( arg1 ) == MInt::BasicType() && nl->SymbolValue( arg2 ) == MInt::BasicType() ) return 8; if( nl->SymbolValue( arg1 ) == MInt::BasicType() && nl->SymbolValue( arg2 ) == MReal::BasicType() ) return 9; if( nl->SymbolValue( arg1 ) == MReal::BasicType() && nl->SymbolValue( arg2 ) == MReal::BasicType() ) return 10; if( nl->SymbolValue( arg1 ) == MReal::BasicType() && nl->SymbolValue( arg2 ) == MInt::BasicType() ) return 11; return -1; // This point should never be reached } /* 16.2 Selection function ~MovingMultiplySelect~ Is used for the ~multiplication~ operation. */ int MovingMultiplySelect( ListExpr args ) { ListExpr arg1 = nl->First( args ), arg2 = nl->Second( args ); if( nl->SymbolValue( arg1 ) == MInt::BasicType() && nl->SymbolValue( arg2 ) == CcInt::BasicType() ) return 0; if( nl->SymbolValue( arg1 ) == MInt::BasicType() && nl->SymbolValue( arg2 ) == CcReal::BasicType() ) return 1; if( nl->SymbolValue( arg1 ) == MReal::BasicType() && nl->SymbolValue( arg2 ) == CcReal::BasicType() ) return 2; if( nl->SymbolValue( arg1 ) == MReal::BasicType() && nl->SymbolValue( arg2 ) == CcInt::BasicType() ) return 3; if( nl->SymbolValue( arg1 ) == CcInt::BasicType() && nl->SymbolValue( arg2 ) == MInt::BasicType() ) return 4; if( nl->SymbolValue( arg1 ) == CcReal::BasicType() && nl->SymbolValue( arg2 ) == MInt::BasicType() ) return 5; if( nl->SymbolValue( arg1 ) == CcInt::BasicType() && nl->SymbolValue( arg2 ) == MReal::BasicType() ) return 6; if( nl->SymbolValue( arg1 ) == CcReal::BasicType() && nl->SymbolValue( arg2 ) == MReal::BasicType() ) return 7; if( nl->SymbolValue( arg1 ) == MInt::BasicType() && nl->SymbolValue( arg2 ) == MInt::BasicType() ) return 8; if( nl->SymbolValue( arg1 ) == MInt::BasicType() && nl->SymbolValue( arg2 ) == MReal::BasicType() ) return 9; if( nl->SymbolValue( arg1 ) == MReal::BasicType() && nl->SymbolValue( arg2 ) == MInt::BasicType() ) return 10; return -1; // This point should never be reached } /* 16.2 Selection function ~MovingDivideSelect~ Is used for the ~/~ operation. */ int MovingDivideSelect( ListExpr args ) { ListExpr arg1 = nl->First( args ), arg2 = nl->Second( args ); if( nl->SymbolValue( arg1 ) == MInt::BasicType() && nl->SymbolValue( arg2 ) == CcInt::BasicType() ) return 0; if( nl->SymbolValue( arg1 ) == MInt::BasicType() && nl->SymbolValue( arg2 ) == CcReal::BasicType() ) return 1; if( nl->SymbolValue( arg1 ) == MReal::BasicType() && nl->SymbolValue( arg2 ) == CcReal::BasicType() ) return 2; if( nl->SymbolValue( arg1 ) == MReal::BasicType() && nl->SymbolValue( arg2 ) == CcInt::BasicType() ) return 3; if( nl->SymbolValue( arg1 ) == CcInt::BasicType() && nl->SymbolValue( arg2 ) == MInt::BasicType() ) return 4; if( nl->SymbolValue( arg1 ) == CcReal::BasicType() && nl->SymbolValue( arg2 ) == MInt::BasicType() ) return 5; if( nl->SymbolValue( arg1 ) == MInt::BasicType() && nl->SymbolValue( arg2 ) == MInt::BasicType() ) return 6; if( nl->SymbolValue( arg1 ) == MReal::BasicType() && nl->SymbolValue( arg2 ) == MInt::BasicType() ) return 7; return -1; // This point should never be reached } /* 16.2 Selection function ~MovingDistanceSelect~ Is used for the ~distance~ operation. */ int MovingDistanceSelect( ListExpr args ) { ListExpr arg1 = nl->First( args ), arg2 = nl->Second( args ); if( nl->SymbolValue( arg1 ) == MPoint::BasicType() && nl->SymbolValue( arg2 ) == MPoint::BasicType() ) return 0; if( nl->SymbolValue( arg1 ) == MReal::BasicType() && nl->SymbolValue( arg2 ) == MReal::BasicType() ) return 1; if( nl->SymbolValue( arg1 ) == MReal::BasicType() && nl->SymbolValue( arg2 ) == CcReal::BasicType() ) return 2; if( nl->SymbolValue( arg1 ) == CcReal::BasicType() && nl->SymbolValue( arg2 ) == MReal::BasicType() ) return 3; if(UPoint::checkType(arg1) && UPoint::checkType(arg2)) return 4; if(UPoint::checkType(arg1) && Point::checkType(arg2)) return 5; if(Point::checkType(arg1) && UPoint::checkType(arg2)) return 6; return -1; // This point should never be reached } /* 16.2 Selection function ~FrechetDistanceSelect~ Is used for the ~frechetdistance~ operation. */ int FrechetDistanceSelect(ListExpr args) { if (nl->HasLength(args, 2)) return 0; if (nl->HasLength(args, 3)) return 1; return -1; // This point should never be reached } /* 16.2 Selection function ~MovingIntersectionSelect~ Is used for the ~intersect~ operation. */ int MovingIntersectionSelect( ListExpr args ) { ListExpr arg1 = nl->First( args ), arg2 = nl->Second( args ); if( nl->SymbolValue( arg1 ) == MBool::BasicType() && nl->SymbolValue( arg2 ) == MBool::BasicType() ) return 0; if( nl->SymbolValue( arg1 ) == MBool::BasicType() && nl->SymbolValue( arg2 ) == CcBool::BasicType() ) return 1; if( nl->SymbolValue( arg1 ) == CcBool::BasicType() && nl->SymbolValue( arg2 ) == MBool::BasicType() ) return 2; if( nl->SymbolValue( arg1 ) == MInt::BasicType() && nl->SymbolValue( arg2 ) == MInt::BasicType() ) return 3; if( nl->SymbolValue( arg1 ) == MInt::BasicType() && nl->SymbolValue( arg2 ) == CcInt::BasicType() ) return 4; if( nl->SymbolValue( arg1 ) == CcInt::BasicType() && nl->SymbolValue( arg2 ) == MInt::BasicType() ) return 5; if( nl->SymbolValue( arg1 ) == MReal::BasicType() && nl->SymbolValue( arg2 ) == MReal::BasicType() ) return 6; if( nl->SymbolValue( arg1 ) == MReal::BasicType() && nl->SymbolValue( arg2 ) == CcReal::BasicType() ) return 7; if( nl->SymbolValue( arg1 ) == CcReal::BasicType() && nl->SymbolValue( arg2 ) == MReal::BasicType() ) return 8; if( nl->SymbolValue( arg1 ) == MPoint::BasicType() && nl->SymbolValue( arg2 ) == Points::BasicType() ) return 9; if( nl->SymbolValue( arg1 ) == MPoint::BasicType() && nl->SymbolValue( arg2 ) == Line::BasicType() ) return 10; if( nl->SymbolValue( arg1 ) == Points::BasicType() && nl->SymbolValue( arg2 ) == MPoint::BasicType() ) return 11; if( nl->SymbolValue( arg1 ) == Line::BasicType() && nl->SymbolValue( arg2 ) == MPoint::BasicType() ) return 12; if( nl->SymbolValue( arg1 ) == MString::BasicType() && nl->SymbolValue( arg2 ) == MString::BasicType() ) return 13; if( nl->SymbolValue( arg1 ) == MString::BasicType() && nl->SymbolValue( arg2 ) == CcString::BasicType() ) return 14; if( nl->SymbolValue( arg1 ) == CcString::BasicType() && nl->SymbolValue( arg2 ) == MString::BasicType() ) return 15; if( nl->SymbolValue( arg1 ) == MPoint::BasicType() && nl->SymbolValue( arg2 ) == MPoint::BasicType() ) return 16; return -1; // This point should never be reached } /* 16.2 Selection function ~MovingMinusSelect~ Is used for the ~minus~ operation. */ int MovingMinusSelect( ListExpr args ) { if (nl->ListLength(args) != 2) return -1; ListExpr arg1 = nl->First( args ), arg2 = nl->Second( args ); if( nl->SymbolValue( arg1 ) == MBool::BasicType() && nl->SymbolValue( arg2 ) == MBool::BasicType() ) return 0; if( nl->SymbolValue( arg1 ) == MBool::BasicType() && nl->SymbolValue( arg2 ) == CcBool::BasicType() ) return 1; if( nl->SymbolValue( arg1 ) == CcBool::BasicType() && nl->SymbolValue( arg2 ) == MBool::BasicType() ) return 2; if( nl->SymbolValue( arg1 ) == MInt::BasicType() && nl->SymbolValue( arg2 ) == MInt::BasicType() ) return 3; if( nl->SymbolValue( arg1 ) == MInt::BasicType() && nl->SymbolValue( arg2 ) == CcInt::BasicType() ) return 4; if( nl->SymbolValue( arg1 ) == CcInt::BasicType() && nl->SymbolValue( arg2 ) == MInt::BasicType() ) return 5; if( nl->SymbolValue( arg1 ) == MReal::BasicType() && nl->SymbolValue( arg2 ) == MReal::BasicType() ) return 6; if( nl->SymbolValue( arg1 ) == MReal::BasicType() && nl->SymbolValue( arg2 ) == CcReal::BasicType() ) return 7; if( nl->SymbolValue( arg1 ) == CcReal::BasicType() && nl->SymbolValue( arg2 ) == MReal::BasicType() ) return 8; if( nl->SymbolValue( arg1 ) == MPoint::BasicType() && nl->SymbolValue( arg2 ) == MPoint::BasicType() ) return 9; if( nl->SymbolValue( arg1 ) == MPoint::BasicType() && nl->SymbolValue( arg2 ) == Point::BasicType() ) return 10; if( nl->SymbolValue( arg1 ) == Point::BasicType() && nl->SymbolValue( arg2 ) == MPoint::BasicType() ) return 11; if(nl->SymbolValue(nl->First(args)) == Region::BasicType() && nl->SymbolValue(nl->Second(args)) == MPoint::BasicType()) return 12; if (nl->SymbolValue(nl->First(args)) == MRegion::BasicType() && nl->SymbolValue(nl->Second(args)) == Point::BasicType()) return 13; if (nl->SymbolValue(nl->First(args)) == MRegion::BasicType() && nl->SymbolValue(nl->Second(args)) == MPoint::BasicType()) return 14; if (nl->SymbolValue(nl->First(args)) == MRegion::BasicType() && nl->SymbolValue(nl->Second(args)) == Points::BasicType()) return 15; if (nl->SymbolValue(nl->First(args)) == MRegion::BasicType() && nl->SymbolValue(nl->Second(args)) == Line::BasicType()) return 16; if( nl->SymbolValue( arg1 ) == MString::BasicType() && nl->SymbolValue( arg2 ) == MString::BasicType() ) return 17; if( nl->SymbolValue( arg1 ) == MString::BasicType() && nl->SymbolValue( arg2 ) == CcString::BasicType() ) return 18; if( nl->SymbolValue( arg1 ) == CcString::BasicType() && nl->SymbolValue( arg2 ) == MString::BasicType() ) return 19; return -1; // This point should never be reached } /* 16.2. Selection function ~InsideSelect~ Is used for the ~inside~ operation. */ int InsideSelect( ListExpr args ) { ListExpr arg1 = nl->First( args ), arg2 = nl->Second( args ); if (nl->ListLength(args) == 2){ if( nl->SymbolValue( arg1 ) == MPoint::BasicType() && nl->SymbolValue( arg2 ) == Points::BasicType() ) return 0; if( nl->SymbolValue( arg1 ) == MPoint::BasicType() && nl->SymbolValue( arg2 ) == Line::BasicType() ) return 1; if (nl->SymbolValue(nl->First(args)) == MRegion::BasicType() && nl->SymbolValue(nl->Second(args)) == Points::BasicType()) return 2; if (nl->SymbolValue(nl->First(args)) == MRegion::BasicType() && nl->SymbolValue(nl->Second(args)) == Line::BasicType()) return 3; return -1; // This point should never be reached } else return -1; } /* 16.2 Selection function ~UnionSelect~ Is used for the ~union~ operation. */ static int UnionSelect(ListExpr args) { if (nl->ListLength(args) == 2){ if(nl->SymbolValue(nl->First(args)) == MPoint::BasicType() && nl->SymbolValue(nl->Second(args)) == Region::BasicType()) return 0; else if (nl->SymbolValue(nl->First(args)) == MPoint::BasicType() && nl->SymbolValue(nl->Second(args)) == MRegion::BasicType()) return 1; else if (nl->SymbolValue(nl->First(args)) == Point::BasicType() && nl->SymbolValue(nl->Second(args)) == MRegion::BasicType()) return 2; else return -1; } else return -1; } /* 16.2 Selection function ~TemporalLiftIsemptySelect~ Is used for the ~isempty~ operation. */ static int TemporalLiftIsemptySelect(ListExpr args) { if (nl->ListLength(args) == 1){ if(nl->SymbolValue(nl->First(args)) == MRegion::BasicType()) return 0; else if (nl->SymbolValue(nl->First(args)) == MBool::BasicType()) return 1; else if (nl->SymbolValue(nl->First(args)) == MInt::BasicType()) return 2; else if (nl->SymbolValue(nl->First(args)) == MReal::BasicType()) return 3; else if (nl->SymbolValue(nl->First(args)) == MPoint::BasicType()) return 4; else if (nl->SymbolValue(nl->First(args)) == MString::BasicType()) return 5; else if (CMPoint::checkType(nl->First(args))) { return 6; } else return -1; } else return -1; } /* 1 ValueMapping-Functions 16.3 Value mapping functions of operator ~\=~, ~<~, ~<\=~, ~>\=~,~>~ and ~\#~ for two mbool, mint and mstring */ template int TemporalMMCompare( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingCompareBoolMM ( *((Mapping1*)args[0].addr), *((Mapping2*)args[1].addr), *((MBool*)result.addr), op); return 0; } /* 16.3 Value mapping functions of operator ~\=~, ~<~, ~<\=~, ~>\=~,~>~ and ~\#~ for mreal/mreal */ template int TemporalMMRealCompare( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingRealCompareMM2(*((MReal*)args[0].addr), *((MReal*)args[1].addr), *((MBool*)result.addr), op); return 0; } /* 16.3 Value mapping functions of operator ~\=~, ~<~, ~<\=~, ~>\=~,~>~ and ~\#~ for mreal/real */ template int TemporalMSRealCompare( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingRealCompareMS(*((MReal*)args[0].addr), *((CcReal*)args[1].addr), *((MBool*)result.addr), op, true); return 0; } /* 16.3 Value mapping functions of operator ~\=~, ~<~, ~<\=~, ~>\=~,~>~ and ~\#~ for real/mreal */ template int TemporalSMRealCompare( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); //int newop = op; //if (op > -3 && op < 3) newop = -op; MovingRealCompareMS(*((MReal*)args[1].addr), *((CcReal*)args[0].addr), *((MBool*)result.addr), op, false); return 0; } /* 16.35 Value mapping functions of operator ~=~ and ~\#~ for mpoint/mpoint */ template int TemporalMMPointCompare( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingPointCompareMM(*((MPoint*)args[0].addr), *((MPoint*)args[1].addr), *((MBool*)result.addr), op); return 0; } /* 16.3 Value mapping functions of operator ~=~ and ~\#~ for mpoint/point */ template int TemporalMSPointCompare( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingPointCompareMS(*((MPoint*)args[0].addr), *((Point*)args[1].addr), *((MBool*)result.addr), op); return 0; } /* 16.3 Value mapping functions of operator ~=~ and ~\#~ for point/mpoint */ template int TemporalSMPointCompare( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingPointCompareMS(*((MPoint*)args[1].addr), *((Point*)args[0].addr), *((MBool*)result.addr), op); return 0; } /* 16.3 Value mapping functions of operator ~=~ and ~\#~ for mregion/region */ template int TemporalMSRegionCompare( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingRegionCompareMS((MRegion*)args[0].addr, (Region*)args[1].addr, (MBool*)result.addr, op); return 0; } /* 16.3 Value mapping functions of operator ~=~ and ~\#~ for region/mregion */ template int TemporalSMRegionCompare( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingRegionCompareMS((MRegion*)args[1].addr, (Region*)args[0].addr, (MBool*)result.addr, op); return 0; } /* 16.3 Value mapping functions of operator ~=~ and ~\#~ for mregion/mregion */ template int TemporalMMRegionCompare( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingRegionCompareMM((MRegion*)args[0].addr, (MRegion*)args[1].addr, (MBool*)result.addr, op); return 0; } /* 16.3 Value mapping functions of operators ~\=~, ~<~, ~<\=~, ~>\=~,~>~ and ~\#~ for mbool/bool, mint/int and mstring/string */ template int TemporalMSCompare( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingCompareBoolMS ( *((Mapping1*)args[0].addr), *((Operator2*)args[1].addr), *((MBool*)result.addr), op); return 0; } /* 16.3 Value mapping functions of operators ~\=~, ~<~, ~<\=~, ~>\=~,~>~ and ~\#~ for bool/mbool, int/mint and string/mstring */ template int TemporalSMCompare( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); int newop = op; if (op > -3 && op < 3) newop = -op; MovingCompareBoolMS ( *((Mapping1*)args[1].addr), *((Operator2*)args[0].addr), *((MBool*)result.addr), newop); return 0; } /* 16.3 Value mapping functions of operators ~-~, ~+~ for {mint, mreal} */ template int TemporalMIIAdd( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingAddMII( static_cast(args[0].addr), static_cast(args[1].addr), static_cast(result.addr), op); return 0; } template int TemporalMIRAdd( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingAddMIR( static_cast(args[0].addr), static_cast(args[1].addr), static_cast(result.addr), op); return 0; } template int TemporalMRRAdd( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingAddMRR( static_cast(args[0].addr), static_cast(args[1].addr), static_cast(result.addr), op); return 0; } template int TemporalMRIAdd( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingAddMRI( static_cast(args[0].addr), static_cast(args[1].addr), static_cast(result.addr), op); return 0; } template int TemporalIMIAdd( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingAddIMI( static_cast(args[0].addr), static_cast(args[1].addr), static_cast(result.addr), op); return 0; } template int TemporalRMIAdd( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingAddRMI( static_cast(args[0].addr), static_cast(args[1].addr), static_cast(result.addr), op); return 0; } template int TemporalRMRAdd( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingAddRMR( static_cast(args[0].addr), static_cast(args[1].addr), static_cast(result.addr), op); return 0; } template int TemporalIMRAdd( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingAddIMR( static_cast(args[0].addr), static_cast(args[1].addr), static_cast(result.addr), op); return 0; } template int TemporalMIMIAdd( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingAddMIMI( static_cast(args[0].addr), static_cast(args[1].addr), static_cast(result.addr), op); return 0; } template int TemporalMIMRAdd( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingAddMIMR( static_cast(args[0].addr), static_cast(args[1].addr), static_cast(result.addr), op); return 0; } template int TemporalMRMRAdd( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingAddMRMR( static_cast(args[0].addr), static_cast(args[1].addr), static_cast(result.addr), op); return 0; } template int TemporalMRMIAdd( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingAddMRMI( static_cast(args[0].addr), static_cast(args[1].addr), static_cast(result.addr), op); return 0; } /* 16.3 Value mapping functions of the multiplication and division operators for {mint, mreal} */ int TemporalMIIMultiply( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingMultiplyMII( static_cast(args[0].addr), static_cast(args[1].addr), static_cast(result.addr)); return 0; } template int TemporalMIRMultiply( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingMultiplyMIR( static_cast(args[0].addr), static_cast(args[1].addr), static_cast(result.addr), inverseSecond); return 0; } template int TemporalMRRMultiply( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingMultiplyMRR( static_cast(args[0].addr), static_cast(args[1].addr), static_cast(result.addr), inverseSecond); return 0; } template int TemporalMRIMultiply( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingMultiplyMRI( static_cast(args[0].addr), static_cast(args[1].addr), static_cast(result.addr), inverseSecond); return 0; } int TemporalIMIMultiply( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingMultiplyIMI( static_cast(args[0].addr), static_cast(args[1].addr), static_cast(result.addr)); return 0; } template int TemporalRMIMultiply( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingMultiplyRMI( static_cast(args[0].addr), static_cast(args[1].addr), static_cast(result.addr), inverseSecond); return 0; } int TemporalIMRMultiply( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingMultiplyIMR( static_cast(args[0].addr), static_cast(args[1].addr), static_cast(result.addr)); return 0; } int TemporalRMRMultiply( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingMultiplyRMR( static_cast(args[0].addr), static_cast(args[1].addr), static_cast(result.addr)); return 0; } int TemporalMIMIMultiply( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingMultiplyMIMI( static_cast(args[0].addr), static_cast(args[1].addr), static_cast(result.addr)); return 0; } int TemporalMIMRMultiply( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingMultiplyMIMR( static_cast(args[0].addr), static_cast(args[1].addr), static_cast(result.addr)); return 0; } template int TemporalMRMIMultiply( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingMultiplyMRMI( static_cast(args[0].addr), static_cast(args[1].addr), static_cast(result.addr), inverseSecond); return 0; } /* 16.3 Value mapping functions of operator ~/~ for {mint, mreal} */ int TemporalMIIDivide( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingDivideMII( static_cast(args[0].addr), static_cast(args[1].addr), static_cast(result.addr)); return 0; } int TemporalIMIDivide( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingDivideIMI( static_cast(args[0].addr), static_cast(args[1].addr), static_cast(result.addr)); return 0; } int TemporalMIMIDivide( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingDivideMIMI( static_cast(args[0].addr), static_cast(args[1].addr), static_cast(result.addr)); return 0; } /* 1.1 ValueMapping of operator ~isempty~ for mbool, mint, mreal, mpoint and mregion */ template int IsEmptyValueMap(Word* args, Word& result, int message, Word& local, Supplier s) { if(TLA_DEBUG) cout<< "IsEmptyValueMap() called" << endl; result = qp->ResultStorage(s); MBool* pResult = (MBool*)result.addr; Mapping1* reg = (Mapping1*)args[0].addr; pResult->Clear(); if( !reg->IsDefined() ){ pResult->SetDefined( false ); return 0; } pResult->SetDefined( true ); Unit1 ureg(true); pResult->StartBulkLoad(); if(reg->GetNoComponents() < 1){ UBool uBool(true); uBool.timeInterval.lc = true; uBool.timeInterval.start.ToMinimum(); uBool.timeInterval.start.SetType(instanttype); uBool.timeInterval.rc = true; uBool.timeInterval.end.ToMaximum(); uBool.timeInterval.end.SetType(instanttype); uBool.constValue.Set(true,true); pResult->Add(uBool); } else { UBool uBool(true); uBool.timeInterval.lc = true; uBool.timeInterval.start.ToMinimum(); uBool.timeInterval.start.SetType(instanttype); for( int i = 0; i < reg->GetNoComponents(); i++) { reg->Get(i, ureg); if(!ureg.IsValid()) continue; uBool.timeInterval.rc = !ureg.timeInterval.lc; uBool.timeInterval.end = ureg.timeInterval.start; uBool.constValue.Set(true,true); if(uBool.timeInterval.start < uBool.timeInterval.end || (uBool.timeInterval.start == uBool.timeInterval.end && uBool.timeInterval.lc && uBool.timeInterval.rc)) pResult->MergeAdd(uBool); uBool.timeInterval = ureg.timeInterval; uBool.constValue.Set(true,false); pResult->MergeAdd(uBool); uBool.timeInterval.lc = !ureg.timeInterval.rc; uBool.timeInterval.start = ureg.timeInterval.end; } uBool.timeInterval.end.ToMaximum(); uBool.timeInterval.end.SetType(instanttype); if(ureg.timeInterval.end.operator<(uBool.timeInterval.end)){ uBool.timeInterval.rc = true; uBool.constValue.Set(true,true); pResult->MergeAdd(uBool);; } } pResult->EndBulkLoad(false); return 0; } /* 16.3 Value mapping of operator ~inside~ and ~intersection~ for mpoint/points. op decides whether it means inside(1) or intersection(2) */ template int MPointPointsInside( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); Periods* pResult = new Periods(0); MPointInsidePoints( *((MPoint*)args[0].addr), *((Points*)args[1].addr), *pResult); if(op == 1){ //create a MBool (inside) MBool* endResult = (MBool*)result.addr; CompletePeriods2MBool(((MPoint*)args[0].addr), pResult, endResult); } else{ //create a MPoint (intersection) MPoint* endResult = (MPoint*)result.addr; CompletePeriods2MPoint(((MPoint*)args[0].addr), pResult, endResult); } pResult->DeleteIfAllowed(); return 0; } /* 16.3 Value mapping of operator ~inside~ and ~intersection~ for mpoint/line. op decides whether it means inside(1) or intersection(2) */ template int MPointLineInside( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); Periods* pResult = new Periods(0); MPointInsideLine( *((MPoint*)args[0].addr), *((Line*)args[1].addr), *pResult); if(op == 1) { //create a MBool (inside) MBool* endResult = (MBool*)result.addr; CompletePeriods2MBool(((MPoint*)args[0].addr), pResult, endResult); } else { //create a MPoint (intersection) MPoint* endResult = (MPoint*)result.addr; CompletePeriods2MPoint(((MPoint*)args[0].addr), pResult, endResult); } pResult->DeleteIfAllowed(); return 0; } /* 1.1 ValueMapping ~MFalseValueMap~ is used in ~inside~ with mregion x points / line Creates a FALSE-unit for every defined interval within the mregion. */ int MFalseValueMap(Word* args, Word& result, int message, Word& local, Supplier s) { if(TLA_DEBUG) cout<< "MFalseValueMap() called" << endl; result = qp->ResultStorage(s); MBool* pResult = (MBool*)result.addr; MRegion* reg = (MRegion*)args[0].addr; pResult->Clear(); if( !reg->IsDefined() ){ pResult->SetDefined( false ); return 0; } pResult->SetDefined( true ); UBool uBool(true); pResult->StartBulkLoad(); for( int i = 0; i < reg->GetNoComponents(); i++) { URegionEmb ureg; reg->Get(i, ureg); if(!ureg.IsValid()) continue; uBool.timeInterval = ureg.timeInterval; uBool.constValue.Set(true,false); pResult->MergeAdd(uBool); } pResult->EndBulkLoad(false); return 0; } /* 16.3 Value mapping of operator ~intersection~ for points/mpoint */ int PointsMPointIntersection( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); Periods* pResult = new Periods(0); MPointInsidePoints( *((MPoint*)args[1].addr), *((Points*)args[0].addr), *pResult); //create a MPoint (intersection) MPoint* endResult = (MPoint*)result.addr; CompletePeriods2MPoint(((MPoint*)args[1].addr), pResult, endResult); pResult->DeleteIfAllowed(); return 0; } /* 16.3 Value mapping of operator ~intersection~ for line/mpoint */ int LineMPointIntersection( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); Periods* pResult = new Periods(0); MPointInsideLine( *((MPoint*)args[1].addr), *((Line*)args[0].addr), *pResult); //create a MPoint (intersection) MPoint* endResult = (MPoint*)result.addr; CompletePeriods2MPoint(((MPoint*)args[1].addr), pResult, endResult); pResult->DeleteIfAllowed(); return 0; } /* 1.1 ValueMapping of operator ~Union~ with Region/MPoint */ int MPRUnionValueMap(Word* args, Word& result, int message, Word& local, Supplier s) { result = qp->ResultStorage(s); copyRegionMPoint(*((Region*)args[1].addr) , *((MPoint*)args[0].addr), *((MRegion*)result.addr) ); return 0; } /* 1.1 ValueMapping of operator ~Union~ with MRegion/Point */ int PMRUnionValueMap(Word* args, Word& result, int message, Word& local, Supplier s) { result = qp->ResultStorage(s); copyMRegion(*((MRegion*)args[1].addr), *(MRegion*)result.addr); return 0; } /* 1.1 ValueMapping of operator ~Union~ with MRegion/MPoint */ int MPMRUnionValueMap(Word* args, Word& result, int message, Word& local, Supplier s) { result = qp->ResultStorage(s); copyMRegionMPoint(*((MRegion*)args[1].addr) , *((MPoint*)args[0].addr), *((MRegion*)result.addr) ); return 0; } /* 16.3 Value mapping functions of operators ~intersection~ and ~minus~ for mbool/bool, mint/int and mstring/string */ template int TemporalMSIntersection( Word* args, Word& result, int message, Word& local, Supplier s ) { if(TLA_DEBUG) cout<<"TemporalMSIntersection called"<ResultStorage( s ); Mapping1 *mop1 = (Mapping1*)args[0].addr; Operator2 *constop = (Operator2*)args[1].addr; Mapping1* res = static_cast(result.addr); res->Clear(); if( !mop1->IsDefined() || !constop->IsDefined() ){ res->SetDefined( false ); return 0; } res->SetDefined( true ); Mapping1 *mop2 = new Mapping1(0); mop2->SetDefined( true ); Unit1 up1; mop2->StartBulkLoad(); for (int i = 0; i < mop1->GetNoComponents(); i++) { mop1->Get(i, up1); if(!up1.IsDefined()) continue; Unit1 *up2 = new Unit1(up1.timeInterval, *constop); mop2->Add(*up2); delete up2; } mop2->EndBulkLoad(false); MovingIntersectionMM(*mop1,*mop2,*res,op); mop2->DeleteIfAllowed(); return 0; } /* 16.3 Value mapping functions of operators ~intsersection~ and ~minus~ for mreal/real */ template int TemporalMSRealIntercept( Word* args, Word& result, int message, Word& local, Supplier s ) { if(TLA_DEBUG) cout<<"TemporalMSRealIntercept called"<ResultStorage( s ); MReal* mop1 = static_cast(args[0].addr); CcReal* constop = static_cast(args[1].addr); MReal* res = static_cast(result.addr); res->Clear(); if( !mop1->IsDefined() || !constop->IsDefined() ){ res->SetDefined( false ); return 0; } res->SetDefined( true ); UReal up1; MReal *mop2= new MReal(0); mop2->Clear(); mop2->StartBulkLoad(); for (int i = 0; i < mop1->GetNoComponents(); i++) { mop1->Get(i, up1); if(!up1.IsDefined()) continue; UReal *up2 = new UReal(up1.timeInterval, 0.0, 0.0, (up1.r) ? pow(constop->GetRealval(), 2) : constop->GetRealval(),up1.r); mop2->Add(*up2); delete up2; } mop2->EndBulkLoad(false); MovingRealIntersectionMM( *mop1, *mop2, *res, op); mop2->DeleteIfAllowed(); return 0; } /* 16.3 Value mapping functions of operators ~intsersection~ and ~minus~ for two mbool, mint and mstring */ template int TemporalMMIntersection( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingIntersectionMM ( *((Mapping1*)args[0].addr), *((Mapping2*)args[1].addr), *((Mapping1*)result.addr), op); return 0; } // value mapping for intersection: mpoint x mpoint --> mpoint int TemporalMPointMPointIntersection( Word* args, Word& result, int message, Word& local, Supplier s ) { if(TLA_DEBUG) cout<<"TemporalMPointMPointIntersection called"<ResultStorage( s )); MPoint *op1 = (MPoint*) args[0].addr; MPoint *op2 = (MPoint*) args[1].addr; MPoint *res = (MPoint*) result.addr; res->Clear(); if( !op1->IsDefined() || !op2->IsDefined() ){ res->SetDefined( false ); return 0; } res->SetDefined( true ); UPoint resunit( false ); UPoint lastresunit( false ); RefinementPartition rp(*op1, *op2); if(TLA_DEBUG) cout<<"Refinement finished, rp.size: "<StartBulkLoad(); for(unsigned int i = 0; i < rp.Size(); i++) { Interval iv; int u1Pos; int u2Pos; UPoint u1( true ); UPoint u2( true ); UPoint u1transfer; UPoint u2transfer; rp.Get(i, iv, u1Pos, u2Pos); assert( iv.IsValid() ); if (TLA_DEBUG) { cout << "rp:" << i << ": " ; iv.Print(cout); cout << "(" << u1Pos << " " << u2Pos << ")" << endl; } if (u1Pos == -1 || u2Pos == -1 ) continue; else { if(TLA_DEBUG) { cout<<"Both operators existant in interval iv #"<Get(u1Pos, u1transfer); op2->Get(u2Pos, u2transfer); if (TLA_DEBUG) { cout << "Actual partition #" << i << "/" << rp.Size()-1 << ":" << endl << " u1="; u1transfer.Print(cout); cout << endl << " u2="; u2transfer.Print(cout); cout << endl; } if( !u1transfer.IsDefined() || !u2transfer.IsDefined() ) continue; u1transfer.AtInterval(iv, u1); u2transfer.AtInterval(iv, u2); // create intersection of u1 x u2 (may be undefined!) u1.Intersection(u2, resunit); if( resunit.IsDefined() ) { if( !resunit.timeInterval.IsValid() ) { // Debugging Info cout << "Error in " << __PRETTY_FUNCTION__ << " ["<< __FILE__ << ":" << __LINE__ << "]:" << endl; cout << "u1transfer = "; u1transfer.Print(cout); cout << endl; cout << "u2transfer = "; u2transfer.Print(cout); cout << endl; cout << "u1 = "; u1.Print(cout); cout << endl; cout << "u2 = "; u2.Print(cout); cout << endl; cout << "iv = " << (iv.lc ? "[" : "(") << iv.start << "," << iv.end << (iv.rc ? "]" : ")") << endl; cout << "resunit.timeInterval = " << (resunit.timeInterval.lc ? "[" : "(") << resunit.timeInterval.start << "," << resunit.timeInterval.end << (resunit.timeInterval.rc ? "]" : ")") << endl; resunit.SetDefined(false); assert( resunit.timeInterval.IsValid() ); } if( resunit.IsDefined() && !resunit.timeInterval.Inside(iv) ) { // invalidate result, if it is on an open border of iv resunit.SetDefined(false); } if ( resunit.IsDefined() && lastresunit.IsDefined() ) { // Check for conflicting timeIntervals: if ( (lastresunit.timeInterval.end == resunit.timeInterval.start) && lastresunit.timeInterval.rc && resunit.timeInterval.lc ) { // We have a conflict! // solution1: change closedness flag for one non-instant unit // solution2: drop a [x, x]-type unit if (TLA_DEBUG) { cout << "\n We have a conflict! \n" << endl; cout << "lastresunit: "; lastresunit.timeInterval.Print(cout); cout << endl; cout << "resunit: "; resunit.timeInterval.Print(cout); cout << endl; } if (lastresunit.timeInterval.start == lastresunit.timeInterval.end) { // drop lastresunit if (TLA_DEBUG) cout << "Dropping lastresunit.\n" << endl; // do not add lastresunit lastresunit = resunit; // queue up resunit } else if (resunit.timeInterval.start == resunit.timeInterval.end) { // drop resunit // do not add lastresunit // let lastresunit in the queue, do not queue up resunit if (TLA_DEBUG) cout << "Dropping resunit.\n" << endl; } else { // set closednessflags to pattern |A,B[ ]B,C| if (TLA_DEBUG) cout << "Changing closedness.\n" << endl; lastresunit.timeInterval.rc = false; resunit.timeInterval.lc = true; res->MergeAdd(lastresunit); // add lastresunit lastresunit = resunit; // queue up resunit } } else { // else: No conflict. if (TLA_DEBUG) cout << "No conflict.\n" << endl; if ( lastresunit.IsDefined() ) res->MergeAdd(lastresunit); // Add lastresunit if ( resunit.IsDefined() ) lastresunit = resunit; // queue up resunit } } else if ( resunit.IsDefined() ) // lastresunit undefined, but resunit defined lastresunit = resunit; // ignore lastresunit, queue up resunit // else: lastresunit defined, but resunit undefined - Do nothing! } // else: resunit undefined. Do nothing. } } if (lastresunit.IsDefined() ) { // possibly insert the last result unit res->MergeAdd(lastresunit); } res->EndBulkLoad( false ); return 0; } /* 16.3 Value mapping functions of operators ~intsersection~ and ~minus~ for mreal/mreal */ template int TemporalMMRealIntercept( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingRealIntersectionMM( *((MReal*)args[0].addr), *((MReal*)args[1].addr), *((MReal*)result.addr), op); return 0; } /* 16.3 Value mapping functions of operator ~intsersection~ and ~minus~ for bool/mbool, int/mint and string/mstring */ template int TemporalSMIntersection( Word* args, Word& result, int message, Word& local, Supplier s ) { if(TLA_DEBUG) cout<<"TemporalSMIntersection called"<ResultStorage( s ); Mapping1 *res = static_cast(result.addr); Operator1 *constop = (Operator1*)args[0].addr; Mapping1 *mop2 = (Mapping1*)args[1].addr; res->Clear(); if( !constop->IsDefined() || !mop2->IsDefined() ){ res->SetDefined( false ); return 0; } res->SetDefined( true ); Mapping1 *mop1 = new Mapping1(0); mop1->Clear(); mop1->SetDefined( true ); mop1->StartBulkLoad(); Unit1 up2; for (int i = 0; i < mop2->GetNoComponents(); i++) { mop2->Get(i, up2); if(!up2.IsDefined()) continue; Unit1 *up1 = new Unit1(up2.timeInterval, *constop); mop1->Add(*up1); delete up1; } mop1->EndBulkLoad(false); MovingIntersectionMM(*mop1,*mop2,*res,op); mop1->DeleteIfAllowed(); return 0; } /* 16.3 Value mapping functions of operators ~intsersection~ and ~minus~ for real/mreal */ template int TemporalSMRealIntercept( Word* args, Word& result, int message, Word& local, Supplier s ) { if(TLA_DEBUG) cout<<"TemporalSMRealIntercept called"<ResultStorage( s ); CcReal *constop = static_cast(args[0].addr); MReal *mop2 = static_cast(args[1].addr); MReal *res = static_cast(result.addr); res->Clear(); if( !constop->IsDefined() || !mop2->IsDefined() ){ res->SetDefined( false ); return 0; } res->SetDefined( true ); UReal up2; MReal *mop1 = new MReal(0); mop1->Clear(); mop1->StartBulkLoad(); for (int i = 0; i < mop2->GetNoComponents(); i++) { mop2->Get(i, up2); if(!up2.IsDefined()) continue; UReal *up1 = new UReal(up2.timeInterval, 0.0, 0.0, (up2.r) ? pow(constop->GetRealval(), 2) : constop->GetRealval(), up2.r); if(TLA_DEBUG){ cout<<"up1["<timeInterval.start.ToString() <<" "<timeInterval.end.ToString()<<" " <timeInterval.lc<<" "<timeInterval.rc<<"] "<Add(*up1); delete up1; } mop1->EndBulkLoad(false); MovingRealIntersectionMM( *mop1, *mop2, *res, op); mop1->DeleteIfAllowed(); return 0; } /* 16.3 Value mapping functions of operator ~minus~ for mpoint/mpoint */ int TemporalMMPointIntercept( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MBool *mBool = new MBool(0); MovingPointCompareMM(*((MPoint*)args[0].addr), *((MPoint*)args[1].addr), *mBool, 0); MPoint* endResult = (MPoint*)result.addr; TransformMBool2MPoint(((MPoint*)args[0].addr), mBool, endResult); mBool->DeleteIfAllowed(); return 0; } /* 16.3 Value mapping functions of operator ~minus~ for mpoint/point */ int TemporalMSPointIntercept( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MBool *mBool = new MBool(0); MovingPointCompareMS(*((MPoint*)args[0].addr), *((Point*)args[1].addr), *mBool, 0); MPoint* endResult = (MPoint*)result.addr; TransformMBool2MPoint(((MPoint*)args[0].addr), mBool, endResult); mBool->DeleteIfAllowed(); return 0; } /* 16.3 Value mapping functions of operator ~minus~ for point/mpoint */ int TemporalSMPointIntercept( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MBool *mBool = new MBool(0); MovingPointCompareMS(*((MPoint*)args[1].addr), *((Point*)args[0].addr), *mBool, 0); MPoint* endResult = (MPoint*)result.addr; TransformMBool2MPoint(((Point*)args[0].addr), mBool, endResult); mBool->DeleteIfAllowed(); return 0; } /* 1.1 ValueMapping of operator ~rough\_center~ for mregion */ int RCenterValueMap(Word* args, Word& result, int message, Word& local, Supplier s) { result = qp->ResultStorage(s); RCenter(* (MRegion*) args[0].addr,* (MPoint*) result.addr); return 0; } /* 1.1 ValueMapping of operator ~minus~ with Region/MPoint */ int RMPMinusValueMap(Word* args, Word& result, int message, Word& local, Supplier s) { result = qp->ResultStorage(s); copyRegionMPoint(*((Region*)args[0].addr) , *((MPoint*)args[1].addr), *((MRegion*)result.addr) ); return 0; } /* 1.1 ValueMapping of operator ~minus~ with MRegion/Point */ int MRPMinusValueMap(Word* args, Word& result, int message, Word& local, Supplier s) { result = qp->ResultStorage(s); copyMRegion(*((MRegion*)args[0].addr), *(MRegion*)result.addr); return 0; } /* 1.1 ValueMapping of operator ~minus~ with MRegion/MPoint */ int MRMPMinusValueMap(Word* args, Word& result, int message, Word& local, Supplier s) { result = qp->ResultStorage(s); copyMRegionMPoint(*((MRegion*)args[0].addr) , *((MPoint*)args[1].addr), *((MRegion*)result.addr) ); return 0; } /* 1.1 ValueMapping of operator ~no\_components~ for mregion */ int NComponentsValueMap(Word* args, Word& result, int message, Word& local, Supplier s) { result = qp->ResultStorage(s); NComponents(* (MRegion*) args[0].addr,* (MInt*) result.addr); return 0; } /* 1.1 ValueMapping of operator ~perimeter~ for mregion */ int PerimeterValueMap(Word* args, Word& result, int message, Word& local, Supplier s) { result = qp->ResultStorage(s); MPerimeter(* (MRegion*) args[0].addr, * (MReal*) result.addr); return 0; } /* 1.1 ValueMapping of operator ~area~ for mregion */ int AreaValueMap(Word* args, Word& result, int message, Word& local, Supplier s) { result = qp->ResultStorage(s); MArea(* (MRegion*) args[0].addr, * (MReal*) result.addr); return 0; } /* 16.3 Value mapping functions of operator ~distance~ for mpoint/mpoint */ int MPointMMDistance( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); DistanceMPoint(*((MPoint*)args[0].addr), *((MPoint*)args[1].addr), *((MReal*)result.addr) ); return 0; } int UPointMMDistance( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); UPoint* u1 = (UPoint*) args[0].addr; UPoint* u2 = (UPoint*) args[1].addr; UReal* ur = (UReal*) result.addr; if(!u1->IsDefined() || !u2->IsDefined()){ ur->SetDefined(false); } else { u1->Distance(*u2,*ur); } return 0; } int UPointMSDistance( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); UPoint* u1 = (UPoint*) args[0].addr; Point* p2 = (Point*) args[1].addr; UReal* ur = (UReal*) result.addr; if(!u1->IsDefined() || !p2->IsDefined()){ ur->SetDefined(false); } else { u1->Distance(*p2,*ur); } return 0; } int UPointSMDistance( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); Point* p1 = (Point*) args[0].addr; UPoint* u2 = (UPoint*) args[1].addr; UReal* ur = (UReal*) result.addr; if(!p1->IsDefined() || !u2->IsDefined()){ ur->SetDefined(false); } else { u2->Distance(*p1,*ur); } return 0; } /* 16.3 Value mapping of operator ~distance~ for mreal/mreal */ int MRealMMDistance( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MRealDistanceMM( *((MReal*)args[0].addr), *((MReal*)args[1].addr), *((MReal*)result.addr)); return 0; } /* 16.3 Value mapping of operator ~distance~ for mreal/real */ int MRealMSDistance( Word* args, Word& result, int message, Word& local, Supplier s ) { if(TLA_DEBUG) cout<<"MRealMSDistance called"<ResultStorage( s ); MReal *res = static_cast(result.addr); MReal *mop1 = static_cast(args[0].addr); CcReal *constop = static_cast(args[1].addr); res->Clear(); if( !mop1->IsDefined() || !constop->IsDefined() ){ res->SetDefined( false ); return 0; } res->SetDefined( true ); UReal up1; MReal *mop2 = new MReal(0); mop2->Clear(); mop2->SetDefined( true ); mop2->StartBulkLoad(); for (int i = 0; i < mop1->GetNoComponents(); i++) { mop1->Get(i, up1); if(!up1.IsDefined()) continue; UReal *up2 = new UReal(up1.timeInterval, 0.0, 0.0, (up1.r) ? pow(constop->GetRealval(), 2) : constop->GetRealval(),up1.r); mop2->Add(*up2); delete up2; } mop2->EndBulkLoad(false); MRealDistanceMM( *mop1, *mop2, *res); mop2->DeleteIfAllowed(); return 0; } /* 16.3 Value mapping of operator ~distance~ for real/mreal */ int MRealSMDistance( Word* args, Word& result, int message, Word& local, Supplier s ) { if(TLA_DEBUG) cout<<"MRealSMDistance called"<ResultStorage( s ); MReal *res = static_cast(result.addr); MReal *mop1 = static_cast(args[1].addr); CcReal *constop = static_cast(args[0].addr); res->Clear(); if( !mop1->IsDefined() || !constop->IsDefined() ){ res->SetDefined( false ); return 0; } res->SetDefined( true ); UReal up1; MReal *mop2 = new MReal(0); mop2->Clear(); mop2->StartBulkLoad(); for (int i = 0; i < mop1->GetNoComponents(); i++) { mop1->Get(i, up1); if(!up1.IsDefined()) continue; UReal *up2 = new UReal(up1.timeInterval, 0.0, 0.0, (up1.r) ? pow(constop->GetRealval(), 2) : constop->GetRealval(),up1.r); mop2->Add(*up2); delete up2; } mop2->EndBulkLoad(false); MRealDistanceMM( *mop1, *mop2, *res ); mop2->DeleteIfAllowed(); return 0; } /* \subsection{Value mapping of operator ~frechetdistance~} */ template int FrechetDistance(Word* args, Word& result, int message, Word& local, Supplier s) { result = qp->ResultStorage(s); CcReal *res = static_cast(result.addr); MPoint *mp1 = static_cast(args[0].addr); MPoint *mp2 = static_cast(args[1].addr); Geoid *geoid = 0; if (hasGeoid) { geoid = static_cast(args[2].addr); } if (!mp1->IsDefined() || !mp2->IsDefined()) { res->SetDefined(false); } else { res->Set(true, mp1->FrechetDistance(mp2, geoid)); } return 0; } /* 16.3 Value mapping functions of operator ~and~ and ~or~ for mbool/mbool op == 1 -> AND, op == 2 -> OR */ template int TemporalMMLogic( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingBoolMMOperators( *((MBool*)args[0].addr), *((MBool*)args[1].addr), *((MBool*)result.addr), op); return 0; } /* 16.3 Value mapping functions of operators ~and~ and ~or~ for mbool/bool op == 1 -> AND, po == 2 -> OR */ template int TemporalMSLogic( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingBoolMSOperators( *((MBool*)args[0].addr), *((CcBool*)args[1].addr), *((MBool*)result.addr), op); return 0; } /* 16.3 Value mapping functions of operators ~and~ and ~or~ for bool/mbool op == 1 -> AND, po == 2 -> OR */ template int TemporalSMLogic( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MovingBoolMSOperators( *((MBool*)args[1].addr), *((CcBool*)args[0].addr), *((MBool*)result.addr), op); return 0; } /* 16.3 Value mapping functions of operator ~not~ for mbool */ int TemporalNot( Word* args, Word& result, int message, Word& local, Supplier s ) { if(TLA_DEBUG) cout<<"temporalNot called"<ResultStorage( s ); MBool* pResult = (MBool*)result.addr; MBool* op = (MBool*)args[0].addr; pResult->Clear(); if( !op->IsDefined() ){ pResult->SetDefined( false ); return 0; } pResult->SetDefined( true ); UBool u1transfer; UBool uBool(true); pResult->StartBulkLoad(); for( int i = 0; i < op->GetNoComponents(); i++) { op->Get(i, u1transfer); if(!u1transfer.IsDefined()) continue; uBool = u1transfer; uBool.constValue.Set(uBool.constValue.IsDefined(), !(uBool.constValue.GetBoolval())); if(TLA_DEBUG){ cout<<"wert "<<&uBool.constValue<Add(uBool); } pResult->EndBulkLoad(false); return 0; } /* 1.1 Value mapping functions of operator ~zero~ Creates a moving int with value 0 for all times */ int TemporalZeroValueMap(Word* args, Word& result, int message, Word& local, Supplier s) { if(TLA_DEBUG) cout<< "TemporalZeroValueMap() called" << endl; result = qp->ResultStorage(s); MInt* pResult = (MInt*)result.addr; pResult->Clear(); pResult->SetDefined( true ); pResult->StartBulkLoad(); UInt uInt(true); uInt.timeInterval.lc = true; uInt.timeInterval.start.ToMinimum(); uInt.timeInterval.start.SetType(instanttype); uInt.timeInterval.rc = true; uInt.timeInterval.end.ToMaximum(); uInt.timeInterval.end.SetType(instanttype); uInt.constValue.Set(true,0); pResult->Add(uInt); pResult->EndBulkLoad(false); return 0; } /* 16.3 Value mapping functions of operator ~mint~ Every interval in periods will be transformed into an UInt with value 1, The definition gaps will be transformed into UInts with value 0. */ int periods2mintVM( Word* args, Word& result, int message, Word& local, Supplier s ) { Periods* src = (Periods*) args[0].addr; result = qp->ResultStorage(s); MInt* res = (MInt*) result.addr; res->Clear(); if(!src->IsDefined()){ res->SetDefined(false); return 0; } Periods* extension = 0; Periods maxInterval(1); if(qp->GetNoSons(s)==2){ // optional second periods value present extension = (Periods*) args[1].addr; if(!extension->IsDefined()){ extension = 0; } else if(extension->IsEmpty()){ extension = 0; } } else { DateTime maxTime(datetime::instanttype); DateTime minTime(datetime::instanttype); maxTime.ToMaximum(); minTime.ToMinimum(); Interval iv(minTime, maxTime, true,true); maxInterval.StartBulkLoad(); maxInterval.Add(iv); maxInterval.EndBulkLoad(); extension = &maxInterval; } CcInt zero(true,0); CcInt one(true,1); if(src->IsEmpty()){ if(extension==0){ return 0; } // create a zero from extension Interval u1; Interval u2; extension->Get(0,u1); extension->Get(extension->GetNoComponents()-1,u2); Interval iv(u1.start, u2.end,u1.lc,u2.rc); UInt v(iv,zero); res->StartBulkLoad(); res->Add(v); res->EndBulkLoad(); return 0; } // normal case, src defined and non-empty int size = src->GetNoComponents(); Interval lastIv; Interval iv; res->StartBulkLoad(); for(int i=0;iGet(0,lastIv); if(extension!=0){ Interval eiv; extension->Get(0,eiv); if( (eiv.start < lastIv.start) || ((eiv.start == lastIv.start) && eiv.lc && !lastIv.lc)){ Interval cur(eiv.start, lastIv.start, eiv.lc, !lastIv.lc); UInt v(cur,zero); res->Add( v); } } UInt v(lastIv,one); res->Add( v); } else { // not the first unit src->Get(i,iv); if((lastIv.end < iv.start) || ( (lastIv.end == iv.start) && (lastIv.rc != iv.lc))) { // fill gap Interval cur(lastIv.end, iv.start, !lastIv.rc, !iv.lc); UInt v(cur,zero); } UInt v(iv,one); res->Add( v); lastIv = iv; } } // extend if required if(extension){ extension->Get(extension->GetNoComponents()-1, iv); if( (lastIv.end < iv.end) || ( (lastIv.end == iv.end) && !lastIv.rc && iv.rc)){ Interval cur(lastIv.end, iv.end, !lastIv.rc, iv.rc); UInt v(cur,zero); res->Add( v); } } res->EndBulkLoad(false, true); return 0; } /* 16.4 Value Mapping Operator ~createmint~ */ int createmintVM( Word* args, Word& result, int message, Word& local, Supplier s ){ result = qp->ResultStorage(s); MInt* res = (MInt*) result.addr; Periods* p = (Periods*) args[0].addr; CcInt* v = (CcInt*) args[1].addr; res->Clear(); if(!p->IsDefined() || !v->IsDefined()){ res->SetDefined(false); return 0; } res->SetDefined(true); res->StartBulkLoad(); int size = p->GetNoComponents(); Interval iv; //int value = v->GetValue(); for(int i=0;iGet(i,iv); UInt ui(iv,*v); res->Add(ui); } res->EndBulkLoad(false); return 0; } int eplusVM( Word* args, Word& result, int message, Word& local, Supplier s ) { MInt* arg1 = static_cast(args[0].addr); MInt* arg2 = static_cast(args[1].addr); result = qp->ResultStorage(s); MInt* res = static_cast(result.addr); res->Clear(); if( !arg1->IsDefined() || !arg2->IsDefined() ){ res->SetDefined( false ); return 0; } res->SetDefined( true ); arg1->PlusExtend(arg2,*res); return 0; } /* 1.1 Value mapping functions of operator ~concat~ Concats two mpoints. If intervals are not disjunct it creates an undefined value. */ int TemporalConcatValueMap(Word* args, Word& result, int message, Word& local, Supplier s) { if(TLA_DEBUG) cout<< "TemporalConcatValueMap() called" << endl; result = qp->ResultStorage(s); MPoint* p1 = (MPoint*)args[0].addr; MPoint* p2 = (MPoint*)args[1].addr; MPoint* pResult = (MPoint*)result.addr; pResult->Clear(); if( !p1->IsDefined() || !p2->IsDefined() ){ pResult->SetDefined( false ); return 0; } pResult->SetDefined( true ); UPoint up1; UPoint up2; pResult->StartBulkLoad(); if(p1->GetNoComponents() > 0 && p2->GetNoComponents() > 0){ p1->Get(p1->GetNoComponents() - 1, up1); p2->Get(0, up2); if(!( up1.timeInterval.end < up2.timeInterval.start || (up1.timeInterval.end == up2.timeInterval.start && !(up1.timeInterval.rc && up2.timeInterval.lc)))){ if(TLA_DEBUG) { cout<<"DefTime of mpoints are not disjunct! Last interval of first " <<"mpoint ends after first interval of of second mpoint begins." << endl; cout << "first interval "; up1.timeInterval.Print(cout); cout << endl << "second interval"; up2.timeInterval.Print(cout); cout<< endl; } pResult->EndBulkLoad(false); pResult->SetDefined( false ); return 0; } } for( int i = 0; i < p1->GetNoComponents(); i++) { p1->Get(i, up1); if(!up1.IsDefined()) continue; pResult->Add(up1); } for( int i = 0; i < p2->GetNoComponents(); i++) { p2->Get(i, up2); if(!up2.IsDefined()) continue; pResult->Add(up2); } pResult->EndBulkLoad(false); return 0; } /* 16.3 Value mapping function of operators ~abs~ for mreal */ int MovingRealABS( Word* args, Word& result, int message, Word& local, Supplier s ) { result = qp->ResultStorage( s ); MRealABS( *((MReal*)args[0].addr), *((MReal*)result.addr)); return 0; } /* 1 ValueMapping-Arrays */ static ValueMapping temporalmequalmap[] = { TemporalMMCompare, TemporalMSCompare, TemporalSMCompare, TemporalMMCompare, TemporalMSCompare, TemporalSMCompare, TemporalMMCompare, TemporalMSCompare, TemporalSMCompare, TemporalMMRealCompare<0>, TemporalMSRealCompare<0>, TemporalSMRealCompare<0>, TemporalMMPointCompare<0>, TemporalMSPointCompare<0>, TemporalSMPointCompare<0>, TemporalMSRegionCompare<0>, TemporalSMRegionCompare<0>, TemporalMMRegionCompare<0>}; static ValueMapping temporalmnotequalmap[] = { TemporalMMCompare, TemporalMSCompare, TemporalSMCompare, TemporalMMCompare, TemporalMSCompare, TemporalSMCompare, TemporalMMCompare, TemporalMSCompare, TemporalSMCompare, TemporalMMRealCompare<-3>, TemporalMSRealCompare<-3>, TemporalSMRealCompare<-3>, TemporalMMPointCompare<-3>, TemporalMSPointCompare<-3>, TemporalSMPointCompare<-3>, TemporalMSRegionCompare<-3>, TemporalSMRegionCompare<-3>, TemporalMMRegionCompare<-3>}; static ValueMapping temporalmlessmap[] = { TemporalMMCompare, TemporalMSCompare, TemporalSMCompare, TemporalMMCompare, TemporalMSCompare, TemporalSMCompare, TemporalMMRealCompare<-2>, TemporalMSRealCompare<-2>, TemporalSMRealCompare<-2>, TemporalMMCompare, TemporalMSCompare, TemporalSMCompare}; static ValueMapping temporalsubtractmap[] = { TemporalMIIAdd<-1>, TemporalMIRAdd<-1>, TemporalMRRAdd<-1>, TemporalMRIAdd<-1>, TemporalIMIAdd<-1>, TemporalRMIAdd<-1>, TemporalRMRAdd<-1>, TemporalIMRAdd<-1>, TemporalMIMIAdd<-1>, TemporalMIMRAdd<-1>, TemporalMRMRAdd<-1>, TemporalMRMIAdd<-1> }; static ValueMapping temporaladdmap[] = { TemporalMIIAdd<1>, TemporalMIRAdd<1>, TemporalMRRAdd<1>, TemporalMRIAdd<1>, TemporalIMIAdd<1>, TemporalRMIAdd<1>, TemporalRMRAdd<1>, TemporalIMRAdd<1>, TemporalMIMIAdd<1>, TemporalMIMRAdd<1>, TemporalMRMRAdd<1>, TemporalMRMIAdd<1> }; static ValueMapping temporalmultiplymap[] = { TemporalMIIMultiply, TemporalMIRMultiply, TemporalMRRMultiply, TemporalMRIMultiply, TemporalIMIMultiply, TemporalRMIMultiply, TemporalIMRMultiply, TemporalRMRMultiply, TemporalMIMIMultiply, TemporalMIMRMultiply, TemporalMRMIMultiply }; static ValueMapping temporaldividemap[] = { TemporalMIIDivide, TemporalMIRMultiply, TemporalMRRMultiply, TemporalMRIMultiply, TemporalIMIDivide, TemporalRMIMultiply, TemporalMIMIDivide, TemporalMRMIMultiply }; static ValueMapping temporalmlessequalmap[] = { TemporalMMCompare, TemporalMSCompare, TemporalSMCompare, TemporalMMCompare, TemporalMSCompare, TemporalSMCompare, TemporalMMRealCompare<-1>, TemporalMSRealCompare<-1>, TemporalSMRealCompare<-1>, TemporalMMCompare, TemporalMSCompare, TemporalSMCompare}; static ValueMapping temporalmgreatermap[] = { TemporalMMCompare, TemporalMSCompare, TemporalSMCompare, TemporalMMCompare, TemporalMSCompare, TemporalSMCompare, TemporalMMRealCompare<2>, TemporalMSRealCompare<2>, TemporalSMRealCompare<2>, TemporalMMCompare, TemporalMSCompare, TemporalSMCompare}; static ValueMapping temporalmgreaterequalmap[] = { TemporalMMCompare, TemporalMSCompare, TemporalSMCompare, TemporalMMCompare, TemporalMSCompare, TemporalSMCompare, TemporalMMRealCompare<1>, TemporalMSRealCompare<1>, TemporalSMRealCompare<1>, TemporalMMCompare, TemporalMSCompare, TemporalSMCompare}; static ValueMapping temporalliftisemptyvaluemap[] = { IsEmptyValueMap, IsEmptyValueMap, IsEmptyValueMap, IsEmptyValueMap, IsEmptyValueMap, IsEmptyValueMap, IsEmptyValueMap }; static ValueMapping temporalliftinsidemap[] = { MPointPointsInside<1>, MPointLineInside<1>, MFalseValueMap, MFalseValueMap }; static ValueMapping temporalliftintersectionmap[] = { TemporalMMIntersection, TemporalMSIntersection, TemporalSMIntersection, TemporalMMIntersection, TemporalMSIntersection, TemporalSMIntersection, TemporalMMRealIntercept<1>, TemporalMSRealIntercept<1>, TemporalSMRealIntercept<1>, MPointPointsInside<2>, MPointLineInside<2>, PointsMPointIntersection, LineMPointIntersection, TemporalMMIntersection, TemporalMSIntersection, TemporalSMIntersection, TemporalMPointMPointIntersection}; static ValueMapping unionvaluemap[] = { MPRUnionValueMap, MPMRUnionValueMap, PMRUnionValueMap}; static ValueMapping temporalliftminusmap[] = { TemporalMMIntersection, TemporalMSIntersection, TemporalSMIntersection, TemporalMMIntersection, TemporalMSIntersection, TemporalSMIntersection, TemporalMMRealIntercept<2>, TemporalMSRealIntercept<2>, TemporalSMRealIntercept<2>, TemporalMMPointIntercept, TemporalMSPointIntercept, TemporalSMPointIntercept, RMPMinusValueMap, MRPMinusValueMap, MRMPMinusValueMap, MRPMinusValueMap, MRPMinusValueMap, TemporalMMIntersection, TemporalMSIntersection, TemporalSMIntersection}; static ValueMapping temporaldistancemap[] = { MPointMMDistance, MRealMMDistance, MRealMSDistance, MRealSMDistance, UPointMMDistance, UPointMSDistance, UPointSMDistance}; static ValueMapping temporalfrechetdistancemap[] = { FrechetDistance, FrechetDistance}; static ValueMapping temporalandmap[] = { TemporalMMLogic<1>, TemporalMSLogic<1>, TemporalSMLogic<1>}; static ValueMapping temporalormap[] = { TemporalMMLogic<2>, TemporalMSLogic<2>, TemporalSMLogic<2>}; /* 1 Specifications of operations */ const string TemporalLiftSpecMEqual = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( T in {bool, int, string, real, point, region}" ", mT X mT -> mbool," " mT x T -> mbool, T x mT -> mbool" " _ = _ " "Logical equality for two MovingT." "mb1 = mb2" ") )"; const string TemporalLiftSpecMNotEqual = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( T in {bool, int, string, real, point, region}" ", mT X mT -> mbool," " mT x T -> mbool, T x mT -> mbool" " _ # _ " "Logical unequality for two MovingT." "mb1 # mb2" ") )"; const string TemporalLiftSpecLT = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" )" "( T in {bool, int, real, string}, mT x T -> mbool," " (mT x mT) -> mbool, (T x mT) -> mbool" "_ < _" "Less than." "query i1 < i2" ") )"; const string TemporalLiftSpecSubtract = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" )" "( (mint x int) -> mint, (mint x mint) -> mint," " (mreal x real) -> mreal, (mreal x mreal) -> mreal," " (mreal x int) -> mreal, (mint x real) -> mreal," " (mreal x mint) -> mreal" "_ - _" "Subtract" "query i1 - i2" ") )"; const string TemporalLiftSpecAdd = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" )" "( (mint x int) -> mint, (mint x mint) -> mint," " (mreal x real) -> mreal, (mreal x mreal) -> mreal," " (mreal x int) -> mreal, (mint x real) -> mreal," " (mreal x mint) -> mreal" "_ + _" "Add" "query i1 + i2" ") )"; const string TemporalLiftSpecMultiply = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" )" "( (mint x int) -> mint, (mint x mint) -> mint," " (mreal x real) -> mreal, " " (mreal x int) -> mreal, (mint x real) -> mreal," " (mreal x mint) -> mreal" "_ * _" "Multiply" "query i1 * i2" ") )"; const string TemporalLiftSpecDivide = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" )" "( (mint x int) -> mreal, (mint x mint) -> mreal," " (mreal x real) -> mreal, " " (mreal x int) -> mreal, (mint x real) -> mreal," " (mreal x mint) -> mreal" "_ / _" "Divide" "query i1 / i2" ") )"; const string TemporalLiftSpecLE = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" )" "( T in {bool, int, real, string}, mT x T -> mbool," " (mT x mT) -> mbool, (T x mT) -> mbool" "_ <= _" "Less or equal than." "query i1 <= i2" ") )"; const string TemporalLiftSpecGT = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" )" "( T in {bool, int, real, string}, mT x T -> mbool," " (mT x mT) -> mbool, (T x mT) -> mbool" "_ > _" "Greater than." "query i1 > i2" ") )"; const string TemporalLiftSpecGE = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" )" "( T in {bool, int, real, string}, mT x T -> mbool," " (mT x mT) -> mbool, (T x mT) -> mbool" "_ >= _" "Greater or equal than." "query i1 >= i2" ") )"; const string temporalliftisemptyspec = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( T in {bool, int, string, real, point, region}" " mT -> mbool" "isempty( _ )" "Checks if the m. object is not defined ." "isempty(mrg1) ) )"; const string TemporalLiftSpecInside = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( mpoint x points -> mbool," " mpoint x line -> mbool, mregion x points ->" " mbool, mregion x line -> mbool" "_ inside _" "Inside." "query mp1 inside pts1" ") )"; const string TemporalLiftSpecIntersection = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( S in {bool, int, string, real}, T in {line, points)," " mS x mS -> mS, mS x S -> mS, S x mS -> mS, " "mpoint x T -> mpoint, T x mpoint -> mpoint\n" "mpoint x mpoint -> mpoint" "intersection( _, _ )" "Intersection." "query intersection (mi1, mi2)" ") )"; const string unionspec = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( R in {region}, P in {point}, mP x R-> mR," " mP x mR -> mR, P x mR -> mR" "_ union _" "Calculates union between the given objects." "rg1 union mp1 ) )"; const string TemporalLiftSpecMinus = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( S in {bool, int, string, real}, mS x mS -> mS," " mS x S -> mS, S x mS -> mS, " "R in {region}, P in {point}, R x mP -> mR, " "mR x P -> mR, mR x mP -> mR, mR x points -> mR, " "mR x line -> mR" "_ minus _" "Minus." "query mi1 minus mi2" ") )"; const string rcenterspec = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( mregion -> mpoint" "rough_center ( _ )" "Calculates an approach to the" "center of gravity of a moving Region." "rough_center(mrg1) ) )"; const string ncomponentsspec = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( mregion -> mint" "no_components ( _ )" "Calculates the number of faces of " "a moving Region." "no_components(mrg1) ) )"; const string perimeterspec = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( mregion -> mreal" "perimeter ( _ )" "Calculates the perimeter of a moving Region." "mraperimeter(mrg1) ) )"; const string areaspec = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( mregion -> mreal" "area ( _ )" "Calculates the area of a moving Region." "area(mrg1) ) )"; const string TemporalLiftSpecDistance = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( T in {real), mpoint x mpoint -> mreal, mT x mT" " -> mreal, mT x T -> mreal, T x mT -> mreal," " [u]point x [u]point -> ureal" " distance( _, _ ) " "returns the moving distance" "distance( mpoint1, point1 )" ") )"; const string TemporalLiftSpecFrechetDistance = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( mpoint x mpoint (x geoid) -> real" "frechetdistance( _ , _ , _ ) " "returns the discrete Fréchet distance" "frechetdistance(mpoint1, mpoint2)" ") )"; const string TemporalLiftSpecAnd = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( bool x mbool -> mbool, mbool x mbool ->" " mbool, mbool x bool -> mbool" " _ and _ " "Logical AND for Bool and MBool." "mb1 and mb2" ") )"; const string TemporalLiftSpecOr = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( bool x mbool -> mbool, mbool x mbool ->" " mbool, mbool x bool -> mbool" " _ or _ " "Logical OR for Bool and MBool." "mb1 or mb2" ") )"; const string TemporalLiftSpecNot = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( mbool -> mbool" " not( _ )" "Negates a MovingBool." "not(mb1)" ") )"; const string temporalzerospec = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( -> mint" "zero()" "Creates an mint-Object with value 0 from minInstant" " to maxInstant" "zero() ) )"; const string periods2mintSpec = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( periods -> mint" "periods2mint( _ )" "Creates an MInt from a periods-object with value 1" " for each existing period and 0 for every hole." "periods2mint(per1) ) )"; const string createmintSpec = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( periods x int -> mint" "createmint( _ )" "Creates a moving int which is defined at the" " intervals of the periods value and haves the given" " int value during these intervals. " "" "mmint(per1) ) )"; const string eplusSpec = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( mint x mint -> mint" "_ eplus _" "Adds two mint-objects" "mi1 + mi2 ) )"; const string temporalconcatspec = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( mpoint x mpoint -> mpoint" "_ _ concat" "Concats two MPoints. DefTime of the first mpoint must" " end before deftime of second point!" "mp1 mp2 concat ) )"; const string TemporalLiftSpecABS = "( ( \"Signature\" \"Syntax\" \"Meaning\" " "\"Example\" ) " "( mreal -> mreal" "abs( _ )" "abs" "query abs(mr1)" ") )"; /* 1 Definition of operations */ static Operator temporalmequal( "=", TemporalLiftSpecMEqual, 18, temporalmequalmap, MovingEqualSelect, MovingEqualTypeMapMBool ); static Operator temporalmnotequal( "#", TemporalLiftSpecMNotEqual, 18, temporalmnotequalmap, MovingEqualSelect, MovingEqualTypeMapMBool ); static Operator temporalmless ( "<", TemporalLiftSpecLT, 12, temporalmlessmap, MovingCompareSelect, MovingCompareTypeMapMBool ); static Operator temporalmlessequal ( "<=", TemporalLiftSpecLE, 12, temporalmlessequalmap, MovingCompareSelect, MovingCompareTypeMapMBool ); static Operator temporalmgreater ( ">", TemporalLiftSpecGT, 12, temporalmgreatermap, MovingCompareSelect, MovingCompareTypeMapMBool ); static Operator temporalmgreaterequal ( ">=", TemporalLiftSpecGE, 12, temporalmgreaterequalmap, MovingCompareSelect, MovingCompareTypeMapMBool ); static Operator temporalsubtract ( "-", TemporalLiftSpecSubtract, 12, temporalsubtractmap, MovingAddSelect, MovingAddTypeMap); static Operator temporaladd ( "+", TemporalLiftSpecAdd, 12, temporaladdmap, MovingAddSelect, MovingAddTypeMap); static Operator temporalmultiply ( "*", TemporalLiftSpecMultiply, 11, temporalmultiplymap, MovingMultiplySelect, MovingMultiplyTypeMap); static Operator temporaldivide ( "/", TemporalLiftSpecDivide, 8, temporaldividemap, MovingDivideSelect, MovingDivideTypeMap); static Operator isempty("isempty", temporalliftisemptyspec, 7, temporalliftisemptyvaluemap, TemporalLiftIsemptySelect, TemporalLiftIsemptyTypeMap); static Operator temporalminside( "inside", TemporalLiftSpecInside, 4, temporalliftinsidemap, InsideSelect, InsideTypeMapMBool ); static Operator temporalmintersection( "intersection", TemporalLiftSpecIntersection, 17, temporalliftintersectionmap, MovingIntersectionSelect, MovingIntersectionTypeMap ); static Operator munion("union", unionspec, 3, unionvaluemap, UnionSelect, UnionTypeMap); static Operator temporalmminus( "minus", TemporalLiftSpecMinus, 20, temporalliftminusmap, MovingMinusSelect, MovingMinusTypeMap ); static Operator rcenter("rough_center", rcenterspec, RCenterValueMap, Operator::SimpleSelect, RCenterTypeMap); static Operator ncomponents("no_components", ncomponentsspec, NComponentsValueMap, Operator::SimpleSelect, NComponentsTypeMap); static Operator perimeter("perimeter", perimeterspec, PerimeterValueMap, Operator::SimpleSelect, PerimeterTypeMap); static Operator area("area", areaspec, AreaValueMap, Operator::SimpleSelect, PerimeterTypeMap); static Operator temporalmdistance( "distance", TemporalLiftSpecDistance, 7, temporaldistancemap, MovingDistanceSelect, MovingDistanceTypeMapMReal ); static Operator temporalfrechetdistance("frechetdistance", TemporalLiftSpecFrechetDistance, 2, temporalfrechetdistancemap, FrechetDistanceSelect, MPointMPointMapReal ); static Operator temporaland( "and", TemporalLiftSpecAnd, 3, temporalandmap, MovingAndOrSelect, AndOrTypeMapMBool ); static Operator temporalor( "or", TemporalLiftSpecOr, 3, temporalormap, MovingAndOrSelect, AndOrTypeMapMBool ); static Operator temporalnot( "not", TemporalLiftSpecNot, TemporalNot, Operator::SimpleSelect, MBoolTypeMapMBool ); static Operator temporalzero("zero", temporalzerospec, TemporalZeroValueMap, Operator::SimpleSelect, TemporalZeroTypeMap); static Operator temporalmint("periods2mint", periods2mintSpec, periods2mintVM, Operator::SimpleSelect, periods2mintTM); static Operator createmint( "createmint", createmintSpec, createmintVM, Operator::SimpleSelect, createmintTM); static Operator eplus("eplus", eplusSpec, eplusVM, Operator::SimpleSelect, TemporalPlusTypeMap); static Operator temporalconcat("concat", temporalconcatspec, TemporalConcatValueMap, Operator::SimpleSelect, TemporalConcatTypeMap); static Operator temporalabs( "abs", TemporalLiftSpecABS, MovingRealABS, Operator::SimpleSelect, ABSTypeMap ); /* 1 Creating the algebra */ class TemporalLiftedAlgebra : public Algebra { public: TemporalLiftedAlgebra() : Algebra() { AddOperator( &temporalmequal ); AddOperator( &temporalmnotequal ); AddOperator( &temporalmless); AddOperator( &temporalmlessequal); AddOperator( &temporalmgreater); AddOperator( &temporalmgreaterequal); AddOperator( &isempty); AddOperator( &temporalminside); AddOperator( &temporalmintersection); AddOperator( &munion); AddOperator( &temporalmminus); AddOperator( &rcenter); AddOperator( &ncomponents); AddOperator( &perimeter); AddOperator( &area); AddOperator( &temporalmdistance); AddOperator( &temporalfrechetdistance); AddOperator( &temporaland ); AddOperator( &temporalor ); AddOperator( &temporalnot ); AddOperator( &temporalzero); AddOperator( &temporalmint); AddOperator( &createmint); AddOperator( &eplus); AddOperator( &temporalconcat); AddOperator( &temporalabs); AddOperator( &temporalsubtract); AddOperator( &temporaladd); AddOperator( &temporalmultiply); AddOperator( &temporaldivide); } ~TemporalLiftedAlgebra() {} }; } // end of namepsace temporalalgebra /* 5 Initialization */ extern "C" Algebra* InitializeTemporalLiftedAlgebra(NestedList *nlRef, QueryProcessor *qpRef) { nl = nlRef; qp = qpRef; return (new temporalalgebra::TemporalLiftedAlgebra()); }