concurrency::DecisionNode Class Reference

#include <src/ExecutionFlowGraph.h>

Inheritance diagram for concurrency::DecisionNode:
Collaboration diagram for concurrency::DecisionNode:

Public Member Functions

 DecisionNode (ExecutionFlowGraph &graph, unsigned int nodeIndex, const std::string &name, bool modeOR, bool allPass, bool isLazy)
 Constructor. More...
 
 ~DecisionNode () override
 Destructor. More...
 
void initialize (const std::unordered_map< std::string, unsigned int > &algname_index_map) override
 Initialize. More...
 
bool accept (IGraphVisitor &visitor) override
 
bool promoteToControlReadyState (const int &slotNum, AlgsExecutionStates &states, std::vector< int > &node_decisions) const override
 XXX: CF tests. Method to set algos to CONTROLREADY, if possible. More...
 
void updateDecision (const int &slotNum, AlgsExecutionStates &states, std::vector< int > &node_decisions, const AlgorithmNode *requestor=nullptr) const override
 XXX: CF tests. More...
 
int updateState (AlgsExecutionStates &states, std::vector< int > &node_decisions) const override
 Method to set algos to CONTROLREADY, if possible. More...
 
void addParentNode (DecisionNode *node)
 XXX: CF tests. Method to add a parent node. More...
 
void addDaughterNode (ControlFlowNode *node)
 Add a daughter node. More...
 
const std::vector< ControlFlowNode * > & getDaughters () const
 
void printState (std::stringstream &output, AlgsExecutionStates &states, const std::vector< int > &node_decisions, const unsigned int &recursionLevel) const override
 Print a string representing the control flow state. More...
 
- Public Member Functions inherited from concurrency::ControlFlowNode
 ControlFlowNode (ExecutionFlowGraph &graph, unsigned int nodeIndex, const std::string &name)
 Constructor. More...
 
virtual ~ControlFlowNode ()
 Destructor. More...
 
const unsigned int & getNodeIndex () const
 XXX: CF tests. More...
 
const std::stringgetNodeName () const
 

Public Attributes

bool m_modeOR
 Whether acting as "and" (false) or "or" node (true) More...
 
bool m_allPass
 Whether always passing regardless of daughter results. More...
 
bool m_isLazy
 Whether to evaluate lazily - i.e. whether to stop once result known. More...
 
- Public Attributes inherited from concurrency::ControlFlowNode
ExecutionFlowGraphm_graph
 

Private Attributes

std::vector< ControlFlowNode * > m_children
 All direct daughter nodes in the tree. More...
 
std::vector< DecisionNode * > m_parents
 XXX: CF tests. All direct parent nodes in the tree. More...
 

Additional Inherited Members

- Protected Member Functions inherited from concurrency::ControlFlowNode
std::string stateToString (const int &stateId) const
 Translation between state id and name. More...
 
- Protected Attributes inherited from concurrency::ControlFlowNode
unsigned int m_nodeIndex
 
std::string m_nodeName
 

Detailed Description

Definition at line 86 of file ExecutionFlowGraph.h.

Constructor & Destructor Documentation

concurrency::DecisionNode::DecisionNode ( ExecutionFlowGraph graph,
unsigned int  nodeIndex,
const std::string name,
bool  modeOR,
bool  allPass,
bool  isLazy 
)
inline

Constructor.

Definition at line 89 of file ExecutionFlowGraph.h.

89  :
90  ControlFlowNode(graph, nodeIndex, name),
91  m_modeOR(modeOR), m_allPass(allPass), m_isLazy(isLazy), m_children()
92  {}
bool m_isLazy
Whether to evaluate lazily - i.e. whether to stop once result known.
std::vector< ControlFlowNode * > m_children
All direct daughter nodes in the tree.
bool m_allPass
Whether always passing regardless of daughter results.
bool m_modeOR
Whether acting as "and" (false) or "or" node (true)
ControlFlowNode(ExecutionFlowGraph &graph, unsigned int nodeIndex, const std::string &name)
Constructor.
concurrency::DecisionNode::~DecisionNode ( )
override

Destructor.

Definition at line 20 of file ExecutionFlowGraph.cpp.

21  {
22 
23  for ( auto node : m_children ) delete node;
24  }
std::vector< ControlFlowNode * > m_children
All direct daughter nodes in the tree.

Member Function Documentation

bool concurrency::DecisionNode::accept ( IGraphVisitor visitor)
overridevirtual

Implements concurrency::ControlFlowNode.

Definition at line 190 of file ExecutionFlowGraph.cpp.

191  {
192 
193  if ( visitor.visitEnter( *this ) ) {
194  bool result = visitor.visit( *this );
195  if ( result ) return visitor.visitLeave( *this );
196 
197  for ( auto child : m_children ) {
198  bool keepGoing = child->accept( visitor );
199  if ( m_isLazy && !keepGoing ) return false; // break;
200  }
201  }
202 
203  return true;
204  }
bool m_isLazy
Whether to evaluate lazily - i.e. whether to stop once result known.
std::vector< ControlFlowNode * > m_children
All direct daughter nodes in the tree.
void concurrency::DecisionNode::addDaughterNode ( ControlFlowNode node)

Add a daughter node.

Definition at line 41 of file ExecutionFlowGraph.cpp.

42  {
43 
44  if ( std::find( m_children.begin(), m_children.end(), node ) == m_children.end() ) m_children.push_back( node );
45  }
std::vector< ControlFlowNode * > m_children
All direct daughter nodes in the tree.
T find(T...args)
void concurrency::DecisionNode::addParentNode ( DecisionNode node)

XXX: CF tests. Method to add a parent node.

Definition at line 34 of file ExecutionFlowGraph.cpp.

35  {
36 
37  if ( std::find( m_parents.begin(), m_parents.end(), node ) == m_parents.end() ) m_parents.push_back( node );
38  }
std::vector< DecisionNode * > m_parents
XXX: CF tests. All direct parent nodes in the tree.
T find(T...args)
const std::vector<ControlFlowNode*>& concurrency::DecisionNode::getDaughters ( ) const
inline

Definition at line 115 of file ExecutionFlowGraph.h.

115 {return m_children;}
std::vector< ControlFlowNode * > m_children
All direct daughter nodes in the tree.
void concurrency::DecisionNode::initialize ( const std::unordered_map< std::string, unsigned int > &  algname_index_map)
overridevirtual

Initialize.

Implements concurrency::ControlFlowNode.

Definition at line 27 of file ExecutionFlowGraph.cpp.

28  {
29 
30  for ( auto daughter : m_children ) daughter->initialize( algname_index_map );
31  }
std::vector< ControlFlowNode * > m_children
All direct daughter nodes in the tree.
void concurrency::DecisionNode::printState ( std::stringstream output,
AlgsExecutionStates states,
const std::vector< int > &  node_decisions,
const unsigned int &  recursionLevel 
) const
overridevirtual

Print a string representing the control flow state.

Implements concurrency::ControlFlowNode.

Definition at line 48 of file ExecutionFlowGraph.cpp.

50  {
51 
52  output << std::string( recursionLevel, ' ' ) << m_nodeName << " (" << m_nodeIndex << ")"
53  << ", w/ decision: " << stateToString( node_decisions[m_nodeIndex] ) << "(" << node_decisions[m_nodeIndex]
54  << ")" << std::endl;
55  for ( auto daughter : m_children ) {
56  daughter->printState( output, states, node_decisions, recursionLevel + 2 );
57  }
58  }
std::vector< ControlFlowNode * > m_children
All direct daughter nodes in the tree.
T endl(T...args)
std::string stateToString(const int &stateId) const
Translation between state id and name.
STL class.
bool concurrency::DecisionNode::promoteToControlReadyState ( const int &  slotNum,
AlgsExecutionStates states,
std::vector< int > &  node_decisions 
) const
overridevirtual

XXX: CF tests. Method to set algos to CONTROLREADY, if possible.

Implements concurrency::ControlFlowNode.

Definition at line 168 of file ExecutionFlowGraph.cpp.

170  {
171  // std::cout << "REACHED DECISNODE " << m_nodeName << std::endl;
172  if ( -1 != node_decisions[m_nodeIndex] ) {
173  return true;
174  }
175 
176  for ( auto daughter : m_children ) {
177  auto res = node_decisions[daughter->getNodeIndex()];
178  if ( -1 == res ) {
179  daughter->promoteToControlReadyState( slotNum, states, node_decisions );
180  if ( m_isLazy ) return true;
181  } else if ( m_isLazy ) {
182  if ( ( false == m_modeOR && res == 0 ) || ( true == m_modeOR && res == 1 ) ) return true;
183  }
184  }
185 
186  return true;
187  }
bool m_isLazy
Whether to evaluate lazily - i.e. whether to stop once result known.
std::vector< ControlFlowNode * > m_children
All direct daughter nodes in the tree.
bool m_modeOR
Whether acting as "and" (false) or "or" node (true)
void concurrency::DecisionNode::updateDecision ( const int &  slotNum,
AlgsExecutionStates states,
std::vector< int > &  node_decisions,
const AlgorithmNode requestor = nullptr 
) const
overridevirtual

XXX: CF tests.

Implements concurrency::ControlFlowNode.

Definition at line 101 of file ExecutionFlowGraph.cpp.

103  {
104 
105  int decision = ( ( m_allPass && m_isLazy ) ? 1 : -1 );
106  bool keepGoing = true;
107  bool hasUndecidedChild = false;
108  // std::cout << "++++++++++++++++++++BEGIN(UPDATING)++++++++++++++++++++" << std::endl;
109  // std::cout << "UPDATING DAUGHTERS of DECISION NODE: " << m_nodeName << std::endl;
110 
111  for ( auto daughter : m_children ) {
112  // if lazy return once result is known already or we can't fully evaluate
113  // right now because one daughter decision is missing still
114  // std::cout << "----UPDATING DAUGHTER: " << daughter->getNodeName() << std::endl;
115  if ( m_isLazy && !keepGoing ) {
116  node_decisions[m_nodeIndex] = decision;
117  // std::cout << "STOPPING ITERATION OVER (UPDATING) DECISION NODE CHILDREN: " << m_nodeName << std::endl;
118  break;
119  // return;
120  }
121 
122  // modified
123  int& res = node_decisions[daughter->getNodeIndex()];
124  if ( -1 == res ) {
125  hasUndecidedChild = true;
126  if ( typeid( *daughter ) != typeid( concurrency::DecisionNode ) ) {
127  auto algod = (AlgorithmNode*)daughter;
128  algod->promoteToControlReadyState( slotNum, states, node_decisions );
129  bool result = algod->promoteToDataReadyState( slotNum, requestor );
130  if ( result ) keepGoing = false;
131  } else {
132  daughter->updateDecision( slotNum, states, node_decisions, requestor );
133  }
134 
135  // "and"-mode (once first result false, the overall decision is false)
136  } else if ( false == m_modeOR && res == 0 ) {
137  decision = 0;
138  keepGoing = false;
139  // "or"-mode (once first result true, the overall decision is true)
140  } else if ( true == m_modeOR && res == 1 ) {
141  decision = 1;
142  keepGoing = false;
143  }
144  }
145 
146  // what to do with yet undefined answers depends on whether AND or OR mode applies
147  if ( !hasUndecidedChild && -1 == decision ) {
148  // OR mode: all results known, and none true -> reject
149  if ( true == m_modeOR ) {
150  decision = 0;
151  // AND mode: all results known, and no false -> accept
152  } else {
153  decision = 1;
154  }
155  }
156 
157  // in all other cases I stay with previous decisions
158  node_decisions[m_nodeIndex] = decision;
159 
160  // propagate decision upwards through the decision graph
161  if ( -1 != decision )
162  for ( auto p : m_parents ) p->updateDecision( slotNum, states, node_decisions, requestor );
163 
164  // std::cout << "++++++++++++++++++++END(UPDATING)++++++++++++++++++++" << std::endl;
165  }
bool m_isLazy
Whether to evaluate lazily - i.e. whether to stop once result known.
std::vector< DecisionNode * > m_parents
XXX: CF tests. All direct parent nodes in the tree.
std::vector< ControlFlowNode * > m_children
All direct daughter nodes in the tree.
bool m_allPass
Whether always passing regardless of daughter results.
bool m_modeOR
Whether acting as "and" (false) or "or" node (true)
int concurrency::DecisionNode::updateState ( AlgsExecutionStates states,
std::vector< int > &  node_decisions 
) const
overridevirtual

Method to set algos to CONTROLREADY, if possible.

Implements concurrency::ControlFlowNode.

Definition at line 61 of file ExecutionFlowGraph.cpp.

62  {
63  // check whether we already had a result earlier
64  // if (-1 != node_decisions[m_nodeIndex] ) { return node_decisions[m_nodeIndex]; }
65  int decision = ( ( m_allPass && m_isLazy ) ? 1 : -1 );
66  bool hasUndecidedChild = false;
67  for ( auto daughter : m_children ) {
68  if ( m_isLazy && ( -1 != decision || hasUndecidedChild ) ) {
69  node_decisions[m_nodeIndex] = decision;
70  return decision;
71  } // if lazy return once result is known already or we can't fully evaluate right now because one daugther
72  // decision is missing still
73  auto res = daughter->updateState( states, node_decisions );
74  if ( -1 == res ) {
75  hasUndecidedChild = true;
76  } else if ( false == m_modeOR && res == 0 ) {
77  decision = 0;
78  } // "and"-mode (once first result false, the overall decision is false)
79  else if ( true == m_modeOR && res == 1 ) {
80  decision = 1;
81  } // "or"-mode (once first result true, the overall decision is true)
82  }
83  // what to do with yet undefined answers depends on whether AND or OR mode applies
84  if ( !hasUndecidedChild && -1 == decision ) {
85  // OR mode: all results known, and none true -> reject
86  if ( true == m_modeOR ) {
87  decision = 0;
88  }
89  // AND mode: all results known, and no false -> accept
90  else {
91  decision = 1;
92  }
93  }
94  // in all other cases I stay with previous decisions
95  node_decisions[m_nodeIndex] = decision;
96  if ( m_allPass ) decision = 1;
97  return decision;
98  }
bool m_isLazy
Whether to evaluate lazily - i.e. whether to stop once result known.
std::vector< ControlFlowNode * > m_children
All direct daughter nodes in the tree.
bool m_allPass
Whether always passing regardless of daughter results.
bool m_modeOR
Whether acting as "and" (false) or "or" node (true)

Member Data Documentation

bool concurrency::DecisionNode::m_allPass

Whether always passing regardless of daughter results.

Definition at line 125 of file ExecutionFlowGraph.h.

std::vector<ControlFlowNode*> concurrency::DecisionNode::m_children
private

All direct daughter nodes in the tree.

Definition at line 130 of file ExecutionFlowGraph.h.

bool concurrency::DecisionNode::m_isLazy

Whether to evaluate lazily - i.e. whether to stop once result known.

Definition at line 127 of file ExecutionFlowGraph.h.

bool concurrency::DecisionNode::m_modeOR

Whether acting as "and" (false) or "or" node (true)

Definition at line 123 of file ExecutionFlowGraph.h.

std::vector<DecisionNode*> concurrency::DecisionNode::m_parents
private

XXX: CF tests. All direct parent nodes in the tree.

Definition at line 132 of file ExecutionFlowGraph.h.


The documentation for this class was generated from the following files: