souffle  2.0.2-371-g6315b36
RemoveRedundantSums.cpp
Go to the documentation of this file.
1 /*
2  * Souffle - A Datalog Compiler
3  * Copyright (c) 2019, 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 RemoveRedundantSums.cpp
12  *
13  ***********************************************************************/
14 
16 #include "AggregateOp.h"
17 #include "ast/Aggregator.h"
18 #include "ast/Argument.h"
19 #include "ast/IntrinsicFunctor.h"
20 #include "ast/Literal.h"
21 #include "ast/Node.h"
22 #include "ast/NumericConstant.h"
23 #include "ast/Program.h"
24 #include "ast/TranslationUnit.h"
25 #include "ast/utility/NodeMapper.h"
27 #include <algorithm>
28 #include <memory>
29 #include <utility>
30 #include <vector>
31 
32 namespace souffle::ast::transform {
33 
34 bool RemoveRedundantSumsTransformer::transform(TranslationUnit& translationUnit) {
35  struct ReplaceSumWithCount : public NodeMapper {
36  ReplaceSumWithCount() = default;
37 
38  Own<Node> operator()(Own<Node> node) const override {
39  // Apply to all aggregates of the form
40  // sum k : { .. } where k is a constant
41  if (auto* agg = dynamic_cast<Aggregator*>(node.get())) {
42  if (agg->getBaseOperator() == AggregateOp::SUM) {
43  if (const auto* constant =
44  dynamic_cast<const NumericConstant*>(agg->getTargetExpression())) {
45  changed = true;
46  // Then construct the new thing to replace it with
47  auto count = mk<Aggregator>(AggregateOp::COUNT);
48  // Duplicate the body of the aggregate
49  VecOwn<Literal> newBody;
50  for (const auto& lit : agg->getBodyLiterals()) {
51  newBody.push_back(souffle::clone(lit));
52  }
53  count->setBody(std::move(newBody));
54  auto number = souffle::clone(constant);
55  // Now it's constant * count : { ... }
56  auto result = mk<IntrinsicFunctor>("*", std::move(number), std::move(count));
57 
58  return result;
59  }
60  }
61  }
62  node->apply(*this);
63  return node;
64  }
65 
66  // variables
67  mutable bool changed = false;
68  };
69 
70  ReplaceSumWithCount update;
71  Program& program = translationUnit.getProgram();
72  program.apply(update);
73  return update.changed;
74 }
75 
76 } // namespace souffle::ast::transform
TranslationUnit.h
souffle::ast::transform::RemoveRedundantSumsTransformer::transform
bool transform(TranslationUnit &translationUnit) override
Definition: RemoveRedundantSums.cpp:38
AggregateOp.h
souffle::Own
std::unique_ptr< A > Own
Definition: ContainerUtil.h:42
MiscUtil.h
IntrinsicFunctor.h
NodeMapper.h
Argument.h
souffle::ast::Program
The program class consists of relations, clauses and types.
Definition: Program.h:52
souffle::clone
auto clone(const std::vector< A * > &xs)
Definition: ContainerUtil.h:172
Literal.h
souffle::test::count
int count(const C &c)
Definition: table_test.cpp:40
souffle::ast::transform
Definition: Program.h:45
Node.h
souffle::AggregateOp::COUNT
@ COUNT
souffle::AggregateOp::SUM
@ SUM
Aggregator.h
souffle::ast::Aggregator
Defines the aggregator class.
Definition: Aggregator.h:53
Program.h
souffle::ast::NumericConstant
Numeric Constant.
Definition: NumericConstant.h:43
souffle::ast::Program::apply
void apply(const NodeMapper &map) override
Apply the mapper to all child nodes.
Definition: Program.h:139
RemoveRedundantSums.h
souffle::VecOwn
std::vector< Own< A > > VecOwn
Definition: ContainerUtil.h:45
NumericConstant.h