souffle  2.0.2-371-g6315b36
ExecutionPlanChecker.cpp
Go to the documentation of this file.
1 /*
2  * Souffle - A Datalog Compiler
3  * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved
4  * Licensed under the Universal Permissive License v 1.0 as shown at:
5  * - https://opensource.org/licenses/UPL
6  * - <souffle root>/licenses/SOUFFLE-UPL.txt
7  */
8 
9 /************************************************************************
10  *
11  * @file ExecutionPlanChecker.cpp
12  *
13  * Implementation of the execution plan checker pass.
14  *
15  ***********************************************************************/
16 
18 #include "ast/Atom.h"
19 #include "ast/Clause.h"
20 #include "ast/ExecutionOrder.h"
21 #include "ast/ExecutionPlan.h"
22 #include "ast/Relation.h"
23 #include "ast/TranslationUnit.h"
26 #include "ast/utility/Utils.h"
27 #include "reports/ErrorReport.h"
28 #include <algorithm>
29 #include <map>
30 #include <set>
31 #include <utility>
32 #include <vector>
33 
34 namespace souffle::ast::transform {
35 
36 bool ExecutionPlanChecker::transform(TranslationUnit& translationUnit) {
37  auto* relationSchedule = translationUnit.getAnalysis<analysis::RelationScheduleAnalysis>();
38  auto* recursiveClauses = translationUnit.getAnalysis<analysis::RecursiveClausesAnalysis>();
39  auto&& report = translationUnit.getErrorReport();
40 
41  Program& program = translationUnit.getProgram();
42  for (const analysis::RelationScheduleAnalysisStep& step : relationSchedule->schedule()) {
43  const std::set<const Relation*>& scc = step.computed();
44  for (const Relation* rel : scc) {
45  for (const Clause* clause : getClauses(program, *rel)) {
46  if (!recursiveClauses->recursive(clause)) {
47  continue;
48  }
49  if (clause->getExecutionPlan() == nullptr) {
50  continue;
51  }
52  int version = 0;
53  for (const auto* atom : getBodyLiterals<Atom>(*clause)) {
54  if (scc.count(getAtomRelation(atom, &program)) != 0u) {
55  version++;
56  }
57  }
58  int maxVersion = -1;
59  for (auto const& cur : clause->getExecutionPlan()->getOrders()) {
60  maxVersion = std::max(cur.first, maxVersion);
61  }
62 
63  if (version <= maxVersion) {
64  for (const auto& cur : clause->getExecutionPlan()->getOrders()) {
65  if (cur.first >= version) {
66  report.addDiagnostic(Diagnostic(Diagnostic::Type::ERROR,
68  "execution plan for version " + std::to_string(cur.first),
69  cur.second->getSrcLoc()),
70  {DiagnosticMessage("only versions 0.." + std::to_string(version - 1) +
71  " permitted")}));
72  }
73  }
74  }
75  }
76  }
77  }
78  return false;
79 }
80 
81 } // namespace souffle::ast::transform
RelationSchedule.h
TranslationUnit.h
RecursiveClauses.h
ExecutionPlan.h
souffle::ast::Relation
Defines a relation with a name, attributes, qualifiers, and internal representation.
Definition: Relation.h:49
souffle::ast::Clause
Intermediate representation of a horn clause.
Definition: Clause.h:51
souffle::DiagnosticMessage
Definition: ErrorReport.h:37
Relation.h
Utils.h
Atom.h
souffle::Diagnostic
Definition: ErrorReport.h:76
souffle::Diagnostic::Type::ERROR
@ ERROR
souffle::ast::transform
Definition: Program.h:45
ExecutionOrder.h
souffle::ast::getClauses
std::vector< Clause * > getClauses(const Program &program, const QualifiedName &relationName)
Returns a vector of clauses in the program describing the relation with the given name.
Definition: Utils.cpp:77
souffle::ast::transform::ExecutionPlanChecker::transform
bool transform(TranslationUnit &translationUnit) override
Definition: ExecutionPlanChecker.cpp:42
Clause.h
souffle::ast::analysis::RelationScheduleAnalysisStep
A single step in a relation schedule, consisting of the relations computed in the step and the relati...
Definition: RelationSchedule.h:46
souffle::ast::getAtomRelation
const Relation * getAtomRelation(const Atom *atom, const Program *program)
Returns the relation referenced by the given atom.
Definition: Utils.cpp:129
rel
void rel(size_t limit, bool showLimit=true)
Definition: Tui.h:1086
ExecutionPlanChecker.h
ErrorReport.h