souffle  2.0.2-371-g6315b36
Utils.h
Go to the documentation of this file.
1 /*
2  * Souffle - A Datalog Compiler
3  * Copyright (c) 2013, 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 Utils.h
12  *
13  * A collection of utilities operating on AST
14  *
15  ***********************************************************************/
16 
17 #pragma once
18 
19 #include "FunctorOps.h"
20 #include <cstddef>
21 #include <map>
22 #include <set>
23 #include <string>
24 #include <vector>
25 
26 namespace souffle::ast {
27 
28 // some forward declarations
29 class Atom;
30 class Clause;
31 class Constraint;
32 class FunctorDeclaration;
33 class IntrinsicFunctor;
34 class Literal;
35 class Node;
36 class Program;
37 class QualifiedName;
38 class Relation;
39 class TranslationUnit;
40 class Type;
41 class Variable;
42 class RecordInit;
43 namespace analysis {
44 class TypeAnalysis;
45 }
46 
47 // ---------------------------------------------------------------
48 // General Utilities
49 // ---------------------------------------------------------------
50 
51 // Deliberately wraps `toString` in order to assure `pprint` works for
52 // all AST nodes during debugging. If `toString` were to be used, only
53 // the specific instanciations would be available at runtime.
54 std::string pprint(const Node& node);
55 
56 /**
57  * Obtains a list of all variables referenced within the AST rooted
58  * by the given root node.
59  *
60  * @param root the root of the AST to be searched
61  * @return a list of all variables referenced within
62  */
63 std::vector<const Variable*> getVariables(const Node& root);
64 
65 /**
66  * Obtains a list of all records referenced within the AST rooted
67  * by the given root node.
68  *
69  * @param root the root of the AST to be searched
70  * @return a list of all records referenced within
71  */
72 std::vector<const RecordInit*> getRecords(const Node& root);
73 
74 /**
75  * Returns literals of a particular type in the body of a clause.
76  *
77  * @param the clause
78  * @return vector of body literals of the specified type
79  */
80 template <typename T, typename C>
81 std::vector<T*> getBodyLiterals(const C& clause) {
82  std::vector<T*> res;
83  for (auto& lit : clause.getBodyLiterals()) {
84  if (T* t = dynamic_cast<T*>(lit)) {
85  res.push_back(t);
86  }
87  }
88  return res;
89 }
90 
91 /**
92  * Returns a vector of clauses in the program describing the relation with the given name.
93  *
94  * @param program the program
95  * @param name the name of the relation to search for
96  * @return vector of clauses describing the relation with the given name
97  */
98 std::vector<Clause*> getClauses(const Program& program, const QualifiedName& relationName);
99 
100 /**
101  * Returns a vector of clauses in the program describing the given relation.
102  *
103  * @param program the program
104  * @param rel the relation to search for
105  * @return vector of clauses describing the given relation
106  */
107 std::vector<Clause*> getClauses(const Program& program, const Relation& rel);
108 
109 /**
110  * Returns the relation with the given name in the program.
111  *
112  * @param program the program
113  * @param name the name of the relation to search for
114  * @return the relation if it exists; nullptr otherwise
115  */
116 Relation* getRelation(const Program& program, const QualifiedName& name);
117 
118 /**
119  * Remove relation and all its clauses from the program.
120  *
121  * @param tu the translation unit
122  * @param name the name of the relation to delete
123  */
124 void removeRelation(TranslationUnit& tu, const QualifiedName& name);
125 
126 /**
127  * Removes the set of clauses with the given relation name.
128  *
129  * @param tu the translation unit
130  * @param name the name of the relation to search for
131  */
132 void removeRelationClauses(TranslationUnit& tu, const QualifiedName& name);
133 
134 /**
135  * Removes the set of IOs with the given relation name.
136  *
137  * @param tu the translation unit
138  * @param name the name of the relation to search for
139  */
140 void removeRelationIOs(TranslationUnit& tu, const QualifiedName& name);
141 
142 /**
143  * Returns the relation referenced by the given atom.
144  * @param atom the atom
145  * @param program the program containing the relations
146  * @return relation referenced by the atom
147  */
148 const Relation* getAtomRelation(const Atom* atom, const Program* program);
149 
150 /**
151  * Returns the relation referenced by the head of the given clause.
152  * @param clause the clause
153  * @param program the program containing the relations
154  * @return relation referenced by the clause head
155  */
156 const Relation* getHeadRelation(const Clause* clause, const Program* program);
157 
158 /**
159  * Returns the relations referenced in the body of the given clause.
160  * @param clause the clause
161  * @param program the program containing the relations
162  * @return relation referenced in the clause body
163  */
164 std::set<const Relation*> getBodyRelations(const Clause* clause, const Program* program);
165 
166 /**
167  * Returns the index of a clause within its relation, ignoring facts.
168  * Used in provenance as a unique ID for clauses within their relations.
169  * @param program the program
170  * @param clause the clause to get the index of
171  * @return the index of the clause ignoring facts; 0 for facts
172  */
173 size_t getClauseNum(const Program* program, const Clause* clause);
174 
175 /**
176  * Returns whether the given relation has any clauses which contain a negation of a specific relation.
177  * @param relation the relation to search the clauses of
178  * @param negRelation the relation to search for negations of in clause bodies
179  * @param program the program containing the relations
180  * @param foundLiteral set to the negation literal that was found
181  */
182 bool hasClauseWithNegatedRelation(const Relation* relation, const Relation* negRelation,
183  const Program* program, const Literal*& foundLiteral);
184 
185 /**
186  * Returns whether the given relation has any clauses which contain an aggregation over of a specific
187  * relation.
188  * @param relation the relation to search the clauses of
189  * @param aggRelation the relation to search for in aggregations in clause bodies
190  * @param program the program containing the relations
191  * @param foundLiteral set to the literal found in an aggregation
192  */
193 bool hasClauseWithAggregatedRelation(const Relation* relation, const Relation* aggRelation,
194  const Program* program, const Literal*& foundLiteral);
195 
196 /**
197  * Returns whether the given clause is recursive.
198  * @param clause the clause to check
199  * @return true iff the clause is recursive
200  */
201 bool isRecursiveClause(const Clause& clause);
202 
203 /**
204  * Returns whether the given clause is a fact
205  * @return true iff the clause is a fact
206  */
207 bool isFact(const Clause& clause);
208 
209 /**
210  * Returns whether the given clause is a rule
211  * @return true iff the clause is a rule
212  */
213 bool isRule(const Clause& clause);
214 
215 /**
216  * Returns whether the given atom is a propositon
217  * @return true iff the atom has no arguments
218  */
219 bool isProposition(const Atom* atom);
220 
221 /**
222  * Returns whether the given atom is a delta relation
223  * @return true iff the atom is a delta relation
224  */
225 bool isDeltaRelation(const QualifiedName& name);
226 
227 /**
228  * Returns a clause which contains head of the given clause
229  * @param clause the clause which head to be cloned
230  * @return pointer to clause which has head cloned from given clause
231  */
232 Clause* cloneHead(const Clause* clause);
233 
234 /**
235  * Reorders the atoms of a clause to be in the given order.
236  * Remaining body literals remain in the same order.
237  *
238  * E.g. if atoms are [a,b,c] and given order is [1,2,0], then
239  * the final atom order will be [b,c,a].
240  *
241  * @param clause clause to reorder atoms in
242  * @param newOrder new order of atoms; atoms[i] = atoms[newOrder[i]]
243  */
244 Clause* reorderAtoms(const Clause* clause, const std::vector<unsigned int>& newOrder);
245 
246 /**
247  * Negate an ast constraint
248  *
249  * @param constraint constraint that will be negated
250  */
251 void negateConstraintInPlace(Constraint& constraint);
252 
253 /**
254  * Pick valid overloads for a functor, sorted by some measure of "preference".
255  */
256 IntrinsicFunctors validOverloads(const analysis::TypeAnalysis&, const IntrinsicFunctor&);
257 
258 /**
259  * Rename all atoms hat appear in a node to a given name.
260  * @param node node to alter the children of
261  * @param oldToNew map from old atom names to new atom names
262  * @return true if the node was changed
263  */
264 bool renameAtoms(Node& node, const std::map<QualifiedName, QualifiedName>& oldToNew);
265 
266 } // namespace souffle::ast
souffle::ast::cloneHead
Clause * cloneHead(const Clause *clause)
Returns a clause which contains head of the given clause.
Definition: Utils.cpp:254
souffle::ast::removeRelation
void removeRelation(TranslationUnit &tu, const QualifiedName &name)
Remove relation and all its clauses from the program.
Definition: Utils.cpp:105
souffle::ast::removeRelationClauses
void removeRelationClauses(TranslationUnit &tu, const QualifiedName &name)
Removes the set of clauses with the given relation name.
Definition: Utils.cpp:114
souffle::ast::reorderAtoms
Clause * reorderAtoms(const Clause *clause, const std::vector< unsigned int > &newOrder)
Reorders the atoms of a clause to be in the given order.
Definition: Utils.cpp:264
souffle::ast::pprint
std::string pprint(const Node &node)
Definition: Utils.cpp:59
souffle::ast::renameAtoms
bool renameAtoms(Node &node, const std::map< QualifiedName, QualifiedName > &oldToNew)
Rename all atoms hat appear in a node to a given name.
Definition: Utils.cpp:307
souffle::ast::getClauseNum
size_t getClauseNum(const Program *program, const Clause *clause)
Returns the index of a clause within its relation, ignoring facts.
Definition: Utils.cpp:150
relation
Relation & relation
Definition: Reader.h:130
souffle::ast::isDeltaRelation
bool isDeltaRelation(const QualifiedName &name)
Returns whether the given atom is a delta relation.
Definition: Utils.cpp:246
souffle::ast::isFact
bool isFact(const Clause &clause)
Returns whether the given clause is a fact.
Definition: Utils.cpp:214
souffle::IntrinsicFunctors
std::vector< std::reference_wrapper< const IntrinsicFunctorInfo > > IntrinsicFunctors
Definition: FunctorOps.h:129
souffle::ast::isRecursiveClause
bool isRecursiveClause(const Clause &clause)
Returns whether the given clause is recursive.
Definition: Utils.cpp:203
souffle::ast::hasClauseWithNegatedRelation
bool hasClauseWithNegatedRelation(const Relation *relation, const Relation *negRelation, const Program *program, const Literal *&foundLiteral)
Returns whether the given relation has any clauses which contain a negation of a specific relation.
Definition: Utils.cpp:171
souffle::ast::hasClauseWithAggregatedRelation
bool hasClauseWithAggregatedRelation(const Relation *relation, const Relation *aggRelation, const Program *program, const Literal *&foundLiteral)
Returns whether the given relation has any clauses which contain an aggregation over of a specific re...
Definition: Utils.cpp:184
souffle::ast::validOverloads
IntrinsicFunctors validOverloads(const analysis::TypeAnalysis &, const IntrinsicFunctor &)
Pick valid overloads for a functor, sorted by some measure of "preference".
souffle::ast::getRelation
Relation * getRelation(const Program &program, const QualifiedName &name)
Returns the relation with the given name in the program.
Definition: Utils.cpp:101
souffle::ast::getBodyLiterals
std::vector< T * > getBodyLiterals(const C &clause)
Returns literals of a particular type in the body of a clause.
Definition: Utils.h:87
souffle::ast::getHeadRelation
const Relation * getHeadRelation(const Clause *clause, const Program *program)
Returns the relation referenced by the head of the given clause.
Definition: Utils.cpp:133
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::isProposition
bool isProposition(const Atom *atom)
Returns whether the given atom is a propositon.
Definition: Utils.cpp:242
souffle::ast::getRecords
std::vector< const RecordInit * > getRecords(const Node &root)
Obtains a list of all records referenced within the AST rooted by the given root node.
Definition: Utils.cpp:70
souffle::ast::negateConstraintInPlace
void negateConstraintInPlace(Constraint &constraint)
Negate an ast constraint.
Definition: Utils.cpp:297
souffle::ast::getVariables
std::vector< const Variable * > getVariables(const Node &root)
Obtains a list of all variables referenced within the AST rooted by the given root node.
Definition: Utils.cpp:63
souffle::ast::getAtomRelation
const Relation * getAtomRelation(const Atom *atom, const Program *program)
Returns the relation referenced by the given atom.
Definition: Utils.cpp:129
FunctorOps.h
souffle::ast
Definition: Aggregator.h:35
souffle::ast::removeRelationIOs
void removeRelationIOs(TranslationUnit &tu, const QualifiedName &name)
Removes the set of IOs with the given relation name.
Definition: Utils.cpp:122
rel
void rel(size_t limit, bool showLimit=true)
Definition: Tui.h:1086
souffle::ast::getBodyRelations
std::set< const Relation * > getBodyRelations(const Clause *clause, const Program *program)
Returns the relations referenced in the body of the given clause.
Definition: Utils.cpp:137
souffle::ast::isRule
bool isRule(const Clause &clause)
Returns whether the given clause is a rule.
Definition: Utils.cpp:238