souffle  2.0.2-371-g6315b36
ReplaceSingletonVariables.cpp
Go to the documentation of this file.
1 /*
2  * Souffle - A Datalog Compiler
3  * Copyright (c) 2018, The Souffle Developers. 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 ReplaceSingletonVariables.cpp
12  *
13  ***********************************************************************/
14 
16 #include "ast/Clause.h"
17 #include "ast/Constraint.h"
18 #include "ast/Node.h"
19 #include "ast/Program.h"
20 #include "ast/RecordInit.h"
21 #include "ast/Relation.h"
22 #include "ast/TranslationUnit.h"
23 #include "ast/UnnamedVariable.h"
24 #include "ast/Variable.h"
25 #include "ast/utility/NodeMapper.h"
26 #include "ast/utility/Utils.h"
27 #include "ast/utility/Visitor.h"
28 #include <memory>
29 #include <set>
30 #include <vector>
31 
32 namespace souffle::ast::transform {
33 
34 bool ReplaceSingletonVariablesTransformer::transform(TranslationUnit& translationUnit) {
35  bool changed = false;
36 
37  Program& program = translationUnit.getProgram();
38 
39  // Node-mapper to replace a set of singletons with unnamed variables
40  struct replaceSingletons : public NodeMapper {
41  std::set<std::string>& singletons;
42 
43  replaceSingletons(std::set<std::string>& singletons) : singletons(singletons) {}
44 
45  Own<Node> operator()(Own<Node> node) const override {
46  if (auto* var = dynamic_cast<ast::Variable*>(node.get())) {
47  if (singletons.find(var->getName()) != singletons.end()) {
48  return mk<UnnamedVariable>();
49  }
50  }
51  node->apply(*this);
52  return node;
53  }
54  };
55 
56  for (Relation* rel : program.getRelations()) {
57  for (Clause* clause : getClauses(program, *rel)) {
58  std::set<std::string> nonsingletons;
59  std::set<std::string> vars;
60 
61  visitDepthFirst(*clause, [&](const ast::Variable& var) {
62  const std::string& name = var.getName();
63  if (vars.find(name) != vars.end()) {
64  // Variable seen before, so not a singleton variable
65  nonsingletons.insert(name);
66  } else {
67  vars.insert(name);
68  }
69  });
70 
71  std::set<std::string> ignoredVars;
72 
73  // Don't unname singleton variables occurring in records.
74  // TODO (azreika): remove this check once issue #420 is fixed
75  std::set<std::string> recordVars;
76  visitDepthFirst(*clause, [&](const RecordInit& rec) {
77  visitDepthFirst(rec, [&](const ast::Variable& var) { ignoredVars.insert(var.getName()); });
78  });
79 
80  // Don't unname singleton variables occuring in constraints.
81  std::set<std::string> constraintVars;
82  visitDepthFirst(*clause, [&](const Constraint& cons) {
83  visitDepthFirst(cons, [&](const ast::Variable& var) { ignoredVars.insert(var.getName()); });
84  });
85 
86  std::set<std::string> singletons;
87  for (auto& var : vars) {
88  if ((nonsingletons.find(var) == nonsingletons.end()) &&
89  (ignoredVars.find(var) == ignoredVars.end())) {
90  changed = true;
91  singletons.insert(var);
92  }
93  }
94 
95  // Replace the singletons found with underscores
96  replaceSingletons update(singletons);
97  clause->apply(update);
98  }
99  }
100 
101  return changed;
102 }
103 
104 } // namespace souffle::ast::transform
TranslationUnit.h
souffle::ast::transform::ReplaceSingletonVariablesTransformer::transform
bool transform(TranslationUnit &translationUnit) override
Definition: ReplaceSingletonVariables.cpp:38
UnnamedVariable.h
souffle::ast::NodeMapper
An abstract class for manipulating AST Nodes by substitution.
Definition: NodeMapper.h:36
souffle::Own
std::unique_ptr< A > Own
Definition: ContainerUtil.h:42
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
Constraint.h
souffle::ast::analysis::Variable
A variable to be utilized within constraints to be handled by the constraint solver.
Definition: ConstraintSystem.h:41
Relation.h
Utils.h
NodeMapper.h
souffle::ast::transform
Definition: Program.h:45
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
Node.h
Program.h
Visitor.h
Clause.h
ReplaceSingletonVariables.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
rel
void rel(size_t limit, bool showLimit=true)
Definition: Tui.h:1086
RecordInit.h
souffle::ast::RecordInit
Defines a record initialization class.
Definition: RecordInit.h:42
Variable.h