/* ---- 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 ---- //paragraph [1] Title: [{\Large \bf \begin {center}] [\end {center}}] //[TOC] [\tableofcontents] [1] Header File of the Spatiotemporal Pattern Algebra Jan, 2010 Mahmoud Sakr [TOC] 1 Overview 2 Defines and includes */ #include "MSet.h" using namespace std; using namespace datetime; namespace mset{ using namespace temporalalgebra; bool Helpers::string2int(char* digit, int& result) { result = 0; while (*digit >= '0' && *digit <='9') { result = (result * 10) + (*digit - '0'); digit++; } return (*digit == 0); // true if at end of string! } string Helpers::ToString( int number ) { ostringstream o; o << number ; //<< char(0) return o.str(); } string Helpers::ToString( double number ) { ostringstream o; o << number ; //<< char(0) return o.str(); } ostream& Helpers::PrintSet( set elems, ostream &os) { set::iterator elemsIt= elems.begin(); os<& data, USet& res) const { if (this->isdefined && this->start <= this->end && this->end <= data.Size()) { res.constValue.Clear(); int elem=0; for(int i= this->start; i< this->end; ++i) { data.Get(i, elem); res.constValue.Insert(elem); } res.SetDefined(true); res.constValue.SetDefined(true); res.timeInterval= this->timeInterval; } } void USetRef::GetSet(const DbArray& data, set& res) const { if (this->isdefined && this->start < this->end && this->end <= data.Size()) { res.clear(); int elem=0; for(int i= this->start; i< this->end; ++i) { data.Get(i, elem); res.insert(elem); } } } void IntSet::Insert(int elem) { int curElem, tmp; if(this->Count()==0) { points.Put(0, elem); return; } if(this->Count()==1) { points.Get(0, tmp); if(tmp < elem) points.Put(1, elem); else if (tmp > elem) { points.Put(1, tmp); points.Put(0, elem); } return; } points.Get(this->Count()-1, tmp); if(elem > tmp) { points.Put(this->Count(), elem); return; } points.Get(0, tmp); if(elem < tmp) { for(int i= this->Count() ; i>0 ; --i) { points.Get(i-1, tmp); points.Put(i, tmp); } points.Put(0, elem); return; } int lb=0,ub=this->Count()-1,mid; //lb=>lower bound,ub=>upper bound while( (ub-lb) > 1) { mid= (lb+ub)/2; points.Get(mid, curElem); if(curElem==elem) return; //element already in set else if(curElem < elem) lb=mid; else if(curElem>elem) ub=mid; } for(int i= this->Count() ; i>ub ; --i) { points.Get(i-1, tmp); points.Put(i, tmp); } points.Put(ub, elem); } void IntSet::Union(IntSet& rhs, IntSet& res) { if(!(this->IsDefined() && rhs.IsDefined())) { res.SetDefined(false); return; } res.SetDefined(true); res.Clear(); res.CopyFrom(this); for(int i=0; iIsDefined() && rhs.IsDefined())) { res.SetDefined(false); return; } res.SetDefined(true); res.Clear(); set l, r, diff; for(int i=0; i < this->Count(); ++i) l.insert((*this)[i]); for(int i=0; i < rhs.Count(); ++i) r.insert(rhs[i]); set_difference(l.begin(), l.end(), r.begin(), r.end(), inserter(diff, diff.begin())); for(set::iterator it= diff.begin(); it != diff.end(); ++it) res.Insert(*it); } void IntSet::Union(IntSet& rhs) { if(!(this->IsDefined() && rhs.IsDefined())) { SetDefined(false); return; } for(int i=0; iSetDefined(true); } IntSet::IntSet(bool def):points(0) { this->SetDefined(def); } IntSet::IntSet(const IntSet& arg):points(0) { if(!arg.IsDefined()) { this->SetDefined(false); } else { this->points.resize(arg.Count()); this->SetDefined(true); for(int i=0; i< arg.Count(); ++i) this->Insert(arg[i]); } } IntSet::~IntSet(){} //IntSet functions bool IntSet::IsSubset(const IntSet& rhs) const { if(!(this->IsDefined() && rhs.IsDefined())) return false; if(this->Count() > rhs.Count()) return false; int l=0, r=0; while(l < this->Count() && r < rhs.Count()) { if( (*this)[l] < rhs[r]) return false; else if ( (*this)[l] == rhs[r]) {++l; ++r;} else ++r; } return (l == this->Count()); } bool IntSet::operator==(const IntSet& rhs) const { return (Compare(&rhs) == 0); } bool IntSet::operator<(const IntSet& rhs) const { return (Compare(&rhs) == -1); } bool IntSet::operator>(const IntSet& rhs) const { return (Compare(&rhs) == 1); } IntSet* IntSet::Intersection(const IntSet& rhs) const { if(!(this->IsDefined() && rhs.IsDefined())) return 0; IntSet* res(0); int l=0, r=0; while(l < this->Count() && r < rhs.Count()) { if( (*this)[l] < rhs[r]) l++; else if ( (*this)[l] == rhs[r]) {res->Insert((*this)[l]);} else ++r; } return res; } void IntSet::Intersection2(const IntSet& rhs) { if(!(this->IsDefined() && rhs.IsDefined())) return; IntSet* res(0); int l=0, r=0; while(l < this->Count() && r < rhs.Count()) { if( (*this)[l] < rhs[r]) l++; else if ( (*this)[l] == rhs[r]) {res->Insert((*this)[l]);} else ++r; } this->CopyFrom(res); res->DeleteIfAllowed(true); } int IntSet::IntersectionCount(const IntSet& rhs) const { if(!(this->IsDefined() && rhs.IsDefined())) return 0; int l=0, r=0, res=0; while(l < this->Count() && r < rhs.Count()) { if((*this)[l] < rhs[r]) ++l; else if ((*this)[l] == rhs[r]) {++res; ++l; ++r;} else ++r; } return res; } bool IntSet::Intersects(const IntSet& rhs) const { if(!(this->IsDefined() && rhs.IsDefined())) return false; int l=0, r=0; int first1= (*this)[0], first2= rhs[0], last1= (*this)[this->Count()-1], last2= rhs[rhs.Count()-1]; if( (last1 < first2) || (last2 < first1) ) return false; while(l < this->Count() && r < rhs.Count()) { if((*this)[l] < rhs[r]) ++l; else if ((*this)[l] == rhs[r]) return true; else ++r; } return false; } int IntSet::BinSearch(int elem) { int curElem=0; int lb=0,ub=this->Count()-1,mid; //lb=>lower bound,ub=>upper bound for(;lb<=ub;) { mid=(lb+ub)/2; points.Get(mid, curElem); if(curElem==elem) return mid; else if(curElem > elem) ub=mid-1; else if(curElem < elem) lb=mid+1; } return -1; } void IntSet::Delete(const int elem) { int tmp=0; int pos= BinSearch(elem); if(pos != -1) { for(int i=pos; i < this->Count()-1 ; ++i) { this->points.Get(i+1, tmp); this->points.Put(i, tmp); } this->points.resize(this->points.Size()-1); } } int IntSet::Count()const { return points.Size(); } /* mosh 3aref */ int IntSet::operator[](int index) const { if(index >= points.Size()) assert(0); int elem; this->points.Get(index, elem); return (elem); } /* members required for the Attribute interface */ size_t IntSet::HashValue() const { if(this->IsDefined()) return this->points.Size(); return 0; } void IntSet::CopyFrom(const Attribute* rhs) { const IntSet* arg= dynamic_cast(rhs); this->Clear(); if(!arg->IsDefined()) { this->SetDefined(false); return; } this->SetDefined(true); for (int a = 0; a < arg->Count(); ++a) { this->Insert( (*arg)[a]); } } int IntSet::Compare( const Attribute* arg ) const { IntSet* rhs= (IntSet*)arg; if( !this->IsDefined() && !rhs->IsDefined() ) return 0; else if(!this->IsDefined()) return -1; else if(!rhs->IsDefined()) return 1; int cnt= min(this->Count(), rhs->Count()); int thiselem=0, rhselem=0; for(int i=0; i < cnt ; ++i) { thiselem= (*this)[i]; rhselem= (*rhs)[i]; if(thiselem < rhselem) return -1; else if(thiselem > rhselem) return 1; } if(this->Count() < rhs->Count()) return -1; else if(this->Count() > rhs->Count()) return 1; return 0; } int IntSet::CompareAlmost( const Attribute* arg ) const { return Compare(arg); } ostream& IntSet::Print( ostream &os ) const { if (! this->IsDefined()) return (os << "UnDefined IntSet"); os << "\nIntSet size:" + Helpers::ToString(this->Count()); os << "\nIntSet members: " ; for (int pointIt=0 ;pointIt < this->Count(); ++pointIt) { os<<(*this)[pointIt] <<", "; } os << "\n"; return os; } size_t IntSet::Sizeof() const { return sizeof(IntSet); } bool IntSet::Adjacent(const Attribute*) const { return false; } Attribute* IntSet::Clone() const { return new IntSet(*this); } /* members required for SECONDO types */ Word IntSet::In( const ListExpr typeInfo, const ListExpr instance, int errorPos, ListExpr& errorInfo, bool& correct ) { if(nl->IsEqual(instance,"undef")) return SetWord(Address( 0 )); ListExpr elem, inst(instance); int count=0; Word elemWord; IntSet* set= new IntSet(nl->ListLength(inst)); while(! nl->IsEmpty(inst)) { elem= nl->First(inst); inst= nl->Rest(inst); if(!nl->IsAtom(elem)) { correct= false; errorInfo= nl->StringAtom("Non-integer element in list"); errorPos= count; delete set; return SetWord(Address(0)); } count++; set->Insert(nl->IntValue(elem)); } correct= true; return SetWord(set); } ListExpr IntSet::Out( ListExpr typeInfo, Word value ) { IntSet* set = static_cast(value.addr); if(!set->IsDefined()) return nl->SymbolAtom("undef"); ListExpr lastElem, elems; elems= lastElem= nl->TheEmptyList(); if(set->Count()>0) { elems = lastElem = nl->OneElemList(nl->IntAtom((*set)[0])); for(int i=1; i< set->Count(); ++i) lastElem = nl->Append(lastElem, nl->IntAtom((*set)[i])); } return elems; } Word IntSet::Create( const ListExpr typeInfo ) { return (SetWord (new IntSet(false))); } void IntSet::Delete( const ListExpr typeInfo, Word& w ) { static_cast(w.addr)->points.Destroy(); static_cast(w.addr)->DeleteIfAllowed(); w.addr= 0; } void IntSet::Close( const ListExpr typeInfo, Word& w ) { static_cast(w.addr)->DeleteIfAllowed(); w.addr= 0; } Word IntSet::Clone( const ListExpr typeInfo, const Word& w ) { IntSet* arg= static_cast(w.addr); IntSet* res= static_cast(arg->Clone()); return SetWord(res); } void* IntSet::Cast(void* addr) { return (new (addr) IntSet); } bool IntSet::KindCheck( ListExpr type, ListExpr& errorInfo ) { return (nl->IsEqual(type, "intset")); } int IntSet::SizeOfObj() { return sizeof(IntSet); } int IntSet::NumOfFLOBs()const { return 1; } Flob* IntSet::GetFLOB(const int i) { assert(i==0); return &points; } ListExpr IntSet::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("-> intset"), nl->StringAtom("(int int int int)"), nl->StringAtom("(elem1 elem2 elem3)"), nl->TextAtom("(4 1 7 3)")))); } const string IntSet::BasicType() { return "intset"; } InMemUSet::~InMemUSet() { constValue.clear(); } void InMemUSet::ReadFrom(USet& arg) { constValue.clear(); SetTimeInterval(arg.timeInterval); int elem; for(int i=0; i< arg.constValue.points.Size(); ++i) { arg.constValue.points.Get(i, elem); constValue.insert(elem); } } void InMemUSet::WriteToUSet(USet& res) { res.constValue.Clear(); res.timeInterval.start.ReadFrom(starttime); res.timeInterval.start.SetType(instanttype); res.timeInterval.end.ReadFrom(endtime); res.timeInterval.end.SetType(instanttype); res.timeInterval.lc= lc; res.timeInterval.rc= rc; for(it=constValue.begin(); it != constValue.end(); ++it) res.constValue.Insert(*it); res.SetDefined(true); res.constValue.SetDefined(true); assert(res.IsValid()); } void InMemUSet::Clear() { constValue.clear(); } void InMemUSet::ReadFrom(UBool& arg, int key) { constValue.clear(); constValue.insert(key); SetTimeInterval(arg.timeInterval); } void InMemUSet::SetTimeInterval(Interval& arg) { assert(arg.IsValid()); starttime= arg.start.millisecondsToNull(); endtime= arg.end.millisecondsToNull(); lc= arg.lc; rc= arg.rc; } void InMemUSet::Intersection(set& arg) { vector res(constValue.size() + arg.size()); vector::iterator res_end; res_end=set_intersection(constValue.begin(), constValue.end(), arg.begin(), arg.end(), res.begin()); constValue.clear(); for(vector::iterator rit=res.begin(); rit != res_end; ++rit) constValue.insert(*rit); } bool InMemUSet::Intersects(set& arg) { if(this->constValue.empty() || arg.empty()) return false; set::iterator first1= this->constValue.begin(), first2= arg.begin(), last1 = this->constValue.end(), last2 = arg.end(); --last1; --last2; if( (*last1 < *first2) || (*last2 < *first1) ) return false; ++last1; ++last2; while (first1 != last1 && first2 != last2) { if (*first1 < *first2) ++first1; else if (*first2 < *first1) ++first2; else return true; } return false; } void InMemUSet::Intersection(set& arg, set& result) { vector res(constValue.size() + arg.size()); vector::iterator res_end; res_end=set_intersection(constValue.begin(), constValue.end(), arg.begin(), arg.end(), res.begin()); result.clear(); for(vector::iterator rit=res.begin(); rit != res_end; ++rit) result.insert(*rit); } void InMemUSet::Union(set& arg) { vector res(constValue.size() + arg.size()); vector::iterator res_end; res_end=set_union (constValue.begin(), constValue.end(), arg.begin(), arg.end(), res.begin()); constValue.clear(); for(vector::iterator rit=res.begin(); rit != res_end; ++rit) constValue.insert(*rit); } void InMemUSet::Union(set& arg, set& result) { vector res(constValue.size() + arg.size()); vector::iterator res_end; res_end=set_union (constValue.begin(), constValue.end(), arg.begin(), arg.end(), res.begin()); result.clear(); for(vector::iterator rit=res.begin(); rit != res_end; ++rit) result.insert(*rit); } ostream& InMemUSet::Print( ostream &os ) { if( constValue.size() == 0 ) { return os << "(USet: empty)"; } Instant tmp(instanttype); tmp.ReadFrom(starttime); char c= (lc)? '[' : '('; os<< c ; tmp.Print(os); tmp.ReadFrom(endtime); os<< "\t"; tmp.Print(os); c= (rc)? ']' : ')'; os << c << " {"; for(it=constValue.begin(); it != constValue.end(); ++it) { os<<(*it); os << ","; } // it= constValue.begin(); // int b = *(constValue.begin()), e= *(--(constValue.end())); // for(int beg= b; beg <= e; ++beg) // { // if(beg == *it) {os<<(*it)<<"\t"; ++it;} // else os<<"e\t"; // // } os << "}" << endl; return os; } unsigned int InMemUSet::Count() { return constValue.size(); } void InMemUSet::Insert(int elem) { constValue.insert(elem); } void InMemUSet::CopyValueFrom(set& arg) { constValue.clear(); for(it=arg.begin(); it != arg.end(); ++it) constValue.insert(*it); } void InMemUSet::CopyFrom(InMemUSet& arg) { constValue.clear(); for(it=arg.constValue.begin(); it != arg.constValue.end(); ++it) constValue.insert(*it); starttime= arg.starttime; endtime= arg.endtime; rc= arg.rc; lc= arg.lc; } InMemMSet::InMemMSet(){} InMemMSet::InMemMSet(MSet& arg) { USet uset(true); USetRef usetref(true); for(int i=0; i< arg.GetNoComponents(); ++i) { arg.Get(i, usetref); usetref.GetUnit(arg.data, uset); InMemUSet tmp(uset); units.push_back(tmp); } } InMemMSet::InMemMSet(InMemMSet& arg, list::iterator begin, list::iterator end) { CopyFrom(arg, begin, end); } InMemMSet::~InMemMSet() { Clear(); } void InMemMSet::Clear() { for(it= units.begin(); it != units.end(); ++it) (*it).constValue.clear(); units.clear(); } int InMemMSet::GetNoComponents() { return units.size(); } void InMemMSet::CopyFrom(InMemMSet& arg) { Clear(); for(arg.it= arg.units.begin(); arg.it != arg.units.end(); ++arg.it) units.push_back(*arg.it); } void InMemMSet::CopyFrom(InMemMSet& arg, list::iterator begin, list::iterator end) { Clear(); for(arg.it= begin; arg.it != end; ++arg.it) units.push_back(*arg.it); units.push_back(*end); } void InMemMSet::ReadFrom(MBool& mbool, int key) { UBool ubool; InMemUSet uset; uset.constValue.insert(key); for(int i=0; iunits.push_back(uset); } } } void InMemMSet::WriteToMSet(MSet& res) { if(units.begin() == units.end()) { res.SetDefined(false); return; } res.Clear(); res.SetDefined(true); for(it=units.begin(); it != units.end(); ++it) { USet uset(true); (*it).WriteToUSet(uset); res.MergeAdd(uset); } } void InMemMSet::WriteToMSet(MSet& res, list::iterator begin, list::iterator end) { if(begin == units.end()) { res.SetDefined(false); return; } res.Clear(); res.SetDefined(true); for(it=begin; it != end; ++it) { USet uset(true); (*it).WriteToUSet(uset); res.MergeAdd(uset); } } bool InMemMSet::MergeAdd( set& val, int64_t &starttime, int64_t &endtime, bool lc, bool rc) { bool merged= false; if(!units.empty()) { InMemUSet* lastElem= &units.back(); if( (starttime == lastElem->endtime) && (lc || lastElem->rc)) { merged= true; bool equals= ((val.size() == lastElem->constValue.size()) && equal(val.begin(), val.end(), lastElem->constValue.begin())); if(equals) { lastElem->endtime= endtime; lastElem->rc= rc; return merged; } } } InMemUSet uset(val, starttime, endtime, lc, rc); units.push_back(uset); return merged; } ostream& InMemMSet::Print( ostream &os ) { if( units.size() == 0 ) { return os << "(InMemMSet: undefined)"; } os << "(InMemMSet: defined, contains " << units.size() << " units: "; for(it=units.begin(); it != units.end(); ++it) { //os << "\n\t"; (*it).Print(os); } os << "\n)" << endl; return os; } void InMemMSet::Union (InMemMSet& arg) { bool debugme=false; int no1 = units.size(); int no2 = arg.units.size(); if(no2==0) return; if(no1==0) { this->CopyFrom(arg); return; } // both arguments are non-empty arg.it = arg.units.begin(); it= units.begin(); int64_t a= (*it).starttime, A=(*it).endtime; int64_t b= (*arg.it).starttime, B=(*arg.it).endtime; bool lcA= (*it).lc, rcA= (*it).rc; bool lcB= (*arg.it).lc, rcB= (*arg.it).rc; InMemMSet result; while(it != units.end() && arg.it != arg.units.end() ) { // both arguments have units if(a < b){ if (debugme) cerr< b){ if (debugme) cerr< a){ if (debugme) cerr< opres; (*it).Union((*arg.it).constValue, opres); if(A < B){ if (debugme) cerr<CopyFrom(result); } bool InMemMSet::RemoveSmallUnits(const unsigned int n) { bool debugme= false; bool changed=false; if(units.size()==0) return false; it= units.end(); --it; while(it!= units.begin()) { if(debugme) {cerr<::iterator begin=units.begin(), end= units.begin(), tmp; while(begin != units.end()) { end = GetPeriodEndUnit(begin); if(((*end).endtime - (*begin).starttime) < dMS) { tmp= end; ++tmp; begin= units.erase(begin, tmp); changed= true; } } return changed; } ostream& InMemMSet::Print( map elems, ostream &os ) { map::iterator elemsIt= elems.begin(); while(elemsIt != elems.end()) { os<<(*elemsIt).first<<" "; (*(*elemsIt).second.second).Print(os); os<::iterator cur= units.begin() , prev, end, tmp; // typedef pair::iterator > inst; map elems; map::iterator elemsIt; bool changed=false; // if(debugme) // Print(cerr); while(cur != units.end()) { end = GetPeriodEndUnit(cur); if(debugme) { (*cur).Print(cerr); (*end).Print(cerr); } if(debugme) { MSet tmp1(0); WriteToMSet(tmp1); tmp1.Print(cerr); } /* IF the period length is less than d, remove all units within the period */ if(((*end).endtime - (*cur).starttime) < dMS) { ++end; cur= units.erase(cur, end); changed= true; } /* ELSE remove short parts of elements as follows: 1. Initialize a hashtable [mset element, its deftime] 2. Update the deftime of every element while iterating ovet the units 3. After each iteration, elements are not updated must have deftime > d, otherwise their observed part is removed from the MSet */ else { elems.clear(); bool firstIteration= true; ++end; vector diff(0); vector diff2(0); vector::iterator diffEnd, diffIt; vector::iterator diff2End, diff2It; while(cur != end) { if(firstIteration) { for(set::iterator elem= (*cur).constValue.begin(); elem != (*cur).constValue.end(); ++elem) { if(debugme) { cerr<(*elem, lt)); } firstIteration= false; prev= cur; ++cur; continue; } if(debugme) { Print(elems,cerr); (*prev).Print(cerr); (*cur).Print(cerr); } diff.resize((*prev).constValue.size()); //Finalize the elements that do not appear anymore in the cur unit diffEnd= set_difference((*prev).constValue.begin(), (*prev).constValue.end(), (*cur).constValue.begin(), (*cur).constValue.end(), diff.begin()); diffIt = diff.begin(); while(diffIt != diffEnd) { int elemToRemove= *diffIt; elemsIt= elems.find(elemToRemove); assert(elemsIt != elems.end()); if( ((*prev).endtime - (*elemsIt).second.first) < dMS ) { list::iterator unitToChange= (*elemsIt).second.second; for(; unitToChange != cur; ++unitToChange) (*unitToChange).constValue.erase(elemToRemove); changed = true; } elems.erase(elemsIt); ++diffIt; } diff2.resize((*cur).constValue.size()); //Add the new elements that starts to appear in the cur unit diff2End= set_difference((*cur).constValue.begin(), (*cur).constValue.end(), (*prev).constValue.begin(), (*prev).constValue.end(), diff2.begin()); diff2It = diff2.begin(); while(diff2It != diff2End) { inst lt((*cur).starttime, cur); elems.insert(pair(*diff2It, lt)); ++diff2It; } prev= cur; ++cur; } for(elemsIt= elems.begin(); elemsIt != elems.end(); ++elemsIt) { if(debugme) { cerr<<(*elemsIt).first; cerr<::iterator unitToChange= (*elemsIt).second.second; for(; unitToChange != cur; ++unitToChange) (*unitToChange).constValue.erase( (*elemsIt).first); changed = true; } } cur= end; } } return changed; } // bool RemoveShortElemParts(const double d) // { // bool debugme= false; // // //handling special cases // if(units.size()==0) return false; // if(units.size()==1) // { // if((units[0].endtime - units[0].starttime) < d) // { // units.clear(); return true; // } // else // return false; // } // // // // list::iterator begin=units.begin(),cur=units.begin(), end, tmp; // typedef pair::iterator > inst; // typedef pair< inst , inst> lifetime; // map elems; // map::iterator elemsIt; // bool changed=false; // if(debugme) // Print(cerr); // while(begin != units.end()) // { // end = GetPeriodEndUnit(begin); // if(debugme) // { // (*begin).Print(cerr); // (*end).Print(cerr); // } ///* //IF the period length is less than d, remove all units within the period // //*/ // if(((*end).endtime - (*begin).starttime) < d) // { // tmp= end; ++tmp; // begin= units.erase(begin, tmp); // changed= true; // } ///* //ELSE remove short parts of elements as follows: // 1. Initialize a hashtable [mset element, its deftime] // 2. Update the deftime of every element while iterating ovet the units // 3. After each iteration, elements are not updated must have deftime > d, // otherwise their observed part is removed from the MSet //*/ // else // { // cur= begin; // list::iterator periodend= end; // for(set::iterator elem= (*begin).constValue.begin(); elem != // (*begin).constValue.end(); ++elem) // { // if(debugme) // { // cerr<(*elem, lt)); // } // ++periodend; // ++cur; // // while(cur != periodend) // { // for(set::iterator elem= (*cur).constValue.begin(); elem != // (*cur).constValue.end(); ++elem) // { // if(debugme) // cerr<(*elem, lt)); // if(debugme) // { // cerr<::iterator InMemMSet::GetPeriodEndUnit(list::iterator begin) { bool debugme= false; if(begin == units.end()) return begin; if(debugme) (*begin).Print(cerr); list::iterator end=begin; int64_t totalLength= (*begin).endtime - (*begin).starttime, curLength=0; ++end; while(end != units.end()) { curLength = (*end).endtime - (*end).starttime; totalLength += curLength; if(totalLength != ((*end).endtime - (*begin).starttime)) break; ++end; } --end; return end; } list::iterator InMemMSet::GetPeriodStartUnit(list::iterator end) { if(end == units.begin()) return end; list::iterator begin= end; int64_t totalLength= (*end).endtime - (*end).starttime, curLength=0; --begin; while(begin != units.begin()) { curLength = (*begin).endtime - (*begin).starttime; totalLength += curLength; if(totalLength != ((*end).endtime - (*begin).starttime)) { ++begin; return begin; } --begin; } curLength = (*begin).endtime - (*begin).starttime; totalLength += curLength; if(totalLength != ((*end).endtime - (*begin).starttime)) ++begin; return begin; } bool InMemMSet::GetNextTrueUnit(MBool& mbool, int& pos, UBool& unit) { while(pos < mbool.GetNoComponents()) { mbool.Get(pos, unit); if(unit.IsDefined() && unit.constValue.GetValue()) return true; else ++pos; } return false; } void InMemMSet::Union (MBool& arg, int key) { bool debugme=false; int no1 = units.size(); int no2 = arg.GetNoComponents(); if(no2==0) return; if(no1==0) { this->ReadFrom(arg, key); return; } // both arguments are non-empty UBool ubool; int rhsit=0; InMemUSet rhs; if (!GetNextTrueUnit(arg, rhsit, ubool)) return; rhs.ReadFrom(ubool, key); it= units.begin(); int64_t a= (*it).starttime, A=(*it).endtime; int64_t b= rhs.starttime, B=rhs.endtime; bool lcA= (*it).lc, rcA= (*it).rc; bool lcB= rhs.lc, rcB= rhs.rc; InMemMSet result; while(it != units.end() && rhsit < arg.GetNoComponents() ) { // both arguments have units if(a < b){ if (debugme) cerr< b){ if (debugme) cerr< a){ if (debugme) cerr< opres; (*it).Union(rhs.constValue, opres); if(A < B){ if (debugme) cerr<CopyFrom(result); } void CompressedInMemUSet::Erase(int victim) { it= added.find(victim); if(it != added.end()) added.erase(it); else removed.insert(victim); } void CompressedInMemUSet::Insert(int elem) { it= removed.find(elem); if(it != removed.end()) removed.erase(it); else added.insert(elem); } ostream& CompressedInMemUSet::Print( ostream &os ) { char l= (lc)? '[' : '('; char r= (rc)? ']' : ')'; Instant i1(instanttype), i2(instanttype); i1.ReadFrom(starttime); i2.ReadFrom(endtime); os<< endl<< l<< i1<< "\t"<< i2<< r<< "\tCount= "<< count; return os; } bool CompressedInMemUSet::EraseNodes( vector& removedNodes, vector >& edge2nodesMap) { pair edgeNodes; set::iterator it= added.begin(); bool changed= false; while(it != added.end()) { edgeNodes= edge2nodesMap[*it]; if(find(removedNodes.begin(), removedNodes.end(), edgeNodes.first) != removedNodes.end() || find(removedNodes.begin(), removedNodes.end(), edgeNodes.second) != removedNodes.end()) { added.erase(it++); changed= true; } else ++it; } it= removed.begin(); while(it != removed.end()) { edgeNodes= edge2nodesMap[*it]; if(find(removedNodes.begin(), removedNodes.end(), edgeNodes.first) != removedNodes.end() || find(removedNodes.begin(), removedNodes.end(), edgeNodes.second) != removedNodes.end()) { removed.erase(it++); changed= true; } else ++it; } return changed; } CompressedInMemMSet::CompressedInMemMSet():validLastUnitValue(false){} CompressedInMemMSet::CompressedInMemMSet(CompressedInMemMSet& arg, list::iterator begin, list::iterator end) { CopyFrom(arg, begin, end); } int CompressedInMemMSet::GetNoComponents() { return units.size(); } void CompressedInMemMSet::CopyFrom(CompressedInMemMSet& arg, list::iterator begin, list::iterator end) { //copies the range [begin, end) into this bool debugme= false; Clear(); if(begin == end) return; set accumlator; arg.GetSet(begin, accumlator); if(debugme) { int tmp= accumlator.size(); cerr << endl<* argLast = arg.GetFinalSet(); copy(argLast->begin(), argLast->end(), inserter(lastUnitValue, lastUnitValue.begin())); this->validLastUnitValue= true; } else this->validLastUnitValue= false; } void CompressedInMemMSet::Clear() { buffer.clear(); units.clear(); lastUnitValue.clear(); validLastUnitValue= true; } void CompressedInMemMSet::GetSet( list::iterator index, set& res) { res.clear(); if(index == units.end()) return; list::iterator i= units.begin(); for(; i!= index; ++i) { res.insert( (*i).added.begin(), (*i).added.end() ); for(set::iterator elem= (*i).removed.begin(); elem != (*i).removed.end(); ++elem) res.erase(*elem); } res.insert( (*index).added.begin(), (*index).added.end() ); for(set::iterator elem= (*index).removed.begin(); elem != (*index).removed.end(); ++elem) res.erase(*elem); } void CompressedInMemMSet::WriteToMSet(MSet& res) { set constValue; if(units.begin() == units.end()) { res.SetDefined(false); return; } res.Clear(); res.SetDefined(true); for(it=units.begin(); it != units.end(); ++it) { USet uset(true); if((*it).added.size() != 0) constValue.insert((*it).added.begin(), (*it).added.end()); if((*it).removed.size() != 0) { for((*it).it= (*it).removed.begin(); (*it).it != (*it).removed.end(); ++(*it).it) constValue.erase(*(*it).it); } WriteUSet(constValue, *it, uset); res.MergeAdd(uset); } } void CompressedInMemMSet::WriteUSet( set& val, CompressedInMemUSet& source, USet& res) { res.constValue.Clear(); res.timeInterval.start.ReadFrom(source.starttime); res.timeInterval.start.SetType(instanttype); res.timeInterval.end.ReadFrom(source.endtime); res.timeInterval.end.SetType(instanttype); res.timeInterval.lc= source.lc; res.timeInterval.rc= source.rc; for(set::iterator i= val.begin(); i != val.end(); ++i) res.constValue.Insert(*i); res.SetDefined(true); res.constValue.SetDefined(true); assert(res.IsValid()); } void CompressedInMemMSet::WriteToMSet( MSet& res, list::iterator begin, list::iterator end) { if(begin == units.end()) { res.SetDefined(false); return; } res.Clear(); res.SetDefined(true); set constValue; for(it=units.begin(); it != begin; ++it) { if((*it).added.size() != 0) constValue.insert((*it).added.begin(), (*it).added.end()); if((*it).removed.size() != 0) { for((*it).it= (*it).removed.begin(); (*it).it != (*it).removed.end(); ++(*it).it) constValue.erase(*(*it).it); } } for(it=begin; it != end; ++it) { USet uset(true); if((*it).added.size() != 0) constValue.insert((*it).added.begin(), (*it).added.end()); if((*it).removed.size() != 0) { for((*it).it= (*it).removed.begin(); (*it).it != (*it).removed.end(); ++(*it).it) constValue.erase(*(*it).it); } WriteUSet(constValue, *it, uset); res.MergeAdd(uset); } } void CompressedInMemMSet::WriteToInMemMSet(InMemMSet& res, list::iterator begin, list::iterator end) { if(begin == units.end()) { res.Clear(); return; } res.Clear(); set constValue; for(it=units.begin(); it != begin; ++it) { if((*it).added.size() != 0) constValue.insert((*it).added.begin(), (*it).added.end()); if((*it).removed.size() != 0) { for((*it).it= (*it).removed.begin(); (*it).it != (*it).removed.end(); ++(*it).it) constValue.erase(*(*it).it); } } for(it=begin; it != end; ++it) { if((*it).added.size() != 0) constValue.insert((*it).added.begin(), (*it).added.end()); if((*it).removed.size() != 0) { for((*it).it= (*it).removed.begin(); (*it).it != (*it).removed.end(); ++(*it).it) constValue.erase(*(*it).it); } InMemUSet uset(constValue, (*it).starttime, (*it).endtime, (*it).lc, (*it).rc); res.units.push_back(uset); } } void CompressedInMemMSet::WriteToInMemMSet(InMemMSet& res) { list::iterator begin = units.begin(); list::iterator end = units.end(); if(begin == units.end()) { res.Clear(); return; } res.Clear(); set constValue; for(it=begin; it != end; ++it) { if((*it).added.size() != 0) constValue.insert((*it).added.begin(), (*it).added.end()); if((*it).removed.size() != 0) { for((*it).it= (*it).removed.begin(); (*it).it != (*it).removed.end(); ++(*it).it) constValue.erase(*(*it).it); } InMemUSet uset(constValue, (*it).starttime, (*it).endtime, (*it).lc, (*it).rc); res.units.push_back(uset); } } ostream& CompressedInMemMSet::Print( ostream &os ) { if( units.size() == 0 ) { return os << "(InMemMSet: undefined)"; } os << "(InMemMSet: defined, contains " << units.size() << " units: "; set constValue; for(it=units.begin(); it != units.end(); ++it) { os<<"\n["; Instant i(instanttype); i.ReadFrom((*it).starttime ); i.Print(os); os<<", "; i.ReadFrom((*it).endtime ); i.Print(os); os<< "]"; if((*it).added.size() != 0) constValue.insert((*it).added.begin(), (*it).added.end()); if((*it).removed.size() != 0) { for((*it).it= (*it).removed.begin(); (*it).it != (*it).removed.end(); ++(*it).it) constValue.erase(*(*it).it); } os<< " Set cardinality = "<< constValue.size()<<" {"; for(set::iterator k= constValue.begin(); k != constValue.end();++k) os<< *k<< ", "; os<<"}"; } os << "\n)" << endl; return os; } list::iterator CompressedInMemMSet::EraseUnit( list::iterator pos) { bool debugme= false; if(pos == units.end()) return pos; list::iterator next= pos; ++next; if(next == units.end()) { validLastUnitValue= false; next= units.erase(pos); return next; } if(debugme) { (*pos).Print(cerr); cerr< common((*pos).added.size() + (*pos).removed.size()); vector::iterator last; last= set_intersection((*pos).added.begin(), (*pos).added.end(), (*next).removed.begin(), (*next).removed.end(), common.begin()); for(vector::iterator i= common.begin(); i< last; ++i) { (*next).removed.erase(*i); (*pos).added.erase(*i); } (*next).added.insert((*pos).added.begin(), (*pos).added.end()); last= set_intersection((*pos).removed.begin(), (*pos).removed.end(), (*next).added.begin(), (*next).added.end(), common.begin()); for(vector::iterator i= common.begin(); i< last; ++i) { (*next).added.erase(*i); (*pos).removed.erase(*i); } (*next).removed.insert((*pos).removed.begin(), (*pos).removed.end()); if(debugme) { (*pos).Print(cerr); cerr<::iterator CompressedInMemMSet::EraseUnits( list::iterator start, list::iterator end) { if(start== units.end()) return start; list::iterator pos= end; --pos; while(pos != start) { pos= EraseUnit(pos); --pos; } pos= EraseUnit(pos); return pos; } bool CompressedInMemMSet::RemoveSmallUnits(const unsigned int n) { bool debugme= false; bool changed=false; if(units.size()==0) return false; list::iterator i= units.end(); --i; while(i!= units.begin()) { if(debugme) {cerr< elems, ostream &os ) { map::iterator elemsIt= elems.begin(); while(elemsIt != elems.end()) { os<<(*elemsIt).first<<" "; os<< "\n Set cardinality = "<< (*(*elemsIt).second.second).count<<" {"; // for(set::iterator k= (*(*elemsIt).second.second).constValue.begin(); // k != (*(*elemsIt).second.second).constValue.end();++k) // os<< *k<< ", "; // os<<"}"; // os<::iterator cur= units.begin() , prev, end, tmp; // typedef pair::iterator > inst; map elems; map::iterator elemsIt; bool changed=false; while(cur != units.end()) { end = GetPeriodEndUnit(cur); if(debugme && 0) { MSet tmp(0); WriteToMSet(tmp); tmp.Print(cerr); cerr<<"\nCur: "; (*cur).Print(cerr); cerr<<"\nEnd: "; (*end).Print(cerr); } /* IF the period length is less than d, remove all units within the period */ if(((*end).endtime - (*cur).starttime) < dMS) { ++end; cur= EraseUnits(cur, end); changed= true; if(debugme && 0) { MSet tmp(0); WriteToMSet(tmp); tmp.Print(cerr); } continue; } /* ELSE remove short parts of elements as follows: 1. Initialize a hashtable [mset element, its deftime] 2. Update the deftime of every element while iterating ovet the units 3. After each iteration, elements are not updated must have deftime > d, otherwise their observed part is removed from the MSet */ else { elems.clear(); //assert( (*cur).removed.size() == 0); set initialIdSet; GetSet(cur, initialIdSet); for(set::iterator elem= initialIdSet.begin(); elem != initialIdSet.end(); ++elem) { if(debugme && 0) cerr<(*elem, lt)); } if(debugme && 0) Print(elems, cerr); prev= cur; ++cur; ++end; int cnt=0; while(cur != end) { if(debugme) { cerr<::iterator diffIt= (*cur).removed.begin(), tmpIt; if(debugme) { cerr<::iterator unitToChange= (*elemsIt).second.second; (*unitToChange).Erase(elemToRemove); while(unitToChange != cur) { --((*unitToChange).count); ++unitToChange; } //tmpIt = diffIt; ++tmpIt; (*cur).removed.erase(diffIt++); //if(! (*cur).removed.empty()) // diffIt = --tmpIt; //else // diffIt = (*cur).removed.end(); changed = true; elems.erase(elemsIt); } else { ++diffIt; elems.erase(elemsIt); } } if(debugme) Print(elems, cerr); //Add the new elements that starts to appear in the cur unit diffIt= (*cur).added.begin(); if(debugme) { cerr<(*diffIt, lt)); ++diffIt; } prev= cur; ++cur; if(debugme && 0) { Print(elems, cerr); MSet tmp(0); WriteToMSet(tmp); tmp.Print(cerr); } } for(elemsIt= elems.begin(); elemsIt != elems.end(); ++elemsIt) { if(debugme) { cerr<<(*elemsIt).first; cerr<::iterator unitToChange= (*elemsIt).second.second; //Erase from the current period (*unitToChange).Erase((*elemsIt).first); while(unitToChange != cur) { --((*unitToChange).count); ++unitToChange; } if(end != units.end()) //insert again in the following period (*end).Insert((*elemsIt).first); changed = true; } } if(debugme ) { Print(elems, cerr); MSet tmp(0); WriteToMSet(tmp); tmp.Print(cerr); } } cur=end; } if(changed) validLastUnitValue= false; return changed; } list::iterator CompressedInMemMSet::GetPeriodEndUnit( list::iterator begin) { bool debugme= false; if(begin == units.end()) return begin; if(debugme) { cerr<< "\n Set cardinality = "<< (*begin).count<<" {"; // for(set::iterator k= (*begin).constValue.begin(); // k != (*begin).constValue.end();++k) // cerr<< *k<< ", "; cerr<<"}"; } list::iterator end=begin; int64_t totalLength= (*begin).endtime - (*begin).starttime, curLength=0; ++end; while(end != units.end()) { curLength = (*end).endtime - (*end).starttime; totalLength += curLength; if(totalLength != ((*end).endtime - (*begin).starttime)) break; ++end; } --end; return end; } bool CompressedInMemMSet::GetNextTrueUnit(MBool& mbool, int& pos, UBool& unit) { while(pos < mbool.GetNoComponents()) { mbool.Get(pos, unit); if(unit.IsDefined() && unit.constValue.GetValue()) return true; else ++pos; } return false; } bool CompressedInMemMSet::Buffer (MBool& arg, int key) { if(arg.GetNoComponents()==0) return false; bool trueUnitFound= false; UBool ubool; int cur=0; int64_t starttime, endtime; bool lc, rc; while(GetNextTrueUnit(arg, cur, ubool)) { trueUnitFound= true; assert(ubool.IsValid()); starttime= ubool.timeInterval.start.millisecondsToNull(); endtime= ubool.timeInterval.end.millisecondsToNull(); lc= ubool.timeInterval.lc; rc= ubool.timeInterval.rc; Event entrance(key, (lc)? closedstart: openstart); Event theleave(key, (rc)? closedend: openend); buffer.insert(pair(starttime, entrance)); buffer.insert(pair(endtime, theleave)); ++cur; } return trueUnitFound; } bool CompressedInMemMSet::Buffer (MBool& arg, int key, int64_t dMS) { if(arg.GetNoComponents()==0) return false; bool longUnitFound= false; UBool ubool; int cur=0; int64_t starttime, endtime; bool lc, rc; while(GetNextTrueUnit(arg, cur, ubool)) { assert(ubool.IsValid()); starttime= ubool.timeInterval.start.millisecondsToNull(); endtime= ubool.timeInterval.end.millisecondsToNull(); ++cur; if(endtime - starttime < dMS) continue; lc= ubool.timeInterval.lc; rc= ubool.timeInterval.rc; Event entrance(key, (lc)? closedstart: openstart); Event theleave(key, (rc)? closedend: openend); buffer.insert(pair(starttime, entrance)); buffer.insert(pair(endtime, theleave)); longUnitFound= true; } return longUnitFound; } void CompressedInMemMSet::ClassifyEvents( pair< multimap::iterator, multimap::iterator >& events, map::iterator> >& eventClasses) { eventClasses[openstart].clear(); eventClasses[closedstart].clear(); eventClasses[openend].clear(); eventClasses[closedend].clear(); if(events.first == events.second) return; for(multimap::iterator k= events.first; k != events.second; ++k) { if((*k).second.type == openstart) eventClasses[openstart].push_back(k); else if((*k).second.type == closedstart) eventClasses[closedstart].push_back(k); else if((*k).second.type == openend) eventClasses[openend].push_back(k); else if((*k).second.type == closedend) eventClasses[closedend].push_back(k); else assert(0); } } void CompressedInMemMSet::AddUnit( int64_t starttime, int64_t endtime, bool lc, bool rc, set& elemsToAdd, set& elemsToRemove, int elemsCount) { bool debugme= false; if(elemsToAdd.empty() && elemsToRemove.empty()) return; CompressedInMemUSet unit; unit.starttime= starttime; unit.endtime= endtime; unit.lc= lc; unit.rc= rc; unit.added= elemsToAdd; unit.removed= elemsToRemove; unit.count= elemsCount; units.push_back(unit); if(debugme) { char l= (unit.lc)? '[' : '(', r = (unit.rc)? ']' : ')'; Instant i1(instanttype),i2(instanttype); i1.ReadFrom(unit.starttime); i2.ReadFrom(unit.endtime); cerr<<"\nAdding unit "<< l ; i1.Print(cerr); cerr<<", "; i2.Print(cerr); cerr<data.Append( unit.constValue[i] ); this->units.Append(unitref); } int MSet::NumOfFLOBs()const {return 2;} Flob *MSet::GetFLOB(const int i) { if(i==0) return &units; if(i==1) return &data; assert(0); } int MSet::Compare( const Attribute* arg ) const { MSet* rhsMSet= (MSet*) arg; USetRef lhsRef(0), rhsRef(0); USet lhs(0), rhs(0); int cnt= min(this->GetNoComponents(), rhsMSet->GetNoComponents()); int cmp=0; for(int i=0; i < cnt; ++i) { this->Get(i, lhsRef); lhsRef.GetUnit(this->data, lhs); rhsMSet->Get(i, lhsRef); rhsRef.GetUnit(rhsMSet->data, lhs); cmp= lhs.Compare(&rhs); if(cmp != 0) return cmp; } if(this->GetNoComponents() < rhsMSet->GetNoComponents()) return -1; else if(this->GetNoComponents() > rhsMSet->GetNoComponents()) return 1; return 0; } int MSet::CompareAlmost( const Attribute* arg ) const { MSet* rhsMSet= (MSet*) arg; USetRef lhsRef(0), rhsRef(0); USet lhs(0), rhs(0); int cnt= min(this->GetNoComponents(), rhsMSet->GetNoComponents()); int cmp=0; for(int i=0; i < cnt; ++i) { this->Get(i, lhsRef); lhsRef.GetUnit(this->data, lhs); rhsMSet->Get(i, lhsRef); lhsRef.GetUnit(rhsMSet->data, lhs); cmp= lhs.CompareAlmost(&rhs); if(cmp != 0) return cmp; } if(this->GetNoComponents() < rhsMSet->GetNoComponents()) return -1; else if(this->GetNoComponents() > rhsMSet->GetNoComponents()) return 1; else return 0; } ostream& MSet::Print( ostream &os ) const { if( !IsDefined() ) { return os << "(MSet: undefined)"; } os << "(MSet: defined, contains " << GetNoComponents() << " units: "; for(int i=0; iSetDefined( false ); return result; } result = new MSet( GetNoComponents() ); result->SetDefined( true ); assert( IsOrdered() ); if(GetNoComponents()>0){ result->units.resize(GetNoComponents()); result->data.resize(GetNoComponents()); } result->StartBulkLoad(); USetRef unitRef; USet unit(false); for( int i = 0; i < GetNoComponents(); i++ ) { Get( i, unitRef ); unitRef.GetUnit(this->data, unit); result->Add( unit ); } result->EndBulkLoad( false ); return result; } /* mosh 3aref */ inline void MSet::CopyFrom( const Attribute* right ) { const MSet *r = (MSet*)right; Clear(); SetDefined( r->IsDefined() ); if( !r->IsDefined() ){ return; } assert( r->IsOrdered() ); StartBulkLoad(); USetRef unitRef; USet unit(false); for( int i = 0; i < r->GetNoComponents(); i++ ) { r->Get( i, unitRef ); unitRef.GetUnit(r->data, unit); Add( unit ); } EndBulkLoad( false ); this->SetDefined(r->IsDefined()); } //int MSet::NumOfFLOBs() const { return 3;} //Flob* MSet::GetFLOB(const int i) //{ // if(dirty) // { // Finalize(); // dirty=false; // } // if(i==0) // return &this->offset; // else if(i==1) // return &this->interval; // else if(i==2) // return &this->elems; // else // assert(0); // return 0; //} bool MSet::KindCheck( ListExpr type, ListExpr& errorInfo ) { return (nl->IsEqual(type, "mset")); } ListExpr MSet::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("-> mset"), nl->StringAtom("((uset) (uset) (uset))"), nl->StringAtom("((uset1) (uset2) (uset3))"), nl->TextAtom("(_ _ _ _)")))); } ListExpr MSet::OutMSet(ListExpr typeInfo, Word value) { bool debugme=false; MSet* ms = static_cast( value.addr ); // check for undefined value if( !ms->IsDefined() ) return (nl->SymbolAtom("undef")); if (ms->IsEmpty()) return (nl->TheEmptyList()); ListExpr l = nl->TheEmptyList(); ListExpr lastElem = l; // CD: lastElem was uninitialized USetRef unitRef; USet unit(true); for (int i = 0; i < ms->GetNoComponents(); i++) { ms->Get(i, unitRef); unitRef.GetUnit(ms->data, unit); ListExpr unitList = USet::OutUSet(nl->TheEmptyList(), SetWord(&unit)); if (l == nl->TheEmptyList()) { l = nl->Cons(unitList, nl->TheEmptyList()); lastElem = l; } else lastElem = nl->Append(lastElem, unitList); } if(debugme) cerr<< endl<ToString(l)<ToString(instance)<IsAtom( instance ) && nl->AtomType( instance ) == SymbolType && nl->SymbolValue( instance ) == "undef" ) { ms->SetDefined(false); correct = true; return SetWord ( ms ); } ms->StartBulkLoad(); Word unit; ListExpr rest = instance; while(!nl->IsEmpty(rest)) { ListExpr first = nl->First(rest); rest = nl->Rest(rest); unit = USet::InUSet(nl->TheEmptyList(), first, errorPos, errorInfo, correct); if (!correct) { ms->Destroy(); delete ms; return SetWord(Address(0)); } ms->Add( (*static_cast(unit.addr))); delete static_cast(unit.addr); } ms->EndBulkLoad(true); if (ms->IsValid()) { correct = true; return SetWord(ms); } else { correct = false; ms->Destroy(); delete ms; return SetWord(Address(0)); } } Word MSet::CreateMSet( const ListExpr typeInfo ) { return (SetWord( new MSet( 0 ) )); } void MSet::DeleteMSet( const ListExpr typeInfo, Word& w ) { static_cast(w.addr)->data.Destroy(); static_cast(w.addr)->Destroy(); delete static_cast(w.addr); w.addr = 0; } bool MSet::operator ==(MSet& rhs) { return ! (*this != rhs); } bool MSet::operator !=(MSet& rhs) { if( !this->IsDefined() || !rhs.IsDefined()) return true; if(this->GetNoComponents() != rhs.GetNoComponents()) return true; USetRef ref1(true), ref2(true); USet unit1(true), unit2(true); for(int i=0; i< this->GetNoComponents(); ++i) { this->Get(i, ref1); rhs.Get(i, ref2); ref1.GetUnit(this->data, unit1); ref2.GetUnit(rhs.data, unit2); if(unit1.Compare(&unit2) != 0) return true; } return false; } void MSet::CloseMSet( const ListExpr typeInfo, Word& w ) { delete static_cast(w.addr); w.addr = 0; } Word MSet::CloneMSet( const ListExpr typeInfo, const Word& w ) { return SetWord( static_cast(w.addr)->Clone()); } void* MSet::CastMSet(void* addr) { return new (addr) MSet; } int MSet::SizeOfMSet() { return sizeof(MSet); } void MSet::LiftedUnion(MSet& arg, MSet& res) { bool debugme=false; res.Clear(); if( !this->IsDefined() || !arg.IsDefined()){ res.SetDefined( false ); return; } res.SetDefined( true ); USet un(true); //part of the Result RefinementPartition rp( *this, arg); if(debugme) cout<<"Refinement finished, rp.size: "< iv; int u1Pos, u2Pos; USetRef u1, u2; USet op1(true), op2(true), resunit(true); for(unsigned int i = 0; i < rp.Size(); i++) { rp.Get(i, iv, u1Pos, u2Pos); if (u1Pos == -1 || u2Pos == -1 ) continue; else { if(debugme) cout<<"Both operands existant in interval iv #"<Get(u1Pos, u1); arg.Get(u2Pos, u2); if(!(u1.IsDefined() && u2.IsDefined())) continue; u1.GetUnit(this->data, op1); u2.GetUnit(arg.data, op2); op1.constValue.Union(op2.constValue, resunit.constValue); resunit.timeInterval= iv; res.MergeAdd(resunit); } } res.EndBulkLoad(false); } void MSet::LiftedUnion2(MSet& arg, MSet& res) { bool debugme=false; res.Clear(); if( this->IsDefined() && !arg.IsDefined()) { res.CopyFrom(this); return; } else if ( !this->IsDefined() && arg.IsDefined()) { res.CopyFrom(&arg); return; } else if ( !this->IsDefined() && !arg.IsDefined()) { res.SetDefined(false); return; } res.SetDefined( true ); USet un(true); //part of the Result RefinementPartition rp( *this, arg); if(debugme) cout<<"Refinement finished, rp.size: "<GetNoComponents(); int count2= arg.GetNoComponents(); cerr<<"\nmset 1 has #units:"<< count1<< "mset 2 has #units:"<< count2; } res.Resize(rp.Size()); res.StartBulkLoad(); Interval iv; int u1Pos, u2Pos; USetRef u1, u2; USet op1(true), op2(true), resunit(true); for(unsigned int i = 0; i < rp.Size(); i++) { rp.Get(i, iv, u1Pos, u2Pos); if (u1Pos == -1 && u2Pos == -1 ) continue; else if (u1Pos != -1 && u2Pos == -1 ) { if(debugme) cout<<"Only operand 1 existant in interval iv #"<Get(u1Pos, u1); if(!u1.IsDefined()) continue; u1.GetUnit(this->data, op1); resunit.constValue.CopyFrom(&op1.constValue) ; resunit.timeInterval= iv; res.MergeAdd(resunit); } else if (u1Pos == -1 && u2Pos != -1 ) { if(debugme) cout<<"Only operand 2 existant in interval iv #"<Get(u1Pos, u1); arg.Get(u2Pos, u2); continue; u1.GetUnit(this->data, op1); u2.GetUnit(arg.data, op2); op1.constValue.Union(op2.constValue, resunit.constValue); resunit.timeInterval= iv; res.MergeAdd(resunit); } } res.EndBulkLoad(false); } void MSet::LiftedUnion(MSet& arg) { bool debugme=false; MSet res(0); if( !this->IsDefined() || !arg.IsDefined()){ res.SetDefined( false ); return; } res.SetDefined( true ); USet un(true); //part of the Result RefinementPartition rp( *this, arg); if(debugme) cout<<"Refinement finished, rp.size: "< iv; int u1Pos, u2Pos; USetRef u1, u2; USet op1(true), op2(true), resunit(true); for(unsigned int i = 0; i < rp.Size(); i++) { rp.Get(i, iv, u1Pos, u2Pos); if (u1Pos == -1 || u2Pos == -1 ) continue; else { if(debugme) cout<<"Both operands existant in interval iv #"<Get(u1Pos, u1); arg.Get(u2Pos, u2); if(!(u1.IsDefined() && u2.IsDefined())) continue; u1.GetUnit(this->data, op1); u2.GetUnit(arg.data, op2); op1.constValue.Union(op2.constValue, resunit.constValue); resunit.timeInterval= iv; res.MergeAdd(resunit); } } res.EndBulkLoad(false); res.Destroy(); this->Clear(); this->CopyFrom(&res); } void MSet::LiftedMinus(MSet& arg, MSet& res) { bool debugme=false; if( !this->IsDefined() || !arg.IsDefined()){ res.SetDefined( false ); return; } res.SetDefined( true ); USet un(true); //part of the Result RefinementPartition rp( *this, arg); if(debugme) cout<<"Refinement finished, rp.size: "< iv; int u1Pos, u2Pos; USetRef u1, u2; USet op1(true), op2(true), resunit(true); for(unsigned int i = 0; i < rp.Size(); i++) { rp.Get(i, iv, u1Pos, u2Pos); if (u1Pos == -1 || u2Pos == -1 ) continue; else { if(debugme) cout<<"Both operands existant in interval iv #"<Get(u1Pos, u1); arg.Get(u2Pos, u2); if(!(u1.IsDefined() && u2.IsDefined())) continue; u1.GetUnit(this->data, op1); u2.GetUnit(arg.data, op2); op1.constValue.Minus(op2.constValue, resunit.constValue); resunit.timeInterval= iv; res.MergeAdd(resunit); } } res.EndBulkLoad(false); res.Destroy(); this->Clear(); this->CopyFrom(&res); } void MSet::LiftedUnion2(MSet& arg) { bool debugme=false; MSet res(0); if( this->IsDefined() && !arg.IsDefined()) { res.CopyFrom(this); return; } else if ( !this->IsDefined() && arg.IsDefined()) { res.CopyFrom(&arg); return; } else if ( !this->IsDefined() && !arg.IsDefined()) { res.SetDefined(false); return; } res.SetDefined( true ); USet un(true); //part of the Result RefinementPartition rp( *this, arg); if(debugme) cout<<"Refinement finished, rp.size: "< iv; int u1Pos, u2Pos; USetRef u1, u2; USet op1(true), op2(true), resunit(true); for(unsigned int i = 0; i < rp.Size(); i++) { rp.Get(i, iv, u1Pos, u2Pos); if (u1Pos == -1 && u2Pos == -1 ) continue; else if (u1Pos != -1 && u2Pos == -1 ) { if(debugme) cout<<"Only operand 1 existant in interval iv #"<Get(u1Pos, u1); if(!u1.IsDefined()) continue; u1.GetUnit(this->data, op1); resunit.constValue.CopyFrom(&op1.constValue) ; resunit.timeInterval= iv; res.MergeAdd(resunit); } else if (u1Pos == -1 && u2Pos != -1 ) { if(debugme) cout<<"Only operand 2 existant in interval iv #"<Get(u2Pos, u2); if(!u2.IsDefined()) continue; u2.GetUnit(arg.data, op2); resunit.constValue.CopyFrom(&op2.constValue) ; resunit.timeInterval= iv; res.MergeAdd(resunit); } else { if(debugme) cout<<"Both operands existant in interval iv #"<Get(u1Pos, u1); arg.Get(u2Pos, u2); if(!(u1.IsDefined() && u2.IsDefined())) continue; u1.GetUnit(this->data, op1); u2.GetUnit(arg.data, op2); op1.constValue.Union(op2.constValue, resunit.constValue); resunit.timeInterval= iv; res.MergeAdd(resunit); } } res.EndBulkLoad(false); this->Clear(); this->CopyFrom(&res); res.Destroy(); } void MSet::LiftedMinus2(MSet& arg, MSet& res) { bool debugme=false; if( this->IsDefined() && !arg.IsDefined()) { res.CopyFrom(this); return; } else if ( !this->IsDefined()) { res.SetDefined(false); return; } res.SetDefined( true ); USet un(true); //part of the Result RefinementPartition rp( *this, arg); if(debugme) cout<<"Refinement finished, rp.size: "< iv; int u1Pos, u2Pos; USetRef u1, u2; USet op1(true), op2(true), resunit(true); for(unsigned int i = 0; i < rp.Size(); i++) { rp.Get(i, iv, u1Pos, u2Pos); if (u1Pos == -1 && u2Pos == -1 ) continue; else if (u1Pos != -1 && u2Pos == -1 ) { if(debugme) cout<<"Only operand 1 existant in interval iv #"<Get(u1Pos, u1); if(!u1.IsDefined()) continue; u1.GetUnit(this->data, op1); resunit.constValue.CopyFrom(&op1.constValue) ; resunit.timeInterval= iv; res.MergeAdd(resunit); } else if (u1Pos == -1 && u2Pos != -1 ) { if(debugme) cout<<"Only operand 2 existant in interval iv #"<Get(u1Pos, u1); arg.Get(u2Pos, u2); if(!(u1.IsDefined() && u2.IsDefined())) continue; u1.GetUnit(this->data, op1); u2.GetUnit(arg.data, op2); op1.constValue.Minus(op2.constValue, resunit.constValue); resunit.timeInterval= iv; res.MergeAdd(resunit); } } res.EndBulkLoad(false); this->Clear(); this->CopyFrom(&res); res.Destroy(); } void MSet::LiftedIsSubset(MSet& arg2, MBool& res) { bool debugme=false; res.Clear(); if( !this->IsDefined() || !arg2.IsDefined()) { res.SetDefined(false); return; } res.SetDefined( true ); USet un(true); //part of the Result RefinementPartition rp( *this, arg2); if(debugme) cout<<"Refinement finished, rp.size: "< iv; int u1Pos, u2Pos; USetRef u1, u2; USet op1(true), op2(true); UBool resunit(true); for(unsigned int i = 0; i < rp.Size(); i++) { rp.Get(i, iv, u1Pos, u2Pos); if (u1Pos == -1 || u2Pos == -1 ) continue; else { this->Get(u1Pos, u1); arg2.Get(u2Pos, u2); if(!(u1.IsDefined() && u2.IsDefined())) continue; u1.GetUnit(this->data, op1); u2.GetUnit(arg2.data, op2); bool _res= op1.constValue.IsSubset(op2.constValue); resunit.constValue.Set(true, _res); resunit.timeInterval= iv; res.MergeAdd(resunit); } } res.EndBulkLoad(false); if(res.GetNoComponents() == 0) res.SetDefined(false); } void MSet::Initial( ISet& result ) const { if( !IsDefined() ){ result.SetDefined( false ); return; } assert( IsOrdered() ); if( IsEmpty() ){ result.SetDefined( false ); } else { USetRef usetRef; units.Get( 0, &usetRef ); USet unit(true); usetRef.GetUnit(this->data, unit); result.SetDefined( true ); unit.TemporalFunction( unit.timeInterval.start, result.value, true ); result.instant.CopyFrom( &unit.timeInterval.start ); } } void MSet::Final( ISet& result ) const { if( !IsDefined() ){ result.SetDefined( false ); return; } assert( IsOrdered() ); if( IsEmpty() ){ result.SetDefined( false ); } else { USetRef usetRef; units.Get( this->GetNoComponents() - 1, &usetRef ); USet unit(true); usetRef.GetUnit(this->data, unit); result.SetDefined( true ); unit.TemporalFunction( unit.timeInterval.start, result.value, true ); result.instant.CopyFrom( &unit.timeInterval.start ); } } void MSet::LiftedCount(MInt& res) { res.SetDefined(this->IsDefined()); if(!this->IsDefined()) return; res.Clear(); USetRef unitS; UInt unitI(true); CcInt count(0); for(int i=0; i< this->GetNoComponents(); ++i) { this->Get(i, unitS); unitI.timeInterval = unitS.timeInterval; count.Set(unitS.end - unitS.start); unitI.constValue= count; res.MergeAdd(unitI); } } void MSet::MBool2MSet(MBool& mb, int elem) { if(!mb.IsDefined()) { this->SetDefined(false); return; } this->SetDefined(true); this->Clear(); IntSet set(true); set.Insert(elem); UBool ubool(true); CcBool tmp; USet uset(true); uset.constValue.CopyFrom(&set); for(int i= 0; iAdd(uset); } } } void MSet::MergeAdd( const USet& unit ) { bool debugme= false; assert( IsDefined() ); USetRef lastunitref; USet lastunit(true); int size = units.Size(); if ( !unit.IsDefined() || !unit.IsValid() ) { cout << __FILE__ << "," << __LINE__ << ":" << __PRETTY_FUNCTION__ << " MergeAdd(Unit): Unit is undefined or invalid:"; unit.Print(cout); cout << endl; assert( false ); } if (size > 0) { units.Get( size - 1, lastunitref ); lastunitref.GetUnit(this->data, lastunit); if(debugme) { unit.Print(cerr); lastunit.Print(cerr); } if (lastunit.EqualValue(unit) && (lastunitref.timeInterval.end == unit.timeInterval.start) && (lastunitref.timeInterval.rc || unit.timeInterval.lc)) { lastunitref.timeInterval.end = unit.timeInterval.end; lastunitref.timeInterval.rc = unit.timeInterval.rc; if ( !lastunitref.IsValid() ) { cout << __FILE__ << "," << __LINE__ << ":" << __PRETTY_FUNCTION__ << "\nMapping::MergeAdd(): lastunit is invalid:"; lastunit.Print(cout); cout << endl; assert( false ); } units.Put(size - 1, lastunitref); } else this->Add( unit ); } else this->Add( unit ); } void MSet::Clear() { this->units.clean(); this->data.clean(); } void MSet::AtPeriods( const Periods& periods, MSet& result ) const { result.Clear(); if( !IsDefined() || !periods.IsDefined() ) { result.SetDefined( false ); return; } assert( IsOrdered() ); assert( periods.IsOrdered() ); if( IsEmpty() || periods.IsEmpty() ) return; result.StartBulkLoad(); USetRef unitRef; USet unit(true); Interval interval; int i = 0, j = 0; Get( i, unitRef ); periods.Get( j, interval ); while( 1 ) { if( unitRef.timeInterval.Before( interval ) ) { if( ++i == GetNoComponents() ) break; Get( i, unitRef ); } else if( interval.Before( unitRef.timeInterval ) ) { if( ++j == periods.GetNoComponents() ) break; periods.Get( j, interval ); } else { USet r(true); unitRef.GetUnit(this->data, unit); unit.AtInterval( interval, r ); result.Add( r ); if( interval.end == unit.timeInterval.end ) { if( interval.rc == unit.timeInterval.rc ) { if( ++i == GetNoComponents() ) break; Get( i, unitRef ); if( ++j == periods.GetNoComponents() ) break; periods.Get( j, interval ); } else if( interval.rc == true ) { if( ++i == GetNoComponents() ) break; Get( i, unitRef ); } else { assert( unit.timeInterval.rc == true ); if( ++j == periods.GetNoComponents() ) break; periods.Get( j, interval ); } } else if( interval.end > unit.timeInterval.end ) { if( ++i == GetNoComponents() ) break; Get( i, unitRef ); } else { assert( interval.end < unit.timeInterval.end ); if( ++j == periods.GetNoComponents() ) break; periods.Get( j, interval ); } } } result.EndBulkLoad( false ); // VTA - The merge of the result is not implemented yet. } USet::USet() {} USet::USet(bool is_defined): StandardTemporalUnit(is_defined),constValue(false) { } USet::USet( const Interval& _interval, const IntSet& a ): StandardTemporalUnit( _interval ),constValue(a) { this->del.isDefined = true; } // the following constructor is for implementation compatibility with // UnitTypes for continious value range types (like UReal, UPoint) USet::USet( const Interval& _interval, const IntSet& a, const IntSet& b ): StandardTemporalUnit( _interval ), constValue(a) { assert(a == b); this->del.isDefined = true; } USet::USet( const USet& u ): StandardTemporalUnit( u.timeInterval ), constValue( u.constValue ) { this->del.isDefined = u.del.isDefined; } USet& USet::operator=( const USet& i ) { this->del.isDefined = i.del.isDefined; if( !i.IsDefined() ){ return *this; } *((TemporalUnit*)this) = *((TemporalUnit*)&i); constValue.CopyFrom( &i.constValue ); return *this; } bool USet::operator==( const USet& i ) const { if( !this->IsDefined() && !i.IsDefined() ){ return true; } return (this->IsDefined()) && (i.IsDefined()) && *((TemporalUnit*)this) == *((TemporalUnit*)&i) && constValue.Compare( &i.constValue ) == 0; } /* Returns ~true~ if this temporal unit is equal to the temporal unit ~i~ and ~false~ if they are different. */ bool USet::operator!=( const USet& i ) const { return !( *this == i ); } /* Returns ~true~ if this temporal unit is different to the temporal unit ~i~ and ~false~ if they are equal. */ /* 3.6.2 The Temporal Functions ~TemporalFunction~ returns an undefined result if the ConstUnit or the Instant is undefined, or the Instant is not within the unit's timeInterval. */ void USet::TemporalFunction( const Instant& t, IntSet& result, bool ignoreLimits = false ) const { if ( !this->IsDefined() || !t.IsDefined() || (!this->timeInterval.Contains( t ) && !ignoreLimits)) { result.SetDefined( false ); } else { result.CopyFrom( &constValue ); result.SetDefined( true ); } } bool USet::Passes( const IntSet& val ) const { if( this->IsDefined() && (constValue.Compare( &val ) == 0) ) return true; return false; } bool USet::At( const IntSet& val, TemporalUnit& result ) const { if( this->IsDefined() && (constValue.Compare( &val ) == 0) ) { ((USet*)&result)->CopyFrom( this ); return true; } ((USet*)&result)->SetDefined( false ); return false; } void USet::AtInterval( const Interval& i, TemporalUnit& result ) const { if( !this->IsDefined() || !this->timeInterval.Intersects( i ) ){ ((USet*)&result)->SetDefined( false ); } else { TemporalUnit::AtInterval( i, result ); ((USet*)&result)->constValue.CopyFrom( &constValue ); } } bool USet::EqualValue( const USet& i ) const { return this->IsDefined() && (constValue.Compare( &i.constValue ) == 0); } /* Returns ~true~ if the value of this temporal unit is defined and equal to the value of the temporal unit ~i~ and ~false~ if they are different. */ bool USet::Merge( const USet& i ) { if(!this->IsDefined() && !i.IsDefined()) { // mergeable, but nothing to do return true; } else if(!this->IsDefined() || !i.IsDefined()) { // not mergable return false; } else if( !this->timeInterval.Adjacent(i.timeInterval) && !this->timeInterval.Intersects(i.timeInterval) ){ return false; // have a gap in between --> not mergeable } else if(!this->EqualValue(i)) { // temporal functions are NOT equal return false; } // merge the units (i.e. their timeIntervals) USet res(false); if(StartsBefore(i)){ res.timeInterval.start = this->timeInterval.start; res.timeInterval.lc = this->timeInterval.lc; } else { res.timeInterval.start = i.timeInterval.start; res.timeInterval.lc = i.timeInterval.lc; } if(EndsAfter(i)){ res.timeInterval.end = this->timeInterval.end; res.timeInterval.rc = this->timeInterval.rc; } else { res.timeInterval.end = i.timeInterval.end; res.timeInterval.rc = i.timeInterval.rc; } res.constValue = this->constValue; if(res.IsDefined() && res.IsValid()){ // invalid result -- do nothing! *this = res; return true; } else { return false; } } /* Merges unit ~i~ into this unit if possible and return ~true~. Otherwise do not modify this unit and return ~false~. */ /* 3.6.3 Functions to be part of relations */ size_t USet::Sizeof() const { return sizeof( *this ); } int USet::Compare( const Attribute* arg ) const { USet* rhs= (USet*)arg; if (this->IsDefined() && !rhs->IsDefined()) return 0; if (!this->IsDefined()) return -1; if (!rhs->IsDefined()) return 1; int cmp = this->timeInterval.CompareTo(rhs->timeInterval); if(cmp != 0){ return cmp; } cmp= constValue.Compare(&(rhs->constValue)); return cmp; } int USet::CompareAlmost( const Attribute* arg ) const { USet* rhs= (USet*)arg; if (this->IsDefined() && !rhs->IsDefined()) return 0; if (!this->IsDefined()) return -1; if (!rhs->IsDefined()) return 1; int cmp = this->timeInterval.CompareTo(rhs->timeInterval); if(cmp != 0){ return cmp; } cmp= constValue.CompareAlmost(&(rhs->constValue)); return cmp; } bool USet::Adjacent( const Attribute* arg ) const { return false; } int USet::NumOfFLOBs()const { return 1; } Flob* USet::GetFLOB(const int i) { assert(i==0); return &this->constValue.points; } ostream& USet::Print( ostream &os ) const { if( this->IsDefined() ) { os << "ConstUnit: ( "; TemporalUnit::timeInterval.Print(os); os << ", "; constValue.Print(os); os << " ) " << endl; return os; } else return os << "ConstUnit: (undef) "; } size_t USet::HashValue() const { if(!this->IsDefined()){ return 0; } return static_cast( this->timeInterval.start.HashValue() ^ this->timeInterval.end.HashValue() ) ; } USet* USet::Clone() const { return new USet(*this); } void USet::CopyFrom( const Attribute* right ) { const USet* i = (const USet*)right; this->SetDefined(i->IsDefined()); this->timeInterval.CopyFrom( i->timeInterval ); constValue.CopyFrom( &(i->constValue) ); } ListExpr USet::USetProperty() { 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("-> uset"), nl->StringAtom("(uset) "), nl->StringAtom("(timeInterval intset) "), nl->StringAtom("((i1 i2 FALSE FALSE) (4 7 1 2))")))); } /* 4.7.3 Kind Checking Function */ bool USet::CheckUSet( ListExpr type, ListExpr& errorInfo ) { return (nl->IsEqual( type, "uset" )); } /* 5.3 Type Constructor ~constunit~ 5.3.1 ~Out~-function */ ListExpr USet::OutUSet( ListExpr typeInfo, Word value ) { //1.get the address of the object and have a class object USet* constunit = (USet*)(value.addr); //2.test for undefined value if ( !constunit->IsDefined() ) return (nl->SymbolAtom("undef")); //3.get the time interval NL ListExpr intervalList = nl->FourElemList( OutDateTime( nl->TheEmptyList(), SetWord(&constunit->timeInterval.start) ), OutDateTime( nl->TheEmptyList(), SetWord(&constunit->timeInterval.end) ), nl->BoolAtom( constunit->timeInterval.lc ), nl->BoolAtom( constunit->timeInterval.rc)); //4. return the final result return nl->TwoElemList( intervalList, IntSet::Out(nl->TheEmptyList(), SetWord( &constunit->constValue ) ) ); } /* 5.3.2 ~In~-function */ Word USet::InUSet( const ListExpr typeInfo, const ListExpr instance, const int errorPos, ListExpr& errorInfo, bool& correct ) { string errmsg; if( nl->ListLength( instance ) == 2 ) { //1. deal with the time interval ListExpr first = nl->First( instance ); if( nl->ListLength( first ) == 4 && nl->IsAtom( nl->Third( first ) ) && nl->AtomType( nl->Third( first ) ) == BoolType && nl->IsAtom( nl->Fourth( first ) ) && nl->AtomType( nl->Fourth( first ) ) == BoolType ) { Instant *start = (Instant *)InInstant( nl->TheEmptyList(), nl->First( first ), errorPos, errorInfo, correct ).addr; if( !correct ) { errmsg = "InUSet(): Error in first instant."; errorInfo = nl->Append(errorInfo, nl->StringAtom(errmsg)); delete start; return SetWord( Address(0) ); } Instant *end = (Instant *)InInstant( nl->TheEmptyList(), nl->Second( first ), errorPos, errorInfo, correct ).addr; if( !correct ) { errmsg = "InUSet(): Error in second instant."; errorInfo = nl->Append(errorInfo, nl->StringAtom(errmsg)); delete start; delete end; return SetWord( Address(0) ); } // get closedness parameters bool lc = nl->BoolValue( nl->Third( first ) ); bool rc = nl->BoolValue( nl->Fourth( first ) ); Interval tinterval( *start, *end, lc, rc ); delete start; delete end; // check, wether interval is well defined correct = tinterval.IsValid(); if ( !correct ) { errmsg = "InUSet: Non valid time interval."; errorInfo = nl->Append(errorInfo, nl->StringAtom(errmsg)); return SetWord( Address(0) ); } //2. deal with the alpha value IntSet *value = (IntSet *)IntSet::In( nl->TheEmptyList(), nl->Second( instance ), errorPos, errorInfo, correct ).addr; //3. create the class object if( correct ) { USet *constunit = new USet( tinterval, *value ); if( constunit->IsValid() ) { delete value; return SetWord( constunit ); } delete constunit; } delete value; } } else if ( nl->IsAtom( instance ) && nl->AtomType( instance ) == SymbolType && nl->SymbolValue( instance ) == "undef" ) { USet *constunit = new USet(false); constunit->timeInterval= Interval(DateTime(instanttype), DateTime(instanttype),true,true); correct = true; return (SetWord( constunit )); } errmsg = "USet(): Error in representation."; errorInfo = nl->Append(errorInfo, nl->StringAtom(errmsg)); correct = false; return SetWord( Address(0) ); } /* 5.3.3 ~Create~-function */ Word USet::CreateUSet( const ListExpr typeInfo ) { return (SetWord( new USet(false) )); } /* 5.3.4 ~Delete~-function */ void USet::DeleteUSet( const ListExpr typeInfo, Word& w ) { static_cast(w.addr)->DeleteIfAllowed(); w.addr= 0; } /* 5.3.5 ~Close~-function */ void USet::CloseUSet( const ListExpr typeInfo, Word& w ) { static_cast(w.addr)->DeleteIfAllowed(); w.addr= 0; } /* 5.3.6 ~Clone~-function */ Word USet::CloneUSet( const ListExpr typeInfo, const Word& w ) { USet *constunit = (USet *)w.addr; return SetWord( new USet( *constunit ) ); } /* 5.3.7 ~Sizeof~-function */ int USet::SizeOfUSet() { return sizeof(USet); } /* 5.3.8 ~Cast~-function */ void* USet::CastUSet(void* addr) { return new (addr) USet; } ISet::ISet() {} ISet::ISet(int i):Intime(i){} ISet::ISet( const Instant& _instant, const IntSet& alpha ): Intime(_instant, alpha){} ISet::ISet( const ISet& intime ): Intime(0) { this->CopyFrom(&intime); } ISet::~ISet(){} int ISet::NumOfFLOBs()const { return 1; } Flob* ISet::GetFLOB(const int i) { assert(i==0); return &this->value.points; } int ISet::Compare( const Attribute* arg ) const { ISet* rhs= (ISet*)arg; int comp= this->instant.Compare(&(rhs->instant)); if(comp != 0) return comp; comp= this->value.Compare(&(rhs->value)); return(comp); } int ISet::CompareAlmost( const Attribute *arg ) const { ISet* rhs= (ISet*)arg; int comp= this->instant.CompareAlmost(&(rhs->instant)); if(comp != 0) return comp; comp= this->value.CompareAlmost(&(rhs->value)); return(comp); } const string ISet::BasicType() { return "iset"; } ListExpr ISet::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("-> iset"), nl->StringAtom("(iset) "), nl->StringAtom("(instant intset) "), nl->StringAtom("((instant 0.5) (intset (1 2 5)))")))); } Word ISet::Create( const ListExpr typeInfo ) { return (SetWord( new ISet(0) )); } /* 5.3.4 ~Delete~-function */ void ISet::Delete( const ListExpr typeInfo, Word& w ) { static_cast(w.addr)->DeleteIfAllowed(); w.addr= 0; } /* 5.3.5 ~Close~-function */ void ISet::Close( const ListExpr typeInfo, Word& w ) { static_cast(w.addr)->DeleteIfAllowed(); w.addr= 0; } /* 5.3.6 ~Clone~-function */ Word ISet::Clone( const ListExpr typeInfo, const Word& w ) { ISet *constunit = (ISet *)w.addr; return SetWord( new ISet( *constunit ) ); } /* 5.3.7 ~Sizeof~-function */ int ISet::SizeOf() { return sizeof(ISet); } /* 5.3.8 ~Cast~-function */ void* ISet::Cast(void* addr) { return new (addr) ISet; } ISet* ISet::Clone() const { return(new ISet(*this)); } bool ISet::KindCheck(const ListExpr type, ListExpr& errorInfo ) { return (nl->IsEqual( type, ISet::BasicType() )); } CompressedUSetRef::CompressedUSetRef(){} CompressedUSetRef::CompressedUSetRef(bool def):isdefined(def){} CompressedMSet::CompressedMSet(){} CompressedMSet::CompressedMSet(int cnt): validLastUnitValue(false), removed(0), added(0), units(cnt){} CompressedMSet::CompressedMSet(CompressedMSet& arg): validLastUnitValue(false), removed(0), added(0), units(0) { this->CopyFrom(arg); } int CompressedMSet::GetNoComponents() { return this->units.Size(); } void CompressedMSet::CopyFrom(CompressedMSet& arg) { Clear(); this->added.copyFrom(arg.added); this->removed.copyFrom(arg.removed); this->units.copyFrom(arg.units); } void CompressedMSet::Clear() { this->units.clean(); this->added.clean(); this->removed.clean(); lastUnitValue.clear(); validLastUnitValue= false; } void CompressedMSet::GetSet(int index, set& res) { CompressedUSetRef unitRef; int elem, cnt; res.clear(); for(int i= 0; i<= index; ++i) { this->units.Get( i, unitRef ); for(int j=unitRef.addedstart; j<= unitRef.addedend; ++j) { this->added.Get(j, elem); res.insert(elem); } for(int j=unitRef.removedstart; j<= unitRef.removedend; ++j) { this->removed.Get(j, elem); res.erase(elem); } cnt= res.size(); assertIf(cnt == unitRef.count); } } set* CompressedMSet::GetFinalSet() { if(this->units.Size() == 0) { validLastUnitValue= true; lastUnitValue.clear(); } if(validLastUnitValue) return &lastUnitValue; else { int last= this->units.Size() - 1; this->GetSet(last, lastUnitValue); validLastUnitValue= true; return &lastUnitValue; } return 0; } void CompressedMSet::WriteToCompressedInMemMSet(CompressedInMemMSet& res) { res.Clear(); CompressedInMemUSet uset; CompressedUSetRef unitRef; int elem; set toAdd, toRemove; for(int i= 0; i< this->units.Size(); ++i) { this->units.Get( i, unitRef ); toAdd.clear(); toRemove.clear(); for(int j=unitRef.addedstart; j<= unitRef.addedend; ++j) { this->added.Get(j, elem); toAdd.insert(elem); } for(int j=unitRef.removedstart; j<= unitRef.removedend; ++j) { this->removed.Get(j, elem); toRemove.insert(elem); } res.AddUnit(unitRef.starttime, unitRef.endtime, unitRef.lc, unitRef.rc, toAdd, toRemove, unitRef.count); } } void CompressedMSet::ReadFromCompressedInMemMSet(CompressedInMemMSet& arg) { this->Clear(); for(list::iterator argUnitIt= arg.units.begin(); argUnitIt!= arg.units.end(); ++argUnitIt) this->AddUnit((*argUnitIt).added, (*argUnitIt).removed, (*argUnitIt).starttime, (*argUnitIt).endtime, (*argUnitIt).lc, (*argUnitIt).rc); } bool CompressedMSet::ReadFromCompressedInMemMSet(CompressedInMemMSet& arg, list::iterator b, list::iterator e) { this->Clear(); if(b== e) return false; set initialSet; arg.GetSet(b, initialSet); this->AddUnit(initialSet, (*b).starttime, (*b).endtime, (*b).lc, (*b).rc); ++b; list::iterator argUnitIt; for(argUnitIt= b; argUnitIt!= e && argUnitIt != arg.units.end(); ++argUnitIt) this->AddUnit((*argUnitIt).added, (*argUnitIt).removed, (*argUnitIt).starttime, (*argUnitIt).endtime, (*argUnitIt).lc, (*argUnitIt).rc); if(argUnitIt == arg.units.end() && e != arg.units.end()) return false; return true; } ostream& CompressedMSet::Print( ostream &os ) { CompressedInMemMSet _mset; this->WriteToCompressedInMemMSet(_mset); return _mset.Print(os); } void CompressedMSet::AddUnit( set& constValue, int64_t starttime, int64_t endtime, bool lc, bool rc) { bool debugme= false; set* finalSet= GetFinalSet(); CompressedUSetRef unit; if(units.Size()== 0) { this->Clear(); for(set::iterator it= constValue.begin(); it!=constValue.end(); ++it) this->added.Append(*it); unit.removedstart=0; unit.removedend=-1; unit.addedstart=0; unit.addedend=constValue.size() - 1; unit.starttime= starttime; unit.endtime= endtime; unit.lc= lc; unit.rc= rc; unit.count= constValue.size(); this->units.Append(unit); this->validLastUnitValue= true; lastUnitValue= constValue; return; } set _added, _removed; set_difference(constValue.begin(), constValue.end(), finalSet->begin(), finalSet->end(), inserter(_added, _added.begin())); set_difference(finalSet->begin(), finalSet->end(), constValue.begin(), constValue.end(), inserter(_removed, _removed.begin())); if(debugme) cerr<size()<<'\t'<< _added.size()<<'\t'<<_removed.size() << '\t' << finalSet->size() + _added.size() - _removed.size()<removed.Size(); unit.addedstart= this->added.Size() ; for(set::iterator it= _added.begin(); it!=_added.end(); ++it) this->added.Append(*it); for(set::iterator it= _removed.begin(); it!=_removed.end(); ++it) this->removed.Append(*it); unit.removedend= this->removed.Size() -1; unit.addedend= this->added.Size() -1; unit.starttime= starttime; unit.endtime= endtime; unit.lc= lc; unit.rc= rc; unit.count= constValue.size(); this->units.Append(unit); if(validLastUnitValue) { //To be changed to lastUnitValue = constValue if(debugme) { lastUnitValue.insert(_added.begin(), _added.end()); for(set::iterator elem= _removed.begin(); elem != _removed.end(); ++elem) lastUnitValue.erase(*elem); assert(lastUnitValue.size() == constValue.size()); } else lastUnitValue = constValue; } } void CompressedMSet::AddUnit( set& added, set& removed, int64_t starttime, int64_t endtime, bool lc, bool rc) { bool debugme= false; CompressedUSetRef unit; if(units.Size()== 0) { assertIf(removed.empty()); this->Clear(); for(set::iterator it= added.begin(); it!=added.end(); ++it) this->added.Append(*it); unit.removedstart=0; unit.removedend=-1; unit.addedstart=0; unit.addedend=added.size() - 1; unit.starttime= starttime; unit.endtime= endtime; unit.lc= lc; unit.rc= rc; unit.count= added.size(); this->units.Append(unit); this->validLastUnitValue= true; lastUnitValue.insert(added.begin(), added.end()); return; } unit.removedstart= this->removed.Size(); unit.addedstart= this->added.Size() ; for(set::iterator it= added.begin(); it!=added.end(); ++it) this->added.Append(*it); for(set::iterator it= removed.begin(); it!=removed.end(); ++it) this->removed.Append(*it); unit.removedend= this->removed.Size() -1; unit.addedend= this->added.Size() -1; unit.starttime= starttime; unit.endtime= endtime; unit.lc= lc; unit.rc= rc; CompressedUSetRef lastUSet; this->units.Get(this->units.Size()-1, lastUSet); unit.count= lastUSet.count + added.size() - removed.size(); this->units.Append(unit); if(debugme) { set _set; this->GetSet(this->GetNoComponents()-2, _set); cerr<<"\nLastSet is: "; for(set::iterator it= _set.begin(); it!=_set.end(); ++it) cerr<<*it<<", "; cerr<<"\nAdding: "; for(set::iterator it= added.begin(); it!=added.end(); ++it) cerr<<*it<<", "; cerr<<"\nRemoving: "; for(set::iterator it= removed.begin(); it!=removed.end(); ++it) cerr<<*it<<", "; } if(validLastUnitValue) { lastUnitValue.insert(added.begin(), added.end()); for(set::iterator elem= removed.begin(); elem != removed.end(); ++elem) lastUnitValue.erase(*elem); } } bool CompressedMSet::MergeAdd(set& val, int64_t &starttime, int64_t &endtime, bool lc, bool rc) { bool merged= false; if(this->units.Size() != 0) { set* finalSet= GetFinalSet(); CompressedUSetRef lastUSet; this->units.Get(this->units.Size()-1, lastUSet); if( AlmostEqual(starttime, lastUSet.endtime) && (lc || lastUSet.rc)) { merged= true; bool equals= ((val.size() == finalSet->size()) && equal(val.begin(), val.end(), finalSet->begin())); if(equals) { lastUSet.endtime= endtime; lastUSet.rc= rc; this->units.Put(this->units.Size()-1, lastUSet); return merged; } } } AddUnit(val, starttime, endtime, lc, rc); return merged; } int64_t CompressedMSet::DurationLength() { if(this->units.Size() == 0) return 0; CompressedUSetRef firstUSet, lastUSet; this->units.Get(0, firstUSet); this->units.Get(this->units.Size()-1, lastUSet); return lastUSet.endtime - firstUSet.starttime; } bool CompressedMSet::Concat(CompressedMSet* arg) { bool debugme= false; if(arg->GetNoComponents() == 0) return true; CompressedUSetRef uset; if(debugme) { if(this->units.Size() > 0) { cerr<<"\nConcatenating:"; this->Print(cerr); arg->Print(cerr); } } set firstUnitElems; arg->GetSet(0, firstUnitElems); arg->units.Get(0, uset); assertIf(uset.removedend < uset.removedstart); this->AddUnit(firstUnitElems, uset.starttime, uset.endtime, uset.lc, uset.rc); if(debugme) { set* finalSet= this->GetFinalSet(); assertIf(finalSet->size() == (size_t)uset.count); } int removedShift= this->removed.Size(), addedShift= this->added.Size() - uset.count, argAddedReadIndex= uset.addedend + 1, argAddedElem; this->validLastUnitValue= false; bool ok= this->removed.Append(arg->removed); for(int i= argAddedReadIndex; iadded.Size() && ok; ++i) { arg->added.Get(i, argAddedElem); ok= this->added.Append(argAddedElem); } if(ok) { for(int i=1; iunits.Size(); ++i) { arg->units.Get(i, uset); uset.addedstart+= addedShift; uset.addedend+= addedShift; uset.removedstart+= removedShift; uset.removedend+= removedShift; this->units.Append(uset); } } if(debugme) { cerr<<"\nResult is:"; this->Print(cerr); } return ok; } CompressedMSet* CompressedMSet::GetSubMSet(int offset, int length) { bool debugme= false; if(offset < 0 || length < 0 || (offset + length) > this->GetNoComponents()) return 0; CompressedMSet* result= new CompressedMSet(0); CompressedUSetRef firstUSet(true), lastUSet(true), curUSet(true); set firstSet; int addedShift, removedShift; this->GetSet(offset,firstSet); this->units.Get(offset, firstUSet); result->AddUnit(firstSet, firstUSet.starttime, firstUSet.endtime, firstUSet.lc, firstUSet.rc); addedShift= firstUSet.addedend + 1 - firstSet.size(); removedShift= firstUSet.removedend + 1; for(int i = 1; i < length; ++i) { this->units.Get(i + offset, curUSet); curUSet.addedstart-= addedShift; curUSet.addedend-= addedShift; curUSet.removedstart-= removedShift; curUSet.removedend-= removedShift; result->units.Append(curUSet); } this->units.Get(offset + length - 1, lastUSet); int sourceOffset= firstUSet.addedend + 1, numberOfElems= lastUSet.addedend - firstUSet.addedend, destOffset= firstSet.size(); this->added.copyTo(result->added, sourceOffset, numberOfElems, destOffset); sourceOffset= firstUSet.removedend + 1; numberOfElems= lastUSet.removedend - firstUSet.removedend; destOffset= 0; this->removed.copyTo( result->removed, sourceOffset, numberOfElems, destOffset); if(debugme) { set* s1= result->GetFinalSet(); set s2; this->GetSet(offset + length -1, s2); assertIf(equal(s1->begin(), s1->end(), s2.begin())); } return result; } };