Skip to content

Commit

Permalink
Split remaining Ast transformers
Browse files Browse the repository at this point in the history
  • Loading branch information
mmcgr committed Aug 1, 2020
1 parent ade059d commit 46a4d84
Show file tree
Hide file tree
Showing 14 changed files with 469 additions and 183 deletions.
23 changes: 15 additions & 8 deletions src/Makefile.am
Expand Up @@ -158,22 +158,18 @@ souffle_sources = \
ast/analysis/TopologicallySortedSCCGraph.h \
ast/transform/ComponentChecker.cpp \
ast/transform/ComponentChecker.h \
ast/transform/PragmaChecker.cpp \
ast/transform/PragmaChecker.h \
ast/transform/SemanticChecker.cpp \
ast/transform/SemanticChecker.h \
ast/transform/Transformer.cpp \
ast/transform/Transformer.h \
ast/transform/UserDefinedFunctors.cpp \
ast/transform/UserDefinedFunctors.h \
ast/transform/ComponentInstantiation.cpp \
ast/transform/ComponentInstantiation.h \
ast/transform/Conditional.h \
ast/transform/DebugReporter.cpp \
ast/transform/DebugReporter.h \
ast/transform/ExecutionPlanChecker.cpp \
ast/transform/ExecutionPlanChecker.h \
ast/transform/Fixpoint.h \
ast/transform/FoldAnonymousRecords.cpp \
ast/transform/FoldAnonymousRecords.h \
ast/transform/GroundedTermsChecker.cpp \
ast/transform/GroundedTermsChecker.h \
ast/transform/IOAttributes.h \
ast/transform/IODefaults.h \
ast/transform/InlineRelations.cpp \
Expand All @@ -184,17 +180,22 @@ souffle_sources = \
ast/transform/MaterializeAggregationQueries.h \
ast/transform/MaterializeSingletonAggregation.cpp \
ast/transform/MaterializeSingletonAggregation.h \
ast/transform/Meta.cpp \
ast/transform/Meta.h \
ast/transform/MinimiseProgram.cpp \
ast/transform/MinimiseProgram.h \
ast/transform/NameUnnamedVariables.cpp \
ast/transform/NameUnnamedVariables.h \
ast/transform/NormaliseConstraints.cpp \
ast/transform/NormaliseConstraints.h \
ast/transform/Null.h \
ast/transform/PartitionBodyLiterals.cpp \
ast/transform/PartitionBodyLiterals.h \
ast/transform/Pipeline.h \
ast/transform/PolymorphicObjects.cpp \
ast/transform/PolymorphicObjects.h \
ast/transform/PragmaChecker.cpp \
ast/transform/PragmaChecker.h \
ast/transform/Provenance.cpp \
ast/transform/Provenance.h \
ast/transform/ReduceExistentials.cpp \
Expand All @@ -219,8 +220,14 @@ souffle_sources = \
ast/transform/ResolveAliases.h \
ast/transform/ResolveAnonymousRecordsAliases.cpp \
ast/transform/ResolveAnonymousRecordsAliases.h \
ast/transform/SemanticChecker.cpp \
ast/transform/SemanticChecker.h \
ast/transform/Transformer.cpp \
ast/transform/Transformer.h \
ast/transform/UniqueAggregationVariables.cpp \
ast/transform/UniqueAggregationVariables.h \
ast/transform/UserDefinedFunctors.cpp \
ast/transform/UserDefinedFunctors.h \
ast/transform/While.h \
interpreter/InterpreterContext.h \
interpreter/InterpreterEngine.cpp \
Expand Down
3 changes: 2 additions & 1 deletion src/ast/transform/DebugReporter.h
Expand Up @@ -15,7 +15,8 @@
***********************************************************************/
#pragma once

#include "ast/transform/Transformer.h"
#include "ast/transform/Meta.h"
#include "ast/transform/Null.h"
#include "utility/MiscUtil.h"
#include <memory>
#include <set>
Expand Down
115 changes: 115 additions & 0 deletions src/ast/transform/ExecutionPlanChecker.cpp
@@ -0,0 +1,115 @@
/*
* Souffle - A Datalog Compiler
* Copyright (c) 2015, 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 SemanticChecker.cpp
*
* Implementation of the execution plan checker pass.
*
***********************************************************************/

#include "ast/transform/ExecutionPlanChecker.h"
#include "AggregateOp.h"
#include "BinaryConstraintOps.h"
#include "ErrorReport.h"
#include "FunctorOps.h"
#include "Global.h"
#include "GraphUtils.h"
#include "RamTypes.h"
#include "RelationTag.h"
#include "SrcLocation.h"
#include "ast/Abstract.h"
#include "ast/Argument.h"
#include "ast/Attribute.h"
#include "ast/Clause.h"
#include "ast/IO.h"
#include "ast/Literal.h"
#include "ast/Node.h"
#include "ast/Program.h"
#include "ast/QualifiedName.h"
#include "ast/Relation.h"
#include "ast/TranslationUnit.h"
#include "ast/Type.h"
#include "ast/TypeSystem.h"
#include "ast/Utils.h"
#include "ast/Visitor.h"
#include "ast/analysis/Ground.h"
#include "ast/analysis/IOType.h"
#include "ast/analysis/PrecedenceGraph.h"
#include "ast/analysis/RecursiveClauses.h"
#include "ast/analysis/RelationSchedule.h"
#include "ast/analysis/SCCGraph.h"
#include "ast/analysis/Type.h"
#include "ast/analysis/TypeEnvironment.h"
#include "utility/ContainerUtil.h"
#include "utility/FunctionalUtil.h"
#include "utility/MiscUtil.h"
#include "utility/StreamUtil.h"
#include "utility/StringUtil.h"
#include "utility/tinyformat.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <functional>
#include <iostream>
#include <map>
#include <memory>
#include <optional>
#include <set>
#include <typeinfo>
#include <utility>
#include <vector>

namespace souffle {

bool AstExecutionPlanChecker::transform(AstTranslationUnit& translationUnit) {
auto* relationSchedule = translationUnit.getAnalysis<RelationScheduleAnalysis>();
auto* recursiveClauses = translationUnit.getAnalysis<RecursiveClausesAnalysis>();
auto&& report = translationUnit.getErrorReport();

for (const RelationScheduleAnalysisStep& step : relationSchedule->schedule()) {
const std::set<const AstRelation*>& scc = step.computed();
for (const AstRelation* rel : scc) {
for (const AstClause* clause : getClauses(*translationUnit.getProgram(), *rel)) {
if (!recursiveClauses->recursive(clause)) {
continue;
}
if (clause->getExecutionPlan() == nullptr) {
continue;
}
int version = 0;
for (const auto* atom : getBodyLiterals<AstAtom>(*clause)) {
if (scc.count(getAtomRelation(atom, translationUnit.getProgram())) != 0u) {
version++;
}
}
int maxVersion = -1;
for (auto const& cur : clause->getExecutionPlan()->getOrders()) {
maxVersion = std::max(cur.first, maxVersion);
}

if (version <= maxVersion) {
for (const auto& cur : clause->getExecutionPlan()->getOrders()) {
if (cur.first >= version) {
report.addDiagnostic(Diagnostic(Diagnostic::Type::ERROR,
DiagnosticMessage(
"execution plan for version " + std::to_string(cur.first),
cur.second->getSrcLoc()),
{DiagnosticMessage("only versions 0.." + std::to_string(version - 1) +
" permitted")}));
}
}
}
}
}
}
return false;
}

} // end of namespace souffle
40 changes: 40 additions & 0 deletions src/ast/transform/ExecutionPlanChecker.h
@@ -0,0 +1,40 @@
/*
* Souffle - A Datalog Compiler
* Copyright (c) 2015, 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 SemanticChecker.h
*
* Defines the execution plan checker pass.
*
***********************************************************************/

#pragma once

#include "ast/transform/Transformer.h"
#include <string>

namespace souffle {

class AstTranslationUnit;

class AstExecutionPlanChecker : public AstTransformer {
public:
std::string getName() const override {
return "AstExecutionPlanChecker";
}

AstExecutionPlanChecker* clone() const override {
return new AstExecutionPlanChecker();
}

private:
bool transform(AstTranslationUnit& translationUnit) override;
};

} // end of namespace souffle
98 changes: 98 additions & 0 deletions src/ast/transform/GroundedTermsChecker.cpp
@@ -0,0 +1,98 @@
/*
* Souffle - A Datalog Compiler
* Copyright (c) 2015, 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 SemanticChecker.cpp
*
* Implementation of the grounded terms checker pass.
*
***********************************************************************/

#include "ast/transform/GroundedTermsChecker.h"
#include "AggregateOp.h"
#include "BinaryConstraintOps.h"
#include "ErrorReport.h"
#include "FunctorOps.h"
#include "Global.h"
#include "GraphUtils.h"
#include "RamTypes.h"
#include "RelationTag.h"
#include "SrcLocation.h"
#include "ast/Abstract.h"
#include "ast/Argument.h"
#include "ast/Attribute.h"
#include "ast/Clause.h"
#include "ast/IO.h"
#include "ast/Literal.h"
#include "ast/Node.h"
#include "ast/Program.h"
#include "ast/QualifiedName.h"
#include "ast/Relation.h"
#include "ast/TranslationUnit.h"
#include "ast/Type.h"
#include "ast/TypeSystem.h"
#include "ast/Utils.h"
#include "ast/Visitor.h"
#include "ast/analysis/Ground.h"
#include "ast/analysis/IOType.h"
#include "ast/analysis/PrecedenceGraph.h"
#include "ast/analysis/RecursiveClauses.h"
#include "ast/analysis/RelationSchedule.h"
#include "ast/analysis/SCCGraph.h"
#include "ast/analysis/Type.h"
#include "ast/analysis/TypeEnvironment.h"
#include "utility/ContainerUtil.h"
#include "utility/FunctionalUtil.h"
#include "utility/MiscUtil.h"
#include "utility/StreamUtil.h"
#include "utility/StringUtil.h"
#include "utility/tinyformat.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <functional>
#include <iostream>
#include <map>
#include <memory>
#include <optional>
#include <set>
#include <typeinfo>
#include <utility>
#include <vector>

namespace souffle {

void GroundedTermsChecker::verify(AstTranslationUnit& translationUnit) {
auto&& program = *translationUnit.getProgram();
auto&& report = translationUnit.getErrorReport();

// -- check grounded variables and records --
visitDepthFirst(program.getClauses(), [&](const AstClause& clause) {
if (isFact(clause)) return; // only interested in rules

auto isGrounded = getGroundedTerms(translationUnit, clause);

std::set<std::string> reportedVars;
// all terms in head need to be grounded
for (auto&& cur : getVariables(clause)) {
if (!isGrounded[cur] && reportedVars.insert(cur->getName()).second) {
report.addError("Ungrounded variable " + cur->getName(), cur->getSrcLoc());
}
}

// all records need to be grounded
for (auto&& cur : getRecords(clause)) {
if (!isGrounded[cur]) {
report.addError("Ungrounded record", cur->getSrcLoc());
}
}
});
}

} // end of namespace souffle
46 changes: 46 additions & 0 deletions src/ast/transform/GroundedTermsChecker.h
@@ -0,0 +1,46 @@
/*
* Souffle - A Datalog Compiler
* Copyright (c) 2015, 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 SemanticChecker.h
*
* Defines the grounded terms checker pass.
*
***********************************************************************/

#pragma once

#include "ast/transform/Transformer.h"
#include <string>

namespace souffle {

class AstTranslationUnit;

class GroundedTermsChecker : public AstTransformer {
public:
std::string getName() const override {
return "GroundedTermsChecker";
}

// `apply` but doesn't immediately bail if any errors are found.
void verify(AstTranslationUnit& translationUnit);

GroundedTermsChecker* clone() const override {
return new GroundedTermsChecker();
}

private:
bool transform(AstTranslationUnit& translationUnit) override {
verify(translationUnit);
return false;
}
};

} // end of namespace souffle

0 comments on commit 46a4d84

Please sign in to comment.