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...
 
virtual ~DecisionNode ()
 Destructor. More...
 
virtual void initialize (const std::unordered_map< std::string, unsigned int > &algname_index_map)
 Initialize. More...
 
virtual bool accept (IGraphVisitor &visitor)
 
virtual bool promoteToControlReadyState (const int &slotNum, AlgsExecutionStates &states, std::vector< int > &node_decisions) const
 XXX: CF tests. Method to set algos to CONTROLREADY, if possible. More...
 
virtual void updateDecision (const int &slotNum, AlgsExecutionStates &states, std::vector< int > &node_decisions, const AlgorithmNode *requestor=nullptr) const
 XXX: CF tests. More...
 
virtual int updateState (AlgsExecutionStates &states, std::vector< int > &node_decisions) const
 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
 
virtual void printState (std::stringstream &output, AlgsExecutionStates &states, const std::vector< int > &node_decisions, const unsigned int &recursionLevel) const
 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 ( )
virtual

Destructor.

Definition at line 15 of file ExecutionFlowGraph.cpp.

15  {
16 
17  for (auto node : m_children)
18  delete node;
19  }
std::vector< ControlFlowNode * > m_children
All direct daughter nodes in the tree.

Member Function Documentation

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

Implements concurrency::ControlFlowNode.

Definition at line 177 of file ExecutionFlowGraph.cpp.

177  {
178 
179  if (visitor.visitEnter(*this)) {
180  bool result = visitor.visit(*this);
181  if (result)
182  return visitor.visitLeave(*this);
183 
184  for (auto child : m_children) {
185  bool keepGoing = child->accept(visitor);
186  if (m_isLazy && !keepGoing)
187  return false; //break;
188  }
189  }
190 
191  return true;
192  }
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 36 of file ExecutionFlowGraph.cpp.

36  {
37 
38  if (std::find(m_children.begin(), m_children.end(), node) == m_children.end())
39  m_children.push_back(node);
40  }
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 29 of file ExecutionFlowGraph.cpp.

29  {
30 
31  if (std::find(m_parents.begin(), m_parents.end(), node) == m_parents.end())
32  m_parents.push_back(node);
33  }
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)
virtual

Initialize.

Implements concurrency::ControlFlowNode.

Definition at line 22 of file ExecutionFlowGraph.cpp.

22  {
23 
24  for (auto daughter : m_children)
25  daughter->initialize(algname_index_map);
26  }
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
virtual

Print a string representing the control flow state.

Implements concurrency::ControlFlowNode.

Definition at line 43 of file ExecutionFlowGraph.cpp.

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

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

Implements concurrency::ControlFlowNode.

Definition at line 155 of file ExecutionFlowGraph.cpp.

157  {
158  //std::cout << "REACHED DECISNODE " << m_nodeName << std::endl;
159  if (-1 != node_decisions[m_nodeIndex]) {
160  return true;
161  }
162 
163  for (auto daughter : m_children ) {
164  auto res = node_decisions[daughter->getNodeIndex()];
165  if (-1 == res) {
166  daughter->promoteToControlReadyState(slotNum, states, node_decisions);
167  if (m_isLazy) return true;
168  } else if (m_isLazy) {
169  if ((false == m_modeOR && res == 0) || (true == m_modeOR && res == 1)) return true;
170  }
171  }
172 
173  return true;
174  }
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
virtual

XXX: CF tests.

Implements concurrency::ControlFlowNode.

Definition at line 85 of file ExecutionFlowGraph.cpp.

88  {
89 
90  int decision = ((m_allPass && m_isLazy) ? 1 : -1);
91  bool keepGoing = true;
92  bool hasUndecidedChild = false;
93  //std::cout << "++++++++++++++++++++BEGIN(UPDATING)++++++++++++++++++++" << std::endl;
94  //std::cout << "UPDATING DAUGHTERS of DECISION NODE: " << m_nodeName << std::endl;
95 
96  for (auto daughter : m_children){
97  // if lazy return once result is known already or we can't fully evaluate
98  // right now because one daughter decision is missing still
99  //std::cout << "----UPDATING DAUGHTER: " << daughter->getNodeName() << std::endl;
100  if (m_isLazy && !keepGoing) {
101  node_decisions[m_nodeIndex] = decision;
102  //std::cout << "STOPPING ITERATION OVER (UPDATING) DECISION NODE CHILDREN: " << m_nodeName << std::endl;
103  break;
104  //return;
105  }
106 
107  // modified
108  int& res = node_decisions[daughter->getNodeIndex()];
109  if (-1 == res) {
110  hasUndecidedChild = true;
111  if (typeid(*daughter) != typeid(concurrency::DecisionNode)) {
112  auto algod = (AlgorithmNode*) daughter;
113  algod->promoteToControlReadyState(slotNum,states,node_decisions);
114  bool result = algod->promoteToDataReadyState(slotNum, requestor);
115  if (result)
116  keepGoing = false;
117  } else {
118  daughter->updateDecision(slotNum, states, node_decisions, requestor);
119  }
120 
121  // "and"-mode (once first result false, the overall decision is false)
122  } else if (false == m_modeOR && res == 0) {
123  decision = 0;
124  keepGoing = false;
125  // "or"-mode (once first result true, the overall decision is true)
126  } else if (true == m_modeOR && res == 1) {
127  decision = 1;
128  keepGoing = false;
129  }
130  }
131 
132  // what to do with yet undefined answers depends on whether AND or OR mode applies
133  if (!hasUndecidedChild && -1 == decision ) {
134  // OR mode: all results known, and none true -> reject
135  if ( true == m_modeOR) {
136  decision = 0;
137  // AND mode: all results known, and no false -> accept
138  } else {
139  decision = 1;
140  }
141  }
142 
143  // in all other cases I stay with previous decisions
144  node_decisions[m_nodeIndex] = decision;
145 
146  // propagate decision upwards through the decision graph
147  if (-1 != decision)
148  for (auto p : m_parents)
149  p->updateDecision(slotNum, states, node_decisions, requestor);
150 
151  //std::cout << "++++++++++++++++++++END(UPDATING)++++++++++++++++++++" << std::endl;
152  }
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
virtual

Method to set algos to CONTROLREADY, if possible.

Implements concurrency::ControlFlowNode.

Definition at line 56 of file ExecutionFlowGraph.cpp.

57  {
58  // check whether we already had a result earlier
59  // if (-1 != node_decisions[m_nodeIndex] ) { return node_decisions[m_nodeIndex]; }
60  int decision = ((m_allPass && m_isLazy) ? 1 : -1);
61  bool hasUndecidedChild = false;
62  for (auto daughter : m_children){
63  if (m_isLazy && (-1 !=decision || hasUndecidedChild ) ) {
64  node_decisions[m_nodeIndex] = decision;
65  return decision;} // if lazy return once result is known already or we can't fully evaluate right now because one daugther decision is missing still
66  auto res = daughter->updateState(states, node_decisions);
67  if ( -1 == res) {hasUndecidedChild = true;}
68  else if ( false == m_modeOR && res == 0 ){decision = 0;} // "and"-mode (once first result false, the overall decision is false)
69  else if ( true == m_modeOR && res == 1){decision = 1;} // "or"-mode (once first result true, the overall decision is true)
70  }
71  // what to do with yet undefined answers depends on whether AND or OR mode applies
72  if (!hasUndecidedChild && -1 == decision ) {
73  // OR mode: all results known, and none true -> reject
74  if ( true == m_modeOR){ decision = 0; }
75  // AND mode: all results known, and no false -> accept
76  else { decision = 1; }
77  }
78  // in all other cases I stay with previous decisions
79  node_decisions[m_nodeIndex] = decision;
80  if (m_allPass) decision = 1;
81  return decision;
82  }
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: