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

236 lines
6.4 KiB
C++

/*
*/
#include "Algebras/Distributed2/DArray.h"
#include "Algebras/Distributed2/fsrel.h"
#include <ListUtils.h>
#include <StandardTypes.h>
#include "Stream.h"
#include "DPDTypeMapper.h"
namespace distributed3 {
/****** static helper functions *********/
bool DPDTypeMapper::arraySubtypeEqualsFunctionArgument(ListExpr arrayType,
ListExpr functionType) {
ListExpr expFunArg = distributed2::DArray::checkType(arrayType)
?nl->Second(arrayType)
: nl->TwoElemList(
listutils::basicSymbol<distributed2::fsrel>(),
nl->Second(nl->Second(arrayType)));
if(!nl->Equal(expFunArg, nl->Second(functionType))){
return false;
}
return true;
}
/* returns the result type of the functions type */
ListExpr DPDTypeMapper::getResultType(ListExpr function) {
ListExpr res = function;
while(!nl->HasLength(res,1)){
res = nl->Rest(res);
}
return nl->First(res);
}
/*
returns the last argument of a function as a ListExpr
TODO not tested for the value part of a function.
*/
ListExpr DPDTypeMapper::getLastArgumentOf(ListExpr function) {
ListExpr d1UsedArg = function;
while(!nl->HasLength(d1UsedArg,2)){
d1UsedArg = nl->Rest(d1UsedArg);
}
return nl->First(d1UsedArg);
}
/*
replaces the occurrance of a type operator in the value part of a function
(functionValue) by replacement.
TODO next part required?
returns a function with one argument. If functionValue contains two arguments
the second is used.
*/
ListExpr DPDTypeMapper::replaceTypeOperator(ListExpr functionValue,
ListExpr replacement) {
ListExpr ddarg = nl->HasLength(functionValue,3)
?nl->Second(functionValue)
:nl->Third(functionValue);
ListExpr result = nl->HasLength(functionValue,3)
?nl->Third(functionValue)
:nl->Fourth(functionValue);
return nl->ThreeElemList(
nl->First(functionValue),
nl->TwoElemList(
nl->First(ddarg), // elem_X
replacement),
result
);
}
/***** public member functions ******/
void DPDTypeMapper::printValues() {
std::cout << "\nargs:";
nl->WriteListExpr(args);
}
ListExpr DPDTypeMapper::typeMapping(){
if ( !rightNumberOfArgs()
|| !usesArgsInTypeMapping()
|| !checkArgs()
|| !checkInterdependencies()) {
return typeError();
}
return result();
}
/****** private member functions ********/
std::string DPDTypeMapper::getErrorMessage() {
return msg;
}
ListExpr DPDTypeMapper::typeError() {
return listutils::typeError(err() + getErrorMessage());
}
bool DPDTypeMapper::isRel() {
return Relation::checkType(getResultType(nl->First(dmap2)));
}
bool DPDTypeMapper::isStream() {
return Stream<Tuple>::checkType(getResultType(nl->First(dmap2)));
}
bool DPDTypeMapper::rightNumberOfArgs() {
if(!nl->HasLength(args,numberOfArgs())){
msg = "wrong number of args in specification file";
return false;
}
return true;
}
bool DPDTypeMapper::usesArgsInTypeMapping() {
ListExpr tmp = args;
while(!nl->IsEmpty(tmp)){
if(!nl->HasLength(nl->First(tmp),2)){
msg = "please set SetUsesArgsInTypeMapping() "
"for this operator in Constructor of Algebra";
return false;
}
tmp = nl->Rest(tmp);
}
return true;
}
bool DPDTypeMapper::checkArrayType() {
ListExpr arrayType = nl->First(array);
if( !distributed2::DArray::checkType(arrayType)
&& !distributed2::DFArray::checkType(arrayType)){
msg = "first arg is not a d[f]array";
return false;
}
ListExpr relation = nl->Second(arrayType);
if(!Relation::checkType(relation)){
msg = "array subtype is not a relation";
return false;
}
return true;
}
bool DPDTypeMapper::checkNameType() {
if(!CcString::checkType(nl->First(name))){
msg = "second arg is not a string";
return false;
}
return true;
}
bool DPDTypeMapper::checkPartitionType() {
ListExpr partitionfunctionType = nl->First(partitionfunction);
if(!listutils::isMap<1>(partitionfunctionType) ){
msg = "fourth arg is not a function";
return false;
}
if(!CcInt::checkType(getResultType(partitionfunctionType))){
msg = "result for distribution function is not an int";
return false;
}
if(!Tuple::checkType(getLastArgumentOf(partitionfunctionType))){
msg = "argument of the distribution function is not a tuple";
return false;
}
return true;
}
bool DPDTypeMapper::checkNumberOfSlotsType() {
if(!CcInt::checkType(nl->First(numberOfSlots))){
msg = " (fifth arg is not an int)";
return false;
}
return true;
}
bool DPDTypeMapper::checkDmap2Type() {
ListExpr dmap2Type = nl->First(dmap2);
if(!listutils::isMap<1>(dmap2Type) ){
msg = "last arg is not a function";
cout << msg;
return false;
}
if (!Stream<Tuple>::checkType(getLastArgumentOf(dmap2Type))) {
msg = "argument of dmap2 function is not a stream";
return false;
}
if(listutils::isStream(getResultType(dmap2Type)) && !isStream()){
msg = "function produces a stream of non-tuples.";
return false;
}
return true;
}
ListExpr DPDTypeMapper::result() {
return nl->ThreeElemList(
nl->SymbolAtom(Symbols::APPEND()),
append(),
resultType());
}
ListExpr DPDTypeMapper::appendDmap2() {
return replaceTypeOperator(nl->Second(dmap2),
nl->Second(nl->First(dmap2)));
}
ListExpr DPDTypeMapper::resultType() {
ListExpr dmap2funRes = getResultType(nl->First(dmap2));
// allowed result types are streams of tuples and
// non-stream objects
// compute the subtype of the resulting array
if(isStream()){
dmap2funRes = nl->TwoElemList(
listutils::basicSymbol<Relation>(),
nl->Second(dmap2funRes));
}
// determine the result array type
// is the origin function result is a tuple stream,
// the result will be a dfarray, otherwise a darray
return nl->TwoElemList(
isStream()?listutils::basicSymbol<distributed2::DFArray>()
:listutils::basicSymbol<distributed2::DArray>(),
dmap2funRes);
}
} // end namespace