/* This file is part of SECONDO. Copyright (C) 2011, 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 2012, July Simone Jandt 1 Includes */ #include "JUnit.h" using namespace jnetwork; using namespace datetime; using namespace std; /* 1 Implementation of class JUnit 1.1 Constructors and Deconstructors */ JUnit::JUnit() : Attribute() {} JUnit::JUnit(const bool def) : Attribute(def), timeInter(temporalalgebra::Interval(instanttype, instanttype,false,false)), routeInter(false) {} JUnit::JUnit(const JUnit& other) : Attribute(other.IsDefined()), timeInter(temporalalgebra::Interval( instanttype,instanttype,false,false)), routeInter(false) { if (other.IsDefined()) { timeInter = other.GetTimeInterval(); routeInter = other.GetRouteInterval(); } } JUnit::JUnit(const temporalalgebra::Interval& inst, const JRouteInterval& rint) : Attribute(inst.IsDefined() && rint.IsDefined()), timeInter(temporalalgebra::Interval( instanttype,instanttype,false,false)), routeInter(false) { if (inst.IsDefined() && rint.IsDefined()) { timeInter = inst; routeInter = rint; } } JUnit::~JUnit() {} /* 1.1.1 Getter and Setter for private Attributes */ temporalalgebra::Interval JUnit::GetTimeInterval() const { return timeInter; } JRouteInterval JUnit::GetRouteInterval() const { return routeInter; } RouteLocation* JUnit::GetStartRLoc() const { return new RouteLocation(routeInter.GetRouteId(), routeInter.GetStartPosition(), routeInter.GetSide()); } RouteLocation* JUnit::GetEndRLoc() const { return new RouteLocation(routeInter.GetRouteId(), routeInter.GetEndPosition(), routeInter.GetSide()); } double JUnit::GetSpeed() const { return routeInter.GetLength() / ((timeInter.end.ToDouble() - timeInter.start.ToDouble())/ 0.00001157); } double JUnit::GetLength() const { return routeInter.GetLength(); } void JUnit::SetTimeInterval(const temporalalgebra::Interval& inst) { timeInter = inst; } void JUnit::SetRouteInterval(const JRouteInterval& ri) { routeInter = ri; } /* 1.1.1 Override Methods from Attribute */ void JUnit::CopyFrom(const Attribute* right) { *this = *((JUnit*)right); } Attribute::StorageType JUnit::GetStorageType() const { return Default; } size_t JUnit::HashValue() const { return routeInter.HashValue() + (size_t) (timeInter.start + timeInter.end).ToDouble() + (size_t) (timeInter.lc + timeInter.rc); } JUnit* JUnit::Clone() const { return new JUnit(*this); } bool JUnit::Adjacent(const Attribute* attrib) const { return false; } int JUnit::Compare(const void* ls, const void* rs) { JUnit lp(*(JUnit*) ls); JUnit rp(*(JUnit*) rs); return lp.Compare(rp); } int JUnit::Compare(const Attribute* rhs) const { return Compare(*((JUnit*)rhs)); } int JUnit::Compare(const JUnit& rhs) const { if (!IsDefined() && !rhs.IsDefined()) return 0; if (IsDefined() && !rhs.IsDefined()) return 1; if (!IsDefined() && rhs.IsDefined()) return -1; int test = timeInter.CompareTo(rhs.GetTimeInterval()); if (test != 0) return test; return routeInter.Compare(rhs.GetRouteInterval()); } size_t JUnit::Sizeof() const { return sizeof(JUnit); } ostream& JUnit::Print(ostream& os) const { if (IsDefined()) { os << "time: "; timeInter.Print(os); os << "positions: "; routeInter.Print(os); } else os << Symbol::UNDEFINED() << endl; return os; } const string JUnit::BasicType() { return "junit"; } const bool JUnit::checkType(const ListExpr type) { return listutils::isSymbol(type, BasicType()); } /* 1.1.1 Standard Operators */ JUnit& JUnit::operator=(const JUnit& other) { SetDefined(other.IsDefined()); if (other.IsDefined()) { timeInter = other.GetTimeInterval(); routeInter = other.GetRouteInterval(); } return *this; } bool JUnit::operator==(const JUnit& other) const { return (Compare(other) == 0); } bool JUnit::operator!=(const JUnit& other) const { return (Compare(other) != 0); } bool JUnit::operator<(const JUnit& other) const { return (Compare(other) < 0); } bool JUnit::operator<=(const JUnit& other) const { return (Compare(other) < 1); } bool JUnit::operator>(const JUnit& other) const { return (Compare(other) > 0); } bool JUnit::operator>=(const JUnit& other) const { return (Compare(other) > -1); } /* 1.1.1 Operators for Secondo Integration */ ListExpr JUnit::Out(ListExpr typeInfo, Word value) { JUnit* in = (JUnit*) value.addr; if (!in->IsDefined()) { return nl->SymbolAtom(Symbol::UNDEFINED()); } else { temporalalgebra::Interval time(in->GetTimeInterval()); Instant start = time.start; Instant end = time.end; JRouteInterval rint(in->GetRouteInterval()); return nl->TwoElemList( nl->FourElemList(OutDateTime(nl->TheEmptyList(), SetWord(&start)), OutDateTime(nl->TheEmptyList(), SetWord(&end)), nl->BoolAtom(time.lc), nl->BoolAtom(time.rc)), JRouteInterval::Out(nl->TheEmptyList(), SetWord((void*) &rint))); } } Word JUnit::In(const ListExpr typeInfo, const ListExpr instance, const int errorPos, ListExpr& errorInfo, bool& correct) { correct = true; if ( listutils::isSymbolUndefined( instance ) ) { JUnit* p = new JUnit(false); correct = true; return SetWord( p ); } else { if (nl->ListLength(instance) != 2) { correct = false; cmsg.inFunError("list length should be 1 or 2");; return SetWord(Address(0)); } ListExpr timeList = nl->First(instance); ListExpr rintList = nl->Second(instance); if (nl->ListLength(timeList) != 4 || !nl->IsAtom(nl->First(timeList)) || !nl->IsAtom(nl->Second(timeList)) || !nl->IsAtom(nl->Third(timeList)) || !nl->IsAtom(nl->Fourth(timeList)) || !nl->AtomType(nl->Third(timeList) == BoolType) || !nl->AtomType(nl->Fourth(timeList) == BoolType)) { cmsg.inFunError("timeintervallist must have length 4."); correct = false; return SetWord(Address(0)); } Instant* start = (Instant*) InInstant(nl->TheEmptyList(), nl->First(timeList), errorPos, errorInfo, correct).addr; Instant* end = (Instant*) InInstant(nl->TheEmptyList(), nl->Second(timeList), errorPos, errorInfo, correct).addr; bool lc = nl->BoolValue(nl->Third(timeList)); bool rc = nl->BoolValue(nl->Fourth(timeList)); if (!correct) { cmsg.inFunError("At least one time instant is invalid."); delete start; delete end; return SetWord(Address(0)); } temporalalgebra::Interval interval(*start,*end, lc, rc); if (!interval.IsValid()) { cmsg.inFunError("Invalid TimeInterval"); delete start; delete end; correct = false; return SetWord(Address(0)); } delete start; delete end; JRouteInterval* rint = (JRouteInterval*) JRouteInterval::In(nl->TheEmptyList(), rintList, errorPos, errorInfo, correct).addr; if (!correct) { cmsg.inFunError("Error in route interval list."); return SetWord(Address(0)); } JUnit* out = new JUnit(interval, *rint); rint->DeleteIfAllowed(); return SetWord(out); } } Word JUnit::Create(const ListExpr typeInfo) { return SetWord(new JUnit(true)); } void JUnit::Delete( const ListExpr typeInfo, Word& w ) { ((JUnit*) w.addr)->DeleteIfAllowed(); w.addr = 0; } void JUnit::Close( const ListExpr typeInfo, Word& w ) { ((JUnit*) w.addr)->DeleteIfAllowed(); w.addr = 0; } Word JUnit::Clone( const ListExpr typeInfo, const Word& w ) { return SetWord(new JUnit(*(JUnit*) w.addr)); } void* JUnit::Cast( void* addr ) { return (new (addr) JUnit); } bool JUnit::KindCheck ( ListExpr type, ListExpr& errorInfo ) { return checkType(type); } int JUnit::SizeOf() { return sizeof(JUnit); } ListExpr JUnit::Property() { return nl->TwoElemList( nl->FourElemList( nl->StringAtom("Signature"), nl->StringAtom("Example Type List"), nl->StringAtom("List Rep"), nl->StringAtom("Example List")), nl->FourElemList( nl->StringAtom("-> " + Kind::TEMPORAL()), nl->StringAtom(BasicType()), nl->TextAtom("( " + JRouteInterval::BasicType() + "), describes the positions of an mjpoint within the time interval."), nl->TextAtom(Example()))); } /* 1.1.1 Other Operations */ string JUnit::Example() { return "(((instant 0.5) (instant 0.6) TRUE FALSE)" + JRouteInterval::Example() + ")"; } /* 1.1.1.1 ExtendedBy */ bool JUnit::ExtendBy(const JUnit& other) { if (CanBeExtendedBy(other)) { JRouteInterval otherRint = other.GetRouteInterval(); temporalalgebra::Interval otherTime = other.GetTimeInterval(); SetTimeInterval(temporalalgebra::Interval (timeInter.start, otherTime.end, timeInter.lc, otherTime.rc)); Direction compD(Down); if (routeInter.GetSide() == compD) { SetRouteInterval(JRouteInterval(routeInter.GetRouteId(), otherRint.GetFirstPosition(), routeInter.GetLastPosition(), routeInter.GetSide())); } else { SetRouteInterval(JRouteInterval(routeInter.GetRouteId(), routeInter.GetFirstPosition(), otherRint.GetLastPosition(), routeInter.GetSide())); } return true; } else return Contains(other); } /* 1.1.1.1 Boxes */ Rectangle<3> JUnit::TempNetBox() const { if (IsDefined()){ double minMax[]={ (double) GetRouteInterval().GetRouteId(), (double) GetRouteInterval().GetRouteId(), GetRouteInterval().GetFirstPosition(), GetRouteInterval().GetLastPosition(), GetTimeInterval().start.ToDouble(), GetTimeInterval().end.ToDouble()}; return Rectangle<3>(true,minMax); } else return Rectangle<3>(false); } Rectangle<2> JUnit::NetBox() const { if (IsDefined()) return routeInter.NetBox(); else return Rectangle<2>(false); } /* 1.1.1.1.1 AtInstant */ IJPoint JUnit::AtInstant(const Instant* inst, const string netId) const { if (!IsDefined() || inst == 0 || !inst->IsDefined() || !timeInter.Contains(*inst,true)) return IJPoint(false); else { if (*inst == timeInter.start) return IJPoint(*inst, JPoint(netId, routeInter.GetStartLocation(), false)); else { if (*inst == timeInter.end) return IJPoint(*inst, JPoint(netId, routeInter.GetEndLocation(), false)); else return IJPoint(*inst, JPoint(netId, RouteLocation(routeInter.GetRouteId(), PosAtTime(inst), routeInter.GetSide()), false)); } } } /* 1.1.1.1 Initial */ IJPoint JUnit::Initial(const string netId) const { if (IsDefined()) return IJPoint(timeInter.start, JPoint(netId, routeInter.GetStartLocation(), false)); else return IJPoint(false); } /* 1.1.1.1 Final */ IJPoint JUnit::Final(const string netId) const { if (IsDefined()) return IJPoint(timeInter.end, JPoint(netId, routeInter.GetEndLocation(), false)); else return IJPoint(false); } /* 1.1.1.1 AtPos */ JUnit* JUnit::AtPos(const JPoint* jp) const { if (IsDefined() && jp != 0 && jp->IsDefined() && routeInter.Contains(jp->GetLocation())) { if (routeInter.GetFirstPosition() != routeInter.GetLastPosition()) { Instant time = TimeAtPos(jp->GetLocation().GetPosition()); return new JUnit(temporalalgebra::Interval ( time, time, true, true), JRouteInterval(routeInter.GetRouteId(), jp->GetLocation().GetPosition(), jp->GetLocation().GetPosition(), routeInter.GetSide())); } else { if (timeInter.start != timeInter.end) { return new JUnit(temporalalgebra::Interval ( timeInter.start, timeInter.end, false, false), JRouteInterval(routeInter.GetRouteId(), jp->GetLocation().GetPosition(), jp->GetLocation().GetPosition(), routeInter.GetSide())); } else { return new JUnit(temporalalgebra::Interval ( timeInter.start, timeInter.end, true, true), JRouteInterval(routeInter.GetRouteId(), jp->GetLocation().GetPosition(), jp->GetLocation().GetPosition(), routeInter.GetSide())); } } } else return 0; } /* 1.1.1.1 AtRint */ JUnit* JUnit::AtRint(const JRouteInterval* rint, bool& lastrc) const { if (IsDefined() && rint != 0 && rint->IsDefined()) { Direction compD(Down); Instant startTime, endTime; double startpos, endpos; bool lc = !lastrc; bool rc = false; lastrc = false; if (rint->Contains(routeInter)) { startpos = routeInter.GetStartPosition(); endpos = routeInter.GetEndPosition(); startTime = timeInter.start; endTime = timeInter.end; } else { if (rint->Inside(routeInter)) { if(routeInter.GetSide() != compD) { startpos = rint->GetFirstPosition(); endpos = rint->GetLastPosition(); } else { startpos = rint->GetLastPosition(); endpos = rint->GetFirstPosition(); } startTime = TimeAtPos(startpos); endTime = TimeAtPos(endpos); } else { if (rint->Contains(routeInter.GetStartLocation()) && rint->GetEndLocation() != routeInter.GetStartLocation()) { startpos = routeInter.GetStartPosition(); startTime = timeInter.start; if (routeInter.GetSide() != compD) endpos = rint->GetLastPosition(); else endpos = rint->GetFirstPosition(); endTime = TimeAtPos(endpos); } else { if (rint->Contains(routeInter.GetEndLocation()) && rint->GetStartLocation() != routeInter.GetEndLocation()) { endpos = routeInter.GetEndPosition(); endTime = timeInter.end; if (routeInter.GetSide() != compD) startpos = rint->GetFirstPosition(); else startpos = rint->GetLastPosition(); startTime = TimeAtPos(startpos); } else { assert(false); //should never been reached startpos = 0.0; endpos = 0.0; } } } } if (startTime == endTime) { lc = true; rc = true; lastrc = true; } return new JUnit(temporalalgebra::Interval( startTime, endTime, lc, rc), JRouteInterval(routeInter.GetRouteId(), startpos, endpos, routeInter.GetSide())); } return 0; } /* 1.1.1.1 CanBeExtendedBy */ bool JUnit::CanBeExtendedBy(const JUnit& other) const { return (timeInter.end == other.GetTimeInterval().start && routeInter.Adjacent(other.GetRouteInterval()) && AlmostEqual(GetSpeed(), other.GetSpeed())); } /* 1.1.1.1 ~PosAtTime~ */ double JUnit::PosAtTime(const Instant* inst) const { return routeInter.GetStartPosition() + ((routeInter.GetEndPosition() - routeInter.GetStartPosition())* ((*inst - timeInter.start)/(timeInter.end - timeInter.start))); } JRouteInterval* JUnit::PosAtTimeInterval( const temporalalgebra::Interval< Instant >& time) const { return new JRouteInterval(routeInter.GetRouteId(), PosAtTime(&time.start), PosAtTime(&time.end), routeInter.GetSide()); } /* 1.1.1.1 ~TimeAtPos~ */ Instant JUnit::TimeAtPos(const double pos) const { return (timeInter.end - timeInter.start)* (fabs(pos - routeInter.GetStartPosition())/ fabs(routeInter.GetEndPosition()-routeInter.GetStartPosition())) + timeInter.start; } /* 1.1.1.1 ~Contains~ */ bool JUnit::Contains(const JUnit& other) const { return (IsDefined() && other.IsDefined() && timeInter.Contains(other.GetTimeInterval(), true) && routeInter.Contains(other.GetRouteInterval())); } /* 1 Overwrite output operator */ ostream& operator<< (ostream& os, const JUnit& jp) { jp.Print(os); return os; }