souffle  2.0.2-371-g6315b36
Public Member Functions | Static Public Attributes | Private Member Functions | Private Attributes
souffle::ast::analysis::TopologicallySortedSCCGraphAnalysis Class Reference

Analysis pass computing a topologically sorted strongly connected component (SCC) graph. More...

#include <TopologicallySortedSCCGraph.h>

Inheritance diagram for souffle::ast::analysis::TopologicallySortedSCCGraphAnalysis:
Inheritance graph
Collaboration diagram for souffle::ast::analysis::TopologicallySortedSCCGraphAnalysis:
Collaboration graph

Public Member Functions

size_t indexOfScc (const size_t scc) const
 
std::set< size_t > indexOfScc (const std::set< size_t > &sccs) const
 
const std::vector< size_t > & order () const
 
void print (std::ostream &os) const override
 Output topologically sorted strongly connected component graph in text format. More...
 
void run (const TranslationUnit &translationUnit) override
 run analysis for a Ast translation unit More...
 
size_t sccOfIndex (const size_t index) const
 
 TopologicallySortedSCCGraphAnalysis ()
 
- Public Member Functions inherited from souffle::ast::analysis::Analysis
 Analysis (std::string identifier)
 
virtual const std::string & getName () const
 get name of the analysis More...
 
virtual ~Analysis ()=default
 

Static Public Attributes

static constexpr const char * name = "topological-scc-graph"
 

Private Member Functions

void computeTopologicalOrdering (size_t scc, std::vector< bool > &visited)
 Recursive component for the forwards algorithm computing the topological ordering of the SCCs. More...
 
int topologicalOrderingCost (const std::vector< size_t > &permutationOfSCCs) const
 Calculate the topological ordering cost of a permutation of as of yet unordered SCCs using the ordered SCCs. More...
 

Private Attributes

SCCGraphAnalysissccGraph = nullptr
 The strongly connected component (SCC) graph. More...
 
std::vector< size_t > sccOrder
 The final topological ordering of the SCCs. More...
 

Additional Inherited Members

- Protected Attributes inherited from souffle::ast::analysis::Analysis
const std::string identifier
 

Detailed Description

Analysis pass computing a topologically sorted strongly connected component (SCC) graph.

Definition at line 49 of file TopologicallySortedSCCGraph.h.

Constructor & Destructor Documentation

◆ TopologicallySortedSCCGraphAnalysis()

souffle::ast::analysis::TopologicallySortedSCCGraphAnalysis::TopologicallySortedSCCGraphAnalysis ( )
inline

Definition at line 53 of file TopologicallySortedSCCGraph.h.

53 {

References sccOrder.

Member Function Documentation

◆ computeTopologicalOrdering()

void souffle::ast::analysis::TopologicallySortedSCCGraphAnalysis::computeTopologicalOrdering ( size_t  scc,
std::vector< bool > &  visited 
)
private

Recursive component for the forwards algorithm computing the topological ordering of the SCCs.

Definition at line 77 of file TopologicallySortedSCCGraph.cpp.

77  {
78  continue;
79  }
80  hasUnvisitedPredecessor = false;
81  const auto& successorsPredecessors = sccGraph->getPredecessorSCCs(scc_i);
82  for (const auto scc_j : successorsPredecessors) {
83  if (!visited[scc_j]) {
84  hasUnvisitedPredecessor = true;
85  break;
86  }
87  }
88  if (!hasUnvisitedPredecessor) {
89  // give it a temporary marking
90  visited[scc_i] = true;
91  // add it to the permanent ordering
92  sccOrder.push_back(scc_i);
93  // and use it as a root node in a recursive call to this function
94  computeTopologicalOrdering(scc_i, visited);
95  // finally, indicate that a successor has been found for this node
96  found = true;
97  }
98  }
99  // return at once if no valid successors have been found; as either it has none or they all have a
100  // better predecessor
101  if (!found) {
102  return;
103  }
104  hasUnvisitedPredecessor = false;
105  const auto& predecessors = sccGraph->getPredecessorSCCs(scc);
106  for (const auto scc_j : predecessors) {
107  if (!visited[scc_j]) {
108  hasUnvisitedPredecessor = true;
109  break;
110  }
111  }
112  hasUnvisitedSuccessor = false;
113  const auto& successors = sccGraph->getSuccessorSCCs(scc);
114  for (const auto scc_j : successors) {
115  if (!visited[scc_j]) {
116  hasUnvisitedSuccessor = true;
117  break;
118  }
119  }
120  // otherwise, if more white successors remain for the current scc, use it again as the root node in a
121  // recursive call to this function
122  if (hasUnvisitedSuccessor && !hasUnvisitedPredecessor) {
123  computeTopologicalOrdering(scc, visited);
124  }
125 }
126 
127 void TopologicallySortedSCCGraphAnalysis::run(const TranslationUnit& translationUnit) {
128  // obtain the scc graph
129  sccGraph = translationUnit.getAnalysis<SCCGraphAnalysis>();
130  // clear the list of ordered sccs
131  sccOrder.clear();
132  std::vector<bool> visited;
133  visited.resize(sccGraph->getNumberOfSCCs());

Referenced by run().

◆ indexOfScc() [1/2]

size_t souffle::ast::analysis::TopologicallySortedSCCGraphAnalysis::indexOfScc ( const size_t  scc) const
inline

Definition at line 65 of file TopologicallySortedSCCGraph.h.

65  : sccs) {
66  indices.insert(indexOfScc(scc));
67  }
68  return indices;
69  }

◆ indexOfScc() [2/2]

std::set<size_t> souffle::ast::analysis::TopologicallySortedSCCGraphAnalysis::indexOfScc ( const std::set< size_t > &  sccs) const
inline

Definition at line 71 of file TopologicallySortedSCCGraph.h.

74  :
75  /** The strongly connected component (SCC) graph. */
76  SCCGraphAnalysis* sccGraph = nullptr;
77 

◆ order()

const std::vector<size_t>& souffle::ast::analysis::TopologicallySortedSCCGraphAnalysis::order ( ) const
inline

Definition at line 57 of file TopologicallySortedSCCGraph.h.

57  {
58  auto it = std::find(sccOrder.begin(), sccOrder.end(), scc);
59  assert(it != sccOrder.end());

References sccOrder.

Referenced by souffle::ast::analysis::RelationScheduleAnalysis::run().

◆ print()

void souffle::ast::analysis::TopologicallySortedSCCGraphAnalysis::print ( std::ostream &  os) const
overridevirtual

Output topologically sorted strongly connected component graph in text format.

Reimplemented from souffle::ast::analysis::Analysis.

Definition at line 159 of file TopologicallySortedSCCGraph.cpp.

160  : successorSccs) {
161  const auto successorSccIndex = *std::find(sccOrder.begin(), sccOrder.end(), successorScc);
162  os << sccIndex << " " << successorSccIndex << std::endl;
163  }
164  }
165  os << "--- total order with relations of each strata ---" << std::endl;
166  for (size_t i = 0; i < sccOrder.size(); i++) {
167  os << i << ": [";
169  [](std::ostream& out, const Relation* rel) { out << rel->getQualifiedName(); });
170  os << "]" << std::endl;
171  }
172  os << std::endl;
173  os << "--- statistics of topological order ---" << std::endl;
174  os << "cost: " << topologicalOrderingCost(sccOrder) << std::endl;
175 }
176 
177 } // namespace souffle::ast::analysis

◆ run()

void souffle::ast::analysis::TopologicallySortedSCCGraphAnalysis::run ( const TranslationUnit )
overridevirtual

run analysis for a Ast translation unit

Implements souffle::ast::analysis::Analysis.

Definition at line 135 of file TopologicallySortedSCCGraph.cpp.

137  {
138  // if that scc has no predecessors
139  if (sccGraph->getPredecessorSCCs(scc).empty()) {
140  // put it in the ordering
141  sccOrder.push_back(scc);
142  visited[scc] = true;
143  // if the scc has successors
144  if (!sccGraph->getSuccessorSCCs(scc).empty()) {
145  computeTopologicalOrdering(scc, visited);
146  }
147  }
148  }
149 }
150 
151 void TopologicallySortedSCCGraphAnalysis::print(std::ostream& os) const {
152  os << "--- partial order of strata as list of pairs ---" << std::endl;
153  for (size_t sccIndex = 0; sccIndex < sccOrder.size(); sccIndex++) {
154  const auto& successorSccs = sccGraph->getSuccessorSCCs(sccOrder.at(sccIndex));
155  // use a self-loop to indicate that an SCC has no successors or predecessors
156  if (successorSccs.empty() && sccGraph->getPredecessorSCCs(sccOrder.at(sccIndex)).empty()) {
157  os << sccIndex << " " << sccIndex << std::endl;

References computeTopologicalOrdering(), souffle::ast::analysis::SCCGraphAnalysis::getPredecessorSCCs(), souffle::ast::analysis::SCCGraphAnalysis::getSuccessorSCCs(), sccGraph, and sccOrder.

Here is the call graph for this function:

◆ sccOfIndex()

size_t souffle::ast::analysis::TopologicallySortedSCCGraphAnalysis::sccOfIndex ( const size_t  index) const
inline

Definition at line 61 of file TopologicallySortedSCCGraph.h.

63  {

◆ topologicalOrderingCost()

int souffle::ast::analysis::TopologicallySortedSCCGraphAnalysis::topologicalOrderingCost ( const std::vector< size_t > &  permutationOfSCCs) const
private

Calculate the topological ordering cost of a permutation of as of yet unordered SCCs using the ordered SCCs.

Returns -1 if the given vector is not a valid topological ordering.

Definition at line 39 of file TopologicallySortedSCCGraph.cpp.

39  {
40  // if the index of the current scc is after the end of the ordered partition
41  if (it_i >= it_k) {
42  // check that the index of all predecessor sccs of are before the index of the current scc
43  for (auto scc : sccGraph->getPredecessorSCCs(*it_i)) {
44  if (std::find(permutationOfSCCs.begin(), it_i, scc) == it_i) {
45  // if not, the sort is not a valid topological sort
46  return -1;
47  }
48  }
49  }
50  // otherwise, calculate the cost of the current scc
51  // as the number of sccs with an index before the current scc
52  for (auto it_j = permutationOfSCCs.begin(); it_j != it_i; ++it_j) {
53  // having some successor scc with an index after the current scc
54  for (auto scc : sccGraph->getSuccessorSCCs(*it_j)) {
55  if (std::find(permutationOfSCCs.begin(), it_i, scc) == it_i) {
56  costOfSCC++;
57  }
58  }
59  }
60  // and if this cost is greater than the maximum recorded cost for the whole permutation so far,
61  // set the cost of the permutation to it
62  if (costOfSCC > costOfPermutation) {
63  costOfPermutation = costOfSCC;
64  }
65  }
66  return costOfPermutation;
67 }
68 
69 void TopologicallySortedSCCGraphAnalysis::computeTopologicalOrdering(size_t scc, std::vector<bool>& visited) {
70  // create a flag to indicate that a successor was visited (by default it hasn't been)
71  bool found = false;
72  bool hasUnvisitedSuccessor = false;
73  bool hasUnvisitedPredecessor = false;
74  // for each successor of the input scc
75  const auto& successorsToVisit = sccGraph->getSuccessorSCCs(scc);

References souffle::ast::analysis::SCCGraphAnalysis::getPredecessorSCCs(), souffle::ast::analysis::SCCGraphAnalysis::getSuccessorSCCs(), and sccGraph.

Here is the call graph for this function:

Field Documentation

◆ name

constexpr const char* souffle::ast::analysis::TopologicallySortedSCCGraphAnalysis::name = "topological-scc-graph"
staticconstexpr

Definition at line 51 of file TopologicallySortedSCCGraph.h.

◆ sccGraph

SCCGraphAnalysis* souffle::ast::analysis::TopologicallySortedSCCGraphAnalysis::sccGraph = nullptr
private

The strongly connected component (SCC) graph.

Definition at line 84 of file TopologicallySortedSCCGraph.h.

Referenced by run(), and topologicalOrderingCost().

◆ sccOrder

std::vector<size_t> souffle::ast::analysis::TopologicallySortedSCCGraphAnalysis::sccOrder
private

The final topological ordering of the SCCs.

Definition at line 87 of file TopologicallySortedSCCGraph.h.

Referenced by order(), run(), and TopologicallySortedSCCGraphAnalysis().


The documentation for this class was generated from the following files:
souffle::ast::analysis::TopologicallySortedSCCGraphAnalysis::sccGraph
SCCGraphAnalysis * sccGraph
The strongly connected component (SCC) graph.
Definition: TopologicallySortedSCCGraph.h:84
souffle::ast::analysis::TopologicallySortedSCCGraphAnalysis::print
void print(std::ostream &os) const override
Output topologically sorted strongly connected component graph in text format.
Definition: TopologicallySortedSCCGraph.cpp:159
i
size_t i
Definition: json11.h:663
souffle::join
detail::joined_sequence< Iter, Printer > join(const Iter &a, const Iter &b, const std::string &sep, const Printer &p)
Creates an object to be forwarded to some output stream for printing sequences of elements interspers...
Definition: StreamUtil.h:175
souffle::ast::analysis::SCCGraphAnalysis::getNumberOfSCCs
size_t getNumberOfSCCs() const
Get the number of SCCs in the graph.
Definition: SCCGraph.h:59
souffle::ast::analysis::TopologicallySortedSCCGraphAnalysis::sccOrder
std::vector< size_t > sccOrder
The final topological ordering of the SCCs.
Definition: TopologicallySortedSCCGraph.h:87
souffle::ast::analysis::TopologicallySortedSCCGraphAnalysis::topologicalOrderingCost
int topologicalOrderingCost(const std::vector< size_t > &permutationOfSCCs) const
Calculate the topological ordering cost of a permutation of as of yet unordered SCCs using the ordere...
Definition: TopologicallySortedSCCGraph.cpp:39
souffle::ast::analysis::TopologicallySortedSCCGraphAnalysis::indexOfScc
size_t indexOfScc(const size_t scc) const
Definition: TopologicallySortedSCCGraph.h:65
souffle::ast::analysis::TopologicallySortedSCCGraphAnalysis::computeTopologicalOrdering
void computeTopologicalOrdering(size_t scc, std::vector< bool > &visited)
Recursive component for the forwards algorithm computing the topological ordering of the SCCs.
Definition: TopologicallySortedSCCGraph.cpp:77
souffle::ast::analysis::SCCGraphAnalysis::getSuccessorSCCs
const std::set< size_t > & getSuccessorSCCs(const size_t scc) const
Get all successor SCCs of a given SCC.
Definition: SCCGraph.h:69
souffle::ast::analysis::SCCGraphAnalysis::getPredecessorSCCs
const std::set< size_t > & getPredecessorSCCs(const size_t scc) const
Get all predecessor SCCs of a given SCC.
Definition: SCCGraph.h:74
rel
void rel(size_t limit, bool showLimit=true)
Definition: Tui.h:1086
souffle::ast::analysis::SCCGraphAnalysis::getInternalRelations
const std::set< const Relation * > & getInternalRelations(const size_t scc) const
Get all internal relations of a given SCC.
Definition: SCCGraph.h:105
souffle::ast::analysis::TopologicallySortedSCCGraphAnalysis::run
void run(const TranslationUnit &translationUnit) override
run analysis for a Ast translation unit
Definition: TopologicallySortedSCCGraph.cpp:135