souffle  2.0.2-371-g6315b36
NormaliseMultiResultFunctors.cpp
Go to the documentation of this file.
1 /*
2  * Souffle - A Datalog Compiler
3  * Copyright (c) 2020, 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 NormaliseMultiResultFunctors.cpp
12  *
13  * Transform pass to normalise all appearances of multi-result functors.
14  *
15  ***********************************************************************/
16 
18 #include "ast/BinaryConstraint.h"
19 #include "ast/IntrinsicFunctor.h"
20 #include "ast/Program.h"
21 #include "ast/TranslationUnit.h"
22 #include "ast/Variable.h"
23 #include "ast/analysis/Functor.h"
25 
26 namespace souffle::ast::transform {
27 
28 bool NormaliseMultiResultFunctorsTransformer::transform(TranslationUnit& translationUnit) {
29  bool changed = false;
30  auto& program = translationUnit.getProgram();
31 
32  // Assign a unique name to each multi-result functor
33  struct name_functors : public NodeMapper {
34  mutable int count{0};
35  mutable std::vector<std::pair<std::string, Own<IntrinsicFunctor>>> functorNames{};
36  name_functors() = default;
37 
38  std::vector<std::pair<std::string, Own<IntrinsicFunctor>>> getFunctorNames() {
39  return std::move(functorNames);
40  }
41 
42  Own<Node> operator()(Own<Node> node) const override {
43  node->apply(*this);
44  if (auto* inf = dynamic_cast<IntrinsicFunctor*>(node.get())) {
46  std::stringstream newName;
47  newName << "@multires_" << count++;
48  functorNames.push_back({newName.str(), Own<IntrinsicFunctor>(inf->clone())});
49  return mk<Variable>(newName.str());
50  }
51  }
52  return node;
53  }
54  };
55 
56  // Apply the mapper to each clause
57  for (auto* clause : program.getClauses()) {
58  name_functors update;
59  clause->apply(update);
60  for (auto& [name, func] : update.getFunctorNames()) {
61  changed = true;
62  clause->addToBody(
63  mk<BinaryConstraint>(BinaryConstraintOp::EQ, mk<Variable>(name), std::move(func)));
64  }
65  }
66  return changed;
67 }
68 
69 } // namespace souffle::ast::transform
souffle::ast::analysis::FunctorAnalysis::isMultiResult
static bool isMultiResult(const Functor &functor)
Definition: Functor.cpp:53
TranslationUnit.h
souffle::Own
std::unique_ptr< A > Own
Definition: ContainerUtil.h:42
souffle::BinaryConstraintOp::EQ
@ EQ
IntrinsicFunctor.h
ContainerUtil.h
souffle::test::count
int count(const C &c)
Definition: table_test.cpp:40
souffle::ast::transform
Definition: Program.h:45
NormaliseMultiResultFunctors.h
Functor.h
Program.h
BinaryConstraint.h
Variable.h
souffle::ast::transform::NormaliseMultiResultFunctorsTransformer::transform
bool transform(TranslationUnit &translationUnit) override
Definition: NormaliseMultiResultFunctors.cpp:34