-
Notifications
You must be signed in to change notification settings - Fork 211
/
Copy pathPrecedenceGraph.cpp
89 lines (79 loc) · 2.81 KB
/
PrecedenceGraph.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/*
* Souffle - A Datalog Compiler
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved
* Licensed under the Universal Permissive License v 1.0 as shown at:
* - https://opensource.org/licenses/UPL
* - <souffle root>/licenses/SOUFFLE-UPL.txt
*/
/************************************************************************
*
* @file PrecedenceGraph.cpp
*
* Implements method of precedence graph to build the precedence graph,
* compute strongly connected components of the precedence graph, and
* build the strongly connected component graph.
*
***********************************************************************/
#include "ast/analysis/PrecedenceGraph.h"
#include "GraphUtils.h"
#include "ast/Argument.h"
#include "ast/Atom.h"
#include "ast/Clause.h"
#include "ast/Literal.h"
#include "ast/Program.h"
#include "ast/QualifiedName.h"
#include "ast/Relation.h"
#include "ast/TranslationUnit.h"
#include "ast/utility/Visitor.h"
#include <set>
#include <string>
#include <vector>
namespace souffle::ast::analysis {
void PrecedenceGraphAnalysis::run(const TranslationUnit& translationUnit) {
/* Get relations */
Program& program = translationUnit.getProgram();
for (const auto* r : program.getRelations()) {
backingGraph.insert(r);
auto addEdgeToR = [&](const Atom& atom) { backingGraph.insert(program.getRelation(atom), r); };
for (auto&& c : program.getClauses(*r)) {
souffle::visit(c->getHead()->getArguments(), addEdgeToR);
auto literals = c->getBodyLiterals();
for (std::size_t i = as<SubsumptiveClause>(c) ? 2 : 0; i < literals.size(); i++) {
souffle::visit(literals[i], addEdgeToR);
}
}
}
}
void PrecedenceGraphAnalysis::printRaw(std::stringstream& ss) const {
/* Print dependency graph */
ss << "digraph {\n";
/* Print node of dependence graph */
for (const Relation* rel : backingGraph.vertices()) {
if (rel != nullptr) {
ss << "\t\"" << rel->getQualifiedName() << "\" [label = \"" << rel->getQualifiedName()
<< "\"];\n";
}
}
for (const Relation* rel : backingGraph.vertices()) {
if (rel != nullptr) {
for (const Relation* adjRel : backingGraph.successors(rel)) {
if (adjRel != nullptr) {
ss << "\t\"" << rel->getQualifiedName() << "\" -> \"" << adjRel->getQualifiedName()
<< "\";\n";
}
}
}
}
ss << "}\n";
}
void PrecedenceGraphAnalysis::print(std::ostream& os) const {
std::stringstream ss;
printRaw(ss);
os << ss.str();
}
void PrecedenceGraphAnalysis::printHTML(std::ostream& os) const {
std::stringstream ss;
printRaw(ss);
printHTMLGraph(os, ss.str(), getName());
}
} // namespace souffle::ast::analysis