11336 lines
324 KiB
C++
11336 lines
324 KiB
C++
/*
|
|
|
|
//paragraph [1] Title: [{\Large \bf \begin{center}] [\end{center}}]
|
|
//paragraph [10] Footnote: [{\footnote{] [}}]
|
|
//[ue] [\"u]
|
|
//[ae] [\"a]
|
|
|
|
//[TOC] [\tableofcontents]
|
|
|
|
[1] TemporalUnitAlgebra - Implementing Units-Operators
|
|
|
|
May 2006, initial version implemented by Thomas Fischer for diploma
|
|
thesis with Prof. Dr. G[ue]ting, Fachbereich Informatik,
|
|
Feruniversit[ae]t Hagen.
|
|
|
|
July 2006, Christian D[ue]ntgen: The so far implemented operators do not suffice
|
|
to model typical queries using the compact unit representation ~moving(T)~ with
|
|
relations of units. Instead, we also need variants of spatiotemporal operators
|
|
that process streams of units. Instead of implementing them directly, we will
|
|
fake them using the set wrapper-operators ~use~ on the native single-unit
|
|
operators.
|
|
|
|
The ~use~ operators passes single values to an operator one-by-one value and
|
|
collects all returned values/streams of values in a flat stream of values.
|
|
This does not work for some binary predicates, like equal, but one could
|
|
implement an ordered pairwise comparison here.
|
|
|
|
It may be useful, to have some operators consuming a stream of units and
|
|
returning an aggregated vale, as e.g. initial, final, present, never, always.
|
|
|
|
December 2006, Christian D[ue]ntgen: Moved class functions for unit types to
|
|
where they belong (ie. ~TemporalAlgebra~).
|
|
|
|
----
|
|
|
|
State Operator/Signatures
|
|
|
|
OK makemvalue (**) stream (tuple ([x1:t1,xi:uT,..,xn:tn])) --> mT
|
|
OK the_mvalue (**) stream uT --> mT
|
|
OK get_duration periods --> duration
|
|
OK point2d periods --> point
|
|
OK queryrect2d instant --> rect
|
|
OK circle point x real x int --> region
|
|
OK uint2ureal: uint --> ureal
|
|
|
|
the_unit: For T in {bool, int, string, region*}
|
|
*: Crashed for T=region
|
|
OK point point instant instant bool bool --> upoint
|
|
OK ipoint ipoint bool bool --> upoint
|
|
OK real real real bool instant instant bool bool --> ureal
|
|
OK iT duration bool bool --> uT
|
|
OK T instant instant bool bool --> uT
|
|
|
|
the_ivalue: For T in {bool, int, string, real, point, region}
|
|
OK (instant T) --> iT
|
|
|
|
OK isempty U --> bool (for U in kind UNIT)
|
|
OK trajectory upoint --> line
|
|
OK velocity mpoint --> mpoint
|
|
OK velocity upoint --> upoint
|
|
OK derivable mreal --> mbool
|
|
OK derivable ureal --> ubool
|
|
OK derivative mreal --> mreal
|
|
OK derivative ureal --> ureal
|
|
OK speed mpoint [ x geoid ] --> mreal
|
|
OK speed upoint [ x geoid ] --> ureal
|
|
|
|
passes: For T in {bool, int, string, point}:
|
|
OK + uT x T --> bool
|
|
OK + ureal x real --> bool
|
|
n/a + uregion x region --> bool
|
|
|
|
OK + deftime (**) uT --> periods
|
|
OK + atinstant (**) uT x instant --> iT
|
|
OK + atperiods (**) uT x periods --> (stream uT)
|
|
OK + Initial (**) uT --> iT
|
|
OK Initial (**) (stream uT) --> iT
|
|
OK + final (**) uT --> iT
|
|
OK final (**) (stream uT) --> iT
|
|
OK + present (**) uT x instant --> bool
|
|
OK + present (**) uT x periods --> bool
|
|
n/a present (stream uT) x instant --> bool (use use2/present)
|
|
n/a present (stream uT) x periods --> bool (use use2/present)
|
|
|
|
atmax: For T in {bool, int, real, string}:
|
|
OK + uT --> (stream uT)
|
|
|
|
atmin: For T in {bool, int, real, string}:
|
|
OK + uT --> (stream uT)
|
|
|
|
at: For T in {bool, int, string, point, region*}
|
|
OK + uT x T --> (stream uT) as intersection: uT x T
|
|
OK ureal x real --> (stream ureal) as intersection: ureal x real
|
|
OK + upoint x region --> (stream upoint) as intersection: upoint x region
|
|
|
|
distance: T in {int, point}
|
|
OK - uT x uT --> ureal
|
|
OK ? uT x T --> ureal
|
|
OK ? T x uT --> ureal
|
|
OK + ureal x ureal --> (stream ureal)
|
|
OK + ureal x real --> (stream ureal)
|
|
OK + real x ureal --> (stream ureal)
|
|
|
|
OK + abs: ureal --> (stream ureal)
|
|
OK + abs: uint --> uint
|
|
|
|
intersection: For T in {bool, int, string}:
|
|
OK + uT x uT --> (stream uT)
|
|
OK + uT x T --> (stream uT) same as at: uT x T
|
|
OK + T x uT --> (stream uT) same as at: uT x T
|
|
OK + ureal x real --> (stream ureal) same as at: ureal x real
|
|
OK + real x ureal --> (stream ureal) same as at: ureal x real
|
|
OK - upoint x point --> (stream upoint) same as at: upoint x point
|
|
OK - point x upoint --> (stream upoint) same as at: upoint x point
|
|
OK - upoint x upoint --> (stream upoint)
|
|
OK + upoint x line --> (stream upoint)
|
|
OK + line x upoint --> (stream upoint)
|
|
OK + ureal x ureal --> (stream ureal)
|
|
OK + upoint x uregion --> (stream upoint) same as at: upoint x uregion
|
|
OK - uregion x upoint --> (stream upoint)
|
|
OK - upoint x region --> (stream upoint) same as: at: upoint x region
|
|
OK - region x upoint --> (stream upoint)
|
|
n/a + upoint x points --> (stream upoint)
|
|
n/a + points x upoint --> (stream upoint)
|
|
Pre - uregion x region --> (stream uregion)
|
|
Pre - region x uregion --> (stream uregion)
|
|
|
|
OK + no_components: uT --> uint
|
|
|
|
OK + and, or: ubool x ubool --> ubool
|
|
OK + bool x ubool --> ubool
|
|
OK + ubool x bool --> ubool
|
|
|
|
==, ##, <<, >>, <<==, >>==:
|
|
For T in {bool, int, string, real, point, region}
|
|
Test+ uT x uT --> bool
|
|
|
|
=, #, <, >, <=, >=: T in {bool, int, string, real}
|
|
OK + uT x uT --> (stream ubool)
|
|
OK + T x uT --> (stream ubool)
|
|
OK + T x uT --> (stream ubool)
|
|
OK + upoint x upoint --> (stream ubool) for {=,#} only
|
|
OK + point x upoint --> (stream ubool) for {=,#} only
|
|
OK + upoint x point --> (stream ubool) for {=,#} only
|
|
pre + uregion x uregion --> (stream ubool) for {=,#} only
|
|
n/a + region x uregion --> (stream ubool) for {=,#} only
|
|
n/a + uregion x region --> (stream ubool) for {=,#} only
|
|
|
|
|
|
OK + not: ubool --> ubool
|
|
|
|
inside:
|
|
OK + upoint x uregion --> (stream ubool)
|
|
pre + upoint x line --> (stream ubool)
|
|
n/a + upoint x points --> (stream ubool)
|
|
n/a + uregion x points --> (stream ubool)
|
|
|
|
n/a + mdirection: upoint --> ureal
|
|
n/a + mheading: upoint --> ureal
|
|
|
|
n/a + area: uregion --> ureal see TemporalLiftedAlgebra
|
|
|
|
OK + sometimes: ( ubool) --> bool
|
|
OK (stream ubool) --> bool
|
|
OK + never: ( ubool) --> bool
|
|
OK (stream ubool) --> bool
|
|
OK + always: ( ubool) --> bool
|
|
OK (stream ubool) --> bool
|
|
|
|
OK length: (upoint [geoid]) --> real
|
|
|
|
COMMENTS:
|
|
|
|
(*): These operators have been implemented for
|
|
T in {bool, int, real, point}
|
|
(**): These operators have been implemented for
|
|
T in {bool, int, real, point, string, region}
|
|
|
|
Key to STATE of implementation:
|
|
|
|
OK : Operator has been implemented and fully tested
|
|
(OK): Operator has been implemented and partially tested
|
|
Test: Operator has been implemented, but tests have not been done
|
|
ERR : Operator produces errors
|
|
Pre : Operator has not been functionally implemented, but
|
|
stubs (dummy code) exist
|
|
n/a : Neither functionally nor dummy code exists for this ones
|
|
|
|
+ : Equivalent exists for according mType
|
|
- : Does nor exist for according mType
|
|
? : It is unclear, whether it exists or not
|
|
|
|
----
|
|
*/
|
|
|
|
/*
|
|
August 2006, Christian D[ue]ntgen: Added missing checks for ~undefined~
|
|
argument values to all value mapping functions. The functions will now
|
|
return ~undefined~ result values for these cases.
|
|
|
|
Changed structure of the file to become ordered by operators rather than by
|
|
typemapping, valuemapping etc. This makes the file easier to extend.
|
|
|
|
September 2009 Simone Jandt: Changed TU\_VM\_ComparePredicateValue\_UReal
|
|
to use new member function CompUReal of UReal.
|
|
|
|
*/
|
|
|
|
/*
|
|
0. Bug-List
|
|
|
|
----
|
|
|
|
(none known)
|
|
|
|
Key:
|
|
(C): system crash
|
|
(R): Wrong result
|
|
|
|
----
|
|
|
|
*/
|
|
|
|
/*
|
|
|
|
[TOC]
|
|
|
|
1 Overview
|
|
|
|
This file contains the implementation of the unit operators and
|
|
helping operators for indexing instant values in R-trees.
|
|
|
|
2 Defines, includes, and constants
|
|
|
|
*/
|
|
|
|
|
|
#include <cmath>
|
|
#include <stack>
|
|
#include <limits>
|
|
#include <sstream>
|
|
#include <vector>
|
|
|
|
#include "TemporalUnitAlgebra.h"
|
|
#include "NestedList.h"
|
|
#include "QueryProcessor.h"
|
|
#include "AlgebraManager.h"
|
|
#include "Algebra.h"
|
|
#include "StandardTypes.h"
|
|
#include "Algebras/Spatial/SpatialAlgebra.h"
|
|
#include "Algebras/Geoid/Geoid.h"
|
|
#include "Algebras/Relation-C++/RelationAlgebra.h"
|
|
#include "Algebras/Temporal/TemporalAlgebra.h"
|
|
#include "Algebras/TemporalExt/TemporalExtAlgebra.h"
|
|
#include "Algebras/MovingRegion/MovingRegionAlgebra.h"
|
|
#include "Algebras/Rectangle/RectangleAlgebra.h"
|
|
#include "PolySolver.h"
|
|
#include "ListUtils.h"
|
|
#include "Symbols.h"
|
|
#include "Stream.h"
|
|
#include "GenericTC.h"
|
|
#include "Algebras/Temporal/RefinementStream.h"
|
|
#include "Algebras/TemporalLifted/TemporalLiftedAlgebra.h"
|
|
#include "DateTime.h"
|
|
|
|
extern NestedList* nl;
|
|
extern QueryProcessor* qp;
|
|
extern AlgebraManager* am;
|
|
|
|
|
|
|
|
// #define TUA_DEBUG
|
|
|
|
|
|
namespace temporalalgebra{
|
|
|
|
|
|
/*
|
|
2.1 Definition of some constants and auxiliary functions
|
|
|
|
*/
|
|
// const double MAXDOUBLE = std::numeric_limits<double>::max();
|
|
// const double MINDOUBLE = std::numeric_limits<double>::min();
|
|
|
|
/*
|
|
2.2 Auxiliary output functions
|
|
|
|
*/
|
|
|
|
// make a string from a numeric value
|
|
std::string TUn2s(const double& i)
|
|
{
|
|
std::stringstream ss;
|
|
std::string str;
|
|
ss << i;
|
|
ss >> str;
|
|
return str;
|
|
}
|
|
|
|
// make a string representation from a time interval
|
|
std::string TUPrintTimeInterval( Interval<datetime::DateTime> iv )
|
|
{
|
|
std::string Result;
|
|
|
|
if (iv.lc)
|
|
Result += "[";
|
|
else
|
|
Result += "]";
|
|
Result += iv.start.ToString();
|
|
Result += ", ";
|
|
Result += iv.end.ToString();
|
|
if (iv.rc)
|
|
Result += "]";
|
|
else
|
|
Result += "[";
|
|
return Result;
|
|
}
|
|
|
|
// make a string representation from a point
|
|
std::string TUPrintPoint( const Point& p )
|
|
{
|
|
std::string Result;
|
|
|
|
if ( p.IsDefined() )
|
|
Result = "( def : ";
|
|
else
|
|
Result = "( undef: ";
|
|
Result += TUn2s(p.GetX());
|
|
Result += "/";
|
|
Result += TUn2s(p.GetY());
|
|
Result += " )";
|
|
|
|
return Result;
|
|
}
|
|
|
|
// make a string representation from an upoint value
|
|
std::string TUPrintUPoint( const UPoint& upoint )
|
|
{
|
|
std::string Result;
|
|
|
|
if ( upoint.IsDefined() )
|
|
Result = "( def : ";
|
|
else
|
|
Result = "( undef: ";
|
|
Result += TUPrintTimeInterval(upoint.timeInterval);
|
|
Result += ", ";
|
|
Result += TUPrintPoint(upoint.p0);
|
|
Result += ", ";
|
|
Result += TUPrintPoint(upoint.p1);
|
|
Result +=" )";
|
|
Result += ((Attribute*)(&upoint))->AttrDelete2string();
|
|
return Result;
|
|
}
|
|
|
|
// make a string representation from an ureal value
|
|
std::string TUPrintUReal( UReal* ureal )
|
|
{
|
|
std::string Result;
|
|
|
|
if ( ureal->IsDefined() )
|
|
Result = "( def : ";
|
|
else
|
|
Result = "( undef: ";
|
|
Result += TUPrintTimeInterval(ureal->timeInterval);
|
|
Result += ", ";
|
|
Result += TUn2s(ureal->a);
|
|
Result += ", ";
|
|
Result += TUn2s(ureal->b);
|
|
Result += ", ";
|
|
Result += TUn2s(ureal->c);
|
|
if (ureal->r)
|
|
Result += ", true )";
|
|
else
|
|
Result +=", false )";
|
|
Result += ureal->AttrDelete2string();
|
|
return Result;
|
|
}
|
|
|
|
/*
|
|
3 Auxiliary Functions
|
|
|
|
*/
|
|
|
|
|
|
/*
|
|
Auxiliary Method ~TU\_GetMidwayInstant~
|
|
|
|
Returns the instant at the middle of the interval defined by ~start~ and ~end~.
|
|
|
|
*/
|
|
|
|
Instant TU_GetMidwayInstant(const Instant &start, const Instant &end)
|
|
{
|
|
datetime::DateTime result(datetime::instanttype);
|
|
result = start + ((end - start) / 2);
|
|
return result;
|
|
}
|
|
|
|
|
|
/*
|
|
4 General Selection functions
|
|
|
|
A selection function is quite similar to a type mapping function. The only
|
|
difference is that it doesn't return a type but the index of a value
|
|
mapping function within the operator's ~ValueMapping~ array, being able to deal
|
|
with the respective combination of input parameter types.
|
|
|
|
Non-overloaded opertors (having only one single signature) do not need a
|
|
selection function or a ValueMapping array.
|
|
|
|
Note that a selection function does not need to check the correctness of
|
|
argument types; it has already been checked by the type mapping function that it
|
|
is applied to correct arguments.
|
|
|
|
Only some more general selection functions are listed here. More of them can
|
|
be found in the operator implementation section below.
|
|
|
|
4.1 Selection function ~UnitSimpleSelect~
|
|
|
|
Is used for the ~deftime~,~atinstant~,~atperiods~ operations.
|
|
|
|
*/
|
|
|
|
int
|
|
UnitSimpleSelect( ListExpr args )
|
|
{
|
|
ListExpr T = nl->First( args );
|
|
if( nl->SymbolValue( T ) == UBool::BasicType() )
|
|
return 0;
|
|
if( nl->SymbolValue( T ) == UInt::BasicType() )
|
|
return 1;
|
|
if( nl->SymbolValue( T ) == UReal::BasicType() )
|
|
return 2;
|
|
if( nl->SymbolValue( T ) == UPoint::BasicType() )
|
|
return 3;
|
|
if( nl->SymbolValue( T ) == UString::BasicType() )
|
|
return 4;
|
|
if( nl->SymbolValue( T ) == URegion::BasicType() )
|
|
return 5;
|
|
|
|
return -1; // This point should never be reached
|
|
}
|
|
|
|
/*
|
|
|
|
4.2 Selection function ~UnitCombinedUnitStreamSelect~
|
|
|
|
This extended version of ~UnitSimpleSelect~ can map (unit) as well as
|
|
(stream unit):
|
|
|
|
*/
|
|
|
|
int
|
|
UnitCombinedUnitStreamSelect( ListExpr args )
|
|
{
|
|
ListExpr arg1 = nl->First( args );
|
|
|
|
if (nl->IsAtom( arg1 ) )
|
|
{
|
|
if( nl->SymbolValue( arg1 ) == UBool::BasicType() )
|
|
return 0;
|
|
if( nl->SymbolValue( arg1 ) == UInt::BasicType() )
|
|
return 1;
|
|
if( nl->SymbolValue( arg1 ) == UReal::BasicType() )
|
|
return 2;
|
|
if( nl->SymbolValue( arg1 ) == UPoint::BasicType() )
|
|
return 3;
|
|
if( nl->SymbolValue( arg1 ) == UString::BasicType() )
|
|
return 4;
|
|
if( nl->SymbolValue( arg1 ) == URegion::BasicType() )
|
|
return 5;
|
|
}
|
|
|
|
if( Stream<ANY>::checkType(arg1)){
|
|
if( nl->IsEqual( nl->Second(arg1), UBool::BasicType() ) )
|
|
return 6;
|
|
if( nl->IsEqual( nl->Second(arg1), UInt::BasicType() ) )
|
|
return 7;
|
|
if( nl->IsEqual( nl->Second(arg1), UReal::BasicType() ) )
|
|
return 8;
|
|
if( nl->IsEqual( nl->Second(arg1), UPoint::BasicType() ) )
|
|
return 9;
|
|
if( nl->IsEqual( nl->Second(arg1), UString::BasicType() ) )
|
|
return 10;
|
|
if( nl->IsEqual( nl->Second(arg1), URegion::BasicType() ) )
|
|
return 11;
|
|
}
|
|
|
|
return -1; // This point should never be reached
|
|
}
|
|
|
|
|
|
/*
|
|
5 Implementation of Algebra Operators
|
|
|
|
5.1 Operator ~speed~
|
|
|
|
5.1.1 Type mapping function for ~speed~
|
|
|
|
Type mapping for ~speed~ is
|
|
|
|
----
|
|
upoint [ x geoid ] --> ureal
|
|
mpoint [ x geoid ] --> mreal
|
|
|
|
----
|
|
|
|
*/
|
|
ListExpr
|
|
TypeMapSpeed( ListExpr args )
|
|
{
|
|
int noargs = nl->ListLength( args );
|
|
std::string errmsg = "Expected ( {upoint|mpoint} [ x geoid ] ).";
|
|
if( (noargs < 1) || (noargs >2) ) {
|
|
return listutils::typeError(errmsg +" 1");
|
|
}
|
|
if( (noargs==2)
|
|
&& !listutils::isSymbol(nl->Second(args), Geoid::BasicType()) ){
|
|
return listutils::typeError(errmsg +" 2");
|
|
}
|
|
ListExpr first = nl->First(args);
|
|
if( listutils::isSymbol(first, UPoint::BasicType()) ) {
|
|
return nl->SymbolAtom( UReal::BasicType() );
|
|
}
|
|
if( listutils::isSymbol(first, MPoint::BasicType()) ) {
|
|
return nl->SymbolAtom( MReal::BasicType() );
|
|
}
|
|
return listutils::typeError(errmsg +" 3");
|
|
}
|
|
|
|
/*
|
|
5.1.2 Value mapping for operator ~speed~
|
|
|
|
*/
|
|
|
|
int MPointSpeed(Word* args, Word& result, int message, Word& local, Supplier s)
|
|
{
|
|
result = (qp->ResultStorage( s ));
|
|
MReal *res = (MReal*)result.addr;
|
|
MPoint *input = (MPoint*)args[0].addr;
|
|
Geoid* g = 0;
|
|
res->Clear();
|
|
|
|
if ( !input->IsDefined() ){
|
|
res->SetDefined(false);
|
|
return 0;
|
|
}
|
|
if( qp->GetNoSons(s)==2 ){
|
|
g = static_cast<Geoid*>(args[1].addr);
|
|
if(!g->IsDefined()){
|
|
res->SetDefined(false);
|
|
return 0;
|
|
}
|
|
}
|
|
// call member function:
|
|
input->MSpeed( *res, g );
|
|
return 0;
|
|
}
|
|
|
|
int UnitPointSpeed(Word* args,Word& result,int message,Word& local,Supplier s)
|
|
{
|
|
result = qp->ResultStorage( s );
|
|
UReal *res = (UReal*)result.addr;
|
|
UPoint *input = (UPoint*)args[0].addr;
|
|
|
|
Geoid* g = 0;
|
|
if ( !input->IsDefined() ){
|
|
res->SetDefined(false);
|
|
return 0;
|
|
}
|
|
if( qp->GetNoSons(s)==2 ){ // using (LON,LAT) and Geoid
|
|
g = static_cast<Geoid*>(args[1].addr);
|
|
if(!g->IsDefined()){
|
|
res->SetDefined(false);
|
|
return 0;
|
|
}
|
|
}
|
|
input->USpeed( *res, g );
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
5.1.3 Specification for operator ~speed~
|
|
|
|
*/
|
|
|
|
const std::string
|
|
TemporalSpecSpeed =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>mpoint [x geoid] -> mreal\n"
|
|
"upoint [x geoid] -> ureal</text--->"
|
|
"<text>speed( Obj [, Geoid] )</text--->"
|
|
"<text>Returns the scalar speed of a spatio-temporal object Obj in "
|
|
"unit/s. If Geoid is used, coordinates in Obj are expected to be geographic "
|
|
"(LON,LAT) coordinates and velocity is calculated in accordance to the geoid. "
|
|
"Otherwise metric (X,Y) coordinates are assumed.</text--->"
|
|
"<text>query speed(mp1)</text---> ) )";
|
|
|
|
/*
|
|
5.1.4 Selection Function of operator ~speed~
|
|
|
|
*/
|
|
int
|
|
SpeedSelect( ListExpr args )
|
|
{
|
|
ListExpr arg1 = nl->First( args );
|
|
|
|
if( nl->SymbolValue( arg1 ) == MPoint::BasicType() )
|
|
return 0;
|
|
|
|
if( nl->SymbolValue( arg1 ) == UPoint::BasicType() )
|
|
return 1;
|
|
|
|
return -1; // This point should never be reached
|
|
}
|
|
|
|
ValueMapping temporalspeedmap[] = { MPointSpeed,
|
|
UnitPointSpeed };
|
|
|
|
/*
|
|
5.1.5 Definition of operator ~speed~
|
|
|
|
*/
|
|
Operator temporalspeed( "speed",
|
|
TemporalSpecSpeed,
|
|
2,
|
|
temporalspeedmap,
|
|
SpeedSelect,
|
|
TypeMapSpeed);
|
|
|
|
/*
|
|
5.2 Operator ~queryrect2d~
|
|
|
|
5.2.1 Type Mapping for ~queryresct2d~
|
|
|
|
Type mapping for ~queryrect2d~ is
|
|
|
|
---- instant [->] rect
|
|
|
|
----
|
|
|
|
*/
|
|
ListExpr
|
|
InstantTypeMapQueryrect2d( ListExpr args )
|
|
{
|
|
if ( nl->ListLength( args ) == 1 )
|
|
{
|
|
ListExpr arg1 = nl->First( args );
|
|
|
|
if( nl->IsEqual( arg1, Instant::BasicType() ) )
|
|
return nl->SymbolAtom( Rectangle<2>::BasicType() );
|
|
}
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
|
}
|
|
|
|
/*
|
|
5.2.2 Value Mapping for ~queryrect2d~
|
|
|
|
*/
|
|
|
|
int Queryrect2d(Word* args, Word& result, int message, Word& local, Supplier s)
|
|
{
|
|
const unsigned dim = 2;
|
|
double min[dim], max[dim];
|
|
double timevalue;
|
|
double mininst, maxinst;
|
|
Instant* Inv = (Instant*)args[0].addr;
|
|
datetime::DateTime tmpinst;
|
|
|
|
tmpinst.ToMinimum();
|
|
mininst = tmpinst.ToDouble();
|
|
tmpinst.ToMaximum();
|
|
maxinst = tmpinst.ToDouble();
|
|
|
|
result = qp->ResultStorage( s );
|
|
|
|
if (Inv->IsDefined()) // Inv is defined: create rect2
|
|
{
|
|
timevalue = Inv->ToDouble();
|
|
|
|
min[0] = mininst; // x1
|
|
min[1] = timevalue; // x2
|
|
max[0] = timevalue; // y1
|
|
max[1] = maxinst; // y2
|
|
|
|
Rectangle<dim>* rect = new Rectangle<dim>(true, min, max);
|
|
((Rectangle<dim>*)result.addr)->CopyFrom(rect);
|
|
delete rect;
|
|
}
|
|
else // Inv is undefined: return mininst^4
|
|
{
|
|
min[0] = mininst;
|
|
min[1] = mininst;
|
|
max[0] = mininst;
|
|
max[1] = mininst;
|
|
|
|
Rectangle<dim>* rect = new Rectangle<dim>(false, min, max);
|
|
((Rectangle<dim>*)result.addr)->CopyFrom(rect);
|
|
delete rect;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
5.2.3 Specification for operator ~queryrect2d~
|
|
|
|
*/
|
|
|
|
const std::string
|
|
TemporalSpecQueryrect2d =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>(instant) -> rect</text--->"
|
|
"<text>queryrect2d( _ )</text--->"
|
|
"<text>Translate an instant object to a rect object to query against "
|
|
"a periods object translated to a point using operator 'point2d'. The "
|
|
"undef instant is mapped to rect mininst^4</text--->"
|
|
"<text>query queryrect2d(instant)</text---> ) )";
|
|
|
|
/*
|
|
5.2.4 Selection Function of operator ~queryrect2d~
|
|
|
|
Not necessary.
|
|
|
|
*/
|
|
|
|
/*
|
|
5.2.5 Definition of operator ~queryrect2d~
|
|
|
|
*/
|
|
|
|
Operator temporalunitqueryrect2d( "queryrect2d",
|
|
TemporalSpecQueryrect2d,
|
|
Queryrect2d,
|
|
Operator::SimpleSelect,
|
|
InstantTypeMapQueryrect2d);
|
|
|
|
/*
|
|
5.3 Operator ~point2d~
|
|
|
|
5.3.1 Type Mapping for ~point2d~
|
|
|
|
Type mapping for ~point2d~ is
|
|
|
|
---- periods [->] point
|
|
|
|
----
|
|
|
|
*/
|
|
|
|
ListExpr
|
|
PeriodsTypeMapPoint2d( ListExpr args )
|
|
{
|
|
|
|
if ( nl->ListLength( args ) == 1 )
|
|
{
|
|
ListExpr arg1 = nl->First( args );
|
|
|
|
if( nl->IsEqual( arg1, Periods::BasicType() ) )
|
|
return nl->SymbolAtom( Point::BasicType() );
|
|
}
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
|
}
|
|
|
|
/*
|
|
5.3.2 Value Mapping for ~point2d~
|
|
|
|
*/
|
|
int Point2d( Word* args, Word& result, int message, Word& local, Supplier s )
|
|
{
|
|
double X, Y;
|
|
Instant sup, inf;
|
|
|
|
result = qp->ResultStorage( s );
|
|
Periods* range = (Periods*)args[0].addr;
|
|
|
|
if ( !range->IsDefined() )
|
|
((Point*)result.addr)->SetDefined( false );
|
|
else
|
|
{
|
|
X = 0;
|
|
Y = 0;
|
|
if( !range->IsEmpty() )
|
|
{
|
|
Interval<Instant> intv1, intv2;
|
|
|
|
range->Get( 0, intv1 );
|
|
range->Get( range->GetNoComponents()-1, intv2 );
|
|
sup = intv1.end;
|
|
inf = intv2.start;
|
|
Y = sup.ToDouble(); // Derives the maximum of all intervals.
|
|
X = inf.ToDouble(); // Derives the minimum of all intervals.
|
|
((Point*)result.addr)->Set(X,Y); // Returns the calculated point.
|
|
((Point*)result.addr)->SetDefined(true);
|
|
}
|
|
else
|
|
{ // empty periods -> set to (mininstant, mininstant)
|
|
((Point*)result.addr)->SetDefined( false );
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
5.3.3 Specification for operator ~point2d~
|
|
|
|
*/
|
|
const std::string
|
|
TemporalSpecPoint2d =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>(periods) -> point</text--->"
|
|
"<text>point2d( _ )</text--->"
|
|
"<text>Translates a periods value to a point value representing "
|
|
"the period's total deftime interval. The empty periods value "
|
|
"is mapped to the undefined point.</text--->"
|
|
"<text>query point2d(periods)</text---> ) )";
|
|
|
|
|
|
/*
|
|
5.3.4 Selection Function of operator ~point2d~
|
|
|
|
Not necessary.
|
|
|
|
*/
|
|
|
|
/*
|
|
5.3.5 Definition of operator ~point2d~
|
|
|
|
*/
|
|
Operator temporalunitpoint2d( "point2d",
|
|
TemporalSpecPoint2d,
|
|
Point2d,
|
|
Operator::SimpleSelect,
|
|
PeriodsTypeMapPoint2d);
|
|
|
|
/*
|
|
5.4 Operator ~get\_duration~
|
|
|
|
5.4.1 Type Mapping for ~get\_duration~
|
|
|
|
Type mapping for ~get\_duration~ is
|
|
|
|
---- periods [->] duration
|
|
|
|
----
|
|
|
|
*/
|
|
ListExpr
|
|
PeriodsTypeMapGetDuration( ListExpr args )
|
|
{
|
|
if ( nl->ListLength( args ) == 1 )
|
|
{
|
|
ListExpr arg1 = nl->First( args );
|
|
|
|
if( nl->IsEqual( arg1, Periods::BasicType() ) )
|
|
return nl->SymbolAtom( Duration::BasicType() );
|
|
}
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
|
}
|
|
|
|
/*
|
|
5.4.2 Value Mapping for ~get\_duration~
|
|
|
|
*/
|
|
int GetDuration( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
result = qp->ResultStorage( s );
|
|
Periods* range = (Periods*)args[0].addr;
|
|
datetime::DateTime* Res = ((datetime::DateTime*)result.addr);
|
|
*Res = datetime::DateTime(0, 0, datetime::durationtype);
|
|
if ( !range->IsDefined() )
|
|
((datetime::DateTime*)result.addr)->SetDefined( false );
|
|
else
|
|
{
|
|
Res->SetDefined(true);
|
|
if( !range->IsEmpty() )
|
|
{
|
|
Interval<Instant> intv;
|
|
|
|
for( int i = 0; i < range->GetNoComponents(); i++ )
|
|
{
|
|
range->Get( i, intv );
|
|
*Res += (intv.end - intv.start);
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
5.4.3 Specification for operator ~get\_duration~
|
|
|
|
*/
|
|
const std::string
|
|
TemporalSpecGetDuration =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>(periods) -> duration</text--->"
|
|
"<text>get_duration( _ )</text--->"
|
|
"<text>Return the duration in spanned by a periods value "
|
|
"as a duration value.</text--->"
|
|
"<text>query get_duration(periods)</text---> ) )";
|
|
|
|
/*
|
|
5.4.4 Selection Function of operator ~get\_duration~
|
|
|
|
Not necessary.
|
|
|
|
*/
|
|
|
|
|
|
/*
|
|
5.4.5 Definition of operator ~get\_duration~
|
|
|
|
*/
|
|
Operator temporalunitget_duration( "get_duration",
|
|
TemporalSpecGetDuration,
|
|
GetDuration,
|
|
Operator::SimpleSelect,
|
|
PeriodsTypeMapGetDuration );
|
|
|
|
/*
|
|
5.5 Operators ~makemvalue~, ~the\_mvalue~
|
|
|
|
This operators create a moving object type mT from a stream of unit type
|
|
objects uT. The operator does not expect the stream to be ordered by their
|
|
timeintervals. Also, undefined units are allowed (but will be ignored).
|
|
If the stream contains amindst 2 units with overlapping timeIntervals,
|
|
the operator might crash. If the stream is empty, the result will be an
|
|
empty mT.
|
|
|
|
5.5.1 Type Mapping for ~makemvalue~, ~the\_mvalue~
|
|
|
|
Type mapping for ~makemvalue~ is
|
|
|
|
----
|
|
|
|
stream (tuple ([x1:t1,x1:ubool,..,[xn:tn))) -> mbool
|
|
APPEND (i ti)
|
|
stream (tuple ([x1:t1,x1:uint,..,[xn:tn))) -> mint
|
|
APPEND (i ti)
|
|
stream (tuple ([x1:t1,x1:ureal,..,[xn:tn))) -> mreal
|
|
APPEND (i ti)
|
|
stream (tuple ([x1:t1,x1:upoint,..,[xn:tn))) -> mpoint
|
|
APPEND (i ti)
|
|
stream (tuple ([x1:t1,x1:ustring,..,[xn:tn))) -> mstring
|
|
APPEND (i ti)
|
|
|
|
NOT YET AVAILABLE DUE TO ERRORS:
|
|
stream (tuple ([x1:t1,x1:uregion,..,[xn:tn))) -> mregion
|
|
APPEND (i ti)
|
|
|
|
----
|
|
|
|
For ~the\_mvalue~, it is
|
|
|
|
----
|
|
the_mvalue: (stream uT) --> mT
|
|
----
|
|
|
|
*/
|
|
|
|
ListExpr TU_TM_themvalue( ListExpr args )
|
|
{
|
|
std::string errmsg = "Expected (stream T), where T "
|
|
"in{ubool,uint,upoint,ustring}";
|
|
if(nl->ListLength(args) != 1){
|
|
return listutils::typeError(errmsg);
|
|
}
|
|
if(!listutils::isDATAStream(nl->First(args))){
|
|
return listutils::typeError(errmsg);
|
|
}
|
|
ListExpr elemtype = nl->Second(nl->First(args));
|
|
if(listutils::isSymbol(elemtype,UBool::BasicType())){
|
|
return nl->SymbolAtom( MBool::BasicType() );
|
|
}
|
|
if(listutils::isSymbol(elemtype,UInt::BasicType())){
|
|
return nl->SymbolAtom( MInt::BasicType() );
|
|
}
|
|
if(listutils::isSymbol(elemtype,UString::BasicType())){
|
|
return nl->SymbolAtom( MString::BasicType() );
|
|
}
|
|
if(listutils::isSymbol(elemtype,UReal::BasicType())){
|
|
return nl->SymbolAtom( MReal::BasicType() );
|
|
}
|
|
if(listutils::isSymbol(elemtype,UPoint::BasicType())){
|
|
return nl->SymbolAtom( MPoint::BasicType() );
|
|
}
|
|
// if(listutils::isSymbol(elemtype,URegion::BasicType())){
|
|
// return nl->SymbolAtom( MRegion::BasicType() );
|
|
// }
|
|
return listutils::typeError(errmsg);
|
|
}
|
|
|
|
ListExpr the_mvalue2TM(ListExpr args){
|
|
std::string err = "stream(UT) , T in {bool. int, real, "
|
|
"string, point} expected";
|
|
if(!nl->HasLength(args,1)){
|
|
return listutils::typeError(err);
|
|
}
|
|
ListExpr a = nl->First(args);
|
|
if(Stream<UBool>::checkType(a)) return nl->SymbolAtom(MBool::BasicType());
|
|
if(Stream<UInt>::checkType(a)) return nl->SymbolAtom(MInt::BasicType());
|
|
if(Stream<UString>::checkType(a)) return nl->SymbolAtom(MString::BasicType());
|
|
if(Stream<UReal>::checkType(a)) return nl->SymbolAtom(MReal::BasicType());
|
|
if(Stream<UPoint>::checkType(a)) return nl->SymbolAtom(MPoint::BasicType());
|
|
return listutils::typeError(err);
|
|
}
|
|
|
|
|
|
|
|
|
|
ListExpr MovingTypeMapMakemvalue( ListExpr args )
|
|
|
|
{
|
|
ListExpr first, second, rest, listn,
|
|
lastlistn, first2, second2, firstr, listfull, attrtype;
|
|
|
|
int j;
|
|
std::string argstr, argstr2, attrname, inputtype, inputname, fulllist;
|
|
|
|
//check the list length.
|
|
if(nl->ListLength(args)!=2){
|
|
return listutils::typeError("two arguments expected");
|
|
}
|
|
|
|
first = nl->First(args);
|
|
nl->WriteToString(argstr, first);
|
|
|
|
// check the structure of the list.
|
|
if( !listutils::isTupleStream(first) )
|
|
{
|
|
ErrorReporter::ReportError("Operator makemvalue expects as first argument "
|
|
"a tuplestream, but gets '" + argstr + "'.");
|
|
return nl->TypeError();
|
|
}
|
|
|
|
// check the given parameter
|
|
second = nl->Second(args);
|
|
nl->WriteToString(argstr, second);
|
|
if(argstr == Symbol::TYPEERROR()){
|
|
return listutils::typeError("invalid attrname" + argstr);
|
|
}
|
|
|
|
// inputname represented the name of the given attribute
|
|
nl->WriteToString(inputname, second);
|
|
|
|
rest = nl->Second(nl->Second(first));
|
|
listn = nl->OneElemList(nl->First(rest));
|
|
lastlistn = listn;
|
|
firstr = nl->First(rest);
|
|
rest = nl->Rest(rest);
|
|
first2 = nl->First(firstr);
|
|
second2 = nl->Second(firstr);
|
|
nl->WriteToString(attrname, first2);
|
|
nl->WriteToString(argstr2, second2);
|
|
|
|
// compare with the attributes in the relation
|
|
if (attrname == inputname)
|
|
inputtype = argstr2;
|
|
|
|
// save from the detected attribute the type
|
|
while (!(nl->IsEmpty(rest)))
|
|
{
|
|
lastlistn = nl->Append(lastlistn,nl->First(rest));
|
|
firstr = nl->First(rest);
|
|
rest = nl->Rest(rest);
|
|
first2 = nl->First(firstr);
|
|
second2 = nl->Second(firstr);
|
|
nl->WriteToString(attrname, first2);
|
|
nl->WriteToString(argstr2, second2);
|
|
|
|
// compare with the attributes in the relation
|
|
if (attrname == inputname)
|
|
inputtype = argstr2;
|
|
|
|
// save from the detected attribute the type
|
|
}
|
|
rest = second;
|
|
listfull = listn;
|
|
nl->WriteToString(fulllist, listfull);
|
|
|
|
|
|
if(inputtype==""){
|
|
return listutils::typeError("attribute not found");
|
|
}
|
|
|
|
if((inputtype != UBool::BasicType()) &&
|
|
(inputtype != UInt::BasicType()) &&
|
|
(inputtype != UReal::BasicType()) &&
|
|
(inputtype != UPoint::BasicType()) &&
|
|
(inputtype != UString::BasicType()) ) {
|
|
return listutils::typeError("attr type not in {ubool, uint,"
|
|
" ustring, ureal, upoint");
|
|
}
|
|
attrname = nl->SymbolValue(second);
|
|
j = FindAttribute(nl->Second(nl->Second(first)), attrname, attrtype);
|
|
|
|
assert( j !=0 );
|
|
|
|
if( inputtype == UPoint::BasicType() )
|
|
attrtype = nl->SymbolAtom( MPoint::BasicType() ) ;
|
|
if( inputtype == UBool::BasicType() )
|
|
attrtype = nl->SymbolAtom( MBool::BasicType() );
|
|
if( inputtype == UReal::BasicType() )
|
|
attrtype = nl->SymbolAtom( MReal::BasicType() );
|
|
if( inputtype == UInt::BasicType() )
|
|
attrtype = nl->SymbolAtom( MInt::BasicType() );
|
|
if( inputtype == UString::BasicType() )
|
|
attrtype = nl->SymbolAtom( MString::BasicType() );
|
|
//if( inputtype == URegion::BasicType() )
|
|
// attrtype = nl->SymbolAtom( MRegion::BasicType());
|
|
|
|
return nl->ThreeElemList(nl->SymbolAtom(Symbol::APPEND()),
|
|
nl->TwoElemList(nl->IntAtom(j),
|
|
nl->StringAtom(nl->SymbolValue(attrtype))), attrtype);
|
|
|
|
// Appending the number of the attribute in the relation is very important,
|
|
// because in the other case we can't work with it in the value function.
|
|
}
|
|
|
|
/*
|
|
5.5.2 Value Mapping for ~makemvalue~, ~the\_mvalue~
|
|
|
|
*/
|
|
|
|
template <class Mapping, class Unit>
|
|
int MappingMakemvalue(Word* args,Word& result,int message,
|
|
Word& local,Supplier s)
|
|
{
|
|
Mapping* m;
|
|
Unit* unit;
|
|
Word currentTupleWord;
|
|
|
|
assert(args[2].addr != 0); // assert existence of input
|
|
assert(args[3].addr != 0); // assert existence of input
|
|
|
|
int attributeIndex = ((CcInt*)args[2].addr)->GetIntval() - 1;
|
|
|
|
qp->Open(args[0].addr);
|
|
qp->Request(args[0].addr, currentTupleWord);
|
|
|
|
result = qp->ResultStorage(s);
|
|
|
|
m = (Mapping*) result.addr;
|
|
m->Clear();
|
|
m->SetDefined( true );
|
|
m->StartBulkLoad();
|
|
|
|
while ( qp->Received(args[0].addr) ) // get all tuples
|
|
{
|
|
Tuple* currentTuple = (Tuple*)currentTupleWord.addr;
|
|
Attribute* currentAttr = (Attribute*)currentTuple->
|
|
GetAttribute(attributeIndex);
|
|
if(currentAttr == 0)
|
|
{
|
|
cout << endl << "ERROR in " << __PRETTY_FUNCTION__
|
|
<< ": received Nullpointer!" << endl;
|
|
assert( false );
|
|
}
|
|
else if(currentAttr->IsDefined())
|
|
{
|
|
unit = static_cast<Unit*>(currentAttr);
|
|
m->Add( *unit );
|
|
} else {
|
|
std::cerr << endl << __PRETTY_FUNCTION__ << ": Dropping undef unit. "
|
|
<< endl;
|
|
}
|
|
currentTuple->DeleteIfAllowed();
|
|
qp->Request(args[0].addr, currentTupleWord);
|
|
}
|
|
m->EndBulkLoad( true, true ); // force Mapping to sort the units
|
|
qp->Close(args[0].addr); // and mark invalid Mapping as undefined
|
|
|
|
return 0;
|
|
}
|
|
|
|
template <class Unit>
|
|
int UCompare( const void *a, const void *b )
|
|
{
|
|
Unit *unita = new ((void*)a) Unit,
|
|
*unitb = new ((void*)b) Unit;
|
|
|
|
int cmp= unita->Compare(unitb);
|
|
return cmp;
|
|
}
|
|
|
|
template <class Mapping, class Unit>
|
|
int MappingMakemvaluePlain(Word* args,Word& result,int message,
|
|
Word& local,Supplier s)
|
|
{
|
|
Word currentUnit;
|
|
Unit* unit1;
|
|
Instant lastInst(datetime::instanttype, 0);
|
|
bool lastRC= false;
|
|
DbArray<Unit> allUnits(0);
|
|
qp->Open(args[0].addr);
|
|
qp->Request(args[0].addr, currentUnit);
|
|
|
|
result = qp->ResultStorage(s);
|
|
Mapping* m = static_cast<Mapping*>(result.addr);
|
|
m->Clear();
|
|
m->SetDefined( true );
|
|
|
|
while ( qp->Received(args[0].addr) ) { // get all tuples
|
|
unit1 = static_cast<Unit*>(currentUnit.addr);
|
|
if(unit1 == 0) {
|
|
cout << endl << __PRETTY_FUNCTION__ << ": Received Nullpointer!"
|
|
<< endl;
|
|
assert( false );
|
|
} else if(unit1->IsDefined()) {
|
|
allUnits.Append(*unit1);
|
|
} else {
|
|
std::cerr << endl << __PRETTY_FUNCTION__ << ": Dropping undef unit "
|
|
<< endl;
|
|
}
|
|
unit1->DeleteIfAllowed();
|
|
qp->Request(args[0].addr, currentUnit);
|
|
}
|
|
qp->Close(args[0].addr);
|
|
if(allUnits.Size() == 0) return 0;
|
|
|
|
allUnits.Sort( UCompare<Unit> );
|
|
|
|
|
|
Unit unit2;
|
|
allUnits.Get(0, unit2);
|
|
lastInst= unit2.timeInterval.start;
|
|
for(int i=0; i< allUnits.Size(); ++i)
|
|
{
|
|
allUnits.Get(i, unit2);
|
|
if(unit2.timeInterval.start > lastInst ||
|
|
((unit2.timeInterval.start == lastInst) &&
|
|
!(unit2.timeInterval.lc && lastRC) ))
|
|
{
|
|
m->MergeAdd( unit2 );
|
|
lastInst= unit2.timeInterval.end;
|
|
lastRC= unit2.timeInterval.rc;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
template<class Mapping, class Unit>
|
|
int the_mvalue2VM1(Word* args, Word& result, int message,
|
|
Word& local, Supplier s){
|
|
|
|
result = qp->ResultStorage(s);
|
|
Mapping* res = (Mapping*)result.addr;
|
|
res->Clear();
|
|
res->StartBulkLoad();
|
|
res->SetDefined(true);
|
|
Stream<Unit> stream(args[0]);
|
|
Unit* unit;
|
|
stream.open();
|
|
unit = stream.request();
|
|
Unit* lastUnit = 0;
|
|
while(unit){
|
|
if(unit->IsDefined()){
|
|
if(lastUnit==0){ // first Unit
|
|
res->MergeAdd(*unit);
|
|
lastUnit = unit;
|
|
} else { // not the first unit
|
|
if((unit->timeInterval.start > lastUnit->timeInterval.end) ||
|
|
( (unit->timeInterval.start == lastUnit->timeInterval.end) &&
|
|
(!unit->timeInterval.lc || !lastUnit->timeInterval.rc))){
|
|
// case : unit starts after lastUnit
|
|
res->MergeAdd(*unit);
|
|
lastUnit->DeleteIfAllowed();
|
|
lastUnit = unit;
|
|
} else if(((unit->timeInterval.end) < (lastUnit->timeInterval.end)) ||
|
|
((unit->timeInterval.end ==lastUnit->timeInterval.end) &&
|
|
(!unit->timeInterval.rc || lastUnit->timeInterval.rc))) {
|
|
// no part of the unit if after the last unit
|
|
// ignore this unit
|
|
unit->DeleteIfAllowed();
|
|
} else {
|
|
// unit overlaps lastUnit, but is longer than lastUnit
|
|
Interval<Instant> iv = unit->timeInterval;
|
|
iv.start = lastUnit->timeInterval.end;
|
|
iv.lc = !lastUnit->timeInterval.rc;
|
|
Unit nUnit(true);
|
|
unit->AtInterval(iv,nUnit);
|
|
res->MergeAdd(nUnit);
|
|
lastUnit->DeleteIfAllowed();
|
|
lastUnit = unit;;
|
|
}
|
|
}
|
|
} // unit is defined
|
|
unit = stream.request();
|
|
}
|
|
if(lastUnit){
|
|
lastUnit->DeleteIfAllowed();
|
|
}
|
|
stream.close();
|
|
|
|
res->EndBulkLoad(false);
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// here comes the version for mregion, where URegion has a rather
|
|
// ugly implementation and thus needs a specialized treatment!
|
|
int MappingMakemvalue_movingregion(Word* args,Word& result,int message,
|
|
Word& local,Supplier s)
|
|
{
|
|
MRegion* m;
|
|
Word currentTupleWord;
|
|
|
|
assert(args[2].addr != 0); // assert existence of input
|
|
assert(args[3].addr != 0); // assert existence of input
|
|
|
|
int attributeIndex = ((CcInt*)args[2].addr)->GetIntval() - 1;
|
|
|
|
qp->Open(args[0].addr);
|
|
qp->Request(args[0].addr, currentTupleWord);
|
|
|
|
result = qp->ResultStorage(s);
|
|
|
|
m = (MRegion*) result.addr;
|
|
m->Clear();
|
|
m->SetDefined( true );
|
|
m->StartBulkLoad();
|
|
|
|
while ( qp->Received(args[0].addr) ) // get all tuples
|
|
{
|
|
Tuple* currentTuple = (Tuple*)currentTupleWord.addr;
|
|
URegion* currentUnit = static_cast<URegion*>(currentTuple->
|
|
GetAttribute(attributeIndex));
|
|
|
|
if(currentUnit == 0) {
|
|
cout << endl << __PRETTY_FUNCTION__ << ": Received Nullpointer!"<< endl;
|
|
assert( false );
|
|
} else if(currentUnit->IsDefined()) {
|
|
m->AddURegion( *currentUnit );
|
|
} else {
|
|
std::cerr << endl << __PRETTY_FUNCTION__ << ": Dropping undef URegion "
|
|
<< endl;
|
|
}
|
|
currentTuple->DeleteIfAllowed();
|
|
qp->Request(args[0].addr, currentTupleWord);
|
|
}
|
|
m->EndBulkLoad( true, true ); // force Mapping to sort the units
|
|
qp->Close(args[0].addr); // and mark invalid Mapping as undefined
|
|
|
|
return 0;
|
|
}
|
|
|
|
int MappingMakemvalue_movingregionPlain(Word* args,Word& result,int message,
|
|
Word& local,Supplier s)
|
|
{
|
|
MRegion* m;
|
|
URegion* unit;
|
|
Word currentUnit;
|
|
|
|
qp->Open(args[0].addr);
|
|
qp->Request(args[0].addr, currentUnit);
|
|
|
|
result = qp->ResultStorage(s);
|
|
|
|
m = (MRegion*) result.addr;
|
|
m->Clear();
|
|
m->SetDefined( true );
|
|
m->StartBulkLoad();
|
|
|
|
while ( qp->Received(args[0].addr) ) // get all tuples
|
|
{
|
|
unit = (URegion*) currentUnit.addr;
|
|
if(unit == 0) {
|
|
cout << endl << __PRETTY_FUNCTION__ << ":received Nullpointer!" << endl;
|
|
assert( false );
|
|
} else if(unit->IsDefined()) {
|
|
m->AddURegion( *unit );
|
|
} else {
|
|
std::cerr << endl << __PRETTY_FUNCTION__ << ": Dropping undef URegion "
|
|
<< endl;
|
|
}
|
|
unit->DeleteIfAllowed();
|
|
qp->Request(args[0].addr, currentUnit);
|
|
}
|
|
m->EndBulkLoad( true, true ); // force Mapping to sort the units
|
|
qp->Close(args[0].addr); // and mark invalid Mapping as undefined
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
5.5.3 Specification for operators ~makemvalue~, ~the\_mvalue~
|
|
|
|
*/
|
|
const std::string
|
|
TemporalSpecMakemvalue =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>For T in {bool, int, string, real, point, region*}:\n"
|
|
"((stream (tuple ((x1 t1)...(xn tn))) (uT)))-> mT\n"
|
|
"*: Not yet available</text--->"
|
|
"<text>_ makemvalue[ _ ]</text--->"
|
|
"<text>Create a moving object from a (not necessarily sorted) "
|
|
"tuple stream containing a unit type attribute. "
|
|
"No two unit timeintervals may overlap. Undefined units are "
|
|
"allowed and will be ignored. A stream with less than 1 defined "
|
|
"unit will result in an 'empty' moving object, not in an 'undef'.</text--->"
|
|
"<text>query units(zug5) transformstream makemvalue[elem]</text---> ) )";
|
|
|
|
const std::string
|
|
TemporalSpecThemvalue =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>For T in {bool, int, string, real, point, region*}:\n"
|
|
"(stream uT) -> mT\n"
|
|
"*: Not yet available</text--->"
|
|
"<text>_ the_mvalue</text--->"
|
|
"<text>Create a moving object from a (not necessarily sorted) "
|
|
"object stream containing units. If two unit time intervals overlap, the unit "
|
|
"that starts first is kept in the result, and the unit that starts later is "
|
|
"ignored. Undefined units are allowed and will be ignored. A stream with less "
|
|
"than 1 defined unit will result in an 'empty' moving object, not in an "
|
|
"'undef'.</text--->"
|
|
"<text>query units(zug5) the_mvalue</text---> ) )";
|
|
|
|
|
|
const std::string
|
|
the_mvalue2Spec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>For T in {bool, int, string, real, point}:\n"
|
|
"(stream uT) -> mT\n"
|
|
"</text--->"
|
|
"<text>_ the_mvalue2</text--->"
|
|
"<text>Create a moving object from a sorted "
|
|
"object stream containing units. "
|
|
"Two units may overlap in time. The second unit will be shortened. "
|
|
"</text--->"
|
|
"<text>query units(zug5) the_mvalue2</text---> ) )";
|
|
|
|
|
|
/*
|
|
5.5.4 Selection Function of operators ~makemvalue~, ~the\_mvalue~
|
|
|
|
*/
|
|
int
|
|
ThemvalueSelect( ListExpr args )
|
|
{
|
|
std::string argstr;
|
|
nl->WriteToString(argstr, args);
|
|
if ( argstr == "((stream ubool))" ) return 0;
|
|
if ( argstr == "((stream uint))" ) return 1;
|
|
if ( argstr == "((stream ustring))" ) return 2;
|
|
if ( argstr == "((stream ureal))" ) return 3;
|
|
if ( argstr == "((stream upoint))" ) return 4;
|
|
if ( argstr == "((stream uregion))" ) return 5;
|
|
return -1; // This point should never be reached
|
|
}
|
|
|
|
int
|
|
the_mvalue2Select( ListExpr args )
|
|
{
|
|
ListExpr t = nl->Second(nl->First(args));
|
|
if(UBool::checkType(t)) return 0;
|
|
if(UInt::checkType(t)) return 1;
|
|
if(UString::checkType(t)) return 2;
|
|
if(UReal::checkType(t)) return 3;
|
|
if(UPoint::checkType(t)) return 4;
|
|
return -1;
|
|
}
|
|
|
|
|
|
int
|
|
MakemvalueSelect( ListExpr args )
|
|
{
|
|
|
|
ListExpr first, second, rest, listn,
|
|
lastlistn, first2, second2, firstr;
|
|
|
|
std::string argstr, argstr2, attrname, inputtype, inputname;
|
|
|
|
first = nl->First(args);
|
|
second = nl->Second(args);
|
|
nl->WriteToString(argstr, first);
|
|
|
|
nl->WriteToString(inputname, second);
|
|
|
|
rest = nl->Second(nl->Second(first));
|
|
listn = nl->OneElemList(nl->First(rest));
|
|
lastlistn = listn;
|
|
firstr = nl->First(rest);
|
|
rest = nl->Rest(rest);
|
|
first2 = nl->First(firstr);
|
|
second2 = nl->Second(firstr);
|
|
nl->WriteToString(attrname, first2);
|
|
nl->WriteToString(argstr2, second2);
|
|
if (attrname == inputname)
|
|
inputtype = argstr2;
|
|
while (!(nl->IsEmpty(rest)))
|
|
{
|
|
lastlistn = nl->Append(lastlistn,nl->First(rest));
|
|
firstr = nl->First(rest);
|
|
rest = nl->Rest(rest);
|
|
first2 = nl->First(firstr);
|
|
second2 = nl->Second(firstr);
|
|
nl->WriteToString(attrname, first2);
|
|
nl->WriteToString(argstr2, second2);
|
|
if (attrname == inputname)
|
|
inputtype = argstr2;
|
|
}
|
|
if( inputtype == UBool::BasicType() ) return 0;
|
|
if( inputtype == UInt::BasicType() ) return 1;
|
|
if( inputtype == UString::BasicType() ) return 2;
|
|
if( inputtype == UReal::BasicType() ) return 3;
|
|
if( inputtype == UPoint::BasicType() ) return 4;
|
|
if( inputtype == URegion::BasicType() ) return 5;
|
|
|
|
return -1; // This point should never be reached
|
|
}
|
|
|
|
ValueMapping temporalmakemvaluemap[] = {
|
|
MappingMakemvalue<MBool, UBool>,
|
|
MappingMakemvalue<MInt, UInt>,
|
|
MappingMakemvalue<MString, UString>,
|
|
MappingMakemvalue<MReal, UReal>,
|
|
MappingMakemvalue<MPoint, UPoint>,
|
|
MappingMakemvalue_movingregion} ;
|
|
|
|
ValueMapping temporalthemvaluemap[] = {
|
|
MappingMakemvaluePlain<MBool, UBool>,
|
|
MappingMakemvaluePlain<MInt, UInt>,
|
|
MappingMakemvaluePlain<MString, UString>,
|
|
MappingMakemvaluePlain<MReal, UReal>,
|
|
MappingMakemvaluePlain<MPoint, UPoint>,
|
|
MappingMakemvalue_movingregionPlain };
|
|
|
|
|
|
ValueMapping the_mvalue2VM[] = {
|
|
the_mvalue2VM1<MBool, UBool>,
|
|
the_mvalue2VM1<MInt, UInt>,
|
|
the_mvalue2VM1<MString, UString>,
|
|
the_mvalue2VM1<MReal, UReal>,
|
|
the_mvalue2VM1<MPoint, UPoint> };
|
|
|
|
/*
|
|
5.5.5 Definition of operators ~makemvalue~, ~the\-mvalue~
|
|
|
|
*/
|
|
Operator temporalunitmakemvalue( "makemvalue",
|
|
TemporalSpecMakemvalue,
|
|
6,
|
|
temporalmakemvaluemap,
|
|
MakemvalueSelect,
|
|
MovingTypeMapMakemvalue );
|
|
|
|
Operator temporalunitthemvalue( "the_mvalue",
|
|
TemporalSpecThemvalue,
|
|
6,
|
|
temporalthemvaluemap,
|
|
ThemvalueSelect,
|
|
TU_TM_themvalue );
|
|
|
|
|
|
Operator the_mvalue2( "the_mvalue2",
|
|
the_mvalue2Spec,
|
|
5,
|
|
the_mvalue2VM,
|
|
the_mvalue2Select,
|
|
the_mvalue2TM);
|
|
|
|
/*
|
|
5.6 Operator ~trajectory~
|
|
|
|
5.6.1 Type Mapping for ~trajectory~
|
|
|
|
*/
|
|
ListExpr
|
|
UnitTrajectoryTypeMap( ListExpr args )
|
|
{
|
|
if ( nl->ListLength( args ) == 1 )
|
|
{
|
|
ListExpr arg1 = nl->First( args );
|
|
|
|
if( nl->IsEqual( arg1, UPoint::BasicType() ) )
|
|
return nl->SymbolAtom( Line::BasicType() );
|
|
}
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
|
}
|
|
|
|
/*
|
|
5.6.2 Value Mapping for ~trajectory~
|
|
|
|
*/
|
|
int UnitPointTrajectory(Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
result = qp->ResultStorage( s );
|
|
|
|
Line *line = ((Line*)result.addr);
|
|
UPoint *upoint = ((UPoint*)args[0].addr);
|
|
|
|
line->Clear(); // clear result
|
|
if ( upoint->IsDefined() ){
|
|
line->SetDefined( true );
|
|
upoint->UTrajectory( *line ); // call memberfunction
|
|
} else {
|
|
line->SetDefined( false );
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
5.6.3 Specification for operator ~trajectory~
|
|
|
|
*/
|
|
const std::string
|
|
TemporalSpecTrajectory =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>upoint -> line</text--->"
|
|
"<text>trajectory( _ )</text--->"
|
|
"<text>get the trajectory of the corresponding"
|
|
"unit point object. Static upoint objects "
|
|
"yield empty line objects, on undef argument, it returns undef.</text--->"
|
|
"<text>trajectory( up1 )</text---> ) )";
|
|
|
|
/*
|
|
5.6.4 Selection Function of operator ~trajectory~
|
|
|
|
Not necessary.
|
|
|
|
*/
|
|
|
|
/*
|
|
5.6.5 Definition of operator ~trajectory~
|
|
|
|
*/
|
|
Operator temporalunittrajectory( "trajectory",
|
|
TemporalSpecTrajectory,
|
|
UnitPointTrajectory,
|
|
Operator::SimpleSelect,
|
|
UnitTrajectoryTypeMap );
|
|
|
|
/*
|
|
5.7 Operator ~deftime~
|
|
|
|
5.7.1 Type Mapping for ~deftime~
|
|
|
|
*/
|
|
ListExpr
|
|
UnitTypeMapPeriods( ListExpr args )
|
|
{
|
|
if ( nl->ListLength( args ) == 1 )
|
|
{
|
|
ListExpr arg1 = nl->First( args );
|
|
|
|
if( nl->IsEqual( arg1, UBool::BasicType() ) ||
|
|
nl->IsEqual( arg1, UInt::BasicType() ) ||
|
|
nl->IsEqual( arg1, UReal::BasicType() ) ||
|
|
nl->IsEqual( arg1, UPoint::BasicType() ) ||
|
|
nl->IsEqual( arg1, UString::BasicType() ) ||
|
|
nl->IsEqual( arg1, URegion::BasicType() ) )
|
|
return nl->SymbolAtom( Periods::BasicType() );
|
|
}
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
|
}
|
|
|
|
/*
|
|
5.7.2 Value Mapping for ~deftime~
|
|
|
|
*/
|
|
template <class Unit>
|
|
int MappingUnitDefTime( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
result = qp->ResultStorage( s );
|
|
Periods* r = ((Periods*) result.addr);
|
|
Unit* m = ((Unit*) args[0].addr);
|
|
|
|
r->Clear();
|
|
if ( !m->IsDefined() )
|
|
r->SetDefined( false );
|
|
else
|
|
{
|
|
r->SetDefined( true );
|
|
r->StartBulkLoad();
|
|
r->Add( m->timeInterval );
|
|
r->EndBulkLoad( false );
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
5.7.3 Specification for operator ~deftime~
|
|
|
|
*/
|
|
const std::string
|
|
TemporalSpecDefTime =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>uT -> periods \n"
|
|
"(for T in {bool, int, real, string, point, region})</text--->"
|
|
"<text>deftime( _ )</text--->"
|
|
"<text>get the definition time for the "
|
|
" unit data objects.</text--->"
|
|
"<text>deftime( up1 )</text---> ) )";
|
|
|
|
/*
|
|
5.7.4 Selection Function of operator ~deftime~
|
|
|
|
Uses ~UnitSimpleSelect~.
|
|
|
|
*/
|
|
|
|
ValueMapping temporalunitdeftimemap[] = { MappingUnitDefTime<UBool>,
|
|
MappingUnitDefTime<UInt>,
|
|
MappingUnitDefTime<UReal>,
|
|
MappingUnitDefTime<UPoint>,
|
|
MappingUnitDefTime<UString>,
|
|
MappingUnitDefTime<URegion>};
|
|
|
|
|
|
/*
|
|
5.7.5 Definition of operator ~deftime~
|
|
|
|
*/
|
|
|
|
Operator temporalunitdeftime( "deftime",
|
|
TemporalSpecDefTime,
|
|
6,
|
|
temporalunitdeftimemap,
|
|
UnitSimpleSelect,
|
|
UnitTypeMapPeriods );
|
|
/*
|
|
5.8 Operator ~atinstant~
|
|
|
|
5.8.1 Type Mapping for ~atinstant~
|
|
|
|
*/
|
|
ListExpr
|
|
UnitInstantTypeMapIntime( ListExpr args )
|
|
{
|
|
if ( nl->ListLength( args ) == 2 )
|
|
{
|
|
ListExpr arg1 = nl->First( args ),
|
|
arg2 = nl->Second( args );
|
|
|
|
if( nl->IsEqual( arg2, Instant::BasicType() ) )
|
|
{
|
|
if( nl->IsEqual( arg1, UBool::BasicType() ) )
|
|
return nl->SymbolAtom( IBool::BasicType() );
|
|
|
|
if( nl->IsEqual( arg1, UInt::BasicType() ) )
|
|
return nl->SymbolAtom( IInt::BasicType() );
|
|
|
|
if( nl->IsEqual( arg1, UReal::BasicType() ) )
|
|
return nl->SymbolAtom( IReal::BasicType() );
|
|
|
|
if( nl->IsEqual( arg1, UPoint::BasicType() ) )
|
|
return nl->SymbolAtom( IPoint::BasicType() );
|
|
|
|
if( nl->IsEqual( arg1, UString::BasicType() ) )
|
|
return nl->SymbolAtom( IString::BasicType() );
|
|
|
|
if( nl->IsEqual( arg1, URegion::BasicType() ) )
|
|
return nl->SymbolAtom( IRegion::BasicType() );
|
|
}
|
|
}
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
|
}
|
|
|
|
/*
|
|
5.8.2 Value Mapping for ~atinstant~
|
|
|
|
*/
|
|
template <class Mapping, class Alpha>
|
|
int MappingUnitAtInstant( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
result = qp->ResultStorage( s );
|
|
|
|
Intime<Alpha>* pResult = (Intime<Alpha>*)result.addr;
|
|
Mapping* posUnit = ((Mapping*)args[0].addr);
|
|
Instant* t = ((Instant*)args[1].addr);
|
|
|
|
if ( !t->IsDefined() || !posUnit->IsDefined() ) {
|
|
pResult->SetDefined( false );
|
|
} else if( posUnit->timeInterval.Contains(*t) ) {
|
|
posUnit->TemporalFunction( *t, pResult->value );
|
|
pResult->instant = *t;
|
|
pResult->SetDefined( true );
|
|
} else { // instant not contained by deftime interval
|
|
pResult->SetDefined( false );
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
5.8.3 Specification for operator ~atinstant~
|
|
|
|
*/
|
|
const std::string
|
|
TemporalSpecAtInstant =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>(uT instant) -> iT\n"
|
|
"(T in {bool, int, real, string, point, region})</text--->"
|
|
"<text>_ atinstant _ </text--->"
|
|
"<text>From a unit type, get the Intime value corresponding to "
|
|
"the given instant.</text--->"
|
|
"<text>upoint1 atinstant instant1</text---> ) )";
|
|
|
|
/*
|
|
5.8.4 Selection Function of operator ~atinstant~
|
|
|
|
Uses ~UnitSimpleSelect~.
|
|
|
|
*/
|
|
|
|
|
|
|
|
ValueMapping temporalunitatinstantmap[] =
|
|
{MappingUnitAtInstant<UBool, CcBool>,
|
|
MappingUnitAtInstant<UInt, CcInt>,
|
|
MappingUnitAtInstant<UReal, CcReal>,
|
|
MappingUnitAtInstant<UPoint, Point>,
|
|
MappingUnitAtInstant<UString, CcString>,
|
|
MappingUnitAtInstant<URegion, Region>};
|
|
|
|
|
|
/*
|
|
5.8.5 Definition of operator ~atinstant~
|
|
|
|
*/
|
|
Operator temporalunitatinstant( "atinstant",
|
|
TemporalSpecAtInstant,
|
|
6,
|
|
temporalunitatinstantmap,
|
|
UnitSimpleSelect,
|
|
UnitInstantTypeMapIntime );
|
|
|
|
/*
|
|
5.9 Operator ~atperiods~
|
|
|
|
5.9.1 Type Mapping for ~atperiods~
|
|
|
|
*/
|
|
ListExpr
|
|
UnitPeriodsTypeMap( ListExpr args )
|
|
{
|
|
ListExpr arg1, arg2;
|
|
std::string argstr;
|
|
|
|
if ( nl->ListLength( args ) != 2 )
|
|
{
|
|
ErrorReporter::ReportError("Operator atperiods expects "
|
|
"a list of length 2.");
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
|
}
|
|
|
|
arg1 = nl->First( args );
|
|
arg2 = nl->Second( args );
|
|
|
|
nl->WriteToString(argstr, arg2);
|
|
if ( !( nl->IsEqual( arg2, Periods::BasicType() ) ) )
|
|
{
|
|
ErrorReporter::ReportError("Operator atperiods expects a second argument"
|
|
" of type 'periods' but gets '" + argstr + "'.");
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
|
}
|
|
|
|
if( nl->IsAtom( arg1 ) )
|
|
{
|
|
if( nl->IsEqual( arg1, UBool::BasicType() ) )
|
|
return nl->TwoElemList(nl->SymbolAtom(Symbol::STREAM()),
|
|
nl->SymbolAtom(UBool::BasicType()));
|
|
if( nl->IsEqual( arg1, UInt::BasicType() ) )
|
|
return nl->TwoElemList(nl->SymbolAtom(Symbol::STREAM()),
|
|
nl->SymbolAtom(UInt::BasicType()));
|
|
if( nl->IsEqual( arg1, UReal::BasicType() ) )
|
|
return nl->TwoElemList(nl->SymbolAtom(Symbol::STREAM()),
|
|
nl->SymbolAtom(UReal::BasicType()));
|
|
if( nl->IsEqual( arg1, UPoint::BasicType() ) )
|
|
return nl->TwoElemList(nl->SymbolAtom(Symbol::STREAM()),
|
|
nl->SymbolAtom(UPoint::BasicType()));
|
|
if( nl->IsEqual( arg1, UString::BasicType() ) )
|
|
return nl->TwoElemList(nl->SymbolAtom(Symbol::STREAM()),
|
|
nl->SymbolAtom(UString::BasicType()));
|
|
if( nl->IsEqual( arg1, URegion::BasicType() ) )
|
|
return nl->TwoElemList(nl->SymbolAtom(Symbol::STREAM()),
|
|
nl->SymbolAtom(URegion::BasicType()));
|
|
|
|
nl->WriteToString(argstr, arg1);
|
|
ErrorReporter::ReportError("Operator atperiods expects a first argument "
|
|
"of type T in {ubool, uint, ureal, upoint, "
|
|
"ustring, uregion} but gets a '"
|
|
+ argstr + "'.");
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
|
}
|
|
|
|
|
|
if(!Stream<ANY>::checkType(arg1)){
|
|
return listutils::typeError("Operator atperiods expects as first "
|
|
"argument a list with structure 'T' or "
|
|
"'stream(T)', T in {ubool, uint, ureal, "
|
|
"upoint, ustring, ureagion} but gets a "
|
|
"list with structure '" + argstr + "'.");
|
|
}
|
|
|
|
|
|
if( nl->IsEqual( nl->Second(arg1), UBool::BasicType() ) )
|
|
return nl->TwoElemList(nl->SymbolAtom(Symbol::STREAM()),
|
|
nl->SymbolAtom(UBool::BasicType()));
|
|
if( nl->IsEqual( nl->Second(arg1), UInt::BasicType() ) )
|
|
return nl->TwoElemList(nl->SymbolAtom(Symbol::STREAM()),
|
|
nl->SymbolAtom(UInt::BasicType()));
|
|
if( nl->IsEqual( nl->Second(arg1), UReal::BasicType() ) )
|
|
return nl->TwoElemList(nl->SymbolAtom(Symbol::STREAM()),
|
|
nl->SymbolAtom(UReal::BasicType()));
|
|
if( nl->IsEqual( nl->Second(arg1), UPoint::BasicType() ) )
|
|
return nl->TwoElemList(nl->SymbolAtom(Symbol::STREAM()),
|
|
nl->SymbolAtom(UPoint::BasicType()));
|
|
if( nl->IsEqual( nl->Second(arg1), UString::BasicType() ) )
|
|
return nl->TwoElemList(nl->SymbolAtom(Symbol::STREAM()),
|
|
nl->SymbolAtom(UString::BasicType()));
|
|
if( nl->IsEqual( nl->Second(arg1), URegion::BasicType() ) )
|
|
return nl->TwoElemList(nl->SymbolAtom(Symbol::STREAM()),
|
|
nl->SymbolAtom(URegion::BasicType()));
|
|
|
|
nl->WriteToString(argstr, nl->Second(arg1));
|
|
ErrorReporter::ReportError("Operator atperiods expects a type "
|
|
"(stream T); T in {ubool, uint, ureal, upoint, "
|
|
"ustring, uregion} but gets '(stream "
|
|
+ argstr + ")'.");
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
|
}
|
|
|
|
/*
|
|
5.9.2 Value Mapping for ~atperiods~
|
|
|
|
*/
|
|
struct AtPeriodsLocalInfo
|
|
{
|
|
Word uWord; // the address of the unit value
|
|
Word pWord; // the adress of the periods value
|
|
int j; // save the number of the interval
|
|
};
|
|
|
|
/*
|
|
Variant 1: first argument is a scalar value
|
|
|
|
*/
|
|
|
|
template <class Alpha>
|
|
int MappingUnitAtPeriods( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
AtPeriodsLocalInfo *localinfo;
|
|
Interval<Instant> interval;
|
|
Alpha *unit;
|
|
Alpha r(true);
|
|
Periods* periods;
|
|
|
|
switch( message )
|
|
{
|
|
case OPEN:
|
|
|
|
// #ifdef TUA_DEBUG
|
|
// cout << "\nMappingUnitAtPeriods: OPEN" << endl;
|
|
// #endif
|
|
|
|
localinfo = new AtPeriodsLocalInfo;
|
|
localinfo->uWord = args[0];
|
|
localinfo->pWord = args[1];
|
|
localinfo->j = 0;
|
|
local.setAddr(localinfo);
|
|
return 0;
|
|
|
|
case REQUEST:
|
|
|
|
// #ifdef TUA_DEBUG
|
|
// cout << "\nMappingUnitAtPeriods: REQUEST" << endl;
|
|
// #endif
|
|
if( local.addr == 0 )
|
|
return CANCEL;
|
|
localinfo = (AtPeriodsLocalInfo *)local.addr;
|
|
unit = (Alpha*)localinfo->uWord.addr;
|
|
periods = (Periods*)localinfo->pWord.addr;
|
|
|
|
if( !unit->IsDefined() ||
|
|
!periods->IsDefined() ||
|
|
periods->IsEmpty() )
|
|
{
|
|
result.setAddr(0);
|
|
return CANCEL;
|
|
}
|
|
// #ifdef TUA_DEBUG
|
|
// cout << " Unit's timeInterval u="
|
|
// << TUPrintTimeInterval( unit->timeInterval ) << endl;
|
|
// #endif
|
|
if( localinfo->j >= periods->GetNoComponents() )
|
|
{
|
|
result.setAddr(0);
|
|
// #ifdef TUA_DEBUG
|
|
// cout << "Maquery train7 inside train7sectionsppingUnitAtPeriods: "
|
|
// << "REQUEST finished: CANCEL (1)"
|
|
// << endl;
|
|
// #endif
|
|
return CANCEL;
|
|
}
|
|
periods->Get( localinfo->j, interval );
|
|
localinfo->j++;
|
|
// #ifdef TUA_DEBUG
|
|
// cout << " Probing timeInterval p ="
|
|
// << TUPrintTimeInterval(interval)
|
|
// << endl;
|
|
// #endif
|
|
while( interval.Before( unit->timeInterval ) &&
|
|
localinfo->j < periods->GetNoComponents() )
|
|
{ // forward to first candidate interval
|
|
periods->Get(localinfo->j, interval);
|
|
localinfo->j++;
|
|
// #ifdef TUA_DEBUG
|
|
// cout << " Probing timeInterval="
|
|
// << TUPrintTimeInterval(interval)
|
|
// << endl;
|
|
// if (interval.Before( unit->timeInterval ))
|
|
// cout << " p is before u" << endl;
|
|
// if (localinfo->j < periods->GetNoComponents())
|
|
// cout << " j < #Intervals" << endl;
|
|
// #endif
|
|
}
|
|
|
|
if( unit->timeInterval.Before( interval ) )
|
|
{ // interval after unit-deftime --> finished
|
|
result.addr = 0;
|
|
// #ifdef TUA_DEBUG
|
|
// cout << "MappingUnitAtPeriods: REQUEST finished: CANCEL (2)"
|
|
// << endl;
|
|
// #endif
|
|
return CANCEL;
|
|
}
|
|
|
|
if(unit->timeInterval.Intersects( interval ))
|
|
{ // interval intersectd unit's deftime --> produce result
|
|
// create unit restricted to interval
|
|
unit->AtInterval( interval, r );
|
|
Alpha* aux = new Alpha( r );
|
|
result.setAddr( aux );
|
|
// #ifdef TUA_DEBUG
|
|
// cout << " Result interval="
|
|
// << TUPrintTimeInterval(aux->timeInterval)
|
|
// << endl;
|
|
// cout << " Result defined=" << aux->IsDefined()
|
|
// << endl;
|
|
// cout << "MappingUnitAtPeriods: REQUEST finished: YIELD"
|
|
// << endl;
|
|
// #endif
|
|
return YIELD;
|
|
}
|
|
|
|
if( localinfo->j >= periods->GetNoComponents() )
|
|
{ // Passed last interval --> finished
|
|
result.addr = 0;
|
|
// #ifdef TUA_DEBUG
|
|
// cout << "MappingUnitAtPeriods: REQUEST finished: CANCEL (3)"
|
|
// << endl;
|
|
// #endif
|
|
return CANCEL;
|
|
}
|
|
|
|
result.setAddr(0 );
|
|
cout << "MappingUnitAtPeriods: REQUEST finished: CANCEL (4)"
|
|
<< endl;
|
|
cout << "Intervals should overlap: " << endl;
|
|
cout << " Unit's timeInterval = ";
|
|
TUPrintTimeInterval(unit->timeInterval);
|
|
cout << " Current Period's interval = ";
|
|
TUPrintTimeInterval(interval);
|
|
cout << endl;
|
|
assert( false );
|
|
return CANCEL; // should not happen
|
|
|
|
case CLOSE:
|
|
|
|
if( local.addr != 0 )
|
|
{
|
|
delete (AtPeriodsLocalInfo *)local.addr;
|
|
local.setAddr(Address(0));
|
|
}
|
|
return 0;
|
|
}
|
|
// should not happen:
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
Variant 2: first argument is a stream
|
|
Implemented on 07/17/2006 by Christian D[ue]ntgen
|
|
|
|
*/
|
|
|
|
struct AtPeriodsLocalInfoUS
|
|
{
|
|
Word uWord; // address of the input stream
|
|
Word pWord; // address of the input periods value
|
|
int j; // interval counter for within periods
|
|
};
|
|
|
|
|
|
template <class Alpha>
|
|
int MappingUnitStreamAtPeriods( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
AtPeriodsLocalInfoUS *localinfo;
|
|
Alpha *unit, *aux;
|
|
Alpha resultUnit(true);
|
|
Periods *periods;
|
|
Interval<Instant> interval;
|
|
bool foundUnit = false;
|
|
|
|
switch( message )
|
|
{
|
|
case OPEN:
|
|
localinfo = new AtPeriodsLocalInfoUS;
|
|
localinfo->pWord = args[1];
|
|
localinfo->j = 0; // init interval counter
|
|
qp->Open( args[0].addr ); // open stream of units
|
|
qp->Request( args[0].addr, localinfo->uWord ); // request first unit
|
|
if ( !( qp->Received( args[0].addr) ) ){
|
|
localinfo->uWord.addr = 0;
|
|
result.addr = 0;
|
|
return CANCEL;
|
|
}
|
|
local.setAddr(localinfo); // pass up link to localinfo
|
|
return 0;
|
|
|
|
case REQUEST:
|
|
if ( local.addr == 0 )
|
|
return CANCEL;
|
|
localinfo = (AtPeriodsLocalInfoUS *) local.addr; // restore local data
|
|
if ( localinfo->uWord.addr == 0 ) { result.addr = 0; return CANCEL; }
|
|
unit = (Alpha *) localinfo->uWord.addr;
|
|
if ( localinfo->pWord.addr == 0 ) { result.addr = 0; return CANCEL; }
|
|
periods = (Periods *) localinfo->pWord.addr;
|
|
|
|
if( !periods->IsDefined() || periods->IsEmpty() )
|
|
return CANCEL;
|
|
|
|
// search for a pair of overlapping unit/interval:
|
|
while (1){
|
|
if ( localinfo->j == periods->GetNoComponents() ){// redo first interval
|
|
localinfo->j = 0;
|
|
unit->DeleteIfAllowed(); // delete original unit?
|
|
localinfo->uWord.addr = 0;
|
|
foundUnit = false;
|
|
while(!foundUnit){
|
|
qp->Request(args[0].addr, localinfo->uWord); // get new unit
|
|
if( qp->Received( args[0].addr ) )
|
|
unit = (Alpha *) localinfo->uWord.addr;
|
|
else {
|
|
localinfo->uWord.addr = 0;
|
|
result.addr = 0;
|
|
return CANCEL;
|
|
} // end of unit stream
|
|
foundUnit = unit->IsDefined();
|
|
}
|
|
}
|
|
periods->Get(localinfo->j, interval); // get an interval
|
|
if ( !( interval.Before( unit->timeInterval ) )
|
|
&& !( unit->timeInterval.Before( interval) ) )
|
|
break; // found candidate, break while
|
|
localinfo->j++; // next interval, loop
|
|
}
|
|
|
|
// We have an interval overlapping the unit's interval now
|
|
// Return unit restricted to overlapping part of both intervals
|
|
if (!unit->timeInterval.Intersects( interval) ){ // This may not happen!
|
|
cout << __FILE__ << __LINE__ << __PRETTY_FUNCTION__
|
|
<< ": Intervals do not overlap, but should do so:" << endl;
|
|
cout << " Unit's timeInterval = ";
|
|
TUPrintTimeInterval(unit->timeInterval);
|
|
cout << endl << " Current Period's interval = ";
|
|
TUPrintTimeInterval(interval);
|
|
cout << endl;
|
|
assert(false);
|
|
}
|
|
unit->AtInterval( interval, resultUnit); // intersect unit and interval
|
|
aux = new Alpha( resultUnit );
|
|
result.setAddr( aux );
|
|
localinfo->j++; // increase interval counter
|
|
return YIELD;
|
|
|
|
case CLOSE:
|
|
if ( local.addr != 0 )
|
|
{
|
|
qp->Close( args[0].addr );
|
|
localinfo = (AtPeriodsLocalInfoUS *) local.addr;
|
|
if ( localinfo->uWord.addr != 0 )
|
|
{
|
|
unit = (Alpha *) localinfo->uWord.addr;
|
|
unit->DeleteIfAllowed(); // delete remaining original unit
|
|
}
|
|
delete (AtPeriodsLocalInfoUS *)localinfo;
|
|
local.setAddr(Address(0));
|
|
}
|
|
return 0;
|
|
|
|
} // end switch
|
|
|
|
return -1; // should never be reached
|
|
|
|
} // end MappingUnitStreamAtPeriods
|
|
|
|
/*
|
|
5.9.3 Specification for operator ~atperiods~
|
|
|
|
*/
|
|
const std::string
|
|
TemporalSpecAtPeriods =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\") "
|
|
"( <text>For T in {int, bool, real, string, point, region}:\n"
|
|
"(uT periods) -> stream uT\n"
|
|
"((stream uT) periods) -> stream uT</text--->"
|
|
"<text>_ atperiods _ </text--->"
|
|
"<text>restrict the movement to the given"
|
|
" periods.</text--->"
|
|
"<text>upoint1 atperiods thehour(2003,11,11,8)\n"
|
|
"sfeed(upoint1) atperiods thehour(2003,11,11,8)</text--->) )";
|
|
|
|
/*
|
|
5.9.4 Selection Function of operator ~atperiods~
|
|
|
|
Uses ~UnitCombinedUnitStreamSelect~.
|
|
|
|
*/
|
|
|
|
ValueMapping temporalunitatperiodsmap[] =
|
|
{ MappingUnitAtPeriods<UBool>,
|
|
MappingUnitAtPeriods<UInt>,
|
|
MappingUnitAtPeriods<UReal>,
|
|
MappingUnitAtPeriods<UPoint>,
|
|
MappingUnitAtPeriods<UString>,
|
|
MappingUnitAtPeriods<URegion>,
|
|
MappingUnitStreamAtPeriods<UBool>,
|
|
MappingUnitStreamAtPeriods<UInt>,
|
|
MappingUnitStreamAtPeriods<UReal>,
|
|
MappingUnitStreamAtPeriods<UPoint>,
|
|
MappingUnitStreamAtPeriods<UString>,
|
|
MappingUnitStreamAtPeriods<URegion>
|
|
};
|
|
|
|
/*
|
|
5.9.5 Definition of operator ~atperiods~
|
|
|
|
*/
|
|
Operator temporalunitatperiods( "atperiods",
|
|
TemporalSpecAtPeriods,
|
|
12,
|
|
temporalunitatperiodsmap,
|
|
UnitCombinedUnitStreamSelect,
|
|
UnitPeriodsTypeMap );
|
|
|
|
/*
|
|
5.10 Operators ~initial~ and ~final~
|
|
|
|
5.10.1 Type Mapping for ~initial~ and ~final~
|
|
|
|
Signatures
|
|
|
|
----
|
|
For T in {bool, int, real, string, point, region}:
|
|
|
|
( uT) --> iT
|
|
(stream uT) --> iT
|
|
|
|
----
|
|
|
|
|
|
*/
|
|
ListExpr
|
|
UnitTypeMapIntime( ListExpr args )
|
|
{
|
|
ListExpr t;
|
|
|
|
if ( nl->ListLength( args ) == 1 )
|
|
{
|
|
if (nl->IsAtom(nl->First(args)))
|
|
t = nl->First( args );
|
|
else if (nl->ListLength(nl->First(args))==2 &&
|
|
nl->IsEqual(nl->First(nl->First(args)), Symbol::STREAM()))
|
|
t = nl->Second(nl->First(args));
|
|
else
|
|
{
|
|
ErrorReporter::ReportError
|
|
("Operator initial/final expects a (stream T)"
|
|
"for T in {bool,int,real,string,point,region}");
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
|
}
|
|
|
|
if( nl->IsEqual( t, UBool::BasicType() ) )
|
|
return nl->SymbolAtom( IBool::BasicType() );
|
|
|
|
if( nl->IsEqual( t, UInt::BasicType() ) )
|
|
return nl->SymbolAtom( IInt::BasicType() );
|
|
|
|
if( nl->IsEqual( t, UReal::BasicType() ) )
|
|
return nl->SymbolAtom( IReal::BasicType() );
|
|
|
|
if( nl->IsEqual( t, UPoint::BasicType() ) )
|
|
return nl->SymbolAtom( IPoint::BasicType() );
|
|
|
|
if( nl->IsEqual( t, UString::BasicType() ) )
|
|
return nl->SymbolAtom( IString::BasicType() );
|
|
|
|
if( nl->IsEqual( t, URegion::BasicType() ) )
|
|
return nl->SymbolAtom( IRegion::BasicType() );
|
|
}
|
|
else
|
|
ErrorReporter::ReportError
|
|
("Operator initial/final expects a list of length one, "
|
|
"containing a value of one type 'T' with T in "
|
|
"{bool,int,real,string,point,region}");
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
|
}
|
|
|
|
/*
|
|
5.10.2 Value Mapping for ~initial~ and ~final~
|
|
|
|
*/
|
|
|
|
// first come the value mappings for (UNIT) argument
|
|
template <class Unit, class Alpha>
|
|
int MappingUnitInitial( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
result = qp->ResultStorage( s );
|
|
|
|
Unit* unit = ((Unit*)args[0].addr);
|
|
Intime<Alpha>* res = ((Intime<Alpha>*)result.addr);
|
|
|
|
if( !unit->IsDefined() || !(unit->timeInterval.start.IsDefined()) )
|
|
res->SetDefined( false );
|
|
else
|
|
{
|
|
unit->TemporalFunction( unit->timeInterval.start, res->value, true );
|
|
res->instant.CopyFrom( &unit->timeInterval.start );
|
|
res->SetDefined( true );
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
template <class Unit, class Alpha>
|
|
int MappingUnitFinal( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
result = qp->ResultStorage( s );
|
|
|
|
Unit *unit = ((Unit*)args[0].addr);
|
|
Intime<Alpha> *res = ((Intime<Alpha>*)result.addr);
|
|
|
|
if( !unit->IsDefined() || !(unit->timeInterval.end.IsDefined()) )
|
|
res->SetDefined( false );
|
|
else
|
|
{
|
|
unit->TemporalFunction( unit->timeInterval.end, res->value, true );
|
|
res->instant.CopyFrom( &unit->timeInterval.end );
|
|
res->SetDefined( true );
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//now, we give the value mappings for (stream UNIT) argument
|
|
// Mode=0 for initial, Mode=1 for final
|
|
template <class Unit, class Alpha, int Mode>
|
|
int MappingUnitStreamInstantFinal( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
assert(Mode>=0 && Mode<=1);
|
|
result = qp->ResultStorage( s );
|
|
Word elem;
|
|
Unit *U = 0, *SavedUnit = 0;
|
|
Intime<Alpha> *I = ((Intime<Alpha>*)result.addr);
|
|
|
|
qp->Open(args[0].addr); // get first elem from stream
|
|
qp->Request(args[0].addr, elem); // get first elem from stream
|
|
while ( qp->Received(args[0].addr) ) // there is a element from the stream
|
|
{
|
|
U = (Unit*) elem.addr;
|
|
if ( U->IsDefined() )
|
|
{
|
|
if (SavedUnit == 0)
|
|
SavedUnit = U;
|
|
else
|
|
{
|
|
if(Mode == 0)
|
|
{ // initial-mode
|
|
if ( U->timeInterval.start < SavedUnit->timeInterval.start)
|
|
{
|
|
SavedUnit->DeleteIfAllowed();
|
|
SavedUnit = U;
|
|
}
|
|
else
|
|
U->DeleteIfAllowed();
|
|
}
|
|
else // (Mode == 1)
|
|
{ // final-mode
|
|
if ( U->timeInterval.end > SavedUnit->timeInterval.end)
|
|
{
|
|
SavedUnit->DeleteIfAllowed();
|
|
SavedUnit = U;
|
|
}
|
|
else
|
|
{
|
|
U->DeleteIfAllowed();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
U->DeleteIfAllowed();
|
|
qp->Request(args[0].addr, elem); // get next stream elem
|
|
}
|
|
qp->Close(args[0].addr); // close the stream
|
|
|
|
// create and return the result
|
|
if (SavedUnit == 0)
|
|
I->SetDefined(false);
|
|
else
|
|
if(Mode == 0)
|
|
{ // initial-mode
|
|
SavedUnit->TemporalFunction
|
|
( SavedUnit->timeInterval.start, I->value, true );
|
|
I->instant.CopyFrom( &SavedUnit->timeInterval.start );
|
|
I->SetDefined( true );
|
|
SavedUnit->DeleteIfAllowed();
|
|
}
|
|
else // (Mode == 1)
|
|
{ // final-mode
|
|
SavedUnit->TemporalFunction
|
|
( SavedUnit->timeInterval.end, I->value, true );
|
|
I->instant.CopyFrom( &SavedUnit->timeInterval.end );
|
|
I->SetDefined( true );
|
|
SavedUnit->DeleteIfAllowed();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
5.10.3 Specification for operator ~initial~ and ~final~
|
|
|
|
*/
|
|
const std::string
|
|
TemporalSpecInitial =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>( uT) -> iT\n"
|
|
"(stream uT) -> iT\n"
|
|
"(T in {bool, int, real, string, point, region})</text--->"
|
|
"<text>initial( _ )</text--->"
|
|
"<text>From a unit type (or a stream of units), get the "
|
|
"intime value corresponding to the (overall) initial instant.</text--->"
|
|
"<text>initial( upoint1 )</text---> ) )";
|
|
|
|
const std::string
|
|
TemporalSpecFinal =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>) uT) -> iT\n"
|
|
"(stream uT) -> iT\n"
|
|
"(T in {bool, int, real, string, point, region})</text--->"
|
|
"<text>final( _ )</text--->"
|
|
"<text>get the intime value corresponding "
|
|
"to the (overall) final instant of the (stream of) unit.</text--->"
|
|
"<text>final( upoint1 )</text---> ) )";
|
|
|
|
/*
|
|
5.10.4 Selection Function of operator ~initial~ and ~final~
|
|
|
|
Using ~UnitCombinedUnitStreamSelect~.
|
|
|
|
*/
|
|
|
|
ValueMapping temporalunitinitialmap[] = {
|
|
MappingUnitInitial<UBool, CcBool>,
|
|
MappingUnitInitial<UInt, CcInt>,
|
|
MappingUnitInitial<UReal, CcReal>,
|
|
MappingUnitInitial<UPoint, Point>,
|
|
MappingUnitInitial<UString, CcString>,
|
|
MappingUnitInitial<URegion, Region>,
|
|
MappingUnitStreamInstantFinal<UBool, CcBool, 0>,
|
|
MappingUnitStreamInstantFinal<UInt, CcInt, 0>,
|
|
MappingUnitStreamInstantFinal<UReal, CcReal, 0>,
|
|
MappingUnitStreamInstantFinal<UPoint, Point, 0>,
|
|
MappingUnitStreamInstantFinal<UString, CcString, 0>,
|
|
MappingUnitStreamInstantFinal<URegion, Region, 0>
|
|
};
|
|
|
|
ValueMapping temporalunitfinalmap[] = {
|
|
MappingUnitFinal<UBool, CcBool>,
|
|
MappingUnitFinal<UInt, CcInt>,
|
|
MappingUnitFinal<UReal, CcReal>,
|
|
MappingUnitFinal<UPoint, Point>,
|
|
MappingUnitFinal<UString, CcString>,
|
|
MappingUnitFinal<URegion, Region>,
|
|
MappingUnitStreamInstantFinal<UBool, CcBool, 1>,
|
|
MappingUnitStreamInstantFinal<UInt, CcInt, 1>,
|
|
MappingUnitStreamInstantFinal<UReal, CcReal, 1>,
|
|
MappingUnitStreamInstantFinal<UPoint, Point, 1>,
|
|
MappingUnitStreamInstantFinal<UString, CcString, 1>,
|
|
MappingUnitStreamInstantFinal<URegion, Region, 1>
|
|
};
|
|
|
|
/*
|
|
5.10.5 Definition of operator ~initial~ and ~final~
|
|
|
|
*/
|
|
Operator temporalunitinitial
|
|
(
|
|
"initial",
|
|
TemporalSpecInitial,
|
|
12,
|
|
temporalunitinitialmap,
|
|
UnitCombinedUnitStreamSelect,
|
|
UnitTypeMapIntime );
|
|
|
|
Operator temporalunitfinal
|
|
(
|
|
"final",
|
|
TemporalSpecFinal,
|
|
12,
|
|
temporalunitfinalmap,
|
|
UnitCombinedUnitStreamSelect,
|
|
UnitTypeMapIntime );
|
|
|
|
/*
|
|
5.11 Operator ~present~
|
|
|
|
5.11.1 Type Mapping for ~present~
|
|
|
|
*/
|
|
ListExpr
|
|
UnitInstantPeriodsTypeMapBool( ListExpr args )
|
|
{
|
|
if ( nl->ListLength( args ) == 2 )
|
|
{
|
|
ListExpr arg1 = nl->First( args ),
|
|
arg2 = nl->Second( args );
|
|
|
|
if( nl->IsEqual( arg2, Instant::BasicType() ) ||
|
|
nl->IsEqual( arg2, Periods::BasicType() ) )
|
|
{
|
|
if( nl->IsEqual( arg1, UBool::BasicType() ) ||
|
|
nl->IsEqual( arg1, UInt::BasicType() ) ||
|
|
nl->IsEqual( arg1, UReal::BasicType() ) ||
|
|
nl->IsEqual( arg1, UPoint::BasicType()) ||
|
|
nl->IsEqual( arg1, UString::BasicType()) ||
|
|
nl->IsEqual( arg1, URegion::BasicType()) )
|
|
|
|
return nl->SymbolAtom( CcBool::BasicType() );
|
|
}
|
|
}
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
|
}
|
|
|
|
/*
|
|
5.11.2 Value Mapping for ~present~
|
|
|
|
*/
|
|
|
|
template <class Unit>
|
|
int MappingUnitPresent_i( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
result = qp->ResultStorage( s );
|
|
Unit *m = ((Unit*)args[0].addr);
|
|
Instant* inst = ((Instant*)args[1].addr);
|
|
Instant t1 = *inst;
|
|
|
|
if ( !inst->IsDefined() || !m->IsDefined() )
|
|
((CcBool *)result.addr)->Set( false, false );
|
|
else
|
|
((CcBool *)result.addr)->Set( true, m->timeInterval.Contains(t1) );
|
|
return 0;
|
|
}
|
|
|
|
template <class Unit>
|
|
int MappingUnitPresent_p( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
result = qp->ResultStorage( s );
|
|
|
|
Unit *m = ((Unit*)args[0].addr);
|
|
Periods* periods = ((Periods*)args[1].addr);
|
|
|
|
if ( !m->IsDefined() || !periods->IsDefined() || periods->IsEmpty() )
|
|
{
|
|
((CcBool *)result.addr)->Set( false, false );
|
|
return 0;
|
|
}
|
|
|
|
// create a periods containing the smallest superinterval
|
|
// of all intervals within the periods value.
|
|
Periods deftime( 1 );
|
|
deftime.Clear();
|
|
deftime.SetDefined( true );
|
|
deftime.StartBulkLoad();
|
|
deftime.Add( m->timeInterval );
|
|
deftime.EndBulkLoad( false );
|
|
((CcBool *)result.addr)->Set( true, periods->Intersects( deftime ) );
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
5.11.3 Specification for operator ~present~
|
|
|
|
*/
|
|
const std::string
|
|
TemporalSpecPresent =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>({m|u}T instant) -> bool\n"
|
|
"({m|u}T periods) -> bool\n"
|
|
"(T in {bool, int, real, string, point, region)</text--->"
|
|
"<text>_ present _ </text--->"
|
|
"<text>whether the moving/unit object is present at the"
|
|
" given instant or period. For an empty or undefines periods value, "
|
|
"the result is undefined.</text--->"
|
|
"<text>mpoint1 present instant1</text---> ) )";
|
|
|
|
/*
|
|
5.11.4 Selection Function of operator ~present~
|
|
|
|
*/
|
|
|
|
int
|
|
UnitInstantPeriodsSelect( ListExpr args )
|
|
{
|
|
ListExpr arg1 = nl->First( args ),
|
|
arg2 = nl->Second( args );
|
|
|
|
// instant versions:
|
|
|
|
if( nl->SymbolValue( arg1 ) == UBool::BasicType() &&
|
|
nl->SymbolValue( arg2 ) == Instant::BasicType() )
|
|
return 0;
|
|
|
|
if( nl->SymbolValue( arg1 ) == UInt::BasicType() &&
|
|
nl->SymbolValue( arg2 ) == Instant::BasicType() )
|
|
return 1;
|
|
|
|
if( nl->SymbolValue( arg1 ) == UReal::BasicType() &&
|
|
nl->SymbolValue( arg2 ) == Instant::BasicType() )
|
|
return 2;
|
|
|
|
if( nl->SymbolValue( arg1 ) == UPoint::BasicType() &&
|
|
nl->SymbolValue( arg2 ) == Instant::BasicType() )
|
|
return 3;
|
|
|
|
if( nl->SymbolValue( arg1 ) == UString::BasicType() &&
|
|
nl->SymbolValue( arg2 ) == Instant::BasicType() )
|
|
return 4;
|
|
|
|
if( nl->SymbolValue( arg1 ) == URegion::BasicType() &&
|
|
nl->SymbolValue( arg2 ) == Instant::BasicType() )
|
|
return 5;
|
|
|
|
// periods versions:
|
|
|
|
if( nl->SymbolValue( arg1 ) == UBool::BasicType() &&
|
|
nl->SymbolValue( arg2 ) == Periods::BasicType() )
|
|
return 6;
|
|
|
|
if( nl->SymbolValue( arg1 ) == UInt::BasicType() &&
|
|
nl->SymbolValue( arg2 ) == Periods::BasicType() )
|
|
return 7;
|
|
|
|
if( nl->SymbolValue( arg1 ) == UReal::BasicType() &&
|
|
nl->SymbolValue( arg2 ) == Periods::BasicType() )
|
|
return 8;
|
|
|
|
if( nl->SymbolValue( arg1 ) == UPoint::BasicType() &&
|
|
nl->SymbolValue( arg2 ) == Periods::BasicType() )
|
|
return 9;
|
|
|
|
if( nl->SymbolValue( arg1 ) == UString::BasicType() &&
|
|
nl->SymbolValue( arg2 ) == Periods::BasicType() )
|
|
return 10;
|
|
|
|
if( nl->SymbolValue( arg1 ) == URegion::BasicType() &&
|
|
nl->SymbolValue( arg2 ) == Periods::BasicType() )
|
|
return 11;
|
|
|
|
|
|
return -1; // This point should never be reached
|
|
}
|
|
|
|
ValueMapping temporalunitpresentmap[] = { MappingUnitPresent_i<UBool>,
|
|
MappingUnitPresent_i<UInt>,
|
|
MappingUnitPresent_i<UReal>,
|
|
MappingUnitPresent_i<UPoint>,
|
|
MappingUnitPresent_i<UString>,
|
|
MappingUnitPresent_i<URegion>,
|
|
MappingUnitPresent_p<UBool>,
|
|
MappingUnitPresent_p<UInt>,
|
|
MappingUnitPresent_p<UReal>,
|
|
MappingUnitPresent_p<UPoint>,
|
|
MappingUnitPresent_p<UString>,
|
|
MappingUnitPresent_p<URegion> };
|
|
|
|
/*
|
|
5.11.5 Definition of operator ~present~
|
|
|
|
*/
|
|
Operator temporalunitpresent( "present",
|
|
TemporalSpecPresent,
|
|
12,
|
|
temporalunitpresentmap,
|
|
UnitInstantPeriodsSelect,
|
|
UnitInstantPeriodsTypeMapBool);
|
|
|
|
/*
|
|
5.12 Operator ~passes~
|
|
|
|
5.12.1 Type Mapping for ~passes~
|
|
|
|
*/
|
|
ListExpr
|
|
UnitBaseTypeMapBool( ListExpr args )
|
|
{
|
|
ListExpr arg1, arg2;
|
|
if( nl->ListLength( args ) == 2 )
|
|
{
|
|
arg1 = nl->First( args );
|
|
arg2 = nl->Second( args );
|
|
|
|
if( ((nl->IsEqual( arg1, UPoint::BasicType() )
|
|
&& nl->IsEqual( arg2, Point::BasicType() ))) )
|
|
return nl->SymbolAtom( CcBool::BasicType() );
|
|
if( ((nl->IsEqual( arg1, UInt::BasicType() )
|
|
&& nl->IsEqual( arg2, CcInt::BasicType() ))) )
|
|
return nl->SymbolAtom( CcBool::BasicType() );
|
|
if( ((nl->IsEqual( arg1, UBool::BasicType() )
|
|
&& nl->IsEqual( arg2, CcBool::BasicType() ))) )
|
|
return nl->SymbolAtom( CcBool::BasicType() );
|
|
if( ((nl->IsEqual( arg1, UReal::BasicType() )
|
|
&& nl->IsEqual( arg2, CcReal::BasicType() ))) )
|
|
return nl->SymbolAtom( CcBool::BasicType() );
|
|
if( ((nl->IsEqual( arg1, UString::BasicType() )
|
|
&& nl->IsEqual( arg2, CcString::BasicType() ))) )
|
|
return nl->SymbolAtom( CcBool::BasicType() );
|
|
if( ((nl->IsEqual( arg1, URegion::BasicType() )
|
|
&& nl->IsEqual( arg2, Point::BasicType() ))) )
|
|
return nl->SymbolAtom( CcBool::BasicType() );
|
|
if( ((nl->IsEqual( arg1, UPoint::BasicType() )
|
|
&& nl->IsEqual( arg2, Region::BasicType() ))) )
|
|
return nl->SymbolAtom( CcBool::BasicType() );
|
|
if( ((nl->IsEqual( arg1, UPoint::BasicType() )
|
|
&& nl->IsEqual( arg2, Rectangle<2>::BasicType() ))) )
|
|
return nl->SymbolAtom( CcBool::BasicType() );
|
|
}
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
|
}
|
|
|
|
/*
|
|
5.12.2 Value Mapping for ~passes~
|
|
|
|
*/
|
|
template <class Mapping, class Alpha>
|
|
int MappingUnitPasses( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
result = qp->ResultStorage( s );
|
|
|
|
Mapping *m = ((Mapping*)args[0].addr);
|
|
Alpha* val = ((Alpha*)args[1].addr);
|
|
|
|
if( !val->IsDefined() || !m->IsDefined() )
|
|
((CcBool *)result.addr)->Set( false, false );
|
|
else
|
|
((CcBool *)result.addr)->Set( true, m->Passes( *val ) );
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
5.12.3 Specification for operator ~passes~
|
|
|
|
*/
|
|
const std::string
|
|
TemporalSpecPasses =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>(uT T) -> bool\n"
|
|
"for T in {bool, int, real*, string, point, region*}\n"
|
|
"(*): Not yet implemented</text--->"
|
|
"<text>_ passes _ </text--->"
|
|
"<text>whether the object unit passes the given"
|
|
" value.</text--->"
|
|
"<text>upoint1 passes point1</text---> ) )";
|
|
|
|
/*
|
|
5.12.4 Selection Function of operator ~passes~
|
|
|
|
*/
|
|
int
|
|
TUPassesSelect( ListExpr args )
|
|
{
|
|
ListExpr arg1 = nl->First( args ),
|
|
arg2 = nl->Second( args );
|
|
|
|
if( nl->SymbolValue( arg1 ) == UBool::BasicType() &&
|
|
nl->SymbolValue( arg2 ) == CcBool::BasicType() )
|
|
return 0;
|
|
|
|
if( nl->SymbolValue( arg1 ) == UInt::BasicType() &&
|
|
nl->SymbolValue( arg2 ) == CcInt::BasicType() )
|
|
return 1;
|
|
|
|
if( nl->SymbolValue( arg1 ) == UReal::BasicType() &&
|
|
nl->SymbolValue( arg2 ) == CcReal::BasicType() )
|
|
return 2;
|
|
|
|
if( nl->SymbolValue( arg1 ) == UPoint::BasicType() &&
|
|
nl->SymbolValue( arg2 ) == Point::BasicType() )
|
|
return 3;
|
|
|
|
if( nl->SymbolValue( arg1 ) == UString::BasicType() &&
|
|
nl->SymbolValue( arg2 ) == CcString::BasicType() )
|
|
return 4;
|
|
|
|
if( nl->SymbolValue( arg1 ) == URegion::BasicType() &&
|
|
nl->SymbolValue( arg2 ) == Region::BasicType() )
|
|
return 5;
|
|
|
|
if( nl->SymbolValue( arg1 ) == UPoint::BasicType() &&
|
|
nl->SymbolValue( arg2 ) == Region::BasicType() )
|
|
return 6;
|
|
|
|
if( nl->SymbolValue( arg1 ) == UPoint::BasicType() &&
|
|
nl->SymbolValue( arg2 ) == Rectangle<2>::BasicType() )
|
|
return 7;
|
|
|
|
return -1; // This point should never be reached
|
|
}
|
|
|
|
ValueMapping temporalunitpassesmap[] = {
|
|
MappingUnitPasses<UBool, CcBool>, //0
|
|
MappingUnitPasses<UInt, CcInt>, //1
|
|
MappingUnitPasses<UReal, CcReal>, //2
|
|
MappingUnitPasses<UPoint, Point>, //3
|
|
MappingUnitPasses<UString, CcString>, //4
|
|
MappingUnitPasses<URegion, Region>, //5
|
|
MappingUnitPasses<UPoint, Region>, //6
|
|
MappingUnitPasses<UPoint, Rectangle<2> >}; //7
|
|
|
|
/*
|
|
5.12.5 Definition of operator ~passes~
|
|
|
|
*/
|
|
Operator temporalunitpasses( "passes",
|
|
TemporalSpecPasses,
|
|
8,
|
|
temporalunitpassesmap,
|
|
TUPassesSelect,
|
|
UnitBaseTypeMapBool);
|
|
|
|
|
|
/*
|
|
5.16 Operator ~velocity~
|
|
|
|
Type mapping for ~velocity~ is
|
|
|
|
----
|
|
mpoint -> mpoint
|
|
upoint -> upoint
|
|
|
|
----
|
|
|
|
*/
|
|
ListExpr
|
|
TypeMapVelocity( ListExpr args )
|
|
{
|
|
ListExpr arg1;
|
|
if( nl->ListLength( args ) == 1 )
|
|
{
|
|
arg1 = nl->First( args );
|
|
|
|
if( nl->IsEqual( arg1, MPoint::BasicType() ) )
|
|
return nl->SymbolAtom( MPoint::BasicType() );
|
|
if( nl->IsEqual( arg1, UPoint::BasicType() ) )
|
|
return nl->SymbolAtom( UPoint::BasicType() );
|
|
}
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
|
}
|
|
|
|
/*
|
|
5.16.2 Value Mapping for ~velocity~
|
|
|
|
*/
|
|
int MPointVelocity(Word* args, Word& result, int message,
|
|
Word& local, Supplier s)
|
|
{
|
|
result = (qp->ResultStorage( s ));
|
|
MPoint *res = (MPoint*) result.addr;
|
|
MPoint *input = (MPoint*)args[0].addr;
|
|
input->MVelocity( *res );
|
|
return 0;
|
|
}
|
|
|
|
int UnitPointVelocity(Word* args, Word& result, int message,
|
|
Word& local, Supplier s)
|
|
{
|
|
result = (qp->ResultStorage( s ));
|
|
UPoint *input = (UPoint*)args[0].addr;
|
|
UPoint *res = (UPoint*)result.addr;
|
|
input->UVelocity( *res );
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
5.16.3 Specification for operator ~velocity~
|
|
|
|
*/
|
|
const std::string
|
|
TemporalSpecVelocity=
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>mpoint -> mpoint\n"
|
|
"upoint -> upoint</text--->"
|
|
"<text>velocity ( Obj ) </text--->"
|
|
"<text>describes the vector of the vectorial velocity "
|
|
"of the given temporal spatial object Obj (i.e. the "
|
|
"componentwise speed in unit/s a vector). An undefined argument yields an "
|
|
"undefined result value</text--->"
|
|
"<text>velocity (mpoint)</text---> ) )";
|
|
|
|
/*
|
|
5.16.4 Selection Function of operator ~velocity~
|
|
|
|
*/
|
|
int
|
|
VelocitySelect( ListExpr args )
|
|
{
|
|
ListExpr arg1 = nl->First( args );
|
|
|
|
if( nl->SymbolValue( arg1 ) == MPoint::BasicType())
|
|
return 0;
|
|
|
|
if( nl->SymbolValue( arg1 ) == UPoint::BasicType())
|
|
return 1;
|
|
|
|
return -1; // This point should never be reached
|
|
}
|
|
|
|
ValueMapping temporalvelocitymap[] = { MPointVelocity,
|
|
UnitPointVelocity };
|
|
|
|
/*
|
|
5.16.5 Definition of operator ~velocity~
|
|
|
|
*/
|
|
Operator temporalvelocity( "velocity",
|
|
TemporalSpecVelocity,
|
|
2,
|
|
temporalvelocitymap,
|
|
VelocitySelect,
|
|
TypeMapVelocity);
|
|
|
|
/*
|
|
5.17 Operator ~derivable~
|
|
|
|
5.17.1 Type Mapping for ~derivable~
|
|
|
|
Type mapping for ~derivable~ is
|
|
|
|
---- mreal -> mbool
|
|
|
|
----
|
|
|
|
*/
|
|
ListExpr
|
|
TypeMapDerivable( ListExpr args )
|
|
{
|
|
ListExpr arg1;
|
|
if( nl->ListLength( args ) == 1 )
|
|
{
|
|
arg1 = nl->First( args );
|
|
|
|
if( nl->IsEqual( arg1, MReal::BasicType() ) )
|
|
return nl->SymbolAtom( MBool::BasicType() );
|
|
if( nl->IsEqual( arg1, UReal::BasicType() ) )
|
|
return nl->SymbolAtom( UBool::BasicType() );
|
|
}
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
|
}
|
|
|
|
/*
|
|
5.17.2 Value Mapping for ~derivable~
|
|
|
|
*/
|
|
int MPointDerivable( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
|
|
result = qp->ResultStorage( s );
|
|
MReal* value = (MReal*)args[0].addr;
|
|
MBool* res = ((MBool*)result.addr);
|
|
|
|
UReal uReal;
|
|
CcBool b;
|
|
|
|
res->Clear();
|
|
if ( !value->IsDefined() )
|
|
res->SetDefined(false);
|
|
else
|
|
{
|
|
res->SetDefined(true);
|
|
res->StartBulkLoad();
|
|
for( int i = 0; i < value->GetNoComponents(); i++ )
|
|
{
|
|
value->Get( i, uReal ); // Load a real unit.
|
|
// FALSE means in this case that a real unit describes a quadratic
|
|
// polynomial. A derivation is possible and the operator returns TRUE.
|
|
if (uReal.r == false)
|
|
b.Set(true,true);
|
|
else
|
|
b.Set(true,false);
|
|
|
|
UBool boolvalue(uReal.timeInterval,b);
|
|
res->MergeAdd( boolvalue );
|
|
}
|
|
res->EndBulkLoad( false );
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int UnitPointDerivable( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
result = qp->ResultStorage( s );
|
|
UReal* uReal = (UReal*)args[0].addr;
|
|
UBool* res = ((UBool*)result.addr);
|
|
|
|
CcBool b;
|
|
|
|
if (uReal->IsDefined())
|
|
{
|
|
res->SetDefined(true);
|
|
res->timeInterval = uReal->timeInterval;
|
|
|
|
if (uReal->r == false)
|
|
b.Set(true,true);
|
|
else
|
|
b.Set(true,false);
|
|
|
|
UBool boolvalue(uReal->timeInterval,b);
|
|
res->CopyFrom(&boolvalue);
|
|
}
|
|
else
|
|
res->SetDefined( false );
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
5.17.3 Specification for operator ~derivable~
|
|
|
|
*/
|
|
const std::string
|
|
TemporalSpecDerivable=
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>mreal -> mbool\n"
|
|
"ureal -> ubool</text--->"
|
|
"<text>derivable ( _ ) </text--->"
|
|
"<text>Returns a moving/unit bool decribing the "
|
|
"derivability of the moving/unit real over time.</text--->"
|
|
"<text>derivable (mreal)</text---> ) )";
|
|
|
|
/*
|
|
5.17.4 Selection Function of operator ~derivable~
|
|
|
|
*/
|
|
|
|
int
|
|
DerivableSelect( ListExpr args )
|
|
{
|
|
ListExpr arg1 = nl->First( args );
|
|
|
|
if( nl->SymbolValue( arg1 ) == MReal::BasicType())
|
|
return 0;
|
|
|
|
if( nl->SymbolValue( arg1 ) == UReal::BasicType())
|
|
return 1;
|
|
|
|
return -1; // This point should never be reached
|
|
}
|
|
|
|
ValueMapping temporalderivablemap[] = { MPointDerivable,
|
|
UnitPointDerivable };
|
|
|
|
/*
|
|
5.17.5 Definition of operator ~derivable~
|
|
|
|
*/
|
|
|
|
Operator temporalderivable( "derivable",
|
|
TemporalSpecDerivable,
|
|
2,
|
|
temporalderivablemap,
|
|
DerivableSelect,
|
|
TypeMapDerivable);
|
|
|
|
/*
|
|
5.18 Operator ~derivative~
|
|
|
|
5.18.1 Type Mapping for ~derivative~
|
|
|
|
Type mapping for ~derivative~ is
|
|
|
|
---- mreal -> mreal
|
|
|
|
----
|
|
|
|
*/
|
|
ListExpr
|
|
TypeMapDerivative( ListExpr args )
|
|
{
|
|
ListExpr arg1;
|
|
if( nl->ListLength( args ) == 1 )
|
|
{
|
|
arg1 = nl->First( args );
|
|
|
|
if( nl->IsEqual( arg1, MReal::BasicType() ) )
|
|
return nl->SymbolAtom( MReal::BasicType() );
|
|
if( nl->IsEqual( arg1, UReal::BasicType() ) )
|
|
return nl->SymbolAtom( UReal::BasicType() );
|
|
}
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
|
}
|
|
|
|
|
|
/*
|
|
5.18.2 Value Mapping for ~derivative~
|
|
|
|
*/
|
|
int MPointDerivative( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
result = qp->ResultStorage( s );
|
|
|
|
MReal* m = ((MReal*)args[0].addr);
|
|
MReal* pResult = ((MReal*)result.addr);
|
|
UReal unitin;
|
|
UReal unitout(true);
|
|
|
|
pResult->Clear();
|
|
if( !m->IsDefined() ){
|
|
pResult->SetDefined( false );
|
|
return 0;
|
|
}
|
|
pResult->SetDefined( true );
|
|
pResult->StartBulkLoad();
|
|
for(int i=0;i<m->GetNoComponents();i++)
|
|
{
|
|
m->Get(i, unitin);
|
|
assert( unitin.IsDefined() );
|
|
if(!unitin.r)
|
|
{
|
|
unitout.a = 0.;
|
|
unitout.b = 2*unitin.a;
|
|
unitout.c = unitin.b;
|
|
unitout.r = false;
|
|
unitout.timeInterval = unitin.timeInterval;
|
|
pResult->MergeAdd(unitout);
|
|
}
|
|
}
|
|
pResult->EndBulkLoad( false );
|
|
|
|
return 0;
|
|
}
|
|
|
|
int UnitPointDerivative( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
result = qp->ResultStorage( s );
|
|
UReal *Unit = (UReal*)args[0].addr;
|
|
UReal *res = (UReal*)result.addr;
|
|
|
|
if (Unit->IsDefined() && !Unit->r)
|
|
{
|
|
res->timeInterval = Unit->timeInterval;
|
|
res->a = 0;
|
|
res->b = 2 * Unit->a;
|
|
res->c = Unit->b;
|
|
res->r = Unit->r;
|
|
res->SetDefined(true);
|
|
}
|
|
else // Unit is undefined
|
|
{
|
|
datetime::DateTime t = datetime::DateTime(datetime::instanttype);
|
|
res->timeInterval = Interval<Instant>(t,t,true,true);
|
|
res->a = 0;
|
|
res->b = 0;
|
|
res->c = 0;
|
|
res->r = false;
|
|
res->SetDefined(false);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
5.18.3 Specification for operator ~derivative~
|
|
|
|
*/
|
|
const std::string
|
|
TemporalSpecDerivative=
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>{m|u}real -> {m|u}real</text--->"
|
|
"<text>derivative ( _ ) </text--->"
|
|
"<text>Determine the derivative"
|
|
" of a mreal/ureal value.</text--->"
|
|
"<text>derivable (mreal)</text---> ) )";
|
|
|
|
/*
|
|
5.18.4 Selection Function of operator ~deriavtive~
|
|
|
|
Uses ~DerivableSelect~.
|
|
|
|
*/
|
|
|
|
ValueMapping temporalderivativemap[] = { MPointDerivative,
|
|
UnitPointDerivative };
|
|
|
|
/*
|
|
5.18.5 Definition of operator ~derivative~
|
|
|
|
*/
|
|
Operator temporalderivative( "derivative",
|
|
TemporalSpecDerivative,
|
|
2,
|
|
temporalderivativemap,
|
|
DerivableSelect,
|
|
TypeMapDerivative);
|
|
|
|
/*
|
|
5.19 Operator ~sfeed~
|
|
|
|
Moved to ~StreamAlgebra~ and renamed it to ~feed~.
|
|
|
|
*/
|
|
|
|
|
|
/*
|
|
5.20 Operator ~suse~
|
|
|
|
Moved to ~StreamAlgebra~ and renamed it to ~use~ resp. ~use2~.
|
|
|
|
*/
|
|
|
|
/*
|
|
5.21 Operator ~distance~
|
|
|
|
The operator calculates the minimum distance between two units of base
|
|
types ~int~ or ~point~. The distance is always a non-negative ~ureal~ value.
|
|
|
|
----
|
|
For T in {int, point}
|
|
distance: uT x uT -> ureal
|
|
uT x T -> ureal
|
|
T x uT -> ureal
|
|
ureal x ureal -> (stream ureal)
|
|
real x ureal -> (stream ureal)
|
|
ureal x real -> (stream ureal)
|
|
|
|
----
|
|
|
|
|
|
5.21.1 Type mapping function for ~distance~
|
|
|
|
typemapping appends the argument number of the argument containing
|
|
the unitvalue (either 0 or 1).
|
|
|
|
*/
|
|
|
|
ListExpr
|
|
TypeMapTemporalUnitDistance( ListExpr args )
|
|
{
|
|
ListExpr first, second;
|
|
std::string outstr1, outstr2;
|
|
|
|
if ( nl->IsAtom( args ) || nl->ListLength( args ) != 2 )
|
|
{
|
|
nl->WriteToString(outstr1, args);
|
|
ErrorReporter::ReportError("Operator distance expects a list of "
|
|
"length two, but gets '" + outstr1 +
|
|
"'.");
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
|
}
|
|
|
|
first = nl->First(args);
|
|
second = nl->Second(args);
|
|
|
|
// check for compatibility of arguments
|
|
if( !nl->IsAtom(first) || !nl->IsAtom(second) )
|
|
{
|
|
nl->WriteToString(outstr1, first);
|
|
nl->WriteToString(outstr2, second);
|
|
ErrorReporter::ReportError("Operator distance expects as arguments "
|
|
"lists of length one, but gets '" + outstr1 +
|
|
"' and '" + outstr2 + "'.");
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
|
}
|
|
|
|
if( nl->IsEqual(first, UPoint::BasicType())
|
|
&& nl->IsEqual(second, UPoint::BasicType()) )
|
|
{
|
|
return nl->SymbolAtom(UReal::BasicType());
|
|
}
|
|
|
|
if( nl->IsEqual(first, UPoint::BasicType())
|
|
&& nl->IsEqual(second, Point::BasicType()) )
|
|
{
|
|
return nl->ThreeElemList(nl->SymbolAtom(Symbol::APPEND()),
|
|
nl->OneElemList(nl->IntAtom(0)),
|
|
nl->SymbolAtom( UReal::BasicType() ));
|
|
}
|
|
|
|
if( nl->IsEqual(first, Point::BasicType())
|
|
&& nl->IsEqual(second, UPoint::BasicType()) )
|
|
{
|
|
return nl->ThreeElemList(nl->SymbolAtom(Symbol::APPEND()),
|
|
nl->OneElemList(nl->IntAtom(1)),
|
|
nl->SymbolAtom( UReal::BasicType() ));
|
|
}
|
|
|
|
if( nl->IsEqual(first, UInt::BasicType())
|
|
&& nl->IsEqual(second, UInt::BasicType()) )
|
|
{
|
|
return nl->SymbolAtom(UReal::BasicType());
|
|
}
|
|
|
|
if( nl->IsEqual(first, UInt::BasicType())
|
|
&& nl->IsEqual(second, CcInt::BasicType()) )
|
|
{
|
|
return nl->ThreeElemList(nl->SymbolAtom(Symbol::APPEND()),
|
|
nl->OneElemList(nl->IntAtom(0)),
|
|
nl->SymbolAtom( UReal::BasicType() ));
|
|
}
|
|
|
|
if( nl->IsEqual(first, CcInt::BasicType())
|
|
&& nl->IsEqual(second, UInt::BasicType()) )
|
|
{
|
|
return nl->ThreeElemList(nl->SymbolAtom(Symbol::APPEND()),
|
|
nl->OneElemList(nl->IntAtom(1)),
|
|
nl->SymbolAtom( UReal::BasicType() ));
|
|
}
|
|
|
|
if( nl->IsEqual(first, UReal::BasicType())
|
|
&& nl->IsEqual(second, UReal::BasicType()) )
|
|
{
|
|
return nl->TwoElemList(nl->SymbolAtom( Symbol::STREAM() ),
|
|
nl->SymbolAtom( UReal::BasicType() ));
|
|
}
|
|
|
|
if( nl->IsEqual(first, UReal::BasicType())
|
|
&& nl->IsEqual(second, CcReal::BasicType()) )
|
|
{
|
|
return nl->ThreeElemList(nl->SymbolAtom(Symbol::APPEND()),
|
|
nl->OneElemList(nl->IntAtom(0)),
|
|
nl->TwoElemList(nl->SymbolAtom(
|
|
Symbol::STREAM() ),
|
|
nl->SymbolAtom( UReal::BasicType() )));
|
|
}
|
|
|
|
if( nl->IsEqual(first, CcReal::BasicType())
|
|
&& nl->IsEqual(second, UReal::BasicType()) )
|
|
{
|
|
return nl->ThreeElemList(nl->SymbolAtom(Symbol::APPEND()),
|
|
nl->OneElemList(nl->IntAtom(1)),
|
|
nl->TwoElemList(
|
|
nl->SymbolAtom( Symbol::STREAM() ),
|
|
nl->SymbolAtom( UReal::BasicType() )));
|
|
}
|
|
|
|
nl->WriteToString(outstr1, first);
|
|
nl->WriteToString(outstr2, second);
|
|
ErrorReporter::ReportError("Operator distance found wrong argument "
|
|
"configuration '" + outstr1 +
|
|
"' and '" + outstr2 + "'.");
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
|
}
|
|
|
|
/*
|
|
5.21.2 Value mapping for operator ~distance~
|
|
*/
|
|
|
|
|
|
/*
|
|
(a1) Value mapping for
|
|
|
|
---- (upoint upoint) -> ureal
|
|
|
|
----
|
|
|
|
*/
|
|
|
|
int TUDistance_UPoint_UPoint( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
Interval<Instant> iv;
|
|
|
|
// Word a1, a2;
|
|
UPoint *u1, *u2;
|
|
result = qp->ResultStorage( s );
|
|
UReal* res = (UReal*) result.addr;
|
|
|
|
u1 = (UPoint*)(args[0].addr);
|
|
u2 = (UPoint*)(args[1].addr);
|
|
if (!u1->IsDefined() ||
|
|
!u2->IsDefined() ||
|
|
!u1->timeInterval.Intersects( u2->timeInterval ) )
|
|
{ // return undefined ureal
|
|
res->SetDefined( false );
|
|
}
|
|
else
|
|
{ // get intersection of deftime intervals
|
|
#ifdef TUA_DEBUG
|
|
cout << __PRETTY_FUNCTION__ << ":" << endl
|
|
<< " iv1=" << TUPrintTimeInterval(u1->timeInterval) << endl
|
|
<< " iv2=" << TUPrintTimeInterval(u2->timeInterval) << endl;
|
|
#endif
|
|
u1->timeInterval.Intersection( u2->timeInterval, iv );
|
|
#ifdef TUA_DEBUG
|
|
cout << __PRETTY_FUNCTION__ << ": iv="
|
|
<< TUPrintTimeInterval(iv) << endl;
|
|
#endif
|
|
// calculate result
|
|
u1->Distance( *u2, *res );
|
|
res->SetDefined( true );
|
|
}
|
|
// pass on result
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
(a2) value mapping for
|
|
|
|
----
|
|
(upoint point) -> ureal
|
|
(point upoint) -> ureal
|
|
|
|
----
|
|
|
|
*/
|
|
|
|
int TUDistance_UPoint_Point( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
Word thePoint, theUPoint;
|
|
result = qp->ResultStorage( s );
|
|
UReal* res = static_cast<UReal*>(result.addr);
|
|
|
|
// get argument configuration
|
|
int argConfDescriptor2;
|
|
argConfDescriptor2 = ((CcInt*)args[2].addr)->GetIntval();
|
|
if (argConfDescriptor2 == 0) {
|
|
theUPoint = args[0];
|
|
thePoint = args[1];
|
|
} else if (argConfDescriptor2 == 1) {
|
|
theUPoint = args[1];
|
|
thePoint = args[0];
|
|
} else {
|
|
cout << "\nWrong argument configuration in "
|
|
<< __PRETTY_FUNCTION__ << ": argConfDescriptor2="
|
|
<< argConfDescriptor2 << endl;
|
|
assert( false );
|
|
return 0;
|
|
}
|
|
UPoint* up = static_cast<UPoint*>(theUPoint.addr);
|
|
Point* p = static_cast<Point*>(thePoint.addr);
|
|
|
|
up->Distance( *p, *res);
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
(b1) value mapping for
|
|
|
|
---- (uint uint) -> ureal
|
|
|
|
----
|
|
|
|
*/
|
|
int TUDistance_UInt_UInt( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
Interval<Instant> iv;
|
|
double c1, c2, c;
|
|
|
|
result = qp->ResultStorage( s );
|
|
UReal* res = static_cast<UReal*>(result.addr);
|
|
UInt* u1 = static_cast<UInt*>(args[0].addr);
|
|
UInt* u2 = static_cast<UInt*>(args[1].addr);
|
|
|
|
if (!u1->IsDefined() ||
|
|
!u2->IsDefined() ||
|
|
!u1->timeInterval.Intersects( u2->timeInterval ) )
|
|
{ // return undefined ureal
|
|
res->SetDefined( false );
|
|
}
|
|
else
|
|
{ // get intersection of deftime intervals
|
|
u1->timeInterval.Intersection( u2->timeInterval, iv );
|
|
|
|
// calculate result
|
|
// (as the result is constant, no translation step is required)
|
|
c1 = static_cast<double>(u2->constValue.GetIntval());
|
|
c2 = static_cast<double>(u2->constValue.GetIntval());
|
|
c = fabs(c1 - c2);
|
|
*res = UReal(iv, 0, 0, c, false);
|
|
res->SetDefined( true );
|
|
}
|
|
// pass on result
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
(b2) value mapping for
|
|
|
|
---- ((uint int) -> ureal) and ((int uint) -> ureal)
|
|
|
|
----
|
|
|
|
*/
|
|
int TUDistance_UInt_Int( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
Word ii, ui;
|
|
int argConfDescriptor2;
|
|
UInt *u;
|
|
CcInt *i;
|
|
double c1, c2, c;
|
|
|
|
// get argument configuration
|
|
argConfDescriptor2 = ((CcInt*)args[2].addr)->GetIntval();
|
|
if (argConfDescriptor2 == 0)
|
|
{
|
|
ui = args[0];
|
|
ii = args[1];
|
|
}
|
|
else if (argConfDescriptor2 == 1)
|
|
{
|
|
ui = args[1];
|
|
ii = args[0];
|
|
}
|
|
else
|
|
{
|
|
cout << "\nWrong argument configuration in "
|
|
<< "'TUDistance_UInt_Int'. argConfDescriptor2="
|
|
<< argConfDescriptor2 << endl;
|
|
return 0;
|
|
}
|
|
|
|
result = qp->ResultStorage( s );
|
|
|
|
u = (UInt*)(ui.addr);
|
|
i = (CcInt*)(ii.addr);
|
|
|
|
if (!u->IsDefined() ||
|
|
!i->IsDefined() )
|
|
{ // return undefined ureal
|
|
((UReal*)(result.addr))->SetDefined( false );
|
|
}
|
|
else
|
|
{ // calculate result
|
|
// (as the result is constant, no translation step is required)
|
|
c1 = (double) u->constValue.GetIntval();
|
|
c2 = (double) i->GetIntval();
|
|
c = fabs(c1 - c2);
|
|
*((UReal*)(result.addr)) = UReal(u->timeInterval, 0, 0, c, false);
|
|
((UReal*)(result.addr))->SetDefined( true );
|
|
}
|
|
// pass on result
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
(c2) value mapping for
|
|
|
|
---- ((ureal ureal) -> (stream ureal))
|
|
|
|
----
|
|
|
|
*/
|
|
struct TUDistanceLocalInfo
|
|
{
|
|
bool finished;
|
|
int NoOfResults;
|
|
int NoOfResultsDelivered;
|
|
std::vector<UReal> resultVector;
|
|
};
|
|
|
|
int TUDistance_UReal_UReal( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
UReal *u1, *u2, utemp(true);
|
|
TUDistanceLocalInfo *localinfo = 0;
|
|
|
|
result = qp->ResultStorage( s );
|
|
|
|
switch( message )
|
|
{
|
|
case OPEN:
|
|
|
|
u1 = (UReal*)(args[0].addr);
|
|
u2 = (UReal*)(args[1].addr);
|
|
|
|
localinfo = new TUDistanceLocalInfo;
|
|
local.setAddr(localinfo);
|
|
localinfo->finished = true;
|
|
localinfo->NoOfResults = 0;
|
|
localinfo->NoOfResultsDelivered = 0;
|
|
localinfo->resultVector.clear();
|
|
|
|
if (!u1->IsDefined() ||
|
|
!u2->IsDefined() ||
|
|
u1->r ||
|
|
u2->r
|
|
)
|
|
{ // return empty stream
|
|
return 0;
|
|
}
|
|
else
|
|
{ // calculate results
|
|
localinfo->NoOfResults = u1->Distance(*u2, localinfo->resultVector);
|
|
localinfo->finished = (localinfo->NoOfResults <= 0);
|
|
return 0;
|
|
}
|
|
|
|
case REQUEST:
|
|
if(local.addr == 0)
|
|
return CANCEL;
|
|
localinfo = (TUDistanceLocalInfo*) local.addr;
|
|
if( localinfo->finished ||
|
|
localinfo->NoOfResultsDelivered >= localinfo->NoOfResults )
|
|
{
|
|
localinfo->finished = true;
|
|
return CANCEL;
|
|
}
|
|
result.setAddr(
|
|
localinfo->resultVector[localinfo->NoOfResultsDelivered].Clone() );
|
|
localinfo->NoOfResultsDelivered++;
|
|
return YIELD;
|
|
|
|
case CLOSE:
|
|
if(local.addr != 0)
|
|
{
|
|
localinfo = (TUDistanceLocalInfo*) local.addr;
|
|
delete localinfo;
|
|
local.setAddr(Address(0));
|
|
}
|
|
return 0;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
(c2) value mapping for
|
|
|
|
---- ((ureal real) -> (stream ureal)) and ((real ureal) -> (stream ureal))
|
|
|
|
----
|
|
|
|
*/
|
|
int TUDistance_UReal_Real( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
Word ii, ui;
|
|
int argConfDescriptor2;
|
|
UReal *u, utemp(true);
|
|
CcReal *i;
|
|
TUDistanceLocalInfo *localinfo = 0;
|
|
|
|
result = qp->ResultStorage( s );
|
|
|
|
switch( message )
|
|
{
|
|
case OPEN:
|
|
|
|
// get argument configuration
|
|
argConfDescriptor2 = ((CcInt*)args[2].addr)->GetIntval();
|
|
if (argConfDescriptor2 == 0)
|
|
{
|
|
ui = args[0];
|
|
ii = args[1];
|
|
}
|
|
else if (argConfDescriptor2 == 1)
|
|
{
|
|
ui = args[1];
|
|
ii = args[0];
|
|
}
|
|
else
|
|
{
|
|
cout << "\nWrong argument configuration in "
|
|
<< "'TUDistance_UReal_Real'. argConfDescriptor2="
|
|
<< argConfDescriptor2 << endl;
|
|
return 0;
|
|
}
|
|
|
|
u = (UReal*)(ui.addr);
|
|
i = (CcReal*)(ii.addr);
|
|
|
|
localinfo = new TUDistanceLocalInfo;
|
|
local.setAddr(localinfo);
|
|
localinfo->finished = true;
|
|
localinfo->NoOfResults = 0;
|
|
localinfo->NoOfResultsDelivered = 0;
|
|
localinfo->resultVector.clear();
|
|
|
|
if (!u->IsDefined() ||
|
|
!i->IsDefined() ||
|
|
u->r
|
|
)
|
|
{ // return empty stream
|
|
return 0;
|
|
}
|
|
else
|
|
{ // calculate result
|
|
utemp =
|
|
UReal(u->timeInterval, u->a, u->b, (u->c - i->GetRealval() ), false);
|
|
localinfo->NoOfResults = utemp.Abs(localinfo->resultVector);
|
|
localinfo->finished = (localinfo->NoOfResults <= 0);
|
|
return 0;
|
|
}
|
|
|
|
case REQUEST:
|
|
if(local.addr != 0)
|
|
localinfo = (TUDistanceLocalInfo*) local.addr;
|
|
else
|
|
return CANCEL;
|
|
if( localinfo->finished ||
|
|
localinfo->NoOfResultsDelivered >= localinfo->NoOfResults )
|
|
{
|
|
localinfo->finished = true;
|
|
return CANCEL;
|
|
}
|
|
result.setAddr(
|
|
localinfo->resultVector[localinfo->NoOfResultsDelivered].Clone() );
|
|
localinfo->NoOfResultsDelivered++;
|
|
return YIELD;
|
|
|
|
case CLOSE:
|
|
if(local.addr != 0)
|
|
{
|
|
localinfo = (TUDistanceLocalInfo*) local.addr;
|
|
delete localinfo;
|
|
local.setAddr(Address(0));
|
|
}
|
|
return 0;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
5.21.3 Specification for operator ~distance~
|
|
|
|
*/
|
|
|
|
const std::string TemporalSpecDistance =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"("
|
|
"<text>For T in {point, int}:\n"
|
|
"(uT uT) -> ureal\n"
|
|
"(uT T) -> ureal\n"
|
|
"( T uT) -> ureal\n"
|
|
"(ureal ureal) -> (stream ureal)\n"
|
|
"(ureal real) -> (stream ureal)\n"
|
|
"( real ureal) -> (stream ureal)</text--->"
|
|
"<text>distance( _, _)</text--->"
|
|
"<text>Calculates the distance of both arguments, "
|
|
"whereof at least one is a unittype, "
|
|
"as a 'ureal' value. For the ureal signatures, all "
|
|
"radix-flags must be FALSE, otherwise the result is "
|
|
"empty.</text--->"
|
|
"<text>distance(upoint1,point1)</text--->"
|
|
") )";
|
|
|
|
/*
|
|
5.21.4 Selection Function of operator ~distance~
|
|
|
|
*/
|
|
|
|
ValueMapping temporalunitdistancemap[] =
|
|
{
|
|
TUDistance_UPoint_UPoint, // 0
|
|
TUDistance_UPoint_Point,
|
|
TUDistance_UInt_UInt,
|
|
TUDistance_UInt_Int,
|
|
TUDistance_UReal_UReal,
|
|
TUDistance_UReal_Real // 5
|
|
};
|
|
|
|
int temporalunitDistanceSelect( ListExpr args )
|
|
{
|
|
ListExpr first = nl->First(args);
|
|
ListExpr second = nl->Second(args);
|
|
|
|
if( nl->IsEqual(first, UPoint::BasicType())
|
|
&& nl->IsEqual(second, UPoint::BasicType()) )
|
|
return 0;
|
|
|
|
else if( nl->IsEqual(first, UPoint::BasicType())
|
|
&& nl->IsEqual(second, Point::BasicType()) )
|
|
return 1;
|
|
|
|
else if( nl->IsEqual(first, Point::BasicType())
|
|
&& nl->IsEqual(second, UPoint::BasicType()) )
|
|
return 1;
|
|
|
|
else if( nl->IsEqual(first, UInt::BasicType())
|
|
&& nl->IsEqual(second, UInt::BasicType()) )
|
|
return 2;
|
|
|
|
else if( nl->IsEqual(first, UInt::BasicType())
|
|
&& nl->IsEqual(second, CcInt::BasicType()) )
|
|
return 3;
|
|
|
|
else if( nl->IsEqual(first, CcInt::BasicType())
|
|
&& nl->IsEqual(second, UInt::BasicType()) )
|
|
return 3;
|
|
|
|
else if( nl->IsEqual(first, UReal::BasicType())
|
|
&& nl->IsEqual(second, UReal::BasicType()) )
|
|
return 4;
|
|
|
|
else if( nl->IsEqual(first, UReal::BasicType())
|
|
&& nl->IsEqual(second, CcReal::BasicType()) )
|
|
return 5;
|
|
|
|
else if( nl->IsEqual(first, CcReal::BasicType())
|
|
&& nl->IsEqual(second, UReal::BasicType()) )
|
|
return 5;
|
|
|
|
else
|
|
cout << "\nERROR in temporalunitDistanceSelect!" << endl;
|
|
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
5.21.5 Definition of operator ~distance~
|
|
|
|
*/
|
|
|
|
Operator temporalunitdistance( "distance",
|
|
TemporalSpecDistance,
|
|
6,
|
|
temporalunitdistancemap,
|
|
temporalunitDistanceSelect,
|
|
TypeMapTemporalUnitDistance);
|
|
|
|
/*
|
|
5.22 Operator ~atmax~
|
|
|
|
From a given unit ~u~, the operator creates a stream of units that
|
|
are restrictions of ~u~ to the periods where it reaches its maximum
|
|
value.
|
|
|
|
----
|
|
For T in {int, real}
|
|
atmax: uT --> (stream uT)
|
|
|
|
----
|
|
|
|
5.22.1 Type mapping function for ~atmax~
|
|
|
|
*/
|
|
ListExpr
|
|
UnitBaseTypeMapAtmax( ListExpr args )
|
|
{
|
|
ListExpr arg1;
|
|
if( nl->ListLength( args ) == 1 )
|
|
{
|
|
arg1 = nl->First( args );
|
|
|
|
if( nl->IsEqual( arg1, UBool::BasicType() ) )
|
|
return nl->SymbolAtom( UBool::BasicType() );
|
|
if( nl->IsEqual( arg1, UInt::BasicType() ) )
|
|
return nl->SymbolAtom( UInt::BasicType() );
|
|
if( nl->IsEqual( arg1, UString::BasicType() ) )
|
|
return nl->SymbolAtom( UString::BasicType() );
|
|
// for ureal, atmax/atmin will return a stream of ureals!
|
|
if( nl->IsEqual( arg1, UReal::BasicType() ) )
|
|
return nl->TwoElemList(nl->SymbolAtom( Symbol::STREAM() ),
|
|
nl->SymbolAtom( UReal::BasicType() ));
|
|
}
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
|
}
|
|
/*
|
|
5.22.2 Value mapping for operator ~atmax~
|
|
|
|
*/
|
|
|
|
struct AtExtrURealLocalInfo
|
|
{
|
|
int NoOfResults;
|
|
int ResultsDelivered;
|
|
std::vector<UReal> resultUnitVector;
|
|
};
|
|
|
|
|
|
int atmaxUReal( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
AtExtrURealLocalInfo *sli;
|
|
UReal *ureal;
|
|
|
|
result = qp->ResultStorage( s );
|
|
|
|
switch (message)
|
|
{
|
|
case OPEN :
|
|
|
|
ureal = (UReal*)(args[0].addr);
|
|
#ifdef TUA_DEBUG
|
|
cout << " Argument ureal value: " << TUPrintUReal(ureal) << endl
|
|
<< " 1" << endl;
|
|
#endif
|
|
sli = new AtExtrURealLocalInfo;
|
|
sli->resultUnitVector.clear();
|
|
sli->NoOfResults = 0;
|
|
sli->ResultsDelivered = 0;
|
|
local.setAddr(sli);
|
|
|
|
if ( !ureal->IsDefined() )
|
|
{ // ureal undefined
|
|
// -> return empty stream
|
|
sli->NoOfResults = 0;
|
|
#ifdef TUA_DEBUG
|
|
cout << " ureal undef: no solution" << endl;
|
|
#endif
|
|
return 0;
|
|
}
|
|
sli->NoOfResults = ureal->AtMax(sli->resultUnitVector);
|
|
return 0;
|
|
|
|
case REQUEST :
|
|
|
|
if (local.addr == 0)
|
|
return CANCEL;
|
|
sli = (AtExtrURealLocalInfo*) local.addr;
|
|
|
|
if (sli->NoOfResults <= sli->ResultsDelivered)
|
|
return CANCEL;
|
|
|
|
result.setAddr( sli->resultUnitVector[sli->ResultsDelivered].Clone() );
|
|
#ifdef TUA_DEBUG
|
|
cout << " delivered result[" << sli->ResultsDelivered+1
|
|
<< "/" << sli->NoOfResults<< "]="
|
|
<< TUPrintUReal((UReal*)(result.addr))
|
|
<< endl;
|
|
#endif
|
|
sli->ResultsDelivered++;
|
|
return YIELD;
|
|
|
|
case CLOSE :
|
|
|
|
if (local.addr != 0)
|
|
{
|
|
sli = (AtExtrURealLocalInfo*) local.addr;
|
|
// for(unsigned int i=0; i< sli->resultUnitVector.size(); i++)
|
|
// sli->resultUnitVector[i].DeleteIfAllowed();
|
|
delete sli;
|
|
local.setAddr(Address(0));
|
|
}
|
|
return 0;
|
|
|
|
} // end switch
|
|
return 0; // should not be reached
|
|
}
|
|
|
|
template<class T>
|
|
int atmaxUConst( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
ConstTemporalUnit<T>* arg = static_cast<ConstTemporalUnit<T>*>(args[0].addr);
|
|
result = qp->ResultStorage( s );
|
|
// This operator is not very interesting. It implements
|
|
// the atmax operator for constant unit types, like uint, ustring or ubool.
|
|
// In fact, it returns just a copy of the argument.
|
|
ConstTemporalUnit<T>* res = static_cast<ConstTemporalUnit<T>*>(result.addr);
|
|
res->CopyFrom(arg);
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
5.22.3 Specification for operator ~atmax~
|
|
|
|
*/
|
|
|
|
const std::string TemporalSpecAtmax =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" "
|
|
"\"Example\" ) "
|
|
"("
|
|
"<text>For T in {int, bool, string}:\n"
|
|
"uT -> uT\n"
|
|
"ureal -> (stream ureal)</text--->"
|
|
"<text>atmax( _ )</text--->"
|
|
"<text>Restricts a the unittype value to the time where "
|
|
"it takes it's maximum value.\n"
|
|
"Observe, that for type 'ureal', the result is a '(stream ureal)' "
|
|
"rather than a 'ureal'!</text--->"
|
|
"<text>atmax( ureal1 )</text--->"
|
|
") )";
|
|
|
|
|
|
/*
|
|
5.22.4 Selection Function of operator ~atmax~
|
|
|
|
*/
|
|
|
|
ValueMapping temporalunitatmaxmap[] =
|
|
{
|
|
atmaxUConst<CcBool>,
|
|
atmaxUConst<CcInt>,
|
|
atmaxUConst<CcString>,
|
|
atmaxUReal
|
|
};
|
|
|
|
int temporalunitAtmaxSelect( ListExpr args )
|
|
{
|
|
ListExpr arg1;
|
|
if( nl->ListLength( args ) == 1 )
|
|
{
|
|
arg1 = nl->First( args );
|
|
|
|
if( nl->IsEqual( arg1, UBool::BasicType() ) )
|
|
return 0;
|
|
if( nl->IsEqual( arg1, UInt::BasicType() ) )
|
|
return 1;
|
|
if( nl->IsEqual( arg1, UString::BasicType() ) )
|
|
return 2;
|
|
if( nl->IsEqual( arg1, UReal::BasicType() ) )
|
|
return 3;
|
|
}
|
|
cout << "\ntemporalunitAtmaxSelect: Wrong type!" << endl;
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
5.22.5 Definition of operator ~atmax~
|
|
|
|
*/
|
|
|
|
Operator temporalunitatmax( "atmax",
|
|
TemporalSpecAtmax,
|
|
4,
|
|
temporalunitatmaxmap,
|
|
temporalunitAtmaxSelect,
|
|
UnitBaseTypeMapAtmax);
|
|
|
|
|
|
/*
|
|
5.23 Operator ~atmin~
|
|
|
|
From a given unit ~u~, the operator creates a stream of units that
|
|
are restrictions of ~u~ to the periods where it reaches its minimum
|
|
value.
|
|
|
|
----
|
|
For T in {int, real}
|
|
atmin: uT --> (stream uT)
|
|
|
|
----
|
|
|
|
5.23.1 Type mapping function for ~atmin~
|
|
|
|
Uses typemapping ~UnitBaseTypeMapAtmax~ intended for related operator ~atmax~
|
|
|
|
*/
|
|
|
|
/*
|
|
5.23.2 Value mapping for operator ~atmin~
|
|
|
|
*/
|
|
|
|
int atminUReal( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
AtExtrURealLocalInfo *sli;
|
|
UReal *ureal;
|
|
|
|
result = qp->ResultStorage( s );
|
|
|
|
switch (message)
|
|
{
|
|
case OPEN :
|
|
|
|
ureal = (UReal*)(args[0].addr);
|
|
#ifdef TUA_DEBUG
|
|
cout << " Argument ureal value: " << TUPrintUReal(ureal) << endl
|
|
<< " 1" << endl;
|
|
#endif
|
|
sli = new AtExtrURealLocalInfo;
|
|
sli->resultUnitVector.clear();
|
|
sli->NoOfResults = 0;
|
|
sli->ResultsDelivered = 0;
|
|
local.setAddr(sli);
|
|
|
|
if ( !ureal->IsDefined() )
|
|
{ // ureal undefined
|
|
// -> return empty stream
|
|
sli->NoOfResults = 0;
|
|
#ifdef TUA_DEBUG
|
|
cout << " ureal undef: no solution" << endl;
|
|
#endif
|
|
return 0;
|
|
}
|
|
sli->NoOfResults = ureal->AtMin(sli->resultUnitVector);
|
|
return 0;
|
|
|
|
case REQUEST :
|
|
|
|
if (local.addr == 0)
|
|
return CANCEL;
|
|
sli = (AtExtrURealLocalInfo*) local.addr;
|
|
|
|
if (sli->NoOfResults <= sli->ResultsDelivered)
|
|
return CANCEL;
|
|
|
|
result.setAddr( sli->resultUnitVector[sli->ResultsDelivered].Clone() );
|
|
#ifdef TUA_DEBUG
|
|
cout << " delivered result[" << sli->ResultsDelivered+1
|
|
<< "/" << sli->NoOfResults<< "]="
|
|
<< TUPrintUReal((UReal*)(result.addr))
|
|
<< endl;
|
|
#endif
|
|
sli->ResultsDelivered++;
|
|
return YIELD;
|
|
|
|
case CLOSE :
|
|
|
|
if (local.addr != 0)
|
|
{
|
|
sli = (AtExtrURealLocalInfo*) local.addr;
|
|
// for(unsigned int i=0; i< sli->resultUnitVector.size(); i++)
|
|
// sli->resultUnitVector[i].DeleteIfAllowed();
|
|
delete sli;
|
|
local.setAddr(Address(0));
|
|
}
|
|
return 0;
|
|
|
|
} // end switch
|
|
return 0; // should not be reached
|
|
}
|
|
|
|
template<class T>
|
|
int atminUConst( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
ConstTemporalUnit<T>* arg = static_cast<ConstTemporalUnit<T>*>(args[0].addr);
|
|
result = qp->ResultStorage( s );
|
|
// This operator is not very interesting. It implements
|
|
// the atmin operator for constant unit types, like uint, ustring or ubool.
|
|
// In fact, it returns just a copy of the argument.
|
|
ConstTemporalUnit<T>* res = static_cast<ConstTemporalUnit<T>*>(result.addr);
|
|
res->CopyFrom(arg);
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
5.23.3 Specification for operator ~atmin~
|
|
|
|
*/
|
|
|
|
const std::string TemporalSpecAtmin =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" "
|
|
"\"Example\" ) "
|
|
"("
|
|
"<text>For T in {int, bool, string}:\n"
|
|
"uT -> uT\n"
|
|
"ureal -> (stream ureal)</text--->"
|
|
"<text>atmin( _ )</text--->"
|
|
"<text>Restricts a the unittype value to the time where "
|
|
"it takes it's minimum value.\n"
|
|
"Observe, that for type 'ureal', the result is a '(stream ureal)' "
|
|
"rather than a 'ureal'!</text--->"
|
|
"<text>atmin( ureal1 )</text--->"
|
|
") )";
|
|
|
|
|
|
/*
|
|
5.23.4 Selection Function of operator ~atmin~
|
|
|
|
Uses selection function ~temporalunitAtmaxSelect~.
|
|
|
|
*/
|
|
|
|
ValueMapping temporalunitatminmap[] =
|
|
{
|
|
atminUConst<CcBool>,
|
|
atminUConst<CcInt>,
|
|
atminUConst<CcString>,
|
|
atminUReal
|
|
};
|
|
|
|
/*
|
|
5.23.5 Definition of operator ~atmin~
|
|
|
|
*/
|
|
Operator temporalunitatmin( "atmin",
|
|
TemporalSpecAtmin,
|
|
4,
|
|
temporalunitatminmap,
|
|
temporalunitAtmaxSelect,
|
|
UnitBaseTypeMapAtmax);
|
|
|
|
|
|
/*
|
|
5.24 Operator ~saggregate~
|
|
|
|
Moved to ~StreamAlgebra~ and remaned it to ~aggregateS~
|
|
|
|
*/
|
|
|
|
/*
|
|
5.25 Operator ~abs~
|
|
|
|
The operator returns the absolute function derived from the
|
|
input ureal or uint.
|
|
|
|
*/
|
|
|
|
/*
|
|
5.25.1 Type mapping function for ~abs~
|
|
|
|
The operator has signature
|
|
|
|
----
|
|
|
|
abs: ureal --> (stream ureal)
|
|
abs: uint --> uint
|
|
|
|
----
|
|
|
|
*/
|
|
|
|
ListExpr TU_TM_Abs( ListExpr args )
|
|
{
|
|
ListExpr first;
|
|
std::string outstr1, outstr2;
|
|
|
|
if ( nl->IsAtom( args ) || nl->ListLength( args ) != 1 )
|
|
{
|
|
nl->WriteToString(outstr1, args);
|
|
ErrorReporter::ReportError("Operator abs expects a list of "
|
|
"length one, but gets '" + outstr1 +
|
|
"'.");
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
|
}
|
|
|
|
first = nl->First(args);
|
|
|
|
if( nl->IsEqual(first, UInt::BasicType()) )
|
|
{
|
|
return nl->SymbolAtom(UInt::BasicType());
|
|
}
|
|
|
|
if( nl->IsEqual(first, UReal::BasicType()) )
|
|
{
|
|
return nl->TwoElemList(nl->SymbolAtom( Symbol::STREAM() ),
|
|
nl->SymbolAtom( UReal::BasicType() ));
|
|
}
|
|
|
|
nl->WriteToString(outstr1, first);
|
|
ErrorReporter::ReportError("Operator abs found wrong argument "
|
|
+ outstr1 + "'.");
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
|
}
|
|
|
|
|
|
/*
|
|
5.25.2 Value mapping for operator ~abs~
|
|
|
|
*/
|
|
// value mapping for uint --> uint
|
|
int TU_VM_Abs_UInt( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
Word a1;
|
|
UInt *u1;
|
|
long c1, c;
|
|
|
|
result = qp->ResultStorage( s );
|
|
|
|
a1 = args[0];
|
|
|
|
u1 = (UInt*)(a1.addr);
|
|
|
|
if ( !u1->IsDefined() )
|
|
{ // return undefined ureal
|
|
((UInt*)(result.addr))->SetDefined( false );
|
|
}
|
|
else
|
|
{
|
|
c1 = (long) u1->constValue.GetIntval();
|
|
c = std::abs(c1);
|
|
((UInt*)(result.addr))->timeInterval = u1->timeInterval;
|
|
((UInt*)(result.addr))->SetDefined( true );
|
|
((UInt*)(result.addr))->constValue.Set(true,c);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
struct TUAbsLocalInfo
|
|
{
|
|
bool finished;
|
|
int NoOfResults;
|
|
int NoOfResultsDelivered;
|
|
std::vector<UReal> resultVector;
|
|
};
|
|
|
|
// value mapping for ureal --> (stream ureal)
|
|
int TU_VM_Abs_UReal( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
TUAbsLocalInfo *sli;
|
|
Word u1;
|
|
UReal *uv1;
|
|
Interval<Instant> iv;
|
|
|
|
switch( message )
|
|
{
|
|
case OPEN:
|
|
|
|
sli = new TUAbsLocalInfo;
|
|
local.setAddr(sli);
|
|
sli->resultVector.clear();
|
|
sli->finished = true;
|
|
sli->NoOfResults = 0;
|
|
sli->NoOfResultsDelivered = 0;
|
|
|
|
u1 = args[0];
|
|
uv1 = (UReal*) (u1.addr);
|
|
|
|
if ( uv1->IsDefined() )
|
|
{
|
|
sli->NoOfResults = uv1->Abs(sli->resultVector);
|
|
sli->finished = ( sli->NoOfResults <= 0 );
|
|
}
|
|
return 0;
|
|
|
|
case REQUEST:
|
|
|
|
if(local.addr == 0)
|
|
{
|
|
return CANCEL;
|
|
}
|
|
sli = (TUAbsLocalInfo*) local.addr;
|
|
if(sli->finished)
|
|
{
|
|
return CANCEL;
|
|
}
|
|
if(sli->NoOfResultsDelivered < sli->NoOfResults)
|
|
{
|
|
result.setAddr(
|
|
sli->resultVector[sli->NoOfResultsDelivered].Clone() );
|
|
sli->NoOfResultsDelivered++;
|
|
return YIELD;
|
|
}
|
|
sli->finished = true;
|
|
return CANCEL;
|
|
|
|
case CLOSE:
|
|
|
|
if (local.addr != 0)
|
|
{
|
|
sli = (TUAbsLocalInfo*) local.addr;
|
|
delete sli;
|
|
local.setAddr(Address(0));
|
|
}
|
|
return 0;
|
|
} // end switch
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
5.24.3 Specification for operator ~abs~
|
|
|
|
*/
|
|
const std::string TU_Spec_Abs =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>uint -> uint\n"
|
|
"ureal -> (stream ureal)</text--->"
|
|
"<text>abs( _ )</text--->"
|
|
"<text>Return the argument's absolute value.</text--->"
|
|
"<text>query speed(mp1)</text---> ) )";
|
|
|
|
|
|
/*
|
|
5.25.4 Selection Function of operator ~abs~
|
|
|
|
*/
|
|
int TU_Select_Abs( ListExpr args )
|
|
{
|
|
ListExpr arg1 = nl->First( args );
|
|
|
|
if( nl->SymbolValue( arg1 ) == UInt::BasicType() )
|
|
return 0;
|
|
|
|
if( nl->SymbolValue( arg1 ) == UReal::BasicType() )
|
|
return 1;
|
|
|
|
return -1; // This point should never be reached
|
|
}
|
|
|
|
ValueMapping temporalunit_abs_map[] = { TU_VM_Abs_UInt, TU_VM_Abs_UReal };
|
|
|
|
/*
|
|
5.25.5 Definition of operator ~abs~
|
|
|
|
*/
|
|
Operator temporalunitabs( "abs",
|
|
TU_Spec_Abs,
|
|
2,
|
|
temporalunit_abs_map,
|
|
TU_Select_Abs,
|
|
TU_TM_Abs);
|
|
|
|
|
|
/*
|
|
5.26 Operator
|
|
|
|
----
|
|
|
|
intersection: For T in {bool, int, string}:
|
|
OK uT x uT --> (stream uT)
|
|
OK uT x T --> (stream uT)
|
|
OK T x uT --> (stream uT)
|
|
(OK) ureal x real --> (stream ureal)
|
|
(OK) real x ureal --> (stream ureal)
|
|
Pre ureal x ureal --> (stream ureal)
|
|
OK upoint x point --> (stream upoint) same as at: upoint x point
|
|
OK point x upoint --> (stream upoint) same as at: upoint x point
|
|
OK upoint x upoint --> (stream upoint)
|
|
OK upoint x line --> (stream upoint)
|
|
OK line x upoint --> (stream upoint)
|
|
OK upoint x region --> (stream upoint)
|
|
OK region x upoint --> (stream upoint)
|
|
OK upoint x uregion --> (stream upoint)
|
|
OK uregion x upoint --> (stream upoint)
|
|
|
|
----
|
|
|
|
A. (T mT) [->] mT and (mT T) -> mT
|
|
|
|
B. (mT mT) [->] mT
|
|
|
|
The operator always returns a stream of units (to handle both, empty and set
|
|
valued results).
|
|
|
|
1. For all types of arguments, we return an empty stream, if both
|
|
timeIntervals don't overlap.
|
|
|
|
2. Now, the algorithms depends on the actual dataype:
|
|
|
|
Then, for ~constant temporal units~ (ubool, uint, ustring), the operator
|
|
restricts two unit values with equal values to the intersection of both time
|
|
intervals, or otherwise (if the const values are nit equal) returns an empty
|
|
stream.
|
|
|
|
For ~ureal~, we test whether the functions of both units are equal, for we
|
|
can pass its restriction to the intersection of deftimes then (resp. create an
|
|
empty stream). Otherwise, we restrict both arguments' deftimes to their
|
|
intersection. Then we calculate the minimum and maximum value for both
|
|
arguments with respect to the restricted deftime. If both ranges don't
|
|
overlap, we return an empty stream. Otherwise, we compute the intersection
|
|
points (1 or 2) and return them as the result - or
|
|
an UNDEFINED value, if the result is not represeantable as a ureal value.
|
|
|
|
For ~upoint~, we interpret the units as straight lines. If both are parallel,
|
|
return the empty stream. If both are identical,
|
|
|
|
Otherwise calculate the intersection point ~S~. From ~S~, calculate the
|
|
instants $t_{u1}$ and $t_{u2}$. If both coincide, return that point if within
|
|
the common timeInterval, otherwise the empty stream.
|
|
|
|
C. (upoint line) [->] (stream upoint) and (line upoint) [->] (stream upoint)
|
|
|
|
|
|
*/
|
|
|
|
/*
|
|
5.26.1 Type mapping function for ~intersection~
|
|
|
|
*/
|
|
|
|
ListExpr TemporalUnitIntersectionTypeMap( ListExpr args )
|
|
{
|
|
ListExpr arg1, arg2;
|
|
std::string argstr1 = "", argstr2 = "";
|
|
|
|
if( nl->ListLength( args ) == 2 )
|
|
{
|
|
arg1 = nl->First( args );
|
|
arg2 = nl->Second( args );
|
|
|
|
// First case: uT uT -> stream uT
|
|
if (nl->Equal( arg1, arg2 ))
|
|
{
|
|
if( nl->IsEqual( arg1, UBool::BasicType() ) )
|
|
return nl->TwoElemList(nl->SymbolAtom( Symbol::STREAM() ),
|
|
nl->SymbolAtom( UBool::BasicType() ));
|
|
if( nl->IsEqual( arg1, UInt::BasicType() ) )
|
|
return nl->TwoElemList(nl->SymbolAtom( Symbol::STREAM() ),
|
|
nl->SymbolAtom( UInt::BasicType() ));
|
|
if( nl->IsEqual( arg1, UReal::BasicType() ) )
|
|
return nl->TwoElemList(nl->SymbolAtom( Symbol::STREAM() ),
|
|
nl->SymbolAtom( UReal::BasicType() ));
|
|
if( nl->IsEqual( arg1, UPoint::BasicType() ) )
|
|
return nl->TwoElemList(nl->SymbolAtom( Symbol::STREAM() ),
|
|
nl->SymbolAtom( UPoint::BasicType() ));
|
|
if( nl->IsEqual( arg1, UString::BasicType() ) )
|
|
return nl->TwoElemList(nl->SymbolAtom( Symbol::STREAM() ),
|
|
nl->SymbolAtom( UString::BasicType() ));
|
|
}
|
|
|
|
// Second case: uT T -> stream uT
|
|
if( nl->IsEqual( arg1, UBool::BasicType() )
|
|
&& nl->IsEqual( arg2, CcBool::BasicType()) )
|
|
return nl->TwoElemList(nl->SymbolAtom( Symbol::STREAM() ),
|
|
nl->SymbolAtom( UBool::BasicType() ));
|
|
if( nl->IsEqual( arg1, UInt::BasicType() )
|
|
&& nl->IsEqual( arg2, CcInt::BasicType()) )
|
|
return nl->TwoElemList(nl->SymbolAtom( Symbol::STREAM() ),
|
|
nl->SymbolAtom( UInt::BasicType() ));
|
|
if( nl->IsEqual( arg1, UReal::BasicType() )
|
|
&& nl->IsEqual( arg2, CcReal::BasicType()) )
|
|
return nl->TwoElemList(nl->SymbolAtom( Symbol::STREAM() ),
|
|
nl->SymbolAtom( UReal::BasicType() ));
|
|
if( nl->IsEqual( arg1, UPoint::BasicType() )
|
|
&& nl->IsEqual( arg2, Point::BasicType()) )
|
|
return nl->TwoElemList(nl->SymbolAtom( Symbol::STREAM() ),
|
|
nl->SymbolAtom( UPoint::BasicType() ));
|
|
if( nl->IsEqual( arg1, UString::BasicType() )
|
|
&& nl->IsEqual( arg2, CcString::BasicType()) )
|
|
return nl->TwoElemList(nl->SymbolAtom( Symbol::STREAM() ),
|
|
nl->SymbolAtom( UString::BasicType() ));
|
|
|
|
// Third case: T uT -> stream uT
|
|
if( nl->IsEqual( arg1, CcBool::BasicType() )
|
|
&& nl->IsEqual( arg2, UBool::BasicType()) )
|
|
return nl->TwoElemList(nl->SymbolAtom( Symbol::STREAM() ),
|
|
nl->SymbolAtom( UBool::BasicType() ));
|
|
if( nl->IsEqual( arg1, CcInt::BasicType() )
|
|
&& nl->IsEqual( arg2, UInt::BasicType()) )
|
|
return nl->TwoElemList(nl->SymbolAtom( Symbol::STREAM() ),
|
|
nl->SymbolAtom( UInt::BasicType() ));
|
|
if( nl->IsEqual( arg1, CcReal::BasicType() )
|
|
&& nl->IsEqual( arg2, UReal::BasicType()) )
|
|
return nl->TwoElemList(nl->SymbolAtom( Symbol::STREAM() ),
|
|
nl->SymbolAtom( UReal::BasicType() ));
|
|
if( nl->IsEqual( arg1, Point::BasicType() )
|
|
&& nl->IsEqual( arg2, UPoint::BasicType()) )
|
|
return nl->TwoElemList(nl->SymbolAtom( Symbol::STREAM() ),
|
|
nl->SymbolAtom( UPoint::BasicType() ));
|
|
if( nl->IsEqual( arg1, CcString::BasicType() )
|
|
&& nl->IsEqual( arg2, UString::BasicType()) )
|
|
return nl->TwoElemList(nl->SymbolAtom( Symbol::STREAM() ),
|
|
nl->SymbolAtom( UString::BasicType() ));
|
|
|
|
// Fourth case: upoint line -> stream upoint
|
|
if( nl->IsEqual( arg1, UPoint::BasicType() )
|
|
&& nl->IsEqual( arg2, Line::BasicType()) )
|
|
return nl->TwoElemList(nl->SymbolAtom( Symbol::STREAM() ),
|
|
nl->SymbolAtom( UPoint::BasicType() ));
|
|
|
|
// Fifth case: line upoint -> stream upoint
|
|
if( nl->IsEqual( arg1, Line::BasicType() )
|
|
&& nl->IsEqual( arg2, UPoint::BasicType()) )
|
|
return nl->TwoElemList(nl->SymbolAtom( Symbol::STREAM() ),
|
|
nl->SymbolAtom( UPoint::BasicType() ));
|
|
|
|
// Sixth case: upoint uregion -> stream upoint
|
|
if( nl->IsEqual( arg1, UPoint::BasicType() )
|
|
&& nl->IsEqual( arg2, URegion::BasicType()) )
|
|
return nl->TwoElemList(nl->SymbolAtom( Symbol::STREAM() ),
|
|
nl->SymbolAtom( UPoint::BasicType() ));
|
|
|
|
// Eighth case: uregion upoint -> stream upoint
|
|
if( nl->IsEqual( arg1, URegion::BasicType() )
|
|
&& nl->IsEqual( arg2, UPoint::BasicType()) )
|
|
return nl->TwoElemList(nl->SymbolAtom( Symbol::STREAM() ),
|
|
nl->SymbolAtom( UPoint::BasicType() ));
|
|
|
|
// Ninth case: upoint region -> stream upoint
|
|
if( nl->IsEqual( arg1, UPoint::BasicType() )
|
|
&& nl->IsEqual( arg2, Region::BasicType()) )
|
|
return nl->TwoElemList(nl->SymbolAtom( Symbol::STREAM() ),
|
|
nl->SymbolAtom( UPoint::BasicType() ));
|
|
|
|
// Tenth case: region upoint -> stream upoint
|
|
if( nl->IsEqual( arg1, Region::BasicType() )
|
|
&& nl->IsEqual( arg2, UPoint::BasicType()) )
|
|
return nl->TwoElemList(nl->SymbolAtom( Symbol::STREAM() ),
|
|
nl->SymbolAtom( UPoint::BasicType() ));
|
|
|
|
// Error case:
|
|
nl->WriteToString(argstr1, arg1);
|
|
nl->WriteToString(argstr2, arg2);
|
|
ErrorReporter::ReportError(
|
|
"Operator intersection expects argumentlist (T,T), (uT,T), (T,uT), "
|
|
"where T in {ubool, uint, ureal, ustring, upoint}\n or a combination "
|
|
"of {upoint,line}, {upoint,uregion}, {upoint,region}.\n"
|
|
"The passed arguments have types '"+ argstr1 +"' and '"
|
|
+ argstr2 + "'.");
|
|
} else {
|
|
// Error case:
|
|
ErrorReporter::ReportError(
|
|
"Operator intersection expects argumentlist (T,T), (uT,T), (T,uT), "
|
|
"where T in {ubool, uint, ureal, ustring, upoint}\n or a combination of"
|
|
" {upoint,line}, {upoint,uregion}, {upoint,region}.\n");
|
|
}
|
|
return nl->SymbolAtom(Symbol::TYPEERROR());
|
|
|
|
}
|
|
|
|
/*
|
|
5.26.2 Value mapping for operator ~intersection~
|
|
|
|
*/
|
|
|
|
struct TUIntersectionLocalInfo
|
|
{
|
|
bool finished;
|
|
int NoOfResults;
|
|
int NoOfResultsDelivered;
|
|
Word resultValues[2]; // Used if at most 2 results can occur
|
|
std::vector<Word> resultValues2; // Used if more than 2 results may occur
|
|
MPoint *mpoint; // Used for upoint x lines
|
|
};
|
|
|
|
// value mapping for constant units (uT uT) -> (stream uT)
|
|
template<class T>
|
|
int temporalUnitIntersection_CU_CU( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
TUIntersectionLocalInfo *sli;
|
|
Word u1, u2;
|
|
T *uv1, *uv2;
|
|
Interval<Instant> iv;
|
|
|
|
// test for overlapping intervals
|
|
switch( message )
|
|
{
|
|
case OPEN:
|
|
|
|
#ifdef TUA_DEBUG
|
|
cout << "temporalUnitIntersection_CU_CU: received OPEN" << endl;
|
|
#endif
|
|
sli = new TUIntersectionLocalInfo;
|
|
sli->finished = true;
|
|
sli->NoOfResults = 0;
|
|
sli->NoOfResultsDelivered = 0;
|
|
|
|
u1 = args[0];
|
|
u2 = args[1];
|
|
|
|
uv1 = (T*) (u1.addr);
|
|
uv2 = (T*) (u2.addr);
|
|
|
|
if ( uv1->IsDefined() &&
|
|
uv2->IsDefined() &&
|
|
uv1->timeInterval.Intersects( uv2->timeInterval ) &&
|
|
uv1->EqualValue(*uv2) )
|
|
{ // get intersection of deftime intervals
|
|
uv1->timeInterval.Intersection( uv2->timeInterval, iv );
|
|
#ifdef TUA_DEBUG
|
|
cout << " iv=" << TUPrintTimeInterval( iv ) << endl;
|
|
#endif
|
|
// store result
|
|
(sli->resultValues[sli->NoOfResults]).setAddr( uv1->Clone() );
|
|
((T*)(sli->resultValues[sli->NoOfResults].addr))->timeInterval = iv;
|
|
sli->NoOfResults++;
|
|
sli->finished = false;
|
|
#ifdef TUA_DEBUG
|
|
cout << " added result" << endl;
|
|
#endif
|
|
}// else: no result
|
|
local.setAddr(sli);
|
|
#ifdef TUA_DEBUG
|
|
cout << "temporalUnitIntersection_CU_CU: finished OPEN" << endl;
|
|
#endif
|
|
|
|
return 0;
|
|
|
|
case REQUEST:
|
|
|
|
#ifdef TUA_DEBUG
|
|
cout << "temporalUnitIntersection_CU_CU: received REQUEST" << endl;
|
|
#endif
|
|
if(local.addr == 0)
|
|
{
|
|
#ifdef TUA_DEBUG
|
|
cout << "temporalUnitIntersection_CU_CU: CANCEL (1)" << endl;
|
|
#endif
|
|
return CANCEL;
|
|
}
|
|
sli = (TUIntersectionLocalInfo*) local.addr;
|
|
if(sli->finished)
|
|
{
|
|
#ifdef TUA_DEBUG
|
|
cout << "temporalUnitIntersection_CU_CU: CANCEL (2)" << endl;
|
|
#endif
|
|
return CANCEL;
|
|
}
|
|
if(sli->NoOfResultsDelivered < sli->NoOfResults)
|
|
{
|
|
result.setAddr( ((T*)
|
|
(sli->resultValues[sli->NoOfResultsDelivered].addr))->Clone() );
|
|
((T*)(sli->resultValues[sli->NoOfResultsDelivered].addr))
|
|
->DeleteIfAllowed();
|
|
sli->NoOfResultsDelivered++;
|
|
#ifdef TUA_DEBUG
|
|
cout << "temporalUnitIntersection_CU_CU: YIELD" << endl;
|
|
#endif
|
|
return YIELD;
|
|
}
|
|
sli->finished = true;
|
|
#ifdef TUA_DEBUG
|
|
cout << "temporalUnitIntersection_CU_CU: CANCEL (3)" << endl;
|
|
#endif
|
|
return CANCEL;
|
|
|
|
case CLOSE:
|
|
|
|
if (local.addr != 0)
|
|
{
|
|
sli = (TUIntersectionLocalInfo*) local.addr;
|
|
while(sli->NoOfResultsDelivered < sli->NoOfResults)
|
|
{
|
|
((T*)(sli->resultValues[sli->NoOfResultsDelivered].addr))
|
|
->DeleteIfAllowed();
|
|
sli->NoOfResultsDelivered++;
|
|
}
|
|
delete sli;
|
|
local.setAddr(Address(0));
|
|
}
|
|
return 0;
|
|
} // end switch
|
|
|
|
return 0;
|
|
}
|
|
|
|
// value mapping for constant units (uT T) -> (stream uT)
|
|
// and ( T uT) -> (stream uT)
|
|
template<class UT, class T, int uargindex>
|
|
int temporalUnitIntersection_CU_C( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
TUIntersectionLocalInfo *sli;
|
|
Word u1, u2;
|
|
UT *uv1;
|
|
T *uv2;
|
|
Interval<Instant> iv;
|
|
|
|
// test for overlapping intervals
|
|
switch( message )
|
|
{
|
|
case OPEN:
|
|
|
|
#ifdef TUA_DEBUG
|
|
cout << "temporalUnitIntersection_CU_C: received OPEN" << endl;
|
|
#endif
|
|
sli = new TUIntersectionLocalInfo;
|
|
sli->finished = true;
|
|
sli->NoOfResults = 0;
|
|
sli->NoOfResultsDelivered = 0;
|
|
|
|
// get arguments, such that u1 is the unit type
|
|
// and u2 is the simple type
|
|
if (uargindex == 0)
|
|
{ u1 = args[0]; u2 = args[1]; }
|
|
else
|
|
{ u1 = args[1]; u2 = args[0];}
|
|
|
|
#ifdef TUA_DEBUG
|
|
cout << " uargindex =" << uargindex << endl;
|
|
#endif
|
|
uv1 = (UT*) (u1.addr);
|
|
uv2 = (T*) (u2.addr);
|
|
|
|
if ( uv1->IsDefined() &&
|
|
uv2->IsDefined() &&
|
|
(uv1->constValue.Compare( uv2 ) == 0 ) )
|
|
{ // store result
|
|
(sli->resultValues[sli->NoOfResults]).setAddr( uv1->Clone() );
|
|
sli->NoOfResults++;
|
|
sli->finished = false;
|
|
#ifdef TUA_DEBUG
|
|
cout << " Added Result" << endl;
|
|
#endif
|
|
}// else: no result
|
|
local.setAddr(sli);
|
|
#ifdef TUA_DEBUG
|
|
cout << "temporalUnitIntersection_CU_C: finished OPEN" << endl;
|
|
#endif
|
|
return 0;
|
|
|
|
case REQUEST:
|
|
|
|
#ifdef TUA_DEBUG
|
|
cout << "temporalUnitIntersection_CU_C: received REQUEST" << endl;
|
|
#endif
|
|
if(local.addr == 0)
|
|
{
|
|
#ifdef TUA_DEBUG
|
|
cout << "temporalUnitIntersection_CU_C: finished REQUEST: "
|
|
<< "CANCEL (1)" << endl;
|
|
#endif
|
|
return CANCEL;
|
|
}
|
|
sli = (TUIntersectionLocalInfo*) local.addr;
|
|
if(sli->finished)
|
|
{
|
|
#ifdef TUA_DEBUG
|
|
cout << "temporalUnitIntersection_CU_C: finished REQUEST: "
|
|
<< "CANCEL (2)" << endl;
|
|
#endif
|
|
return CANCEL;
|
|
}
|
|
if(sli->NoOfResultsDelivered < sli->NoOfResults)
|
|
{
|
|
result.setAddr( ((UT*)
|
|
(sli->resultValues[sli->NoOfResultsDelivered].addr))->Clone() );
|
|
((UT*)(sli->resultValues[sli->NoOfResultsDelivered].addr))
|
|
->DeleteIfAllowed();
|
|
sli->NoOfResultsDelivered++;
|
|
#ifdef TUA_DEBUG
|
|
cout << "temporalUnitIntersection_CU_C: finished REQUEST: "
|
|
<< "YIELD" << endl;
|
|
#endif
|
|
return YIELD;
|
|
}
|
|
sli->finished = true;
|
|
#ifdef TUA_DEBUG
|
|
cout << "temporalUnitIntersection_CU_C: finished REQUEST: "
|
|
<< "CANCEL (3)" << endl;
|
|
#endif
|
|
return CANCEL;
|
|
|
|
case CLOSE:
|
|
|
|
if (local.addr != 0)
|
|
{
|
|
sli = (TUIntersectionLocalInfo*) local.addr;
|
|
while(sli->NoOfResultsDelivered < sli->NoOfResults)
|
|
{
|
|
((UT*)(sli->resultValues[sli->NoOfResultsDelivered].addr))
|
|
->DeleteIfAllowed();
|
|
sli->NoOfResultsDelivered++;
|
|
}
|
|
delete sli;
|
|
local.setAddr(Address(0));
|
|
}
|
|
return 0;
|
|
} // end switch
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
|
Value mapping for ureal
|
|
|
|
We will calculate the intersection points (time instants) of both ureal
|
|
functions. Therefore, we need to distinguish 2 different cases:
|
|
|
|
1. $ureal_1.r = ureal_2.r$
|
|
|
|
Then, we have to solve the equation
|
|
\[ (a_1-a_2)t^2 + (b_1-b_2)t + (c_1-c_2) = 0 \]
|
|
With $a\neq 0$, this computes to
|
|
\[ t_{1,2} = \frac{-(b_1-b_2) \pm \sqrt{(b_1-b_2)^2 - 4(a_1-a_2)(c_1-c_2)}}
|
|
{2(a_1-a_2)} \]
|
|
|
|
And depending on the value of $D = (b_1-b_2)^2 - 4(a_1-a_2)(c_1-c_2)$, we will
|
|
have 0 ($D<0$), 1 ($D=0$) or 2 ($D>0$) solutions.
|
|
|
|
|
|
2. $ureal_1.r \neq ureal2_.r$
|
|
|
|
Then we have to solve the equation
|
|
\[ {a_1}^2 t^4 + 2 a_1 b_1 t^3 + (2 a_1 c_1 + {b_1}^2 - a_2)
|
|
t^2 + (2 b_1 c_1 - b_2) t - c_2 = 0 \]
|
|
|
|
where $x_1$ stands for parameters from the
|
|
~ureal~ value that does have $r = false$, $x_2$ for the parameters of the
|
|
~ureal~ value with $r = true$.
|
|
|
|
*/
|
|
struct MappingUnitIntersection_rLocalInfo {
|
|
bool finished;
|
|
int NoOfResults; // total number of results
|
|
int ResultsDelivered; // number of results already delivered
|
|
std::vector<UReal> resvector; // the results
|
|
};
|
|
|
|
int temporalUnitIntersection_ureal_ureal( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
MappingUnitIntersection_rLocalInfo *localinfo;
|
|
UReal *ureal1, *ureal2;
|
|
Word a0, a1;
|
|
Periods result_times(2);
|
|
|
|
switch (message)
|
|
{
|
|
case OPEN :
|
|
|
|
localinfo = new MappingUnitIntersection_rLocalInfo;
|
|
local.setAddr(localinfo);
|
|
localinfo->finished = true;
|
|
localinfo->resvector.clear();
|
|
localinfo->NoOfResults = 0;
|
|
localinfo->ResultsDelivered = 0;
|
|
|
|
// initialize arguments, such that a0 always contains the UReal
|
|
// and a1 the CcReal
|
|
a0 = args[0]; a1 = args[1];
|
|
ureal1 = (UReal*)(a0.addr);
|
|
ureal2 = (UReal*)(a1.addr);
|
|
if ( !ureal1->IsDefined() ||
|
|
!ureal2->IsDefined() )
|
|
{ // some input is undefined -> return empty stream
|
|
return 0;
|
|
}
|
|
|
|
// call int UReal::PeriodsAtEqual( UReal& other, Periods& times)
|
|
localinfo->NoOfResults = ureal1->PeriodsAtEqual( *ureal2, result_times);
|
|
// cout << "temporalUnitIntersection_ureal_ureal(): NoOfResults="
|
|
// << localinfo->NoOfResults << endl;
|
|
localinfo->finished = (localinfo->NoOfResults <= 0);
|
|
for(int i=0; i<localinfo->NoOfResults; i++)
|
|
{ // create result vector
|
|
UReal unit(true);
|
|
Interval<Instant> iv;
|
|
// cout << "temporalUnitIntersection_ureal_ureal(): Processing interval "
|
|
// << i << endl;
|
|
result_times.Get(i, iv);
|
|
if( iv.start == iv.end )
|
|
{ // simplify result to constant
|
|
datetime::DateTime T(datetime::durationtype);
|
|
T = iv.start - ureal1->timeInterval.start;
|
|
double t = T.ToDouble();
|
|
double value = ureal1->a*t*t + ureal1->b*t + ureal1->c;
|
|
value = ureal1->r ? sqrt(value) : value;
|
|
unit = UReal(iv, 0.0, 0.0, value, false);
|
|
}
|
|
else
|
|
ureal1->AtInterval(iv, unit);
|
|
localinfo->resvector.push_back(unit);
|
|
// cout << "temporalUnitIntersection_ureal_ureal(): Added unit ";
|
|
// unit.Print(cout);
|
|
cout << endl;
|
|
}
|
|
localinfo->finished = ( localinfo->NoOfResults <= 0 );
|
|
// cout << "temporalUnitIntersection_ureal_ureal(): NoOfResults="
|
|
// << localinfo->NoOfResults << endl
|
|
// << "temporalUnitIntersection_ureal_ureal(): finished="
|
|
// << localinfo->finished << endl;
|
|
return 0;
|
|
|
|
case REQUEST :
|
|
|
|
if (local.addr == 0)
|
|
return CANCEL;
|
|
localinfo = (MappingUnitIntersection_rLocalInfo*) local.addr;
|
|
|
|
if (localinfo->finished)
|
|
return CANCEL;
|
|
if ( localinfo->NoOfResults <= localinfo->ResultsDelivered )
|
|
{ localinfo->finished = true;
|
|
return CANCEL;
|
|
}
|
|
result =
|
|
SetWord(localinfo->resvector[localinfo->ResultsDelivered].Clone());
|
|
localinfo->ResultsDelivered++;
|
|
return YIELD;
|
|
|
|
case CLOSE :
|
|
|
|
if (local.addr != 0)
|
|
{
|
|
localinfo = (MappingUnitIntersection_rLocalInfo*) local.addr;
|
|
delete localinfo;
|
|
local.setAddr(Address(0));
|
|
}
|
|
return 0;
|
|
} // end switch
|
|
|
|
// should not be reached
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
// value mapping for constant units (uT T) -> (stream uT)
|
|
// and ( T uT) -> (stream uT)
|
|
template<int uargindex>
|
|
int temporalUnitIntersection_ureal_real( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
MappingUnitIntersection_rLocalInfo *localinfo;
|
|
UReal *uinput;
|
|
CcReal *value;
|
|
Word a0, a1;
|
|
|
|
switch (message)
|
|
{
|
|
case OPEN :
|
|
|
|
localinfo = new MappingUnitIntersection_rLocalInfo;
|
|
local.setAddr(localinfo);
|
|
localinfo->finished = true;
|
|
localinfo->NoOfResults = 0;
|
|
localinfo->ResultsDelivered = 0;
|
|
|
|
// initialize arguments, such that a0 always contains the UReal
|
|
// and a1 the CcReal
|
|
if (uargindex == 0)
|
|
{ a0 = args[0]; a1 = args[1]; }
|
|
else
|
|
{ a0 = args[1]; a1 = args[0]; }
|
|
|
|
uinput = (UReal*)(a0.addr);
|
|
value = (CcReal*)(a1.addr);
|
|
if ( !uinput->IsDefined() ||
|
|
!value->IsDefined() )
|
|
{ // some input is undefined -> return empty stream
|
|
localinfo->NoOfResults = 0;
|
|
localinfo->finished = true;
|
|
return 0;
|
|
}
|
|
|
|
// call UReal::AtValue(CcReal value, vector<UReal>& result)
|
|
localinfo->NoOfResults = uinput->AtValue(*value, localinfo->resvector);
|
|
localinfo->finished = (localinfo->NoOfResults <= 0);
|
|
return 0;
|
|
|
|
case REQUEST :
|
|
|
|
if (local.addr == 0)
|
|
return CANCEL;
|
|
localinfo = (MappingUnitIntersection_rLocalInfo*) local.addr;
|
|
|
|
if (localinfo->finished)
|
|
return CANCEL;
|
|
if ( localinfo->NoOfResults <= localinfo->ResultsDelivered )
|
|
{ localinfo->finished = true;
|
|
return CANCEL;
|
|
}
|
|
result =
|
|
SetWord(localinfo->resvector[localinfo->ResultsDelivered].Clone());
|
|
localinfo->ResultsDelivered++;
|
|
return YIELD;
|
|
|
|
case CLOSE :
|
|
|
|
if (local.addr != 0)
|
|
{
|
|
localinfo = (MappingUnitIntersection_rLocalInfo*) local.addr;
|
|
delete localinfo;
|
|
local.setAddr(Address(0));
|
|
}
|
|
return 0;
|
|
} // end switch
|
|
|
|
// should not be reached
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
|
|
value mapping for
|
|
|
|
----
|
|
(upoint upoint) -> (stream upoint)
|
|
|
|
----
|
|
|
|
*/
|
|
int
|
|
temporalUnitIntersection_upoint_upoint( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
TUIntersectionLocalInfo *sli;
|
|
Word u1, u2;
|
|
UPoint *uv1, *uv2, *res;
|
|
|
|
// test for overlapping intervals
|
|
switch( message )
|
|
{
|
|
case OPEN:
|
|
|
|
#ifdef TUA_DEBUG
|
|
cout << "temporalUnitIntersection_upoint_upoint: received OPEN" << endl;
|
|
#endif
|
|
sli = new TUIntersectionLocalInfo;
|
|
sli->finished = true;
|
|
sli->NoOfResults = 0;
|
|
sli->NoOfResultsDelivered = 0;
|
|
local.setAddr(sli);
|
|
u1 = args[0];
|
|
u2 = args[1];
|
|
uv1 = (UPoint*) (u1.addr);
|
|
uv2 = (UPoint*) (u2.addr);
|
|
res = new UPoint( false );
|
|
uv1->Intersection(*uv2, *res);
|
|
if ( res->IsDefined() && res->timeInterval.Inside(uv1->timeInterval) &&
|
|
res->timeInterval.Inside(uv2->timeInterval) )
|
|
{ // 2nd and 3rd condition guarantees, that results on "open borders"
|
|
// are filtered out
|
|
(sli->resultValues[sli->NoOfResults]).setAddr( res );
|
|
sli->NoOfResults++;
|
|
sli->finished = false;
|
|
}
|
|
else
|
|
delete( res );
|
|
#ifdef TUA_DEBUG
|
|
cout << "temporalUnitIntersection_upoint_upoint: finished OPEN (6)"
|
|
<< endl;
|
|
#endif
|
|
return 0;
|
|
|
|
case REQUEST:
|
|
|
|
#ifdef TUA_DEBUG
|
|
cout << "temporalUnitIntersection_upoint_upoint: received REQUEST"
|
|
<< endl;
|
|
#endif
|
|
if(local.addr == 0)
|
|
{
|
|
#ifdef TUA_DEBUG
|
|
cout << "temporalUnitIntersection_upoint_upoint: CANCEL (1)"
|
|
<< endl;
|
|
#endif
|
|
return CANCEL;
|
|
}
|
|
sli = (TUIntersectionLocalInfo*) local.addr;
|
|
if(sli->finished)
|
|
{
|
|
#ifdef TUA_DEBUG
|
|
cout << "temporalUnitIntersection_upoint_upoint: CANCEL (2)"
|
|
<< endl;
|
|
#endif
|
|
return CANCEL;
|
|
}
|
|
#ifdef TUA_DEBUG
|
|
cout << " NoOfResults=" << sli->NoOfResults << endl
|
|
<< " NoOfResultsDelivered=" << sli->NoOfResultsDelivered
|
|
<< endl;
|
|
#endif
|
|
if(sli->NoOfResultsDelivered < sli->NoOfResults)
|
|
{
|
|
result.setAddr( ((UPoint*)
|
|
(sli->resultValues[sli->NoOfResultsDelivered].addr))->Clone() );
|
|
((UPoint*)(sli->resultValues[sli->NoOfResultsDelivered].addr))
|
|
->DeleteIfAllowed();
|
|
sli->NoOfResultsDelivered++;
|
|
#ifdef TUA_DEBUG
|
|
cout << "temporalUnitIntersection_upoint_upoint: YIELD"
|
|
<< endl;
|
|
#endif
|
|
return YIELD;
|
|
}
|
|
sli->finished = true;
|
|
#ifdef TUA_DEBUG
|
|
cout << "temporalUnitIntersection_upoint_upoint: CANCEL (3)" << endl;
|
|
#endif
|
|
return CANCEL;
|
|
|
|
case CLOSE:
|
|
|
|
if (local.addr != 0)
|
|
{
|
|
sli = (TUIntersectionLocalInfo*) local.addr;
|
|
while(sli->NoOfResultsDelivered < sli->NoOfResults)
|
|
{
|
|
((UPoint*)(sli->resultValues[sli->NoOfResultsDelivered].addr))
|
|
->DeleteIfAllowed();
|
|
sli->NoOfResultsDelivered++;
|
|
}
|
|
delete sli;
|
|
local.setAddr(0);
|
|
}
|
|
return 0;
|
|
} // end switch
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
value mapping for (upoint point) -> (stream upoint)
|
|
and (point upoint) -> (stream upoint)
|
|
|
|
is identical with at: (upoint point) -> (stream upoint).
|
|
We just add switches for both signatures and the stream framework
|
|
|
|
*/
|
|
|
|
template<int uargindex>
|
|
int
|
|
temporalUnitIntersection_upoint_point( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
TUIntersectionLocalInfo *sli;
|
|
Word a0, a1;
|
|
UPoint *unit, pResult(true);
|
|
Point *val;
|
|
|
|
|
|
switch( message )
|
|
{
|
|
case OPEN:
|
|
|
|
sli = new TUIntersectionLocalInfo;
|
|
sli->finished = true;
|
|
sli->NoOfResults = 0;
|
|
sli->NoOfResultsDelivered = 0;
|
|
local.setAddr(sli);
|
|
|
|
if (uargindex == 0)
|
|
{ a0 = args[0]; a1 = args[1]; }
|
|
else
|
|
{ a0 = args[1]; a1 = args[0]; }
|
|
|
|
unit = ((UPoint*)a0.addr);
|
|
val = ((Point*) a1.addr);
|
|
|
|
if ( !unit->IsDefined() || !val->IsDefined() )
|
|
return 0;
|
|
|
|
if (unit->At( *val, pResult ))
|
|
{
|
|
pResult.SetDefined(true);
|
|
pResult.timeInterval.start.SetDefined(true);
|
|
pResult.timeInterval.end.SetDefined(true);
|
|
(sli->resultValues[sli->NoOfResults]).setAddr( pResult.Clone() );
|
|
sli->NoOfResults++;
|
|
sli->finished = false;
|
|
}
|
|
|
|
return 0;
|
|
|
|
case REQUEST:
|
|
|
|
if(local.addr == 0)
|
|
return CANCEL;
|
|
sli = (TUIntersectionLocalInfo*) local.addr;
|
|
if(sli->finished)
|
|
return CANCEL;
|
|
if(sli->NoOfResultsDelivered < sli->NoOfResults)
|
|
{
|
|
result.setAddr( ((UPoint*)
|
|
(sli->resultValues[sli->NoOfResultsDelivered].addr))->Clone() );
|
|
((UPoint*)(sli->resultValues[sli->NoOfResultsDelivered].addr))
|
|
->DeleteIfAllowed();
|
|
sli->NoOfResultsDelivered++;
|
|
return YIELD;
|
|
}
|
|
sli->finished = true;
|
|
return CANCEL;
|
|
|
|
case CLOSE:
|
|
|
|
if (local.addr != 0)
|
|
{
|
|
sli = (TUIntersectionLocalInfo*) local.addr;
|
|
while(sli->NoOfResultsDelivered < sli->NoOfResults)
|
|
{
|
|
((UPoint*)(sli->resultValues[sli->NoOfResultsDelivered].addr))
|
|
->DeleteIfAllowed();
|
|
sli->NoOfResultsDelivered++;
|
|
}
|
|
delete sli;
|
|
local.setAddr(0);
|
|
}
|
|
return 0;
|
|
} // end switch
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
Value mapping for
|
|
|
|
----
|
|
|
|
intersection: (upoint line) -> (stream upoint)
|
|
(line upoint) -> (stream upoint)
|
|
|
|
----
|
|
|
|
Method ~TUUPointInsideLine~
|
|
|
|
Copied from TempralLiftedAlgebra
|
|
|
|
calculates the periods where the given UPoint lies
|
|
inside the given Line. It returns the existing intervals in a Periods-Object.
|
|
|
|
*/
|
|
static void TUUPointInsideLine(UPoint *u, Line& ln, Periods& pResult)
|
|
{
|
|
#ifdef TUA_DEBUG
|
|
cout<<"MPointLineInside called"<<endl;
|
|
#endif
|
|
pResult.Clear();
|
|
if( !u->IsDefined() || !ln.IsDefined() ){
|
|
pResult.SetDefined( false );
|
|
return;
|
|
}
|
|
pResult.SetDefined( true );
|
|
|
|
HalfSegment l;
|
|
|
|
const UPoint* up = (UPoint*) u;
|
|
Periods* period = new Periods(0);
|
|
Periods* between = new Periods(0);
|
|
Point pt;
|
|
Interval<Instant> newper; //part of the result
|
|
|
|
#ifdef TUA_DEBUG
|
|
cout << "up = " << *up << endl;
|
|
#endif
|
|
|
|
for( int n = 0; n < ln.Size(); n++)
|
|
{
|
|
Instant t;
|
|
ln.Get(n, l);
|
|
#ifdef TUA_DEBUG
|
|
cout << "up = " << *up << endl;
|
|
cout << "ln: Segment # "<< n << " l = " << l << endl;
|
|
#endif
|
|
if (l.GetRightPoint().GetX() == l.GetDomPoint().GetX()
|
|
&& l.GetRightPoint().GetY() == l.GetDomPoint().GetY()) {
|
|
#ifdef TUA_DEBUG
|
|
cout<<"right point is dominating -> continue"<<endl;
|
|
#endif
|
|
continue;
|
|
}
|
|
if(( l.GetRightPoint().GetX() < up->p0.GetX()
|
|
&& l.GetRightPoint().GetX() < up->p1.GetX())
|
|
|| (l.GetLeftPoint().GetX() > up->p0.GetX()
|
|
&& l.GetLeftPoint().GetX() > up->p1.GetX())
|
|
|| (l.GetRightPoint().GetY() < up->p0.GetY()
|
|
&& l.GetRightPoint().GetY() < up->p1.GetY()
|
|
&& (l.GetLeftPoint().GetY() < up->p0.GetY()
|
|
&& l.GetLeftPoint().GetY() < up->p1.GetY()))
|
|
|| (l.GetRightPoint().GetY() > up->p0.GetY()
|
|
&& l.GetRightPoint().GetY() > up->p1.GetY()
|
|
&& (l.GetLeftPoint().GetY() > up->p0.GetY()
|
|
&& l.GetLeftPoint().GetY() > up->p1.GetY()))) {
|
|
#ifdef TUA_DEBUG
|
|
cout<<"Bounding Boxes not crossing!"<<endl;
|
|
#endif
|
|
continue;
|
|
}
|
|
double al=0.0, bl=0.0, aup=0.0, bup=0.0;
|
|
bool vl, vup;
|
|
vl = l.GetRightPoint().GetX() == l.GetLeftPoint().GetX();
|
|
if(!vl){
|
|
al = (l.GetRightPoint().GetY() - l.GetLeftPoint().GetY())
|
|
/ (l.GetRightPoint().GetX() - l.GetLeftPoint().GetX());
|
|
bl = l.GetLeftPoint().GetY() - l.GetLeftPoint().GetX() * al;
|
|
#ifdef TUA_DEBUG
|
|
cout<<"al: "<<al<<" bl: "<<bl<<endl;
|
|
#endif
|
|
}
|
|
#ifdef TUA_DEBUG
|
|
else
|
|
cout<<"l is vertical"<<endl;
|
|
#endif
|
|
vup = up->p1.GetX() == up->p0.GetX();
|
|
if(!vup){
|
|
aup = (up->p1.GetY() - up->p0.GetY())
|
|
/ (up->p1.GetX() - up->p0.GetX());
|
|
bup = up->p0.GetY() - up->p0.GetX() * aup;
|
|
#ifdef TUA_DEBUG
|
|
cout<<"aup: "<<aup<<" bup: "<<bup<<endl;
|
|
#endif
|
|
}
|
|
#ifdef TUA_DEBUG
|
|
else
|
|
cout<<"up is vertical"<<endl;
|
|
#endif
|
|
if(vl && vup){
|
|
#ifdef TUA_DEBUG
|
|
cout<<"both elements are vertical!"<<endl;
|
|
#endif
|
|
if(up->p1.GetX() != l.GetLeftPoint().GetX()){
|
|
#ifdef TUA_DEBUG
|
|
cout<<"elements are vertical but not at same line"<<endl;
|
|
#endif
|
|
continue;
|
|
}
|
|
else {
|
|
#ifdef TUA_DEBUG
|
|
cout<<"elements on same line"<<endl;
|
|
#endif
|
|
if(up->p1.GetY() < l.GetLeftPoint().GetY()
|
|
&& up->p0.GetY() < l.GetLeftPoint().GetY()){
|
|
#ifdef TUA_DEBUG
|
|
cout<<"uPoint lower as linesegment"<<endl;
|
|
#endif
|
|
continue;
|
|
}
|
|
else if(up->p1.GetY() > l.GetRightPoint().GetY()
|
|
&& up->p0.GetY() > l.GetRightPoint().GetY()){
|
|
#ifdef TUA_DEBUG
|
|
cout<<"uPoint higher as linesegment"<<endl;
|
|
#endif
|
|
continue;
|
|
}
|
|
else{
|
|
#ifdef TUA_DEBUG
|
|
cout<<"uPoint and linesegment partequal"<<endl;
|
|
#endif
|
|
if (up->p0.GetY() <= l.GetLeftPoint().GetY()
|
|
&& up->p1.GetY() >= l.GetLeftPoint().GetY()){
|
|
#ifdef TUA_DEBUG
|
|
cout<<"uPoint starts below linesegemet"<<endl;
|
|
#endif
|
|
t.ReadFrom((l.GetLeftPoint().GetY() - up->p0.GetY())
|
|
/ (up->p1.GetY() - up->p0.GetY())
|
|
* (up->timeInterval.end.ToDouble()
|
|
- up->timeInterval.start.ToDouble())
|
|
+ up->timeInterval.start.ToDouble());
|
|
t.SetType(datetime::instanttype);
|
|
#ifdef TUA_DEBUG
|
|
cout<<"t "<<t.ToString()<<endl;
|
|
#endif
|
|
newper.start = t;
|
|
newper.lc = (up->timeInterval.start == t)
|
|
? up->timeInterval.lc : true;
|
|
}
|
|
if(up->p1.GetY() <= l.GetLeftPoint().GetY()
|
|
&& up->p0.GetY() >= l.GetLeftPoint().GetY()){
|
|
#ifdef TUA_DEBUG
|
|
cout<<"uPoint ends below linesegemet"<<endl;
|
|
#endif
|
|
t.ReadFrom((l.GetLeftPoint().GetY() - up->p0.GetY())
|
|
/ (up->p1.GetY() - up->p0.GetY())
|
|
* (up->timeInterval.end.ToDouble()
|
|
- up->timeInterval.start.ToDouble())
|
|
+ up->timeInterval.start.ToDouble());
|
|
t.SetType(datetime::instanttype);
|
|
#ifdef TUA_DEBUG
|
|
cout<<"t "<<t.ToString()<<endl;
|
|
#endif
|
|
newper.end = t;
|
|
newper.rc = (up->timeInterval.end == t)
|
|
? up->timeInterval.rc : true;
|
|
}
|
|
if(up->p0.GetY() <= l.GetRightPoint().GetY()
|
|
&& up->p1.GetY() >= l.GetRightPoint().GetY()){
|
|
#ifdef TUA_DEBUG
|
|
cout<<"uPoint ends above linesegemet"<<endl;
|
|
#endif
|
|
t.ReadFrom((l.GetRightPoint().GetY() - up->p0.GetY())
|
|
/ (up->p1.GetY() - up->p0.GetY())
|
|
* (up->timeInterval.end.ToDouble()
|
|
- up->timeInterval.start.ToDouble())
|
|
+ up->timeInterval.start.ToDouble());
|
|
t.SetType(datetime::instanttype);
|
|
#ifdef TUA_DEBUG
|
|
cout<<"t "<<t.ToString()<<endl;
|
|
#endif
|
|
newper.end = t;
|
|
newper.rc = (up->timeInterval.end == t)
|
|
? up->timeInterval.rc : true;
|
|
}
|
|
if(up->p1.GetY() <= l.GetRightPoint().GetY()
|
|
&& up->p0.GetY() >= l.GetRightPoint().GetY()){
|
|
#ifdef TUA_DEBUG
|
|
cout<<"uPoint starts above linesegemet"<<endl;
|
|
#endif
|
|
t.ReadFrom((l.GetRightPoint().GetY() - up->p0.GetY())
|
|
/ (up->p1.GetY() - up->p0.GetY())
|
|
* (up->timeInterval.end.ToDouble()
|
|
- up->timeInterval.start.ToDouble())
|
|
+ up->timeInterval.start.ToDouble());
|
|
t.SetType(datetime::instanttype);
|
|
#ifdef TUA_DEBUG
|
|
cout<<"t "<<t.ToString()<<endl;
|
|
#endif
|
|
newper.start = t;
|
|
newper.lc = (up->timeInterval.start == t)
|
|
? up->timeInterval.lc : true;
|
|
}
|
|
if (up->p0.GetY() <= l.GetRightPoint().GetY()
|
|
&& up->p0.GetY() >= l.GetLeftPoint().GetY()){
|
|
#ifdef TUA_DEBUG
|
|
cout<<"uPoint starts inside linesegemet"<<endl;
|
|
#endif
|
|
newper.start = up->timeInterval.start;
|
|
newper.lc = up->timeInterval.lc;
|
|
}
|
|
if( up->p1.GetY() <= l.GetRightPoint().GetY()
|
|
&& up->p1.GetY() >= l.GetLeftPoint().GetY()){
|
|
#ifdef TUA_DEBUG
|
|
cout<<"uPoint ends inside linesegemet"<<endl;
|
|
#endif
|
|
newper.end = up->timeInterval.end;
|
|
newper.rc = up->timeInterval.rc;
|
|
}
|
|
if(newper.start == newper.end
|
|
&& (!newper.lc || !newper.rc)){
|
|
#ifdef TUA_DEBUG
|
|
cout<<"not an interval"<<endl;
|
|
#endif
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if(vl){
|
|
#ifdef TUA_DEBUG
|
|
cout<<"vl is vertical vup not"<<endl;
|
|
#endif
|
|
t.ReadFrom((l.GetRightPoint().GetX() - up->p0.GetX())
|
|
/ (up->p1.GetX() - up->p0.GetX())
|
|
* (up->timeInterval.end.ToDouble()
|
|
- up->timeInterval.start.ToDouble())
|
|
+ up->timeInterval.start.ToDouble());
|
|
t.SetType(datetime::instanttype);
|
|
#ifdef TUA_DEBUG
|
|
cout<<"t "<<t.ToString()<<endl;
|
|
#endif
|
|
if((up->timeInterval.start == t && !up->timeInterval.lc)
|
|
|| (up->timeInterval.end == t && !up->timeInterval.rc))
|
|
continue;
|
|
|
|
if(up->timeInterval.start > t|| up->timeInterval.end < t){
|
|
#ifdef TUA_DEBUG
|
|
cout<<"up outside line"<<endl;
|
|
#endif
|
|
continue;
|
|
}
|
|
up->TemporalFunction(t, pt);
|
|
if( pt.GetX() < l.GetLeftPoint().GetX() ||
|
|
pt.GetX() > l.GetRightPoint().GetX()
|
|
|| (pt.GetY() < l.GetLeftPoint().GetY() &&
|
|
pt.GetY() < l.GetRightPoint().GetY())
|
|
|| (pt.GetY() > l.GetLeftPoint().GetY() &&
|
|
pt.GetY() > l.GetRightPoint().GetY())){
|
|
#ifdef TUA_DEBUG
|
|
cout<<"pt outside up!"<<endl;
|
|
#endif
|
|
continue;
|
|
}
|
|
|
|
newper.start = t;
|
|
newper.lc = true;
|
|
newper.end = t;
|
|
newper.rc = true;
|
|
}
|
|
else if(vup){
|
|
#ifdef TUA_DEBUG
|
|
cout<<"vup is vertical vl not"<<endl;
|
|
#endif
|
|
if(up->p1.GetY() != up->p0.GetY()) {
|
|
t.ReadFrom((up->p0.GetX() * al + bl - up->p0.GetY())
|
|
/ (up->p1.GetY() - up->p0.GetY())
|
|
* (up->timeInterval.end.ToDouble()
|
|
- up->timeInterval.start.ToDouble())
|
|
+ up->timeInterval.start.ToDouble());
|
|
t.SetType(datetime::instanttype);
|
|
#ifdef TUA_DEBUG
|
|
cout<<"t "<<t.ToString()<<endl;
|
|
#endif
|
|
if((up->timeInterval.start == t && !up->timeInterval.lc)
|
|
|| (up->timeInterval.end == t && !up->timeInterval.rc)){
|
|
#ifdef TUA_DEBUG
|
|
cout<<"continue"<<endl;
|
|
#endif
|
|
continue;
|
|
}
|
|
|
|
if(up->timeInterval.start > t|| up->timeInterval.end < t){
|
|
#ifdef TUA_DEBUG
|
|
cout<<"up outside line"<<endl;
|
|
#endif
|
|
continue;
|
|
}
|
|
up->TemporalFunction(t, pt);
|
|
if( pt.GetX() < l.GetLeftPoint().GetX() ||
|
|
pt.GetX() > l.GetRightPoint().GetX()
|
|
|| (pt.GetY() < l.GetLeftPoint().GetY() &&
|
|
pt.GetY() < l.GetRightPoint().GetY())
|
|
|| (pt.GetY() > l.GetLeftPoint().GetY() &&
|
|
pt.GetY() > l.GetRightPoint().GetY())){
|
|
#ifdef TUA_DEBUG
|
|
cout<<"pt outside up!"<<endl;
|
|
#endif
|
|
continue;
|
|
}
|
|
|
|
newper.start = t;
|
|
newper.lc = true;
|
|
newper.end = t;
|
|
newper.rc = true;
|
|
}
|
|
else {
|
|
#ifdef TUA_DEBUG
|
|
cout<<"up is not moving"<<endl;
|
|
#endif
|
|
if(al * up->p1.GetX() + bl == up->p1.GetY()){
|
|
#ifdef TUA_DEBUG
|
|
cout<<"Point lies on line"<<endl;
|
|
#endif
|
|
newper = up->timeInterval;
|
|
}
|
|
else {
|
|
#ifdef TUA_DEBUG
|
|
cout<<"continue 2"<<endl;
|
|
#endif
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
else if(aup == al){
|
|
#ifdef TUA_DEBUG
|
|
cout<<"both lines have same gradient"<<endl;
|
|
#endif
|
|
if(bup != bl){
|
|
#ifdef TUA_DEBUG
|
|
cout<<"colinear but not equal"<<endl;
|
|
#endif
|
|
continue;
|
|
}
|
|
if(up->p0.GetX() <= l.GetLeftPoint().GetX()
|
|
&& up->p1.GetX() >= l.GetLeftPoint().GetX()){
|
|
#ifdef TUA_DEBUG
|
|
cout<<"uPoint starts left of linesegment"<<endl;
|
|
#endif
|
|
t.ReadFrom((l.GetLeftPoint().GetX() - up->p0.GetX())
|
|
/ (up->p1.GetX() - up->p0.GetX())
|
|
* (up->timeInterval.end.ToDouble()
|
|
- up->timeInterval.start.ToDouble())
|
|
+ up->timeInterval.start.ToDouble());
|
|
t.SetType(datetime::instanttype);
|
|
#ifdef TUA_DEBUG
|
|
cout<<"t "<<t.ToString()<<endl;
|
|
#endif
|
|
newper.start = t;
|
|
newper.lc = (up->timeInterval.start == t)
|
|
? up->timeInterval.lc : true;
|
|
}
|
|
if(up->p1.GetX() <= l.GetLeftPoint().GetX()
|
|
&& up->p0.GetX() >= l.GetLeftPoint().GetX()){
|
|
#ifdef TUA_DEBUG
|
|
cout<<"uPoint ends left of linesegment"<<endl;
|
|
#endif
|
|
t.ReadFrom((l.GetLeftPoint().GetX() - up->p0.GetX())
|
|
/ (up->p1.GetX() - up->p0.GetX())
|
|
* (up->timeInterval.end.ToDouble()
|
|
- up->timeInterval.start.ToDouble())
|
|
+ up->timeInterval.start.ToDouble());
|
|
t.SetType(datetime::instanttype);
|
|
#ifdef TUA_DEBUG
|
|
cout<<"t "<<t.ToString()<<endl;
|
|
#endif
|
|
newper.end = t;
|
|
newper.rc = (up->timeInterval.end == t)
|
|
? up->timeInterval.rc : true;
|
|
}
|
|
if(up->p0.GetX() <= l.GetRightPoint().GetX()
|
|
&& up->p1.GetX() >= l.GetRightPoint().GetX()){
|
|
#ifdef TUA_DEBUG
|
|
cout<<"uPoint ends right of linesegment"<<endl;
|
|
#endif
|
|
t.ReadFrom((l.GetRightPoint().GetX() - up->p0.GetX())
|
|
/ (up->p1.GetX() - up->p0.GetX())
|
|
* (up->timeInterval.end.ToDouble()
|
|
- up->timeInterval.start.ToDouble())
|
|
+ up->timeInterval.start.ToDouble());
|
|
t.SetType(datetime::instanttype);
|
|
#ifdef TUA_DEBUG
|
|
cout<<"t "<<t.ToString()<<endl;
|
|
#endif
|
|
newper.end = t;
|
|
newper.rc = (up->timeInterval.end == t)
|
|
? up->timeInterval.rc : true;
|
|
}
|
|
if(up->p1.GetX() <= l.GetRightPoint().GetX()
|
|
&& up->p0.GetX() >= l.GetRightPoint().GetX()){
|
|
#ifdef TUA_DEBUG
|
|
cout<<"uPoint starts right of linesegment"<<endl;
|
|
#endif
|
|
t.ReadFrom((l.GetRightPoint().GetX() - up->p0.GetX())
|
|
/ (up->p1.GetX() - up->p0.GetX())
|
|
* (up->timeInterval.end.ToDouble()
|
|
- up->timeInterval.start.ToDouble())
|
|
+ up->timeInterval.start.ToDouble());
|
|
t.SetType(datetime::instanttype);
|
|
#ifdef TUA_DEBUG
|
|
cout<<"t "<<t.ToString()<<endl;
|
|
#endif
|
|
newper.start = t;
|
|
newper.lc = (up->timeInterval.start == t)
|
|
? up->timeInterval.lc : true;
|
|
}
|
|
if(up->p0.GetX() <= l.GetRightPoint().GetX()
|
|
&& up->p0.GetX() >= l.GetLeftPoint().GetX()){
|
|
#ifdef TUA_DEBUG
|
|
cout<<"uPoint starts inside linesegment"<<endl;
|
|
#endif
|
|
newper.start = up->timeInterval.start;
|
|
newper.lc = up->timeInterval.lc;
|
|
}
|
|
if(up->p1.GetX() <= l.GetRightPoint().GetX()
|
|
&& up->p1.GetX() >= l.GetLeftPoint().GetX()){
|
|
#ifdef TUA_DEBUG
|
|
cout<<"uPoint ends inside linesegment"<<endl;
|
|
#endif
|
|
newper.end = up->timeInterval.end;
|
|
newper.rc = up->timeInterval.rc;
|
|
}
|
|
if(newper.start == newper.end
|
|
&& (!newper.lc || !newper.rc)){
|
|
#ifdef TUA_DEBUG
|
|
cout<<"not an interval"<<endl;
|
|
#endif
|
|
continue;
|
|
}
|
|
} else{
|
|
#ifdef TUA_DEBUG
|
|
cout<<"both lines have different gradients"<<endl;
|
|
#endif
|
|
t.ReadFrom(((bl - bup) / (aup - al) - up->p0.GetX())
|
|
/ (up->p1.GetX() - up->p0.GetX())
|
|
* (up->timeInterval.end.ToDouble()
|
|
- up->timeInterval.start.ToDouble())
|
|
+ up->timeInterval.start.ToDouble());
|
|
t.SetType(datetime::instanttype);
|
|
if((up->timeInterval.start == t && !up->timeInterval.lc)
|
|
|| (up->timeInterval.end == t && !up->timeInterval.rc)){
|
|
#ifdef TUA_DEBUG
|
|
cout<<"continue"<<endl;
|
|
#endif
|
|
continue;
|
|
}
|
|
|
|
if(up->timeInterval.start > t|| up->timeInterval.end < t){
|
|
#ifdef TUA_DEBUG
|
|
cout<<"up outside line"<<endl;
|
|
#endif
|
|
continue;
|
|
}
|
|
up->TemporalFunction(t, pt);
|
|
if( pt.GetX() < l.GetLeftPoint().GetX() ||
|
|
pt.GetX() > l.GetRightPoint().GetX()
|
|
|| (pt.GetY() < l.GetLeftPoint().GetY() &&
|
|
pt.GetY() < l.GetRightPoint().GetY())
|
|
|| (pt.GetY() > l.GetLeftPoint().GetY() &&
|
|
pt.GetY() > l.GetRightPoint().GetY())){
|
|
#ifdef TUA_DEBUG
|
|
cout<<"pt outside up!"<<endl;
|
|
#endif
|
|
continue;
|
|
}
|
|
|
|
newper.start = t;
|
|
newper.lc = true;
|
|
newper.end = t;
|
|
newper.rc = true;
|
|
}
|
|
#ifdef TUA_DEBUG
|
|
cout<<"newper ["<< newper.start.ToString()<<" "<<newper.end.ToString()
|
|
<<" "<<newper.lc<<" "<<newper.rc<<"]"<<endl;
|
|
#endif
|
|
period->Clear();
|
|
period->StartBulkLoad();
|
|
period->Add(newper);
|
|
period->EndBulkLoad(false);
|
|
if (!pResult.IsEmpty()) {
|
|
between->Clear();
|
|
period->Union(pResult, *between);
|
|
pResult.Clear();
|
|
pResult.CopyFrom(between);
|
|
}
|
|
else{
|
|
pResult.CopyFrom(period);
|
|
}
|
|
} // end for each segment
|
|
delete between;
|
|
delete period;
|
|
}
|
|
|
|
/*
|
|
Method ~TUCompletePeriods2MPoint~
|
|
|
|
Copied from TempralLiftedAlgebra
|
|
|
|
Completes a Periods-value to a MPoint-value. For this it adds the starting
|
|
and end points.
|
|
|
|
*/
|
|
static void TUCompletePeriods2MPoint(UPoint* u, Periods* pResult,
|
|
MPoint* endResult){
|
|
#ifdef TUA_DEBUG
|
|
cout<<"TUCompletePeriods2MPoint called"<<endl;
|
|
#endif
|
|
endResult->Clear();
|
|
if( !u->IsDefined() || !pResult->IsDefined() ){
|
|
endResult->SetDefined( false );
|
|
return;
|
|
}
|
|
endResult->SetDefined( true );
|
|
|
|
const UPoint* up = (UPoint*) u;
|
|
Interval<Instant> per;
|
|
UPoint newUp(true);
|
|
Point pt;
|
|
int m = 0;
|
|
bool pfinished = (pResult->GetNoComponents() == 0);
|
|
endResult->StartBulkLoad();
|
|
for ( int i = 0; i < 1; i++) {
|
|
if(!up->IsDefined())
|
|
continue;
|
|
#ifdef TUA_DEBUG
|
|
cout<<"*up = "<< *up <<endl;
|
|
#endif
|
|
if(!pfinished) {
|
|
pResult->Get(m, per);
|
|
#ifdef TUA_DEBUG
|
|
cout<<"per "<<m<<" ["<<per.start.ToString()<<" "
|
|
<<per.end.ToString()<<" "<<per.lc<<" "<<per.rc<<"]"<<endl;
|
|
#endif
|
|
}
|
|
if(pfinished) {
|
|
#ifdef TUA_DEBUG
|
|
cout<<"no per any more. break 1"<<endl;
|
|
#endif
|
|
break;
|
|
}
|
|
if(!(pfinished || up->timeInterval.end < per.start
|
|
|| (up->timeInterval.end == per.start
|
|
&& !up->timeInterval.rc && per.lc))) {
|
|
#ifdef TUA_DEBUG
|
|
cout<<"per not totally after up"<<endl;
|
|
#endif
|
|
if(up->timeInterval.start < per.start
|
|
|| (up->timeInterval.start == per.start
|
|
&& up->timeInterval.lc && !per.lc)) {
|
|
#ifdef TUA_DEBUG
|
|
cout<<"up starts before per"<<endl;
|
|
#endif
|
|
newUp.timeInterval = per;
|
|
}
|
|
else {
|
|
#ifdef TUA_DEBUG
|
|
cout<<"per starts before or with up"<<endl;
|
|
#endif
|
|
newUp.timeInterval.start = up->timeInterval.start;
|
|
newUp.timeInterval.lc = up->timeInterval.lc;
|
|
}
|
|
while(true) {
|
|
if(up->timeInterval.end < per.end
|
|
|| (up->timeInterval.end == per.end
|
|
&& per.rc && !up->timeInterval.rc)) {
|
|
#ifdef TUA_DEBUG
|
|
cout<<"per ends after up (break)"<<endl;
|
|
#endif
|
|
newUp.timeInterval.end = up->timeInterval.end;
|
|
newUp.timeInterval.rc = up->timeInterval.rc;
|
|
up->TemporalFunction(newUp.timeInterval.start, pt, true);
|
|
newUp.p0 = pt;
|
|
up->TemporalFunction(newUp.timeInterval.end, pt, true);
|
|
newUp.p1 = pt;
|
|
#ifdef TUA_DEBUG
|
|
cout<<"Add3 ("<<newUp.p0.GetX()<<" "<<newUp.p0.GetY()
|
|
<<")->("<<newUp.p1.GetX()<<" "<<newUp.p1.GetY()
|
|
<<") ["<<newUp.timeInterval.start.ToString()<<" "
|
|
<<newUp.timeInterval.end.ToString()<<" "
|
|
<<newUp.timeInterval.lc<<" "<<newUp.timeInterval.rc<<"]"<<endl;
|
|
#endif
|
|
endResult->Add(newUp);
|
|
break;
|
|
}
|
|
else {
|
|
#ifdef TUA_DEBUG
|
|
cout<<"per ends inside up"<<endl;
|
|
#endif
|
|
newUp.timeInterval.end = per.end;
|
|
newUp.timeInterval.rc = per.rc;
|
|
up->TemporalFunction(newUp.timeInterval.start, pt, true);
|
|
newUp.p0 = pt;
|
|
up->TemporalFunction(newUp.timeInterval.end, pt, true);
|
|
newUp.p1 = pt;
|
|
#ifdef TUA_DEBUG
|
|
cout<<"Add4 ("<<newUp.p0.GetX()<<" "<<newUp.p0.GetY()
|
|
<<")->("<<newUp.p1.GetX()<<" "<<newUp.p1.GetY()
|
|
<<") ["<<newUp.timeInterval.start.ToString()<<" "
|
|
<<newUp.timeInterval.end.ToString()<<" "
|
|
<<newUp.timeInterval.lc<<" "<<newUp.timeInterval.rc<<"]"<<endl;
|
|
#endif
|
|
endResult->Add(newUp);
|
|
}
|
|
if(m == pResult->GetNoComponents() - 1){
|
|
#ifdef TUA_DEBUG
|
|
cout<<"last per"<<endl;
|
|
#endif
|
|
pfinished = true;
|
|
}
|
|
else {
|
|
pResult->Get(++m, per);
|
|
#ifdef TUA_DEBUG
|
|
cout<<"per "<<m<<" ["<<per.start.ToString()
|
|
<<" "<<per.end.ToString()<<" "<<per.lc<<" "<<per.rc<<"]"<<endl;
|
|
#endif
|
|
}
|
|
if(!pfinished && (per.start < up->timeInterval.end
|
|
|| (per.start == up->timeInterval.end
|
|
&& up->timeInterval.rc && per.rc))){
|
|
#ifdef TUA_DEBUG
|
|
cout<<"next per starts in same up"<<endl;
|
|
#endif
|
|
newUp.timeInterval.start = per.start;
|
|
newUp.timeInterval.lc = per.lc;
|
|
}
|
|
else {
|
|
#ifdef TUA_DEBUG
|
|
cout<<"next interval after up -> finish up"<<endl;
|
|
#endif
|
|
break;
|
|
}
|
|
} //while
|
|
}
|
|
}
|
|
endResult->EndBulkLoad(false);
|
|
}
|
|
|
|
/*
|
|
The value mapping function:
|
|
|
|
*/
|
|
|
|
template<int uargindex>
|
|
int temporalUnitIntersection_upoint_line( Word* args, Word& result,
|
|
int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
TUIntersectionLocalInfo *sli;
|
|
Word a0, a1;
|
|
UPoint res(true);
|
|
UPoint *u;
|
|
Line *l;
|
|
Periods *p;
|
|
|
|
UPoint cu;
|
|
|
|
switch( message )
|
|
{
|
|
case OPEN:
|
|
|
|
#ifdef TUA_DEBUG
|
|
cout << "temporalUnitIntersection_upoint_line<"
|
|
<< uargindex << ">: Received OPEN" << endl;
|
|
#endif
|
|
p = new Periods(10);
|
|
sli = new TUIntersectionLocalInfo;
|
|
sli->finished = true;
|
|
sli->NoOfResults = 0;
|
|
sli->NoOfResultsDelivered = 0;
|
|
sli->mpoint = new MPoint(10);
|
|
local.setAddr(sli);
|
|
|
|
// initialize arguments, such that a0 always contains the upoint
|
|
// and a1 the line
|
|
#ifdef TUA_DEBUG
|
|
cout << " uargindex=" << uargindex << endl;
|
|
#endif
|
|
if (uargindex == 0)
|
|
{ a0 = args[0]; a1 = args[1]; }
|
|
else
|
|
{ a0 = args[1]; a1 = args[0]; }
|
|
u = (UPoint*)(a0.addr);
|
|
l = (Line*)(a1.addr);
|
|
|
|
// test for definedness
|
|
if ( !u->IsDefined() || !l->IsDefined() || l->IsEmpty() )
|
|
{
|
|
#ifdef TUA_DEBUG
|
|
cout << " Undef/Empty arg -> Empty Result" << endl << endl;
|
|
#endif
|
|
// nothing to do
|
|
}
|
|
else
|
|
{
|
|
TUUPointInsideLine(u, *l, *p); // get intersecting timeintervals
|
|
TUCompletePeriods2MPoint(u, p, sli->mpoint); // create upoints
|
|
sli->NoOfResults = sli->mpoint->GetNoComponents();
|
|
sli->finished = (sli->NoOfResults <= 0);
|
|
#ifdef TUA_DEBUG
|
|
cout << " " << sli->NoOfResults << " result units" << endl << endl;
|
|
#endif
|
|
}
|
|
delete p;
|
|
#ifdef TUA_DEBUG
|
|
cout << "temporalUnitIntersection_upoint_line: Finished OPEN"
|
|
<< endl;
|
|
#endif
|
|
return 0;
|
|
|
|
case REQUEST:
|
|
|
|
if(local.addr == 0)
|
|
return CANCEL;
|
|
sli = (TUIntersectionLocalInfo*) local.addr;
|
|
if(sli->finished)
|
|
return CANCEL;
|
|
if(sli->NoOfResultsDelivered < sli->NoOfResults)
|
|
{
|
|
sli->mpoint->Get(sli->NoOfResultsDelivered, cu);
|
|
result.setAddr( cu.Clone() );
|
|
sli->NoOfResultsDelivered++;
|
|
return YIELD;
|
|
}
|
|
sli->finished = true;
|
|
return CANCEL;
|
|
|
|
case CLOSE:
|
|
|
|
if (local.addr != 0)
|
|
{
|
|
sli = (TUIntersectionLocalInfo*) local.addr;
|
|
delete sli->mpoint;
|
|
delete sli;
|
|
local.setAddr(0);
|
|
}
|
|
return 0;
|
|
} // end switch
|
|
|
|
return 0;
|
|
}
|
|
|
|
// for (upoint uregion) -> (stream upoint) (with <0, true>)
|
|
// (uregion upoint) -> (stream upoint) (with <1, true>)
|
|
// (upoint region) -> (stream upoint) (with <0, false>)
|
|
// (region upoint) -> (stream upoint) (with <1, false>)
|
|
//
|
|
template<int uargindex, bool regionismoving>
|
|
int temporalUnitIntersection_upoint_uregion( Word* args, Word& result,
|
|
int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
// This implementation uses class function
|
|
// MRegion::Intersection(MPoint& mp, MPoint& res)
|
|
// by creating a single-unit MRegion and a single-unit MPoint
|
|
// This is not very clever, but is comparable to the implementation found in
|
|
// the MovingRegionAlgebra.
|
|
|
|
TUIntersectionLocalInfo *sli;
|
|
Word a0, a1;
|
|
UPoint *u = 0;
|
|
URegion *r = 0;
|
|
Region *f = 0;
|
|
MPoint *mp_tmp;
|
|
MRegion *mr_tmp;
|
|
UPoint cu;
|
|
|
|
switch( message )
|
|
{
|
|
case OPEN:
|
|
|
|
#ifdef TUA_DEBUG
|
|
std::cerr << "temporalUnitIntersection_upoint_uregion<"
|
|
<< uargindex << ", " << regionismoving
|
|
<< ">: Received OPEN" << endl;
|
|
#endif
|
|
sli = new TUIntersectionLocalInfo;
|
|
sli->finished = true;
|
|
sli->NoOfResults = 0;
|
|
sli->NoOfResultsDelivered = 0;
|
|
sli->mpoint = new MPoint(10);
|
|
local.setAddr(sli);
|
|
|
|
// initialize arguments, such that a0 always contains the upoint
|
|
// and a1 the uregion/region
|
|
#ifdef TUA_DEBUG
|
|
std::cerr << " uargindex=" << uargindex << endl;
|
|
#endif
|
|
if (uargindex == 0)
|
|
{ a0 = args[0]; a1 = args[1]; }
|
|
else if (uargindex == 1)
|
|
{ a0 = args[1]; a1 = args[0]; }
|
|
else
|
|
{
|
|
std::cerr << "temporalUnitIntersection_upoint_uregion<"
|
|
<< uargindex << ", " << regionismoving
|
|
<< ">: WRONG uargindex!" << endl;
|
|
return -1;
|
|
}
|
|
u = (UPoint*)(a0.addr);
|
|
if ( regionismoving )
|
|
r = (URegion*)(a1.addr);
|
|
else
|
|
f = (Region*) (a1.addr);
|
|
|
|
// test for definedness
|
|
if ( !u->IsDefined() ||
|
|
( regionismoving && !r->IsDefined()) ||
|
|
(!regionismoving && !f->IsDefined()) )
|
|
{
|
|
#ifdef TUA_DEBUG
|
|
std::cerr << " Undef arg -> Empty Result" << endl << endl;
|
|
#endif
|
|
// nothing to do
|
|
}
|
|
else
|
|
{
|
|
mp_tmp = new MPoint(1); // create temporary MPoint
|
|
mp_tmp->SetDefined(true);
|
|
mp_tmp->Add(*u);
|
|
|
|
// create temporary MRegion
|
|
if ( regionismoving )
|
|
{ // case (upoint x uregion): from a URegion
|
|
mr_tmp = new MRegion(1);
|
|
mr_tmp->SetDefined(true);
|
|
mr_tmp->AddURegion(*r);
|
|
//mr_tmp.EndBulkLoad();
|
|
assert( mr_tmp->IsDefined() );
|
|
}
|
|
else
|
|
{ // case (upoint x region): from (MPoint,Region)
|
|
mr_tmp = new MRegion(*mp_tmp, *f);
|
|
assert( mr_tmp->IsDefined() );
|
|
}
|
|
mr_tmp->Intersection(*mp_tmp, *(sli->mpoint)); // get and save result;
|
|
delete mp_tmp;
|
|
delete mr_tmp;
|
|
sli->NoOfResults = sli->mpoint->GetNoComponents();
|
|
sli->finished = (sli->NoOfResults <= 0);
|
|
#ifdef TUA_DEBUG
|
|
std::cerr << " " << sli->NoOfResults << " result units"
|
|
<< endl << endl;
|
|
#endif
|
|
}
|
|
#ifdef TUA_DEBUG
|
|
std::cerr << "temporalUnitIntersection_upoint_uregion: Finished OPEN"
|
|
<< endl;
|
|
#endif
|
|
return 0;
|
|
|
|
case REQUEST:
|
|
#ifdef TUA_DEBUG
|
|
std::cerr << "temporalUnitIntersection_upoint_uregion<"
|
|
<< uargindex << ", " << regionismoving
|
|
<< ">: Received REQUEST" << endl;
|
|
#endif
|
|
if(local.addr == 0)
|
|
{
|
|
#ifdef TUA_DEBUG
|
|
std::cerr << "temporalUnitIntersection_upoint_uregion<"
|
|
<< uargindex << ", " << regionismoving
|
|
<< ">: Finished REQUEST (1)" << endl;
|
|
#endif
|
|
return CANCEL;
|
|
}
|
|
sli = (TUIntersectionLocalInfo*) local.addr;
|
|
if(sli->finished)
|
|
{
|
|
#ifdef TUA_DEBUG
|
|
std::cerr << "temporalUnitIntersection_upoint_uregion<"
|
|
<< uargindex << ", " << regionismoving
|
|
<< ">: Finished REQUEST (2)" << endl;
|
|
#endif
|
|
return CANCEL;
|
|
}
|
|
if(sli->NoOfResultsDelivered < sli->NoOfResults)
|
|
{
|
|
sli->mpoint->Get(sli->NoOfResultsDelivered, cu);
|
|
result.setAddr( cu.Clone() );
|
|
sli->NoOfResultsDelivered++;
|
|
#ifdef TUA_DEBUG
|
|
std::cerr << "temporalUnitIntersection_upoint_uregion<"
|
|
<< uargindex << ", " << regionismoving
|
|
<< ">: Finished REQUEST (YIELD)" << endl;
|
|
#endif
|
|
return YIELD;
|
|
}
|
|
sli->finished = true;
|
|
#ifdef TUA_DEBUG
|
|
std::cerr << "temporalUnitIntersection_upoint_uregion<"
|
|
<< uargindex << ", " << regionismoving
|
|
<< ">: Finished REQUEST (3)" << endl;
|
|
#endif
|
|
return CANCEL;
|
|
|
|
case CLOSE:
|
|
|
|
#ifdef TUA_DEBUG
|
|
std::cerr << "temporalUnitIntersection_upoint_uregion<"
|
|
<< uargindex << ", " << regionismoving
|
|
<< ">: Received CLOSE" << endl;
|
|
#endif
|
|
if (local.addr != 0)
|
|
{
|
|
sli = (TUIntersectionLocalInfo*) local.addr;
|
|
delete sli->mpoint;
|
|
delete sli;
|
|
local.setAddr(0);
|
|
}
|
|
#ifdef TUA_DEBUG
|
|
std::cerr << "temporalUnitIntersection_upoint_uregion<"
|
|
<< uargindex << ", " << regionismoving
|
|
<< ">: Finished CLOSE" << endl;
|
|
#endif
|
|
return 0;
|
|
} // end switch
|
|
|
|
std::cerr << "temporalUnitIntersection_upoint_uregion<"
|
|
<< uargindex << ", " << regionismoving
|
|
<< ">: Received UNKNOWN COMMAND" << endl;
|
|
return 0;
|
|
}
|
|
|
|
// For signatures
|
|
// (upoint region) -> (stream upoint) (with <0>)
|
|
// (region upoint) -> (stream upoint) (with <1>)
|
|
|
|
struct TUIntersectionUPointRegionLocalInfo
|
|
{
|
|
TUIntersectionUPointRegionLocalInfo() :
|
|
finished(true), NoOfResults(0), NoOfResultsDelivered(0)
|
|
{ results.clear(); }
|
|
|
|
~TUIntersectionUPointRegionLocalInfo() {}
|
|
|
|
bool finished;
|
|
int NoOfResults;
|
|
int NoOfResultsDelivered;
|
|
std::vector<UPoint> results;
|
|
};
|
|
|
|
template<int uargindex>
|
|
int temporalUnitIntersection_upoint_region( Word* args, Word& result,
|
|
int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
TUIntersectionUPointRegionLocalInfo *sli =
|
|
static_cast<TUIntersectionUPointRegionLocalInfo*>(local.addr);
|
|
Word a0, a1;
|
|
UPoint *u = 0;
|
|
Region *r = 0;
|
|
UPoint cu;
|
|
|
|
switch( message )
|
|
{
|
|
case OPEN:
|
|
|
|
if(sli){
|
|
delete sli;
|
|
}
|
|
sli = new TUIntersectionUPointRegionLocalInfo;
|
|
local.setAddr(sli);
|
|
|
|
// initialize arguments, such that a0 always contains the upoint
|
|
// and a1 the uregion/region
|
|
if (uargindex == 0) {
|
|
a0 = args[0]; a1 = args[1];
|
|
} else if (uargindex == 1) {
|
|
a0 = args[1]; a1 = args[0];
|
|
} else {
|
|
std::cerr << __PRETTY_FUNCTION__ << ": WRONG uargindex!" << endl;
|
|
return -1;
|
|
}
|
|
u = static_cast<UPoint*>(a0.addr);
|
|
r = static_cast<Region*>(a1.addr);
|
|
// test for definedness
|
|
if ( u->IsDefined() && r->IsDefined() ){
|
|
if(u->AtRegion(r, sli->results)) {
|
|
sli->NoOfResults = sli->results.size();
|
|
sli->finished = (sli->NoOfResults <= 0);
|
|
} else {
|
|
std::cerr << __PRETTY_FUNCTION__ << ": INFO: UPoint::AtRegion failed!"
|
|
<< endl;
|
|
}
|
|
}
|
|
return 0;
|
|
|
|
case REQUEST:
|
|
|
|
if( !sli
|
|
|| sli->finished
|
|
|| (sli->NoOfResultsDelivered >= sli->NoOfResults)
|
|
){
|
|
sli->finished = true;
|
|
return CANCEL;
|
|
} else {
|
|
result.setAddr(sli->results[sli->NoOfResultsDelivered].Clone());
|
|
sli->NoOfResultsDelivered++;
|
|
return YIELD;
|
|
}
|
|
|
|
case CLOSE:
|
|
|
|
if (sli) {
|
|
delete sli;
|
|
local.setAddr(0);
|
|
}
|
|
return 0;
|
|
} // end switch
|
|
|
|
std::cerr << __PRETTY_FUNCTION__ << ": Received UNKNOWN COMMAND" << endl;
|
|
return 0;
|
|
}
|
|
|
|
template<int uargindex>
|
|
int temporalUnitIntersection_uregion_region( Word* args, Word& result,
|
|
int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
std::cerr << "temporalUnitIntersection_uregion_region(): Not yet Implemented!"
|
|
<< endl;
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
5.26.3 Specification for operator ~intersection~
|
|
|
|
*/
|
|
|
|
const std::string TemporalUnitIntersectionSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" "
|
|
"\"Example\" ) "
|
|
"("
|
|
"<text>For T in {bool, int, real, string, point}:\n"
|
|
"(uT uT) -> (stream uT)*\n"
|
|
"(uT T) -> (stream uT)\n"
|
|
"( T uT) -> (stream uT)\n"
|
|
"(line upoint) -> (stream upoint)\n"
|
|
"(upoint line) -> (stream upoint)\n"
|
|
"(upoint uregion) -> (stream upoint)\n"
|
|
"(uregion upoint) -> (stream upoint)\n"
|
|
"(upoint region) -> (stream upoint)\n"
|
|
"(region upoint) -> (stream upoint)\n"
|
|
"(*): Not yet implemented for T = real</text--->"
|
|
"<text>intersection(_, _)</text--->"
|
|
"<text>Returns the intersection of two unit datatype values "
|
|
"or of a unit datatype and its corrosponding simple datatype "
|
|
"as a stream of that unit datatype.</text--->"
|
|
"<text>query intersection(upoint1, upoint2) count</text--->"
|
|
") )";
|
|
|
|
|
|
/*
|
|
5.26.4 Selection Function of operator ~intersection~
|
|
|
|
*/
|
|
|
|
ValueMapping temporalunitintersectionmap[] =
|
|
{
|
|
temporalUnitIntersection_CU_CU<UBool>, // 0
|
|
temporalUnitIntersection_CU_CU<UInt>,
|
|
temporalUnitIntersection_ureal_ureal,
|
|
temporalUnitIntersection_upoint_upoint,
|
|
temporalUnitIntersection_CU_CU<UString>,
|
|
|
|
temporalUnitIntersection_CU_C<UBool, CcBool, 0>, // 5
|
|
temporalUnitIntersection_CU_C<UInt, CcInt, 0>,
|
|
temporalUnitIntersection_ureal_real<0>,
|
|
temporalUnitIntersection_upoint_point<0>,
|
|
temporalUnitIntersection_CU_C<UString, CcString, 0>,
|
|
|
|
temporalUnitIntersection_CU_C<UBool, CcBool, 1>, // 10
|
|
temporalUnitIntersection_CU_C<UInt, CcInt, 1>,
|
|
temporalUnitIntersection_ureal_real<1>,
|
|
temporalUnitIntersection_upoint_point<1>,
|
|
temporalUnitIntersection_CU_C<UString, CcString, 1>,
|
|
|
|
temporalUnitIntersection_upoint_line<0>, // 15
|
|
temporalUnitIntersection_upoint_line<1>,
|
|
|
|
temporalUnitIntersection_upoint_uregion<0, true>,
|
|
temporalUnitIntersection_upoint_uregion<1, true>,
|
|
|
|
temporalUnitIntersection_upoint_region<0>,
|
|
temporalUnitIntersection_upoint_region<1> // 20
|
|
};
|
|
|
|
int temporalunitIntersectionSelect( ListExpr args )
|
|
{
|
|
ListExpr arg1 = nl->First(args);
|
|
ListExpr arg2 = nl->Second(args);
|
|
if( nl->IsEqual( arg1, UBool::BasicType() ) &&
|
|
nl->IsEqual( arg2, UBool::BasicType()) ) return 0;
|
|
if( nl->IsEqual( arg1, UInt::BasicType() ) &&
|
|
nl->IsEqual( arg2, UInt::BasicType() ) ) return 1;
|
|
if( nl->IsEqual( arg1, UReal::BasicType() ) &&
|
|
nl->IsEqual( arg2, UReal::BasicType() ) ) return 2;
|
|
if( nl->IsEqual( arg1, UPoint::BasicType() ) &&
|
|
nl->IsEqual( arg2, UPoint::BasicType() ) ) return 3;
|
|
if( nl->IsEqual( arg1, UString::BasicType() ) &&
|
|
nl->IsEqual( arg2, UString::BasicType() ) ) return 4;
|
|
|
|
if( nl->IsEqual( arg1, UBool::BasicType() ) &&
|
|
nl->IsEqual( arg2, CcBool::BasicType() )) return 5;
|
|
if( nl->IsEqual( arg1, UInt::BasicType() ) &&
|
|
nl->IsEqual( arg2, CcInt::BasicType() )) return 6;
|
|
if( nl->IsEqual( arg1, UReal::BasicType() ) &&
|
|
nl->IsEqual( arg2, CcReal::BasicType() )) return 7;
|
|
if( nl->IsEqual( arg1, UPoint::BasicType() ) &&
|
|
nl->IsEqual( arg2, Point::BasicType() ) ) return 8;
|
|
if( nl->IsEqual( arg1, UString::BasicType() ) &&
|
|
nl->IsEqual( arg2, CcString::BasicType() )) return 9;
|
|
|
|
if( nl->IsEqual( arg2, UBool::BasicType() ) &&
|
|
nl->IsEqual( arg1, CcBool::BasicType() )) return 10;
|
|
if( nl->IsEqual( arg2, UInt::BasicType() ) &&
|
|
nl->IsEqual( arg1, CcInt::BasicType() )) return 11;
|
|
if( nl->IsEqual( arg2, UReal::BasicType() ) &&
|
|
nl->IsEqual( arg1, CcReal::BasicType() )) return 12;
|
|
if( nl->IsEqual( arg2, UPoint::BasicType() ) &&
|
|
nl->IsEqual( arg1, Point::BasicType() )) return 13;
|
|
if( nl->IsEqual( arg2, UString::BasicType() ) &&
|
|
nl->IsEqual( arg1, UString::BasicType() )) return 14;
|
|
|
|
if( nl->IsEqual( arg1, UPoint::BasicType() ) &&
|
|
nl->IsEqual( arg2, Line::BasicType() )) return 15;
|
|
if( nl->IsEqual( arg1, Line::BasicType() ) &&
|
|
nl->IsEqual( arg2, UPoint::BasicType() ) ) return 16;
|
|
if( nl->IsEqual( arg1, UPoint::BasicType() ) &&
|
|
nl->IsEqual( arg2, URegion::BasicType() ) ) return 17;
|
|
if( nl->IsEqual( arg1, URegion::BasicType() ) &&
|
|
nl->IsEqual( arg2, UPoint::BasicType() ) ) return 18;
|
|
if( nl->IsEqual( arg1, UPoint::BasicType() ) &&
|
|
nl->IsEqual( arg2, Region::BasicType() ) ) return 19;
|
|
if( nl->IsEqual( arg1, Region::BasicType() ) &&
|
|
nl->IsEqual( arg2, UPoint::BasicType() ) ) return 20;
|
|
|
|
std::cerr << "ERROR: Unmatched case in temporalunitIntersectionSelect"
|
|
<< endl;
|
|
std::string argstr;
|
|
nl->WriteToString(argstr, args);
|
|
std::cerr << " Argumets = '" << argstr << "'." << endl;
|
|
return -1;
|
|
}
|
|
|
|
|
|
/*
|
|
5.26.5 Definition of operator ~intersection~
|
|
|
|
*/
|
|
|
|
Operator temporalunitintersection( "intersection",
|
|
TemporalUnitIntersectionSpec,
|
|
21,
|
|
temporalunitintersectionmap,
|
|
temporalunitIntersectionSelect,
|
|
TemporalUnitIntersectionTypeMap);
|
|
|
|
|
|
/*
|
|
5.13 Operator ~at~
|
|
|
|
The operator restricts a unit type to the interval, where it's value
|
|
is equal to a given value. For base types ~bool~, ~int~ and ~point~,
|
|
the result will be only a single unit, but for base type ~real~, there
|
|
may be two units, as ~ureal~ is represented by a quadratic polynomial
|
|
function (or it's radical).
|
|
|
|
5.13.1 Type Mapping for ~at~
|
|
|
|
----
|
|
at: For T in {bool, int, string, point, region*}
|
|
OK + uT x T --> uT
|
|
OK ureal x real --> (stream ureal)
|
|
OK + upoint x region --> (stream upoint)
|
|
upoint x rect --> upoint
|
|
|
|
(*): Not yet implemented
|
|
|
|
----
|
|
|
|
*/
|
|
ListExpr
|
|
TemporalUnitAtTypeMapUnit( ListExpr args )
|
|
{
|
|
ListExpr arg1, arg2;
|
|
if( nl->ListLength( args ) == 2 )
|
|
{
|
|
arg1 = nl->First( args );
|
|
arg2 = nl->Second( args );
|
|
|
|
#ifdef TUA_DEBUG
|
|
cout << "\nTemporalUnitAtTypeMapUnit: 0" << endl;
|
|
#endif
|
|
if( nl->IsEqual( arg1, UBool::BasicType() )
|
|
&& nl->IsEqual( arg2, CcBool::BasicType() ) )
|
|
return nl->TwoElemList(nl->SymbolAtom( Symbol::STREAM() ),
|
|
nl->SymbolAtom( UBool::BasicType() ));
|
|
if( nl->IsEqual( arg1, UInt::BasicType() )
|
|
&& nl->IsEqual( arg2, CcInt::BasicType() ) )
|
|
return nl->TwoElemList(nl->SymbolAtom( Symbol::STREAM() ),
|
|
nl->SymbolAtom( UInt::BasicType() ));
|
|
if( nl->IsEqual( arg1, UPoint::BasicType() )
|
|
&& nl->IsEqual( arg2, Point::BasicType() ) )
|
|
return nl->TwoElemList(nl->SymbolAtom( Symbol::STREAM() ),
|
|
nl->SymbolAtom( UPoint::BasicType() ));
|
|
// for ureal, _ at _ will return a stream of ureals!
|
|
if( nl->IsEqual( arg1, UReal::BasicType() )
|
|
&& nl->IsEqual( arg2, CcReal::BasicType() ) )
|
|
return nl->TwoElemList(nl->SymbolAtom( Symbol::STREAM() ),
|
|
nl->SymbolAtom( UReal::BasicType() ));
|
|
if( nl->IsEqual( arg1, UString::BasicType() )
|
|
&& nl->IsEqual( arg2, CcString::BasicType() ) )
|
|
return nl->TwoElemList(nl->SymbolAtom( Symbol::STREAM() ),
|
|
nl->SymbolAtom( UString::BasicType() ));
|
|
if( nl->IsEqual( arg1, URegion::BasicType() )
|
|
&& nl->IsEqual( arg2, Region::BasicType() ) )
|
|
return nl->TwoElemList(nl->SymbolAtom( Symbol::STREAM() ),
|
|
nl->SymbolAtom( URegion::BasicType() ));
|
|
if( nl->IsEqual( arg1, UPoint::BasicType() )
|
|
&& nl->IsEqual( arg2, Region::BasicType() ) )
|
|
return nl->TwoElemList(nl->SymbolAtom( Symbol::STREAM() ),
|
|
nl->SymbolAtom( UPoint::BasicType() ));
|
|
if( nl->IsEqual( arg1, UPoint::BasicType() )
|
|
&& nl->IsEqual( arg2, Rectangle<2>::BasicType() ) )
|
|
return nl->SymbolAtom( UPoint::BasicType() );
|
|
}
|
|
#ifdef TUA_DEBUG
|
|
cout << "\nTemporalUnitAtTypeMapUnit: 1" << endl;
|
|
#endif
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
|
}
|
|
|
|
/*
|
|
5.13.2 Value Mapping for ~at~
|
|
|
|
Instead of implementing dedicated value mappings, we use those for operator
|
|
~intersection~ except for "upoint x rect".
|
|
|
|
*/
|
|
|
|
|
|
int AtUpR(Word* args, Word& result,
|
|
int message, Word& local, Supplier s) {
|
|
|
|
result = qp->ResultStorage(s);
|
|
UPoint* arg1 = static_cast<UPoint*>(args[0].addr);
|
|
Rectangle<2>* arg2 = static_cast<Rectangle<2>*>(args[1].addr);
|
|
UPoint* res = static_cast<UPoint*>(result.addr);
|
|
arg1->At(*arg2,*res);
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
5.13.3 Specification for operator ~at~
|
|
|
|
*/
|
|
const std::string
|
|
TemporalSpecAt =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>For T in {bool, int, string, point, region*}:\n"
|
|
"(uT T ) -> (stream uT)\n"
|
|
"(ureal real ) -> (stream ureal)\n"
|
|
"(upoint region) -> (stream upoint)\n"
|
|
"(upoint rect) -> upoint\n"
|
|
"(*): Not yet implemented</text--->"
|
|
"<text>_ at _ </text--->"
|
|
"<text>restrict the movement to the times "
|
|
"where the equality occurs.\n"
|
|
"Observe, that the result is always a "
|
|
"'(stream UNIT)' rather than a 'UNIT'! except for upoint x rect</text--->"
|
|
"<text>upoint1 at point1 the_mvalue</text---> ) )";
|
|
|
|
/*
|
|
5.13.4 Selection Function of operator ~at~
|
|
|
|
*/
|
|
int
|
|
TUSelectAt( ListExpr args )
|
|
{
|
|
ListExpr arg1 = nl->First( args ),
|
|
arg2 = nl->Second( args );
|
|
|
|
if( nl->SymbolValue( arg1 ) == UBool::BasicType() &&
|
|
nl->SymbolValue( arg2 ) == CcBool::BasicType() )
|
|
return 0;
|
|
|
|
if( nl->SymbolValue( arg1 ) == UInt::BasicType() &&
|
|
nl->SymbolValue( arg2 ) == CcInt::BasicType() )
|
|
return 1;
|
|
|
|
if( nl->SymbolValue( arg1 ) == UReal::BasicType() &&
|
|
nl->SymbolValue( arg2 ) == CcReal::BasicType() )
|
|
return 2;
|
|
|
|
if( nl->SymbolValue( arg1 ) == UPoint::BasicType() &&
|
|
nl->SymbolValue( arg2 ) == Point::BasicType() )
|
|
return 3;
|
|
|
|
if( nl->SymbolValue( arg1 ) == UString::BasicType() &&
|
|
nl->SymbolValue( arg2 ) == CcString::BasicType() )
|
|
return 4;
|
|
|
|
if( nl->SymbolValue( arg1 ) == URegion::BasicType() &&
|
|
nl->SymbolValue( arg2 ) == Region::BasicType() )
|
|
return 5;
|
|
|
|
if( nl->SymbolValue( arg1 ) == UPoint::BasicType() &&
|
|
nl->SymbolValue( arg2 ) == Region::BasicType() )
|
|
return 6;
|
|
|
|
if( nl->SymbolValue( arg1 ) == UPoint::BasicType() &&
|
|
nl->SymbolValue( arg2 ) == Rectangle<2>::BasicType() )
|
|
return 7;
|
|
|
|
return -1; // This point should never be reached
|
|
}
|
|
|
|
|
|
ValueMapping temporalunitatmap[] = {
|
|
temporalUnitIntersection_CU_C< UBool, CcBool, 0 >, //0
|
|
temporalUnitIntersection_CU_C< UInt, CcInt, 0 >, //1
|
|
temporalUnitIntersection_ureal_real<0>, //2
|
|
temporalUnitIntersection_upoint_point<0>, //3
|
|
temporalUnitIntersection_CU_C< UString, CcString, 0 >, //4
|
|
temporalUnitIntersection_uregion_region<0>, //5
|
|
temporalUnitIntersection_upoint_region<0>, //6
|
|
AtUpR}; //7
|
|
|
|
/*
|
|
5.13.5 Definition of operator ~at~
|
|
|
|
*/
|
|
Operator temporalunitat( "at",
|
|
TemporalSpecAt,
|
|
8,
|
|
temporalunitatmap,
|
|
TUSelectAt,
|
|
TemporalUnitAtTypeMapUnit );
|
|
|
|
|
|
|
|
/*
|
|
5.31 Operator ~no\_components~
|
|
|
|
Return the number of components (units) contained by the object. For unit types,
|
|
the result is either undef (for undef values) or a const unit with value=1
|
|
(otherwise).
|
|
|
|
----
|
|
n/a + no_components: (uT) --> uint
|
|
|
|
----
|
|
|
|
*/
|
|
|
|
/*
|
|
5.31.1 Type mapping function for ~no\_components~
|
|
|
|
*/
|
|
|
|
static ListExpr TUNoComponentsTypeMap(ListExpr args) {
|
|
|
|
if (nl->ListLength(args) == 1)
|
|
{
|
|
if (nl->IsEqual(nl->First(args), UBool::BasicType()))
|
|
return nl->SymbolAtom(UInt::BasicType());
|
|
if (nl->IsEqual(nl->First(args), UInt::BasicType()))
|
|
return nl->SymbolAtom(UInt::BasicType());
|
|
if (nl->IsEqual(nl->First(args), UReal::BasicType()))
|
|
return nl->SymbolAtom(UInt::BasicType());
|
|
if (nl->IsEqual(nl->First(args), UString::BasicType()))
|
|
return nl->SymbolAtom(UInt::BasicType());
|
|
if (nl->IsEqual(nl->First(args), UPoint::BasicType()))
|
|
return nl->SymbolAtom(UInt::BasicType());
|
|
if (nl->IsEqual(nl->First(args), URegion::BasicType()))
|
|
return nl->SymbolAtom(UInt::BasicType());
|
|
}
|
|
return nl->SymbolAtom(Symbol::TYPEERROR());
|
|
}
|
|
|
|
/*
|
|
5.31.2 Value mapping for operator ~no\_components~
|
|
|
|
*/
|
|
|
|
template<class T>
|
|
int TUNoComponentsValueMap(Word* args, Word& result,
|
|
int message, Word& local, Supplier s)
|
|
{
|
|
result = (qp->ResultStorage( s ));
|
|
UInt *res = (UInt*)result.addr;
|
|
T *input = (T*)args[0].addr;
|
|
|
|
if ( input->IsDefined() ) {
|
|
res->SetDefined(true);
|
|
res->timeInterval.CopyFrom(input->timeInterval);
|
|
res->constValue.Set(true,1);
|
|
} else {
|
|
res->SetDefined(false);
|
|
res->constValue.Set(true,0);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
5.31.3 Specification for operator ~no\_components~
|
|
|
|
*/
|
|
const std::string TUNoComponentsSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>For T in {bool, int, real, point, region}:\n"
|
|
"(uT) -> uint</text--->"
|
|
"<text>no_components( _ )</text--->"
|
|
"<text>Returns an undef uint for undef unit, an uint with the "
|
|
"argument's deftime and value '1' otherwise.</text--->"
|
|
"<text>query no_components([const uint value undef])</text--->"
|
|
") )";
|
|
|
|
/*
|
|
5.31.4 Selection Function of operator ~no\_components~
|
|
|
|
Uses ~UnitSimpleSelect( ListExpr args )~
|
|
|
|
*/
|
|
|
|
ValueMapping temporalunitNoComponentsvaluemap[] = {
|
|
TUNoComponentsValueMap<UBool>,
|
|
TUNoComponentsValueMap<UInt>,
|
|
TUNoComponentsValueMap<UReal>,
|
|
TUNoComponentsValueMap<UPoint>,
|
|
TUNoComponentsValueMap<UString>,
|
|
TUNoComponentsValueMap<URegion>};
|
|
/*
|
|
5.31.5 Definition of operator ~no\_components~
|
|
|
|
*/
|
|
Operator temporalunitnocomponents
|
|
(
|
|
"no_components",
|
|
TUNoComponentsSpec,
|
|
6,
|
|
temporalunitNoComponentsvaluemap,
|
|
UnitSimpleSelect,
|
|
TUNoComponentsTypeMap
|
|
);
|
|
|
|
/*
|
|
5.32 Operator ~isempty~
|
|
|
|
The operator returns TRUE, if the unit is undefined, otherwise it returns FALSE.
|
|
It will never return an undefined result!
|
|
|
|
----
|
|
For U in kind UNIT and U in kind DATA:
|
|
isempty U --> bool
|
|
|
|
----
|
|
|
|
*/
|
|
|
|
/*
|
|
5.32.1 Type mapping function for ~isempty~
|
|
|
|
*/
|
|
ListExpr
|
|
TUIsemptyTypeMap( ListExpr args )
|
|
{
|
|
ListExpr arg1;
|
|
ListExpr errorInfo = nl->OneElemList(nl->SymbolAtom(Symbol::ERRORS()));
|
|
|
|
if ( ( nl->ListLength(args) == 1 ) && ( nl->IsAtom(nl->First(args) ) ) )
|
|
{
|
|
arg1 = nl->First(args);
|
|
if( am->CheckKind(Kind::UNIT(), arg1, errorInfo) )
|
|
return nl->SymbolAtom(CcBool::BasicType());
|
|
}
|
|
ErrorReporter::ReportError("Operator isempty expects a list of length one, "
|
|
"containing a value of type 'U' with U in "
|
|
"kind UNIT.");
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
|
}
|
|
|
|
/*
|
|
5.32.2 Value mapping for operator ~isempty~
|
|
|
|
*/
|
|
int TUIsemptyValueMap( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
result = qp->ResultStorage( s );
|
|
Attribute* val = ((Attribute*)args[0].addr);
|
|
((CcBool *)result.addr)->Set( true, !val->IsDefined() );
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
5.32.3 Specification for operator ~isempty~
|
|
|
|
*/
|
|
const std::string TUIsemptySpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>For U in kind UNIT:\n"
|
|
"U -> bool</text--->"
|
|
"<text>isempty( _ )</text--->"
|
|
"<text>The operator returns TRUE, if the unit is undefined, "
|
|
"otherwise it returns FALSE. It will never return an "
|
|
"undefined result!</text--->"
|
|
"<text>query isempty([const uint value undef])</text--->"
|
|
") )";
|
|
|
|
/*
|
|
5.32.4 Selection Function of operator ~isempty~
|
|
|
|
Simple selection is used, as there is only one value mapping function.
|
|
|
|
*/
|
|
|
|
ValueMapping temporalunitIsemptyvaluemap[] = { TUIsemptyValueMap };
|
|
|
|
/*
|
|
5.32.5 Definition of operator ~isempty~
|
|
|
|
*/
|
|
Operator temporalunitisempty
|
|
(
|
|
"isempty",
|
|
TUIsemptySpec,
|
|
1,
|
|
temporalunitIsemptyvaluemap,
|
|
Operator::SimpleSelect,
|
|
TUIsemptyTypeMap
|
|
);
|
|
|
|
/*
|
|
5.33 Operator ~not~
|
|
|
|
Negates an ubool.
|
|
|
|
----
|
|
not: ubool --> ubool
|
|
|
|
----
|
|
|
|
*/
|
|
|
|
/*
|
|
5.33.1 Type mapping function for ~not~
|
|
|
|
*/
|
|
|
|
ListExpr
|
|
TUNotTypeMap( ListExpr args )
|
|
{
|
|
if ( nl->ListLength( args ) == 1 )
|
|
{
|
|
ListExpr arg1 = nl->First( args );
|
|
|
|
if( nl->IsEqual( arg1, UBool::BasicType() ) )
|
|
return nl->SymbolAtom( UBool::BasicType() );
|
|
}
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
|
}
|
|
/*
|
|
5.33.2 Value mapping for operator ~not~
|
|
|
|
*/
|
|
|
|
int TUNotValueMap(Word* args, Word& result, int message,
|
|
Word& local, Supplier s)
|
|
{
|
|
result = (qp->ResultStorage( s ));
|
|
UBool *res = (UBool*) result.addr;
|
|
UBool *input = (UBool*)args[0].addr;
|
|
|
|
if(!input->IsDefined()){
|
|
res->SetDefined( false );
|
|
} else {
|
|
res->SetDefined( true );
|
|
res->CopyFrom(input);
|
|
res->constValue.Set(res->constValue.IsDefined(),
|
|
!(res->constValue.GetBoolval()));
|
|
}
|
|
return 0;
|
|
}
|
|
/*
|
|
5.33.3 Specification for operator ~not~
|
|
|
|
*/
|
|
const std::string TUNotSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>ubool -> ubool</text--->"
|
|
"<text>not( _ )</text--->"
|
|
"<text>The operator returns the logical complement of "
|
|
"its argument. Undef argument resullts in an undef result."
|
|
"</text--->"
|
|
"<text>query not([const ubool value ((\"2010-11-11\" "
|
|
"\"2011-01-03\" TRUE FALSE) TRUE)])</text--->"
|
|
") )";
|
|
/*
|
|
5.33.4 Selection Function of operator ~not~
|
|
|
|
We use simple selection:
|
|
|
|
*/
|
|
|
|
ValueMapping temporalunitNotvaluemap[] = { TUNotValueMap };
|
|
|
|
/*
|
|
5.33.5 Definition of operator ~not~
|
|
|
|
*/
|
|
Operator temporalunitnot
|
|
(
|
|
"not",
|
|
TUNotSpec,
|
|
1,
|
|
temporalunitNotvaluemap,
|
|
Operator::SimpleSelect,
|
|
TUNotTypeMap
|
|
);
|
|
|
|
/*
|
|
5.34 Operators ~and~ and ~or~
|
|
|
|
These operators perform the binary conjunction/disjunction for ubool (and bool):
|
|
|
|
----
|
|
|
|
and, or: ubool x ubool -> ubool
|
|
bool x ubool -> ubool
|
|
ubool x bool -> ubool
|
|
----
|
|
|
|
*/
|
|
|
|
/*
|
|
5.34.1 Type mapping function for ~and~ and ~or~
|
|
|
|
We implement a genric function for binary boolean functions here:
|
|
|
|
*/
|
|
|
|
ListExpr TUBinaryBoolFuncTypeMap( ListExpr args )
|
|
{
|
|
if( nl->ListLength( args ) == 2 )
|
|
{
|
|
ListExpr arg1 = nl->First( args );
|
|
ListExpr arg2 = nl->Second( args );
|
|
|
|
// First case: ubool ubool -> ubool
|
|
if ( nl->IsEqual( arg1, UBool::BasicType() )
|
|
&& nl->IsEqual( arg2, UBool::BasicType() ) )
|
|
return nl->SymbolAtom(UBool::BasicType());
|
|
|
|
// Second case: ubool bool -> ubool
|
|
if( nl->IsEqual( arg1, UBool::BasicType() )
|
|
&& nl->IsEqual( arg2, CcBool::BasicType()) )
|
|
return nl->SymbolAtom(UBool::BasicType());
|
|
|
|
// Third case: bool ubool -> ubool
|
|
if( nl->IsEqual( arg1, CcBool::BasicType() )
|
|
&& nl->IsEqual( arg2, UBool::BasicType()) )
|
|
return nl->SymbolAtom(UBool::BasicType());
|
|
|
|
// Error case:
|
|
std::string argstr1, argstr2;
|
|
nl->WriteToString(argstr1, arg1);
|
|
nl->WriteToString(argstr2, arg2);
|
|
ErrorReporter::ReportError(
|
|
"Binary booleon operator expects any combination of {bool, ubool} "
|
|
"as arguments, but the passed arguments have types '"+ argstr1 +
|
|
"' and '" + argstr2 + "'.");
|
|
} else {
|
|
ErrorReporter::ReportError(
|
|
"Binary booleon operator expects any combination of {bool, ubool} "
|
|
"as arguments.");
|
|
}
|
|
return nl->SymbolAtom(Symbol::TYPEERROR());
|
|
}
|
|
/*
|
|
5.34.2 Value mapping for operators ~and~ and ~or~
|
|
|
|
*/
|
|
template<int ArgConf>
|
|
int TUAndValueMap(Word* args, Word& result, int message,
|
|
Word& local, Supplier s)
|
|
{
|
|
assert( (ArgConf>=0) && (ArgConf<=2));
|
|
|
|
result = (qp->ResultStorage( s ));
|
|
UBool *res = (UBool*) result.addr;
|
|
UBool *u1, *u2;
|
|
CcBool *cb;
|
|
Interval<Instant> iv;
|
|
|
|
if(ArgConf == 0) // case: ubool x ubool -> ubool
|
|
{
|
|
u1 = (UBool*) args[0].addr;
|
|
u2 = (UBool*) args[1].addr;
|
|
|
|
if (!u1->IsDefined() ||
|
|
!u2->IsDefined() ||
|
|
!u1->timeInterval.Intersects( u2->timeInterval) )
|
|
res->SetDefined( false );
|
|
else
|
|
{
|
|
u1->timeInterval.Intersection( u2->timeInterval, iv );
|
|
res->SetDefined( true );
|
|
res->timeInterval = iv;
|
|
res->constValue.Set(
|
|
u1->constValue.IsDefined() && u2->constValue.IsDefined(),
|
|
u1->constValue.GetBoolval() && u2->constValue.GetBoolval());
|
|
}
|
|
return 0;
|
|
}
|
|
else if(ArgConf == 1) // case: ubool x bool -> ubool
|
|
{
|
|
u1 = (UBool*)args[0].addr;
|
|
cb = (CcBool*)args[1].addr;
|
|
}
|
|
else if(ArgConf == 2) // case: bool x ubool -> ubool
|
|
{
|
|
u1 = (UBool*)args[1].addr;
|
|
cb = (CcBool*)args[0].addr;
|
|
}
|
|
if (!u1->IsDefined() || !cb->IsDefined())
|
|
res->SetDefined( false );
|
|
else
|
|
{
|
|
res->CopyFrom(u1);
|
|
res->constValue.Set(u1->constValue.IsDefined(),
|
|
u1->constValue.GetBoolval() && cb->GetBoolval() );
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
template<int ArgConf>
|
|
int TUOrValueMap(Word* args, Word& result, int message,
|
|
Word& local, Supplier s)
|
|
{
|
|
assert( (ArgConf>=0) && (ArgConf<=2));
|
|
|
|
result = (qp->ResultStorage( s ));
|
|
UBool *res = (UBool*) result.addr;
|
|
UBool *u1, *u2;
|
|
CcBool *cb;
|
|
Interval<Instant> iv;
|
|
|
|
if(ArgConf == 0) // case: ubool x ubool -> ubool
|
|
{
|
|
u1 = (UBool*) args[0].addr;
|
|
u2 = (UBool*) args[1].addr;
|
|
|
|
if (!u1->IsDefined() ||
|
|
!u2->IsDefined() ||
|
|
!u1->timeInterval.Intersects( u2->timeInterval) )
|
|
res->SetDefined( false );
|
|
else
|
|
{
|
|
u1->timeInterval.Intersection( u2->timeInterval, iv );
|
|
res->SetDefined( true );
|
|
res->timeInterval = iv;
|
|
res->constValue.Set(
|
|
u1->constValue.IsDefined() && u2->constValue.IsDefined(),
|
|
u1->constValue.GetBoolval() || u2->constValue.GetBoolval());
|
|
}
|
|
return 0;
|
|
}
|
|
else if(ArgConf == 1) // case: ubool x bool -> ubool
|
|
{
|
|
u1 = (UBool*)args[0].addr;
|
|
cb = (CcBool*)args[1].addr;
|
|
}
|
|
else if(ArgConf == 2) // case: bool x ubool -> ubool
|
|
{
|
|
u1 = (UBool*)args[1].addr;
|
|
cb = (CcBool*)args[0].addr;
|
|
}
|
|
if (!u1->IsDefined() || !cb->IsDefined())
|
|
res->SetDefined( false );
|
|
else
|
|
{
|
|
res->CopyFrom(u1);
|
|
res->constValue.Set(u1->constValue.IsDefined(),
|
|
u1->constValue.GetBoolval() || cb->GetBoolval() );
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
5.34.3 Specification for operators ~and~ and ~or~
|
|
|
|
*/
|
|
const std::string TUAndSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>(ubool ubool) -> ubool\n"
|
|
"(ubool bool) -> ubool\n"
|
|
"( bool ubool) -> ubool</text--->"
|
|
"<text>_ and _</text--->"
|
|
"<text>The operator returns the logical conjunction of its "
|
|
"arguments, restricted to their common deftime. Any undefined "
|
|
"argument or non-overlapping intervals result in an "
|
|
"undefined result."
|
|
"</text--->"
|
|
"<text>query [const ubool value ((\"2010-11-11\" "
|
|
"\"2011-01-03\" TRUE FALSE) TRUE)] and [const ubool value "
|
|
"((\"2011-01-01\"2012-09-17\" FALSE TRUE) TRUE)]</text--->"
|
|
") )";
|
|
|
|
const std::string TUOrSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>(ubool ubool) -> ubool\n"
|
|
"(ubool bool) -> ubool\n"
|
|
"( bool ubool) -> ubool</text--->"
|
|
"<text>_ or _</text--->"
|
|
"<text>The operator returns the logical disjunction of its "
|
|
"arguments, restricted to their common deftime. Any undefined "
|
|
"argument or non-overlapping intervals result in an "
|
|
"undefined result."
|
|
"</text--->"
|
|
"<text>query [const ubool value ((\"2010-11-11\" "
|
|
"\"2011-01-03\" TRUE FALSE) TRUE)] or [const ubool value "
|
|
"((\"2011-01-01\"2012-09-17\" FALSE TRUE) TRUE)]</text--->"
|
|
") )";
|
|
|
|
|
|
/*
|
|
5.34.4 Selection Function of operators ~and~ and ~or~
|
|
|
|
*/
|
|
int TUBinaryBoolFuncSelect( ListExpr args )
|
|
{
|
|
ListExpr arg1 = nl->First( args ),
|
|
arg2 = nl->Second( args );
|
|
|
|
if( nl->SymbolValue( arg1 ) == UBool::BasicType()
|
|
&& nl->SymbolValue( arg2 ) == UBool::BasicType() )
|
|
return 0;
|
|
if( nl->SymbolValue( arg1 ) == UBool::BasicType()
|
|
&& nl->SymbolValue( arg2 ) == CcBool::BasicType() )
|
|
return 1;
|
|
if( nl->SymbolValue( arg1 ) == CcBool::BasicType()
|
|
&& nl->SymbolValue( arg2 ) == UBool::BasicType() )
|
|
return 2;
|
|
|
|
return -1; // This point should never be reached
|
|
}
|
|
|
|
ValueMapping temporalunitAndValuemap[] = {
|
|
TUAndValueMap<0>,
|
|
TUAndValueMap<1>,
|
|
TUAndValueMap<2>
|
|
};
|
|
|
|
ValueMapping temporalunitOrValuemap[] = {
|
|
TUOrValueMap<0>,
|
|
TUOrValueMap<1>,
|
|
TUOrValueMap<2>
|
|
};
|
|
|
|
/*
|
|
5.34.5 Definition of operators ~and~ and ~or~
|
|
|
|
*/
|
|
Operator temporalunitand
|
|
(
|
|
"and",
|
|
TUAndSpec,
|
|
3,
|
|
temporalunitAndValuemap,
|
|
TUBinaryBoolFuncSelect,
|
|
TUBinaryBoolFuncTypeMap
|
|
);
|
|
|
|
Operator temporalunitor
|
|
(
|
|
"or",
|
|
TUOrSpec,
|
|
3,
|
|
temporalunitOrValuemap,
|
|
TUBinaryBoolFuncSelect,
|
|
TUBinaryBoolFuncTypeMap
|
|
);
|
|
|
|
|
|
/*
|
|
5.35 Operator ~ComparePredicates~
|
|
|
|
Here, we implement the binary comparison operators/predicates for (uT uT).
|
|
The predicates are:
|
|
|
|
----
|
|
|
|
== (equality),
|
|
## (unequality),
|
|
<< (smaller than),
|
|
>> (bigger than),
|
|
<<== (smaller than or equal to),
|
|
>>== (bigger than or equal to).
|
|
|
|
----
|
|
|
|
The operators use the internal ~Compare~ function, which implements an
|
|
ordering on the elements, but does not need to respect intuitive operator
|
|
semantics (e.g. in case ureal).
|
|
They compare whole units as such. They do NOT compare the values!
|
|
|
|
WARNING: Do not confuse this operators with the ~CompareValuePredicates~, which
|
|
compare the values.
|
|
|
|
----
|
|
=, #, <, >, <=, >=: For T in {int, bool, real, string, point, region}
|
|
n/a + uT x uT --> bool
|
|
|
|
----
|
|
|
|
*/
|
|
|
|
/*
|
|
5.35.1 Type mapping function for ~ComparePredicates~
|
|
|
|
*/
|
|
ListExpr TUComparePredicatesTypeMap( ListExpr args )
|
|
{
|
|
if( nl->ListLength( args ) == 2 )
|
|
{
|
|
ListExpr arg1 = nl->First( args );
|
|
ListExpr arg2 = nl->Second( args );
|
|
if (nl->Equal( arg1, arg2 ))
|
|
{
|
|
if( (nl->IsEqual( arg1, UBool::BasicType() ) ) ||
|
|
(nl->IsEqual( arg1, UInt::BasicType() ) ) ||
|
|
(nl->IsEqual( arg1, UString::BasicType() ) ) ||
|
|
(nl->IsEqual( arg1, UReal::BasicType() ) ) ||
|
|
(nl->IsEqual( arg1, URegion::BasicType() ) ) ||
|
|
(nl->IsEqual( arg1, UPoint::BasicType() ) ) )
|
|
return nl->SymbolAtom( CcBool::BasicType() );
|
|
}
|
|
std::string argstr1, argstr2;
|
|
nl->WriteToString(argstr1, arg1);
|
|
nl->WriteToString(argstr2, arg2);
|
|
ErrorReporter::ReportError(
|
|
"Compare Operator (one of ==, ##, <<, >>, , <<==, >>==) expects "
|
|
"two arguments of type 'uT', where T in {bool, int, real, "
|
|
"string, point, region}./nThe passed arguments have types '"
|
|
+ argstr1 +"' and '" + argstr2 + "'.");
|
|
} else {
|
|
// Error case:
|
|
ErrorReporter::ReportError(
|
|
"Compare Operator (one of ==, ##, <<, >>, , <<==, >>==) expects "
|
|
"two arguments of type 'uT', where T in {bool, int, real, "
|
|
"string, point, region}./n");
|
|
}
|
|
return nl->SymbolAtom(Symbol::TYPEERROR());
|
|
}
|
|
/*
|
|
5.35.2 Value mapping for operator ~ComparePredicates~
|
|
|
|
template parameter ~OPType~ gives the character of the operator:
|
|
|
|
----
|
|
|
|
0 =,
|
|
1 #,
|
|
2 <,
|
|
3 >,
|
|
4 <=,
|
|
5 >=-
|
|
|
|
----
|
|
|
|
*/
|
|
|
|
template<int OpType>
|
|
int TUComparePredicatedValueMap(Word* args, Word& result, int message,
|
|
Word& local, Supplier s)
|
|
{
|
|
assert( (OpType>=0) && (OpType<=5));
|
|
|
|
result = (qp->ResultStorage( s ));
|
|
CcBool *res = (CcBool*) result.addr;
|
|
Attribute *u1, *u2;
|
|
int p1;
|
|
|
|
u1 = (Attribute*)args[0].addr;
|
|
u2 = (Attribute*)args[1].addr;
|
|
|
|
p1 = u1->Compare(u2);
|
|
|
|
switch (OpType)
|
|
{
|
|
case 0: // is_equal
|
|
res->Set(true, (p1 == 0));
|
|
return 0;
|
|
|
|
case 1: // is_not_equal
|
|
res->Set(true, (p1 != 0));
|
|
return 0;
|
|
|
|
case 2: // less_than
|
|
res->Set(true, (p1 == -1));
|
|
return 0;
|
|
|
|
case 3: // bigger_than
|
|
res->Set(true, (p1 == 1));
|
|
return 0;
|
|
|
|
case 4: // less_or_equal
|
|
res->Set(true, (p1 < 1) );
|
|
return 0;
|
|
|
|
case 5: // bigger_or_equal
|
|
res->Set(true, (p1 > -1));
|
|
return 0;
|
|
}
|
|
|
|
res->Set(false, false);
|
|
return -1; // should not happen
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
5.35.3 Specification for operator ~ComparePredicates~
|
|
|
|
*/
|
|
const std::string TUEqSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>(uT uT) -> bool\n</text--->"
|
|
"<text>_ == _</text--->"
|
|
"<text>The operator checks if the internal ordering predicate "
|
|
"holds for both arguments.</text--->"
|
|
"<text>query [const ubool value ((\"2010-11-11\" "
|
|
"\"2011-01-03\" TRUE FALSE) TRUE)] == [const ubool value "
|
|
"((\"2011-01-01\" \"2012-09-17\" FALSE TRUE) TRUE)]</text--->"
|
|
") )";
|
|
|
|
const std::string TUNEqSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>(uT uT) -> bool\n</text--->"
|
|
"<text>_ ## _</text--->"
|
|
"<text>The operator checks if the internal ordering predicate "
|
|
"holds for both arguments.</text--->"
|
|
"<text>query [const ubool value ((\"2010-11-11\" "
|
|
"\"2011-01-03\" TRUE FALSE) TRUE)] ## [const ubool value "
|
|
"((\"2011-01-01\" \"2012-09-17\" FALSE TRUE) TRUE)]</text--->"
|
|
") )";
|
|
|
|
const std::string TULtSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>(uT uT) -> bool\n</text--->"
|
|
"<text>_ << _</text--->"
|
|
"<text>The operator checks if the internal ordering predicate "
|
|
"holds for both arguments.</text--->"
|
|
"<text>query [const ubool value ((\"2010-11-11\" "
|
|
"\"2011-01-03\" TRUE FALSE) TRUE)] << [const ubool value "
|
|
"((\"2011-01-01\" \"2012-09-17\" FALSE TRUE) TRUE)]</text--->"
|
|
") )";
|
|
|
|
const std::string TUBtSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>(uT uT) -> bool\n</text--->"
|
|
"<text>_ >> _</text--->"
|
|
"<text>The operator checks if the internal ordering predicate "
|
|
"holds for both arguments.</text--->"
|
|
"<text>query [const ubool value ((\"2010-11-11\" "
|
|
"\"2011-01-03\" TRUE FALSE) TRUE)] >> [const ubool value "
|
|
"((\"2011-01-01\" \"2012-09-17\" FALSE TRUE) TRUE)]</text--->"
|
|
") )";
|
|
|
|
const std::string TULtEqSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>(uT uT) -> bool\n</text--->"
|
|
"<text>_ <<== _</text--->"
|
|
"<text>The operator checks if the internal ordering predicate "
|
|
"holds for both arguments.</text--->"
|
|
"<text>query [const ubool value ((\"2010-11-11\" "
|
|
"\"2011-01-03\" TRUE FALSE) TRUE)] <<== [const ubool value "
|
|
"((\"2011-01-01\" \"2012-09-17\" FALSE TRUE) TRUE)]</text--->"
|
|
") )";
|
|
|
|
const std::string TUBtEqSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>(uT uT) -> bool\n</text--->"
|
|
"<text>_ >>== _</text--->"
|
|
"<text>The operator checks if the internal ordering predicate "
|
|
"holds for both arguments.</text--->"
|
|
"<text>query [const ubool value ((\"2010-11-11\" "
|
|
"\"2011-01-03\" TRUE FALSE) TRUE)] >>== [const ubool value "
|
|
"((\"2011-01-01\" \"2012-09-17\" FALSE TRUE) TRUE)]</text--->"
|
|
") )";
|
|
|
|
/*
|
|
5.35.4 Selection Function of operator ~ComparePredicates~
|
|
|
|
We can use Operator::SimpleSelect:
|
|
|
|
*/
|
|
|
|
/*
|
|
5.35.5 Definition of operator ~ComparePredicates~
|
|
|
|
*/
|
|
Operator temporalunitisequal
|
|
(
|
|
"==",
|
|
TUEqSpec,
|
|
TUComparePredicatedValueMap<0>,
|
|
Operator::SimpleSelect,
|
|
TUComparePredicatesTypeMap
|
|
);
|
|
|
|
Operator temporalunitisnotequal
|
|
(
|
|
"##",
|
|
TUNEqSpec,
|
|
TUComparePredicatedValueMap<1>,
|
|
Operator::SimpleSelect,
|
|
TUComparePredicatesTypeMap
|
|
);
|
|
|
|
Operator temporalunitsmaller
|
|
(
|
|
"<<",
|
|
TULtSpec,
|
|
TUComparePredicatedValueMap<2>,
|
|
Operator::SimpleSelect,
|
|
TUComparePredicatesTypeMap
|
|
);
|
|
|
|
Operator temporalunitbigger
|
|
(
|
|
">>",
|
|
TUBtSpec,
|
|
TUComparePredicatedValueMap<3>,
|
|
Operator::SimpleSelect,
|
|
TUComparePredicatesTypeMap
|
|
);
|
|
|
|
Operator temporalunitsmallereq
|
|
(
|
|
"<<==",
|
|
TULtEqSpec,
|
|
TUComparePredicatedValueMap<4>,
|
|
Operator::SimpleSelect,
|
|
TUComparePredicatesTypeMap
|
|
);
|
|
|
|
Operator temporalunitbiggereq
|
|
(
|
|
">>==",
|
|
TUBtEqSpec,
|
|
TUComparePredicatedValueMap<5>,
|
|
Operator::SimpleSelect,
|
|
TUComparePredicatesTypeMap
|
|
);
|
|
/*
|
|
5.36 Operator ~uint2ureal~
|
|
|
|
This operator creates an ureal value from an uint value
|
|
|
|
----
|
|
uint --> ureal
|
|
|
|
----
|
|
|
|
*/
|
|
|
|
/*
|
|
5.36.1 Type mapping function for ~uint2ureal~
|
|
|
|
*/
|
|
ListExpr TUuint2urealTypeMap( ListExpr args )
|
|
{
|
|
if( nl->ListLength( args ) == 1 )
|
|
{
|
|
ListExpr arg1 = nl->First( args );
|
|
if( nl->IsEqual( arg1, UInt::BasicType() ) )
|
|
return nl->SymbolAtom(UReal::BasicType());
|
|
// Error case:
|
|
std::string argstr1;
|
|
nl->WriteToString(argstr1, arg1);
|
|
ErrorReporter::ReportError(
|
|
"Operator uint2ureal expects an argument of type 'uint', "
|
|
"but the passed argument has type '"+ argstr1 + "'.");
|
|
} else {
|
|
ErrorReporter::ReportError(
|
|
"Operator uint2ureal expects an argument of type 'uint'.");
|
|
}
|
|
return nl->SymbolAtom(Symbol::TYPEERROR());
|
|
}
|
|
/*
|
|
5.36.2 Value mapping for operator ~uint2ureal~
|
|
|
|
*/
|
|
int TUuint2urealValueMap(Word* args, Word& result, int message,
|
|
Word& local, Supplier s)
|
|
{
|
|
result = (qp->ResultStorage( s ));
|
|
UReal *res = (UReal*) result.addr;
|
|
UInt *u1;
|
|
|
|
u1 = (UInt*)args[0].addr;
|
|
|
|
res->SetDefined(u1->IsDefined());
|
|
if ( u1->IsDefined() )
|
|
{
|
|
res->timeInterval.CopyFrom(u1->timeInterval);
|
|
res->a = 0.0;
|
|
res->b = 0.0;
|
|
res->c = u1->constValue.GetIntval();
|
|
res->r = false;
|
|
}
|
|
return 0;
|
|
}
|
|
/*
|
|
5.36.3 Specification for operator ~uint2ureal~
|
|
|
|
*/
|
|
const std::string TUuint2urealSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>uint -> ureal\n</text--->"
|
|
"<text>uint2ureal( _ )</text--->"
|
|
"<text>The operator creates a ureal value from an uint value.</text--->"
|
|
"<text>query uint2ureal([const uint value ((\"2010-11-11\" "
|
|
"\"2011-01-03\" TRUE FALSE) -5.4)])</text--->"
|
|
") )";
|
|
|
|
/*
|
|
5.36.4 Selection Function of operator ~uint2ureal~
|
|
|
|
We use Operator::SimpleSelect here.
|
|
|
|
*/
|
|
|
|
/*
|
|
5.36.5 Definition of operator ~uint2ureal~
|
|
|
|
*/
|
|
Operator temporalunituint2ureal
|
|
(
|
|
"uint2ureal",
|
|
TUuint2urealSpec,
|
|
TUuint2urealValueMap,
|
|
Operator::SimpleSelect,
|
|
TUuint2urealTypeMap
|
|
);
|
|
|
|
/*
|
|
5.37 Operator
|
|
|
|
----
|
|
inside:
|
|
OK + upoint x uregion --> (stream ubool)
|
|
OK + upoint x line --> (stream ubool)
|
|
pre + upoint x points --> (stream ubool)
|
|
pre + uregion x points --> (stream ubool)
|
|
|
|
----
|
|
|
|
|
|
*/
|
|
|
|
/*
|
|
5.37.1 Type mapping function for ~inside~
|
|
|
|
*/
|
|
ListExpr TemporalUnitInsideTypeMap( ListExpr args )
|
|
{
|
|
ListExpr arg1, arg2;
|
|
std::string argstr;
|
|
|
|
if( nl->ListLength( args ) == 2 )
|
|
{
|
|
arg1 = nl->First( args );
|
|
arg2 = nl->Second( args );
|
|
|
|
if( nl->IsEqual( arg1, UPoint::BasicType() )
|
|
&& nl->IsEqual( arg2, URegion::BasicType()) )
|
|
return nl->TwoElemList(nl->SymbolAtom( Symbol::STREAM() ),
|
|
nl->SymbolAtom( UBool::BasicType() ));
|
|
if( nl->IsEqual( arg1, UPoint::BasicType() )
|
|
&& nl->IsEqual( arg2, Line::BasicType()) )
|
|
return nl->TwoElemList(nl->SymbolAtom( Symbol::STREAM() ),
|
|
nl->SymbolAtom( UBool::BasicType() ));
|
|
if( nl->IsEqual( arg1, UPoint::BasicType() )
|
|
&& nl->IsEqual( arg2, Points::BasicType()) )
|
|
return nl->TwoElemList(nl->SymbolAtom( Symbol::STREAM() ),
|
|
nl->SymbolAtom( UBool::BasicType() ));
|
|
if( nl->IsEqual( arg1, URegion::BasicType() )
|
|
&& nl->IsEqual( arg2, Points::BasicType()) )
|
|
return nl->TwoElemList(nl->SymbolAtom( Symbol::STREAM() ),
|
|
nl->SymbolAtom( UBool::BasicType() ));
|
|
}
|
|
|
|
// Error case:
|
|
nl->WriteToString(argstr, args);
|
|
ErrorReporter::ReportError(
|
|
"Operator inside expects a list of length two with a certain signature. "
|
|
"But it gets '" + argstr + "'.");
|
|
return nl->SymbolAtom(Symbol::TYPEERROR());
|
|
}
|
|
|
|
/*
|
|
5.37.2 Value mapping for operator ~inside~
|
|
|
|
*/
|
|
struct TUInsideLocalInfo
|
|
{
|
|
bool finished;
|
|
int NoOfResults;
|
|
int NoOfResultsDelivered;
|
|
MBool *mbool; // Used to store results
|
|
};
|
|
// case upoint x uregion --> (stream ubool)
|
|
int temporalUnitInside_up_ur( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
// This implementation uses class-function
|
|
// void MRegion::Inside(MPoint& mp, MBool& res)
|
|
TUInsideLocalInfo *sli;
|
|
Word a0, a1;
|
|
UPoint *u;
|
|
URegion *r;
|
|
UBool cu;
|
|
|
|
switch( message )
|
|
{
|
|
case OPEN:
|
|
|
|
#ifdef TUA_DEBUG
|
|
std::cerr << "temporalUnitInside_up_ur: Received OPEN" << endl;
|
|
#endif
|
|
|
|
sli = new TUInsideLocalInfo;
|
|
sli->finished = true;
|
|
sli->NoOfResults = 0;
|
|
sli->NoOfResultsDelivered = 0;
|
|
sli->mbool = new MBool(10);
|
|
local.setAddr(sli);
|
|
|
|
// initialize arguments, such that a0 always contains the upoint
|
|
// and a1 the uregion
|
|
a0 = args[0];
|
|
a1 = args[1];
|
|
u = (UPoint*)(a0.addr);
|
|
r = (URegion*)(a1.addr);
|
|
|
|
// test for definedness
|
|
if ( !u->IsDefined() || !r->IsDefined() )
|
|
{
|
|
#ifdef TUA_DEBUG
|
|
std::cerr << " Undef arg -> Empty Result" << endl << endl;
|
|
#endif
|
|
// nothing to do
|
|
}
|
|
else
|
|
{
|
|
MPoint mp_tmp(1);
|
|
mp_tmp.Clear(); // create temporary MPoint
|
|
mp_tmp.SetDefined( true );
|
|
mp_tmp.Add(*u);
|
|
|
|
MRegion mr_tmp(1);
|
|
mr_tmp.Clear(); // create temporary MRegion
|
|
mr_tmp.SetDefined( true );
|
|
mr_tmp.AddURegion(*r);
|
|
|
|
mr_tmp.Inside(mp_tmp, *(sli->mbool)); // get and save result;
|
|
|
|
sli->NoOfResults = sli->mbool->GetNoComponents();
|
|
sli->finished = (sli->NoOfResults <= 0);
|
|
#ifdef TUA_DEBUG
|
|
std::cerr << " " << sli->NoOfResults << " result units"
|
|
<< endl << endl;
|
|
#endif
|
|
}
|
|
#ifdef TUA_DEBUG
|
|
std::cerr << "temporalUnitInside_up_ur: Finished OPEN"
|
|
<< endl;
|
|
#endif
|
|
return 0;
|
|
|
|
case REQUEST:
|
|
#ifdef TUA_DEBUG
|
|
std::cerr << "temporalUnitInside_up_ur: Received REQUEST"<< endl;
|
|
#endif
|
|
if(local.addr == 0)
|
|
{
|
|
#ifdef TUA_DEBUG
|
|
std::cerr << "temporalUnitInside_up_ur: Finished REQUEST (1)" << endl;
|
|
#endif
|
|
return CANCEL;
|
|
}
|
|
sli = (TUInsideLocalInfo*) local.addr;
|
|
if(sli->finished)
|
|
{
|
|
#ifdef TUA_DEBUG
|
|
std::cerr << "temporalUnitInside_up_ur: Finished REQUEST (2)"<< endl;
|
|
#endif
|
|
return CANCEL;
|
|
}
|
|
if(sli->NoOfResultsDelivered < sli->NoOfResults)
|
|
{
|
|
sli->mbool->Get(sli->NoOfResultsDelivered, cu);
|
|
result.setAddr( cu.Clone() );
|
|
sli->NoOfResultsDelivered++;
|
|
#ifdef TUA_DEBUG
|
|
std::cerr << "temporalUnitInside_up_ur: "
|
|
<< "Finished REQUEST (YIELD)" << endl;
|
|
#endif
|
|
return YIELD;
|
|
}
|
|
sli->finished = true;
|
|
#ifdef TUA_DEBUG
|
|
std::cerr << "temporalUnitInside_up_ur: Finished REQUEST (3)"<< endl;
|
|
#endif
|
|
return CANCEL;
|
|
|
|
case CLOSE:
|
|
|
|
#ifdef TUA_DEBUG
|
|
std::cerr << "temporalUnitInside_up_ur: Received CLOSE"<< endl;
|
|
#endif
|
|
if (local.addr != 0)
|
|
{
|
|
sli = (TUInsideLocalInfo*) local.addr;
|
|
delete sli->mbool;
|
|
delete sli;
|
|
local.setAddr(0);
|
|
}
|
|
#ifdef TUA_DEBUG
|
|
std::cerr << "temporalUnitInside_up_ur: Finished CLOSE"<< endl;
|
|
#endif
|
|
return 0;
|
|
} // end switch
|
|
|
|
std::cerr << "temporalUnitInside_up_ur: Received UNKNOWN COMMAND"
|
|
<< endl;
|
|
return 0;
|
|
}
|
|
|
|
// case upoint x line --> (stream ubool)
|
|
int temporalUnitInside_up_l( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
cout << "\nATTENTION: temporalUnitInside_up_l "
|
|
<< "not yet implemented!" << endl;
|
|
assert( false );
|
|
return 0;
|
|
}
|
|
|
|
// case upoint x points --> (stream ubool)
|
|
int temporalUnitInside_up_pts( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
cout << "\nATTENTION: temporalUnitInside_up_pts "
|
|
<< "not yet implemented!" << endl;
|
|
assert( false );
|
|
return 0;
|
|
}
|
|
|
|
// case uregion x points --> (stream ubool)
|
|
int temporalUnitInside_ur_pts( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
cout << "\nATTENTION: temporalUnitInside_ur_pts "
|
|
<< "not yet implemented!" << endl;
|
|
assert( false );
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
5.37.3 Specification for operator ~inside~
|
|
|
|
*/
|
|
|
|
const std::string TemporalUnitInsideSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" "
|
|
"\"Example\" ) "
|
|
"("
|
|
"<text>"
|
|
"(upoint uregion) -> (stream ubool)\n"
|
|
"(upoint line) -> (stream ubool)*\n"
|
|
"(upoint points) -> (stream ubool)*\n"
|
|
"(uregion points) -> (stream ubool)*\n"
|
|
"(*): Not yet implemented</text--->"
|
|
"<text>_ inside _</text--->"
|
|
"<text>Returns a stream of ubool indicating, whether the first "
|
|
"object is fully included by the second one.</text--->"
|
|
"<text>query upoint1 inside uregion1 count</text--->"
|
|
") )";
|
|
|
|
/*
|
|
5.37.4 Selection Function of operator ~inside~
|
|
|
|
*/
|
|
ValueMapping temporalunitinsidemap[] =
|
|
{
|
|
temporalUnitInside_up_ur,
|
|
temporalUnitInside_up_l,
|
|
temporalUnitInside_up_pts,
|
|
temporalUnitInside_ur_pts
|
|
};
|
|
|
|
int temporalunitInsideSelect( ListExpr args )
|
|
{
|
|
ListExpr arg1 = nl->First(args);
|
|
ListExpr arg2 = nl->Second(args);
|
|
if( nl->IsEqual( arg1, UPoint::BasicType() ) &&
|
|
nl->IsEqual( arg2, URegion::BasicType()) ) return 0;
|
|
if( nl->IsEqual( arg1, UPoint::BasicType() ) &&
|
|
nl->IsEqual( arg2, Line::BasicType() ) ) return 1;
|
|
if( nl->IsEqual( arg1, UPoint::BasicType() ) &&
|
|
nl->IsEqual( arg2, Points::BasicType() ) ) return 2;
|
|
if( nl->IsEqual( arg1, URegion::BasicType() ) &&
|
|
nl->IsEqual( arg2, Points::BasicType() ) ) return 3;
|
|
|
|
std::cerr << "ERROR: Unmatched case in temporalunitInsideSelect" << endl;
|
|
std::string argstr;
|
|
nl->WriteToString(argstr, args);
|
|
std::cerr << " Argumets = '" << argstr << "'." << endl;
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
5.37.5 Definition of operator ~inside~
|
|
|
|
*/
|
|
Operator temporalunitinside( "inside",
|
|
TemporalUnitInsideSpec,
|
|
4,
|
|
temporalunitinsidemap,
|
|
temporalunitInsideSelect,
|
|
TemporalUnitInsideTypeMap);
|
|
|
|
/*
|
|
5.38 Operator ~sometimes~
|
|
|
|
----
|
|
|
|
sometimes: ( ubool) --> bool
|
|
(stream ubool) --> bool
|
|
|
|
----
|
|
|
|
*/
|
|
|
|
/*
|
|
5.38.1 Type mapping function for ~sometimes~
|
|
|
|
*/
|
|
ListExpr TemporalUnitBoolAggrTypeMap( ListExpr args )
|
|
{
|
|
ListExpr t;
|
|
std::string argstr;
|
|
|
|
if ( nl->ListLength( args ) == 1 )
|
|
{
|
|
if (nl->IsAtom(nl->First(args)))
|
|
t = nl->First( args );
|
|
else if (nl->ListLength(nl->First(args))==2 &&
|
|
nl->IsEqual(nl->First(nl->First(args)), Symbol::STREAM()))
|
|
t = nl->Second(nl->First(args));
|
|
else
|
|
{
|
|
ErrorReporter::ReportError
|
|
("Operator sometimes/always/never expects a (stream ubool)"
|
|
"or (ubool).");
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
|
}
|
|
|
|
if( nl->IsEqual( t, UBool::BasicType() ) )
|
|
return nl->SymbolAtom( CcBool::BasicType() );
|
|
}
|
|
nl->WriteToString(argstr, args);
|
|
ErrorReporter::ReportError
|
|
("Operator sometimes/always/never expects a list of length one, "
|
|
"having list structure (ubool) or (stream ubool), but it gets '"
|
|
+ argstr + "'.");
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
|
}
|
|
|
|
/*
|
|
5.38.2 Value mapping for operator ~sometimes~
|
|
|
|
*/
|
|
|
|
int TemporalUnitSometimes_streamubool( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
result = qp->ResultStorage( s );
|
|
CcBool *res = (CcBool*) result.addr;
|
|
Word elem;
|
|
UBool *U;
|
|
bool found = false;
|
|
|
|
qp->Open(args[0].addr); // open input stream
|
|
qp->Request(args[0].addr, elem); // get first elem from stream
|
|
while ( !found && qp->Received(args[0].addr) )
|
|
{
|
|
U = (UBool*) elem.addr;
|
|
if ( U->IsDefined() && U->constValue.GetBoolval() ){
|
|
found = true;
|
|
} else {
|
|
qp->Request(args[0].addr, elem);
|
|
}
|
|
U->DeleteIfAllowed();
|
|
}
|
|
qp->Close(args[0].addr); // close the stream
|
|
|
|
// create and return the result
|
|
res->Set( true, found );
|
|
return 0;
|
|
}
|
|
|
|
int TemporalUnitSometimes_ubool( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
result = qp->ResultStorage( s );
|
|
CcBool *res = (CcBool*) result.addr;
|
|
UBool *U = (UBool*) args[0].addr;
|
|
res->Set( true, ( U->IsDefined() && U->constValue.GetBoolval() ) );
|
|
return 0;
|
|
}
|
|
/*
|
|
5.38.3 Specification for operator ~sometimes~
|
|
|
|
*/
|
|
|
|
const std::string TemporalUnitSometimesSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" "
|
|
"\"Example\" ) "
|
|
"("
|
|
"<text>"
|
|
"ubool -> bool\n"
|
|
"(stream ubool) -> bool\n"
|
|
"</text--->"
|
|
"<text>sometimes( _ )</text--->"
|
|
"<text>Returns 'true', iff the ubool/stream of ubool is 'true'"
|
|
"at least once, otherwise 'false'. Never returns 'undef' itself.</text--->"
|
|
"<text>query sometimes(ubool1)</text--->"
|
|
") )";
|
|
|
|
/*
|
|
5.38.4 Selection Function of operator ~sometimes~
|
|
|
|
*/
|
|
|
|
int
|
|
TemporalUnitBoolAggrSelect( ListExpr args )
|
|
{
|
|
ListExpr arg1 = nl->First( args );
|
|
return UBool::checkType(arg1)?0:1;
|
|
}
|
|
|
|
ValueMapping TemporalUnitSometimesMap[] = {
|
|
TemporalUnitSometimes_ubool,
|
|
TemporalUnitSometimes_streamubool,
|
|
};
|
|
|
|
/*
|
|
5.38.5 Definition of operator ~sometimes~
|
|
|
|
*/
|
|
Operator temporalunitsometimes( "sometimes",
|
|
TemporalUnitSometimesSpec,
|
|
2,
|
|
TemporalUnitSometimesMap,
|
|
TemporalUnitBoolAggrSelect,
|
|
TemporalUnitBoolAggrTypeMap);
|
|
|
|
/*
|
|
5.38 Operator ~never~
|
|
|
|
----
|
|
|
|
never: ( ubool) --> bool
|
|
(stream ubool) --> bool
|
|
|
|
----
|
|
|
|
*/
|
|
|
|
/*
|
|
5.39.1 Type mapping function for ~never~
|
|
|
|
Using ~TemporalUnitBoolAggrTypeMap~
|
|
|
|
*/
|
|
|
|
/*
|
|
5.39.2 Value mapping for operator ~never~localinfo
|
|
|
|
*/
|
|
int TemporalUnitNever_streamubool( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
result = qp->ResultStorage( s );
|
|
CcBool *res = (CcBool*) result.addr;
|
|
Word elem;
|
|
UBool *U;
|
|
bool found = true;
|
|
|
|
qp->Open(args[0].addr); // open input stream
|
|
qp->Request(args[0].addr, elem); // get first elem from stream
|
|
while ( found && qp->Received(args[0].addr) )
|
|
{
|
|
U = (UBool*) elem.addr;
|
|
if ( U->IsDefined() && U->constValue.GetBoolval() )
|
|
found = false;
|
|
else
|
|
qp->Request(args[0].addr, elem);
|
|
U->DeleteIfAllowed();
|
|
}
|
|
qp->Close(args[0].addr); // close the stream
|
|
|
|
// create and return the result
|
|
res->Set( true, found );
|
|
return 0;
|
|
}
|
|
|
|
int TemporalUnitNever_ubool( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
result = qp->ResultStorage( s );
|
|
CcBool *res = (CcBool*) result.addr;
|
|
UBool *U = (UBool*) args[0].addr;
|
|
res->Set( true, ( !U->IsDefined() || !U->constValue.GetBoolval() ) );
|
|
return 0;
|
|
}
|
|
/*
|
|
5.39.3 Specification for operator ~never~
|
|
|
|
*/
|
|
const std::string TemporalUnitNeverSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" "
|
|
"\"Example\" ) "
|
|
"("
|
|
"<text>"
|
|
"ubool -> bool\n"
|
|
"(stream ubool) -> bool\n"
|
|
"</text--->"
|
|
"<text>never( _ )</text--->"
|
|
"<text>Returns 'true', iff the ubool/stream does never take value 'true', "
|
|
"otherwise 'false'. Never returns 'undef'.</text--->"
|
|
"<text>query never(ubool1)</text--->"
|
|
") )";
|
|
|
|
/*
|
|
5.39.4 Selection Function of operator ~never~
|
|
|
|
Using ~TemporalUnitBoolAggrSelect~
|
|
|
|
*/
|
|
ValueMapping TemporalUnitNeverMap[] = {
|
|
TemporalUnitNever_ubool,
|
|
TemporalUnitNever_streamubool,
|
|
};
|
|
|
|
|
|
/*
|
|
5.39.5 Definition of operator ~never~
|
|
|
|
*/
|
|
Operator temporalunitnever( "never",
|
|
TemporalUnitNeverSpec,
|
|
2,
|
|
TemporalUnitNeverMap,
|
|
TemporalUnitBoolAggrSelect,
|
|
TemporalUnitBoolAggrTypeMap);
|
|
|
|
/*
|
|
5.40 Operator ~always~
|
|
|
|
----
|
|
|
|
always: ( ubool) --> bool
|
|
(stream ubool) --> bool
|
|
|
|
----
|
|
|
|
*/
|
|
|
|
/*
|
|
5.40.1 Type mapping function for ~always~
|
|
|
|
Using ~TemporalUnitBoolAggrTypeMap~
|
|
|
|
*/
|
|
|
|
/*
|
|
5.40.2 Value mapping for operator ~always~
|
|
|
|
*/
|
|
int TemporalUnitAlways_streamubool( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
result = qp->ResultStorage( s );
|
|
CcBool *res = (CcBool*) result.addr;
|
|
Word elem;
|
|
UBool *U;
|
|
bool found = true;
|
|
|
|
qp->Open(args[0].addr); // open input stream
|
|
qp->Request(args[0].addr, elem); // get first elem from stream
|
|
while ( found && qp->Received(args[0].addr) )
|
|
{
|
|
U = (UBool*) elem.addr;
|
|
if ( U->IsDefined() && !U->constValue.GetBoolval() )
|
|
found = false;
|
|
else
|
|
qp->Request(args[0].addr, elem);
|
|
U->DeleteIfAllowed();
|
|
}
|
|
qp->Close(args[0].addr); // close the stream
|
|
|
|
// create and return the result
|
|
res->Set( true, found );
|
|
return 0;
|
|
}
|
|
|
|
int TemporalUnitAlways_ubool( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
result = qp->ResultStorage( s );
|
|
CcBool *res = (CcBool*) result.addr;
|
|
UBool *U = (UBool*) args[0].addr;
|
|
res->Set( true, ( U->IsDefined() && U->constValue.GetBoolval() ) );
|
|
return 0;
|
|
}
|
|
/*
|
|
5.40.3 Specification for operator ~always~
|
|
|
|
*/
|
|
const std::string TemporalUnitAlwaysSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" "
|
|
"\"Example\" ) "
|
|
"("
|
|
"<text>"
|
|
"ubool -> bool\n"
|
|
"(stream ubool) -> bool"
|
|
"</text--->"
|
|
"<text>always( _ )</text--->"
|
|
"<text>Returns 'false', iff the ubool/stream takes value 'false' "
|
|
"at least once, otherwise 'true'. Never returns 'undef'.</text--->"
|
|
"<text>query never(ubool1)</text--->"
|
|
") )";
|
|
|
|
/*
|
|
5.40.4 Selection Function of operator ~always~
|
|
|
|
Using ~TemporalUnitBoolAggrSelect~
|
|
|
|
*/
|
|
ValueMapping TemporalUnitAlwaysMap[] = {
|
|
TemporalUnitAlways_ubool,
|
|
TemporalUnitAlways_streamubool,
|
|
};
|
|
|
|
/*
|
|
5.40.5 Definition of operator ~always~
|
|
|
|
*/
|
|
Operator temporalunitalways( "always",
|
|
TemporalUnitAlwaysSpec,
|
|
2,
|
|
TemporalUnitAlwaysMap,
|
|
TemporalUnitBoolAggrSelect,
|
|
TemporalUnitBoolAggrTypeMap);
|
|
|
|
/*
|
|
5.41 Operator ~the\_unit~
|
|
|
|
----
|
|
|
|
the_unit: For T in {bool, int, string}
|
|
point point instant instant bool bool --> upoint
|
|
ipoint ipoint bool bool --> upoint
|
|
real real real bool instant instant bool bool --> ureal
|
|
iT duration bool bool --> uT
|
|
T instant instant bool bool --> uT
|
|
|
|
----
|
|
|
|
*/
|
|
|
|
/*
|
|
5.41.1 Type mapping function for ~the\_unit~
|
|
|
|
*/
|
|
ListExpr TU_TM_TheUnit( ListExpr args )
|
|
{
|
|
if (nl->Equal(args , nl->SixElemList(nl->SymbolAtom(Point::BasicType()),
|
|
nl->SymbolAtom(Point::BasicType()),
|
|
nl->SymbolAtom(Instant::BasicType()),
|
|
nl->SymbolAtom(Instant::BasicType()),
|
|
nl->SymbolAtom(CcBool::BasicType()),
|
|
nl->SymbolAtom(CcBool::BasicType())))){
|
|
return nl->SymbolAtom( UPoint::BasicType() );
|
|
}
|
|
|
|
if (nl->Equal(args , nl->FourElemList(nl->SymbolAtom(IPoint::BasicType()),
|
|
nl->SymbolAtom(IPoint::BasicType()),
|
|
nl->SymbolAtom(CcBool::BasicType()),
|
|
nl->SymbolAtom(CcBool::BasicType())))){
|
|
return nl->SymbolAtom( UPoint::BasicType() );
|
|
}
|
|
|
|
if(nl->Equal(args ,nl->Cons( nl->SymbolAtom(CcReal::BasicType()),
|
|
nl->Cons( nl->SymbolAtom(CcReal::BasicType()),
|
|
nl->SixElemList(nl->SymbolAtom(CcReal::BasicType()),
|
|
nl->SymbolAtom(CcBool::BasicType()),
|
|
nl->SymbolAtom(Instant::BasicType()),
|
|
nl->SymbolAtom(Instant::BasicType()),
|
|
nl->SymbolAtom(CcBool::BasicType()),
|
|
nl->SymbolAtom(CcBool::BasicType())))))){
|
|
return nl->SymbolAtom( UReal::BasicType() );
|
|
}
|
|
|
|
if (nl->Equal(args , nl->FiveElemList(nl->SymbolAtom(CcBool::BasicType()),
|
|
nl->SymbolAtom(Instant::BasicType()),
|
|
nl->SymbolAtom(Instant::BasicType()),
|
|
nl->SymbolAtom(CcBool::BasicType()),
|
|
nl->SymbolAtom(CcBool::BasicType())))){
|
|
return nl->SymbolAtom( UBool::BasicType() );
|
|
}
|
|
|
|
if (nl->Equal(args , nl->FourElemList(nl->SymbolAtom(IBool::BasicType()),
|
|
nl->SymbolAtom(Duration::BasicType()),
|
|
nl->SymbolAtom(CcBool::BasicType()),
|
|
nl->SymbolAtom(CcBool::BasicType())))){
|
|
return nl->SymbolAtom( UBool::BasicType() );
|
|
}
|
|
|
|
if (nl->Equal(args , nl->FiveElemList(nl->SymbolAtom(CcInt::BasicType()),
|
|
nl->SymbolAtom(Instant::BasicType()),
|
|
nl->SymbolAtom(Instant::BasicType()),
|
|
nl->SymbolAtom(CcBool::BasicType()),
|
|
nl->SymbolAtom(CcBool::BasicType())))){
|
|
return nl->SymbolAtom( UInt::BasicType() );
|
|
}
|
|
|
|
if (nl->Equal(args , nl->FourElemList(nl->SymbolAtom(IInt::BasicType()),
|
|
nl->SymbolAtom(Duration::BasicType()),
|
|
nl->SymbolAtom(CcBool::BasicType()),
|
|
nl->SymbolAtom(CcBool::BasicType())))){
|
|
return nl->SymbolAtom( UInt::BasicType() );
|
|
}
|
|
|
|
if (nl->Equal(args , nl->FiveElemList(nl->SymbolAtom(CcString::BasicType()),
|
|
nl->SymbolAtom(Instant::BasicType()),
|
|
nl->SymbolAtom(Instant::BasicType()),
|
|
nl->SymbolAtom(CcBool::BasicType()),
|
|
nl->SymbolAtom(CcBool::BasicType())))){
|
|
return nl->SymbolAtom( UString::BasicType() );
|
|
}
|
|
|
|
if (nl->Equal(args , nl->FourElemList(nl->SymbolAtom(IString::BasicType()),
|
|
nl->SymbolAtom(Duration::BasicType()),
|
|
nl->SymbolAtom(CcBool::BasicType()),
|
|
nl->SymbolAtom(CcBool::BasicType())))){
|
|
return nl->SymbolAtom( UString::BasicType() );
|
|
}
|
|
|
|
if (nl->Equal(args, nl->TwoElemList(nl->SymbolAtom(CcString::BasicType()),
|
|
nl->SymbolAtom(SecInterval::BasicType())))) {
|
|
return nl->SymbolAtom(UString::BasicType());
|
|
}
|
|
|
|
if (nl->Equal(args, nl->TwoElemList(nl->SymbolAtom(CcInt::BasicType()),
|
|
nl->SymbolAtom(SecInterval::BasicType())))) {
|
|
return nl->SymbolAtom(UInt::BasicType());
|
|
}
|
|
|
|
if (nl->Equal(args, nl->TwoElemList(nl->SymbolAtom(CcBool::BasicType()),
|
|
nl->SymbolAtom(SecInterval::BasicType())))) {
|
|
return nl->SymbolAtom(UBool::BasicType());
|
|
}
|
|
|
|
if (nl->Equal(args, nl->FiveElemList(nl->SymbolAtom(CcReal::BasicType()),
|
|
nl->SymbolAtom(CcReal::BasicType()),
|
|
nl->SymbolAtom(CcReal::BasicType()),
|
|
nl->SymbolAtom(CcBool::BasicType()),
|
|
nl->SymbolAtom(SecInterval::BasicType())))) {
|
|
return nl->SymbolAtom(UReal::BasicType());
|
|
}
|
|
|
|
if (nl->Equal(args, nl->ThreeElemList(nl->SymbolAtom(Point::BasicType()),
|
|
nl->SymbolAtom(Point::BasicType()),
|
|
nl->SymbolAtom(SecInterval::BasicType())))) {
|
|
return nl->SymbolAtom(UPoint::BasicType());
|
|
}
|
|
|
|
return listutils::typeError(
|
|
"Operator 'the_unit' expects a list with structure\n"
|
|
"'(point point instant instant bool bool)', or \n"
|
|
"'(ipoint ipoint bool bool)', or \n"
|
|
"'(real real real bool instant instant bool bool)', or\n"
|
|
"'(T instant instant bool bool)', or \n"
|
|
"'(iT duration bool bool)'\n for T in {bool, int, string}, or\n"
|
|
"'(T interval)' for T in {bool, int, string}, or\n"
|
|
"'(real real real bool interval)', or\n"
|
|
"'(point point interval)'");
|
|
}
|
|
|
|
/*
|
|
5.41.2 Value mapping for operator ~the\_unit~
|
|
|
|
*/
|
|
// point point instant instant bool bool --> ubool
|
|
int TU_VM_TheUnit_ppiibb(Word* args, Word& result,
|
|
int message, Word& local, Supplier s)
|
|
{
|
|
result = (qp->ResultStorage( s ));
|
|
UPoint *res = (UPoint*)result.addr;
|
|
Point *p1 = (Point*)args[0].addr;
|
|
Point *p2 = (Point*)args[1].addr;
|
|
Instant *i1 = (Instant*)args[2].addr;
|
|
Instant *i2 = (Instant*)args[3].addr;
|
|
CcBool *cl = (CcBool*)args[4].addr;
|
|
CcBool *cr = (CcBool*)args[5].addr;
|
|
bool clb, crb;
|
|
|
|
// Test arguments for definedness
|
|
if ( !p1->IsDefined() || !p2->IsDefined() ||
|
|
!i1->IsDefined() || !i2->IsDefined() ||
|
|
!cl->IsDefined() || !cr->IsDefined() )
|
|
{
|
|
res->SetDefined( false );
|
|
return 0;
|
|
}
|
|
clb = cl->GetBoolval();
|
|
crb = cr->GetBoolval();
|
|
|
|
if ( ( (*i1 == *i2) && (!clb || !crb) ) ||
|
|
( i1->Adjacent(i2) && !(clb || crb) ) )
|
|
// illegal interval setting
|
|
{ res->SetDefined( false ); return 0; }
|
|
if ( *i1 < *i2 ) // sort instants
|
|
{
|
|
Interval<Instant> interval( *i1, *i2, clb, crb );
|
|
*res = UPoint( interval, *p1, *p2 );
|
|
}
|
|
else
|
|
{
|
|
Interval<Instant> interval( *i2, *i1, clb, crb );
|
|
*res = UPoint( interval, *p2, *p1 );
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// ipoint ipoint bool bool --> upoint
|
|
int TU_VM_TheUnit_ipipbb(Word* args, Word& result,
|
|
int message, Word& local, Supplier s)
|
|
{
|
|
result = (qp->ResultStorage( s ));
|
|
UPoint *res = (UPoint*)result.addr;
|
|
Intime<Point> *ip1 = (Intime<Point> *)args[0].addr;
|
|
Intime<Point> *ip2 = (Intime<Point> *)args[1].addr;
|
|
CcBool *cl = (CcBool*)args[2].addr;
|
|
CcBool *cr = (CcBool*)args[3].addr;
|
|
bool clb, crb;
|
|
|
|
// Test arguments for definedness
|
|
if ( !ip1->IsDefined() || !ip2->IsDefined() ||
|
|
!cl->IsDefined() || !cr->IsDefined() )
|
|
{
|
|
res->SetDefined( false );
|
|
return 0;
|
|
}
|
|
clb = cl->GetBoolval();
|
|
crb = cr->GetBoolval();
|
|
|
|
if ( ( (ip1->instant == ip2->instant) && (!clb || !crb) ) ||
|
|
( ip1->instant.Adjacent(&ip2->instant) && !(clb || crb) ) )
|
|
// illegal interval setting
|
|
{ res->SetDefined( false ); return 0; }
|
|
if ( ip1->instant < ip2->instant ) // sort instants
|
|
{
|
|
Interval<Instant> interval( ip1->instant, ip2->instant, clb, crb );
|
|
*res = UPoint( interval, ip1->value, ip2->value );
|
|
}
|
|
else
|
|
{
|
|
Interval<Instant> interval( ip2->instant, ip1->instant, clb, crb );
|
|
*res = UPoint( interval, ip2->value, ip1->value );
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// real real real bool instant instant bool bool -> ubool
|
|
int TU_VM_TheUnit_rrrbiibb(Word* args, Word& result,
|
|
int message, Word& local, Supplier s)
|
|
{
|
|
result = (qp->ResultStorage( s ));
|
|
UReal *res = (UReal*)result.addr;
|
|
CcReal *a = (CcReal*)args[0].addr;
|
|
CcReal *b = (CcReal*)args[1].addr;
|
|
CcReal *c = (CcReal*)args[2].addr;
|
|
CcBool *r = (CcBool*)args[3].addr;
|
|
Instant *i1 = (Instant*)args[4].addr;
|
|
Instant *i2 = (Instant*)args[5].addr;
|
|
CcBool *cl = (CcBool*)args[6].addr;
|
|
CcBool *cr = (CcBool*)args[7].addr;
|
|
bool clb, crb;
|
|
|
|
// Test arguments for definedness
|
|
if ( !a->IsDefined() || !b->IsDefined() ||
|
|
!c->IsDefined() || !r->IsDefined() ||
|
|
!i1->IsDefined() || !i2->IsDefined() ||
|
|
!cl->IsDefined() || !cr->IsDefined() )
|
|
{
|
|
res->SetDefined( false );
|
|
return 0;
|
|
}
|
|
clb = cl->GetBoolval();
|
|
crb = cr->GetBoolval();
|
|
|
|
if ( ( (*i1 == *i2) && (!clb || !crb) ) ||
|
|
( i1->Adjacent(i2) && !(clb || crb) ) )// illegal interval setting
|
|
{ res->SetDefined( false ); return 0; }
|
|
if ( *i1 < *i2 ) // sort instants
|
|
{
|
|
Interval<Instant> interval( *i1, *i2, clb, crb );
|
|
*res = UReal( interval, a->GetRealval(), b->GetRealval(),
|
|
c->GetRealval(), r->GetBoolval() );
|
|
}
|
|
else
|
|
{
|
|
Interval<Instant> interval( *i2, *i1, clb, crb );
|
|
*res = UReal( interval, a->GetRealval(), b->GetRealval(),
|
|
c->GetRealval(), r->GetBoolval() );
|
|
};
|
|
return 0;
|
|
}
|
|
|
|
// template for constant unit types:
|
|
// iT duration bool bool -> uT
|
|
template<class T>
|
|
int TU_VM_TheUnit_iTdbb(Word* args, Word& result,
|
|
int message, Word& local, Supplier s)
|
|
{
|
|
result = (qp->ResultStorage( s ));
|
|
ConstTemporalUnit<T> *res = (ConstTemporalUnit<T> *)result.addr;
|
|
Intime<T> *ip = (Intime<T> *)args[0].addr;
|
|
datetime::DateTime *dur = (datetime::DateTime*) args[1].addr;
|
|
CcBool *cl = (CcBool*)args[2].addr;
|
|
CcBool *cr = (CcBool*)args[3].addr;
|
|
bool clb, crb;
|
|
|
|
// Test arguments for definedness
|
|
if ( !ip->IsDefined() || !dur->IsDefined() ||
|
|
!cl->IsDefined() || !cr->IsDefined() )
|
|
{
|
|
res->SetDefined( false );
|
|
return 0;
|
|
}
|
|
clb = cl->GetBoolval();
|
|
crb = cr->GetBoolval();
|
|
|
|
assert(dur->GetType() == datetime::durationtype);
|
|
if ( ( (*dur == datetime::DateTime(0,0,datetime::durationtype))
|
|
&& (!clb || !crb) ) ||
|
|
( (*dur == datetime::DateTime(0,1,datetime::durationtype))
|
|
&& !( clb || crb) ) )
|
|
// illegal interval setting
|
|
{ res->SetDefined( false ); return 0; }
|
|
Interval<Instant> interval( ip->instant, ip->instant+(*dur), clb, crb );
|
|
*res = ConstTemporalUnit<T>( interval, ip->value );
|
|
return 0;
|
|
}
|
|
|
|
|
|
// template for constant unit types:
|
|
// T instant instant bool bool -> uT
|
|
template<class T>
|
|
int TU_VM_TheUnit_Tiibb(Word* args, Word& result,
|
|
int message, Word& local, Supplier s)
|
|
{
|
|
result = (qp->ResultStorage( s ));
|
|
ConstTemporalUnit<T> *res = static_cast<ConstTemporalUnit<T> *>(result.addr);
|
|
T *value = static_cast<T*>(args[0].addr);
|
|
Instant *i1 = static_cast<datetime::DateTime*>(args[1].addr);
|
|
Instant *i2 = static_cast<datetime::DateTime*>(args[2].addr);
|
|
CcBool *cl = static_cast<CcBool*>(args[3].addr);
|
|
CcBool *cr = static_cast<CcBool*>(args[4].addr);
|
|
bool clb, crb;
|
|
|
|
// Test arguments for definedness
|
|
if ( !value->IsDefined() ||
|
|
!i1->IsDefined() || !i2->IsDefined() ||
|
|
!cl->IsDefined() || !cr->IsDefined() ) {
|
|
res->SetDefined( false );
|
|
return 0;
|
|
}
|
|
|
|
clb = cl->GetBoolval();
|
|
crb = cr->GetBoolval();
|
|
|
|
if ( ( (*i1 == *i2) && (!clb || !crb) ) ||
|
|
( i1->Adjacent(i2) && !(clb || crb) ) ) { // illegal interval setting
|
|
res->SetDefined( false );
|
|
return 0;
|
|
}
|
|
if ( *i1 < *i2 ) {// sort instants
|
|
Interval<Instant> interval( *i1, *i2, clb, crb );
|
|
*res = ConstTemporalUnit<T>( interval, *value );
|
|
} else {
|
|
Interval<Instant> interval( *i2, *i1, clb, crb );
|
|
*res = ConstTemporalUnit<T>( interval, *value );
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
// template for constant unit types:
|
|
// T x interval --> uT
|
|
template<class T>
|
|
int TU_VM_TheUnit_Tiv(Word* args, Word& result, int message, Word& local,
|
|
Supplier s) {
|
|
result = qp->ResultStorage(s);
|
|
ConstTemporalUnit<T> *res = static_cast<ConstTemporalUnit<T> *>(result.addr);
|
|
T *value = static_cast<T*>(args[0].addr);
|
|
SecInterval *iv = static_cast<SecInterval*>(args[1].addr);
|
|
if (!value->IsDefined() || !iv->IsDefined()) {
|
|
res->SetDefined(false);
|
|
return 0;
|
|
}
|
|
*res = ConstTemporalUnit<T>(*iv, *value);
|
|
return 0;
|
|
}
|
|
|
|
|
|
// real real real bool interval -> ubool
|
|
int TU_VM_TheUnit_rrrbiv(Word* args, Word& result, int message, Word& local,
|
|
Supplier s) {
|
|
result = qp->ResultStorage(s);
|
|
UReal *res = (UReal*)result.addr;
|
|
CcReal *a = (CcReal*)args[0].addr;
|
|
CcReal *b = (CcReal*)args[1].addr;
|
|
CcReal *c = (CcReal*)args[2].addr;
|
|
CcBool *r = (CcBool*)args[3].addr;
|
|
SecInterval *iv = (SecInterval*)args[4].addr;
|
|
if (!a->IsDefined() || !b->IsDefined() || !c->IsDefined() || !r->IsDefined()
|
|
|| !iv->IsDefined()) {
|
|
res->SetDefined(false);
|
|
return 0;
|
|
}
|
|
*res = UReal(*iv, a->GetRealval(), b->GetRealval(), c->GetRealval(),
|
|
r->GetBoolval());
|
|
return 0;
|
|
}
|
|
|
|
|
|
// point point interval --> ubool
|
|
int TU_VM_TheUnit_ppiv(Word* args, Word& result, int message, Word& local,
|
|
Supplier s) {
|
|
result = qp->ResultStorage(s);
|
|
UPoint *res = (UPoint*)result.addr;
|
|
Point *p1 = (Point*)args[0].addr;
|
|
Point *p2 = (Point*)args[1].addr;
|
|
SecInterval *iv = (SecInterval*)args[2].addr;
|
|
if (!p1->IsDefined() || !p2->IsDefined() || !iv->IsDefined()) {
|
|
res->SetDefined(false);
|
|
return 0;
|
|
}
|
|
*res = UPoint(*iv, *p1, *p2);
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
5.41.3 Specification for operator ~the\_unit~
|
|
|
|
*/
|
|
const std::string TU_Spec_TheUnit =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" "
|
|
"\"Example\" ) "
|
|
"("
|
|
"<text>For T in {bool, int, string}:\n"
|
|
"point x point x instant x instant x bool x bool --> upoint\n"
|
|
"ipoint x ipoint x bool x bool --> upoint\n"
|
|
"real x real x real x bool x instant x instant x bool x bool --> ureal\n"
|
|
"iT x duration x bool x bool --> uT\n"
|
|
"T x instant x instant x bool x bool --> uT\n"
|
|
"T x interval --> uT\n"
|
|
"real x real x real x bool x interval --> ureal\n"
|
|
"point x point x interval --> upoint\n"
|
|
"</text--->"
|
|
"<text>the_unit( pstart, pend, tstart, tend, cl, cr )\n"
|
|
"the_unit( ip1, ip2, cl, cr )\n"
|
|
"the_unit( a, b, c, r, tstart, tend, cl, cr )</text--->"
|
|
"<text>Creates a unit value from the argument list. The instants/ipoints"
|
|
"/(point/instant)-pairs will be sorted automatically.</text--->"
|
|
"<text>query the_unit(point1, point2, instant1, instant2, bool1, bool2)"
|
|
"</text--->"
|
|
") )";
|
|
|
|
/*
|
|
5.41.4 Selection Function of operator ~the\_unit~
|
|
|
|
*/
|
|
int TU_Select_TheUnit( ListExpr args )
|
|
{
|
|
std::string argstr;
|
|
nl->WriteToString(argstr, args);
|
|
|
|
if (argstr == "(point point instant instant bool bool)") return 0;
|
|
if (argstr == "(ipoint ipoint bool bool)") return 1;
|
|
if (argstr == "(real real real bool instant instant bool bool)") return 2;
|
|
if (argstr == "(bool instant instant bool bool)") return 3;
|
|
if (argstr == "(ibool duration bool bool)") return 4;
|
|
if (argstr == "(int instant instant bool bool)") return 5;
|
|
if (argstr == "(iint duration bool bool)") return 6;
|
|
if (argstr == "(string instant instant bool bool)") return 7;
|
|
if (argstr == "(istring duration bool bool)") return 8;
|
|
if (argstr == "(string interval)") return 9;
|
|
if (argstr == "(int interval)") return 10;
|
|
if (argstr == "(bool interval)") return 11;
|
|
if (argstr == "(real real real bool interval)") return 12;
|
|
if (argstr == "(point point interval)") return 13;
|
|
return -1; // should not be reached!
|
|
}
|
|
|
|
ValueMapping TU_VMMap_TheUnit[] =
|
|
{
|
|
TU_VM_TheUnit_ppiibb, //0
|
|
TU_VM_TheUnit_ipipbb,
|
|
TU_VM_TheUnit_rrrbiibb, //2
|
|
TU_VM_TheUnit_Tiibb<CcBool>,
|
|
TU_VM_TheUnit_iTdbb<CcBool>, //4
|
|
TU_VM_TheUnit_Tiibb<CcInt>,
|
|
TU_VM_TheUnit_iTdbb<CcInt>, //6
|
|
TU_VM_TheUnit_Tiibb<CcString>,
|
|
TU_VM_TheUnit_iTdbb<CcString>, //8
|
|
TU_VM_TheUnit_Tiv<CcString>,
|
|
TU_VM_TheUnit_Tiv<CcInt>, //10
|
|
TU_VM_TheUnit_Tiv<CcBool>,
|
|
TU_VM_TheUnit_rrrbiv, //12
|
|
TU_VM_TheUnit_ppiv};
|
|
/*
|
|
5.41.5 Definition of operator ~the\_unit~
|
|
|
|
*/
|
|
Operator temporalunittheupoint( "the_unit",
|
|
TU_Spec_TheUnit,
|
|
14,
|
|
TU_VMMap_TheUnit,
|
|
TU_Select_TheUnit,
|
|
TU_TM_TheUnit);
|
|
/*
|
|
5.42 Operator ~the\_ivalue~
|
|
|
|
This operator creates an intime value from an instant and a value.
|
|
|
|
----
|
|
the_ivalue: For T in {bool, int, string, real, point, region}
|
|
OK (instant T) --> iT
|
|
|
|
----
|
|
|
|
*/
|
|
|
|
/*
|
|
5.42.1 Type mapping function for ~the\_ivalue~
|
|
|
|
*/
|
|
ListExpr TU_TM_TheIvalue( ListExpr args )
|
|
{
|
|
if( (nl->ListLength(args)==2) &&
|
|
(listutils::isSymbol(nl->First(args),Instant::BasicType())) ){
|
|
|
|
ListExpr second = nl->Second(args);
|
|
if (listutils::isSymbol(second, CcBool::BasicType()) ){
|
|
return nl->SymbolAtom( IBool::BasicType() );
|
|
}
|
|
if (listutils::isSymbol(second, CcInt::BasicType()) ){
|
|
return nl->SymbolAtom( IInt::BasicType() );
|
|
}
|
|
if (listutils::isSymbol(second, CcString::BasicType()) ){
|
|
return nl->SymbolAtom( IString::BasicType() );
|
|
}
|
|
if (listutils::isSymbol(second, CcReal::BasicType()) ){
|
|
return nl->SymbolAtom( IReal::BasicType() );
|
|
}
|
|
if (listutils::isSymbol(second, Point::BasicType()) ){
|
|
return nl->SymbolAtom( IPoint::BasicType() );
|
|
}
|
|
if (listutils::isSymbol(second, Region::BasicType()) ){
|
|
return nl->SymbolAtom( IRegion::BasicType() );
|
|
}
|
|
}
|
|
return listutils::typeError(
|
|
"Operator 'the_ivalue' expects a list with structure "
|
|
"'(instant T)', "
|
|
"for T in {bool, int, string, real, point, region}.");
|
|
}
|
|
|
|
/*
|
|
5.42.2 Value mapping for operator ~the\_ivalue~
|
|
|
|
*/
|
|
|
|
template <class T>
|
|
int TU_VM_TheIvalue(Word* args, Word& result,
|
|
int message, Word& local, Supplier s)
|
|
{
|
|
result = (qp->ResultStorage( s ));
|
|
Intime<T> *res = (Intime<T> *) result.addr;
|
|
Instant *inst = (datetime::DateTime*) args[0].addr;
|
|
T *value = (T*) args[1].addr;
|
|
*res = Intime<T>(*inst, *value);
|
|
return 0;
|
|
|
|
}
|
|
|
|
/*
|
|
5.42.3 Specification for operator ~the\_ivalue~
|
|
|
|
*/
|
|
const std::string TU_Spec_TheIvalue =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" "
|
|
"\"Example\" ) "
|
|
"("
|
|
"<text>For T in {bool, int, string, real, point, region}:\n"
|
|
"instant T --> iT"
|
|
"</text--->"
|
|
"<text>the_ivalue( instant, value )</text--->"
|
|
"<text>Creates an intime value from the argument list. "
|
|
"An undef 'instant' argument results in an undef result.</text--->"
|
|
"<text>query the_ivalue(instant1, point1)"
|
|
"</text--->"
|
|
") )";
|
|
|
|
/*
|
|
5.42.4 Selection Function of operator ~the\_ivalue~
|
|
|
|
*/
|
|
int TU_Select_TheIvalue( ListExpr args )
|
|
{
|
|
std::string argstr;
|
|
nl->WriteToString(argstr, args);
|
|
|
|
if (argstr == "(instant bool)")
|
|
return 0;
|
|
if (argstr == "(instant int)")
|
|
return 1;
|
|
if (argstr == "(instant string)")
|
|
return 2;
|
|
if (argstr == "(instant real)")
|
|
return 3;
|
|
if (argstr == "(instant point)")
|
|
return 4;
|
|
if (argstr == "(instant region)")
|
|
return 5;
|
|
|
|
return -1; // should not be reached!
|
|
}
|
|
|
|
ValueMapping TU_VMMap_TheIvalue[] =
|
|
{
|
|
TU_VM_TheIvalue<CcBool>,
|
|
TU_VM_TheIvalue<CcInt>,
|
|
TU_VM_TheIvalue<CcString>,
|
|
TU_VM_TheIvalue<CcReal>,
|
|
TU_VM_TheIvalue<Point>,
|
|
TU_VM_TheIvalue<Region>
|
|
};
|
|
/*
|
|
5.42.5 Definition of operator ~the\_ivalue~
|
|
|
|
*/
|
|
Operator temporalunittheivalue( "the_ivalue",
|
|
TU_Spec_TheIvalue,
|
|
6,
|
|
TU_VMMap_TheIvalue,
|
|
TU_Select_TheIvalue,
|
|
TU_TM_TheIvalue);
|
|
|
|
/*
|
|
5.41 Operator ~ComparePredicateValues~
|
|
|
|
Here, we implement the binary comparison operators/predicates for (uT uT).
|
|
The predicates are
|
|
|
|
----
|
|
|
|
= (equality),
|
|
# (unequality),
|
|
< (smaller than),
|
|
> (bigger than),
|
|
<= (smaller than or equal to),
|
|
>= (bigger than or equal to).
|
|
|
|
----
|
|
|
|
The operators compare the values for each instant of time, so they will return
|
|
a (stream ubool) for the intersection of the arguments' deftimes.
|
|
|
|
WARNING: Do not confuse this operators with the ~ComparePredicates~, which
|
|
compare the units as such, but not the temporal functions.
|
|
|
|
----
|
|
=, #, <, >, <=, >=: For T in {int, bool, real, string, point*, region*}
|
|
(*): {#, =} only
|
|
Test + uT x uT --> (stream ubool)
|
|
Test + uT x T --> (stream ubool) (**)
|
|
Test + T x uT --> (stream ubool) +(**)
|
|
(**): Not for T = region
|
|
|
|
----
|
|
|
|
*/
|
|
|
|
/*
|
|
5.43.1 Type mapping function for ~ComparePredicateValues~
|
|
|
|
*/
|
|
ListExpr TUCompareValuePredicatesTypeMap( ListExpr args )
|
|
{
|
|
|
|
if( nl->ListLength( args ) == 2 )
|
|
{
|
|
ListExpr arg1, arg2;
|
|
arg1 = nl->First( args );
|
|
arg2 = nl->Second( args );
|
|
if (nl->Equal( arg1, arg2 ))
|
|
{
|
|
if( (nl->IsEqual( arg1, UBool::BasicType() ) ) ||
|
|
(nl->IsEqual( arg1, UInt::BasicType() ) ) ||
|
|
(nl->IsEqual( arg1, UReal::BasicType() ) ) ||
|
|
(nl->IsEqual( arg1, UString::BasicType() ) )
|
|
)
|
|
return nl->TwoElemList(nl->SymbolAtom( Symbol::STREAM() ),
|
|
nl->SymbolAtom( UBool::BasicType() ));
|
|
}
|
|
else if
|
|
(
|
|
((nl->IsEqual( arg1, UBool::BasicType() ))
|
|
&& (nl->IsEqual( arg2, CcBool::BasicType() ))) ||
|
|
((nl->IsEqual( arg1, UInt::BasicType() ))
|
|
&& (nl->IsEqual( arg2, CcInt::BasicType() ))) ||
|
|
((nl->IsEqual( arg1, UReal::BasicType() ))
|
|
&& (nl->IsEqual( arg2, CcReal::BasicType() ))) ||
|
|
((nl->IsEqual( arg1, UString::BasicType() ))
|
|
&& (nl->IsEqual( arg2, CcString::BasicType() ))) ||
|
|
((nl->IsEqual( arg1, CcBool::BasicType() ))
|
|
&& (nl->IsEqual( arg2, UBool::BasicType() ))) ||
|
|
((nl->IsEqual( arg1, CcInt::BasicType() ))
|
|
&& (nl->IsEqual( arg2, UInt::BasicType() ))) ||
|
|
((nl->IsEqual( arg1, CcReal::BasicType() ))
|
|
&& (nl->IsEqual( arg2, UReal::BasicType() ))) ||
|
|
((nl->IsEqual( arg1, CcString::BasicType() ))
|
|
&& (nl->IsEqual( arg2, UString::BasicType() )))
|
|
)
|
|
return nl->TwoElemList(nl->SymbolAtom( Symbol::STREAM() ),
|
|
nl->SymbolAtom( UBool::BasicType() ));
|
|
}
|
|
// Error case:
|
|
ErrorReporter::ReportError(
|
|
"CompareTemporalValueOperator (one of <, >, <=, >=) "
|
|
"expects two arguments of types '(uT x uT)', '(T x uT)', or '(uT x T)', "
|
|
"where T in {bool, int, real, string}.");
|
|
return nl->SymbolAtom(Symbol::TYPEERROR());
|
|
}
|
|
|
|
ListExpr TUCompareValueEqPredicatesTypeMap( ListExpr args )
|
|
{
|
|
if( nl->ListLength( args ) == 2 )
|
|
{
|
|
ListExpr arg1, arg2;
|
|
arg1 = nl->First( args );
|
|
arg2 = nl->Second( args );
|
|
if (nl->Equal( arg1, arg2 ))
|
|
{
|
|
if( (nl->IsEqual( arg1, UBool::BasicType() ) ) ||
|
|
(nl->IsEqual( arg1, UInt::BasicType() ) ) ||
|
|
(nl->IsEqual( arg1, UReal::BasicType() ) ) ||
|
|
(nl->IsEqual( arg1, UString::BasicType() ) ||
|
|
(nl->IsEqual( arg1, UPoint::BasicType() ) ) ||
|
|
(nl->IsEqual( arg1, URegion::BasicType() ) ) ) )
|
|
return nl->TwoElemList(nl->SymbolAtom( Symbol::STREAM() ),
|
|
nl->SymbolAtom( UBool::BasicType() ));
|
|
}
|
|
std::string argstr;
|
|
nl->WriteToString(argstr, args);
|
|
if (argstr == "(bool ubool)" || argstr == "(ubool bool)" ||
|
|
argstr == "(int uint)" || argstr == "(unit int)" ||
|
|
argstr == "(string ustring)" || argstr == "(ustring string)" ||
|
|
argstr == "(real ureal)" || argstr == "(ureal real)" ||
|
|
argstr == "(point upoint)" || argstr == "(upoint point)")
|
|
return nl->TwoElemList(nl->SymbolAtom( Symbol::STREAM() ),
|
|
nl->SymbolAtom( UBool::BasicType() ));
|
|
}
|
|
// Error case:
|
|
ErrorReporter::ReportError(
|
|
"CompareTemporalValueOperator (one of =, #) "
|
|
"expects two arguments of "
|
|
"type 'uT x uT', 'T x uT' or 'uT x T', where T in "
|
|
"{bool, int, real, string, point}, or (uregion x uregion). ");
|
|
return nl->SymbolAtom(Symbol::TYPEERROR());
|
|
}
|
|
|
|
/*
|
|
5.43.2 Value mapping for operator ~ComparePredicateValues~
|
|
|
|
*/
|
|
template <class T, int opcode>
|
|
int TU_VM_ComparePredicateValue_Const(Word* args, Word& result,
|
|
int message, Word& local, Supplier s)
|
|
{
|
|
assert( (opcode >= 0) && (opcode <= 5));
|
|
|
|
ConstTemporalUnit<T> *u1 = (ConstTemporalUnit<T> *) args[0].addr;
|
|
ConstTemporalUnit<T> *u2 = (ConstTemporalUnit<T> *) args[1].addr;
|
|
bool *finished;
|
|
Interval<Instant> iv;
|
|
int p1;
|
|
bool compresult = false;
|
|
|
|
switch( message )
|
|
{
|
|
case OPEN:
|
|
finished = new bool(false); //
|
|
local.setAddr(finished);
|
|
return 0;
|
|
|
|
case REQUEST:
|
|
if( local.addr == 0 )
|
|
return CANCEL;
|
|
finished = (bool*) local.addr;
|
|
if ( *finished )
|
|
return CANCEL;
|
|
if ( !u1->IsDefined() || !u2->IsDefined() )
|
|
{ *finished = true; return CANCEL; }
|
|
if (!u1->timeInterval.Intersects(u2->timeInterval) )
|
|
{ *finished = true; return CANCEL; }
|
|
|
|
u1->timeInterval.Intersection(u2->timeInterval, iv);
|
|
p1 = u1->constValue.Compare( &u2->constValue );
|
|
|
|
switch (opcode)
|
|
{
|
|
case 0: // is_equal
|
|
compresult = (p1 == 0); break;
|
|
case 1: // is_not_equal
|
|
compresult = (p1 != 0); break;
|
|
case 2: // less_than
|
|
compresult = (p1 == -1); break;
|
|
case 3: // bigger_than
|
|
compresult = (p1 == 1); break;
|
|
case 4: // less_or_equal
|
|
compresult = (p1 < 1); break;
|
|
case 5: // bigger_or_equal
|
|
compresult = (p1 > -1); break;
|
|
} // end switch (opcode)
|
|
result.setAddr(
|
|
new ConstTemporalUnit<CcBool>(iv, CcBool(true, compresult) ) );
|
|
*finished = true; // only one result!
|
|
return YIELD;
|
|
|
|
case CLOSE:
|
|
if( local.addr != 0 )
|
|
{
|
|
finished = (bool*) local.addr;
|
|
delete finished;
|
|
local.setAddr(0);
|
|
}
|
|
return 0;
|
|
} // end switch (message)
|
|
return -1; // should not be reached
|
|
}
|
|
|
|
template <class T, int opcode, int unit_arg>
|
|
int TU_VM_ComparePredicateValue_Const_T(Word* args, Word& result,
|
|
int message, Word& local, Supplier s)
|
|
{
|
|
assert( (opcode >= 0) && (opcode <= 5));
|
|
assert( (unit_arg >=0) && (unit_arg <=1));
|
|
|
|
ConstTemporalUnit<T> *u1;
|
|
T *u2;
|
|
|
|
if (unit_arg == 0)
|
|
{
|
|
u1 = (ConstTemporalUnit<T> *) args[0].addr;
|
|
u2 = (T*) args[1].addr;
|
|
}
|
|
else // (unit_arg == 1)
|
|
{
|
|
u1 = (ConstTemporalUnit<T> *) args[1].addr;
|
|
u2 = (T*) args[0].addr;
|
|
}
|
|
bool *finished;
|
|
Interval<Instant> iv;
|
|
int p1;
|
|
bool compresult = false;
|
|
|
|
switch( message )
|
|
{
|
|
case OPEN:
|
|
finished = new bool(false); //
|
|
local.setAddr(finished);
|
|
return 0;
|
|
|
|
case REQUEST:
|
|
if( local.addr == 0 )
|
|
return CANCEL;
|
|
finished = (bool*) local.addr;
|
|
if ( *finished )
|
|
return CANCEL;
|
|
if ( !u1->IsDefined() || !u2->IsDefined() )
|
|
{ *finished = true; return CANCEL; }
|
|
|
|
if(unit_arg == 0)
|
|
p1 = u1->constValue.Compare( u2 );
|
|
else
|
|
p1 = u2->Compare( &(u1->constValue) );
|
|
|
|
switch (opcode)
|
|
{
|
|
case 0: // is_equal
|
|
compresult = (p1 == 0); break;
|
|
case 1: // is_not_equal
|
|
compresult = (p1 != 0); break;
|
|
case 2: // less_than
|
|
compresult = (p1 == -1); break;
|
|
case 3: // bigger_than
|
|
compresult = (p1 == 1); break;
|
|
case 4: // less_or_equal
|
|
compresult = (p1 < 1); break;
|
|
case 5: // bigger_or_equal
|
|
compresult = (p1 > -1); break;
|
|
} // end switch (opcode)
|
|
result.setAddr(
|
|
new ConstTemporalUnit<CcBool>(u1->timeInterval,
|
|
CcBool(true, compresult) ) );
|
|
*finished = true; // only one result!
|
|
return YIELD;
|
|
|
|
case CLOSE:
|
|
if( local.addr != 0 )
|
|
{
|
|
finished = (bool*) local.addr;
|
|
delete finished;
|
|
local.setAddr(0);
|
|
}
|
|
return 0;
|
|
} // end switch (message)
|
|
return -1; // should not be reached
|
|
}
|
|
|
|
struct TUCompareValueLocalInfo
|
|
{
|
|
bool finished;
|
|
int NoOfResults;
|
|
int NoOfResultsDelivered;
|
|
MBool *intersectionBool;
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <int opcode>
|
|
int TU_VM_ComparePredicateValue_UPoint(Word* args, Word& result,
|
|
int message, Word& local, Supplier s)
|
|
{
|
|
assert( (opcode >= 0) && (opcode <= 1));
|
|
|
|
UPoint *u1 = (UPoint*) args[0].addr;
|
|
UPoint *u2 = (UPoint*) args[1].addr;
|
|
UPoint uinters(true);
|
|
UBool cu;
|
|
TUCompareValueLocalInfo *localinfo;
|
|
Interval<Instant> iv, ivBefore, ivInters, ivAfter;
|
|
|
|
switch( message )
|
|
{
|
|
case OPEN: {
|
|
localinfo = new TUCompareValueLocalInfo();
|
|
localinfo->finished = true;
|
|
localinfo->NoOfResults = 0;
|
|
localinfo->NoOfResultsDelivered = 0;
|
|
localinfo->intersectionBool = new MBool(5);
|
|
local.setAddr(localinfo);
|
|
|
|
if ( !u1->IsDefined() || !u2->IsDefined() ) {
|
|
return 0;
|
|
}
|
|
// fill up the result
|
|
RefinementStream<MPoint,MPoint,UPoint,UPoint> rs(u1,u2);
|
|
int pos1;
|
|
int pos2;
|
|
Interval<Instant> iv;
|
|
bool compValue = opcode==0?true:false;
|
|
|
|
while(rs.hasNext()){
|
|
rs.getNext(iv,pos1,pos2);
|
|
if(pos1==0 && pos2==0){ // the common time interval if exists
|
|
Point p1_start(true);
|
|
Point p1_end(true);
|
|
Point p2_start(true);
|
|
Point p2_end(true);
|
|
u1->TemporalFunction(iv.start,p1_start,true);
|
|
u1->TemporalFunction(iv.end,p1_end,true);
|
|
u2->TemporalFunction(iv.start,p2_start,true);
|
|
u2->TemporalFunction(iv.end,p2_end,true);
|
|
computeMEquality(iv, p1_start, p1_end,
|
|
p2_start, p2_end,
|
|
*(localinfo->intersectionBool),
|
|
compValue);
|
|
}
|
|
}
|
|
localinfo->NoOfResults = localinfo->intersectionBool->GetNoComponents();
|
|
localinfo->finished = localinfo->NoOfResults == 0;
|
|
}
|
|
return 0;
|
|
case REQUEST:
|
|
if( local.addr == 0 ) {
|
|
return CANCEL;
|
|
}
|
|
localinfo = (TUCompareValueLocalInfo*) local.addr;
|
|
if ( localinfo->finished ){
|
|
return CANCEL;
|
|
}
|
|
if ( localinfo->NoOfResultsDelivered >= localinfo->NoOfResults) {
|
|
localinfo->finished = true;
|
|
return CANCEL;
|
|
}
|
|
localinfo->intersectionBool->Get(localinfo->NoOfResultsDelivered, cu);
|
|
result.setAddr( cu.Clone() );
|
|
localinfo->NoOfResultsDelivered++;
|
|
return YIELD;
|
|
|
|
case CLOSE:
|
|
if( local.addr != 0 )
|
|
{
|
|
localinfo = (TUCompareValueLocalInfo*) local.addr;
|
|
delete localinfo->intersectionBool;
|
|
delete localinfo;
|
|
local.setAddr(0);
|
|
}
|
|
return 0;
|
|
} // end switch (message)
|
|
return -1; // should not be reached
|
|
}
|
|
|
|
template <int opcode, int unit_arg>
|
|
int TU_VM_ComparePredicateValue_UPoint_Point(Word* args, Word& result,
|
|
int message, Word& local, Supplier s)
|
|
{
|
|
assert( (opcode >= 0) && (opcode <= 1));
|
|
assert( (unit_arg >= 0) && (unit_arg <= 1));
|
|
|
|
UPoint *u1;
|
|
Point *p;
|
|
|
|
if(unit_arg == 0)
|
|
{
|
|
u1 = (UPoint*) args[0].addr;
|
|
p = (Point*) args[1].addr;
|
|
}
|
|
else{
|
|
u1 = (UPoint*) args[1].addr;
|
|
p = (Point*) args[0].addr;
|
|
}
|
|
UPoint *u2, uinters(true);
|
|
UBool cu;
|
|
TUCompareValueLocalInfo *localinfo;
|
|
Interval<Instant> iv, ivBefore, ivInters, ivAfter;
|
|
bool compresult = false;
|
|
|
|
switch( message )
|
|
{
|
|
case OPEN:
|
|
|
|
localinfo = new TUCompareValueLocalInfo;
|
|
localinfo->finished = true;
|
|
localinfo->NoOfResults = 0;
|
|
localinfo->NoOfResultsDelivered = 0;
|
|
localinfo->intersectionBool = new MBool(5);
|
|
local.setAddr(localinfo);
|
|
|
|
if ( !u1->IsDefined()) // || !u2->IsDefined() )
|
|
{
|
|
// std::cerr << "Undef input" << endl;
|
|
return 0;
|
|
}
|
|
iv = u1->timeInterval;
|
|
u2 = new UPoint(iv, *p, *p);
|
|
u1->Intersection(*u2, uinters);
|
|
delete u2;
|
|
ivInters = uinters.timeInterval;
|
|
compresult = (opcode == 0) ? uinters.IsDefined() : !uinters.IsDefined();
|
|
|
|
if ( !uinters.IsDefined() ||
|
|
( uinters.IsDefined() && !uinters.timeInterval.Inside(ivInters))
|
|
)
|
|
{// no intersection or intersection outside common interval:
|
|
// result unit spans common interval totally
|
|
// cout << "No intersection in: "; iv.Print(cout); cout << endl;
|
|
localinfo->intersectionBool->Add(UBool(iv,CcBool(true,compresult)));
|
|
localinfo->NoOfResults++;
|
|
localinfo->finished = false;
|
|
return 0;
|
|
}
|
|
|
|
if( uinters.IsDefined() &&
|
|
iv.start == ivInters.start &&
|
|
iv.end == ivInters.end
|
|
)
|
|
{// only one resultunit
|
|
// cout << "Complete intersection: "; ivInters.Print(cout); cout << endl;
|
|
localinfo->intersectionBool->Add(
|
|
ConstTemporalUnit<CcBool>(ivInters, CcBool(true, compresult)) );
|
|
localinfo->NoOfResults++;
|
|
localinfo->finished = false;
|
|
return 0;
|
|
}
|
|
|
|
if ( uinters.IsDefined() )
|
|
{// possibly more than 1 resultunit
|
|
if ( (iv.start < ivInters.start) ||
|
|
( (iv.start == ivInters.start) && iv.lc && !ivInters.lc &&
|
|
ivInters.Inside(iv) )
|
|
)
|
|
{// result before intersection interval
|
|
ivBefore=Interval<Instant>(iv.start,ivInters.start,
|
|
iv.lc,!ivInters.lc);
|
|
// cout << "Before intersection: "; ivBefore.Print(cout); cout << endl;
|
|
localinfo->intersectionBool->Add(
|
|
ConstTemporalUnit<CcBool>(ivBefore, CcBool(true, !compresult)) );
|
|
localinfo->NoOfResults++;
|
|
localinfo->finished = false;
|
|
}
|
|
if ( ivInters.Inside(iv) )
|
|
{ // result at intersection interval
|
|
// UPoint::Intersection(...) will also return a result being on the
|
|
// limit of an open interval. Therefore, we need the second condition!
|
|
// cout << "At intersection: "; ivInters.Print(cout); cout << endl;
|
|
localinfo->intersectionBool->Add(
|
|
ConstTemporalUnit<CcBool>(ivInters, CcBool(true, compresult)) );
|
|
localinfo->NoOfResults++;
|
|
localinfo->finished = false;
|
|
}
|
|
if ( (iv.end > ivInters.end) ||
|
|
( (iv.end == ivInters.end) && iv.rc && !ivInters.rc &&
|
|
ivInters.Inside(iv) )
|
|
)
|
|
{// result after intersection interval
|
|
ivAfter = Interval<Instant>(ivInters.end,iv.end,!ivInters.rc,iv.rc);
|
|
// cout << "After intersection: "; ivAfter.Print(cout); cout << endl;
|
|
localinfo->intersectionBool->Add(
|
|
ConstTemporalUnit<CcBool>(ivAfter, CcBool(true, !compresult)) );
|
|
localinfo->NoOfResults++;
|
|
localinfo->finished = false;
|
|
}
|
|
}
|
|
return 0;
|
|
|
|
case REQUEST:
|
|
|
|
if( local.addr == 0 )
|
|
return CANCEL;
|
|
localinfo = (TUCompareValueLocalInfo*) local.addr;
|
|
if ( localinfo->finished )
|
|
return CANCEL;
|
|
if ( localinfo->NoOfResultsDelivered >= localinfo->NoOfResults)
|
|
{ localinfo->finished = true; return CANCEL; }
|
|
localinfo->intersectionBool->Get(localinfo->NoOfResultsDelivered, cu);
|
|
result.setAddr( cu.Clone() );
|
|
localinfo->NoOfResultsDelivered++;
|
|
return YIELD;
|
|
|
|
case CLOSE:
|
|
if( local.addr != 0 )
|
|
{
|
|
localinfo = (TUCompareValueLocalInfo*) local.addr;
|
|
delete localinfo->intersectionBool;
|
|
delete localinfo;
|
|
local.setAddr(0);
|
|
}
|
|
return 0;
|
|
} // end switch (message)
|
|
return -1; // should not be reached
|
|
}
|
|
|
|
/*
|
|
Implementation changed after ~CompUReal~ became memberfunction of UReal.
|
|
Simone
|
|
|
|
*/
|
|
template<int opcode>
|
|
int TU_VM_ComparePredicateValue_UReal(Word* args, Word& result,
|
|
int message, Word& local, Supplier s)
|
|
{
|
|
UReal *u1 = (UReal*) args[0].addr;
|
|
UReal *u2 = (UReal*) args[1].addr;
|
|
TUCompareValueLocalInfo *localinfo;
|
|
UBool cu;
|
|
std::vector<UBool> res;
|
|
switch (message)
|
|
{
|
|
case OPEN:
|
|
localinfo = new TUCompareValueLocalInfo;
|
|
local.setAddr(localinfo);
|
|
localinfo->finished = true;
|
|
localinfo->NoOfResults = 0;
|
|
localinfo->NoOfResultsDelivered = 0;
|
|
localinfo->intersectionBool = new MBool(5);
|
|
localinfo->intersectionBool->Clear();
|
|
if ( !u1->IsDefined() ||
|
|
!u2->IsDefined() ||
|
|
!u1->timeInterval.Intersects(u2->timeInterval) )
|
|
{ // no result
|
|
// cout << "TU_VM_ComparePredicateValue_UReal: No Result." << endl;
|
|
return 0;
|
|
}
|
|
// common deftime --> some result exists
|
|
|
|
u1->CompUReal(*u2, opcode, res);
|
|
localinfo->intersectionBool->StartBulkLoad();
|
|
for (size_t i = 0;i < res.size();i++)
|
|
{
|
|
localinfo->intersectionBool->MergeAdd(res[i]);
|
|
}
|
|
res.clear();
|
|
localinfo->intersectionBool->EndBulkLoad(true);
|
|
localinfo->NoOfResults = localinfo->intersectionBool->GetNoComponents();
|
|
localinfo->finished = ( localinfo->NoOfResults <= 0 );
|
|
return 0;
|
|
|
|
case REQUEST:
|
|
if (local.addr == 0)
|
|
return CANCEL;
|
|
localinfo = (TUCompareValueLocalInfo*) local.addr;
|
|
if (localinfo->finished)
|
|
return CANCEL;
|
|
if (localinfo->NoOfResultsDelivered >= localinfo->NoOfResults)
|
|
{
|
|
localinfo->finished = true;
|
|
return CANCEL;
|
|
}
|
|
localinfo->intersectionBool->Get(localinfo->NoOfResultsDelivered, cu);
|
|
result.setAddr( cu.Clone() );
|
|
localinfo->NoOfResultsDelivered++;
|
|
return YIELD;
|
|
|
|
case CLOSE:
|
|
if( local.addr != 0 )
|
|
{
|
|
localinfo = (TUCompareValueLocalInfo*) local.addr;
|
|
delete localinfo->intersectionBool;
|
|
delete localinfo;
|
|
local.setAddr(0);
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
template<int opcode, int unit_arg>
|
|
int TU_VM_ComparePredicateValue_UReal_CcReal(Word* args, Word& result,
|
|
int message, Word& local, Supplier s)
|
|
{
|
|
assert(opcode>=0 && opcode<=5);
|
|
assert(unit_arg>=0 && unit_arg <=1);
|
|
|
|
UReal *u1;
|
|
CcReal *r;
|
|
|
|
if(unit_arg == 0)
|
|
{
|
|
u1 = (UReal*) args[0].addr;
|
|
r = (CcReal*) args[1].addr;
|
|
}
|
|
else
|
|
{
|
|
u1 = (UReal*) args[1].addr;
|
|
r = (CcReal*) args[0].addr;
|
|
}
|
|
|
|
UBool cu;
|
|
UBool newunit(true);
|
|
TUCompareValueLocalInfo *localinfo;
|
|
Interval<Instant>
|
|
iv(datetime::DateTime(0,0,datetime::instanttype),
|
|
datetime::DateTime(0,0,datetime::instanttype),
|
|
false, false),
|
|
ivnew(datetime::DateTime(0,0,datetime::instanttype),
|
|
datetime::DateTime(0,0,datetime::instanttype),
|
|
false, false);
|
|
Interval<Instant> actIntv;
|
|
Instant
|
|
start(datetime::instanttype),
|
|
end(datetime::instanttype),
|
|
testInst(datetime::instanttype);
|
|
Periods *eqPeriods;
|
|
int i, numEq, cmpres;
|
|
bool compresult, lc;
|
|
CcReal fccr1(true, 0.0), fccr2(true,0.0);
|
|
|
|
switch (message)
|
|
{
|
|
case OPEN:
|
|
localinfo = new TUCompareValueLocalInfo;
|
|
local.setAddr(localinfo);
|
|
localinfo->finished = true;
|
|
localinfo->NoOfResults = 0;
|
|
localinfo->NoOfResultsDelivered = 0;
|
|
localinfo->intersectionBool = new MBool(5);
|
|
localinfo->intersectionBool->Clear();
|
|
|
|
if ( !u1->IsDefined() || !r->IsDefined() )
|
|
{ // no result
|
|
// cout << "TU_VM_ComparePredicateValue_UReal: No Result." << endl;
|
|
return 0;
|
|
}
|
|
iv = u1->timeInterval;
|
|
eqPeriods = new Periods(4);
|
|
u1->PeriodsAtVal(r->GetRealval(), *eqPeriods);// only intervals of length
|
|
numEq = eqPeriods->GetNoComponents();// 1 instant herein (start==end)
|
|
// cout << " numEq=" << numEq << endl;
|
|
if ( numEq == 0 )
|
|
{ // special case: no equality -> only one result unit
|
|
// cout << "TU_VM_ComparePredicateValue_UReal: Single Result." << endl;
|
|
testInst = TU_GetMidwayInstant(iv.start, iv.end);
|
|
u1->TemporalFunction(testInst, fccr1, false);
|
|
fccr2 = *r;
|
|
if(unit_arg == 0)
|
|
cmpres = fccr1.Compare( &fccr2 );
|
|
else
|
|
cmpres = fccr2.Compare( &fccr1 );
|
|
|
|
compresult = ( (opcode == 0 && cmpres == 0) || // ==
|
|
(opcode == 1 && cmpres != 0) || // #
|
|
(opcode == 2 && cmpres < 0) || // <
|
|
(opcode == 3 && cmpres > 0) || // >
|
|
(opcode == 4 && cmpres <= 0) || // <=
|
|
(opcode == 5 && cmpres >= 0) );// >=
|
|
newunit = UBool(iv, CcBool(true, compresult));
|
|
localinfo->intersectionBool->StartBulkLoad();
|
|
localinfo->intersectionBool->Add(newunit);
|
|
localinfo->intersectionBool->EndBulkLoad();
|
|
localinfo->NoOfResults++;
|
|
localinfo->finished = false;
|
|
delete eqPeriods;
|
|
return 0;
|
|
}
|
|
// case: numEq > 0, at least one instant of equality
|
|
// iterate the Periods and create result units
|
|
// UBool::MergeAdd() will merge units with common value
|
|
// for <= and >=
|
|
// cout << "TU_VM_ComparePredicateValue_UReal: Multiple Results." << endl;
|
|
localinfo->intersectionBool->StartBulkLoad();
|
|
start = iv.start; // the ending instant for the next interval
|
|
lc = iv.lc;
|
|
i = 0; // counter for instants of equality
|
|
eqPeriods->Get(i, actIntv);
|
|
// handle special case: first equality in first instant
|
|
if (start == actIntv.start)
|
|
{
|
|
// cout << "TU_VM_ComparePredicateValue_UReal: Handling start...";
|
|
if (iv.lc)
|
|
{
|
|
// cout << " required." << endl;
|
|
u1->TemporalFunction(u1->timeInterval.start, fccr1, false);
|
|
fccr2 = *r;
|
|
if(unit_arg == 0)
|
|
cmpres = fccr1.Compare( &fccr2 );
|
|
else
|
|
cmpres = fccr2.Compare( &fccr1 );
|
|
compresult = ( (opcode == 0 && cmpres == 0) ||
|
|
(opcode == 1 && cmpres != 0) ||
|
|
(opcode == 2 && cmpres < 0) ||
|
|
(opcode == 3 && cmpres > 0) ||
|
|
(opcode == 4 && cmpres <= 0) ||
|
|
(opcode == 5 && cmpres >= 0) );
|
|
ivnew = Interval<Instant>(start, start, true, true);
|
|
newunit = UBool(ivnew, CcBool(true, compresult));
|
|
localinfo->intersectionBool->Add(newunit);
|
|
// cout << "TU_VM_ComparePredicateValue_UReal: Added initial"
|
|
// << i << endl;
|
|
lc = false;
|
|
} // else: equal instant not in interval!
|
|
// else
|
|
// cout << " not required." << endl;
|
|
i++;
|
|
}
|
|
while ( i < numEq )
|
|
{
|
|
// cout << "TU_VM_ComparePredicateValue_UReal: Pass i=" << i << endl;
|
|
eqPeriods->Get(i, actIntv);
|
|
// if(actIntv.start != actIntv.end)
|
|
// {
|
|
// cout << "Something's wrong with actIntv!" << endl;
|
|
// }
|
|
end = actIntv.start;
|
|
// cout << " start=" << start.ToString()
|
|
// << " end=" << end.ToString() << endl;
|
|
ivnew = Interval<Instant>(start, end, lc, false);
|
|
testInst = TU_GetMidwayInstant(start, end);
|
|
u1->TemporalFunction(testInst, fccr1, false);
|
|
fccr2 = *r;
|
|
if(unit_arg == 0)
|
|
cmpres = fccr1.Compare( &fccr2 );
|
|
else
|
|
cmpres = fccr2.Compare( &fccr1 );
|
|
compresult = ( (opcode == 0 && cmpres == 0) ||
|
|
(opcode == 1 && cmpres != 0) ||
|
|
(opcode == 2 && cmpres < 0) ||
|
|
(opcode == 3 && cmpres > 0) ||
|
|
(opcode == 4 && cmpres <= 0) ||
|
|
(opcode == 5 && cmpres >= 0) );
|
|
newunit = UBool(ivnew, CcBool(true, compresult));
|
|
localinfo->intersectionBool->MergeAdd(newunit);
|
|
// cout << "TU_VM_ComparePredicateValue_UReal: Added regular" << i << endl;
|
|
if ( !(end == iv.end) || iv.rc )
|
|
{
|
|
// cout << "TU_VM_ComparePredicateValue_UReal: rc==true" << endl;
|
|
ivnew = Interval<Instant>(end, end, true, true);
|
|
compresult = (opcode == 0 || opcode == 4 || opcode == 5);
|
|
newunit = UBool(ivnew, CcBool(true, compresult));
|
|
localinfo->intersectionBool->MergeAdd(newunit);
|
|
}
|
|
start = end;
|
|
i++;
|
|
lc = false;
|
|
}
|
|
if ( start < iv.end )
|
|
{ // handle teq[numEq-1] < iv.end
|
|
ivnew = Interval<Instant>(start, iv.end, false, iv.rc);
|
|
testInst = TU_GetMidwayInstant(start, iv.end);
|
|
u1->TemporalFunction(testInst, fccr1, false);
|
|
fccr2 = *r;
|
|
if(unit_arg == 0)
|
|
cmpres = fccr1.Compare( &fccr2 );
|
|
else
|
|
cmpres = fccr2.Compare( &fccr1 );
|
|
compresult = ( (opcode == 0 && cmpres == 0) ||
|
|
(opcode == 1 && cmpres != 0) ||
|
|
(opcode == 2 && cmpres < 0) ||
|
|
(opcode == 3 && cmpres > 0) ||
|
|
(opcode == 4 && cmpres <= 0) ||
|
|
(opcode == 5 && cmpres >= 0) );
|
|
newunit = UBool(ivnew, CcBool(true, compresult));
|
|
localinfo->intersectionBool->MergeAdd(newunit);
|
|
// cout << "TU_VM_ComparePredicateValue_UReal: Added final res"
|
|
// << i << endl;
|
|
}
|
|
localinfo->intersectionBool->EndBulkLoad(true);
|
|
localinfo->NoOfResults = localinfo->intersectionBool->GetNoComponents();
|
|
localinfo->finished = ( localinfo->NoOfResults <= 0 );
|
|
delete eqPeriods;
|
|
return 0;
|
|
|
|
case REQUEST:
|
|
if (local.addr == 0)
|
|
return CANCEL;
|
|
localinfo = (TUCompareValueLocalInfo*) local.addr;
|
|
if (localinfo->finished)
|
|
return CANCEL;
|
|
if (localinfo->NoOfResultsDelivered >= localinfo->NoOfResults)
|
|
{
|
|
localinfo->finished = true;
|
|
return CANCEL;
|
|
}
|
|
localinfo->intersectionBool->Get(localinfo->NoOfResultsDelivered, cu);
|
|
result.setAddr( cu.Clone() );
|
|
localinfo->NoOfResultsDelivered++;
|
|
return YIELD;
|
|
|
|
case CLOSE:
|
|
if( local.addr != 0 )
|
|
{
|
|
localinfo = (TUCompareValueLocalInfo*) local.addr;
|
|
delete localinfo->intersectionBool;
|
|
delete localinfo;
|
|
local.setAddr(0);
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
|
|
template<int opcode>
|
|
int TU_VM_ComparePredicateValue_URegion(Word* args, Word& result,
|
|
int message, Word& local, Supplier s)
|
|
{
|
|
// URegion *u1 = (URegion*) args[0].addr;
|
|
// URegion *u2 = (URegion*) args[1].addr;
|
|
|
|
std::cerr << "TU_VM_ComparePredicateValue_URegion() not yet implemented!"
|
|
<< endl;
|
|
return -1; // should not be reached
|
|
}
|
|
|
|
/*
|
|
5.43.3 Specification for operator ~ComparePredicateValues~
|
|
|
|
*/
|
|
|
|
const std::string TUEqVSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>For T in {bool, int, string, real, point, region}\n"
|
|
"(uT uT) -> (stream ubool)\n"
|
|
"(uT T) -> (stream ubool)\n"
|
|
"( T uT) -> (stream ubool)</text--->"
|
|
"<text>_ = _</text--->"
|
|
"<text>The operator returns the value of the temporal predicate.</text--->"
|
|
"<text>query [const ubool value ((\"2010-11-11\" "
|
|
"\"2011-01-03\" TRUE FALSE) TRUE)] = [const ubool value "
|
|
"((\"2011-01-01\"2012-09-17\" FALSE TRUE) TRUE)] the_mvalue</text--->"
|
|
") )";
|
|
|
|
const std::string TUNEqVSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>For T in {bool, int, string, real, point, region}\n"
|
|
"(uT uT) -> (stream ubool)\n"
|
|
"(uT T) -> (stream ubool)\n"
|
|
"( T uT) -> (stream ubool)</text--->"
|
|
"<text>_ # _</text--->"
|
|
"<text>The operator returns the value of the temporal predicate.</text--->"
|
|
"<text>query [const ubool value ((\"2010-11-11\" "
|
|
"\"2011-01-03\" TRUE FALSE) TRUE)] # [const ubool value "
|
|
"((\"2011-01-01\" \"2012-09-17\" FALSE TRUE) TRUE)] the_mvalue</text--->"
|
|
") )";
|
|
|
|
const std::string TULtVSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>For T in {bool, int, string, real}\n"
|
|
"(uT uT) -> (stream ubool)\n"
|
|
"(uT T) -> (stream ubool)\n"
|
|
"( T uT) -> (stream ubool)</text--->"
|
|
"<text>_ < _</text--->"
|
|
"<text>The operator returns the value of the temporal predicate.</text--->"
|
|
"<text>query [const ubool value ((\"2010-11-11\" "
|
|
"\"2011-01-03\" TRUE FALSE) TRUE)] < [const ubool value "
|
|
"((\"2011-01-01\" \"2012-09-17\" FALSE TRUE) TRUE)] the_mvalue</text--->"
|
|
") )";
|
|
|
|
const std::string TUBtVSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>For T in {bool, int, string, real}\n"
|
|
"(uT uT) -> (stream ubool)\n"
|
|
"(uT T) -> (stream ubool)\n"
|
|
"( T uT) -> (stream ubool)</text--->"
|
|
"<text>_ > _</text--->"
|
|
"<text>The operator returns the value of the temporal predicate.</text--->"
|
|
"<text>query [const ubool value ((\"2010-11-11\" "
|
|
"\"2011-01-03\" TRUE FALSE) TRUE)] > [const ubool value "
|
|
"((\"2011-01-01\" \"2012-09-17\" FALSE TRUE) TRUE)] the_mvalue</text--->"
|
|
") )";
|
|
|
|
const std::string TULtEqVSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>For T in {bool, int, string, real}\n"
|
|
"(uT uT) -> (stream ubool)\n"
|
|
"(uT T) -> (stream ubool)\n"
|
|
"( T uT) -> (stream ubool)</text--->"
|
|
"<text>_ <= _</text--->"
|
|
"<text>The operator returns the value of the temporal predicate.</text--->"
|
|
"<text>query [const ubool value ((\"2010-11-11\" "
|
|
"\"2011-01-03\" TRUE FALSE) TRUE)] <= [const ubool value "
|
|
"((\"2011-01-01\" \"2012-09-17\" FALSE TRUE) TRUE)] the_mvalue</text--->"
|
|
") )";
|
|
|
|
const std::string TUBtEqVSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>For T in {bool, int, string, real}\n"
|
|
"(uT uT) -> (stream ubool)\n"
|
|
"(uT T) -> (stream ubool)\n"
|
|
"( T uT) -> (stream ubool)</text--->"
|
|
"<text>_ >= _</text--->"
|
|
"<text>The operator returns the value of the temporal predicate.</text--->"
|
|
"<text>query [const ubool value ((\"2010-11-11\" "
|
|
"\"2011-01-03\" TRUE FALSE) TRUE)] >= [const ubool value "
|
|
"((\"2011-01-01\" \"2012-09-17\" FALSE TRUE) TRUE)] the_mvalue</text--->"
|
|
") )";
|
|
|
|
/*
|
|
5.43.4 Selection Function of operator ~ComparePredicateValues~
|
|
|
|
*/
|
|
template<int opcode>
|
|
int TU_Select_ComparePredicateValue ( ListExpr args )
|
|
{
|
|
std::string argstr;
|
|
nl->WriteToString(argstr, args);
|
|
|
|
if (argstr == "(ubool ubool)")
|
|
return 0 + opcode;
|
|
if (argstr == "(uint uint)")
|
|
return 6 + opcode;
|
|
if (argstr == "(ustring ustring)")
|
|
return 12 + opcode;
|
|
if (argstr == "(ureal ureal)")
|
|
return 18 + opcode;
|
|
if (argstr == "(upoint upoint)")
|
|
return 24 + opcode;
|
|
if (argstr == "(uregion uregion)")
|
|
return 26 + opcode;
|
|
|
|
if (argstr == "(bool ubool)")
|
|
return 28 + opcode;
|
|
if (argstr == "(ubool bool)")
|
|
return 34 + opcode;
|
|
if (argstr == "(int uint)")
|
|
return 40 + opcode;
|
|
if (argstr == "(unit int)")
|
|
return 46 + opcode;
|
|
if (argstr == "(string ustring)")
|
|
return 52 + opcode;
|
|
if (argstr == "(ustring string)")
|
|
return 58 + opcode;
|
|
if (argstr == "(real ureal)")
|
|
return 64 + opcode;
|
|
if (argstr == "(ureal real)")
|
|
return 70 + opcode;
|
|
if (argstr == "(point upoint)")
|
|
return 76 + opcode;
|
|
if (argstr == "(upoint point)")
|
|
return 78 + opcode;
|
|
|
|
return -1; // should not be reached!
|
|
}
|
|
|
|
ValueMapping TU_VMMap_ComparePredicateValue[] =
|
|
{
|
|
TU_VM_ComparePredicateValue_Const<CcBool,0>, // 0
|
|
TU_VM_ComparePredicateValue_Const<CcBool,1>,
|
|
TU_VM_ComparePredicateValue_Const<CcBool,2>,
|
|
TU_VM_ComparePredicateValue_Const<CcBool,3>,
|
|
TU_VM_ComparePredicateValue_Const<CcBool,4>,
|
|
TU_VM_ComparePredicateValue_Const<CcBool,5>, // 5
|
|
TU_VM_ComparePredicateValue_Const<CcInt,0>, // 6
|
|
TU_VM_ComparePredicateValue_Const<CcInt,1>,
|
|
TU_VM_ComparePredicateValue_Const<CcInt,2>,
|
|
TU_VM_ComparePredicateValue_Const<CcInt,3>,
|
|
TU_VM_ComparePredicateValue_Const<CcInt,4>,
|
|
TU_VM_ComparePredicateValue_Const<CcInt,5>, // 11
|
|
TU_VM_ComparePredicateValue_Const<CcString,0>, // 12
|
|
TU_VM_ComparePredicateValue_Const<CcString,1>,
|
|
TU_VM_ComparePredicateValue_Const<CcString,2>,
|
|
TU_VM_ComparePredicateValue_Const<CcString,3>,
|
|
TU_VM_ComparePredicateValue_Const<CcString,4>,
|
|
TU_VM_ComparePredicateValue_Const<CcString,5>, // 17
|
|
TU_VM_ComparePredicateValue_UReal<0>, // 18
|
|
TU_VM_ComparePredicateValue_UReal<1>,
|
|
TU_VM_ComparePredicateValue_UReal<2>,
|
|
TU_VM_ComparePredicateValue_UReal<3>,
|
|
TU_VM_ComparePredicateValue_UReal<4>,
|
|
TU_VM_ComparePredicateValue_UReal<5>, // 23
|
|
TU_VM_ComparePredicateValue_UPoint<0>, // 24
|
|
TU_VM_ComparePredicateValue_UPoint<1>, // 25
|
|
TU_VM_ComparePredicateValue_URegion<0>, // 26
|
|
TU_VM_ComparePredicateValue_URegion<1>, // 27
|
|
|
|
TU_VM_ComparePredicateValue_Const_T<CcBool,0,1>,// 28
|
|
TU_VM_ComparePredicateValue_Const_T<CcBool,1,1>,
|
|
TU_VM_ComparePredicateValue_Const_T<CcBool,2,1>,
|
|
TU_VM_ComparePredicateValue_Const_T<CcBool,3,1>,
|
|
TU_VM_ComparePredicateValue_Const_T<CcBool,4,1>,
|
|
TU_VM_ComparePredicateValue_Const_T<CcBool,5,1>,
|
|
TU_VM_ComparePredicateValue_Const_T<CcBool,0,0>,//34
|
|
TU_VM_ComparePredicateValue_Const_T<CcBool,1,0>,
|
|
TU_VM_ComparePredicateValue_Const_T<CcBool,2,0>,
|
|
TU_VM_ComparePredicateValue_Const_T<CcBool,3,0>,
|
|
TU_VM_ComparePredicateValue_Const_T<CcBool,4,0>,
|
|
TU_VM_ComparePredicateValue_Const_T<CcBool,5,0>,
|
|
|
|
TU_VM_ComparePredicateValue_Const_T<CcInt,0,1>,// 40
|
|
TU_VM_ComparePredicateValue_Const_T<CcInt,1,1>,
|
|
TU_VM_ComparePredicateValue_Const_T<CcInt,2,1>,
|
|
TU_VM_ComparePredicateValue_Const_T<CcInt,3,1>,
|
|
TU_VM_ComparePredicateValue_Const_T<CcInt,4,1>,
|
|
TU_VM_ComparePredicateValue_Const_T<CcInt,5,1>,
|
|
TU_VM_ComparePredicateValue_Const_T<CcInt,0,0>,// 46
|
|
TU_VM_ComparePredicateValue_Const_T<CcInt,1,0>,
|
|
TU_VM_ComparePredicateValue_Const_T<CcInt,2,0>,
|
|
TU_VM_ComparePredicateValue_Const_T<CcInt,3,0>,
|
|
TU_VM_ComparePredicateValue_Const_T<CcInt,4,0>,
|
|
TU_VM_ComparePredicateValue_Const_T<CcInt,5,0>,
|
|
|
|
TU_VM_ComparePredicateValue_Const_T<CcString,0,1>,// 52
|
|
TU_VM_ComparePredicateValue_Const_T<CcString,1,1>,
|
|
TU_VM_ComparePredicateValue_Const_T<CcString,2,1>,
|
|
TU_VM_ComparePredicateValue_Const_T<CcString,3,1>,
|
|
TU_VM_ComparePredicateValue_Const_T<CcString,4,1>,
|
|
TU_VM_ComparePredicateValue_Const_T<CcString,5,1>,
|
|
TU_VM_ComparePredicateValue_Const_T<CcString,0,0>,// 58
|
|
TU_VM_ComparePredicateValue_Const_T<CcString,1,0>,
|
|
TU_VM_ComparePredicateValue_Const_T<CcString,2,0>,
|
|
TU_VM_ComparePredicateValue_Const_T<CcString,3,0>,
|
|
TU_VM_ComparePredicateValue_Const_T<CcString,4,0>,
|
|
TU_VM_ComparePredicateValue_Const_T<CcString,5,0>,
|
|
|
|
TU_VM_ComparePredicateValue_UReal_CcReal<0,1>, // 64
|
|
TU_VM_ComparePredicateValue_UReal_CcReal<1,1>,
|
|
TU_VM_ComparePredicateValue_UReal_CcReal<2,1>,
|
|
TU_VM_ComparePredicateValue_UReal_CcReal<3,1>,
|
|
TU_VM_ComparePredicateValue_UReal_CcReal<4,1>,
|
|
TU_VM_ComparePredicateValue_UReal_CcReal<5,1>,
|
|
TU_VM_ComparePredicateValue_UReal_CcReal<0,0>, // 70
|
|
TU_VM_ComparePredicateValue_UReal_CcReal<1,0>,
|
|
TU_VM_ComparePredicateValue_UReal_CcReal<2,0>,
|
|
TU_VM_ComparePredicateValue_UReal_CcReal<3,0>,
|
|
TU_VM_ComparePredicateValue_UReal_CcReal<4,0>,
|
|
TU_VM_ComparePredicateValue_UReal_CcReal<5,0>, // 75
|
|
|
|
TU_VM_ComparePredicateValue_UPoint_Point<0,1>, // 76
|
|
TU_VM_ComparePredicateValue_UPoint_Point<1,1>, // 77
|
|
TU_VM_ComparePredicateValue_UPoint_Point<0,0>, // 78
|
|
TU_VM_ComparePredicateValue_UPoint_Point<1,0> // 79
|
|
};
|
|
|
|
/*
|
|
5.43.5 Definition of operator ~ComparePredicateValues~
|
|
|
|
*/
|
|
Operator temporalunitvalisequal
|
|
(
|
|
"=",
|
|
TUEqVSpec,
|
|
80,
|
|
TU_VMMap_ComparePredicateValue,
|
|
TU_Select_ComparePredicateValue<0>,
|
|
TUCompareValueEqPredicatesTypeMap
|
|
);
|
|
|
|
Operator temporalunitvalisnotequal
|
|
(
|
|
"#",
|
|
TUNEqVSpec,
|
|
80,
|
|
TU_VMMap_ComparePredicateValue,
|
|
TU_Select_ComparePredicateValue<1>,
|
|
TUCompareValueEqPredicatesTypeMap
|
|
);
|
|
|
|
Operator temporalunitvalsmaller
|
|
(
|
|
"<",
|
|
TULtVSpec,
|
|
80,
|
|
TU_VMMap_ComparePredicateValue,
|
|
TU_Select_ComparePredicateValue<2>,
|
|
TUCompareValuePredicatesTypeMap
|
|
);
|
|
|
|
Operator temporalunitvalbigger
|
|
(
|
|
">",
|
|
TUBtVSpec,
|
|
80,
|
|
TU_VMMap_ComparePredicateValue,
|
|
TU_Select_ComparePredicateValue<3>,
|
|
TUCompareValuePredicatesTypeMap
|
|
);
|
|
|
|
Operator temporalunitvalsmallereq
|
|
(
|
|
"<=",
|
|
TULtEqVSpec,
|
|
80,
|
|
TU_VMMap_ComparePredicateValue,
|
|
TU_Select_ComparePredicateValue<4>,
|
|
TUCompareValuePredicatesTypeMap
|
|
);
|
|
|
|
Operator temporalunitvalbiggereq
|
|
(
|
|
">=",
|
|
TUBtEqVSpec,
|
|
80,
|
|
TU_VMMap_ComparePredicateValue,
|
|
TU_Select_ComparePredicateValue<5>,
|
|
TUCompareValuePredicatesTypeMap
|
|
);
|
|
|
|
|
|
/*
|
|
5.44 Operator ~length~
|
|
|
|
Calculate the spatial length of the movement.
|
|
|
|
----
|
|
length: upoint --> real
|
|
|
|
----
|
|
|
|
*/
|
|
|
|
/*
|
|
5.44.1 Type mapping function for ~length~
|
|
|
|
---- upoint [ x geoid ] --> real
|
|
----
|
|
|
|
*/
|
|
ListExpr TUTypeMapLength( ListExpr args )
|
|
{
|
|
std::string errmsg = "Expected (upoint) or (upoint x geoid).";
|
|
int noargs = nl->ListLength(args);
|
|
if((noargs<1) || (noargs>2)){
|
|
return listutils::typeError(errmsg);
|
|
}
|
|
if(!listutils::isSymbol(nl->First(args),UPoint::BasicType())){
|
|
return listutils::typeError(errmsg);
|
|
}
|
|
if( (noargs==2)
|
|
&& (!listutils::isSymbol(nl->Second(args),Geoid::BasicType())) ){
|
|
return listutils::typeError(errmsg);
|
|
}
|
|
return nl->SymbolAtom(CcReal::BasicType());
|
|
}
|
|
|
|
/*
|
|
5.44.2 Value mapping for operator ~length~
|
|
|
|
*/
|
|
int TUUnitLength(Word* args,Word& result,int message,Word& local,Supplier s)
|
|
{
|
|
result = qp->ResultStorage( s );
|
|
CcReal *res = (CcReal*)result.addr;
|
|
UPoint *input = (UPoint*)args[0].addr;
|
|
|
|
if(qp->GetNoSons(s)==2){ // variant using (LON,LAT)-coordinates
|
|
Geoid* g = static_cast<Geoid*>(args[1].addr);
|
|
if(!g->IsDefined()){
|
|
res->Set(false, 0.0);
|
|
return 0;
|
|
}
|
|
input->Length(*g, *res);
|
|
} else { // normal variant using (X,Y)-coordinates
|
|
input->Length( *res );
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
5.44.3 Specification for operator ~length~
|
|
|
|
*/
|
|
const std::string TULengthSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text> upoint [ x geoid ] -> real</text--->"
|
|
"<text> length( Up [, Geoid ] )</text--->"
|
|
"<text>The operator returns the distance of the unit's initial and final"
|
|
"position. If the optional parameter Geoid is not used, spatial "
|
|
"coordinates are interpreted as metric (X,Y)-pairs, otherwise as "
|
|
"geographic (LON,LAT)-coordinates relative to the passed geoid.</text--->"
|
|
"<text>query units(Trains feed extract[Trip]) use[fun(U:upoint) "
|
|
"length(U)] transformstream sum[elem]</text--->"
|
|
") )";
|
|
|
|
/*
|
|
5.44.4 Selection Function of operator ~length~
|
|
|
|
none - uses simpleselect
|
|
*/
|
|
|
|
/*
|
|
5.44.5 Definition of operator ~length~
|
|
|
|
*/
|
|
|
|
Operator temporalunitlength( "length",
|
|
TULengthSpec,
|
|
TUUnitLength,
|
|
Operator::SimpleSelect,
|
|
TUTypeMapLength);
|
|
|
|
/*
|
|
5.45 Operator ~canmeet~
|
|
|
|
The predicate predictes whether two mpoint objects will become close to
|
|
eachother (in terms of a given distance threshold), within a given time
|
|
duration assuming that they keep the speed and direction of the given two
|
|
upoints.
|
|
|
|
*/
|
|
|
|
/*
|
|
5.45.1 Type mapping function for ~canmeet~
|
|
|
|
*/
|
|
|
|
ListExpr
|
|
TypeMapTemporalUnitCanMeet( ListExpr args )
|
|
{
|
|
ListExpr upoint1, upoint2, distance, duration;
|
|
std::string outstr;
|
|
|
|
if ( nl->IsAtom( args ) || nl->ListLength( args ) != 4 )
|
|
{
|
|
nl->WriteToString(outstr, args);
|
|
ErrorReporter::ReportError("Operator canmeet expects a list of "
|
|
"length four, but gets '" + outstr +
|
|
"'.");
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
|
}
|
|
|
|
upoint1 = nl->First(args);
|
|
upoint2 = nl->Second(args);
|
|
distance = nl->Third(args);
|
|
duration = nl->Fourth(args);
|
|
|
|
// check for compatibility of arguments
|
|
if( !nl->IsAtom(upoint1) || !nl->IsEqual(upoint1, UPoint::BasicType()))
|
|
{
|
|
nl->WriteToString(outstr, upoint1);
|
|
ErrorReporter::ReportError("Operator canmeet expects upoint as a first "
|
|
"argument, but gets '" + outstr + "'.");
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
|
}
|
|
|
|
if( !nl->IsAtom(upoint2) || !nl->IsEqual(upoint2, UPoint::BasicType()))
|
|
{
|
|
nl->WriteToString(outstr, upoint2);
|
|
ErrorReporter::ReportError("Operator canmeet expects upoint as a second "
|
|
"argument, but gets '" + outstr + "'.");
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
|
}
|
|
|
|
if( !nl->IsAtom(distance) || !nl->IsEqual(distance, CcReal::BasicType()))
|
|
{
|
|
nl->WriteToString(outstr, distance);
|
|
ErrorReporter::ReportError("Operator canmeet expects real as a third "
|
|
"argument, but gets '" + outstr + "'.");
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
|
}
|
|
|
|
if( !nl->IsAtom(duration) || !nl->IsEqual(duration, Duration::BasicType()))
|
|
{
|
|
nl->WriteToString(outstr, duration);
|
|
ErrorReporter::ReportError("Operator canmeet expects duration as a "
|
|
"fourth "
|
|
"argument, but gets '" + outstr + "'.");
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
|
}
|
|
return nl->SymbolAtom( CcBool::BasicType() );
|
|
}
|
|
|
|
/*
|
|
5.45.2 Value mapping for operator ~canmeet~
|
|
|
|
*/
|
|
|
|
int TUCanMeet( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
bool debugme=false;
|
|
Interval<Instant> iv;
|
|
|
|
// Word a1, a2;
|
|
UPoint *u1, *u2;
|
|
CcReal* distThreshold;
|
|
Instant* timeThreshold;
|
|
result = qp->ResultStorage( s );
|
|
CcBool* res = (CcBool*) result.addr;
|
|
|
|
u1 = (UPoint*)(args[0].addr);
|
|
u2 = (UPoint*)(args[1].addr);
|
|
distThreshold = (CcReal*)(args[2].addr);
|
|
timeThreshold = (Instant*)(args[3].addr);
|
|
double tThresholdMin=0, tThresholdMax=0;
|
|
if (!u1->IsDefined() ||
|
|
!u2->IsDefined() ||
|
|
!distThreshold->IsDefined() ||
|
|
! timeThreshold->IsDefined())
|
|
{ // return undefined ureal
|
|
res->SetDefined( false );
|
|
}
|
|
else
|
|
{
|
|
// calculate result
|
|
res->SetDefined( true );
|
|
// 1- Extend the two upoints so that their time intervals are equal
|
|
UPoint u1ex(*u1), u2ex(*u2);
|
|
Point newPoint;
|
|
if(u1->timeInterval.start < u2->timeInterval.start)
|
|
//extend u2 backward
|
|
{
|
|
tThresholdMin = u2->timeInterval.start.ToDouble();
|
|
u2->TemporalFunction(u1->timeInterval.start, newPoint, true);
|
|
u2ex.timeInterval.start = u1->timeInterval.start;
|
|
u2ex.p0 = newPoint;
|
|
}
|
|
else
|
|
//extend u1 backward
|
|
{
|
|
tThresholdMin = u1->timeInterval.start.ToDouble();
|
|
u1->TemporalFunction(u2->timeInterval.start, newPoint, true);
|
|
u1ex.timeInterval.start = u2->timeInterval.start;
|
|
u1ex.p0 = newPoint;
|
|
}
|
|
|
|
if(u1->timeInterval.end < u2->timeInterval.end)
|
|
//extend u1 forward
|
|
{
|
|
tThresholdMax = u2->timeInterval.end.ToDouble() +
|
|
timeThreshold->ToDouble();
|
|
u1->TemporalFunction(u2->timeInterval.end, newPoint, true);
|
|
u1ex.timeInterval.end = u2->timeInterval.end;
|
|
u1ex.p1 = newPoint;
|
|
}
|
|
else
|
|
//extend u2 forward
|
|
{
|
|
tThresholdMax = u1->timeInterval.end.ToDouble() +
|
|
timeThreshold->ToDouble();
|
|
u2->TemporalFunction(u1->timeInterval.end, newPoint, true);
|
|
u2ex.timeInterval.end = u1->timeInterval.end;
|
|
u2ex.p1 = newPoint;
|
|
}
|
|
|
|
// 2- Compute the distance between the two extended units
|
|
UReal dist(0);
|
|
u1ex.Distance( u2ex, dist );
|
|
if(debugme)
|
|
dist.Print(std::cerr);
|
|
// 3- Compute the time when the distance reaches the distThreshould
|
|
double c= dist.c - ((dist.r)?
|
|
distThreshold->GetRealval() * distThreshold->GetRealval():
|
|
distThreshold->GetRealval());
|
|
double coeff = (dist.b * dist.b) - (4 * dist.a * c);
|
|
if(coeff < 0)
|
|
{
|
|
res->Set(true, false);
|
|
return 0;
|
|
}
|
|
coeff = sqrt(coeff);
|
|
double t1= ((dist.b * -1) + coeff )/ (2 * dist.a);
|
|
double t2= ((dist.b * -1) - coeff )/ (2 * dist.a);
|
|
double intervalStart= u1ex.timeInterval.start.ToDouble();
|
|
if( (t1 + intervalStart) > tThresholdMin &&
|
|
(t1 + intervalStart) < tThresholdMax)
|
|
res->Set(true, true);
|
|
else if( (t2 + intervalStart) > tThresholdMin &&
|
|
(t2 + intervalStart) < tThresholdMax)
|
|
res->Set(true, true);
|
|
else
|
|
res->Set(true, false);
|
|
}
|
|
// pass on result
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
5.45.3 Specification for operator ~canmeet~
|
|
|
|
*/
|
|
const std::string TemporalSpecCanMeet =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"(<text>"
|
|
"( upoint upoint real duration) -> bool</text--->"
|
|
"<text>canmeet( _, _, _, _)</text--->"
|
|
"<text> The predicate predictes whether two upoint objects will become close"
|
|
" to eachother (in terms of the given distance threshold), within the given "
|
|
" time duration, assuming that they keep their speed and direction.</text--->"
|
|
"<text>canmeet(upoint1,upoint2, 50.0, now() + create_duration(0, 5000))"
|
|
"</text--->"
|
|
") )";
|
|
|
|
/*
|
|
5.45.5 Definition of operator ~canmeet~
|
|
|
|
*/
|
|
|
|
Operator temporalunitcanmeet( "canmeet",
|
|
TemporalSpecCanMeet,
|
|
TUCanMeet,
|
|
Operator::SimpleSelect,
|
|
TypeMapTemporalUnitCanMeet);
|
|
|
|
|
|
|
|
/*
|
|
5.46 Operator ~when~
|
|
|
|
5.46.1 Type Mapping for ~when~
|
|
|
|
*/
|
|
ListExpr
|
|
UnitWhenTypeMap( ListExpr args )
|
|
{
|
|
ListExpr arg1, arg2;
|
|
std::string argstr;
|
|
|
|
if ( nl->ListLength( args ) != 2 )
|
|
{
|
|
ErrorReporter::ReportError("Operator when expects a list of length 2.");
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
|
}
|
|
|
|
arg1 = nl->First( args );
|
|
arg2 = nl->Second( args );
|
|
|
|
nl->WriteToString(argstr, arg2);
|
|
if ( !( nl->IsEqual( arg2, MBool::BasicType() ) ) )
|
|
{
|
|
ErrorReporter::ReportError("Operator when expects a second argument"
|
|
" of type " + MBool::BasicType() + " but gets '" + argstr + "'.");
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
|
}
|
|
|
|
if( nl->IsAtom( arg1 ) )
|
|
{
|
|
if( nl->IsEqual( arg1, UBool::BasicType() ) )
|
|
return nl->TwoElemList(nl->SymbolAtom(Symbol::STREAM()),
|
|
nl->SymbolAtom(UBool::BasicType()));
|
|
if( nl->IsEqual( arg1, UInt::BasicType() ) )
|
|
return nl->TwoElemList(nl->SymbolAtom(Symbol::STREAM()),
|
|
nl->SymbolAtom(UInt::BasicType()));
|
|
if( nl->IsEqual( arg1, UReal::BasicType() ) )
|
|
return nl->TwoElemList(nl->SymbolAtom(Symbol::STREAM()),
|
|
nl->SymbolAtom(UReal::BasicType()));
|
|
if( nl->IsEqual( arg1, UPoint::BasicType() ) )
|
|
return nl->TwoElemList(nl->SymbolAtom(Symbol::STREAM()),
|
|
nl->SymbolAtom(UPoint::BasicType()));
|
|
if( nl->IsEqual( arg1, UString::BasicType() ) )
|
|
return nl->TwoElemList(nl->SymbolAtom(Symbol::STREAM()),
|
|
nl->SymbolAtom(UString::BasicType()));
|
|
|
|
nl->WriteToString(argstr, arg1);
|
|
ErrorReporter::ReportError("Operator when expects a first argument "
|
|
"of type T in {ubool, uint, ureal, upoint, "
|
|
"ustring, uregion} but gets a '"
|
|
+ argstr + "'.");
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
|
}
|
|
|
|
if(!Stream<ANY>::checkType(arg1)){
|
|
return listutils::typeError("Operator when expects as first "
|
|
"argument a list with structure 'T' or "
|
|
"'stream(T)', T in {ubool, uint, ureal, "
|
|
"upoint, ustring, ureagion} but gets a "
|
|
"list with structure '" + argstr + "'.");
|
|
|
|
}
|
|
|
|
if( nl->IsEqual( nl->Second(arg1), UBool::BasicType() ) )
|
|
return nl->TwoElemList(nl->SymbolAtom(Symbol::STREAM()),
|
|
nl->SymbolAtom(UBool::BasicType()));
|
|
if( nl->IsEqual( nl->Second(arg1), UInt::BasicType() ) )
|
|
return nl->TwoElemList(nl->SymbolAtom(Symbol::STREAM()),
|
|
nl->SymbolAtom(UInt::BasicType()));
|
|
if( nl->IsEqual( nl->Second(arg1), UReal::BasicType() ) )
|
|
return nl->TwoElemList(nl->SymbolAtom(Symbol::STREAM()),
|
|
nl->SymbolAtom(UReal::BasicType()));
|
|
if( nl->IsEqual( nl->Second(arg1), UPoint::BasicType() ) )
|
|
return nl->TwoElemList(nl->SymbolAtom(Symbol::STREAM()),
|
|
nl->SymbolAtom(UPoint::BasicType()));
|
|
if( nl->IsEqual( nl->Second(arg1), UString::BasicType() ) )
|
|
return nl->TwoElemList(nl->SymbolAtom(Symbol::STREAM()),
|
|
nl->SymbolAtom(UString::BasicType()));
|
|
|
|
nl->WriteToString(argstr, nl->Second(arg1));
|
|
ErrorReporter::ReportError("Operator when expects a type "
|
|
"(stream T); T in {ubool, uint, ureal, upoint, "
|
|
"ustring, uregion} but gets '(stream "
|
|
+ argstr + ")'.");
|
|
return nl->SymbolAtom( Symbol::TYPEERROR() );
|
|
}
|
|
|
|
/*
|
|
5.46.2 Value Mapping for ~atperiods~
|
|
|
|
*/
|
|
struct WhenLocalInfo
|
|
{
|
|
Word uWord; // the address of the unit value
|
|
Word pWord; // the adress of the periods value
|
|
int j; // save the number of the interval
|
|
};
|
|
|
|
/*
|
|
Variant 1: first argument is a scalar value
|
|
|
|
*/
|
|
|
|
template <class Alpha>
|
|
int MappingUnitWhen( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
AtPeriodsLocalInfo *localinfo;
|
|
Interval<Instant> interval;
|
|
Alpha *unit;
|
|
Alpha r(true);
|
|
Periods* periods;
|
|
|
|
switch( message )
|
|
{
|
|
case OPEN:
|
|
{
|
|
// #ifdef TUA_DEBUG
|
|
// cout << "\nMappingUnitAtPeriods: OPEN" << endl;
|
|
// #endif
|
|
Periods* p= new Periods(0);
|
|
MBool* mb= static_cast<MBool*>(args[1].addr);
|
|
CcBool tru(true, true);
|
|
MBool mbTrue(0);
|
|
mb->At(tru, mbTrue);
|
|
mbTrue.DefTime(*p);
|
|
|
|
localinfo = new AtPeriodsLocalInfo;
|
|
localinfo->uWord = args[0];
|
|
localinfo->pWord = SetWord(p);
|
|
localinfo->j = 0;
|
|
local.setAddr(localinfo);
|
|
return 0;
|
|
}break;
|
|
case REQUEST:
|
|
{
|
|
// #ifdef TUA_DEBUG
|
|
// cout << "\nMappingUnitAtPeriods: REQUEST" << endl;
|
|
// #endif
|
|
if( local.addr == 0 )
|
|
return CANCEL;
|
|
localinfo = (AtPeriodsLocalInfo *)local.addr;
|
|
unit = (Alpha*)localinfo->uWord.addr;
|
|
periods = (Periods*)localinfo->pWord.addr;
|
|
|
|
if( !unit->IsDefined() ||
|
|
!periods->IsDefined() ||
|
|
periods->IsEmpty() )
|
|
{
|
|
result.setAddr(0);
|
|
return CANCEL;
|
|
}
|
|
// #ifdef TUA_DEBUG
|
|
// cout << " Unit's timeInterval u="
|
|
// << TUPrintTimeInterval( unit->timeInterval ) << endl;
|
|
// #endif
|
|
if( localinfo->j >= periods->GetNoComponents() )
|
|
{
|
|
result.setAddr(0);
|
|
// #ifdef TUA_DEBUG
|
|
// cout << "Maquery train7 inside train7sectionsppingUnitAtPeriods: "
|
|
// << "REQUEST finished: CANCEL (1)"
|
|
// << endl;
|
|
// #endif
|
|
return CANCEL;
|
|
}
|
|
periods->Get( localinfo->j, interval );
|
|
localinfo->j++;
|
|
// #ifdef TUA_DEBUG
|
|
// cout << " Probing timeInterval p ="
|
|
// << TUPrintTimeInterval(interval)
|
|
// << endl;
|
|
// #endif
|
|
while( interval.Before( unit->timeInterval ) &&
|
|
localinfo->j < periods->GetNoComponents() )
|
|
{ // forward to first candidate interval
|
|
periods->Get(localinfo->j, interval);
|
|
localinfo->j++;
|
|
// #ifdef TUA_DEBUG
|
|
// cout << " Probing timeInterval="
|
|
// << TUPrintTimeInterval(interval)
|
|
// << endl;
|
|
// if (interval.Before( unit->timeInterval ))
|
|
// cout << " p is before u" << endl;
|
|
// if (localinfo->j < periods->GetNoComponents())
|
|
// cout << " j < #Intervals" << endl;
|
|
// #endif
|
|
}
|
|
|
|
if( unit->timeInterval.Before( interval ) )
|
|
{ // interval after unit-deftime --> finished
|
|
result.addr = 0;
|
|
// #ifdef TUA_DEBUG
|
|
// cout << "MappingUnitAtPeriods: REQUEST finished: CANCEL (2)"
|
|
// << endl;
|
|
// #endif
|
|
return CANCEL;
|
|
}
|
|
|
|
if(unit->timeInterval.Intersects( interval ))
|
|
{ // interval intersectd unit's deftime --> produce result
|
|
// create unit restricted to interval
|
|
unit->AtInterval( interval, r );
|
|
Alpha* aux = new Alpha( r );
|
|
result.setAddr( aux );
|
|
// #ifdef TUA_DEBUG
|
|
// cout << " Result interval="
|
|
// << TUPrintTimeInterval(aux->timeInterval)
|
|
// << endl;
|
|
// cout << " Result defined=" << aux->IsDefined()
|
|
// << endl;
|
|
// cout << "MappingUnitAtPeriods: REQUEST finished: YIELD"
|
|
// << endl;
|
|
// #endif
|
|
return YIELD;
|
|
}
|
|
|
|
if( localinfo->j >= periods->GetNoComponents() )
|
|
{ // Passed last interval --> finished
|
|
result.addr = 0;
|
|
// #ifdef TUA_DEBUG
|
|
// cout << "MappingUnitAtPeriods: REQUEST finished: CANCEL (3)"
|
|
// << endl;
|
|
// #endif
|
|
return CANCEL;
|
|
}
|
|
|
|
result.setAddr(0 );
|
|
cout << "MappingUnitWhen: REQUEST finished: CANCEL (4)"
|
|
<< endl;
|
|
cout << "Intervals should overlap: " << endl;
|
|
cout << " Unit's timeInterval = ";
|
|
TUPrintTimeInterval(unit->timeInterval);
|
|
cout << " Current Period's interval = ";
|
|
TUPrintTimeInterval(interval);
|
|
cout << endl;
|
|
assert( false );
|
|
return CANCEL; // should not happen
|
|
}break;
|
|
case CLOSE:
|
|
{
|
|
if( local.addr != 0 )
|
|
{
|
|
AtPeriodsLocalInfo *li= static_cast<AtPeriodsLocalInfo *>(local.addr);
|
|
Periods* p = static_cast<Periods*>(li->pWord.addr);
|
|
delete p;
|
|
delete li;
|
|
local.setAddr(Address(0));
|
|
}
|
|
return 0;
|
|
}
|
|
}
|
|
// should not happen:
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
Variant 2: first argument is a stream
|
|
|
|
*/
|
|
|
|
struct WhenLocalInfoUS
|
|
{
|
|
Word uWord; // address of the input stream
|
|
Word pWord; // address of the input periods value
|
|
int j; // interval counter for within periods
|
|
};
|
|
|
|
|
|
template <class Alpha>
|
|
int MappingUnitStreamWhen( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
AtPeriodsLocalInfoUS *localinfo;
|
|
Alpha *unit, *aux;
|
|
Alpha resultUnit(true);
|
|
Periods *periods;
|
|
Interval<Instant> interval;
|
|
bool foundUnit = false;
|
|
|
|
switch( message )
|
|
{
|
|
case OPEN:
|
|
{
|
|
Periods* p= new Periods(0);
|
|
MBool* mb= static_cast<MBool*>(args[1].addr);
|
|
CcBool tru(true, true);
|
|
MBool mbTrue(0);
|
|
mb->At(tru, mbTrue);
|
|
mbTrue.DefTime(*p);
|
|
|
|
localinfo = new AtPeriodsLocalInfoUS;
|
|
localinfo->pWord = p;
|
|
localinfo->j = 0; // init interval counter
|
|
qp->Open( args[0].addr ); // open stream of units
|
|
qp->Request( args[0].addr, localinfo->uWord ); // request first unit
|
|
if ( !( qp->Received( args[0].addr) ) ){
|
|
localinfo->uWord.addr = 0;
|
|
result.addr = 0;
|
|
return CANCEL;
|
|
}
|
|
local.setAddr(localinfo); // pass up link to localinfo
|
|
return 0;
|
|
}break;
|
|
case REQUEST:
|
|
{
|
|
if ( local.addr == 0 )
|
|
return CANCEL;
|
|
localinfo = (AtPeriodsLocalInfoUS *) local.addr; // restore local data
|
|
if ( localinfo->uWord.addr == 0 ) { result.addr = 0; return CANCEL; }
|
|
unit = (Alpha *) localinfo->uWord.addr;
|
|
if ( localinfo->pWord.addr == 0 ) { result.addr = 0; return CANCEL; }
|
|
periods = (Periods *) localinfo->pWord.addr;
|
|
|
|
if( !periods->IsDefined() || periods->IsEmpty() )
|
|
return CANCEL;
|
|
|
|
// search for a pair of overlapping unit/interval:
|
|
while (1){
|
|
if ( localinfo->j == periods->GetNoComponents() ){// redo first interval
|
|
localinfo->j = 0;
|
|
unit->DeleteIfAllowed(); // delete original unit?
|
|
localinfo->uWord.addr = 0;
|
|
foundUnit = false;
|
|
while(!foundUnit){
|
|
qp->Request(args[0].addr, localinfo->uWord); // get new unit
|
|
if( qp->Received( args[0].addr ) )
|
|
unit = (Alpha *) localinfo->uWord.addr;
|
|
else {
|
|
localinfo->uWord.addr = 0;
|
|
result.addr = 0;
|
|
return CANCEL;
|
|
} // end of unit stream
|
|
foundUnit = unit->IsDefined();
|
|
}
|
|
}
|
|
periods->Get(localinfo->j, interval); // get an interval
|
|
if ( !( interval.Before( unit->timeInterval ) )
|
|
&& !( unit->timeInterval.Before( interval) ) )
|
|
break; // found candidate, break while
|
|
localinfo->j++; // next interval, loop
|
|
}
|
|
|
|
// We have an interval overlapping the unit's interval now
|
|
// Return unit restricted to overlapping part of both intervals
|
|
if (!unit->timeInterval.Intersects( interval) ){ // This may not happen!
|
|
cout << __FILE__ << __LINE__ << __PRETTY_FUNCTION__
|
|
<< ": Intervals do not overlap, but should do so:" << endl;
|
|
cout << " Unit's timeInterval = ";
|
|
TUPrintTimeInterval(unit->timeInterval);
|
|
cout << endl << " Current Period's interval = ";
|
|
TUPrintTimeInterval(interval);
|
|
cout << endl;
|
|
assert(false);
|
|
}
|
|
unit->AtInterval( interval, resultUnit); // intersect unit and interval
|
|
aux = new Alpha( resultUnit );
|
|
result.setAddr( aux );
|
|
localinfo->j++; // increase interval counter
|
|
return YIELD;
|
|
}break;
|
|
case CLOSE:
|
|
{
|
|
if ( local.addr != 0 )
|
|
{
|
|
qp->Close( args[0].addr );
|
|
localinfo = (AtPeriodsLocalInfoUS *) local.addr;
|
|
if ( localinfo->uWord.addr != 0 )
|
|
{
|
|
unit = (Alpha *) localinfo->uWord.addr;
|
|
unit->DeleteIfAllowed(); // delete remaining original unit
|
|
}
|
|
Periods* p = static_cast<Periods*>(localinfo->pWord.addr);
|
|
delete p;
|
|
delete (AtPeriodsLocalInfoUS *)localinfo;
|
|
local.setAddr(Address(0));
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
} // end switch
|
|
|
|
return -1; // should never be reached
|
|
|
|
} // end MappingUnitStreamAtPeriods
|
|
|
|
/*
|
|
5.46.3 Specification for operator ~atperiods~
|
|
|
|
*/
|
|
const std::string
|
|
TemporalSpecWhen =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\") "
|
|
"( <text>For T in {int, bool, real, string, point, region}:\n"
|
|
"(uT periods) -> stream uT\n"
|
|
"((stream uT) periods) -> stream uT</text--->"
|
|
"<text>_ when[_] </text--->"
|
|
"<text>restrict the movement to the times on which the given mbool is true."
|
|
"</text--->"
|
|
"<text>units(mpoint1) when[speed(mpoint1) > 20.0] </text--->) )";
|
|
|
|
/*
|
|
5.46.4 Value map of operator ~when~
|
|
|
|
*/
|
|
|
|
ValueMapping temporalunitwhenmap[] =
|
|
{ MappingUnitWhen<UBool>,
|
|
MappingUnitWhen<UInt>,
|
|
MappingUnitWhen<UReal>,
|
|
MappingUnitWhen<UPoint>,
|
|
MappingUnitWhen<UString>,
|
|
MappingUnitStreamWhen<UBool>,
|
|
MappingUnitStreamWhen<UInt>,
|
|
MappingUnitStreamWhen<UReal>,
|
|
MappingUnitStreamWhen<UPoint>,
|
|
MappingUnitStreamWhen<UString>
|
|
};
|
|
|
|
/*
|
|
5.46.4 Selection Function of operator ~when~
|
|
|
|
*/
|
|
|
|
int
|
|
WhenSelect( ListExpr args )
|
|
{
|
|
ListExpr arg1 = nl->First( args );
|
|
|
|
if (nl->IsAtom( arg1 ) )
|
|
{
|
|
if( nl->SymbolValue( arg1 ) == UBool::BasicType() )
|
|
return 0;
|
|
if( nl->SymbolValue( arg1 ) == UInt::BasicType() )
|
|
return 1;
|
|
if( nl->SymbolValue( arg1 ) == UReal::BasicType() )
|
|
return 2;
|
|
if( nl->SymbolValue( arg1 ) == UPoint::BasicType() )
|
|
return 3;
|
|
if( nl->SymbolValue( arg1 ) == UString::BasicType() )
|
|
return 4;
|
|
}
|
|
|
|
if( Stream<ANY>:: checkType(arg1)){
|
|
if( nl->IsEqual( nl->Second(arg1), UBool::BasicType() ) )
|
|
return 5;
|
|
if( nl->IsEqual( nl->Second(arg1), UInt::BasicType() ) )
|
|
return 6;
|
|
if( nl->IsEqual( nl->Second(arg1), UReal::BasicType() ) )
|
|
return 7;
|
|
if( nl->IsEqual( nl->Second(arg1), UPoint::BasicType() ) )
|
|
return 8;
|
|
if( nl->IsEqual( nl->Second(arg1), UString::BasicType() ) )
|
|
return 9;
|
|
}
|
|
|
|
return -1; // This point should never be reached
|
|
}
|
|
|
|
/*
|
|
5.46.6 Definition of operator ~when~
|
|
|
|
*/
|
|
Operator temporalunitwhen( "when",
|
|
TemporalSpecWhen,
|
|
10,
|
|
temporalunitwhenmap,
|
|
WhenSelect,
|
|
UnitWhenTypeMap );
|
|
|
|
|
|
/*
|
|
5.47.1 Operator atRect Value Mapping
|
|
|
|
*/
|
|
|
|
int atRectUVM( Word* args, Word& result, int message, Word&
|
|
local, Supplier s ){
|
|
UPoint* up = (UPoint*) args[0].addr;
|
|
Rectangle<2>* rect = (Rectangle<2>*) args[1].addr;
|
|
result = qp->ResultStorage(s);
|
|
UPoint* res = (UPoint*) result.addr;
|
|
up->At(*rect,*res);
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
5.47.2 Operator atRect Type Mapping
|
|
|
|
Signature is: upoint x rect -> upoint
|
|
|
|
*/
|
|
|
|
ListExpr atRectUTM(ListExpr args){
|
|
std::string err ="upoint x rect expected";
|
|
if(!nl->HasLength(args,2)){
|
|
return listutils::typeError(err + " (wrong number of arguments)");
|
|
}
|
|
if(!UPoint::checkType(nl->First(args)) ||
|
|
!Rectangle<2>::checkType(nl->Second(args))){
|
|
return listutils::typeError(err);
|
|
}
|
|
return nl->SymbolAtom(UPoint::BasicType());
|
|
}
|
|
|
|
/*
|
|
5.47.3 Specification
|
|
|
|
*/
|
|
const std::string atRectUSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
|
|
"( <text>upoint x rect -> upoint </text---> "
|
|
"<text> up atRect r </text--->"
|
|
"<text>Restricts the upoint up to the part inside r "
|
|
"</text--->"
|
|
"<text>query getunit(train7, 1) atRect bbox(thecenter)</text--->"
|
|
") )";
|
|
|
|
/*
|
|
5.47.4 Definition of operator atRect
|
|
|
|
*/
|
|
Operator atRectU( "atRect",
|
|
atRectUSpec,
|
|
atRectUVM,
|
|
Operator::SimpleSelect,
|
|
atRectUTM);
|
|
|
|
|
|
/*
|
|
5.47 Operator ~contains~
|
|
|
|
----
|
|
Secinterval x SecInterval -> bool
|
|
Secinterval x Periods -> bool
|
|
Periods x SecInterval -> bool
|
|
Periods x Periods -> bool
|
|
----
|
|
|
|
*/
|
|
|
|
/*
|
|
5.47.1 Class ~SecInterval~
|
|
|
|
*/
|
|
const std::string SecInterval::BasicType() {
|
|
return "interval";
|
|
}
|
|
|
|
const bool SecInterval::checkType(const ListExpr type) {
|
|
return listutils::isSymbol(type, BasicType());
|
|
}
|
|
|
|
bool SecInterval::CheckKind(ListExpr type, ListExpr& errorInfo) {
|
|
return checkType(type);
|
|
}
|
|
|
|
size_t SecInterval::Sizeof() const {
|
|
return 2 * sizeof(Instant) + 2 * sizeof(CcBool);
|
|
}
|
|
|
|
int SecInterval::Compare(const Attribute* attr) const {
|
|
SecInterval* si = (SecInterval*) attr;
|
|
if(!IsDefined()) {
|
|
return si->IsDefined()? -1 : 0;
|
|
}
|
|
if(!si->IsDefined()){
|
|
return 1;
|
|
}
|
|
return Interval<Instant>::CompareTo(*si);
|
|
}
|
|
|
|
std::ostream& SecInterval::Print(std::ostream &os) const {
|
|
os << (lc?"[":"(");
|
|
start.Print(os) << ", ";
|
|
end.Print(os) << (rc?"]":")");
|
|
return os;
|
|
}
|
|
|
|
bool SecInterval::Adjacent(const Attribute* attr) const {
|
|
if(!IsDefined() || !attr->IsDefined())
|
|
return false;
|
|
return Interval<Instant>::Adjacent(*((Interval<Instant>*)attr));
|
|
}
|
|
|
|
SecInterval* SecInterval::Clone() const {
|
|
SecInterval* i = new SecInterval(*this);
|
|
return i;
|
|
}
|
|
|
|
size_t SecInterval::HashValue() const {
|
|
return (this->start).HashValue() + (this->end).HashValue();
|
|
}
|
|
|
|
void SecInterval::CopyFrom(const Attribute *attr) {
|
|
*this = *((SecInterval*)attr);
|
|
}
|
|
|
|
void SecInterval::WriteTo(char *dest) {
|
|
strcpy(dest, ToString().c_str());
|
|
}
|
|
|
|
std::string SecInterval::ToString() {
|
|
std::string result = "(" + start.ToString() + " " + end.ToString() + " "
|
|
+ (lc ? "TRUE" : "FALSE") + " " + (rc ? "TRUE" : "FALSE") + ")";
|
|
return result;
|
|
}
|
|
|
|
ListExpr SecInterval::ToListExpr(const ListExpr typeInfo) const{
|
|
if(IsDefined())
|
|
return nl->FourElemList(start.ToListExpr(false), end.ToListExpr(false),
|
|
nl->BoolAtom(lc), nl->BoolAtom(rc));
|
|
else
|
|
return nl->SymbolAtom(Symbol::UNDEFINED());
|
|
}
|
|
|
|
SmiSize SecInterval::SizeOfChars() {
|
|
std::string key = this->ToString();
|
|
return (SmiSize)key.length();
|
|
}
|
|
|
|
bool SecInterval::ReadFrom(const ListExpr instance, const ListExpr typeInfo){
|
|
if(listutils::isSymbolUndefined(instance)){
|
|
SetDefined(false);
|
|
return true;
|
|
}
|
|
if(!nl->HasLength(instance,4))
|
|
return false;
|
|
datetime::DateTime s(datetime::instanttype);
|
|
datetime::DateTime e(datetime::instanttype);
|
|
bool lc;
|
|
bool rc;
|
|
if (!s.ReadFrom(nl->First(instance), false)
|
|
|| !e.ReadFrom(nl->Second(instance), false))
|
|
return false;
|
|
ListExpr Lc = nl->Third(instance);
|
|
if (nl->AtomType(Lc) != BoolType)
|
|
return false;
|
|
else
|
|
lc = nl->BoolValue(Lc);
|
|
ListExpr Rc = nl->Fourth(instance);
|
|
if (nl->AtomType(Rc) != BoolType)
|
|
return false;
|
|
else
|
|
rc = nl->BoolValue(Rc);
|
|
return Set(s,e,lc,rc);
|
|
}
|
|
|
|
bool SecInterval::Set(const datetime::DateTime& s, const datetime::DateTime& e,
|
|
const bool lc, const bool rc) {
|
|
if ((s < e) || ((s == e) && lc && rc)) {
|
|
SetDefined(true);
|
|
this->start = s;
|
|
this->end = e;
|
|
this->lc = lc;
|
|
this->rc = rc;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool SecInterval::Set(const Interval<Instant>* iinst) {
|
|
return Set(iinst->start, iinst->end, iinst->lc, iinst->rc);
|
|
}
|
|
|
|
bool SecInterval::SetStart(const datetime::DateTime& s, const bool lc) {
|
|
if ((s < this->end) || ((s == this->end) && lc && this->rc)) {
|
|
this->start = s;
|
|
this->lc = lc;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool SecInterval::SetEnd(const datetime::DateTime& e, const bool rc) {
|
|
if ((this->start < e) || ((this->start == e) && rc && this->lc)) {
|
|
this->end = e;
|
|
this->rc = rc;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
ListExpr SecInterval::Property(){
|
|
return (nl->TwoElemList(
|
|
nl->FiveElemList(
|
|
nl->StringAtom("Signature"),
|
|
nl->StringAtom("Example Type List"),
|
|
nl->StringAtom("List Rep"),
|
|
nl->StringAtom("Example List"),
|
|
nl->StringAtom("Remarks")),
|
|
nl->FiveElemList(
|
|
nl->StringAtom("-> SecInterval"),
|
|
nl->StringAtom(SecInterval::BasicType()),
|
|
nl->StringAtom("(start end leftclosed rightclosed)"),
|
|
nl->TextAtom
|
|
("2004-4-12-8:03:32.645 2011-07-01-08:55:22.000 TRUE FALSE"),
|
|
nl->StringAtom("This type represents an interval"))));
|
|
}
|
|
|
|
const bool SecInterval::Contains(const Periods& per) const{
|
|
if (!IsDefined() || !per.IsDefined())
|
|
return false;
|
|
int no = per.GetNoComponents();
|
|
if (!no)
|
|
return true;
|
|
Interval<Instant> firstIv, lastIv;
|
|
per.Get(0, firstIv);
|
|
per.Get(no - 1, lastIv);
|
|
return Interval<Instant>::Contains(firstIv)
|
|
&& Interval<Instant>::Contains(lastIv);
|
|
}
|
|
|
|
const bool SecInterval::Contains(const Interval<Instant>& si) const{
|
|
if(!IsDefined())
|
|
return false;
|
|
return Interval<Instant>::Contains(si);
|
|
}
|
|
|
|
/*
|
|
5.47.2 Type mapping function for ~contains~
|
|
|
|
*/
|
|
ListExpr containsTM(ListExpr args) {
|
|
if (nl->ListLength(args) != 2) {
|
|
ErrorReporter::ReportError("Exactly two arguments required.");
|
|
return nl->SymbolAtom(Symbol::TYPEERROR());
|
|
}
|
|
if (!SecInterval::checkType(nl->First(args))
|
|
&& !Periods::checkType(nl->First(args))) {
|
|
ErrorReporter::ReportError
|
|
("1st argument requires type interval or periods.");
|
|
return nl->SymbolAtom(Symbol::TYPEERROR());
|
|
}
|
|
if (!SecInterval::checkType(nl->First(args))
|
|
&& !Periods::checkType(nl->First(args))) {
|
|
ErrorReporter::ReportError
|
|
("2nd argument requires type interval or periods.");
|
|
return nl->SymbolAtom(Symbol::TYPEERROR());
|
|
}
|
|
return nl->SymbolAtom(CcBool::BasicType());
|
|
}
|
|
|
|
/*
|
|
5.47.3 Value mapping for operator ~contains~
|
|
|
|
*/
|
|
template<class C1, class C2>
|
|
int containsVM(Word* args, Word& result, int message, Word& local, Supplier s){
|
|
C1* arg1 = static_cast<C1*>(args[0].addr);
|
|
C2* arg2 = static_cast<C2*>(args[1].addr);
|
|
result = qp->ResultStorage(s);
|
|
CcBool* res = (CcBool*)result.addr;
|
|
if(!arg1->IsDefined() || !arg2->IsDefined())
|
|
res->SetDefined(false);
|
|
else
|
|
res->Set(true, arg1->Contains(*arg2));
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
5.47.4 Value mapping array for operator ~contains~
|
|
|
|
*/
|
|
ValueMapping containsvm[] = {containsVM<SecInterval, SecInterval>,
|
|
containsVM<Periods, SecInterval>,
|
|
containsVM<SecInterval, Periods>,
|
|
containsVM<Periods, Periods>};
|
|
|
|
GenTC<SecInterval> interval;
|
|
|
|
/*
|
|
5.47.5 Specification for operator ~contains~
|
|
|
|
*/
|
|
const std::string ContainsSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\") "
|
|
"( <text>periods x periods -> bool</text--->"
|
|
"<text>_ contains _ </text--->"
|
|
"<text>decides whether the first argument contains the second</text--->"
|
|
"<text>p1 contains p2</text--->) )";
|
|
|
|
/*
|
|
5.47.6 Selection Function of operator ~contains~
|
|
|
|
*/
|
|
int containsSelect(ListExpr args) {
|
|
if (SecInterval::checkType(nl->First(args))
|
|
&& SecInterval::checkType(nl->Second(args)))
|
|
return 0;
|
|
else if (Periods::checkType(nl->First(args))
|
|
&& SecInterval::checkType(nl->Second(args)))
|
|
return 1;
|
|
else if (SecInterval::checkType(nl->First(args))
|
|
&& Periods::checkType(nl->Second(args)))
|
|
return 2;
|
|
else if (Periods::checkType(nl->First(args))
|
|
&& Periods::checkType(nl->Second(args)))
|
|
return 3;
|
|
else
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
5.47.7 Definition of operator ~contains~
|
|
|
|
*/
|
|
Operator temporalcontains("contains",
|
|
ContainsSpec,
|
|
4,
|
|
containsvm,
|
|
containsSelect,
|
|
containsTM);
|
|
|
|
/*
|
|
5.48 Operator ~swapcoord~
|
|
|
|
----
|
|
mpoint -> mpoint
|
|
----
|
|
|
|
*/
|
|
|
|
/*
|
|
5.48.1 Type mapping function for ~swapcoord~
|
|
|
|
*/
|
|
ListExpr swapcoordTM(ListExpr args) {
|
|
if (nl->ListLength(args) != 1) {
|
|
return listutils::typeError("Exactly one argument required.");
|
|
}
|
|
if (!MPoint::checkType(nl->First(args))) {
|
|
return listutils::typeError("Type mpoint required.");
|
|
}
|
|
return nl->SymbolAtom(MPoint::BasicType());
|
|
}
|
|
|
|
/*
|
|
5.48.2 Value mapping function for operator ~swapcoord~
|
|
|
|
*/
|
|
int swapcoordVM(Word* args, Word& result, int message, Word& local, Supplier s){
|
|
MPoint* source = static_cast<MPoint*>(args[0].addr);
|
|
result = qp->ResultStorage(s);
|
|
MPoint* res = (MPoint*)result.addr;
|
|
if (!source->IsDefined()) {
|
|
res->SetDefined(false);
|
|
return 0;
|
|
}
|
|
res->SetDefined(true);
|
|
res->Clear();
|
|
UPoint up(1);
|
|
Point p0, p1;
|
|
for (int i = 0; i < source->GetNoComponents(); i++) {
|
|
source->Get(i, up);
|
|
p0.Set(up.p0.GetY(), up.p0.GetX());
|
|
p1.Set(up.p1.GetY(), up.p1.GetX());
|
|
p0.SetDefined(true);
|
|
p1.SetDefined(true);
|
|
up.p0 = p0;
|
|
up.p1 = p1;
|
|
res->MergeAdd(up);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
5.48.3 Specification for operator ~swapcoord~
|
|
|
|
*/
|
|
const std::string swapcoordSpec =
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\") "
|
|
"( <text>mpoint -> mpoint</text--->"
|
|
"<text>swapcoord( _ )</text--->"
|
|
"<text>swaps the x and y coordinates of an mpoint</text--->"
|
|
"<text>swapcoord(mpoint1)</text--->) )";
|
|
|
|
/*
|
|
5.48.4 Definition of operator ~swapcoord~
|
|
|
|
*/
|
|
Operator temporalswapcoord("swapcoord",
|
|
swapcoordSpec,
|
|
swapcoordVM,
|
|
Operator::SimpleSelect,
|
|
swapcoordTM);
|
|
|
|
|
|
|
|
/*
|
|
5.49 Operator ~getInterval~
|
|
|
|
This operator computes bounding interval of a moving
|
|
object.
|
|
|
|
*/
|
|
ListExpr getIntervalTM(ListExpr args){
|
|
if(!nl->HasLength(args,1)){
|
|
return listutils::typeError("one arg expected");
|
|
}
|
|
ListExpr a = nl->First(args);
|
|
if( !MString::checkType(a)
|
|
&& !MRegion::checkType(a)
|
|
&& !MReal::checkType(a)
|
|
&& !MPoint::checkType(a)
|
|
&& !MInt::checkType(a)
|
|
&& !MBool::checkType(a)
|
|
&& !Periods::checkType(a)
|
|
&& !UString::checkType(a)
|
|
&& !URegion::checkType(a)
|
|
&& !UReal::checkType(a)
|
|
&& !UPoint::checkType(a)
|
|
&& !UInt::checkType(a)
|
|
&& !UBool::checkType(a)){
|
|
return listutils::typeError("unsupported type found");
|
|
}
|
|
return listutils::basicSymbol<SecInterval>();
|
|
}
|
|
|
|
template<class A>
|
|
int getIntervalVM_Unit(Word* args, Word& result,
|
|
int message, Word& local, Supplier s){
|
|
|
|
A* arg = (A*) args[0].addr;
|
|
result=qp->ResultStorage(s);
|
|
SecInterval* res = (SecInterval*) result.addr;
|
|
if(!arg->IsDefined()){
|
|
res->SetDefined(false);
|
|
return 0;
|
|
}
|
|
(*res) = arg->timeInterval;
|
|
return 0;
|
|
}
|
|
|
|
|
|
int getIntervalVM_Periods(Word* args, Word& result,
|
|
int message, Word& local, Supplier s){
|
|
|
|
Periods* arg = (Periods*) args[0].addr;
|
|
result=qp->ResultStorage(s);
|
|
SecInterval* res = (SecInterval*) result.addr;
|
|
if(!arg->IsDefined() || arg->GetNoComponents()<1){
|
|
res->SetDefined(false);
|
|
return 0;
|
|
}
|
|
Interval<Instant> iv(false);
|
|
arg->Get(0,iv);
|
|
(*res) = iv;
|
|
if(arg->GetNoComponents()==1){
|
|
return 0;
|
|
}
|
|
arg->Get(arg->GetNoComponents()-1, iv);
|
|
res->SetEnd(iv.end, iv.rc);
|
|
return 0;
|
|
}
|
|
|
|
|
|
template<class A>
|
|
int getIntervalVM_Moving(Word* args, Word& result,
|
|
int message, Word& local, Supplier s){
|
|
A* arg = (A*) args[0].addr;
|
|
result = qp->ResultStorage(s);
|
|
typedef typename A::unittype U;
|
|
SecInterval* res = (SecInterval*) result.addr;
|
|
|
|
if(!arg->IsDefined() || arg->GetNoComponents()<1){
|
|
res->SetDefined(false);
|
|
return 0;
|
|
}
|
|
U unit(false);
|
|
arg->Get(0,unit);
|
|
(*res) = unit.timeInterval;
|
|
if(arg->GetNoComponents()==1){
|
|
return 0;
|
|
}
|
|
arg->Get(arg->GetNoComponents()-1, unit);
|
|
res->SetEnd(unit.timeInterval.end, unit.timeInterval.rc);
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
|
|
ValueMapping getIntervalVM[] = {
|
|
getIntervalVM_Unit<UString>,
|
|
getIntervalVM_Unit<URegion>,
|
|
getIntervalVM_Unit<UReal>,
|
|
getIntervalVM_Unit<UPoint>,
|
|
getIntervalVM_Unit<UInt>,
|
|
getIntervalVM_Unit<UBool>,
|
|
getIntervalVM_Periods,
|
|
getIntervalVM_Moving<MString>,
|
|
getIntervalVM_Moving<MRegion>,
|
|
getIntervalVM_Moving<MReal>,
|
|
getIntervalVM_Moving<MPoint>,
|
|
getIntervalVM_Moving<MInt>,
|
|
getIntervalVM_Moving<MBool>
|
|
};
|
|
|
|
|
|
int getIntervalSelect(ListExpr args){
|
|
ListExpr a = nl->First(args);
|
|
if(UString::checkType(a) ) return 0;
|
|
if(URegion::checkType(a) ) return 1;
|
|
if(UReal::checkType(a) ) return 2;
|
|
if(UPoint::checkType(a) ) return 3;
|
|
if(UInt::checkType(a) ) return 4;
|
|
if(UBool::checkType(a) ) return 5;
|
|
if(Periods::checkType(a) ) return 6;
|
|
if(MString::checkType(a) ) return 7;
|
|
if(MRegion::checkType(a) ) return 8;
|
|
if(MReal::checkType(a) ) return 9;
|
|
if(MPoint::checkType(a) ) return 10;
|
|
if(MInt::checkType(a) ) return 11;
|
|
if(MBool::checkType(a) ) return 12;
|
|
return -1;
|
|
}
|
|
|
|
OperatorSpec getIntervalSpec(
|
|
"uX, uX -> interval, "
|
|
"X in {string, region, real, int, boll, point, periods}",
|
|
"getInterval(_)",
|
|
"Computes the time interval (boxed).",
|
|
"query getInterval(train1)"
|
|
);
|
|
|
|
Operator getIntervalOp(
|
|
"getInterval",
|
|
getIntervalSpec.getStr(),
|
|
13,
|
|
getIntervalVM,
|
|
getIntervalSelect,
|
|
getIntervalTM
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
6 Creating the Algebra
|
|
|
|
*/
|
|
|
|
class TemporalUnitAlgebra : public Algebra
|
|
{
|
|
public:
|
|
TemporalUnitAlgebra() : Algebra()
|
|
{
|
|
|
|
AddTypeConstructor(&interval);
|
|
interval.AssociateKind("DATA");
|
|
|
|
AddOperator( &temporalunitmakemvalue );
|
|
AddOperator( &temporalunitthemvalue );
|
|
AddOperator( &the_mvalue2 );
|
|
AddOperator( &temporalunitqueryrect2d );
|
|
AddOperator( &temporalunitpoint2d );
|
|
AddOperator( &temporalunitisempty );
|
|
AddOperator( &temporalunitdeftime );
|
|
AddOperator( &temporalunitpresent );
|
|
AddOperator( &temporalunitinitial );
|
|
AddOperator( &temporalunitfinal );
|
|
AddOperator( &temporalunitatinstant );
|
|
AddOperator( &temporalunitatperiods );
|
|
AddOperator( &temporalunitwhen );
|
|
AddOperator( &temporalunitat );
|
|
AddOperator( &temporalunitatmax );
|
|
AddOperator( &temporalunitatmin );
|
|
AddOperator( &temporalunitintersection );
|
|
AddOperator( &temporalunitinside );
|
|
AddOperator( &temporalunitpasses );
|
|
AddOperator( &temporalunitget_duration );
|
|
AddOperator( &temporalunittrajectory );
|
|
AddOperator( &temporalunitdistance );
|
|
AddOperator( &temporalunitabs );
|
|
AddOperator( &temporalspeed );
|
|
AddOperator( &temporalvelocity );
|
|
AddOperator( &temporalderivable );
|
|
AddOperator( &temporalderivative );
|
|
AddOperator( &temporalunitnocomponents );
|
|
AddOperator( &temporalunitnot );
|
|
AddOperator( &temporalunitand );
|
|
AddOperator( &temporalunitor );
|
|
AddOperator( &temporalunitsometimes );
|
|
AddOperator( &temporalunitnever );
|
|
AddOperator( &temporalunitalways );
|
|
AddOperator( &temporalunitisequal );
|
|
AddOperator( &temporalunitisnotequal );
|
|
AddOperator( &temporalunitsmaller );
|
|
AddOperator( &temporalunitbigger );
|
|
AddOperator( &temporalunitsmallereq );
|
|
AddOperator( &temporalunitbiggereq );
|
|
AddOperator( &temporalunitvalisequal );
|
|
AddOperator( &temporalunitvalisnotequal );
|
|
AddOperator( &temporalunitvalsmaller );
|
|
AddOperator( &temporalunitvalbigger );
|
|
AddOperator( &temporalunitvalsmallereq );
|
|
AddOperator( &temporalunitvalbiggereq );
|
|
AddOperator( &temporalunituint2ureal );
|
|
AddOperator( &temporalunittheupoint );
|
|
AddOperator( &temporalunittheivalue );
|
|
AddOperator( &temporalunitlength );
|
|
AddOperator( &temporalunitcanmeet);
|
|
AddOperator( &atRectU);
|
|
AddOperator(&temporalcontains);
|
|
AddOperator(&temporalswapcoord);
|
|
AddOperator(&getIntervalOp);
|
|
}
|
|
~TemporalUnitAlgebra() {};
|
|
};
|
|
|
|
} // end of namespace temporalalgebra
|
|
|
|
/*
|
|
7 Initialization
|
|
|
|
Each algebra module needs an initialization function. The algebra manager
|
|
has a reference to this function if this algebra is included in the list
|
|
of required algebras, thus forcing the linker to include this module.
|
|
|
|
The algebra manager invokes this function to get a reference to the instance
|
|
of the algebra class and to provide references to the global nested list
|
|
container (used to store constructor, type, operator and object information)
|
|
and to the query processor.
|
|
|
|
The function has a C interface to make it possible to load the algebra
|
|
dynamically at runtime.
|
|
|
|
*/
|
|
|
|
extern "C"
|
|
Algebra*
|
|
InitializeTemporalUnitAlgebra( NestedList* nlRef, QueryProcessor* qpRef )
|
|
{
|
|
nl = nlRef;
|
|
qp = qpRef;
|
|
return (new temporalalgebra::TemporalUnitAlgebra());
|
|
}
|
|
|
|
|