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

Make indexable operations to indexed operations. More...

#include <MakeIndex.h>

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

Public Types

using ExpressionPair = std::pair< Own< Expression >, Own< Expression > >
 Get expression of RAM element access. More...
 

Public Member Functions

Own< ConditionconstructPattern (const std::vector< std::string > &attributeTypes, RamPattern &queryPattern, bool &indexable, VecOwn< Condition > conditionList, int identifier)
 
ExpressionPair getExpressionPair (const Constraint *binRelOp, size_t &element, int identifier)
 
ExpressionPair getLowerUpperExpression (Condition *c, size_t &element, int level)
 
std::string getName () const override
 @Brief get name of the transformer More...
 
bool makeIndex (Program &program)
 Make indexable RAM operation indexed. More...
 
Own< OperationrewriteAggregate (const Aggregate *agg)
 Rewrite an aggregate operation to an indexed aggregate operation. More...
 
Own< OperationrewriteIndexScan (const IndexScan *iscan)
 Rewrite an index scan operation to an amended index scan operation. More...
 
Own< OperationrewriteScan (const Scan *scan)
 Rewrite a scan operation to an indexed scan operation. 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::RelationAnalysisrelAnalysis {nullptr}
 
analysis::LevelAnalysisrla {nullptr}
 

Detailed Description

Make indexable operations to indexed operations.

The transformer assumes that the RAM has been levelled before. The conditions that could be used for an index must be located immediately after the scan or aggregate operation.

QUERY
...
FOR t1 IN A
IF t1.x = 10 /\ t1.y = 20 /\ C
...

will be rewritten to

QUERY
...
SEARCH t1 IN A INDEX t1.x=10 AND t1.y = 20
IF C
...

Definition at line 68 of file MakeIndex.h.

Member Typedef Documentation

◆ ExpressionPair

Get expression of RAM element access.

Parameters
Equivalenceconstraints of the format t1.x = <expression> or <expression> = t1.x
Elementthat was accessed, e.g., for t1.x this would be the index of attribute x.
Tupleidentifier

The method retrieves expression the expression of an equivalence constraint of the format t1.x = <expr> or <expr> = t1.x

Definition at line 84 of file MakeIndex.h.

Member Function Documentation

◆ constructPattern()

Own< Condition > souffle::ram::transform::MakeIndexTransformer::constructPattern ( const std::vector< std::string > &  attributeTypes,
RamPattern queryPattern,
bool &  indexable,
VecOwn< Condition conditionList,
int  identifier 
)
Parameters
AttributeTypesto indicate type of each attribute in the relation
Querypattern that is to be constructed
Flagto indicate whether operation is indexable
Alist of conditions that will be transformed to query patterns
Tupleidentifier of the indexable operation
Returns
Remaining conditions that could not be transformed to an index

Definition at line 121 of file MakeIndex.cpp.

121  {
122  if (condition != nullptr) {
123  condition = mk<Conjunction>(std::move(condition), std::move(c));
124  } else {
125  condition = std::move(c);
126  }
127  };
128 
129  // transform condition list so that every strict inequality becomes a weak inequality + filter
130  // e.g. Tuple[level, element] < <expr> --> Tuple[level, element] <= <expr> and Tuple[level, element] !=
131  // <expr>
132  std::vector<std::unique_ptr<Condition>> toAppend;
133  auto it = conditionList.begin();
134  while (it != conditionList.end()) {
135  auto* binRelOp = dynamic_cast<Constraint*>(it->get());
136  if (binRelOp == nullptr) {
137  ++it;
138  continue;
139  }
140 
141  bool transformable = false;
142 
143  if (isStrictIneqConstraint(binRelOp->getOperator())) {
144  if (const auto* lhs = dynamic_cast<const TupleElement*>(&binRelOp->getLHS())) {
145  const Expression* rhs = &binRelOp->getRHS();
146  if (lhs->getTupleId() == identifier && rla->getLevel(rhs) < identifier) {
147  transformable = true;
148  }
149  }
150  if (const auto* rhs = dynamic_cast<const TupleElement*>(&binRelOp->getRHS())) {
151  const Expression* lhs = &binRelOp->getLHS();
152  if (rhs->getTupleId() == identifier && rla->getLevel(lhs) < identifier) {
153  transformable = true;
154  }
155  }
156  }
157 
158  if (transformable) {
159  // append the weak version of inequality
160  toAppend.emplace_back(
161  std::make_unique<Constraint>(convertStrictToWeakIneqConstraint(binRelOp->getOperator()),
162  clone(&binRelOp->getLHS()), clone(&binRelOp->getRHS())));
163  // append the != constraint
164  toAppend.emplace_back(
165  std::make_unique<Constraint>(convertStrictToNotEqualConstraint(binRelOp->getOperator()),
166  clone(&binRelOp->getLHS()), clone(&binRelOp->getRHS())));
167 
168  // remove the strict version of inequality
169  it = conditionList.erase(it);
170  } else {
171  ++it;
172  }
173  }
174 
175  std::transform(toAppend.begin(), toAppend.end(), std::back_inserter(conditionList),
176  [](const std::unique_ptr<Condition>& cond) { return clone(cond); });
177 
178  // Build query pattern and remaining condition
179  for (auto& cond : conditionList) {
180  size_t element = 0;
181  Own<Expression> lowerExpression;
182  Own<Expression> upperExpression;
183  std::tie(lowerExpression, upperExpression) = getLowerUpperExpression(cond.get(), element, identifier);
184 
185  // we have new bounds if at least one is defined
186  if (!isUndefValue(lowerExpression.get()) || !isUndefValue(upperExpression.get())) {
187  // if no previous bounds are set then just assign them, consider both bounds to be set (but not
188  // necessarily defined) in all remaining cases
189  auto type = attributeTypes[element];
190  indexable = true;
191  if (isUndefValue(queryPattern.first[element].get()) &&
192  isUndefValue(queryPattern.second[element].get())) {
193  queryPattern.first[element] = std::move(lowerExpression);
194  queryPattern.second[element] = std::move(upperExpression);
195  // if lower bound is undefined and we have a new lower bound then assign it
196  } else if (isUndefValue(queryPattern.first[element].get()) &&
197  !isUndefValue(lowerExpression.get()) && isUndefValue(upperExpression.get())) {
198  queryPattern.first[element] = std::move(lowerExpression);
199  // if upper bound is undefined and we have a new upper bound then assign it
200  } else if (isUndefValue(queryPattern.second[element].get()) &&
201  isUndefValue(lowerExpression.get()) && !isUndefValue(upperExpression.get())) {
202  queryPattern.second[element] = std::move(upperExpression);
203  // if both bounds are defined ...
204  // and equal then we have a previous equality constraint i.e. Tuple[level, element] = <expr1>
205  } else if (!isUndefValue(queryPattern.first[element].get()) &&
206  !isUndefValue(queryPattern.second[element].get()) &&
207  (*(queryPattern.first[element]) == *(queryPattern.second[element]))) {
208  // new equality constraint i.e. Tuple[level, element] = <expr2>
209  // simply hoist <expr1> = <expr2> to the outer loop
210  if (!isUndefValue(lowerExpression.get()) && !isUndefValue(upperExpression.get())) {
211  // FIXME: `FEQ` handling; need to know if the expr is a float exp or not
212  addCondition(mk<Constraint>(getEqConstraint(type),
213  souffle::clone(queryPattern.first[element]), std::move(lowerExpression)));
214  }
215  // new lower bound i.e. Tuple[level, element] >= <expr2>
216  // we need to hoist <expr1> >= <expr2> to the outer loop
217  else if (!isUndefValue(lowerExpression.get()) && isUndefValue(upperExpression.get())) {
218  addCondition(mk<Constraint>(getGreaterEqualConstraint(type),
219  souffle::clone(queryPattern.first[element]), std::move(lowerExpression)));
220  }
221  // new upper bound i.e. Tuple[level, element] <= <expr2>
222  // we need to hoist <expr1> <= <expr2> to the outer loop
223  else if (isUndefValue(lowerExpression.get()) && !isUndefValue(upperExpression.get())) {
224  addCondition(mk<Constraint>(getLessEqualConstraint(type),
225  souffle::clone(queryPattern.first[element]), std::move(upperExpression)));
226  }
227  // if either bound is defined but they aren't equal we must consider the cases for updating
228  // them note that at this point we know that if we have a lower/upper bound it can't be the
229  // first one
230  } else if (!isUndefValue(queryPattern.first[element].get()) ||
231  !isUndefValue(queryPattern.second[element].get())) {
232  // if we have a new equality constraint and previous inequality constraints
233  if (!isUndefValue(lowerExpression.get()) && !isUndefValue(upperExpression.get()) &&
234  *lowerExpression == *upperExpression) {
235  // if Tuple[level, element] >= <expr1> and we see Tuple[level, element] = <expr2>
236  // need to hoist <expr2> >= <expr1> to the outer loop
237  if (!isUndefValue(queryPattern.first[element].get())) {
238  addCondition(mk<Constraint>(getGreaterEqualConstraint(type),
239  souffle::clone(lowerExpression), std::move(queryPattern.first[element])));
240  }
241  // if Tuple[level, element] <= <expr1> and we see Tuple[level, element] = <expr2>
242  // need to hoist <expr2> <= <expr1> to the outer loop
243  if (!isUndefValue(queryPattern.second[element].get())) {
244  addCondition(mk<Constraint>(getLessEqualConstraint(type),
245  souffle::clone(upperExpression), std::move(queryPattern.second[element])));
246  }
247  // finally replace bounds with equality constraint
248  queryPattern.first[element] = std::move(lowerExpression);
249  queryPattern.second[element] = std::move(upperExpression);
250  // if we have a new lower bound
251  } else if (!isUndefValue(lowerExpression.get())) {
252  // we want the tightest lower bound so we take the max
253  VecOwn<Expression> maxArguments;
254  maxArguments.push_back(std::move(queryPattern.first[element]));
255  maxArguments.push_back(std::move(lowerExpression));
256 
257  queryPattern.first[element] =
258  mk<IntrinsicOperator>(getMaxOp(type), std::move(maxArguments));
259  // if we have a new upper bound
260  } else if (!isUndefValue(upperExpression.get())) {
261  // we want the tightest upper bound so we take the min
262  VecOwn<Expression> minArguments;
263  minArguments.push_back(std::move(queryPattern.second[element]));
264  minArguments.push_back(std::move(upperExpression));
265 
266  queryPattern.second[element] =
267  mk<IntrinsicOperator>(getMinOp(type), std::move(minArguments));
268  }
269  }
270  } else {
271  addCondition(std::move(cond));
272  }
273  }
274 
275  // Avoid null-pointers for condition and query pattern
276  if (condition == nullptr) {
277  condition = mk<True>();
278  }
279  return condition;
280 }
281 
282 Own<Operation> MakeIndexTransformer::rewriteAggregate(const Aggregate* agg) {
283  if (dynamic_cast<const True*>(&agg->getCondition()) == nullptr) {
284  const Relation& rel = relAnalysis->lookup(agg->getRelation());

◆ getExpressionPair()

ExpressionPair souffle::ram::transform::MakeIndexTransformer::getExpressionPair ( const Constraint binRelOp,
size_t &  element,
int  identifier 
)

Definition at line 48 of file MakeIndex.cpp.

48  {
49  const Expression* rhs = &binRelOp->getRHS();
50  if (lhs->getTupleId() == identifier && rla->getLevel(rhs) < identifier) {
51  element = lhs->getElement();
52  return {mk<UndefValue>(), clone(rhs)};
53  }
54  }
55  // <expr> <= Tuple[level, element]
56  if (const auto* rhs = dynamic_cast<const TupleElement*>(&binRelOp->getRHS())) {
57  const Expression* lhs = &binRelOp->getLHS();
58  if (rhs->getTupleId() == identifier && rla->getLevel(lhs) < identifier) {
59  element = rhs->getElement();
60  return {clone(lhs), mk<UndefValue>()};
61  }
62  }
63  }
64 
65  if (isGreaterEqual(binRelOp->getOperator())) {
66  // Tuple[level, element] >= <expr>
67  if (const auto* lhs = dynamic_cast<const TupleElement*>(&binRelOp->getLHS())) {
68  const Expression* rhs = &binRelOp->getRHS();
69  if (lhs->getTupleId() == identifier && rla->getLevel(rhs) < identifier) {
70  element = lhs->getElement();
71  return {clone(rhs), mk<UndefValue>()};
72  }
73  }
74  // <expr> >= Tuple[level, element]
75  if (const auto* rhs = dynamic_cast<const TupleElement*>(&binRelOp->getRHS())) {
76  const Expression* lhs = &binRelOp->getLHS();
77  if (rhs->getTupleId() == identifier && rla->getLevel(lhs) < identifier) {
78  element = rhs->getElement();
79  return {mk<UndefValue>(), clone(lhs)};
80  }
81  }
82  }
83  return {mk<UndefValue>(), mk<UndefValue>()};
84 }
85 
86 // Retrieves the <expr1> <= Tuple[level, element] <= <expr2> part of the constraint as a pair { <expr1>,
87 // <expr2> }

References souffle::clone(), souffle::ram::analysis::LevelAnalysis::getLevel(), souffle::identifier(), lhs, rhs, and rla.

Here is the call graph for this function:

◆ getLowerUpperExpression()

ExpressionPair souffle::ram::transform::MakeIndexTransformer::getLowerUpperExpression ( Condition c,
size_t &  element,
int  level 
)

Definition at line 92 of file MakeIndex.cpp.

93  {
94  return {mk<UndefValue>(), mk<UndefValue>()};
95  } else if (isEqConstraint(binRelOp->getOperator())) {
96  if (const auto* lhs = dynamic_cast<const TupleElement*>(&binRelOp->getLHS())) {
97  const Expression* rhs = &binRelOp->getRHS();
98  if (lhs->getTupleId() == identifier && rla->getLevel(rhs) < identifier) {
99  element = lhs->getElement();
100  return {clone(rhs), clone(rhs)};
101  }
102  }
103  if (const auto* rhs = dynamic_cast<const TupleElement*>(&binRelOp->getRHS())) {
104  const Expression* lhs = &binRelOp->getLHS();
105  if (rhs->getTupleId() == identifier && rla->getLevel(lhs) < identifier) {
106  element = rhs->getElement();
107  return {clone(lhs), clone(lhs)};
108  }
109  }
110  } else if (isWeakIneqConstraint(binRelOp->getOperator())) {
111  return getExpressionPair(binRelOp, element, identifier);
112  }
113  }
114  return {mk<UndefValue>(), mk<UndefValue>()};
115 }
116 
117 Own<Condition> MakeIndexTransformer::constructPattern(const std::vector<std::string>& attributeTypes,
118  RamPattern& queryPattern, bool& indexable, VecOwn<Condition> conditionList, int identifier) {
119  // Remaining conditions which cannot be handled by an index

◆ getName()

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

@Brief get name of the transformer

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

Definition at line 70 of file MakeIndex.h.

◆ makeIndex()

bool souffle::ram::transform::MakeIndexTransformer::makeIndex ( Program program)

Make indexable RAM operation indexed.

Parameters
RAMprogram that is transformed
Returns
Flag that indicates whether the input program has changed

Definition at line 361 of file MakeIndex.cpp.

361  {
362  const Relation& rel = relAnalysis->lookup(scan->getRelation());
363  if (rel.getRepresentation() != RelationRepresentation::INFO) {
364  if (Own<Operation> op = rewriteScan(scan)) {
365  changed = true;
366  node = std::move(op);
367  }
368  }
369  } else if (const IndexScan* iscan = dynamic_cast<IndexScan*>(node.get())) {
370  if (Own<Operation> op = rewriteIndexScan(iscan)) {
371  changed = true;
372  node = std::move(op);
373  }
374  } else if (const Aggregate* agg = dynamic_cast<Aggregate*>(node.get())) {
375  if (Own<Operation> op = rewriteAggregate(agg)) {
376  changed = true;
377  node = std::move(op);
378  }
379  }
380  node->apply(makeLambdaRamMapper(scanRewriter));
381  return node;
382  };
383  const_cast<Query*>(&query)->apply(makeLambdaRamMapper(scanRewriter));
384  });
385  return changed;
386 }
387 
388 } // namespace souffle::ram::transform

References souffle::INFO, souffle::ram::analysis::RelationAnalysis::lookup(), rel(), relAnalysis, and rewriteScan().

Here is the call graph for this function:

◆ rewriteAggregate()

Own< Operation > souffle::ram::transform::MakeIndexTransformer::rewriteAggregate ( const Aggregate agg)

Rewrite an aggregate operation to an indexed aggregate operation.

Parameters
Aggregateoperation that is potentially rewritten to an indexed version
Returns
The result is null if the aggregate could not be rewritten to an indexed version; otherwise the new indexed version of the aggregate is returned.

Definition at line 286 of file MakeIndex.cpp.

287  {
288  queryPattern.first.push_back(mk<UndefValue>());
289  queryPattern.second.push_back(mk<UndefValue>());
290  }
291 
292  bool indexable = false;
293  Own<Condition> condition = constructPattern(rel.getAttributeTypes(), queryPattern, indexable,
294  toConjunctionList(&agg->getCondition()), identifier);
295  if (indexable) {
296  return mk<IndexAggregate>(souffle::clone(&agg->getOperation()), agg->getFunction(),
297  agg->getRelation(), souffle::clone(&agg->getExpression()), std::move(condition),
298  std::move(queryPattern), agg->getTupleId());
299  }
300  }
301  return nullptr;
302 }
303 
304 Own<Operation> MakeIndexTransformer::rewriteScan(const Scan* scan) {
305  if (const auto* filter = dynamic_cast<const Filter*>(&scan->getOperation())) {
306  const Relation& rel = relAnalysis->lookup(scan->getRelation());

◆ rewriteIndexScan()

Own< Operation > souffle::ram::transform::MakeIndexTransformer::rewriteIndexScan ( const IndexScan iscan)

Rewrite an index scan operation to an amended index scan operation.

Parameters
AnIndexScan that can be amended with new index values
Returns
The result is null if the index scan cannot be amended; otherwise the new IndexScan operation is returned.

Definition at line 333 of file MakeIndex.cpp.

343  {
344  // Merge Index Pattern here
345 
346  Own<Operation> op = souffle::clone(&filter->getOperation());
347  if (!isTrue(condition.get())) {
348  op = mk<Filter>(std::move(condition), std::move(op));
349  }
350  return mk<IndexScan>(iscan->getRelation(), identifier, std::move(strengthenedPattern),
351  std::move(op), iscan->getProfileText());
352  }
353  }
354  return nullptr;
355 }
356 
357 bool MakeIndexTransformer::makeIndex(Program& program) {
358  bool changed = false;
359  visitDepthFirst(program, [&](const Query& query) {

◆ rewriteScan()

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

Rewrite a scan operation to an indexed scan operation.

Parameters
Scanoperation that is potentially rewritten to an IndexScan
Returns
The result is null if the scan could not be rewritten to an IndexScan; otherwise the new IndexScan operation is returned.

Definition at line 308 of file MakeIndex.cpp.

309  {
310  queryPattern.first.push_back(mk<UndefValue>());
311  queryPattern.second.push_back(mk<UndefValue>());
312  }
313 
314  bool indexable = false;
315  Own<Condition> condition = constructPattern(rel.getAttributeTypes(), queryPattern, indexable,
316  toConjunctionList(&filter->getCondition()), identifier);
317  if (indexable) {
318  Own<Operation> op = souffle::clone(&filter->getOperation());
319  if (!isTrue(condition.get())) {
320  op = mk<Filter>(std::move(condition), std::move(op));
321  }
322  return mk<IndexScan>(scan->getRelation(), identifier, std::move(queryPattern), std::move(op),
323  scan->getProfileText());
324  }
325  }
326  return nullptr;
327 }
328 
329 Own<Operation> MakeIndexTransformer::rewriteIndexScan(const IndexScan* iscan) {
330  if (const auto* filter = dynamic_cast<const Filter*>(&iscan->getOperation())) {
331  const Relation& rel = relAnalysis->lookup(iscan->getRelation());

Referenced by makeIndex().

◆ transform()

bool souffle::ram::transform::MakeIndexTransformer::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 134 of file MakeIndex.h.

136  {nullptr};
137 };
138 

Field Documentation

◆ relAnalysis

analysis::RelationAnalysis* souffle::ram::transform::MakeIndexTransformer::relAnalysis {nullptr}
protected

Definition at line 140 of file MakeIndex.h.

Referenced by makeIndex().

◆ rla

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

Definition at line 132 of file MakeIndex.h.

Referenced by getExpressionPair().


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::isGreaterEqual
bool isGreaterEqual(const BinaryConstraintOp constraintOp)
Definition: BinaryConstraintOps.h:217
souffle::ram::transform::MakeIndexTransformer::getLowerUpperExpression
ExpressionPair getLowerUpperExpression(Condition *c, size_t &element, int level)
Definition: MakeIndex.cpp:92
souffle::ram::transform::MakeIndexTransformer::rewriteIndexScan
Own< Operation > rewriteIndexScan(const IndexScan *iscan)
Rewrite an index scan operation to an amended index scan operation.
Definition: MakeIndex.cpp:333
souffle::getMaxOp
FunctorOp getMaxOp(const std::string &type)
Definition: FunctorOps.cpp:276
souffle::ram::isUndefValue
bool isUndefValue(const Expression *expr)
Determines if an expression represents an undefined value.
Definition: Utils.h:40
souffle::ram::toConjunctionList
VecOwn< Condition > toConjunctionList(const Condition *condition)
Convert terms of a conjunction to a list.
Definition: Utils.h:57
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::getGreaterEqualConstraint
BinaryConstraintOp getGreaterEqualConstraint(const std::string &type)
Definition: BinaryConstraintOps.h:94
souffle::ram::transform::MakeIndexTransformer::rewriteAggregate
Own< Operation > rewriteAggregate(const Aggregate *agg)
Rewrite an aggregate operation to an indexed aggregate operation.
Definition: MakeIndex.cpp:286
souffle::isWeakIneqConstraint
bool isWeakIneqConstraint(const BinaryConstraintOp constraintOp)
Definition: BinaryConstraintOps.h:146
souffle::getLessEqualConstraint
BinaryConstraintOp getLessEqualConstraint(const std::string &type)
Definition: BinaryConstraintOps.h:84
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::MakeIndexTransformer::ExpressionPair
std::pair< Own< Expression >, Own< Expression > > ExpressionPair
Get expression of RAM element access.
Definition: MakeIndex.h:84
rhs
Own< Argument > rhs
Definition: ResolveAliases.cpp:185
souffle::ram::transform::MakeIndexTransformer::rewriteScan
Own< Operation > rewriteScan(const Scan *scan)
Rewrite a scan operation to an indexed scan operation.
Definition: MakeIndex.cpp:308
lhs
Own< Argument > lhs
Definition: ResolveAliases.cpp:184
souffle::getMinOp
FunctorOp getMinOp(const std::string &type)
Given a type of an an attribute it returns the appropriate min/max functor operation.
Definition: FunctorOps.cpp:267
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::convertStrictToNotEqualConstraint
BinaryConstraintOp convertStrictToNotEqualConstraint(const BinaryConstraintOp constraintOp)
Definition: BinaryConstraintOps.h:173
souffle::ram::transform::MakeIndexTransformer::constructPattern
Own< Condition > constructPattern(const std::vector< std::string > &attributeTypes, RamPattern &queryPattern, bool &indexable, VecOwn< Condition > conditionList, int identifier)
Definition: MakeIndex.cpp:121
souffle::ram::isTrue
bool isTrue(const Condition *cond)
Determines if a condition represents true.
Definition: Utils.h:45
souffle::isEqConstraint
bool isEqConstraint(const BinaryConstraintOp constraintOp)
Definition: BinaryConstraintOps.h:124
souffle::ram::transform::MakeIndexTransformer::relAnalysis
analysis::RelationAnalysis * relAnalysis
Definition: MakeIndex.h:140
souffle::isStrictIneqConstraint
bool isStrictIneqConstraint(const BinaryConstraintOp constraintOp)
Definition: BinaryConstraintOps.h:133
souffle::ram::RamPattern
std::pair< RamBound, RamBound > RamPattern
Definition: IndexOperation.h:42
souffle::RelationRepresentation::INFO
@ INFO
souffle::getEqConstraint
BinaryConstraintOp getEqConstraint(const std::string &type)
Definition: BinaryConstraintOps.h:74
souffle::ram::transform::MakeIndexTransformer::makeIndex
bool makeIndex(Program &program)
Make indexable RAM operation indexed.
Definition: MakeIndex.cpp:361
souffle::ram::transform::MakeIndexTransformer::getExpressionPair
ExpressionPair getExpressionPair(const Constraint *binRelOp, size_t &element, int identifier)
Definition: MakeIndex.cpp:48
souffle::ram::analysis::RelationAnalysis::lookup
const ram::Relation & lookup(const std::string &name) const
Definition: Relation.cpp:33
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::transform::MakeIndexTransformer::rla
analysis::LevelAnalysis * rla
Definition: MakeIndex.h:132
std::type
ElementType type
Definition: span.h:640
souffle::convertStrictToWeakIneqConstraint
BinaryConstraintOp convertStrictToWeakIneqConstraint(const BinaryConstraintOp constraintOp)
Definition: BinaryConstraintOps.h:159
souffle::ram::makeLambdaRamMapper
LambdaNodeMapper< Lambda > makeLambdaRamMapper(const Lambda &lambda)
Creates a node mapper based on a corresponding lambda expression.
Definition: LambdaNodeMapper.h:67