souffle
2.0.2-371-g6315b36
|
Go to the documentation of this file.
53 std::string
pprint(
const Node& node) {
57 std::vector<const Variable*>
getVariables(
const Node& root) {
59 std::vector<const Variable*> vars;
66 std::vector<const RecordInit*> recs;
74 if (clause->getHead()->getQualifiedName() == relationName) {
81 std::vector<Clause*>
getClauses(
const Program& program,
const Relation&
rel) {
85 std::vector<Directive*>
getDirectives(
const Program& program,
const QualifiedName& relationName) {
88 if (dir->getQualifiedName() == relationName) {
95 Relation*
getRelation(
const Program& program,
const QualifiedName& name) {
96 return getIf(program.getRelations(), [&](
const Relation* r) { return r->getQualifiedName() == name; });
99 void removeRelation(TranslationUnit& tu,
const QualifiedName& name) {
100 Program& program = tu.getProgram();
104 program.removeRelationDecl(name);
109 Program& program = tu.getProgram();
110 const auto& relDetail = *tu.getAnalysis<analysis::RelationDetailCacheAnalysis>();
111 for (
const auto* clause : relDetail.getClauses(name)) {
112 program.removeClause(clause);
117 Program& program = tu.getProgram();
119 program.removeDirective(directive);
131 std::set<const Relation*>
getBodyRelations(
const Clause* clause,
const Program* program) {
132 std::set<const Relation*> bodyRelations;
133 for (
const auto& lit : clause->getBodyLiterals()) {
137 for (
const auto& arg : clause->getHead()->getArguments()) {
141 return bodyRelations;
144 size_t getClauseNum(
const Program* program,
const Clause* clause) {
147 const Relation*
rel =
getRelation(*program, clause->getHead()->getQualifiedName());
148 assert(
rel !=
nullptr &&
"clause relation does not exist");
150 size_t clauseNum = 1;
152 bool isFact = cur->getBodyLiterals().empty();
154 return isFact ? 0 : clauseNum;
162 fatal(
"clause does not exist");
166 const Program* program,
const Literal*& foundLiteral) {
168 for (
const auto* neg : getBodyLiterals<Negation>(*cl)) {
179 const Program* program,
const Literal*& foundLiteral) {
185 foundLiteral = &atom;
198 QualifiedName relationName = clause.getHead()->getQualifiedName();
199 bool recursive =
false;
201 if (atom.getQualifiedName() == relationName) {
208 bool isFact(
const Clause& clause) {
210 if (clause.getHead() ==
nullptr) {
214 if (!clause.getBodyLiterals().empty()) {
219 bool hasAggregatesOrMultiResultFunctor =
false;
221 if (isA<Aggregator>(arg)) {
222 hasAggregatesOrMultiResultFunctor = true;
225 auto* func = as<IntrinsicFunctor>(arg);
226 hasAggregatesOrMultiResultFunctor |=
227 (func !=
nullptr) && analysis::FunctorAnalysis::isMultiResult(*func);
229 return !hasAggregatesOrMultiResultFunctor;
232 bool isRule(
const Clause& clause) {
233 return (clause.getHead() !=
nullptr) && !
isFact(clause);
237 return atom->getArguments().empty();
241 const auto& qualifiers = name.getQualifiers();
242 if (qualifiers.empty()) {
245 return isPrefix(
"@delta_", qualifiers[0]);
248 Clause*
cloneHead(
const Clause* clause) {
249 auto*
clone =
new Clause();
250 clone->setSrcLoc(clause->getSrcLoc());
252 if (clause->getExecutionPlan() !=
nullptr) {
258 Clause*
reorderAtoms(
const Clause* clause,
const std::vector<unsigned int>& newOrder) {
260 std::vector<unsigned int> atomPositions;
262 for (
unsigned int i = 0;
i < bodyLiterals.size();
i++) {
263 if (isA<Atom>(bodyLiterals[
i])) {
264 atomPositions.push_back(
i);
269 assert(newOrder.size() == atomPositions.size());
270 std::vector<unsigned int> nopOrder;
271 for (
unsigned int i = 0;
i < atomPositions.size();
i++) {
272 nopOrder.push_back(
i);
274 assert(std::is_permutation(nopOrder.begin(), nopOrder.end(), newOrder.begin()));
278 unsigned int currentAtom = 0;
279 for (
unsigned int currentLiteral = 0; currentLiteral < bodyLiterals.size(); currentLiteral++) {
280 Literal* literalToAdd = bodyLiterals[currentLiteral];
281 if (isA<Atom>(literalToAdd)) {
283 literalToAdd = bodyLiterals[atomPositions[newOrder[currentAtom++]]];
292 if (
auto* bcstr =
dynamic_cast<BooleanConstraint*
>(&constraint)) {
293 bcstr->set(!bcstr->isTrue());
294 }
else if (
auto* cstr =
dynamic_cast<BinaryConstraint*
>(&constraint)) {
297 fatal(
"Unknown ast-constraint type");
301 bool renameAtoms(Node& node,
const std::map<QualifiedName, QualifiedName>& oldToNew) {
302 struct rename_atoms :
public NodeMapper {
303 mutable bool changed{
false};
304 const std::map<QualifiedName, QualifiedName>& oldToNew;
305 rename_atoms(
const std::map<QualifiedName, QualifiedName>& oldToNew) : oldToNew(oldToNew) {}
306 Own<Node> operator()(Own<Node> node)
const override {
308 if (
auto* atom =
dynamic_cast<Atom*
>(node.get())) {
309 if (
contains(oldToNew, atom->getQualifiedName())) {
311 renamedAtom->setQualifiedName(oldToNew.at(atom->getQualifiedName()));
319 rename_atoms update(oldToNew);
321 return update.changed;
Clause * cloneHead(const Clause *clause)
Returns a clause which contains head of the given clause.
bool isPrefix(const std::string &prefix, const std::string &element)
Determine if one string is a prefix of another.
void removeRelation(TranslationUnit &tu, const QualifiedName &name)
Remove relation and all its clauses from the program.
void removeRelationClauses(TranslationUnit &tu, const QualifiedName &name)
Removes the set of clauses with the given relation name.
Clause * reorderAtoms(const Clause *clause, const std::vector< unsigned int > &newOrder)
Reorders the atoms of a clause to be in the given order.
std::string pprint(const Node &node)
bool renameAtoms(Node &node, const std::map< QualifiedName, QualifiedName > &oldToNew)
Rename all atoms hat appear in a node to a given name.
bool contains(const C &container, const typename C::value_type &element)
A utility to check generically whether a given element is contained in a given container.
size_t getClauseNum(const Program *program, const Clause *clause)
Returns the index of a clause within its relation, ignoring facts.
bool isDeltaRelation(const QualifiedName &name)
Returns whether the given atom is a delta relation.
Defines a relation with a name, attributes, qualifiers, and internal representation.
Intermediate representation of a horn clause.
bool isFact(const Clause &clause)
Returns whether the given clause is a fact.
std::vector< Clause * > getClauses() const
Return clauses.
A variable to be utilized within constraints to be handled by the constraint solver.
bool isRecursiveClause(const Clause &clause)
Returns whether the given clause is recursive.
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.
const std::string & toString(const std::string &str)
A generic function converting strings into strings (trivial case).
The program class consists of relations, clauses and types.
Object-oriented wrapper class for Souffle's templatized relations.
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...
const QualifiedName & getQualifiedName() const
Return qualified name.
a directive has a type (e.g. input/output/printsize/limitsize), qualified relation name,...
auto clone(const std::vector< A * > &xs)
BinaryConstraintOp negatedConstraintOp(const BinaryConstraintOp op)
Negated Constraint Operator Each operator requires a negated operator which is necessary for the expa...
Relation * getRelation(const Program &program, const QualifiedName &name)
Returns the relation with the given name in the program.
std::vector< Own< Clause > > clauses
const Relation * getHeadRelation(const Clause *clause, const Program *program)
Returns the relation referenced by the head of the given clause.
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.
bool isProposition(const Atom *atom)
Returns whether the given atom is a propositon.
std::vector< Own< Directive > > directives
C::value_type getIf(const C &container, std::function< bool(const typename C::value_type)> pred)
Returns the first element in a container that satisfies a given predicate, nullptr otherwise.
Abstract class for syntactic elements in an input program.
std::vector< const RecordInit * > getRecords(const Node &root)
Obtains a list of all records referenced within the AST rooted by the given root node.
void fatal(const char *format, const Args &... args)
void negateConstraintInPlace(Constraint &constraint)
Negate an ast constraint.
std::vector< const Variable * > getVariables(const Node &root)
Obtains a list of all variables referenced within the AST rooted by the given root node.
const Relation * getAtomRelation(const Atom *atom, const Program *program)
Returns the relation referenced by the given atom.
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-...
void removeRelationIOs(TranslationUnit &tu, const QualifiedName &name)
Removes the set of IOs with the given relation name.
Qualified Name class defines fully/partially qualified names to identify objects in components.
void rel(size_t limit, bool showLimit=true)
std::set< const Relation * > getBodyRelations(const Clause *clause, const Program *program)
Returns the relations referenced in the body of the given clause.
std::vector< Directive * > getDirectives(const Program &program, const QualifiedName &relationName)
Defines a record initialization class.
bool isRule(const Clause &clause)
Returns whether the given clause is a rule.
std::vector< Literal * > getBodyLiterals() const
Obtains a copy of the internally maintained body literals.