| souffle
    2.0.2-371-g6315b36
    | 
 
 
 
Main class for the AST->RAM translator.  
 More...
#include <AstToRamTranslator.h>
Main class for the AST->RAM translator. 
Definition at line 71 of file AstToRamTranslator.h.
◆ AstToRamTranslator()
  
  | 
        
          | souffle::ast2ram::AstToRamTranslator::AstToRamTranslator | ( |  | ) |  |  | default | 
 
 
◆ ~AstToRamTranslator()
  
  | 
        
          | souffle::ast2ram::AstToRamTranslator::~AstToRamTranslator | ( |  | ) |  |  | default | 
 
 
◆ getAuxArityAnalysis()
◆ getConstantRamRepresentation()
  
  | 
        
          | RamDomain souffle::ast2ram::AstToRamTranslator::getConstantRamRepresentation | ( | const ast::Constant & | constant | ) |  |  | private | 
 
Get ram representation of constant. 
Definition at line 418 of file AstToRamTranslator.cpp.
  428     fatal(
"unaccounted-for constant");
 
  434     if (
auto* 
const c_num = 
dynamic_cast<const ast::NumericConstant*
>(&c)) {
 
  435         switch (c_num->getFinalType().value()) {
 
 
 
 
◆ getEvaluationArity()
      
        
          | size_t souffle::ast2ram::AstToRamTranslator::getEvaluationArity | ( | const ast::Atom * | atom | ) | const | 
      
 
determine the auxiliary for relations 
Definition at line 154 of file AstToRamTranslator.cpp.
  165         const ast::Relation* 
rel) {
 
  166     std::vector<std::map<std::string, std::string>> inputDirectives;
 
 
 
 
◆ getFunctorAnalysis()
◆ getInputDirectives()
  
  | 
        
          | std::vector< std::map< std::string, std::string > > souffle::ast2ram::AstToRamTranslator::getInputDirectives | ( | const ast::Relation * | rel | ) |  |  | private | 
 
Definition at line 170 of file AstToRamTranslator.cpp.
  174         std::map<std::string, std::string> 
directives;
 
  175         for (
const auto& currentPair : load->getParameters()) {
 
  181     if (inputDirectives.empty()) {
 
  182         inputDirectives.emplace_back();
 
  185     return inputDirectives;
 
  189         const ast::Relation* 
rel) {
 
  190     std::vector<std::map<std::string, std::string>> outputDirectives;
 
 
 
 
◆ getOutputDirectives()
  
  | 
        
          | std::vector< std::map< std::string, std::string > > souffle::ast2ram::AstToRamTranslator::getOutputDirectives | ( | const ast::Relation * | rel | ) |  |  | private | 
 
Definition at line 194 of file AstToRamTranslator.cpp.
  199         std::map<std::string, std::string> 
directives;
 
  200         for (
const auto& currentPair : store->getParameters()) {
 
  206     if (outputDirectives.empty()) {
 
  207         outputDirectives.emplace_back();
 
  210     return outputDirectives;
 
 
 
 
◆ getPolymorphicObjectsAnalysis()
◆ getRelationName()
  
  | 
        
          | std::string souffle::ast2ram::AstToRamTranslator::getRelationName | ( | const ast::QualifiedName & | id | ) |  |  | staticprivate | 
 
converts the given relation identifier into a relation name 
Definition at line 549 of file AstToRamTranslator.cpp.
  551     VecOwn<ram::Statement> preamble;
 
 
 
 
◆ getSipsMetric()
  
  | 
        
          | const ast::SipsMetric* souffle::ast2ram::AstToRamTranslator::getSipsMetric | ( |  | ) | const |  | inline | 
 
 
◆ getSymbolTable()
  
  | 
        
          | SymbolTable & souffle::ast2ram::AstToRamTranslator::getSymbolTable | ( |  | ) |  |  | private | 
 
Return a symbol table. 
Definition at line 335 of file AstToRamTranslator.cpp.
  336     class ConstraintTranslator : 
public ast::Visitor<Own<ram::Condition>> {
 
  338         const ValueIndex& index;
 
 
References polyAnalysis.
 
 
◆ lookupRelation()
  
  | 
        
          | const ram::Relation* souffle::ast2ram::AstToRamTranslator::lookupRelation | ( | const std::string & | name | ) | const |  | inline | 
 
 
◆ makeNegationSubproofSubroutine()
translate RAM code for subroutine to get subproofs for non-existence of a tuple 
make a subroutine to search for subproofs for the non-existence of a tuple 
Definition at line 841 of file AstToRamTranslator.cpp.
  850                       : clause.getBodyLiterals()) {
 
  852         if (!isA<ast::Constraint>(bodyLit)) {
 
  858     for (
auto bodyLit : ast::getBodyLiterals<ast::Constraint>(clause)) {
 
  863     struct AggregatesToVariables : 
public ast::NodeMapper {
 
  866         AggregatesToVariables(
int& aggNumber) : aggNumber(aggNumber) {}
 
  868         Own<ast::Node> operator()(Own<ast::Node> node)
 const override {
 
  869             if (
dynamic_cast<ast::Aggregator*
>(node.get()) != 
nullptr) {
 
  870                 return mk<ast::Variable>(
"agg_" + std::to_string(aggNumber++));
 
  878     AggregatesToVariables aggToVar(aggNumber);
 
  879     clauseReplacedAggregates->apply(aggToVar);
 
  882     std::vector<const ast::Variable*> uniqueVariables;
 
  884     visitDepthFirst(*clauseReplacedAggregates, [&](
const ast::Variable& var) {
 
  885         if (var.getName().find(
"@level_num") == std::string::npos) {
 
  888             if (std::find_if(uniqueVariables.begin(), uniqueVariables.end(),
 
  889                         [&](const ast::Variable* v) { return *v == var; }) == uniqueVariables.end()) {
 
  890                 uniqueVariables.push_back(&var);
 
  896     struct VariablesToArguments : 
public ast::NodeMapper {
 
  897         const std::vector<const ast::Variable*>& uniqueVariables;
 
  899         VariablesToArguments(
const std::vector<const ast::Variable*>& uniqueVariables)
 
  900                 : uniqueVariables(uniqueVariables) {}
 
  902         Own<ast::Node> operator()(Own<ast::Node> node)
 const override {
 
  904             if (
auto varPtr = 
dynamic_cast<const ast::Variable*
>(node.get())) {
 
  905                 if (varPtr->getName().find(
"@level_num") == std::string::npos) {
 
  906                     size_t argNum = std::find_if(uniqueVariables.begin(), uniqueVariables.end(),
 
  907                                             [&](
const ast::Variable* v) { return *v == *varPtr; }) -
 
  908                                     uniqueVariables.begin();
 
  910                     return mk<ast::SubroutineArgument>(argNum);
 
  912                     return mk<ast::UnnamedVariable>();
 
  926     VecOwn<ram::Statement> searchSequence;
 
  932     size_t litNumber = 0;
 
  933     for (
const auto& lit : newClause->getBodyLiterals()) {
 
  934         if (
auto atom = 
dynamic_cast<ast::Atom*
>(lit)) {
 
  939             VecOwn<ram::Expression> query;
 
  942             VariablesToArguments varsToArgs(uniqueVariables);
 
  943             atom->apply(varsToArgs);
 
  945             auto atomArgs = atom->getArguments();
 
  947             for (
size_t i = 0; 
i < atom->getArity() - auxiliaryArity; 
i++) {
 
  948                 auto arg = atomArgs[
i];
 
  953             for (
size_t i = 0; 
i < auxiliaryArity; 
i++) {
 
  954                 query.push_back(mk<ram::UndefValue>());
 
  958             assert(query.size() == atom->getArity() && 
"wrong query tuple size");
 
  961             auto existenceCheck = mk<ram::ExistenceCheck>(relName, std::move(query));
 
  962             auto negativeExistenceCheck = mk<ram::Negation>(
souffle::clone(existenceCheck));
 
  965             VecOwn<ram::Expression> returnTrue;
 
  966             returnTrue.push_back(mk<ram::SignedConstant>(1));
 
  969             VecOwn<ram::Expression> returnFalse;
 
  970             returnFalse.push_back(mk<ram::SignedConstant>(0));
 
  973             appendStmt(searchSequence, mk<ram::Query>(mk<ram::Filter>(std::move(existenceCheck),
 
  974                                                mk<ram::SubroutineReturn>(std::move(returnTrue)))));
 
  975             appendStmt(searchSequence, mk<ram::Query>(mk<ram::Filter>(std::move(negativeExistenceCheck),
 
  976                                                mk<ram::SubroutineReturn>(std::move(returnFalse)))));
 
  977         } 
else if (
auto neg = 
dynamic_cast<ast::Negation*
>(lit)) {
 
  978             auto atom = neg->getAtom();
 
  983             VecOwn<ram::Expression> query;
 
  986             VariablesToArguments varsToArgs(uniqueVariables);
 
  987             atom->apply(varsToArgs);
 
  989             auto atomArgs = atom->getArguments();
 
  991             for (
size_t i = 0; 
i < atom->getArity() - auxiliaryArity; 
i++) {
 
  992                 auto arg = atomArgs[
i];
 
  997             for (
size_t i = 0; 
i < auxiliaryArity; 
i++) {
 
  998                 query.push_back(mk<ram::UndefValue>());
 
 1002             assert(query.size() == atom->getArity() && 
"wrong query tuple size");
 
 1005             auto existenceCheck = mk<ram::ExistenceCheck>(relName, std::move(query));
 
 1006             auto negativeExistenceCheck = mk<ram::Negation>(
souffle::clone(existenceCheck));
 
 1009             VecOwn<ram::Expression> returnTrue;
 
 1010             returnTrue.push_back(mk<ram::SignedConstant>(1));
 
 1013             VecOwn<ram::Expression> returnFalse;
 
 1014             returnFalse.push_back(mk<ram::SignedConstant>(0));
 
 1017             appendStmt(searchSequence, mk<ram::Query>(mk<ram::Filter>(std::move(existenceCheck),
 
 1018                                                mk<ram::SubroutineReturn>(std::move(returnFalse)))));
 
 1019             appendStmt(searchSequence, mk<ram::Query>(mk<ram::Filter>(std::move(negativeExistenceCheck),
 
 1020                                                mk<ram::SubroutineReturn>(std::move(returnTrue)))));
 
 1022         } 
else if (
auto con = 
dynamic_cast<ast::Constraint*
>(lit)) {
 
 1023             VariablesToArguments varsToArgs(uniqueVariables);
 
 1024             con->apply(varsToArgs);
 
 1028             auto negativeCondition = mk<ram::Negation>(
souffle::clone(condition));
 
 1031             VecOwn<ram::Expression> returnTrue;
 
 1032             returnTrue.push_back(mk<ram::SignedConstant>(1));
 
 1035             VecOwn<ram::Expression> returnFalse;
 
 1036             returnFalse.push_back(mk<ram::SignedConstant>(0));
 
 1038             appendStmt(searchSequence, mk<ram::Query>(mk<ram::Filter>(std::move(condition),
 
 1039                                                mk<ram::SubroutineReturn>(std::move(returnTrue)))));
 
 1040             appendStmt(searchSequence, mk<ram::Query>(mk<ram::Filter>(std::move(negativeCondition),
 
 1041                                                mk<ram::SubroutineReturn>(std::move(returnFalse)))));
 
 1047     return mk<ram::Sequence>(std::move(searchSequence));
 
 1051     struct ADTsFuneral : 
public ast::NodeMapper {
 
 1052         mutable bool changed{
false};
 
 1053         const ast::analysis::SumTypeBranchesAnalysis& sumTypesBranches;
 
 
 
◆ makeRamTupleElement()
◆ makeSubproofSubroutine()
translate RAM code for subroutine to get subproofs 
make a subroutine to search for subproofs 
Definition at line 765 of file AstToRamTranslator.cpp.
  771     for (
auto bodyLit : ast::getBodyLiterals<ast::Constraint>(clause)) {
 
  779     ast::Atom* head = intermediateClause->getHead();
 
  781     auto args = head->getArguments();
 
  782     for (
size_t i = 0; 
i < head->getArity() - auxiliaryArity; 
i++) {
 
  785         if (
auto var = 
dynamic_cast<ast::Variable*
>(arg)) {
 
  787             auto constraint = mk<ast::BinaryConstraint>(
 
  790             intermediateClause->addToBody(std::move(constraint));
 
  791         } 
else if (
auto func = 
dynamic_cast<ast::Functor*
>(arg)) {
 
  793             if (
auto* inf = 
dynamic_cast<ast::IntrinsicFunctor*
>(func)) {
 
  794                 assert(inf->getFinalReturnType().has_value() && 
"functor has missing return type");
 
  795                 returnType = inf->getFinalReturnType().value();
 
  796             } 
else if (
auto* udf = 
dynamic_cast<ast::UserDefinedFunctor*
>(func)) {
 
  797                 assert(udf->getFinalReturnType().has_value() && 
"functor has missing return type");
 
  798                 returnType = udf->getFinalReturnType().value();
 
  800                 assert(
false && 
"unexpected functor type");
 
  804                     mk<ast::BinaryConstraint>(opEq, 
souffle::clone(func), mk<ast::SubroutineArgument>(
i));
 
  805             constraint->setFinalType(opEq);
 
  806             intermediateClause->addToBody(std::move(constraint));
 
  807         } 
else if (
auto rec = 
dynamic_cast<ast::RecordInit*
>(arg)) {
 
  808             auto constraint = mk<ast::BinaryConstraint>(
 
  811             intermediateClause->addToBody(std::move(constraint));
 
  816     size_t levelIndex = head->getArguments().size() - auxiliaryArity;
 
  819     const auto& bodyLiterals = intermediateClause->getBodyLiterals();
 
  820     for (
auto lit : bodyLiterals) {
 
  821         if (
auto atom = 
dynamic_cast<ast::Atom*
>(lit)) {
 
  822             auto arity = atom->getArity();
 
  823             auto atomArgs = atom->getArguments();
 
  826                     souffle::clone(atomArgs[arity - 1]), mk<ast::SubroutineArgument>(levelIndex));
 
  828             intermediateClause->addToBody(std::move(constraint));
 
  831     return ProvenanceClauseTranslator(*this).translateClause(*intermediateClause, clause);
 
 
References souffle::clone().
 
 
◆ nameUnnamedVariables()
  
  | 
        
          | void souffle::ast2ram::AstToRamTranslator::nameUnnamedVariables | ( | ast::Clause * | clause | ) |  |  | private | 
 
assigns names to unnamed variables such that enclosing constructs may be cloned without losing the variable-identity 
A utility function assigning names to unnamed variables such that enclosing constructs may be cloned without losing the variable-identity. 
Definition at line 519 of file AstToRamTranslator.cpp.
  525             if (
dynamic_cast<ast::UnnamedVariable*
>(node.get()) != 
nullptr) {
 
  526                 auto name = 
" _unnamed_var" + 
toString(++counter);
 
  527                 return mk<ast::Variable>(name);
 
  537     for (
auto& atom : ast::getBodyLiterals<ast::Atom>(*clause)) {
 
 
References souffle::toString().
 
 
◆ removeADTs()
  
  | 
        
          | bool souffle::ast2ram::AstToRamTranslator::removeADTs | ( | const ast::TranslationUnit & | translationUnit | ) |  |  | staticprivate | 
 
replace ADTs with special records 
Definition at line 1056 of file AstToRamTranslator.cpp.
 1056                 : sumTypesBranches(*tu.getAnalysis<ast::analysis::SumTypeBranchesAnalysis>()) {}
 
 1058         Own<ast::Node> operator()(Own<ast::Node> node)
 const override {
 
 1062             if (!isA<ast::BranchInit>(node)) {
 
 1067             auto& adt = *as<ast::BranchInit>(node);
 
 1068             auto& 
type = sumTypesBranches.unsafeGetType(adt.getConstructor());
 
 1069             auto& branches = 
type.getBranches();
 
 1072             ast::analysis::AlgebraicDataType::Branch searchDummy{adt.getConstructor(), {}};
 
 1073             auto iterToBranch = std::lower_bound(branches.begin(), branches.end(), searchDummy,
 
 1074                     [](
const ast::analysis::AlgebraicDataType::Branch& left,
 
 1075                             const ast::analysis::AlgebraicDataType::Branch& right) {
 
 1076                         return left.name < right.name;
 
 1080             auto branchID = std::distance(std::begin(branches), iterToBranch);
 
 1083                 auto branchTag = mk<ast::NumericConstant>(branchID);
 
 1088                 VecOwn<ast::Argument> branchArguments;
 
 1089                 for (
auto* arg : adt.getArguments()) {
 
 1090                     branchArguments.emplace_back(arg->clone());
 
 1095                 auto branchArgs = [&]() -> Own<ast::Argument> {
 
 1096                     if (branchArguments.size() != 1) {
 
 1097                         return mk<ast::Argument, ast::RecordInit>(std::move(branchArguments));
 
 1099                         return std::move(branchArguments.at(0));
 
 1104                 VecOwn<ast::Argument> finalRecordArgs;
 
 1106                 auto branchTag = mk<ast::NumericConstant>(branchID);
 
 1108                 finalRecordArgs.push_back(std::move(branchTag));
 
 1109                 finalRecordArgs.push_back(std::move(branchArgs));
 
 1111                 return mk<ast::RecordInit>(std::move(finalRecordArgs), adt.getSrcLoc());
 
 1116     ADTsFuneral mapper(translationUnit);
 
 1117     translationUnit.getProgram().apply(mapper);
 
 1118     return mapper.changed;
 
 1124     ioType = translationUnit.getAnalysis<ast::analysis::IOTypeAnalysis>();
 
 1125     typeEnv = &translationUnit.getAnalysis<ast::analysis::TypeEnvironmentAnalysis>()->getTypeEnvironment();
 
 
 
◆ translateConstant()
translate RAM code for a constant value 
Definition at line 437 of file AstToRamTranslator.cpp.
  437                                            : 
return mk<ram::UnsignedConstant>(rawConstant);
 
  442     return mk<ram::SignedConstant>(rawConstant);
 
  447         const ast::Relation& 
rel, 
const ast::analysis::RecursiveClausesAnalysis* recursiveClauses) {
 
  449     VecOwn<ram::Statement> res;
 
 
 
◆ translateConstraint()
translate an AST constraint to a RAM condition 
for atoms
for binary relations
for provenance negation
for negations
Definition at line 340 of file AstToRamTranslator.cpp.
  343                 const ast::analysis::PolymorphicObjectsAnalysis* 
polyAnalysis)
 
  347         Own<ram::Condition> visitAtom(
const ast::Atom&)
 override {
 
  352         Own<ram::Condition> visitBinaryConstraint(
const ast::BinaryConstraint& binRel)
 override {
 
  353             assert(binRel.getFinalType().has_value() && 
"binary constraint has unset type");
 
  354             auto valLHS = translator.translateValue(binRel.getLHS(), index);
 
  355             auto valRHS = translator.translateValue(binRel.getRHS(), index);
 
  356             return mk<ram::Constraint>(binRel.getFinalType().value(), std::move(valLHS), std::move(valRHS));
 
  360         Own<ram::Condition> visitProvenanceNegation(
const ast::ProvenanceNegation& neg)
 override {
 
  361             const auto* atom = neg.getAtom();
 
  362             size_t auxiliaryArity = translator.getEvaluationArity(atom);
 
  363             assert(auxiliaryArity <= atom->getArity() && 
"auxiliary arity out of bounds");
 
  364             size_t arity = atom->getArity() - auxiliaryArity;
 
  365             VecOwn<ram::Expression> values;
 
  367             auto args = atom->getArguments();
 
  368             for (
size_t i = 0; 
i < arity; 
i++) {
 
  369                 values.push_back(translator.translateValue(args[
i], index));
 
  374                 values.push_back(mk<ram::UndefValue>());
 
  376                 for (
size_t height = 1; height < auxiliaryArity; height++) {
 
  377                     values.push_back(translator.translateValue(args[arity + height], index));
 
  380             return mk<ram::Negation>(
 
  381                     mk<ram::ProvenanceExistenceCheck>(translator.translateRelation(atom), std::move(values)));
 
  385         Own<ram::Condition> visitNegation(
const ast::Negation& neg)
 override {
 
  386             const auto* atom = neg.getAtom();
 
  387             size_t auxiliaryArity = translator.getEvaluationArity(atom);
 
  388             assert(auxiliaryArity <= atom->getArity() && 
"auxiliary arity out of bounds");
 
  389             size_t arity = atom->getArity() - auxiliaryArity;
 
  393                 return mk<ram::EmptinessCheck>(translator.translateRelation(atom));
 
  397             VecOwn<ram::Expression> values;
 
  398             auto args = atom->getArguments();
 
  399             for (
size_t i = 0; 
i < arity; 
i++) {
 
  400                 values.push_back(translator.translateValue(args[
i], index));
 
  402             for (
size_t i = 0; 
i < auxiliaryArity; 
i++) {
 
  403                 values.push_back(mk<ram::UndefValue>());
 
  405             return mk<ram::Negation>(
 
  406                     mk<ram::ExistenceCheck>(translator.translateRelation(atom), std::move(values)));
 
  409     return ConstraintTranslator(*
this, index, 
polyAnalysis)(*lit);
 
  413     if (
auto strConstant = 
dynamic_cast<const ast::StringConstant*
>(&constant)) {
 
  415     } 
else if (isA<ast::NilConstant>(&constant)) {
 
 
 
 
◆ translateDeltaRelation()
  
  | 
        
          | std::string souffle::ast2ram::AstToRamTranslator::translateDeltaRelation | ( | const ast::Relation * | rel | ) |  |  | private | 
 
translate a temporary delta relation to a RAM relation for semi-naive evaluation 
Definition at line 228 of file AstToRamTranslator.cpp.
 
 
◆ translateNewRelation()
  
  | 
        
          | std::string souffle::ast2ram::AstToRamTranslator::translateNewRelation | ( | const ast::Relation * | rel | ) |  |  | private | 
 
translate a temporary new relation to a RAM relation for semi-naive evaluation 
Definition at line 232 of file AstToRamTranslator.cpp.
  235                           : 
public ast::Visitor<Own<ram::Expression>> {
 
 
 
◆ translateNonRecursiveRelation()
translate RAM code for the non-recursive clauses of the given relation. 
generate RAM code for a non-recursive relation
- Returns
- a corresponding statement or null if there are no non-recursive clauses. 
Definition at line 452 of file AstToRamTranslator.cpp.
  456         if (recursiveClauses->recursive(clause)) {
 
  461         Own<ram::Statement> 
rule = ClauseTranslator(*this).translateClause(*clause, *clause);
 
  465             const std::string& relationName = 
toString(
rel.getQualifiedName());
 
  466             const SrcLocation& srcLocation = clause->getSrcLoc();
 
  468             const std::string logTimerStatement =
 
  470             const std::string logSizeStatement =
 
  472             rule = mk<ram::LogRelationTimer>(std::move(
rule), logTimerStatement, relName);
 
  476         std::ostringstream ds;
 
  477         ds << 
toString(*clause) << 
"\nin file ";
 
  478         ds << clause->getSrcLoc();
 
  479         rule = mk<ram::DebugInfo>(std::move(
rule), ds.str());
 
  487         const std::string& relationName = 
toString(
rel.getQualifiedName());
 
  488         const SrcLocation& srcLocation = 
rel.getSrcLoc();
 
  493             const std::string logTimerStatement =
 
  496                     mk<ram::LogRelationTimer>(mk<ram::Sequence>(std::move(res)), logTimerStatement, relName);
 
  501             appendStmt(res, mk<ram::LogSize>(relName, logSizeStatement));
 
  506     return mk<ram::Sequence>(std::move(res));
 
 
References souffle::ast2ram::appendStmt(), souffle::Global::config(), souffle::LogStatement::nNonrecursiveRule(), rel(), rule, souffle::stringify(), souffle::LogStatement::tNonrecursiveRule(), souffle::toString(), and souffle::ast2ram::ClauseTranslator::translateClause().
 
 
◆ translateProgram()
  
  | 
        
          | void souffle::ast2ram::AstToRamTranslator::translateProgram | ( | const ast::TranslationUnit & | translationUnit | ) |  |  | private | 
 
translate AST to RAM Program 
translates the given datalog program into an equivalent RAM program 
 
Definition at line 1128 of file AstToRamTranslator.cpp.
 1155     std::string sipsChosen = 
"all-bound";
 
 1165     if (sccGraph.getNumberOfSCCs() == 0) 
return;
 
 1168     const auto& makeRamLoad = [&](VecOwn<ram::Statement>& current, 
const ast::Relation* 
relation) {
 
 1174                 statement = mk<ram::LogRelationTimer>(
 
 1182     const auto& makeRamStore = [&](VecOwn<ram::Statement>& current, 
const ast::Relation* 
relation) {
 
 1188                 statement = mk<ram::LogRelationTimer>(
 
 1196     const auto& makeRamClear = [&](VecOwn<ram::Statement>& current, 
const ast::Relation* 
relation) {
 
 1201     for (
const auto& scc : sccOrder.order()) {
 
 1202         const auto& isRecursive = sccGraph.isRecursive(scc);
 
 1203         const auto& allInterns = sccGraph.getInternalRelations(scc);
 
 1204         for (
const auto& 
rel : allInterns) {
 
 1205             std::string name = 
rel->getQualifiedName().toString();
 
 1206             auto arity = 
rel->getArity();
 
 1208             auto representation = 
rel->getRepresentation();
 
 1209             const auto& attributes = 
rel->getAttributes();
 
 1211             std::vector<std::string> attributeNames;
 
 1212             std::vector<std::string> attributeTypeQualifiers;
 
 1213             for (
size_t i = 0; 
i < 
rel->getArity(); ++
i) {
 
 1214                 attributeNames.push_back(attributes[
i]->getName());
 
 1216                     attributeTypeQualifiers.push_back(
 
 1220             ramRels[name] = mk<ram::Relation>(
 
 1221                     name, arity, auxiliaryArity, attributeNames, attributeTypeQualifiers, representation);
 
 1225                 std::string deltaName = 
"@delta_" + name;
 
 1226                 std::string newName = 
"@new_" + name;
 
 1227                 ramRels[deltaName] = mk<ram::Relation>(deltaName, arity, auxiliaryArity, attributeNames,
 
 1228                         attributeTypeQualifiers, representation);
 
 1229                 ramRels[newName] = mk<ram::Relation>(newName, arity, auxiliaryArity, attributeNames,
 
 1230                         attributeTypeQualifiers, representation);
 
 1236     size_t indexOfScc = 0;
 
 1239     for (
const auto& scc : sccOrder.order()) {
 
 1241         VecOwn<ram::Statement> current;
 
 1244         const auto& isRecursive = sccGraph.isRecursive(scc);
 
 1248         const auto& allInterns = sccGraph.getInternalRelations(scc);
 
 1249         const auto& internIns = sccGraph.getInternalInputRelations(scc);
 
 1250         const auto& internOuts = sccGraph.getInternalOutputRelations(scc);
 
 1253         const auto& internExps = expirySchedule.at(indexOfScc).expired();
 
 1256         for (
const auto& 
relation : internIns) {
 
 1261         Own<ram::Statement> bodyStatement =
 
 1263                                          *((
const ast::Relation*)*allInterns.begin()), recursiveClauses)
 
 1265         appendStmt(current, std::move(bodyStatement));
 
 1268         for (
const auto& 
relation : internOuts) {
 
 1274             for (
const auto& 
relation : internExps) {
 
 1280         ramSubs[
"stratum_" + std::to_string(indexOfScc)] = mk<ram::Sequence>(std::move(current));
 
 1285     VecOwn<ram::Statement> res;
 
 1286     for (
size_t i = 0; 
i < indexOfScc; 
i++) {
 
 1287         appendStmt(res, mk<ram::Call>(
"stratum_" + std::to_string(
i)));
 
 1298     ramMain = mk<ram::Sequence>(std::move(res));
 
 1303             std::stringstream relName;
 
 1304             relName << clause.getHead()->getQualifiedName();
 
 1307             if (relName.str().find(
"@info") != std::string::npos || clause.getBodyLiterals().empty()) {
 
 1311             std::string subroutineLabel =
 
 1315             std::string negationSubroutineLabel = relName.str() + 
"_" +
 
 1317                                                   "_negation_subproof";
 
 
 
 
◆ translateRecursiveRelation()
translate RAM code for recursive relations in a strongly-connected component 
generate RAM code for recursive relations in a strongly-connected component 
Definition at line 554 of file AstToRamTranslator.cpp.
  557         VecOwn<ram::Expression> values;
 
  558         if (
rel->getArity() == 0) {
 
  559             return mk<ram::Query>(mk<ram::Filter>(mk<ram::Negation>(mk<ram::EmptinessCheck>(srcRel)),
 
  560                     mk<ram::Project>(destRel, std::move(values))));
 
  562         for (std::size_t 
i = 0; 
i < 
rel->getArity(); 
i++) {
 
  563             values.push_back(mk<ram::TupleElement>(0, 
i));
 
  565         auto stmt = mk<ram::Query>(mk<ram::Scan>(srcRel, 0, mk<ram::Project>(destRel, std::move(values))));
 
  567             return mk<ram::Sequence>(mk<ram::Extend>(destRel, srcRel), std::move(stmt));
 
  576     for (
const ast::Relation* 
rel : scc) {
 
  578         Own<ram::Statement> updateRelTable =
 
  585             updateRelTable = mk<ram::LogRelationTimer>(std::move(updateRelTable),
 
  600         appendStmt(updateTable, std::move(updateRelTable));
 
  605     VecOwn<ram::Statement> loopSeq;
 
  608     auto isInSameSCC = [&](
const ast::Relation* 
rel) {
 
  609         return std::find(scc.begin(), scc.end(), 
rel) != scc.end();
 
  613     for (
const ast::Relation* 
rel : scc) {
 
  614         VecOwn<ram::Statement> loopRelSeq;
 
  619             if (!recursiveClauses->recursive(cl)) {
 
  625             const auto& atoms = ast::getBodyLiterals<ast::Atom>(*cl);
 
  626             for (
size_t j = 0; 
j < atoms.size(); ++
j) {
 
  627                 const ast::Atom* atom = atoms[
j];
 
  631                 if (!isInSameSCC(atomRelation)) {
 
  636                 Own<ast::Clause> r1(cl->clone());
 
  638                 ast::getBodyLiterals<ast::Atom>(*r1)[
j]->setQualifiedName(
 
  641                     r1->addToBody(mk<ast::ProvenanceNegation>(
souffle::clone(cl->getHead())));
 
  643                     if (r1->getHead()->getArity() > 0) {
 
  653                 for (
size_t k = 
j + 1; 
k < atoms.size(); 
k++) {
 
  657                         r1->addToBody(mk<ast::Negation>(std::move(cur)));
 
  661                 Own<ram::Statement> 
rule = ClauseTranslator(*this).translateClause(*r1, *cl, version);
 
  665                     const std::string& relationName = 
toString(
rel->getQualifiedName());
 
  666                     const SrcLocation& srcLocation = cl->getSrcLoc();
 
  668                     const std::string logTimerStatement =
 
  670                     const std::string logSizeStatement =
 
  672                     rule = mk<ram::LogRelationTimer>(
 
  677                 std::ostringstream ds;
 
  678                 ds << 
toString(*cl) << 
"\nin file ";
 
  679                 ds << cl->getSrcLoc();
 
  680                 rule = mk<ram::DebugInfo>(std::move(
rule), ds.str());
 
  689             if (cl->getExecutionPlan() != 
nullptr) {
 
  692                 for (
auto const& cur : cl->getExecutionPlan()->getOrders()) {
 
  693                     maxVersion = std::max(cur.first, maxVersion);
 
  695                 assert(version > maxVersion && 
"missing clause versions");
 
  700         if (loopRelSeq.size() == 0) {
 
  706             const std::string& relationName = 
toString(
rel->getQualifiedName());
 
  707             const SrcLocation& srcLocation = 
rel->getSrcLoc();
 
  710             auto newStmt = mk<ram::LogRelationTimer>(
 
  717         appendStmt(loopSeq, mk<ram::Sequence>(std::move(loopRelSeq)));
 
  719     auto loop = mk<ram::Parallel>(std::move(loopSeq));
 
  722     auto addCondition = [](Own<ram::Condition>& cond, Own<ram::Condition> clause) {
 
  723         cond = ((cond) ? mk<ram::Conjunction>(std::move(cond), std::move(clause)) : std::move(clause));
 
  726     Own<ram::Condition> exitCond;
 
  727     VecOwn<ram::Statement> exitStmts;
 
  728     for (
const ast::Relation* 
rel : scc) {
 
  731             Own<ram::Condition> limit =
 
  734             appendStmt(exitStmts, mk<ram::Exit>(std::move(limit)));
 
  739     VecOwn<ram::Statement> res;
 
  740     if (preamble.size() > 0) {
 
  741         appendStmt(res, mk<ram::Sequence>(std::move(preamble)));
 
  743     if (!loop->getStatements().empty() && exitCond && updateTable.size() > 0) {
 
  745                 mk<ram::Loop>(mk<ram::Sequence>(std::move(loop), mk<ram::Exit>(std::move(exitCond)),
 
  746                         mk<ram::Sequence>(std::move(exitStmts)), mk<ram::Sequence>(std::move(updateTable)))));
 
  748     if (postamble.size() > 0) {
 
  749         appendStmt(res, mk<ram::Sequence>(std::move(postamble)));
 
  751     if (res.size() > 0) {
 
  752         return mk<ram::Sequence>(std::move(res));
 
  755     fatal(
"Not Implemented");
 
  760     auto intermediateClause = mk<ast::Clause>(
souffle::clone(clause.getHead()));
 
 
References souffle::EQREL, i, and rel().
 
 
◆ translateRelation() [1/2]
      
        
          | std::string souffle::ast2ram::AstToRamTranslator::translateRelation | ( | const ast::Atom * | atom | ) |  | 
      
 
 
◆ translateRelation() [2/2]
      
        
          | std::string souffle::ast2ram::AstToRamTranslator::translateRelation | ( | const ast::Relation * | rel, | 
        
          |  |  | const std::string | relationNamePrefix = "" | 
        
          |  | ) |  |  | 
      
 
 
◆ translateUnit()
translates AST to translation unit 
Definition at line 1329 of file AstToRamTranslator.cpp.
 1333         rels.push_back(std::move(cur.second));
 
 1336         ramMain = mk<ram::Sequence>();
 
 1338     auto ramProg = mk<ram::Program>(std::move(rels), std::move(
ramMain), std::move(
ramSubs));
 
 1342             std::string runtimeStr =
 
 1343                     "(" + std::to_string(std::chrono::duration<double>(ram_end - ram_start).
count()) + 
"s)";
 
 1344             std::stringstream ramProgStr;
 
 1345             ramProgStr << *ramProg;
 
 1346             debugReport.addSection(
"ram-program", 
"RAM Program " + runtimeStr, ramProgStr.str());
 
 1349     return mk<ram::TranslationUnit>(std::move(ramProg), std::move(symTab), errReport, debugReport);
 
 
 
 
◆ translateValue()
translate an AST argument to a RAM value 
Definition at line 236 of file AstToRamTranslator.cpp.
  242                 const ast::analysis::PolymorphicObjectsAnalysis* 
polyAnalysis)
 
  245         Own<ram::Expression> visitVariable(
const ast::Variable& var)
 override {
 
  246             if (!index.isDefined(var)) 
fatal(
"variable `%s` is not grounded", var);
 
  250         Own<ram::Expression> visitUnnamedVariable(
const ast::UnnamedVariable&)
 override {
 
  251             return mk<ram::UndefValue>();
 
  254         Own<ram::Expression> visitNumericConstant(
const ast::NumericConstant& c)
 override {
 
  255             assert(c.getFinalType().has_value() && 
"constant should have valid type");
 
  256             switch (c.getFinalType().value()) {
 
  265             fatal(
"unexpected numeric constant type");
 
  268         Own<ram::Expression> visitStringConstant(
const ast::StringConstant& c)
 override {
 
  269             return mk<ram::SignedConstant>(translator.getSymbolTable().lookup(c.getConstant()));
 
  272         Own<ram::Expression> visitNilConstant(
const ast::NilConstant&)
 override {
 
  273             return mk<ram::SignedConstant>(0);
 
  276         Own<ram::Expression> visitTypeCast(
const ast::TypeCast& typeCast)
 override {
 
  277             return translator.translateValue(typeCast.getValue(), index);
 
  280         Own<ram::Expression> visitIntrinsicFunctor(
const ast::IntrinsicFunctor& inf)
 override {
 
  281             VecOwn<ram::Expression> values;
 
  282             for (
const auto& cur : inf.getArguments()) {
 
  283                 values.push_back(translator.translateValue(cur, index));
 
  287                 return translator.makeRamTupleElement(index.getGeneratorLoc(inf));
 
  289                 return mk<ram::IntrinsicOperator>(inf.getFinalOpType().value(), std::move(values));
 
  293         Own<ram::Expression> visitUserDefinedFunctor(
const ast::UserDefinedFunctor& udf)
 override {
 
  294             VecOwn<ram::Expression> values;
 
  295             for (
const auto& cur : udf.getArguments()) {
 
  296                 values.push_back(translator.translateValue(cur, index));
 
  298             auto returnType = translator.functorAnalysis->getReturnType(&udf);
 
  299             auto argTypes = translator.functorAnalysis->getArgTypes(udf);
 
  300             return mk<ram::UserDefinedOperator>(udf.getName(), argTypes, returnType,
 
  301                     translator.functorAnalysis->isStateful(&udf), std::move(values));
 
  304         Own<ram::Expression> visitCounter(
const ast::Counter&)
 override {
 
  305             return mk<ram::AutoIncrement>();
 
  308         Own<ram::Expression> visitRecordInit(
const ast::RecordInit& init)
 override {
 
  309             VecOwn<ram::Expression> values;
 
  310             for (
const auto& cur : init.getArguments()) {
 
  311                 values.push_back(translator.translateValue(cur, index));
 
  313             return mk<ram::PackRecord>(std::move(values));
 
  316         Own<ram::Expression> visitAggregator(
const ast::Aggregator& agg)
 override {
 
  318             return translator.makeRamTupleElement(index.getGeneratorLoc(agg));
 
  321         Own<ram::Expression> visitSubroutineArgument(
const ast::SubroutineArgument& subArg)
 override {
 
  322             return mk<ram::SubroutineArgument>(subArg.getNumber());
 
  326     return ValueTranslator(*
this, index, 
polyAnalysis)(*arg);
 
  330     static SymbolTable symbolTable;
 
 
Referenced by souffle::ast2ram::ProvenanceClauseTranslator::createOperation(), and souffle::ast2ram::ClauseTranslator::translateClause().
 
 
◆ auxArityAnalysis
◆ functorAnalysis
◆ ioType
◆ polyAnalysis
◆ program
  
  | 
        
          | const ast::Program* souffle::ast2ram::AstToRamTranslator::program = nullptr |  | private | 
 
 
◆ ramMain
◆ ramRels
  
  | 
        
          | std::map<std::string, Own<ram::Relation> > souffle::ast2ram::AstToRamTranslator::ramRels |  | private | 
 
 
◆ ramSubs
  
  | 
        
          | std::map<std::string, Own<ram::Statement> > souffle::ast2ram::AstToRamTranslator::ramSubs |  | private | 
 
 
◆ sips
◆ typeEnv
The documentation for this class was generated from the following files:
 
Own< ast::SipsMetric > sips
SIPS metric for reordering.
static const std::string nNonrecursiveRule(const std::string &relationName, const SrcLocation &srcLocation, const std::string &datalogText)
RamSigned RamSignedFromString(const std::string &str, std::size_t *position=nullptr, const int base=10)
Converts a string to a RamSigned.
static bool isMultiResult(const Functor &functor)
RamDomain getConstantRamRepresentation(const ast::Constant &constant)
Get ram representation of constant.
Own< ram::Statement > ramMain
RAM program.
Own< ram::Statement > translateNonRecursiveRelation(const ast::Relation &rel, const ast::analysis::RecursiveClausesAnalysis *recursiveClauses)
translate RAM code for the non-recursive clauses of the given relation.
NumericConstant::Type getInferredType(const NumericConstant *nc) const
static const std::string cRecursiveRelation(const std::string &relationName, const SrcLocation &srcLocation)
const ast::analysis::AuxiliaryArityAnalysis * auxArityAnalysis
Auxiliary Arity Analysis.
bool isADTEnum(const AlgebraicDataType &type)
Determine if ADT is enumerations (are all constructors empty)
std::map< std::string, Own< ram::Statement > > ramSubs
Subroutines.
const Type & getType(const QualifiedName &) const
static const std::string tRecursiveRelation(const std::string &relationName, const SrcLocation &srcLocation)
void nameUnnamedVariables(ast::Clause *clause)
assigns names to unnamed variables such that enclosing constructs may be cloned without losing the va...
size_t getClauseNum(const Program *program, const Clause *clause)
Returns the index of a clause within its relation, ignoring facts.
static const std::string runtime()
const ast::analysis::FunctorAnalysis * functorAnalysis
Functors' analysis.
std::string translateDeltaRelation(const ast::Relation *rel)
translate a temporary delta relation to a RAM relation for semi-naive evaluation
std::vector< std::map< std::string, std::string > > getInputDirectives(const ast::Relation *rel)
FunctorOp getOverloadedFunctionOp(const IntrinsicFunctor *inf) const
const ast::Program * program
AST program.
std::map< std::string, Own< ram::Relation > > ramRels
RAM relations.
std::string translateRelation(const ast::Atom *atom)
a utility to translate atoms to relations
std::string unescape(const std::string &inputString, const std::string &needle, const std::string &replacement)
bool isLimitSize(const Relation *relation) const
static std::unique_ptr< SipsMetric > create(const std::string &heuristic, const TranslationUnit &tu)
Create a SIPS metric based on a given heuristic.
static const std::string nRecursiveRule(const std::string &relationName, const int version, const SrcLocation &srcLocation, const std::string &datalogText)
const std::string & toString(const std::string &str)
A generic function converting strings into strings (trivial case).
RamDomain lookup(const std::string &symbol)
Find the index of a symbol in the table, inserting a new symbol if it does not exist there already.
static const std::string nRecursiveRelation(const std::string &relationName, const SrcLocation &srcLocation)
std::string stringify(const std::string &input)
Stringify a string using escapes for escape, newline, tab, double-quotes and semicolons.
auto clone(const std::vector< A * > &xs)
detail::joined_sequence< Iter, Printer > join(const Iter &a, const Iter &b, const std::string &sep, const Printer &p)
Creates an object to be forwarded to some output stream for printing sequences of elements interspers...
Own< ram::Condition > translateConstraint(const ast::Literal *arg, const ValueIndex &index)
translate an AST constraint to a RAM condition
static const std::string tNonrecursiveRelation(const std::string &relationName, const SrcLocation &srcLocation)
static const std::string tNonrecursiveRule(const std::string &relationName, const SrcLocation &srcLocation, const std::string &datalogText)
const ast::analysis::PolymorphicObjectsAnalysis * polyAnalysis
Polymorphic Objects Analysis.
TypeAttribute getReturnType(const Functor *functor) const
Return return type of functor.
Own< ram::Statement > makeNegationSubproofSubroutine(const ast::Clause &clause)
translate RAM code for subroutine to get subproofs for non-existence of a tuple
constexpr auto get(span< E, S > s) -> decltype(s[N])
static const std::string tRelationLoadTime(const std::string &relationName, const SrcLocation &srcLocation)
const ast::analysis::TypeEnvironment * typeEnv
Type environment.
std::vector< Clause * > getClauses(const Program &program, const QualifiedName &relationName)
Returns a vector of clauses in the program describing the relation with the given name.
std::vector< Directive * > getDirectives() const
Return relation directives.
void translateProgram(const ast::TranslationUnit &translationUnit)
translate AST to RAM Program
static bool removeADTs(const ast::TranslationUnit &translationUnit)
replace ADTs with special records
static std::string getRelationName(const ast::QualifiedName &id)
converts the given relation identifier into a relation name
std::string translateNewRelation(const ast::Relation *rel)
translate a temporary new relation to a RAM relation for semi-naive evaluation
std::vector< Own< Directive > > directives
void appendStmt(VecOwn< ram::Statement > &stmtList, Own< ram::Statement > stmt)
append statement to a list of statements
std::size_t getLimitSize(const Relation *relation) const
static MainConfig & config()
static Own< ram::TupleElement > makeRamTupleElement(const Location &loc)
create a RAM element access node
Own< ram::Statement > makeSubproofSubroutine(const ast::Clause &clause)
translate RAM code for subroutine to get subproofs
SymbolTable & getSymbolTable()
Return a symbol table.
static const std::string nNonrecursiveRelation(const std::string &relationName, const SrcLocation &srcLocation)
static const std::string tRecursiveRule(const std::string &relationName, const int version, const SrcLocation &srcLocation, const std::string &datalogText)
void fatal(const char *format, const Args &... args)
Own< ram::Expression > translateValue(const ast::Argument *arg, const ValueIndex &index)
translate an AST argument to a RAM value
size_t getArity(const Atom *atom) const
Returns the number of auxiliary parameters of an atom's relation.
const ast::analysis::IOTypeAnalysis * ioType
IO Type.
RamUnsigned RamUnsignedFromString(const std::string &str, std::size_t *position=nullptr, const int base=10)
Converts a string to a RamUnsigned.
const Relation * getAtomRelation(const Atom *atom, const Program *program)
Returns the relation referenced by the given atom.
Own< ram::TranslationUnit > translateUnit(ast::TranslationUnit &tu)
translates AST to translation unit
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-...
Own< ram::Expression > translateConstant(ast::Constant const &c)
translate RAM code for a constant value
static const std::string tRelationSaveTime(const std::string &relationName, const SrcLocation &srcLocation)
std::string getTypeQualifier(const Type &type)
Returns full type qualifier for a given type.
RamFloat RamFloatFromString(const std::string &str, std::size_t *position=nullptr)
Converts a string to a RamFloat.
void rel(size_t limit, bool showLimit=true)
BinaryConstraintOp getOverloadedOperator(const BinaryConstraint *bc) const
std::vector< std::map< std::string, std::string > > getOutputDirectives(const ast::Relation *rel)
Own< ram::Statement > translateRecursiveRelation(const std::set< const ast::Relation * > &scc, const ast::analysis::RecursiveClausesAnalysis *recursiveClauses)
translate RAM code for recursive relations in a strongly-connected component