souffle  2.0.2-371-g6315b36
Public Member Functions | Protected Member Functions | Protected Attributes | Private Member Functions | Private Attributes
souffle::ast2ram::ClauseTranslator Class Reference

#include <ClauseTranslator.h>

Inheritance diagram for souffle::ast2ram::ClauseTranslator:
Inheritance graph
Collaboration diagram for souffle::ast2ram::ClauseTranslator:
Collaboration graph

Public Member Functions

 ClauseTranslator (AstToRamTranslator &translator)
 
Own< ram::StatementtranslateClause (const ast::Clause &clause, const ast::Clause &originalClause, const int version=0)
 generate RAM code for a clause More...
 

Protected Member Functions

virtual Own< ram::ConditioncreateCondition (const ast::Clause &originalClause)
 
virtual Own< ram::OperationcreateOperation (const ast::Clause &clause)
 
Own< ram::OperationfilterByConstraints (size_t level, const std::vector< ast::Argument * > &args, Own< ram::Operation > op, bool constrainByFunctors=true)
 apply constraint filters to a given operation More...
 

Protected Attributes

int level = 0
 
AstToRamTranslatortranslator
 
Own< ValueIndexvalueIndex = mk<ValueIndex>()
 

Private Member Functions

void createValueIndex (const ast::Clause &clause)
 index values in rule More...
 
Own< ast::ClausegetReorderedClause (const ast::Clause &clause, const int version) const
 
void indexValues (const ast::Node *curNode, const std::vector< ast::Argument * > &curNodeArgs, std::map< const ast::Node *, int > &nodeLevel, const ram::Relation *relation)
 

Private Attributes

std::vector< const ast::Argument * > generators
 
std::vector< const ast::Node * > op_nesting
 

Detailed Description

Definition at line 41 of file ClauseTranslator.h.

Constructor & Destructor Documentation

◆ ClauseTranslator()

souffle::ast2ram::ClauseTranslator::ClauseTranslator ( AstToRamTranslator translator)
inline

Definition at line 43 of file ClauseTranslator.h.

Member Function Documentation

◆ createCondition()

Own< ram::Condition > souffle::ast2ram::ClauseTranslator::createCondition ( const ast::Clause originalClause)
protectedvirtual

Reimplemented in souffle::ast2ram::ProvenanceClauseTranslator.

Definition at line 314 of file ClauseTranslator.cpp.

320  {
321  size_t pos = 0;
322 
323  auto mkFilter = [&](bool isFloatArg, Own<ram::Expression> rhs) {

◆ createOperation()

Own< ram::Operation > souffle::ast2ram::ClauseTranslator::createOperation ( const ast::Clause clause)
protectedvirtual

Reimplemented in souffle::ast2ram::ProvenanceClauseTranslator.

Definition at line 295 of file ClauseTranslator.cpp.

299  {
300  project = mk<ram::Filter>(
301  mk<ram::EmptinessCheck>(translator.translateRelation(head)), std::move(project));
302  }
303 
304  // build up insertion call
305  return project; // start with innermost
306 }
307 
308 Own<ram::Condition> ClauseTranslator::createCondition(const ast::Clause& originalClause) {
309  const auto head = originalClause.getHead();
310 
311  // add stopping criteria for nullary relations
312  // (if it contains already the null tuple, don't re-compute)

◆ createValueIndex()

void souffle::ast2ram::ClauseTranslator::createValueIndex ( const ast::Clause clause)
private

index values in rule

Definition at line 425 of file ClauseTranslator.cpp.

434  {
435  // returns the write-location for this generator (or none if an equiv arg was already seen)
436  auto addGenerator = [&]() -> std::optional<int> {
437  // The by-value compare means that we're effectively doing CSE for any
438  // generator args during code-gen. This is a weird place to do this.
439  if (dynamic_cast<const ast::Aggregator*>(&arg) != nullptr &&
440  any_of(generators, [&](auto* x) { return *x == arg; }))
441  return {};
442  generators.push_back(&arg);
443 
444  int aggLoc = level++;
445  valueIndex->setGeneratorLoc(arg, Location({aggLoc, 0}));
446  return aggLoc;
447  };
448 
449  if (auto agg = dynamic_cast<const ast::Aggregator*>(&arg)) {
450  if (auto aggLoc = addGenerator()) {
451  // bind aggregator variables to locations
452  const ast::Atom* atom = nullptr;
453  for (auto lit : agg->getBodyLiterals()) {
454  if (atom == nullptr) {
455  atom = dynamic_cast<const ast::Atom*>(lit);
456  } else {
457  break;
458  }
459  }
460  if (atom != nullptr) {
461  size_t pos = 0;
462  for (auto* arg : atom->getArguments()) {
463  if (const auto* var = dynamic_cast<const ast::Variable*>(arg)) {
464  valueIndex->addVarReference(
465  *var, *aggLoc, (int)pos, translator.translateRelation(atom));
466  }
467  ++pos;
468  }
469  }
470  }
471  }
472 
473  auto* func = as<ast::IntrinsicFunctor>(arg);
475  addGenerator();
476  }
477  });
478 
479  // add multi-result functor introductions
480  visitDepthFirst(clause, [&](const ast::BinaryConstraint& bc) {
481  if (!isEqConstraint(bc.getBaseOperator())) return;
482  const auto* lhs = dynamic_cast<const ast::Variable*>(bc.getLHS());
483  const auto* rhs = dynamic_cast<const ast::IntrinsicFunctor*>(bc.getRHS());
484  if (lhs == nullptr || rhs == nullptr) return;
486  valueIndex->addVarReference(*lhs, valueIndex->getGeneratorLoc(*rhs));
487  });
488 }
489 
490 } // namespace souffle::ast2ram

◆ filterByConstraints()

Own< ram::Operation > souffle::ast2ram::ClauseTranslator::filterByConstraints ( size_t  level,
const std::vector< ast::Argument * > &  args,
Own< ram::Operation op,
bool  constrainByFunctors = true 
)
protected

apply constraint filters to a given operation

Definition at line 325 of file ClauseTranslator.cpp.

326  mk<ram::TupleElement>(level, pos), std::move(rhs)),
327  std::move(op));
328  };
329 
330  for (auto* a : args) {
331  if (auto* c = dynamic_cast<const ast::Constant*>(a)) {
332  auto* const c_num = dynamic_cast<const ast::NumericConstant*>(c);
333  assert((!c_num || c_num->getFinalType().has_value()) &&
334  "numeric constant wasn't bound to a type");
335  op = mkFilter(c_num && c_num->getFinalType().value() == ast::NumericConstant::Type::Float,
337  } else if (auto* func = dynamic_cast<const ast::Functor*>(a)) {
338  if (constrainByFunctors) {
340  op = mkFilter(
342  }
343  }
344 
345  ++pos;
346  }
347 
348  return op;
349 }
350 
351 Own<ast::Clause> ClauseTranslator::getReorderedClause(const ast::Clause& clause, const int version) const {
352  const auto plan = clause.getExecutionPlan();
353 
354  // check whether there is an imposed order constraint
355  if (plan == nullptr) {

◆ getReorderedClause()

Own< ast::Clause > souffle::ast2ram::ClauseTranslator::getReorderedClause ( const ast::Clause clause,
const int  version 
) const
private

Definition at line 357 of file ClauseTranslator.cpp.

358  {
359  return Own<ast::Clause>(reorderedClause);
360  }
361  return nullptr;
362  }
363  auto orders = plan->getOrders();
364  if (orders.find(version) == orders.end()) {
365  return nullptr;
366  }
367 
368  // get the imposed order
369  const auto& order = orders[version];
370 
371  // create a copy and fix order
372  Own<ast::Clause> reorderedClause(clause.clone());
373 
374  // Change order to start at zero
375  std::vector<unsigned int> newOrder(order->getOrder().size());
376  std::transform(order->getOrder().begin(), order->getOrder().end(), newOrder.begin(),
377  [](unsigned int i) -> unsigned int { return i - 1; });
378 
379  // re-order atoms
380  reorderedClause.reset(reorderAtoms(reorderedClause.get(), newOrder));
381 
382  // clear other order and fix plan
383  reorderedClause->clearExecutionPlan();
384 
385  return reorderedClause;
386 }
387 
388 void ClauseTranslator::indexValues(const ast::Node* curNode, const std::vector<ast::Argument*>& curNodeArgs,
389  std::map<const ast::Node*, int>& nodeLevel, const ram::Relation* relation) {
390  for (size_t pos = 0; pos < curNodeArgs.size(); ++pos) {
391  // get argument
392  auto& arg = curNodeArgs[pos];

◆ indexValues()

void souffle::ast2ram::ClauseTranslator::indexValues ( const ast::Node curNode,
const std::vector< ast::Argument * > &  curNodeArgs,
std::map< const ast::Node *, int > &  nodeLevel,
const ram::Relation relation 
)
private

Definition at line 394 of file ClauseTranslator.cpp.

395  {
396  if (pos < relation->getArity()) {
397  valueIndex->addVarReference(*var, nodeLevel[curNode], pos, relation->getName());
398  } else {
399  valueIndex->addVarReference(*var, nodeLevel[curNode], pos);
400  }
401  }
402 
403  // check for nested records
404  if (auto rec = dynamic_cast<const ast::RecordInit*>(arg)) {
405  // introduce new nesting level for unpack
406  op_nesting.push_back(rec);
407  nodeLevel[rec] = level++;
408 
409  // register location of record
410  valueIndex->setRecordDefinition(*rec, nodeLevel[curNode], pos);
411 
412  // resolve nested components
413  indexValues(rec, rec->getArguments(), nodeLevel, relation);
414  }
415  }
416 }
417 
418 /** index values in rule */
419 void ClauseTranslator::createValueIndex(const ast::Clause& clause) {
420  for (const auto* atom : ast::getBodyLiterals<ast::Atom>(clause)) {
421  // map from each list of arguments to its nesting level
422  std::map<const ast::Node*, int> nodeLevel;

References relation, and valueIndex.

◆ translateClause()

Own< ram::Statement > souffle::ast2ram::ClauseTranslator::translateClause ( const ast::Clause clause,
const ast::Clause originalClause,
const int  version = 0 
)

generate RAM code for a clause

Definition at line 61 of file ClauseTranslator.cpp.

66  {
67  // translate arguments
68  VecOwn<ram::Expression> values;
69  for (auto& arg : head->getArguments()) {
70  values.push_back(translator.translateValue(arg, ValueIndex()));
71  }
72 
73  // create a fact statement
74  return mk<ram::Query>(mk<ram::Project>(translator.translateRelation(head), std::move(values)));
75  }
76 
77  // the rest should be rules
78  assert(isRule(clause));
79 
80  createValueIndex(clause);
81 
82  // -- create RAM statement --
83 
84  Own<ram::Operation> op = createOperation(clause);
85 
86  /* add equivalence constraints imposed by variable binding */
87  for (const auto& cur : valueIndex->getVariableReferences()) {
88  // the first appearance
89  const Location& first = *cur.second.begin();
90  // all other appearances
91  for (const Location& loc : cur.second) {
92  if (first != loc && !valueIndex->isGenerator(loc.identifier)) {
93  // FIXME: equiv' for float types (`FEQ`)
94  op = mk<ram::Filter>(
95  mk<ram::Constraint>(BinaryConstraintOp::EQ, translator.makeRamTupleElement(first),
97  std::move(op));
98  }
99  }
100  }
101 
102  /* add conditions caused by atoms, negations, and binary relations */
103  for (const auto& lit : clause.getBodyLiterals()) {
104  if (auto condition = translator.translateConstraint(lit, *valueIndex)) {
105  op = mk<ram::Filter>(std::move(condition), std::move(op));
106  }
107  }
108 
109  // add aggregator conditions
110  size_t curLevel = op_nesting.size() - 1;
111  for (auto it = op_nesting.rbegin(); it != op_nesting.rend(); ++it, --curLevel) {
112  const ast::Node* cur = *it;
113 
114  if (const auto* atom = dynamic_cast<const ast::Atom*>(cur)) {
115  // add constraints
116  size_t pos = 0;
117  for (auto arg : atom->getArguments()) {
118  if (auto* agg = dynamic_cast<ast::Aggregator*>(arg)) {
119  auto loc = valueIndex->getGeneratorLoc(*agg);
120  // FIXME: equiv' for float types (`FEQ`)
121  op = mk<ram::Filter>(
122  mk<ram::Constraint>(BinaryConstraintOp::EQ, mk<ram::TupleElement>(curLevel, pos),
124  std::move(op));
125  }
126  ++pos;
127  }
128  }
129  }
130 
131  // add generator levels
132  --level;
133  for (auto* cur : reverse(generators)) {
134  if (auto agg = dynamic_cast<const ast::Aggregator*>(cur)) {
135  // condition for aggregate and helper function to add terms
136  Own<ram::Condition> aggCond;
137  auto addAggCondition = [&](Own<ram::Condition> arg) {
138  aggCond = aggCond ? mk<ram::Conjunction>(std::move(aggCond), std::move(arg)) : std::move(arg);
139  };
140 
141  // translate constraints of sub-clause
142  for (auto&& lit : agg->getBodyLiterals()) {
143  if (auto newCondition = translator.translateConstraint(lit, *valueIndex)) {
144  addAggCondition(std::move(newCondition));
145  }
146  }
147 
148  // get the first predicate of the sub-clause
149  // NB: at most one atom is permitted in a sub-clause
150  const ast::Atom* atom = nullptr;
151  for (auto&& lit : agg->getBodyLiterals()) {
152  if (atom == nullptr) {
153  atom = dynamic_cast<const ast::Atom*>(lit);
154  } else {
155  assert(!isA<ast::Atom>(lit) && "Unsupported complex aggregation body encountered!");
156  }
157  }
158 
159  // translate arguments's of atom (if exists) to conditions
160  if (atom != nullptr) {
161  size_t pos = 0;
162  auto addAggEqCondition = [&](Own<ram::Expression> value) {
163  if (isUndefValue(value.get())) return;
164 
165  // FIXME: equiv' for float types (`FEQ`)
166  addAggCondition(mk<ram::Constraint>(
167  BinaryConstraintOp::EQ, mk<ram::TupleElement>(level, pos), std::move(value)));
168  };
169  for (auto* arg : atom->getArguments()) {
170  // variable bindings are issued differently since we don't want self
171  // referential variable bindings
172  if (auto* var = dynamic_cast<const ast::Variable*>(arg)) {
173  for (auto&& loc : valueIndex->getVariableReferences().find(var->getName())->second) {
174  if (level != loc.identifier || (int)pos != loc.element) {
175  addAggEqCondition(translator.makeRamTupleElement(loc));
176  break;
177  }
178  }
179  } else if (auto value = translator.translateValue(arg, *valueIndex)) {
180  addAggEqCondition(std::move(value));
181  }
182  ++pos;
183  }
184  }
185 
186  // translate aggregate expression
187  auto expr = translator.translateValue(agg->getTargetExpression(), *valueIndex);
188 
189  // add Ram-Aggregation layer
190  op = mk<ram::Aggregate>(std::move(op), agg->getFinalType().value(),
191  translator.translateRelation(atom), expr ? std::move(expr) : mk<ram::UndefValue>(),
192  aggCond ? std::move(aggCond) : mk<ram::True>(), level);
193  } else if (const auto* func = dynamic_cast<const ast::IntrinsicFunctor*>(cur)) {
194  VecOwn<ram::Expression> args;
195  for (auto&& x : func->getArguments()) {
196  args.push_back(translator.translateValue(x, *valueIndex));
197  }
198 
199  auto func_op = [&]() -> ram::NestedIntrinsicOp {
200  switch (func->getFinalOpType().value()) {
204 
205  default: fatal("missing case handler or bad code-gen");
206  }
207  };
208 
209  op = mk<ram::NestedIntrinsicOperator>(func_op(), std::move(args), std::move(op), level);
210  }
211 
212  --level;
213  }
214 
215  // build operation bottom-up
216  while (!op_nesting.empty()) {
217  // get next operator
218  const ast::Node* cur = op_nesting.back();
219  op_nesting.pop_back();
220 
221  // get current nesting level
222  auto level = op_nesting.size();
223 
224  if (const auto* atom = dynamic_cast<const ast::Atom*>(cur)) {
225  // add constraints
226  // TODO: do we wish to enable constraints by header functor? record inits do so...
227  op = filterByConstraints(level, atom->getArguments(), std::move(op), false);
228 
229  // check whether all arguments are unnamed variables
230  bool isAllArgsUnnamed = true;
231  for (auto* argument : atom->getArguments()) {
232  if (!isA<ast::UnnamedVariable>(argument)) {
233  isAllArgsUnnamed = false;
234  }
235  }
236 
237  // add check for emptiness for an atom
238  op = mk<ram::Filter>(
239  mk<ram::Negation>(mk<ram::EmptinessCheck>(translator.translateRelation(atom))),
240  std::move(op));
241 
242  // add a scan level
243  if (atom->getArity() != 0 && !isAllArgsUnnamed) {
244  if (head->getArity() == 0) {
245  op = mk<ram::Break>(
246  mk<ram::Negation>(mk<ram::EmptinessCheck>(translator.translateRelation(head))),
247  std::move(op));
248  }
249  if (Global::config().has("profile")) {
250  std::stringstream ss;
251  ss << head->getQualifiedName();
252  ss.str("");
253  ss << "@frequency-atom" << ';';
254  ss << originalClause.getHead()->getQualifiedName() << ';';
255  ss << version << ';';
256  ss << stringify(toString(clause)) << ';';
257  ss << stringify(toString(*atom)) << ';';
258  ss << stringify(toString(originalClause)) << ';';
259  ss << level << ';';
260  op = mk<ram::Scan>(translator.translateRelation(atom), level, std::move(op), ss.str());
261  } else {
262  op = mk<ram::Scan>(translator.translateRelation(atom), level, std::move(op));
263  }
264  }
265 
266  // TODO: support constants in nested records!
267  } else if (const auto* rec = dynamic_cast<const ast::RecordInit*>(cur)) {
268  // add constant constraints
269  op = filterByConstraints(level, rec->getArguments(), std::move(op));
270 
271  // add an unpack level
272  const Location& loc = valueIndex->getDefinitionPoint(*rec);
273  op = mk<ram::UnpackRecord>(
274  std::move(op), level, translator.makeRamTupleElement(loc), rec->getArguments().size());
275  } else {
276  fatal("Unsupported AST node for creation of scan-level!");
277  }
278  }
279 
280  /* generate the final RAM Insert statement */
281  Own<ram::Condition> cond = createCondition(originalClause);
282  if (cond != nullptr) {
283  return mk<ram::Query>(mk<ram::Filter>(std::move(cond), std::move(op)));
284  } else {
285  return mk<ram::Query>(std::move(op));
286  }
287 }
288 
289 Own<ram::Operation> ClauseTranslator::createOperation(const ast::Clause& clause) {
290  const auto head = clause.getHead();
291 
292  VecOwn<ram::Expression> values;
293  for (ast::Argument* arg : head->getArguments()) {

References souffle::ast::Atom::getArguments(), souffle::ast2ram::AstToRamTranslator::translateRelation(), souffle::ast2ram::AstToRamTranslator::translateValue(), and translator.

Referenced by souffle::ast2ram::AstToRamTranslator::translateNonRecursiveRelation().

Here is the call graph for this function:

Field Documentation

◆ generators

std::vector<const ast::Argument*> souffle::ast2ram::ClauseTranslator::generators
private

Definition at line 65 of file ClauseTranslator.h.

◆ level

int souffle::ast2ram::ClauseTranslator::level = 0
protected

Definition at line 55 of file ClauseTranslator.h.

◆ op_nesting

std::vector<const ast::Node*> souffle::ast2ram::ClauseTranslator::op_nesting
private

Definition at line 68 of file ClauseTranslator.h.

◆ translator

AstToRamTranslator& souffle::ast2ram::ClauseTranslator::translator
protected

◆ valueIndex

Own<ValueIndex> souffle::ast2ram::ClauseTranslator::valueIndex = mk<ValueIndex>()
protected

The documentation for this class was generated from the following files:
souffle::ast::analysis::FunctorAnalysis::isMultiResult
static bool isMultiResult(const Functor &functor)
Definition: Functor.cpp:53
souffle::ast2ram::ClauseTranslator::createValueIndex
void createValueIndex(const ast::Clause &clause)
index values in rule
Definition: ClauseTranslator.cpp:425
TypeAttribute
Type attribute class.
souffle::ram::isUndefValue
bool isUndefValue(const Expression *expr)
Determines if an expression represents an undefined value.
Definition: Utils.h:40
souffle::ast::reorderAtoms
Clause * reorderAtoms(const Clause *clause, const std::vector< unsigned int > &newOrder)
Reorders the atoms of a clause to be in the given order.
Definition: Utils.cpp:264
souffle::FunctorOp::URANGE
@ URANGE
souffle::ast2ram::ClauseTranslator::translator
AstToRamTranslator & translator
Definition: ClauseTranslator.h:49
souffle::ram::NestedIntrinsicOp::RANGE
@ RANGE
relation
Relation & relation
Definition: Reader.h:130
souffle::BinaryConstraintOp::EQ
@ EQ
souffle::ram::NestedIntrinsicOp::FRANGE
@ FRANGE
souffle::ast2ram::AstToRamTranslator::translateRelation
std::string translateRelation(const ast::Atom *atom)
a utility to translate atoms to relations
Definition: AstToRamTranslator.cpp:219
rhs
Own< Argument > rhs
Definition: ResolveAliases.cpp:185
souffle::ram::NestedIntrinsicOp::URANGE
@ URANGE
souffle::ast2ram::AstToRamTranslator::getFunctorAnalysis
const ast::analysis::FunctorAnalysis * getFunctorAnalysis() const
Definition: AstToRamTranslator.h:80
lhs
Own< Argument > lhs
Definition: ResolveAliases.cpp:184
souffle::toString
const std::string & toString(const std::string &str)
A generic function converting strings into strings (trivial case).
Definition: StringUtil.h:234
souffle::FunctorOp::FRANGE
@ FRANGE
souffle::stringify
std::string stringify(const std::string &input)
Stringify a string using escapes for escape, newline, tab, double-quotes and semicolons.
Definition: StringUtil.h:334
i
size_t i
Definition: json11.h:663
souffle::ast2ram::AstToRamTranslator::translateConstraint
Own< ram::Condition > translateConstraint(const ast::Literal *arg, const ValueIndex &index)
translate an AST constraint to a RAM condition
Definition: AstToRamTranslator.cpp:340
souffle::FunctorOp::RANGE
@ RANGE
souffle::any_of
bool any_of(const Container &c, UnaryPredicate p)
A generic test checking whether any elements within a container satisfy a certain predicate.
Definition: FunctionalUtil.h:124
souffle::ast::analysis::FunctorAnalysis::getReturnType
TypeAttribute getReturnType(const Functor *functor) const
Return return type of functor.
Definition: Functor.cpp:40
souffle::ast2ram::ClauseTranslator::getReorderedClause
Own< ast::Clause > getReorderedClause(const ast::Clause &clause, const int version) const
Definition: ClauseTranslator.cpp:357
souffle::ram::NestedIntrinsicOp
NestedIntrinsicOp
Definition: NestedIntrinsicOperator.h:38
souffle::isEqConstraint
bool isEqConstraint(const BinaryConstraintOp constraintOp)
Definition: BinaryConstraintOps.h:124
souffle::ast2ram::ClauseTranslator::op_nesting
std::vector< const ast::Node * > op_nesting
Definition: ClauseTranslator.h:68
souffle::Global::config
static MainConfig & config()
Definition: Global.h:141
souffle::ast2ram::AstToRamTranslator::makeRamTupleElement
static Own< ram::TupleElement > makeRamTupleElement(const Location &loc)
create a RAM element access node
Definition: AstToRamTranslator.cpp:150
std
Definition: Brie.h:3053
souffle::ast2ram::ClauseTranslator::createOperation
virtual Own< ram::Operation > createOperation(const ast::Clause &clause)
Definition: ClauseTranslator.cpp:295
souffle::ast2ram::ClauseTranslator::createCondition
virtual Own< ram::Condition > createCondition(const ast::Clause &originalClause)
Definition: ClauseTranslator.cpp:314
souffle::fatal
void fatal(const char *format, const Args &... args)
Definition: MiscUtil.h:198
souffle::ast2ram::AstToRamTranslator::translateValue
Own< ram::Expression > translateValue(const ast::Argument *arg, const ValueIndex &index)
translate an AST argument to a RAM value
Definition: AstToRamTranslator.cpp:236
souffle::ast2ram::ClauseTranslator::valueIndex
Own< ValueIndex > valueIndex
Definition: ClauseTranslator.h:52
souffle::ast2ram::ClauseTranslator::generators
std::vector< const ast::Argument * > generators
Definition: ClauseTranslator.h:65
souffle::ast::visitDepthFirst
void visitDepthFirst(const Node &root, Visitor< R, Ps... > &visitor, Args &... args)
A utility function visiting all nodes within the ast rooted by the given node recursively in a depth-...
Definition: Visitor.h:273
souffle::ast2ram::AstToRamTranslator::translateConstant
Own< ram::Expression > translateConstant(ast::Constant const &c)
translate RAM code for a constant value
Definition: AstToRamTranslator.cpp:437
souffle::ast2ram::ClauseTranslator::indexValues
void indexValues(const ast::Node *curNode, const std::vector< ast::Argument * > &curNodeArgs, std::map< const ast::Node *, int > &nodeLevel, const ram::Relation *relation)
Definition: ClauseTranslator.cpp:394
souffle::ast::NumericConstant::Type::Float
@ Float
souffle::TypeAttribute::Float
@ Float
souffle::ast2ram::ClauseTranslator::filterByConstraints
Own< ram::Operation > filterByConstraints(size_t level, const std::vector< ast::Argument * > &args, Own< ram::Operation > op, bool constrainByFunctors=true)
apply constraint filters to a given operation
Definition: ClauseTranslator.cpp:325
souffle::ast::isRule
bool isRule(const Clause &clause)
Returns whether the given clause is a rule.
Definition: Utils.cpp:238
souffle::ast2ram::ClauseTranslator::level
int level
Definition: ClauseTranslator.h:55
souffle::profile::ss
class souffle::profile::Tui ss
Definition: Tui.h:336