souffle  2.0.2-371-g6315b36
Public Member Functions | Private Member Functions
souffle::ast::transform::RemoveBooleanConstraintsTransformer Class Reference

Transformation pass to remove constant boolean constraints Should be called after any transformation that may generate boolean constraints. More...

#include <RemoveBooleanConstraints.h>

Inheritance diagram for souffle::ast::transform::RemoveBooleanConstraintsTransformer:
Inheritance graph
Collaboration diagram for souffle::ast::transform::RemoveBooleanConstraintsTransformer:
Collaboration graph

Public Member Functions

RemoveBooleanConstraintsTransformerclone () const override
 
std::string getName () const override
 
- Public Member Functions inherited from souffle::ast::transform::Transformer
bool apply (TranslationUnit &translationUnit)
 
virtual ~Transformer ()=default
 

Private Member Functions

bool transform (TranslationUnit &translationUnit) override
 

Detailed Description

Transformation pass to remove constant boolean constraints Should be called after any transformation that may generate boolean constraints.

Definition at line 31 of file RemoveBooleanConstraints.h.

Member Function Documentation

◆ clone()

RemoveBooleanConstraintsTransformer* souffle::ast::transform::RemoveBooleanConstraintsTransformer::clone ( ) const
inlineoverridevirtual

Implements souffle::ast::transform::Transformer.

Definition at line 41 of file RemoveBooleanConstraints.h.

◆ getName()

std::string souffle::ast::transform::RemoveBooleanConstraintsTransformer::getName ( ) const
inlineoverridevirtual

Implements souffle::ast::transform::Transformer.

Definition at line 37 of file RemoveBooleanConstraints.h.

37  :
38  bool transform(TranslationUnit& translationUnit) override;
39 };

◆ transform()

bool souffle::ast::transform::RemoveBooleanConstraintsTransformer::transform ( TranslationUnit translationUnit)
overrideprivatevirtual

Implements souffle::ast::transform::Transformer.

Definition at line 42 of file RemoveBooleanConstraints.cpp.

43  { changed = true; });
44 
45  // Remove true and false constant literals from all aggregators
46  struct removeBools : public NodeMapper {
47  Own<Node> operator()(Own<Node> node) const override {
48  // Remove them from child nodes
49  node->apply(*this);
50 
51  if (auto* aggr = dynamic_cast<Aggregator*>(node.get())) {
52  bool containsTrue = false;
53  bool containsFalse = false;
54 
55  // Check if aggregator body contains booleans.
56  for (Literal* lit : aggr->getBodyLiterals()) {
57  if (auto* bc = dynamic_cast<BooleanConstraint*>(lit)) {
58  if (bc->isTrue()) {
59  containsTrue = true;
60  } else {
61  containsFalse = true;
62  }
63  }
64  }
65 
66  // Only keep literals that aren't boolean constraints
67  if (containsFalse || containsTrue) {
68  auto replacementAggregator = souffle::clone(aggr);
69  VecOwn<Literal> newBody;
70 
71  bool isEmpty = true;
72 
73  // Don't bother copying over body literals if any are false
74  if (!containsFalse) {
75  for (Literal* lit : aggr->getBodyLiterals()) {
76  // Don't add in boolean constraints
77  if (!isA<BooleanConstraint>(lit)) {
78  isEmpty = false;
79  newBody.push_back(souffle::clone(lit));
80  }
81  }
82 
83  // If the body is still empty and the original body contains true add it now.
84  if (containsTrue && isEmpty) {
85  newBody.push_back(mk<BinaryConstraint>(
86  BinaryConstraintOp::EQ, mk<NumericConstant>(1), mk<NumericConstant>(1)));
87 
88  isEmpty = false;
89  }
90  }
91 
92  if (containsFalse || isEmpty) {
93  // Empty aggregator body!
94  // Not currently handled, so add in a false literal in the body
95  // E.g. max x : { } =becomes=> max 1 : {0 = 1}
96  newBody.push_back(mk<BinaryConstraint>(
97  BinaryConstraintOp::EQ, mk<NumericConstant>(0), mk<NumericConstant>(1)));
98  }
99 
100  replacementAggregator->setBody(std::move(newBody));
101  return replacementAggregator;
102  }
103  }
104 
105  // no false or true, so return the original node
106  return node;
107  }
108  };
109 
110  removeBools update;
111  program.apply(update);
112 
113  // Remove true and false constant literals from all clauses
114  for (Relation* rel : program.getRelations()) {
115  for (Clause* clause : getClauses(program, *rel)) {
116  bool containsTrue = false;
117  bool containsFalse = false;
118 
119  for (Literal* lit : clause->getBodyLiterals()) {
120  if (auto* bc = dynamic_cast<BooleanConstraint*>(lit)) {
121  bc->isTrue() ? containsTrue = true : containsFalse = true;
122  }
123  }
124 
125  if (containsFalse) {
126  // Clause will always fail
127  program.removeClause(clause);
128  } else if (containsTrue) {
129  auto replacementClause = Own<Clause>(cloneHead(clause));
130 
131  // Only keep non-'true' literals
132  for (Literal* lit : clause->getBodyLiterals()) {
133  if (!isA<BooleanConstraint>(lit)) {
134  replacementClause->addToBody(souffle::clone(lit));
135  }
136  }
137 
138  program.removeClause(clause);
139  program.addClause(std::move(replacementClause));
140  }
141  }
142  }
143 
144  return changed;
145 }
146 
147 } // namespace souffle::ast::transform

The documentation for this class was generated from the following files:
souffle::ast::cloneHead
Clause * cloneHead(const Clause *clause)
Returns a clause which contains head of the given clause.
Definition: Utils.cpp:254
souffle::BinaryConstraintOp::EQ
@ EQ
souffle::clone
auto clone(const std::vector< A * > &xs)
Definition: ContainerUtil.h:172
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::transform::RemoveBooleanConstraintsTransformer::transform
bool transform(TranslationUnit &translationUnit) override
Definition: RemoveBooleanConstraints.cpp:42
rel
void rel(size_t limit, bool showLimit=true)
Definition: Tui.h:1086