souffle  2.0.2-371-g6315b36
Public Member Functions | Protected Member Functions | Protected Attributes
souffle::ram::transform::ChoiceConversionTransformer Class Reference

Convert (Scan/If)/(IndexScan/If) operaitons to (Choice)/(IndexChoice) operations. More...

#include <ChoiceConversion.h>

Inheritance diagram for souffle::ram::transform::ChoiceConversionTransformer:
Inheritance graph
Collaboration diagram for souffle::ram::transform::ChoiceConversionTransformer:
Collaboration graph

Public Member Functions

bool convertScans (Program &program)
 Apply choice-conversion to the whole program. More...
 
std::string getName () const override
 @Brief get name of the transformer More...
 
Own< OperationrewriteIndexScan (const IndexScan *indexScan)
 Rewrite IndexScan operations. More...
 
Own< OperationrewriteScan (const Scan *scan)
 Rewrite Scan operations. More...
 
- Public Member Functions inherited from souffle::ram::transform::Transformer
bool apply (TranslationUnit &translationUnit)
 @Brief apply the transformer to a translation unit @Param translationUnit that will be transformed. More...
 
virtual ~Transformer ()=default
 

Protected Member Functions

bool transform (TranslationUnit &translationUnit) override
 @Brief transform the translation unit / used by apply @Param translationUnit that will be transformed. More...
 

Protected Attributes

analysis::LevelAnalysisrla {nullptr}
 

Detailed Description

Convert (Scan/If)/(IndexScan/If) operaitons to (Choice)/(IndexChoice) operations.

If there exists Scan/IndexScan operations in the RAM, and the variables are used in a subsequent Filter operation but no subsequent operation in the tree (up until and including the Project), the operations are rewritten to Choice/IndexChoice operations.

For example,

QUERY
...
FOR t1 IN A ON INDEX t1.x=10 AND t1.y = 20
IF (t1.x, t1.y) NOT IN A
... // no occurrence of t1

will be rewritten to

QUERY
...
CHOICE A AS t1 ON INDEX t1.x=10 AND t1.y = 20
WHERE (t1.x, t1.y) NOT IN A
...

Definition at line 65 of file ChoiceConversion.h.

Member Function Documentation

◆ convertScans()

bool souffle::ram::transform::ChoiceConversionTransformer::convertScans ( Program program)

Apply choice-conversion to the whole program.

Parameters
RAMprogram
Returns
A flag indicating whether the RAM program has been changed.

Search for queries and rewrite their Scan/IndexScan and If operations if possible.

Definition at line 116 of file ChoiceConversion.cpp.

116  {
117  if (Own<Operation> op = rewriteScan(scan)) {
118  changed = true;
119  node = std::move(op);
120  }
121  } else if (const IndexScan* indexScan = dynamic_cast<IndexScan*>(node.get())) {
122  if (Own<Operation> op = rewriteIndexScan(indexScan)) {
123  changed = true;
124  node = std::move(op);
125  }
126  }
127  node->apply(makeLambdaRamMapper(scanRewriter));
128 
129  return node;
130  };
131  const_cast<Query*>(&query)->apply(makeLambdaRamMapper(scanRewriter));
132  });
133 
134  return changed;
135 }
136 
137 } // namespace souffle::ram::transform

References rewriteScan().

Here is the call graph for this function:

◆ getName()

std::string souffle::ram::transform::ChoiceConversionTransformer::getName ( ) const
inlineoverridevirtual

@Brief get name of the transformer

Implements souffle::ram::transform::Transformer.

Definition at line 67 of file ChoiceConversion.h.

96  :
97  analysis::LevelAnalysis* rla{nullptr};

◆ rewriteIndexScan()

Own< Operation > souffle::ram::transform::ChoiceConversionTransformer::rewriteIndexScan ( const IndexScan indexScan)

Rewrite IndexScan operations.

Parameters
Anindex operation
Returns
The old operation if the if-conversion fails; otherwise the IndexChoice operation

Rewrites IndexScan/If pair to an IndexChoice operation if value is not used in a consecutive RAM operation

Definition at line 68 of file ChoiceConversion.cpp.

68  {
69  // Check that the Filter uses the identifier in the IndexScan
70  if (rla->getLevel(&filter->getCondition()) == indexScan->getTupleId()) {
71  transformTuple = true;
72 
73  // Check that the filter is not referred to after
74  const auto* nextNode = dynamic_cast<const Node*>(&filter->getOperation());
75 
76  visitDepthFirst(*nextNode, [&](const TupleElement& element) {
77  if (element.getTupleId() == indexScan->getTupleId()) {
78  transformTuple = false;
79  }
80  });
81  }
82  }
83 
84  // Convert the IndexScan/If pair into an IndexChoice
85  if (transformTuple) {
86  RamPattern newValues;
87  const auto* filter = dynamic_cast<const Filter*>(&indexScan->getOperation());
88  const int identifier = indexScan->getTupleId();
89  const std::string& rel = indexScan->getRelation();
90 
91  for (auto& cur : indexScan->getRangePattern().first) {
92  Expression* val = nullptr;
93  if (cur != nullptr) {
94  val = cur->clone();
95  }
96  newValues.first.emplace_back(val);
97  }
98  for (auto& cur : indexScan->getRangePattern().second) {
99  Expression* val = nullptr;
100  if (cur != nullptr) {
101  val = cur->clone();
102  }
103  newValues.second.emplace_back(val);
104  }
105 
106  return mk<IndexChoice>(rel, identifier, souffle::clone(&filter->getCondition()), std::move(newValues),
107  souffle::clone(&filter->getOperation()), indexScan->getProfileText());
108  }
109  return nullptr;
110 }
111 
112 bool ChoiceConversionTransformer::convertScans(Program& program) {
113  bool changed = false;
114  visitDepthFirst(program, [&](const Query& query) {

References souffle::filter(), souffle::ram::analysis::LevelAnalysis::getLevel(), souffle::ram::TupleElement::getTupleId(), rla, and souffle::ram::visitDepthFirst().

Here is the call graph for this function:

◆ rewriteScan()

Own< Operation > souffle::ram::transform::ChoiceConversionTransformer::rewriteScan ( const Scan scan)

Rewrite Scan operations.

Parameters
Ascan operation
Returns
The old operation if the if-conversion fails; otherwise the Choice operation

Rewrites Scan/If pair to a Choice operation if value is not used in a consecutive RAM operation

Definition at line 36 of file ChoiceConversion.cpp.

36  {
37  // Check that the Filter uses the identifier in the Scan
38  if (rla->getLevel(&filter->getCondition()) == scan->getTupleId()) {
39  transformTuple = true;
40 
41  // Check that the filter is not referred to after
42  const auto* nextNode = dynamic_cast<const Node*>(&filter->getOperation());
43 
44  visitDepthFirst(*nextNode, [&](const TupleElement& element) {
45  if (element.getTupleId() == scan->getTupleId()) {
46  transformTuple = false;
47  }
48  });
49  }
50  }
51 
52  // Convert the Scan/If pair into a Choice
53  if (transformTuple) {
54  VecOwn<Expression> newValues;
55  const auto* filter = dynamic_cast<const Filter*>(&scan->getOperation());
56  const int identifier = scan->getTupleId();
57 
58  return mk<Choice>(scan->getRelation(), identifier, souffle::clone(&filter->getCondition()),
59  souffle::clone(&filter->getOperation()), scan->getProfileText());
60  }
61  return nullptr;
62 }
63 
64 Own<Operation> ChoiceConversionTransformer::rewriteIndexScan(const IndexScan* indexScan) {
65  bool transformTuple = false;
66 

References souffle::filter(), souffle::ram::analysis::LevelAnalysis::getLevel(), souffle::ram::TupleOperation::getTupleId(), souffle::ram::TupleElement::getTupleId(), rla, and souffle::ram::visitDepthFirst().

Referenced by convertScans().

Here is the call graph for this function:

◆ transform()

bool souffle::ram::transform::ChoiceConversionTransformer::transform ( TranslationUnit translationUnit)
inlineoverrideprotectedvirtual

@Brief transform the translation unit / used by apply @Param translationUnit that will be transformed.

@Return flag reporting whether the RAM program has changed

Implements souffle::ram::transform::Transformer.

Definition at line 102 of file ChoiceConversion.h.

Field Documentation

◆ rla

analysis::LevelAnalysis* souffle::ram::transform::ChoiceConversionTransformer::rla {nullptr}
protected

Definition at line 101 of file ChoiceConversion.h.

Referenced by rewriteIndexScan(), and rewriteScan().


The documentation for this class was generated from the following files:
souffle::ram::analysis::LevelAnalysis::getLevel
int getLevel(const Node *value) const
Get level of a RAM expression/condition.
Definition: Level.cpp:64
souffle::ram::transform::Transformer::apply
bool apply(TranslationUnit &translationUnit)
@Brief apply the transformer to a translation unit @Param translationUnit that will be transformed.
Definition: Transformer.cpp:39
souffle::identifier
std::string identifier(std::string id)
Valid C++ identifier, note that this does not ensure the uniqueness of identifiers returned.
Definition: StringUtil.h:387
souffle::ram::transform::ChoiceConversionTransformer::rewriteIndexScan
Own< Operation > rewriteIndexScan(const IndexScan *indexScan)
Rewrite IndexScan operations.
Definition: ChoiceConversion.cpp:68
souffle::clone
auto clone(const std::vector< A * > &xs)
Definition: ContainerUtil.h:172
souffle::filter
std::vector< A > filter(std::vector< A > xs, F &&f)
Filter a vector to include certain elements.
Definition: FunctionalUtil.h:155
souffle::ram::transform::ChoiceConversionTransformer::rla
analysis::LevelAnalysis * rla
Definition: ChoiceConversion.h:101
souffle::ram::transform::ChoiceConversionTransformer::convertScans
bool convertScans(Program &program)
Apply choice-conversion to the whole program.
Definition: ChoiceConversion.cpp:116
CHOICE
#define CHOICE(Structure, Arity,...)
souffle::ram::transform::ChoiceConversionTransformer::rewriteScan
Own< Operation > rewriteScan(const Scan *scan)
Rewrite Scan operations.
Definition: ChoiceConversion.cpp:36
souffle::ram::RamPattern
std::pair< RamBound, RamBound > RamPattern
Definition: IndexOperation.h:42
souffle::ram::visitDepthFirst
void visitDepthFirst(const Node &root, Visitor< R, Ps... > &visitor, Args &... args)
A utility function visiting all nodes within the RAM fragments rooted by the given node recursively i...
Definition: Visitor.h:357
rel
void rel(size_t limit, bool showLimit=true)
Definition: Tui.h:1086
souffle::ram::makeLambdaRamMapper
LambdaNodeMapper< Lambda > makeLambdaRamMapper(const Lambda &lambda)
Creates a node mapper based on a corresponding lambda expression.
Definition: LambdaNodeMapper.h:67