56         const ast::Clause& clause, 
const ast::Clause& originalClause, 
const int version) {
 
   87     for (
const auto& cur : 
valueIndex->getVariableReferences()) {
 
   89         const Location& first = *cur.second.begin();
 
   91         for (
const Location& loc : cur.second) {
 
  103     for (
const auto& lit : clause.getBodyLiterals()) {
 
  105             op = mk<ram::Filter>(std::move(condition), std::move(op));
 
  112         const ast::Node* cur = *it;
 
  114         if (
const auto* atom = 
dynamic_cast<const ast::Atom*
>(cur)) {
 
  117             for (
auto arg : atom->getArguments()) {
 
  118                 if (
auto* agg = 
dynamic_cast<ast::Aggregator*
>(arg)) {
 
  121                     op = mk<ram::Filter>(
 
  134         if (
auto agg = 
dynamic_cast<const ast::Aggregator*
>(cur)) {
 
  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);
 
  142             for (
auto&& lit : agg->getBodyLiterals()) {
 
  144                     addAggCondition(std::move(newCondition));
 
  150             const ast::Atom* atom = 
nullptr;
 
  151             for (
auto&& lit : agg->getBodyLiterals()) {
 
  152                 if (atom == 
nullptr) {
 
  153                     atom = 
dynamic_cast<const ast::Atom*
>(lit);
 
  155                     assert(!isA<ast::Atom>(lit) && 
"Unsupported complex aggregation body encountered!");
 
  160             if (atom != 
nullptr) {
 
  162                 auto addAggEqCondition = [&](Own<ram::Expression> value) {
 
  166                     addAggCondition(mk<ram::Constraint>(
 
  169                 for (
auto* arg : atom->getArguments()) {
 
  172                     if (
auto* var = 
dynamic_cast<const ast::Variable*
>(arg)) {
 
  173                         for (
auto&& loc : 
valueIndex->getVariableReferences().find(var->getName())->second) {
 
  180                         addAggEqCondition(std::move(value));
 
  190             op = mk<ram::Aggregate>(std::move(op), agg->getFinalType().value(),
 
  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()) {
 
  200                 switch (func->getFinalOpType().value()) {
 
  205                     default: 
fatal(
"missing case handler or bad code-gen");
 
  209             op = mk<ram::NestedIntrinsicOperator>(func_op(), std::move(args), std::move(op), 
level);
 
  224         if (
const auto* atom = 
dynamic_cast<const ast::Atom*
>(cur)) {
 
  230             bool isAllArgsUnnamed = 
true;
 
  231             for (
auto* argument : atom->getArguments()) {
 
  232                 if (!isA<ast::UnnamedVariable>(argument)) {
 
  233                     isAllArgsUnnamed = 
false;
 
  238             op = mk<ram::Filter>(
 
  243             if (atom->getArity() != 0 && !isAllArgsUnnamed) {
 
  250                     std::stringstream 
ss;
 
  253                     ss << 
"@frequency-atom" << 
';';
 
  254                     ss << originalClause.getHead()->getQualifiedName() << 
';';
 
  255                     ss << version << 
';';
 
  267         } 
else if (
const auto* rec = 
dynamic_cast<const ast::RecordInit*
>(cur)) {
 
  272             const Location& loc = 
valueIndex->getDefinitionPoint(*rec);
 
  273             op = mk<ram::UnpackRecord>(
 
  276             fatal(
"Unsupported AST node for creation of scan-level!");
 
  282     if (cond != 
nullptr) {
 
  283         return mk<ram::Query>(mk<ram::Filter>(std::move(cond), std::move(op)));
 
  285         return mk<ram::Query>(std::move(op));
 
  290     const auto head = clause.getHead();
 
  292     VecOwn<ram::Expression> values;
 
  300         project = mk<ram::Filter>(
 
  309     const auto head = originalClause.getHead();
 
  320         const std::vector<ast::Argument*>& args, 
Own<ram::Operation> op, 
bool constrainByFunctors) {
 
  324         return mk<ram::Filter>(
 
  326                         mk<ram::TupleElement>(
level, pos), std::move(
rhs)),
 
  330     for (
auto* a : args) {
 
  333             assert((!c_num || c_num->getFinalType().has_value()) &&
 
  334                     "numeric constant wasn't bound to a type");
 
  337         } 
else if (
auto* func = 
dynamic_cast<const ast::Functor*
>(a)) {
 
  338             if (constrainByFunctors) {
 
  352     const auto plan = clause.getExecutionPlan();
 
  355     if (plan == 
nullptr) {
 
  363     auto orders = plan->getOrders();
 
  364     if (orders.find(version) == orders.end()) {
 
  369     const auto& order = orders[version];
 
  372     Own<ast::Clause> reorderedClause(clause.clone());
 
  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; });
 
  380     reorderedClause.reset(
reorderAtoms(reorderedClause.get(), newOrder));
 
  383     reorderedClause->clearExecutionPlan();
 
  385     return reorderedClause;
 
  389         std::map<const ast::Node*, int>& nodeLevel, 
const ram::Relation* 
relation) {
 
  390     for (
size_t pos = 0; pos < curNodeArgs.size(); ++pos) {
 
  392         auto& arg = curNodeArgs[pos];
 
  396             if (pos < relation->getArity()) {
 
  399                 valueIndex->addVarReference(*var, nodeLevel[curNode], pos);
 
  407             nodeLevel[rec] = 
level++;
 
  410             valueIndex->setRecordDefinition(*rec, nodeLevel[curNode], pos);
 
  420     for (
const auto* atom : ast::getBodyLiterals<ast::Atom>(clause)) {
 
  422         std::map<const ast::Node*, int> nodeLevel;
 
  436         auto addGenerator = [&]() -> std::optional<int> {
 
  444             int aggLoc = 
level++;
 
  445             valueIndex->setGeneratorLoc(arg, Location({aggLoc, 0}));
 
  449         if (
auto agg = 
dynamic_cast<const ast::Aggregator*
>(&arg)) {
 
  450             if (
auto aggLoc = addGenerator()) {
 
  452                 const ast::Atom* atom = 
nullptr;
 
  453                 for (
auto lit : agg->getBodyLiterals()) {
 
  454                     if (atom == 
nullptr) {
 
  455                         atom = 
dynamic_cast<const ast::Atom*
>(lit);
 
  460                 if (atom != 
nullptr) {
 
  462                     for (
auto* arg : atom->getArguments()) {
 
  463                         if (
const auto* var = 
dynamic_cast<const ast::Variable*
>(arg)) {
 
  473         auto* func = as<ast::IntrinsicFunctor>(arg);
 
  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;