Files
secondo/Algebras/Temporal2/TemporalAlgebraOperators.cpp
2026-01-23 17:03:45 +08:00

418 lines
11 KiB
C++

/*
Operator definitions for example operators
copied from TemporalAlgebra.h/.cpp
and adapted to use free functions from TemporalAlgebraFunctions.h
*/
#include "TemporalAlgebraOperators.h"
#include "TemporalAlgebraFunctions.h"
#include "Operator.h"
#include "NestedList.h"
#include "QueryProcessor.h"
#include "StandardTypes.h"
#include "TypeMapUtils.h"
#include "ListUtils.h"
#include "MPoint2.h"
#include "Algebras/Temporal/TemporalAlgebra.h"
#include "DateTime.h"
namespace temporal2algebra {
using temporalalgebra::Periods;
using datetime::DateTime;
/*
16.1.7 Type mapping function ~MovingPeriodsTypeMapMoving~
It is for the operator ~atperiods~.
*/
ListExpr
MovingPeriodsTypeMapMoving( ListExpr args )
{
if ( nl->ListLength( args ) == 2 )
{
ListExpr arg1 = nl->First( args ),
arg2 = nl->Second( args );
if( nl->IsEqual( arg2, Periods::BasicType() ) )
{
if( nl->IsEqual( arg1, MPoint2::BasicType() ) )
return nl->SymbolAtom( MPoint2::BasicType() );
}
}
return nl->SymbolAtom( Symbol::TYPEERROR() );
}
/*
16.2.3 Selection function ~MovingSimpleSelect~
Is used for the ~deftime~, ~initial~, ~final~, ~inst~, ~val~, ~atinstant~,
~atperiods~, ~getposition~ operations.
*/
int
MovingSimpleSelect( ListExpr args )
{
ListExpr arg1 = nl->First( args );
if( nl->SymbolValue( arg1 ) == MPoint2::BasicType() )
return 0;
return -1; // This point should never be reached
}
int MPoint2AtPeriods( Word* args, Word& result, int message,
Word& local, Supplier s )
{
result = qp->ResultStorage( s );
MPoint2* mp = ((MPoint2*)args[0].addr);
MPoint2* pResult = (MPoint2*)result.addr;
Periods* per = (Periods*)args[1].addr;
AtPeriods(*mp, *per,*pResult);
return 0;
}
ValueMapping temporalatperiodsmap[] = { MPoint2AtPeriods };
const std::string TemporalSpecAtPeriods =
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
"( <text>(mT periods) -> mT</text--->"
"<text>_ atperiods _ </text--->"
"<text>Restrict the moving object to the given periods.</text--->"
"<text>mpoint1 atperiods periods1</text--->"
") )";
Operator* getAtperiodsOpPtr() {
return new Operator( "atperiods",
TemporalSpecAtPeriods,
1,
temporalatperiodsmap,
MovingSimpleSelect,
MovingPeriodsTypeMapMoving
);
}
/*
16.1.18 Type mapping function "Temporal2BBoxTypeMap"
For operator ~bbox~
*/
ListExpr Temporal2BBoxTypeMap( ListExpr args )
{
int noargs = nl->ListLength( args );
std::string errmsg =
"Expected (M [x geoid]) OR (T), where M in {upoint, mpoint, "
"ipoint}, T in {instant,periods}.";
if ( (noargs<1) || (noargs>2) ){
return listutils::typeError(errmsg);
}
if( (noargs==2) && !listutils::isSymbol(nl->Second(args),Geoid::BasicType())){
return listutils::typeError(errmsg);
}
ListExpr arg1 = nl->First( args );
if( listutils::isSymbol( arg1, MPoint2::BasicType() ) )
return (nl->SymbolAtom( Rectangle<3>::BasicType() ));
return listutils::typeError(errmsg);
}
/*
Selection function for the bbox operator
*/
int Temporal2BBoxSelect( ListExpr args )
{
ListExpr arg1 = nl->First( args );
if( nl->SymbolValue( arg1 ) == MPoint2::BasicType() )
return 0;
return -1; // This point should never be reached
}
/*
Since MPoint is not a subclass of ~SpatialAttribute~, it has no ~BoundingBox()~
function. One could make it inherit from ~SpatialAttribute~, but than one had to
restore all databases and adopt the Add, MergeAdd, +=, -=, etc.
*/
int MPoint2BBox(Word* args, Word& result, int message, Word& local,
Supplier s )
{
result = qp->ResultStorage( s );
Rectangle<3>* res = (Rectangle<3>*) result.addr;
const MPoint2* arg = static_cast<const MPoint2*>(args[0].addr);
const Geoid* geoid =
(qp->GetNoSons(s)==2)?static_cast<const Geoid*>(args[1].addr):0;
if( !arg->IsDefined() || (arg->GetNoComponents() < 1) )
{ // empty/undefined MPoint2 --> undef
res->SetDefined(false);
}
else { // return MBR
*res = BoundingBox(*arg, geoid);
}
return 0;
}
ValueMapping temporal2bboxmap[] = {
MPoint2BBox };
const std::string Temporal2SpecBBox =
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
"( <text>upoint [x geoid] -> rect3,\n"
"mpoint [x geoid] -> rect3,\n"
"ipoint [x geoid] -> rect3,\n"
"instant -> rect3,\n"
"periods -> rect3</text--->"
"<text>bbox ( Obj [, Geoid])</text--->"
"<text>Returns the 3d bounding box of the spatio-temporal2 object Obj, \n"
"resp. the universe restricted to the definition time of the instant/\n"
"period value. If Geoid is passed, the geographic MBR is computed.</text--->"
"<text>query bbox( upoint1 )</text--->"
") )";
Operator* getBBoxOpPtr() {
return new Operator(
"bbox",
Temporal2SpecBBox,
1,
temporal2bboxmap,
Temporal2BBoxSelect,
Temporal2BBoxTypeMap
);
}
/*
16.1.8 Type mapping function ~MovingTypeMapSpatial~
It is for the operator ~trajectory~.
*/
ListExpr
MovingTypeMapSpatial( ListExpr args )
{
if ( nl->ListLength( args ) == 1 )
{
ListExpr arg1 = nl->First( args );
if( nl->IsEqual( arg1, MPoint2::BasicType() ) )
return nl->SymbolAtom( Line::BasicType() );
}
return nl->SymbolAtom( Symbol::TYPEERROR() );
}
/*
16.3.23 Value mapping functions of operator ~trajectory~
*/
int MPointTrajectory( Word* args, Word& result, int message,
Word& local, Supplier s )
{
result = qp->ResultStorage( s );
Line *line = ((Line*)result.addr);
MPoint2* mpoint = ((MPoint2*)args[0].addr);
Trajectory(*mpoint, *line );
return 0;
}
const std::string TemporalSpecTrajectory =
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
"( <text>mpoint -> line</text--->"
"<text> trajectory( _ )</text--->"
"<text>Get the trajectory of the corresponding moving point object.</text--->"
"<text>trajectory( mp1 )</text--->"
") )";
Operator* getTrajectoryOpPtr() {
return new Operator(
"trajectory",
TemporalSpecTrajectory,
MPointTrajectory,
Operator::SimpleSelect,
MovingTypeMapSpatial
);
}
/*
16.1.20 TranslateAppendS
This operator consumes a stream of tuples having an attribute
x of type mpoint. The attribute name must be given in the second
argument. As third argument, a duration is given which determines
a break between the two movements.
*/
ListExpr TranslateAppendSTM(ListExpr args){
int len = nl->ListLength(args);
if(len != 3 ){
ErrorReporter::ReportError("three arguments expected");
return nl->SymbolAtom(Symbol::TYPEERROR());
}
// check the third argument to be of type duration
if(!nl->IsEqual(nl->Third(args),Duration::BasicType())){
ErrorReporter::ReportError("the third argument has to be a duration");
return nl->SymbolAtom(Symbol::TYPEERROR());
}
// extract the attribute name
ListExpr attrlist = nl->Second(args);
if(nl->AtomType(attrlist)!=SymbolType){
ErrorReporter::ReportError("the second argument has to be a symbol");
return nl->SymbolAtom(Symbol::TYPEERROR());
}
std::string a1 = nl->SymbolValue(attrlist);
int a1index = -1;
// search for attrname in stream definition
ListExpr stype = nl->First(args);
if(nl->AtomType(stype)!=NoAtom){
ErrorReporter::ReportError("stream(tuple(...))"
" expected as the first argument");
return nl->SymbolAtom(Symbol::TYPEERROR());
}
if((nl->ListLength(stype)!=2) ||
(!nl->IsEqual(nl->First(stype),Symbol::STREAM() ))){
ErrorReporter::ReportError("stream(tuple(...))"
" expected as the first argument");
return nl->SymbolAtom(Symbol::TYPEERROR());
}
ListExpr ttype = nl->Second(stype);
if((nl->ListLength(ttype)!=2) ||
(!nl->IsEqual(nl->First(ttype),Tuple::BasicType() ))){
ErrorReporter::ReportError("stream(tuple(...))"
" expected as the first argument");
return nl->SymbolAtom(Symbol::TYPEERROR());
}
ListExpr attributes = nl->Second(ttype);
if(nl->AtomType(attributes)!=NoAtom){
ErrorReporter::ReportError("invalid tuple type");
return nl->SymbolAtom(Symbol::TYPEERROR());
}
int pos = 0;
while(!nl->IsEmpty(attributes)){
ListExpr attr = nl->First(attributes);
if( (nl->AtomType(attr)!=NoAtom) ||
(nl->ListLength(attr)!=2)){
ErrorReporter::ReportError("invalid tuple type");
return nl->SymbolAtom(Symbol::TYPEERROR());
}
ListExpr anl = nl->First(attr);
ListExpr atl = nl->Second(attr);
if( (nl->AtomType(anl)!=SymbolType) ||
(nl->AtomType(atl)!=SymbolType)){
ErrorReporter::ReportError("invalid tuple type");
return nl->SymbolAtom(Symbol::TYPEERROR());
}
std::string aname = nl->SymbolValue(anl);
if(aname==a1){
if(a1index>=0){
ErrorReporter::ReportError("attr name occurs twice");
return nl->SymbolAtom(Symbol::TYPEERROR());
}
if(!nl->IsEqual(atl,MPoint2::BasicType())){
ErrorReporter::ReportError("the attribute"
" has to be of type mpoint2");
return nl->SymbolAtom(Symbol::TYPEERROR());
}
a1index = pos;
}
pos++;
attributes = nl->Rest(attributes);
}
if(a1index<0){
ErrorReporter::ReportError("first attr name does"
" not occur in the typle");
return nl->SymbolAtom(Symbol::TYPEERROR());
}
// all is correct
ListExpr ind = nl->OneElemList(nl->IntAtom(a1index));
return nl->ThreeElemList(nl->SymbolAtom(Symbol::APPEND()),
ind,
nl->SymbolAtom(MPoint2::BasicType()));
}
/*
16.3.45 Value mapping function for ~translateAppendS~
*/
int TranslateAppendSVM(Word* args, Word& result,
int message, Word& local,
Supplier s){
result = qp->ResultStorage(s);
MPoint2* res = (MPoint2*) result.addr;
int index = ((CcInt*)args[3].addr)->GetIntval();
DateTime* duration = (DateTime*) args[2].addr;
res->Clear();
res->SetDefined(true);
Word current;
MPoint2* mpoint=NULL;
qp->Open(args[0].addr);
qp->Request(args[0].addr, current);
while (qp->Received(args[0].addr)) {
Tuple* tuple = (Tuple*)current.addr;
mpoint = (MPoint2*)(tuple->GetAttribute(index));
TranslateAppend(*mpoint,*duration, *res);
tuple->DeleteIfAllowed();
qp->Request(args[0].addr, current);
}
qp->Close(args[0].addr);
return 0;
}
const std::string TranslateAppendSSpec =
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
"( <text>stream(tuple((a1 t1)...(an tn))) x ai x duration"
" -> mpoint, where ti = mpoint</text--->"
"<text> _ translateappendS[ _ _ ]</text--->"
"<text>Builds a single moving point from all mpoints in the stream \n"
" translating the mpoints in such a way that a connected movement\n"
" is created. 'Jumps' within stream elements are not removed.</text--->"
"<text>query Trains feed translateappendS[Trip [const"
" duration value(0 10000)]]</text--->"
") )";
Operator* getTranslateappendSOpPtr(){
return new Operator(
"translateappendS",
TranslateAppendSSpec,
TranslateAppendSVM,
Operator::SimpleSelect,
TranslateAppendSTM
);
}
} /* namespace temporal2algebra */