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::string & getNodeName () 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 14 of file ExecutionFlowGraph.cpp.

14  {
15 
16  for (auto node : m_children)
17  delete node;
18  }
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 176 of file ExecutionFlowGraph.cpp.

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

35  {
36 
37  if (std::find(m_children.begin(), m_children.end(), node) == m_children.end())
38  m_children.push_back(node);
39  }
std::vector< ControlFlowNode * > m_children
All direct daughter nodes in the tree.
void concurrency::DecisionNode::addParentNode ( DecisionNode node)

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

Definition at line 28 of file ExecutionFlowGraph.cpp.

28  {
29 
30  if (std::find(m_parents.begin(), m_parents.end(), node) == m_parents.end())
31  m_parents.push_back(node);
32  }
std::vector< DecisionNode * > m_parents
XXX: CF tests. All direct parent nodes in the tree.
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 21 of file ExecutionFlowGraph.cpp.

21  {
22 
23  for (auto daughter : m_children)
24  daughter->initialize(algname_index_map);
25  }
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 42 of file ExecutionFlowGraph.cpp.

45  {
46 
47  output << std::string(recursionLevel, ' ') << m_nodeName << " (" << m_nodeIndex << ")" << ", w/ decision: "
48  << stateToString(node_decisions[m_nodeIndex]) << "(" << node_decisions[m_nodeIndex] <<")" << std::endl;
49  for (auto daughter : m_children ) {
50  daughter->printState(output,states,node_decisions,recursionLevel+2);
51  }
52  }
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.
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 154 of file ExecutionFlowGraph.cpp.

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

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

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