/******************************************************************* * * DESCRIPTION: class SpecNode, VarNode and CountNode * * AUTHOR: Amir Barylko & Jorge Beyoglonian * Version 2: Daniel Rodriguez * * EMAIL: mailto://amir@dc.uba.ar * mailto://jbeyoglo@dc.uba.ar * mailto://drodrigu@dc.uba.ar * * DATE: 27/06/1998 * DATE: 13/06/1999 (v2) * *******************************************************************/ // ** include files **// #include "synnode.h" #include "neighval.h" // NeighborhoodValue #include "atomcell.h" #include "cellpos.h" // ** public data ** // const RealType RealType::TheReal; const IntType IntType::TheInt ; const BoolType BoolType::TheBool ; // ** public ** // /******************************************************************* * Method: addRule ********************************************************************/ SpecNode &SpecNode::addRule( SyntaxNode *rule, int StochasticCondition ) { Rule r; r.Node = rule; r.StochasticNode = StochasticCondition != 0 ? true: false; rules.push_back( r ) ; return *this ; } /******************************************************************* * Method: evaluate ********************************************************************/ Real RuleNode::evaluate() { if (EvalDebug().Active()) { Real aux( boolExp->evaluate() ); EvalDebug().Stream() << "Evaluate: Rule = " << (aux.IsUndefined() ? "Undefined" : (aux.value()==0 ? "False":"True")) << "\n"; EvalDebug().Stream() << "\n"; return aux; } return boolExp->evaluate(); } /******************************************************************* * Method: evaluate ********************************************************************/ Real SpecNode::evaluate() { register int total = 1, validRules = 0; register bool avise = false; Real cursorEval; if ( DebugCellRules().Active() ) total = rules.size(); RuleList::iterator cursor ; for( cursor = rules.begin() ; cursor != rules.end() && validRules < total ; cursor++ ) { cursorEval = cursor->Node->evaluate(); if (cursor->StochasticNode) anyStochastic = true; if( cursorEval.value() == 1 ) // 1 == TRUE { validRules++ ; if( validRules == 1 ) { lastDelay = static_cast(cursor->Node)->delay() ; lastValue = static_cast(cursor->Node)->value() ; } else { if( (bool)(lastValue != static_cast(cursor->Node)->value()) && !anyStochastic ) { InvalidEvaluation e( "Two rules evaluate to TRUE and the result is different!" ) ; MTHROW( e ) ; } if( (bool)(lastDelay != static_cast(cursor->Node)->delay()) && !anyStochastic ) { InvalidEvaluation e( "Two rules evaluate to TRUE and the delay is different!" ) ; MTHROW( e ) ; } if (anyStochastic && !avise) { avise = true; cout << "\nWARNING. In the stochastic model, two o more rules evaluate to TRUE.\n"; } } } else if ( cursorEval.IsUndefined() ) // Value = ? anyUndef = true; // else if ( cursorEval.value() == 0 ) // 0 = FALSE // ; } if ( validRules <= 0 && anyUndef ) { // If the evaluation of any rule is undefined then: if (elseFunction() == "") cout << "Warning! - None of the rules evaluate to True, but any evaluate to undefined.\n"; lastValue = Real::tundef; return Real::tundef; } else if ( validRules <= 0 && !anyUndef ) { // IF all the rules evaluate to FALSE and none of them // have a 'random' like function if (elseFunction() == "") { if (anyStochastic) { cout << "Warning! - None of the rules evaluate to True in the Stochastic Model.\n"; lastValue = Real::tundef; return Real::zero; } else { InvalidEvaluation e( "None of the rules evaluate to TRUE!" ) ; MTHROW( e ) ; } } else { lastValue = Real::tundef; return Real::zero; } } // If any rule evaluate to TRUE then return Real::one ; } /******************************************************************* * Method: checkType ********************************************************************/ bool SpecNode::checkType() const { RuleList::const_iterator cursor ; for( cursor = rules.begin() ; cursor != rules.end() && cursor->Node->checkType() && cursor->Node->type().isValid( BoolType::TheBool ) ; cursor++ ) ; return cursor == rules.end() ; } /******************************************************************* * Method: print ********************************************************************/ ostream &SpecNode::print( ostream &os ) { RuleList::iterator cursor ; for( cursor = rules.begin() ; cursor != rules.end() ; (*cursor++).Node->print( os ) ) ; return os ; } /******************************************************************* * Method: evaluate ********************************************************************/ Real VarNode::evaluate() { if (EvalDebug().Active()) { Real valueToReturn = SingleLocalTransAdmin::Instance().cellValue( NeighborPosition( tupla ) ).value(); EvalDebug().Stream() << "Evaluate: Cell Reference" << tupla << " = " << valueToReturn << "\n"; return valueToReturn; } return SingleLocalTransAdmin::Instance().cellValue( NeighborPosition( tupla ) ).value() ; } /******************************************************************* * Method: evaluate ********************************************************************/ Real PortRefNode::evaluate() { string name ( static_cast(portName)->getString() ); if (name == "thisport" ) name = SingleLocalTransAdmin::Instance().portSource(); if (EvalDebug().Active()) { Real valueToReturn = SingleLocalTransAdmin::Instance().portValue(name); EvalDebug().Stream() << "Evaluate: PortIn Reference(" << name << ") = " << valueToReturn << "\n"; return valueToReturn; } return SingleLocalTransAdmin::Instance().portValue(name); } /******************************************************************* * Method: evaluate ********************************************************************/ Real SendPortNode::evaluate() { string name( static_cast(portName)->getString() ); Real valor( portValue->evaluate().value() ); Time actualTime( SingleLocalTransAdmin::Instance().actualTime() ); if (EvalDebug().Active()) EvalDebug().Stream() << "Evaluate: SendToPort Reference(" << name << ", " << valor << ") at time " << SingleLocalTransAdmin::Instance().actualTime() << "\n"; const Model *am = SingleLocalTransAdmin::Instance().actualModel(); const VirtualPortList *vpl = static_cast(& (SingleLocalTransAdmin::Instance().outputPorts()) ); ((Model *) am)->sendOutput( (const Time &) actualTime, (const Port &) *getPort((VirtualPortList *) vpl, name), valor.value() ); return 0; } /******************************************************************* * Method: evaluate ********************************************************************/ Real AbsCellPosNode::evaluate() { Real aux = posIndex->evaluate(); MASSERTMSG( aux.value() < INT_MAX, "The CellPos function has a parameter greater than the maximum integer allowed" ); if (EvalDebug().Active()) EvalDebug().Stream() << "Evaluate: CellPosition(" << (int) aux.value() << ") = " << SingleLocalTransAdmin::Instance().neighborhood().centralPosition().get( (int) aux.value() ) << "\n"; return SingleLocalTransAdmin::Instance().neighborhood().centralPosition().get( (int) aux.value() ); } /******************************************************************* * Function Name: evaluate ********************************************************************/ Real CountNode::evaluate() { if (evalType == toEval) value = sn->evaluate(); register int total( 0 ) ; NeighborhoodValue *neighbors = (NeighborhoodValue *) &( SingleLocalTransAdmin::Instance().neighborhood() ) ; // mList *neighbor = neighbors->neighborList(); NeighborhoodValue::NeighborsValues_type::const_iterator cursor; cursor = neighbors->getNeighborsValues().begin(); for (; cursor != neighbors->getNeighborsValues().end() ; cursor++) { if (SingleLocalTransAdmin::Instance().cellValue( cursor->first) == value) total++; } /* for (neighbor->initCursor(); !neighbor->endCursor(); neighbor->next() ) if( SingleLocalTransAdmin::Instance().cellValue( neighbor->elementCell() ) == value ) total++ ; */ if (EvalDebug().Active()) EvalDebug().Stream() << "Evaluate: CountNode(" << value << ") = " << total << "\n"; return total ; } /******************************************************************* * Function Name: addNeighborhood ********************************************************************/ InvalidEvaluation &InvalidEvaluation::addNeighborhood( const NeighborhoodValue &neighbors ) { // Rami : to be fixed // * mList *nv; register int dimension = 0; // nv = ((NeighborhoodValue *) &neighbors)->neighborList(); // nv->initCursor(); // if ( !nv->endCursor()) // dimension = nv->elementCell().dimension(); CellPosition counter = CellPosition(dimension,0); bool overflow = false; dimension = neighbors.dimension(); MASSERTMSG( dimension >= 2, "The dimension must be >= 2"); if (dimension == 2) { addText( "The state of the Neighbours is: " ); // primero calculo el valor de 'dim' long dimXMin = 9999999, dimXMax = 0; long dimYMin = 9999999, dimYMax = 0; NeighborhoodValue::NeighborsValues_type::const_iterator cursor; cursor = neighbors.getNeighborsValues().begin(); for( ; cursor != neighbors.getNeighborsValues().end(); cursor++) { if( (cursor->first).get(DIM_WIDTH) > dimXMax) dimXMax = (cursor->first).get(DIM_WIDTH); if( (cursor->first).get(DIM_WIDTH) < dimXMin) dimXMin = (cursor->first).get(DIM_WIDTH); if( (cursor->first).get(DIM_HEIGHT) > dimYMax) dimYMax = (cursor->first).get(DIM_HEIGHT); if( (cursor->first).get(DIM_HEIGHT) < dimYMin) dimYMin = (cursor->first).get(DIM_HEIGHT); } /* for (; !nv->endCursor(); nv->next() ) { // Veo para 2 dimensiones (height, width) if ( nv->elementCell().get(DIM_WIDTH) > dimXMax ) dimXMax = nv->elementCell().get(DIM_WIDTH); if ( nv->elementCell().get(DIM_WIDTH) < dimXMin ) dimXMin = nv->elementCell().get(DIM_WIDTH); if ( nv->elementCell().get(DIM_HEIGHT) > dimYMax ) dimYMax = nv->elementCell().get(DIM_HEIGHT); if ( nv->elementCell().get(DIM_HEIGHT) < dimYMin ) dimYMin = nv->elementCell().get(DIM_HEIGHT); } */ string line("+") ; for( int i = dimXMin ; i<= dimXMax ; i++ ) for (int w = 0; w <= Impresion::Default.Width() + 1; w++) line += "-" ; line += "+" ; addText( line ) ; for( int i = dimYMin ; i<= dimYMax ; i++ ) { line = "|" ; for( int j = dimXMin; j<= dimXMax; j++ ){ nTupla nt; nt.add(i); nt.add(j); line += string( " " ); if (neighbors.isValid(nt)) line += neighbors.get( NeighborPosition(nt) ).asString(); else for (int w = 0; w < Impresion::Default.Width(); w++) line += " " ; line += " " ; } line += "|" ; addText( line ) ; } line = "+" ; for( int i = dimXMin; i<= dimXMax; i++ ) for (int w = 0; w <= Impresion::Default.Width() + 1; w++) line += "-" ; line += "+" ; addText( line ) ; } else { // Estoy en 3 o mas dimensiones NeighborhoodValue::NeighborsValues_type::const_iterator cursor; cursor = neighbors.getNeighborsValues().begin(); for(; cursor != neighbors.getNeighborsValues().end() ; cursor++) addText( (cursor->first).print() + " = " + (cursor->second).asString() ); // for (nv->initCursor(); !nv->endCursor(); nv->next() ) // addText( nv->elementCell().print() + " = " + nv->elementValue()->asString() ); } return *this ; } /******************************************************************* * Function Name: print ********************************************************************/ ostream &AbsCellPosNode::print( ostream &os ) { return os << "CellPosition " << SingleLocalTransAdmin::Instance().neighborhood().centralPosition(); }