souffle  2.0.2-371-g6315b36
UniqueAggregationVariables.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 UniqueAggregationVariables.cpp
12  *
13  ***********************************************************************/
14 
16 #include "ast/Aggregator.h"
17 #include "ast/Argument.h"
18 #include "ast/Program.h"
19 #include "ast/TranslationUnit.h"
20 #include "ast/Variable.h"
21 #include "ast/analysis/Aggregate.h"
22 #include "ast/utility/Visitor.h"
24 #include <set>
25 #include <vector>
26 
27 namespace souffle::ast::transform {
28 
29 /**
30  * Renames all local variables of the aggregate to something unique, so that
31  * the scope of the local variable is limited to the body of the aggregate subclause.
32  * This assumes that we have simplified the target expression to a target variable.
33  **/
34 bool UniqueAggregationVariablesTransformer::transform(TranslationUnit& translationUnit) {
35  bool changed = false;
36 
37  // make variables in aggregates unique
38  visitDepthFirst(translationUnit.getProgram(), [&](const Clause& clause) {
39  // find out if the target expression variable occurs elsewhere in the rule. If so, rename it
40  // to avoid naming conflicts
41  visitDepthFirst(clause, [&](const Aggregator& agg) {
42  // get the set of local variables in this aggregate and rename
43  // those that occur outside the aggregate
44  std::set<std::string> localVariables = analysis::getLocalVariables(translationUnit, clause, agg);
45  std::set<std::string> variablesOutsideAggregate =
46  analysis::getVariablesOutsideAggregate(clause, agg);
47  for (const std::string& name : localVariables) {
48  if (variablesOutsideAggregate.find(name) != variablesOutsideAggregate.end()) {
49  // then this MUST be renamed to avoid scoping issues
50  std::string uniqueName = analysis::findUniqueVariableName(clause, name);
51  visitDepthFirst(agg, [&](const Variable& var) {
52  if (var.getName() == name) {
53  const_cast<Variable&>(var).setName(uniqueName);
54  changed = true;
55  }
56  });
57  }
58  }
59  });
60  });
61  return changed;
62 }
63 
64 } // namespace souffle::ast::transform
TranslationUnit.h
souffle::ast::transform::UniqueAggregationVariablesTransformer::transform
bool transform(TranslationUnit &translationUnit) override
Renames all local variables of the aggregate to something unique, so that the scope of the local vari...
Definition: UniqueAggregationVariables.cpp:38
souffle::ast::Clause
Intermediate representation of a horn clause.
Definition: Clause.h:51
Aggregate.h
Argument.h
StringUtil.h
souffle::ast::transform
Definition: Program.h:45
Aggregator.h
Program.h
Visitor.h
UniqueAggregationVariables.h
souffle::ast::visitDepthFirst
void visitDepthFirst(const Node &root, Visitor< R, Ps... > &visitor, Args &... args)
A utility function visiting all nodes within the ast rooted by the given node recursively in a depth-...
Definition: Visitor.h:273
Variable.h