souffle  2.0.2-371-g6315b36
Public Member Functions | Static Public Member Functions | Private Member Functions | Static Private Member Functions | Private Attributes
souffle::ast2ram::AstToRamTranslator Class Reference

Main class for the AST->RAM translator. More...

#include <AstToRamTranslator.h>

Collaboration diagram for souffle::ast2ram::AstToRamTranslator:
Collaboration graph

Public Member Functions

 AstToRamTranslator ()
 
const ast::analysis::AuxiliaryArityAnalysisgetAuxArityAnalysis () const
 
size_t getEvaluationArity (const ast::Atom *atom) const
 determine the auxiliary for relations More...
 
const ast::analysis::FunctorAnalysisgetFunctorAnalysis () const
 
const ast::analysis::PolymorphicObjectsAnalysisgetPolymorphicObjectsAnalysis () const
 
const ast::SipsMetricgetSipsMetric () const
 
const ram::RelationlookupRelation (const std::string &name) const
 
Own< ram::ExpressiontranslateConstant (ast::Constant const &c)
 translate RAM code for a constant value More...
 
Own< ram::ConditiontranslateConstraint (const ast::Literal *arg, const ValueIndex &index)
 translate an AST constraint to a RAM condition More...
 
std::string translateRelation (const ast::Atom *atom)
 a utility to translate atoms to relations More...
 
std::string translateRelation (const ast::Relation *rel, const std::string relationNamePrefix="")
 translate an AST relation to a RAM relation More...
 
Own< ram::TranslationUnittranslateUnit (ast::TranslationUnit &tu)
 translates AST to translation unit More...
 
Own< ram::ExpressiontranslateValue (const ast::Argument *arg, const ValueIndex &index)
 translate an AST argument to a RAM value More...
 
 ~AstToRamTranslator ()
 

Static Public Member Functions

static Own< ram::TupleElementmakeRamTupleElement (const Location &loc)
 create a RAM element access node More...
 

Private Member Functions

RamDomain getConstantRamRepresentation (const ast::Constant &constant)
 Get ram representation of constant. More...
 
std::vector< std::map< std::string, std::string > > getInputDirectives (const ast::Relation *rel)
 
std::vector< std::map< std::string, std::string > > getOutputDirectives (const ast::Relation *rel)
 
SymbolTablegetSymbolTable ()
 Return a symbol table. More...
 
Own< ram::StatementmakeNegationSubproofSubroutine (const ast::Clause &clause)
 translate RAM code for subroutine to get subproofs for non-existence of a tuple More...
 
Own< ram::StatementmakeSubproofSubroutine (const ast::Clause &clause)
 translate RAM code for subroutine to get subproofs More...
 
void nameUnnamedVariables (ast::Clause *clause)
 assigns names to unnamed variables such that enclosing constructs may be cloned without losing the variable-identity More...
 
std::string translateDeltaRelation (const ast::Relation *rel)
 translate a temporary delta relation to a RAM relation for semi-naive evaluation More...
 
std::string translateNewRelation (const ast::Relation *rel)
 translate a temporary new relation to a RAM relation for semi-naive evaluation More...
 
Own< ram::StatementtranslateNonRecursiveRelation (const ast::Relation &rel, const ast::analysis::RecursiveClausesAnalysis *recursiveClauses)
 translate RAM code for the non-recursive clauses of the given relation. More...
 
void translateProgram (const ast::TranslationUnit &translationUnit)
 translate AST to RAM Program More...
 
Own< ram::StatementtranslateRecursiveRelation (const std::set< const ast::Relation * > &scc, const ast::analysis::RecursiveClausesAnalysis *recursiveClauses)
 translate RAM code for recursive relations in a strongly-connected component More...
 

Static Private Member Functions

static std::string getRelationName (const ast::QualifiedName &id)
 converts the given relation identifier into a relation name More...
 
static bool removeADTs (const ast::TranslationUnit &translationUnit)
 replace ADTs with special records More...
 

Private Attributes

const ast::analysis::AuxiliaryArityAnalysisauxArityAnalysis = nullptr
 Auxiliary Arity Analysis. More...
 
const ast::analysis::FunctorAnalysisfunctorAnalysis = nullptr
 Functors' analysis. More...
 
const ast::analysis::IOTypeAnalysisioType = nullptr
 IO Type. More...
 
const ast::analysis::PolymorphicObjectsAnalysispolyAnalysis = nullptr
 Polymorphic Objects Analysis. More...
 
const ast::Programprogram = nullptr
 AST program. More...
 
Own< ram::StatementramMain
 RAM program. More...
 
std::map< std::string, Own< ram::Relation > > ramRels
 RAM relations. More...
 
std::map< std::string, Own< ram::Statement > > ramSubs
 Subroutines. More...
 
Own< ast::SipsMetricsips
 SIPS metric for reordering. More...
 
const ast::analysis::TypeEnvironmenttypeEnv = nullptr
 Type environment. More...
 

Detailed Description

Main class for the AST->RAM translator.

Definition at line 71 of file AstToRamTranslator.h.

Constructor & Destructor Documentation

◆ AstToRamTranslator()

souffle::ast2ram::AstToRamTranslator::AstToRamTranslator ( )
default

◆ ~AstToRamTranslator()

souffle::ast2ram::AstToRamTranslator::~AstToRamTranslator ( )
default

Member Function Documentation

◆ getAuxArityAnalysis()

const ast::analysis::AuxiliaryArityAnalysis* souffle::ast2ram::AstToRamTranslator::getAuxArityAnalysis ( ) const
inline

Definition at line 76 of file AstToRamTranslator.h.

76  {
77  return auxArityAnalysis;
78  }

References auxArityAnalysis.

◆ getConstantRamRepresentation()

RamDomain souffle::ast2ram::AstToRamTranslator::getConstantRamRepresentation ( const ast::Constant constant)
private

Get ram representation of constant.

Definition at line 418 of file AstToRamTranslator.cpp.

419  {
421  return RamSignedFromString(numConstant->getConstant(), nullptr, 0);
423  return RamUnsignedFromString(numConstant->getConstant(), nullptr, 0);
424  case ast::NumericConstant::Type::Float: return RamFloatFromString(numConstant->getConstant());
425  }
426  }
427 
428  fatal("unaccounted-for constant");
429 }
430 
431 Own<ram::Expression> AstToRamTranslator::translateConstant(ast::Constant const& c) {
432  auto const rawConstant = getConstantRamRepresentation(c);
433 
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.

157  {
158  return 0;
159  } else {
160  return auxArityAnalysis->getArity(atom);
161  }
162 }
163 
164 std::vector<std::map<std::string, std::string>> AstToRamTranslator::getInputDirectives(
165  const ast::Relation* rel) {
166  std::vector<std::map<std::string, std::string>> inputDirectives;
167 
168  for (const auto* load : program->getDirectives()) {

◆ getFunctorAnalysis()

const ast::analysis::FunctorAnalysis* souffle::ast2ram::AstToRamTranslator::getFunctorAnalysis ( ) const
inline

Definition at line 80 of file AstToRamTranslator.h.

80  {
81  return functorAnalysis;
82  }

References functorAnalysis.

◆ 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.

170  {
171  continue;
172  }
173 
174  std::map<std::string, std::string> directives;
175  for (const auto& currentPair : load->getParameters()) {
176  directives.insert(std::make_pair(currentPair.first, unescape(currentPair.second)));
177  }
178  inputDirectives.push_back(directives);
179  }
180 
181  if (inputDirectives.empty()) {
182  inputDirectives.emplace_back();
183  }
184 
185  return inputDirectives;
186 }
187 
188 std::vector<std::map<std::string, std::string>> AstToRamTranslator::getOutputDirectives(
189  const ast::Relation* rel) {
190  std::vector<std::map<std::string, std::string>> outputDirectives;
191 
192  for (const auto* store : program->getDirectives()) {

◆ 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.

195  {
196  continue;
197  }
198 
199  std::map<std::string, std::string> directives;
200  for (const auto& currentPair : store->getParameters()) {
201  directives.insert(std::make_pair(currentPair.first, unescape(currentPair.second)));
202  }
203  outputDirectives.push_back(directives);
204  }
205 
206  if (outputDirectives.empty()) {
207  outputDirectives.emplace_back();
208  }
209 
210  return outputDirectives;
211 }
212 
213 std::string AstToRamTranslator::translateRelation(const ast::Atom* atom) {
214  return getRelationName(atom->getQualifiedName());
215 }
216 

◆ getPolymorphicObjectsAnalysis()

const ast::analysis::PolymorphicObjectsAnalysis* souffle::ast2ram::AstToRamTranslator::getPolymorphicObjectsAnalysis ( ) const
inline

Definition at line 84 of file AstToRamTranslator.h.

84  {
85  return polyAnalysis;
86  }

References polyAnalysis.

◆ 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.

549  {
550  // initialize sections
551  VecOwn<ram::Statement> preamble;

◆ getSipsMetric()

const ast::SipsMetric* souffle::ast2ram::AstToRamTranslator::getSipsMetric ( ) const
inline

Definition at line 88 of file AstToRamTranslator.h.

88  {
89  return sips.get();
90  }

References sips.

◆ getSymbolTable()

SymbolTable & souffle::ast2ram::AstToRamTranslator::getSymbolTable ( )
private

Return a symbol table.

Definition at line 335 of file AstToRamTranslator.cpp.

335  {
336  class ConstraintTranslator : public ast::Visitor<Own<ram::Condition>> {
337  AstToRamTranslator& translator;
338  const ValueIndex& index;

References polyAnalysis.

◆ lookupRelation()

const ram::Relation* souffle::ast2ram::AstToRamTranslator::lookupRelation ( const std::string &  name) const
inline

Definition at line 116 of file AstToRamTranslator.h.

116  {
117  auto it = ramRels.find(name);
118  assert(it != ramRels.end() && "relation not found");
119  return (*it).second.get();
120  }

References ramRels.

◆ makeNegationSubproofSubroutine()

Own< ram::Statement > souffle::ast2ram::AstToRamTranslator::makeNegationSubproofSubroutine ( const ast::Clause clause)
private

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()) {
851  // first add all the things that are not constraints
852  if (!isA<ast::Constraint>(bodyLit)) {
853  clauseReplacedAggregates->addToBody(souffle::clone(bodyLit));
854  }
855  }
856 
857  // now add all constraints
858  for (auto bodyLit : ast::getBodyLiterals<ast::Constraint>(clause)) {
859  clauseReplacedAggregates->addToBody(souffle::clone(bodyLit));
860  }
861 
862  int aggNumber = 0;
863  struct AggregatesToVariables : public ast::NodeMapper {
864  int& aggNumber;
865 
866  AggregatesToVariables(int& aggNumber) : aggNumber(aggNumber) {}
867 
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++));
871  }
872 
873  node->apply(*this);
874  return node;
875  }
876  };
877 
878  AggregatesToVariables aggToVar(aggNumber);
879  clauseReplacedAggregates->apply(aggToVar);
880 
881  // build a vector of unique variables
882  std::vector<const ast::Variable*> uniqueVariables;
883 
884  visitDepthFirst(*clauseReplacedAggregates, [&](const ast::Variable& var) {
885  if (var.getName().find("@level_num") == std::string::npos) {
886  // use find_if since uniqueVariables stores pointers, and we need to dereference the pointer to
887  // check equality
888  if (std::find_if(uniqueVariables.begin(), uniqueVariables.end(),
889  [&](const ast::Variable* v) { return *v == var; }) == uniqueVariables.end()) {
890  uniqueVariables.push_back(&var);
891  }
892  }
893  });
894 
895  // a mapper to replace variables with subroutine arguments
896  struct VariablesToArguments : public ast::NodeMapper {
897  const std::vector<const ast::Variable*>& uniqueVariables;
898 
899  VariablesToArguments(const std::vector<const ast::Variable*>& uniqueVariables)
900  : uniqueVariables(uniqueVariables) {}
901 
902  Own<ast::Node> operator()(Own<ast::Node> node) const override {
903  // replace unknown variables
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();
909 
910  return mk<ast::SubroutineArgument>(argNum);
911  } else {
912  return mk<ast::UnnamedVariable>();
913  }
914  }
915 
916  // apply recursive
917  node->apply(*this);
918 
919  // otherwise nothing
920  return node;
921  }
922  };
923 
924  // the structure of this subroutine is a sequence where each nested statement is a search in each
925  // relation
926  VecOwn<ram::Statement> searchSequence;
927 
928  // make a copy so that when we mutate clause, pointers to objects in newClause are not affected
929  auto newClause = souffle::clone(clauseReplacedAggregates);
930 
931  // go through each body atom and create a return
932  size_t litNumber = 0;
933  for (const auto& lit : newClause->getBodyLiterals()) {
934  if (auto atom = dynamic_cast<ast::Atom*>(lit)) {
935  size_t auxiliaryArity = auxArityAnalysis->getArity(atom);
936 
937  auto relName = translateRelation(atom);
938  // construct a query
939  VecOwn<ram::Expression> query;
940 
941  // translate variables to subroutine arguments
942  VariablesToArguments varsToArgs(uniqueVariables);
943  atom->apply(varsToArgs);
944 
945  auto atomArgs = atom->getArguments();
946  // add each value (subroutine argument) to the search query
947  for (size_t i = 0; i < atom->getArity() - auxiliaryArity; i++) {
948  auto arg = atomArgs[i];
949  query.push_back(translateValue(arg, ValueIndex()));
950  }
951 
952  // fill up query with nullptrs for the provenance columns
953  for (size_t i = 0; i < auxiliaryArity; i++) {
954  query.push_back(mk<ram::UndefValue>());
955  }
956 
957  // ensure the length of query tuple is correct
958  assert(query.size() == atom->getArity() && "wrong query tuple size");
959 
960  // create existence checks to check if the tuple exists or not
961  auto existenceCheck = mk<ram::ExistenceCheck>(relName, std::move(query));
962  auto negativeExistenceCheck = mk<ram::Negation>(souffle::clone(existenceCheck));
963 
964  // return true if the tuple exists
965  VecOwn<ram::Expression> returnTrue;
966  returnTrue.push_back(mk<ram::SignedConstant>(1));
967 
968  // return false if the tuple exists
969  VecOwn<ram::Expression> returnFalse;
970  returnFalse.push_back(mk<ram::SignedConstant>(0));
971 
972  // create a ram::Query to return true/false
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();
979 
980  size_t auxiliaryArity = auxArityAnalysis->getArity(atom);
981  auto relName = translateRelation(atom);
982  // construct a query
983  VecOwn<ram::Expression> query;
984 
985  // translate variables to subroutine arguments
986  VariablesToArguments varsToArgs(uniqueVariables);
987  atom->apply(varsToArgs);
988 
989  auto atomArgs = atom->getArguments();
990  // add each value (subroutine argument) to the search query
991  for (size_t i = 0; i < atom->getArity() - auxiliaryArity; i++) {
992  auto arg = atomArgs[i];
993  query.push_back(translateValue(arg, ValueIndex()));
994  }
995 
996  // fill up query with nullptrs for the provenance columns
997  for (size_t i = 0; i < auxiliaryArity; i++) {
998  query.push_back(mk<ram::UndefValue>());
999  }
1000 
1001  // ensure the length of query tuple is correct
1002  assert(query.size() == atom->getArity() && "wrong query tuple size");
1003 
1004  // create existence checks to check if the tuple exists or not
1005  auto existenceCheck = mk<ram::ExistenceCheck>(relName, std::move(query));
1006  auto negativeExistenceCheck = mk<ram::Negation>(souffle::clone(existenceCheck));
1007 
1008  // return true if the tuple exists
1009  VecOwn<ram::Expression> returnTrue;
1010  returnTrue.push_back(mk<ram::SignedConstant>(1));
1011 
1012  // return false if the tuple exists
1013  VecOwn<ram::Expression> returnFalse;
1014  returnFalse.push_back(mk<ram::SignedConstant>(0));
1015 
1016  // create a ram::Query to return true/false
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)))));
1021 
1022  } else if (auto con = dynamic_cast<ast::Constraint*>(lit)) {
1023  VariablesToArguments varsToArgs(uniqueVariables);
1024  con->apply(varsToArgs);
1025 
1026  // translate to a ram::Condition
1027  auto condition = translateConstraint(con, ValueIndex());
1028  auto negativeCondition = mk<ram::Negation>(souffle::clone(condition));
1029 
1030  // create a return true value
1031  VecOwn<ram::Expression> returnTrue;
1032  returnTrue.push_back(mk<ram::SignedConstant>(1));
1033 
1034  // create a return false value
1035  VecOwn<ram::Expression> returnFalse;
1036  returnFalse.push_back(mk<ram::SignedConstant>(0));
1037 
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)))));
1042  }
1043 
1044  litNumber++;
1045  }
1046 
1047  return mk<ram::Sequence>(std::move(searchSequence));
1048 }
1049 
1050 bool AstToRamTranslator::removeADTs(const ast::TranslationUnit& translationUnit) {
1051  struct ADTsFuneral : public ast::NodeMapper {
1052  mutable bool changed{false};
1053  const ast::analysis::SumTypeBranchesAnalysis& sumTypesBranches;
1054 

◆ makeRamTupleElement()

Own< ram::TupleElement > souffle::ast2ram::AstToRamTranslator::makeRamTupleElement ( const Location loc)
static

create a RAM element access node

Definition at line 150 of file AstToRamTranslator.cpp.

153  {

◆ makeSubproofSubroutine()

Own< ram::Statement > souffle::ast2ram::AstToRamTranslator::makeSubproofSubroutine ( const ast::Clause clause)
private

translate RAM code for subroutine to get subproofs

make a subroutine to search for subproofs

Definition at line 765 of file AstToRamTranslator.cpp.

765  {
766  intermediateClause->addToBody(souffle::clone(bodyLit));
767  }
768  }
769 
770  // now add all constraints
771  for (auto bodyLit : ast::getBodyLiterals<ast::Constraint>(clause)) {
772  intermediateClause->addToBody(souffle::clone(bodyLit));
773  }
774 
775  // name unnamed variables
776  nameUnnamedVariables(intermediateClause.get());
777 
778  // add constraint for each argument in head of atom
779  ast::Atom* head = intermediateClause->getHead();
780  size_t auxiliaryArity = auxArityAnalysis->getArity(head);
781  auto args = head->getArguments();
782  for (size_t i = 0; i < head->getArity() - auxiliaryArity; i++) {
783  auto arg = args[i];
784 
785  if (auto var = dynamic_cast<ast::Variable*>(arg)) {
786  // FIXME: float equiv (`FEQ`)
787  auto constraint = mk<ast::BinaryConstraint>(
788  BinaryConstraintOp::EQ, souffle::clone(var), mk<ast::SubroutineArgument>(i));
789  constraint->setFinalType(BinaryConstraintOp::EQ);
790  intermediateClause->addToBody(std::move(constraint));
791  } else if (auto func = dynamic_cast<ast::Functor*>(arg)) {
792  TypeAttribute returnType;
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();
799  } else {
800  assert(false && "unexpected functor type");
801  }
803  auto constraint =
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>(
809  BinaryConstraintOp::EQ, souffle::clone(rec), mk<ast::SubroutineArgument>(i));
810  constraint->setFinalType(BinaryConstraintOp::EQ);
811  intermediateClause->addToBody(std::move(constraint));
812  }
813  }
814 
815  // index of level argument in argument list
816  size_t levelIndex = head->getArguments().size() - auxiliaryArity;
817 
818  // add level constraints, i.e., that each body literal has height less than that of the head atom
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();
824  // arity - 1 is the level number in body atoms
825  auto constraint = mk<ast::BinaryConstraint>(BinaryConstraintOp::LT,
826  souffle::clone(atomArgs[arity - 1]), mk<ast::SubroutineArgument>(levelIndex));
827  constraint->setFinalType(BinaryConstraintOp::LT);
828  intermediateClause->addToBody(std::move(constraint));
829  }
830  }
831  return ProvenanceClauseTranslator(*this).translateClause(*intermediateClause, clause);
832 }
833 
834 /** make a subroutine to search for subproofs for the non-existence of a tuple */
835 Own<ram::Statement> AstToRamTranslator::makeNegationSubproofSubroutine(const ast::Clause& clause) {
836  // TODO (taipan-snake): Currently we only deal with atoms (no constraints or negations or aggregates
837  // or anything else...)
838  //

References souffle::clone().

Here is the call graph for this function:

◆ 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.

520  {
521  // apply recursive
522  node->apply(*this);
523 
524  // replace unknown variables
525  if (dynamic_cast<ast::UnnamedVariable*>(node.get()) != nullptr) {
526  auto name = " _unnamed_var" + toString(++counter);
527  return mk<ast::Variable>(name);
528  }
529 
530  // otherwise nothing
531  return node;
532  }
533  };
534 
535  // name all variables in the atoms
536  Instantiator init;
537  for (auto& atom : ast::getBodyLiterals<ast::Atom>(*clause)) {
538  atom->apply(init);
539  }
540 }
541 
542 /** converts the given relation identifier into a relation name */
543 std::string AstToRamTranslator::getRelationName(const ast::QualifiedName& id) {
544  return toString(join(id.getQualifiers(), "."));
545 }
546 

References souffle::toString().

Here is the call graph for this function:

◆ 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>()) {}
1057 
1058  Own<ast::Node> operator()(Own<ast::Node> node) const override {
1059  // Rewrite sub-expressions first
1060  node->apply(*this);
1061 
1062  if (!isA<ast::BranchInit>(node)) {
1063  return node;
1064  }
1065 
1066  changed = true;
1067  auto& adt = *as<ast::BranchInit>(node);
1068  auto& type = sumTypesBranches.unsafeGetType(adt.getConstructor());
1069  auto& branches = type.getBranches();
1070 
1071  // Find branch ID.
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;
1077  });
1078 
1079  // Branch id corresponds to the position in lexicographical ordering.
1080  auto branchID = std::distance(std::begin(branches), iterToBranch);
1081 
1082  if (isADTEnum(type)) {
1083  auto branchTag = mk<ast::NumericConstant>(branchID);
1084  branchTag->setFinalType(ast::NumericConstant::Type::Int);
1085  return branchTag;
1086  } else {
1087  // Collect branch arguments
1088  VecOwn<ast::Argument> branchArguments;
1089  for (auto* arg : adt.getArguments()) {
1090  branchArguments.emplace_back(arg->clone());
1091  }
1092 
1093  // Branch is stored either as [branch_id, [arguments]]
1094  // or [branch_id, argument] in case of a single argument.
1095  auto branchArgs = [&]() -> Own<ast::Argument> {
1096  if (branchArguments.size() != 1) {
1097  return mk<ast::Argument, ast::RecordInit>(std::move(branchArguments));
1098  } else {
1099  return std::move(branchArguments.at(0));
1100  }
1101  }();
1102 
1103  // Arguments for the resulting record [branch_id, branch_args].
1104  VecOwn<ast::Argument> finalRecordArgs;
1105 
1106  auto branchTag = mk<ast::NumericConstant>(branchID);
1107  branchTag->setFinalType(ast::NumericConstant::Type::Int);
1108  finalRecordArgs.push_back(std::move(branchTag));
1109  finalRecordArgs.push_back(std::move(branchArgs));
1110 
1111  return mk<ast::RecordInit>(std::move(finalRecordArgs), adt.getSrcLoc());
1112  }
1113  }
1114  };
1115 
1116  ADTsFuneral mapper(translationUnit);
1117  translationUnit.getProgram().apply(mapper);
1118  return mapper.changed;
1119 }
1120 
1121 /** translates the given datalog program into an equivalent RAM program */
1122 void AstToRamTranslator::translateProgram(const ast::TranslationUnit& translationUnit) {
1123  // keep track of relevant analyses
1124  ioType = translationUnit.getAnalysis<ast::analysis::IOTypeAnalysis>();
1125  typeEnv = &translationUnit.getAnalysis<ast::analysis::TypeEnvironmentAnalysis>()->getTypeEnvironment();

◆ translateConstant()

Own< ram::Expression > souffle::ast2ram::AstToRamTranslator::translateConstant ( ast::Constant const &  c)

translate RAM code for a constant value

Definition at line 437 of file AstToRamTranslator.cpp.

437  : return mk<ram::UnsignedConstant>(rawConstant);
438  case ast::NumericConstant::Type::Float: return mk<ram::FloatConstant>(rawConstant);
439  }
440  }
441 
442  return mk<ram::SignedConstant>(rawConstant);
443 }
444 
445 /** generate RAM code for a non-recursive relation */
447  const ast::Relation& rel, const ast::analysis::RecursiveClausesAnalysis* recursiveClauses) {
448  /* start with an empty sequence */
449  VecOwn<ram::Statement> res;

◆ translateConstraint()

Own< ram::Condition > souffle::ast2ram::AstToRamTranslator::translateConstraint ( const ast::Literal arg,
const ValueIndex index 
)

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.

341  :
342  ConstraintTranslator(AstToRamTranslator& translator, const ValueIndex& index,
343  const ast::analysis::PolymorphicObjectsAnalysis* polyAnalysis)
344  : translator(translator), index(index), polyAnalysis(polyAnalysis) {}
345 
346  /** for atoms */
347  Own<ram::Condition> visitAtom(const ast::Atom&) override {
348  return nullptr; // covered already within the scan/lookup generation step
349  }
350 
351  /** for binary relations */
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));
357  }
358 
359  /** for provenance negation */
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;
366 
367  auto args = atom->getArguments();
368  for (size_t i = 0; i < arity; i++) {
369  values.push_back(translator.translateValue(args[i], index));
370  }
371  // we don't care about the provenance columns when doing the existence check
372  if (Global::config().has("provenance")) {
373  // undefined value for rule number
374  values.push_back(mk<ram::UndefValue>());
375  // add the height annotation for provenanceNotExists
376  for (size_t height = 1; height < auxiliaryArity; height++) {
377  values.push_back(translator.translateValue(args[arity + height], index));
378  }
379  }
380  return mk<ram::Negation>(
381  mk<ram::ProvenanceExistenceCheck>(translator.translateRelation(atom), std::move(values)));
382  }
383 
384  /** for negations */
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;
390 
391  if (arity == 0) {
392  // for a nullary, negation is a simple emptiness check
393  return mk<ram::EmptinessCheck>(translator.translateRelation(atom));
394  }
395 
396  // else, we construct the atom and create a negation
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));
401  }
402  for (size_t i = 0; i < auxiliaryArity; i++) {
403  values.push_back(mk<ram::UndefValue>());
404  }
405  return mk<ram::Negation>(
406  mk<ram::ExistenceCheck>(translator.translateRelation(atom), std::move(values)));
407  }
408  };
409  return ConstraintTranslator(*this, index, polyAnalysis)(*lit);
410 }
411 
412 RamDomain AstToRamTranslator::getConstantRamRepresentation(const ast::Constant& constant) {
413  if (auto strConstant = dynamic_cast<const ast::StringConstant*>(&constant)) {
414  return getSymbolTable().lookup(strConstant->getConstant());
415  } else if (isA<ast::NilConstant>(&constant)) {
416  return 0;

◆ 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.

230  {

◆ 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()

Own< ram::Statement > souffle::ast2ram::AstToRamTranslator::translateNonRecursiveRelation ( const ast::Relation rel,
const ast::analysis::RecursiveClausesAnalysis recursiveClauses 
)
private

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.

454  : getClauses(*program, rel)) {
455  // skip recursive rules
456  if (recursiveClauses->recursive(clause)) {
457  continue;
458  }
459 
460  // translate clause
461  Own<ram::Statement> rule = ClauseTranslator(*this).translateClause(*clause, *clause);
462 
463  // add logging
464  if (Global::config().has("profile")) {
465  const std::string& relationName = toString(rel.getQualifiedName());
466  const SrcLocation& srcLocation = clause->getSrcLoc();
467  const std::string clauseText = stringify(toString(*clause));
468  const std::string logTimerStatement =
469  LogStatement::tNonrecursiveRule(relationName, srcLocation, clauseText);
470  const std::string logSizeStatement =
471  LogStatement::nNonrecursiveRule(relationName, srcLocation, clauseText);
472  rule = mk<ram::LogRelationTimer>(std::move(rule), logTimerStatement, relName);
473  }
474 
475  // add debug info
476  std::ostringstream ds;
477  ds << toString(*clause) << "\nin file ";
478  ds << clause->getSrcLoc();
479  rule = mk<ram::DebugInfo>(std::move(rule), ds.str());
480 
481  // add rule to result
482  appendStmt(res, std::move(rule));
483  }
484 
485  // add logging for entire relation
486  if (Global::config().has("profile")) {
487  const std::string& relationName = toString(rel.getQualifiedName());
488  const SrcLocation& srcLocation = rel.getSrcLoc();
489  const std::string logSizeStatement = LogStatement::nNonrecursiveRelation(relationName, srcLocation);
490 
491  // add timer if we did any work
492  if (!res.empty()) {
493  const std::string logTimerStatement =
494  LogStatement::tNonrecursiveRelation(relationName, srcLocation);
495  auto newStmt =
496  mk<ram::LogRelationTimer>(mk<ram::Sequence>(std::move(res)), logTimerStatement, relName);
497  res.clear();
498  appendStmt(res, std::move(newStmt));
499  } else {
500  // add table size printer
501  appendStmt(res, mk<ram::LogSize>(relName, logSizeStatement));
502  }
503  }
504 
505  // done
506  return mk<ram::Sequence>(std::move(res));
507 }
508 
509 /**
510  * A utility function assigning names to unnamed variables such that enclosing
511  * constructs may be cloned without losing the variable-identity.
512  */
513 void AstToRamTranslator::nameUnnamedVariables(ast::Clause* clause) {

References souffle::ast2ram::appendStmt(), souffle::Global::config(), souffle::LogStatement::nNonrecursiveRule(), rel(), rule, souffle::stringify(), souffle::LogStatement::tNonrecursiveRule(), souffle::toString(), and souffle::ast2ram::ClauseTranslator::translateClause().

Here is the call graph for this function:

◆ 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.

1137  {
1138  const_cast<ast::NumericConstant&>(nc).setFinalType(polyAnalysis->getInferredType(&nc));
1139  });
1140  visitDepthFirst(*program, [&](const ast::Aggregator& aggr) {
1141  const_cast<ast::Aggregator&>(aggr).setFinalType(polyAnalysis->getOverloadedOperator(&aggr));
1142  });
1143  visitDepthFirst(*program, [&](const ast::BinaryConstraint& bc) {
1144  const_cast<ast::BinaryConstraint&>(bc).setFinalType(polyAnalysis->getOverloadedOperator(&bc));
1145  });
1146  visitDepthFirst(*program, [&](const ast::IntrinsicFunctor& inf) {
1147  const_cast<ast::IntrinsicFunctor&>(inf).setFinalOpType(polyAnalysis->getOverloadedFunctionOp(&inf));
1148  const_cast<ast::IntrinsicFunctor&>(inf).setFinalReturnType(functorAnalysis->getReturnType(&inf));
1149  });
1150  visitDepthFirst(*program, [&](const ast::UserDefinedFunctor& udf) {
1151  const_cast<ast::UserDefinedFunctor&>(udf).setFinalReturnType(functorAnalysis->getReturnType(&udf));
1152  });
1153 
1154  // determine the sips to use
1155  std::string sipsChosen = "all-bound";
1156  if (Global::config().has("RamSIPS")) {
1157  sipsChosen = Global::config().get("RamSIPS");
1158  }
1159  sips = ast::SipsMetric::create(sipsChosen, translationUnit);
1160 
1161  // replace ADTs with record representatives
1162  removeADTs(translationUnit);
1163 
1164  // handle the case of an empty SCC graph
1165  if (sccGraph.getNumberOfSCCs() == 0) return;
1166 
1167  // a function to load relations
1168  const auto& makeRamLoad = [&](VecOwn<ram::Statement>& current, const ast::Relation* relation) {
1169  for (auto directives : getInputDirectives(relation)) {
1170  Own<ram::Statement> statement = mk<ram::IO>(translateRelation(relation), directives);
1171  if (Global::config().has("profile")) {
1172  const std::string logTimerStatement = LogStatement::tRelationLoadTime(
1173  toString(relation->getQualifiedName()), relation->getSrcLoc());
1174  statement = mk<ram::LogRelationTimer>(
1175  std::move(statement), logTimerStatement, translateRelation(relation));
1176  }
1177  appendStmt(current, std::move(statement));
1178  }
1179  };
1180 
1181  // a function to store relations
1182  const auto& makeRamStore = [&](VecOwn<ram::Statement>& current, const ast::Relation* relation) {
1183  for (auto directives : getOutputDirectives(relation)) {
1184  Own<ram::Statement> statement = mk<ram::IO>(translateRelation(relation), directives);
1185  if (Global::config().has("profile")) {
1186  const std::string logTimerStatement = LogStatement::tRelationSaveTime(
1187  toString(relation->getQualifiedName()), relation->getSrcLoc());
1188  statement = mk<ram::LogRelationTimer>(
1189  std::move(statement), logTimerStatement, translateRelation(relation));
1190  }
1191  appendStmt(current, std::move(statement));
1192  }
1193  };
1194 
1195  // a function to drop relations
1196  const auto& makeRamClear = [&](VecOwn<ram::Statement>& current, const ast::Relation* relation) {
1197  appendStmt(current, mk<ram::Clear>(translateRelation(relation)));
1198  };
1199 
1200  // create all Ram relations in ramRels
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();
1207  auto auxiliaryArity = auxArityAnalysis->getArity(rel);
1208  auto representation = rel->getRepresentation();
1209  const auto& attributes = rel->getAttributes();
1210 
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());
1215  if (typeEnv != nullptr) {
1216  attributeTypeQualifiers.push_back(
1217  getTypeQualifier(typeEnv->getType(attributes[i]->getTypeName())));
1218  }
1219  }
1220  ramRels[name] = mk<ram::Relation>(
1221  name, arity, auxiliaryArity, attributeNames, attributeTypeQualifiers, representation);
1222 
1223  // recursive relations also require @delta and @new variants, with the same signature
1224  if (isRecursive) {
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);
1231  }
1232  }
1233  }
1234 
1235  // maintain the index of the SCC within the topological order
1236  size_t indexOfScc = 0;
1237 
1238  // iterate over each SCC according to the topological order
1239  for (const auto& scc : sccOrder.order()) {
1240  // make a new ram statement for the current SCC
1241  VecOwn<ram::Statement> current;
1242 
1243  // find out if the current SCC is recursive
1244  const auto& isRecursive = sccGraph.isRecursive(scc);
1245 
1246  // make variables for particular sets of relations contained within the current SCC, and,
1247  // predecessors and successor SCCs thereof
1248  const auto& allInterns = sccGraph.getInternalRelations(scc);
1249  const auto& internIns = sccGraph.getInternalInputRelations(scc);
1250  const auto& internOuts = sccGraph.getInternalOutputRelations(scc);
1251 
1252  // make a variable for all relations that are expired at the current SCC
1253  const auto& internExps = expirySchedule.at(indexOfScc).expired();
1254 
1255  // load all internal input relations from the facts dir with a .facts extension
1256  for (const auto& relation : internIns) {
1257  makeRamLoad(current, relation);
1258  }
1259 
1260  // compute the relations themselves
1261  Own<ram::Statement> bodyStatement =
1262  (!isRecursive) ? translateNonRecursiveRelation(
1263  *((const ast::Relation*)*allInterns.begin()), recursiveClauses)
1264  : translateRecursiveRelation(allInterns, recursiveClauses);
1265  appendStmt(current, std::move(bodyStatement));
1266 
1267  // store all internal output relations to the output dir with a .csv extension
1268  for (const auto& relation : internOuts) {
1269  makeRamStore(current, relation);
1270  }
1271 
1272  // if provenance is disabled, drop all relations expired as per the topological order
1273  if (!Global::config().has("provenance")) {
1274  for (const auto& relation : internExps) {
1275  makeRamClear(current, relation);
1276  }
1277  }
1278 
1279  // create subroutine for this stratum
1280  ramSubs["stratum_" + std::to_string(indexOfScc)] = mk<ram::Sequence>(std::move(current));
1281  indexOfScc++;
1282  }
1283 
1284  // invoke all strata
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)));
1288  }
1289 
1290  // add main timer if profiling
1291  if (res.size() > 0 && Global::config().has("profile")) {
1292  auto newStmt = mk<ram::LogTimer>(mk<ram::Sequence>(std::move(res)), LogStatement::runtime());
1293  res.clear();
1294  appendStmt(res, std::move(newStmt));
1295  }
1296 
1297  // done for main prog
1298  ramMain = mk<ram::Sequence>(std::move(res));
1299 
1300  // add subroutines for each clause
1301  if (Global::config().has("provenance")) {
1302  visitDepthFirst(*program, [&](const ast::Clause& clause) {
1303  std::stringstream relName;
1304  relName << clause.getHead()->getQualifiedName();
1305 
1306  // do not add subroutines for info relations or facts
1307  if (relName.str().find("@info") != std::string::npos || clause.getBodyLiterals().empty()) {
1308  return;
1309  }
1310 
1311  std::string subroutineLabel =
1312  relName.str() + "_" + std::to_string(getClauseNum(program, &clause)) + "_subproof";
1313  ramSubs[subroutineLabel] = makeSubproofSubroutine(clause);
1314 
1315  std::string negationSubroutineLabel = relName.str() + "_" +
1316  std::to_string(getClauseNum(program, &clause)) +
1317  "_negation_subproof";
1318  ramSubs[negationSubroutineLabel] = makeNegationSubproofSubroutine(clause);
1319  });
1320  }
1321 }
1322 
1323 Own<ram::TranslationUnit> AstToRamTranslator::translateUnit(ast::TranslationUnit& tu) {
1324  auto ram_start = std::chrono::high_resolution_clock::now();
1325  program = &tu.getProgram();
1326 
1327  translateProgram(tu);

◆ translateRecursiveRelation()

Own< ram::Statement > souffle::ast2ram::AstToRamTranslator::translateRecursiveRelation ( const std::set< const ast::Relation * > &  scc,
const ast::analysis::RecursiveClausesAnalysis recursiveClauses 
)
private

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.

556  {
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))));
561  }
562  for (std::size_t i = 0; i < rel->getArity(); i++) {
563  values.push_back(mk<ram::TupleElement>(0, i));
564  }
565  auto stmt = mk<ram::Query>(mk<ram::Scan>(srcRel, 0, mk<ram::Project>(destRel, std::move(values))));
566  if (rel->getRepresentation() == RelationRepresentation::EQREL) {
567  return mk<ram::Sequence>(mk<ram::Extend>(destRel, srcRel), std::move(stmt));
568  }
569  return stmt;
570  };
571 
572  // --- create preamble ---
573 
574  /* Compute non-recursive clauses for relations in scc and push
575  the results in their delta tables. */
576  for (const ast::Relation* rel : scc) {
577  /* create update statements for fixpoint (even iteration) */
578  Own<ram::Statement> updateRelTable =
579  mk<ram::Sequence>(genMerge(rel, translateRelation(rel), translateNewRelation(rel)),
581  mk<ram::Clear>(translateNewRelation(rel)));
582 
583  /* measure update time for each relation */
584  if (Global::config().has("profile")) {
585  updateRelTable = mk<ram::LogRelationTimer>(std::move(updateRelTable),
586  LogStatement::cRecursiveRelation(toString(rel->getQualifiedName()), rel->getSrcLoc()),
588  }
589 
590  /* drop temporary tables after recursion */
591  appendStmt(postamble, mk<ram::Clear>(translateDeltaRelation(rel)));
592  appendStmt(postamble, mk<ram::Clear>(translateNewRelation(rel)));
593 
594  /* Generate code for non-recursive part of relation */
595  /* Generate merge operation for temp tables */
596  appendStmt(preamble, translateNonRecursiveRelation(*rel, recursiveClauses));
598 
599  /* Add update operations of relations to parallel statements */
600  appendStmt(updateTable, std::move(updateRelTable));
601  }
602 
603  // --- build main loop ---
604 
605  VecOwn<ram::Statement> loopSeq;
606 
607  // create a utility to check SCC membership
608  auto isInSameSCC = [&](const ast::Relation* rel) {
609  return std::find(scc.begin(), scc.end(), rel) != scc.end();
610  };
611 
612  /* Compute temp for the current tables */
613  for (const ast::Relation* rel : scc) {
614  VecOwn<ram::Statement> loopRelSeq;
615 
616  /* Find clauses for relation rel */
617  for (const auto& cl : getClauses(*program, *rel)) {
618  // skip non-recursive clauses
619  if (!recursiveClauses->recursive(cl)) {
620  continue;
621  }
622 
623  // each recursive rule results in several operations
624  int version = 0;
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];
628  const ast::Relation* atomRelation = getAtomRelation(atom, program);
629 
630  // only interested in atoms within the same SCC
631  if (!isInSameSCC(atomRelation)) {
632  continue;
633  }
634 
635  // modify the processed rule to use delta relation and write to new relation
636  Own<ast::Clause> r1(cl->clone());
637  r1->getHead()->setQualifiedName(translateNewRelation(rel));
638  ast::getBodyLiterals<ast::Atom>(*r1)[j]->setQualifiedName(
639  translateDeltaRelation(atomRelation));
640  if (Global::config().has("provenance")) {
641  r1->addToBody(mk<ast::ProvenanceNegation>(souffle::clone(cl->getHead())));
642  } else {
643  if (r1->getHead()->getArity() > 0) {
644  r1->addToBody(mk<ast::Negation>(souffle::clone(cl->getHead())));
645  }
646  }
647 
648  // replace wildcards with variables (reduces indices when wildcards are used in recursive
649  // atoms)
650  nameUnnamedVariables(r1.get());
651 
652  // reduce R to P ...
653  for (size_t k = j + 1; k < atoms.size(); k++) {
654  if (isInSameSCC(getAtomRelation(atoms[k], program))) {
655  auto cur = souffle::clone(ast::getBodyLiterals<ast::Atom>(*r1)[k]);
656  cur->setQualifiedName(translateDeltaRelation(getAtomRelation(atoms[k], program)));
657  r1->addToBody(mk<ast::Negation>(std::move(cur)));
658  }
659  }
660 
661  Own<ram::Statement> rule = ClauseTranslator(*this).translateClause(*r1, *cl, version);
662 
663  /* add logging */
664  if (Global::config().has("profile")) {
665  const std::string& relationName = toString(rel->getQualifiedName());
666  const SrcLocation& srcLocation = cl->getSrcLoc();
667  const std::string clauseText = stringify(toString(*cl));
668  const std::string logTimerStatement =
669  LogStatement::tRecursiveRule(relationName, version, srcLocation, clauseText);
670  const std::string logSizeStatement =
671  LogStatement::nRecursiveRule(relationName, version, srcLocation, clauseText);
672  rule = mk<ram::LogRelationTimer>(
673  std::move(rule), logTimerStatement, translateNewRelation(rel));
674  }
675 
676  // add debug info
677  std::ostringstream ds;
678  ds << toString(*cl) << "\nin file ";
679  ds << cl->getSrcLoc();
680  rule = mk<ram::DebugInfo>(std::move(rule), ds.str());
681 
682  // add to loop body
683  appendStmt(loopRelSeq, std::move(rule));
684 
685  // increment version counter
686  version++;
687  }
688 
689  if (cl->getExecutionPlan() != nullptr) {
690  // ensure that all required versions have been created, as expected
691  int maxVersion = -1;
692  for (auto const& cur : cl->getExecutionPlan()->getOrders()) {
693  maxVersion = std::max(cur.first, maxVersion);
694  }
695  assert(version > maxVersion && "missing clause versions");
696  }
697  }
698 
699  // if there was no rule, continue
700  if (loopRelSeq.size() == 0) {
701  continue;
702  }
703 
704  // label all versions
705  if (Global::config().has("profile")) {
706  const std::string& relationName = toString(rel->getQualifiedName());
707  const SrcLocation& srcLocation = rel->getSrcLoc();
708  const std::string logTimerStatement = LogStatement::tRecursiveRelation(relationName, srcLocation);
709  const std::string logSizeStatement = LogStatement::nRecursiveRelation(relationName, srcLocation);
710  auto newStmt = mk<ram::LogRelationTimer>(
711  mk<ram::Sequence>(std::move(loopRelSeq)), logTimerStatement, translateNewRelation(rel));
712  loopRelSeq.clear();
713  appendStmt(loopRelSeq, std::move(newStmt));
714  }
715 
716  /* add rule computations of a relation to parallel statement */
717  appendStmt(loopSeq, mk<ram::Sequence>(std::move(loopRelSeq)));
718  }
719  auto loop = mk<ram::Parallel>(std::move(loopSeq));
720 
721  /* construct exit conditions for odd and even iteration */
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));
724  };
725 
726  Own<ram::Condition> exitCond;
727  VecOwn<ram::Statement> exitStmts;
728  for (const ast::Relation* rel : scc) {
729  addCondition(exitCond, mk<ram::EmptinessCheck>(translateNewRelation(rel)));
730  if (ioType->isLimitSize(rel)) {
731  Own<ram::Condition> limit =
732  mk<ram::Constraint>(BinaryConstraintOp::GE, mk<ram::RelationSize>(translateRelation(rel)),
733  mk<ram::SignedConstant>(ioType->getLimitSize(rel)));
734  appendStmt(exitStmts, mk<ram::Exit>(std::move(limit)));
735  }
736  }
737 
738  /* construct fixpoint loop */
739  VecOwn<ram::Statement> res;
740  if (preamble.size() > 0) {
741  appendStmt(res, mk<ram::Sequence>(std::move(preamble)));
742  }
743  if (!loop->getStatements().empty() && exitCond && updateTable.size() > 0) {
744  appendStmt(res,
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)))));
747  }
748  if (postamble.size() > 0) {
749  appendStmt(res, mk<ram::Sequence>(std::move(postamble)));
750  }
751  if (res.size() > 0) {
752  return mk<ram::Sequence>(std::move(res));
753  }
754 
755  fatal("Not Implemented");
756 }
757 
758 /** make a subroutine to search for subproofs */
759 Own<ram::Statement> AstToRamTranslator::makeSubproofSubroutine(const ast::Clause& clause) {
760  auto intermediateClause = mk<ast::Clause>(souffle::clone(clause.getHead()));
761 
762  // create a clone where all the constraints are moved to the end

References souffle::EQREL, i, and rel().

Here is the call graph for this function:

◆ translateRelation() [1/2]

std::string souffle::ast2ram::AstToRamTranslator::translateRelation ( const ast::Atom atom)

a utility to translate atoms to relations

Definition at line 219 of file AstToRamTranslator.cpp.

Referenced by souffle::ast2ram::ClauseTranslator::translateClause().

◆ translateRelation() [2/2]

std::string souffle::ast2ram::AstToRamTranslator::translateRelation ( const ast::Relation rel,
const std::string  relationNamePrefix = "" 
)

translate an AST relation to a RAM relation

Definition at line 223 of file AstToRamTranslator.cpp.

226  {

◆ translateUnit()

Own< ram::TranslationUnit > souffle::ast2ram::AstToRamTranslator::translateUnit ( ast::TranslationUnit tu)

translates AST to translation unit

Definition at line 1329 of file AstToRamTranslator.cpp.

1332  : ramRels) {
1333  rels.push_back(std::move(cur.second));
1334  }
1335  if (ramMain == nullptr) {
1336  ramMain = mk<ram::Sequence>();
1337  }
1338  auto ramProg = mk<ram::Program>(std::move(rels), std::move(ramMain), std::move(ramSubs));
1339  if (!Global::config().get("debug-report").empty()) {
1340  if (ramProg) {
1341  auto ram_end = std::chrono::high_resolution_clock::now();
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());
1347  }
1348  }
1349  return mk<ram::TranslationUnit>(std::move(ramProg), std::move(symTab), errReport, debugReport);
1350 }
1351 
1352 } // namespace souffle::ast2ram

◆ translateValue()

Own< ram::Expression > souffle::ast2ram::AstToRamTranslator::translateValue ( const ast::Argument arg,
const ValueIndex index 
)

translate an AST argument to a RAM value

Definition at line 236 of file AstToRamTranslator.cpp.

240  :
241  ValueTranslator(AstToRamTranslator& translator, const ValueIndex& index,
242  const ast::analysis::PolymorphicObjectsAnalysis* polyAnalysis)
243  : translator(translator), index(index), polyAnalysis(polyAnalysis) {}
244 
245  Own<ram::Expression> visitVariable(const ast::Variable& var) override {
246  if (!index.isDefined(var)) fatal("variable `%s` is not grounded", var);
247  return makeRamTupleElement(index.getDefinitionPoint(var));
248  }
249 
250  Own<ram::Expression> visitUnnamedVariable(const ast::UnnamedVariable&) override {
251  return mk<ram::UndefValue>();
252  }
253 
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()) {
258  return mk<ram::SignedConstant>(RamSignedFromString(c.getConstant(), nullptr, 0));
260  return mk<ram::UnsignedConstant>(RamUnsignedFromString(c.getConstant(), nullptr, 0));
262  return mk<ram::FloatConstant>(RamFloatFromString(c.getConstant()));
263  }
264 
265  fatal("unexpected numeric constant type");
266  }
267 
268  Own<ram::Expression> visitStringConstant(const ast::StringConstant& c) override {
269  return mk<ram::SignedConstant>(translator.getSymbolTable().lookup(c.getConstant()));
270  }
271 
272  Own<ram::Expression> visitNilConstant(const ast::NilConstant&) override {
273  return mk<ram::SignedConstant>(0);
274  }
275 
276  Own<ram::Expression> visitTypeCast(const ast::TypeCast& typeCast) override {
277  return translator.translateValue(typeCast.getValue(), index);
278  }
279 
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));
284  }
285 
287  return translator.makeRamTupleElement(index.getGeneratorLoc(inf));
288  } else {
289  return mk<ram::IntrinsicOperator>(inf.getFinalOpType().value(), std::move(values));
290  }
291  }
292 
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));
297  }
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));
302  }
303 
304  Own<ram::Expression> visitCounter(const ast::Counter&) override {
305  return mk<ram::AutoIncrement>();
306  }
307 
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));
312  }
313  return mk<ram::PackRecord>(std::move(values));
314  }
315 
316  Own<ram::Expression> visitAggregator(const ast::Aggregator& agg) override {
317  // here we look up the location the aggregation result gets bound
318  return translator.makeRamTupleElement(index.getGeneratorLoc(agg));
319  }
320 
321  Own<ram::Expression> visitSubroutineArgument(const ast::SubroutineArgument& subArg) override {
322  return mk<ram::SubroutineArgument>(subArg.getNumber());
323  }
324  };
325 
326  return ValueTranslator(*this, index, polyAnalysis)(*arg);
327 }
328 
329 SymbolTable& AstToRamTranslator::getSymbolTable() {
330  static SymbolTable symbolTable;
331  return symbolTable;
332 }
333 

Referenced by souffle::ast2ram::ProvenanceClauseTranslator::createOperation(), and souffle::ast2ram::ClauseTranslator::translateClause().

Field Documentation

◆ auxArityAnalysis

const ast::analysis::AuxiliaryArityAnalysis* souffle::ast2ram::AstToRamTranslator::auxArityAnalysis = nullptr
private

Auxiliary Arity Analysis.

Definition at line 136 of file AstToRamTranslator.h.

Referenced by getAuxArityAnalysis().

◆ functorAnalysis

const ast::analysis::FunctorAnalysis* souffle::ast2ram::AstToRamTranslator::functorAnalysis = nullptr
private

Functors' analysis.

Definition at line 133 of file AstToRamTranslator.h.

Referenced by getFunctorAnalysis().

◆ ioType

const ast::analysis::IOTypeAnalysis* souffle::ast2ram::AstToRamTranslator::ioType = nullptr
private

IO Type.

Definition at line 130 of file AstToRamTranslator.h.

◆ polyAnalysis

const ast::analysis::PolymorphicObjectsAnalysis* souffle::ast2ram::AstToRamTranslator::polyAnalysis = nullptr
private

Polymorphic Objects Analysis.

Definition at line 139 of file AstToRamTranslator.h.

Referenced by getPolymorphicObjectsAnalysis(), and getSymbolTable().

◆ program

const ast::Program* souffle::ast2ram::AstToRamTranslator::program = nullptr
private

AST program.

Definition at line 124 of file AstToRamTranslator.h.

◆ ramMain

Own<ram::Statement> souffle::ast2ram::AstToRamTranslator::ramMain
private

RAM program.

Definition at line 145 of file AstToRamTranslator.h.

◆ ramRels

std::map<std::string, Own<ram::Relation> > souffle::ast2ram::AstToRamTranslator::ramRels
private

RAM relations.

Definition at line 151 of file AstToRamTranslator.h.

Referenced by lookupRelation().

◆ ramSubs

std::map<std::string, Own<ram::Statement> > souffle::ast2ram::AstToRamTranslator::ramSubs
private

Subroutines.

Definition at line 148 of file AstToRamTranslator.h.

◆ sips

Own<ast::SipsMetric> souffle::ast2ram::AstToRamTranslator::sips
private

SIPS metric for reordering.

Definition at line 142 of file AstToRamTranslator.h.

Referenced by getSipsMetric().

◆ typeEnv

const ast::analysis::TypeEnvironment* souffle::ast2ram::AstToRamTranslator::typeEnv = nullptr
private

Type environment.

Definition at line 127 of file AstToRamTranslator.h.


The documentation for this class was generated from the following files:
souffle::ast2ram::AstToRamTranslator::sips
Own< ast::SipsMetric > sips
SIPS metric for reordering.
Definition: AstToRamTranslator.h:142
souffle::LogStatement::nNonrecursiveRule
static const std::string nNonrecursiveRule(const std::string &relationName, const SrcLocation &srcLocation, const std::string &datalogText)
Definition: LogStatement.h:76
souffle::RamSignedFromString
RamSigned RamSignedFromString(const std::string &str, std::size_t *position=nullptr, const int base=10)
Converts a string to a RamSigned.
Definition: StringUtil.h:51
souffle::ast::analysis::FunctorAnalysis::isMultiResult
static bool isMultiResult(const Functor &functor)
Definition: Functor.cpp:53
souffle::ast2ram::AstToRamTranslator::getConstantRamRepresentation
RamDomain getConstantRamRepresentation(const ast::Constant &constant)
Get ram representation of constant.
Definition: AstToRamTranslator.cpp:418
souffle::ast2ram::AstToRamTranslator::ramMain
Own< ram::Statement > ramMain
RAM program.
Definition: AstToRamTranslator.h:145
souffle::ast2ram::AstToRamTranslator::translateNonRecursiveRelation
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.
Definition: AstToRamTranslator.cpp:452
souffle::ast::analysis::PolymorphicObjectsAnalysis::getInferredType
NumericConstant::Type getInferredType(const NumericConstant *nc) const
Definition: PolymorphicObjects.cpp:40
souffle::LogStatement::cRecursiveRelation
static const std::string cRecursiveRelation(const std::string &relationName, const SrcLocation &srcLocation)
Definition: LogStatement.h:118
souffle::ast2ram::AstToRamTranslator::auxArityAnalysis
const ast::analysis::AuxiliaryArityAnalysis * auxArityAnalysis
Auxiliary Arity Analysis.
Definition: AstToRamTranslator.h:136
TypeAttribute
Type attribute class.
souffle::RamDomain
int32_t RamDomain
Definition: RamTypes.h:56
souffle::ast::analysis::isADTEnum
bool isADTEnum(const AlgebraicDataType &type)
Determine if ADT is enumerations (are all constructors empty)
Definition: TypeSystem.cpp:377
souffle::ast2ram::AstToRamTranslator::ramSubs
std::map< std::string, Own< ram::Statement > > ramSubs
Subroutines.
Definition: AstToRamTranslator.h:148
souffle::RelationRepresentation::EQREL
@ EQREL
souffle::ast::analysis::TypeEnvironment::getType
const Type & getType(const QualifiedName &) const
Definition: TypeSystem.cpp:81
souffle::LogStatement::tRecursiveRelation
static const std::string tRecursiveRelation(const std::string &relationName, const SrcLocation &srcLocation)
Definition: LogStatement.h:102
souffle::ast2ram::AstToRamTranslator::nameUnnamedVariables
void nameUnnamedVariables(ast::Clause *clause)
assigns names to unnamed variables such that enclosing constructs may be cloned without losing the va...
Definition: AstToRamTranslator.cpp:519
souffle::ast::getClauseNum
size_t getClauseNum(const Program *program, const Clause *clause)
Returns the index of a clause within its relation, ignoring facts.
Definition: Utils.cpp:150
souffle::LogStatement::runtime
static const std::string runtime()
Definition: LogStatement.h:139
souffle::ast2ram::AstToRamTranslator::functorAnalysis
const ast::analysis::FunctorAnalysis * functorAnalysis
Functors' analysis.
Definition: AstToRamTranslator.h:133
souffle::ast2ram::AstToRamTranslator::translateDeltaRelation
std::string translateDeltaRelation(const ast::Relation *rel)
translate a temporary delta relation to a RAM relation for semi-naive evaluation
Definition: AstToRamTranslator.cpp:228
relation
Relation & relation
Definition: Reader.h:130
souffle::BinaryConstraintOp::EQ
@ EQ
souffle::ast2ram::AstToRamTranslator::getInputDirectives
std::vector< std::map< std::string, std::string > > getInputDirectives(const ast::Relation *rel)
Definition: AstToRamTranslator.cpp:170
souffle::ast::analysis::PolymorphicObjectsAnalysis::getOverloadedFunctionOp
FunctorOp getOverloadedFunctionOp(const IntrinsicFunctor *inf) const
Definition: PolymorphicObjects.cpp:36
souffle::ast2ram::AstToRamTranslator::program
const ast::Program * program
AST program.
Definition: AstToRamTranslator.h:124
souffle::ast2ram::AstToRamTranslator::ramRels
std::map< std::string, Own< ram::Relation > > ramRels
RAM relations.
Definition: AstToRamTranslator.h:151
souffle::ast2ram::AstToRamTranslator::translateRelation
std::string translateRelation(const ast::Atom *atom)
a utility to translate atoms to relations
Definition: AstToRamTranslator.cpp:219
souffle::unescape
std::string unescape(const std::string &inputString, const std::string &needle, const std::string &replacement)
Definition: StringUtil.h:398
souffle::ast::analysis::IOTypeAnalysis::isLimitSize
bool isLimitSize(const Relation *relation) const
Definition: IOType.h:61
souffle::BinaryConstraintOp::FEQ
@ FEQ
souffle::ast::SipsMetric::create
static std::unique_ptr< SipsMetric > create(const std::string &heuristic, const TranslationUnit &tu)
Create a SIPS metric based on a given heuristic.
Definition: SipsMetric.cpp:68
souffle::LogStatement::nRecursiveRule
static const std::string nRecursiveRule(const std::string &relationName, const int version, const SrcLocation &srcLocation, const std::string &datalogText)
Definition: LogStatement.h:93
j
var j
Definition: htmlJsChartistMin.h:15
souffle::ast::NumericConstant::Type::Int
@ Int
souffle::ast2ram::AstToRamTranslator::AstToRamTranslator
AstToRamTranslator()
souffle::toString
const std::string & toString(const std::string &str)
A generic function converting strings into strings (trivial case).
Definition: StringUtil.h:234
souffle::SymbolTable::lookup
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.
Definition: SymbolTable.h:124
souffle::LogStatement::nRecursiveRelation
static const std::string nRecursiveRelation(const std::string &relationName, const SrcLocation &srcLocation)
Definition: LogStatement.h:110
souffle::now
time_point now()
Definition: MiscUtil.h:89
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
souffle::clone
auto clone(const std::vector< A * > &xs)
Definition: ContainerUtil.h:172
i
size_t i
Definition: json11.h:663
souffle::join
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...
Definition: StreamUtil.h:175
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::BinaryConstraintOp::GE
@ GE
souffle::LogStatement::tNonrecursiveRelation
static const std::string tNonrecursiveRelation(const std::string &relationName, const SrcLocation &srcLocation)
Definition: LogStatement.h:37
souffle::LogStatement::tNonrecursiveRule
static const std::string tNonrecursiveRule(const std::string &relationName, const SrcLocation &srcLocation, const std::string &datalogText)
Definition: LogStatement.h:68
souffle::ast2ram::AstToRamTranslator::polyAnalysis
const ast::analysis::PolymorphicObjectsAnalysis * polyAnalysis
Polymorphic Objects Analysis.
Definition: AstToRamTranslator.h:139
souffle::ast::analysis::FunctorAnalysis::getReturnType
TypeAttribute getReturnType(const Functor *functor) const
Return return type of functor.
Definition: Functor.cpp:40
souffle::ast2ram::AstToRamTranslator::makeNegationSubproofSubroutine
Own< ram::Statement > makeNegationSubproofSubroutine(const ast::Clause &clause)
translate RAM code for subroutine to get subproofs for non-existence of a tuple
Definition: AstToRamTranslator.cpp:841
souffle::test::count
int count(const C &c)
Definition: table_test.cpp:40
TCB_SPAN_NAMESPACE_NAME::get
constexpr auto get(span< E, S > s) -> decltype(s[N])
Definition: span.h:599
souffle::LogStatement::tRelationLoadTime
static const std::string tRelationLoadTime(const std::string &relationName, const SrcLocation &srcLocation)
Definition: LogStatement.h:44
souffle::BinaryConstraintOp::LT
@ LT
souffle::ast2ram::AstToRamTranslator::typeEnv
const ast::analysis::TypeEnvironment * typeEnv
Type environment.
Definition: AstToRamTranslator.h:127
souffle::ast::getClauses
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.
Definition: Utils.cpp:77
souffle::ast::Program::getDirectives
std::vector< Directive * > getDirectives() const
Return relation directives.
Definition: Program.h:75
k
var k
Definition: htmlJsChartistMin.h:15
souffle::ast2ram::AstToRamTranslator::translateProgram
void translateProgram(const ast::TranslationUnit &translationUnit)
translate AST to RAM Program
Definition: AstToRamTranslator.cpp:1128
souffle::ast2ram::AstToRamTranslator::removeADTs
static bool removeADTs(const ast::TranslationUnit &translationUnit)
replace ADTs with special records
Definition: AstToRamTranslator.cpp:1056
souffle::ast2ram::AstToRamTranslator::getRelationName
static std::string getRelationName(const ast::QualifiedName &id)
converts the given relation identifier into a relation name
Definition: AstToRamTranslator.cpp:549
souffle::ast2ram::AstToRamTranslator::translateNewRelation
std::string translateNewRelation(const ast::Relation *rel)
translate a temporary new relation to a RAM relation for semi-naive evaluation
Definition: AstToRamTranslator.cpp:232
directives
std::vector< Own< Directive > > directives
Definition: ComponentInstantiation.cpp:66
souffle::ast2ram::appendStmt
void appendStmt(VecOwn< ram::Statement > &stmtList, Own< ram::Statement > stmt)
append statement to a list of statements
Definition: AstToRamTranslator.cpp:144
souffle::ast::analysis::IOTypeAnalysis::getLimitSize
std::size_t getLimitSize(const Relation *relation) const
Definition: IOType.h:65
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
souffle::ast2ram::AstToRamTranslator::makeSubproofSubroutine
Own< ram::Statement > makeSubproofSubroutine(const ast::Clause &clause)
translate RAM code for subroutine to get subproofs
Definition: AstToRamTranslator.cpp:765
souffle::ast2ram::AstToRamTranslator::getSymbolTable
SymbolTable & getSymbolTable()
Return a symbol table.
Definition: AstToRamTranslator.cpp:335
souffle::LogStatement::nNonrecursiveRelation
static const std::string nNonrecursiveRelation(const std::string &relationName, const SrcLocation &srcLocation)
Definition: LogStatement.h:60
souffle::LogStatement::tRecursiveRule
static const std::string tRecursiveRule(const std::string &relationName, const int version, const SrcLocation &srcLocation, const std::string &datalogText)
Definition: LogStatement.h:84
rule
Rule & rule
Definition: Reader.h:85
souffle::ast::NumericConstant::Type::Uint
@ Uint
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::ast::analysis::AuxiliaryArityAnalysis::getArity
size_t getArity(const Atom *atom) const
Returns the number of auxiliary parameters of an atom's relation.
Definition: AuxArity.h:59
souffle::ast2ram::AstToRamTranslator::ioType
const ast::analysis::IOTypeAnalysis * ioType
IO Type.
Definition: AstToRamTranslator.h:130
souffle::RamUnsignedFromString
RamUnsigned RamUnsignedFromString(const std::string &str, std::size_t *position=nullptr, const int base=10)
Converts a string to a RamUnsigned.
Definition: StringUtil.h:110
souffle::ast::getAtomRelation
const Relation * getAtomRelation(const Atom *atom, const Program *program)
Returns the relation referenced by the given atom.
Definition: Utils.cpp:129
souffle::ast2ram::AstToRamTranslator::translateUnit
Own< ram::TranslationUnit > translateUnit(ast::TranslationUnit &tu)
translates AST to translation unit
Definition: AstToRamTranslator.cpp:1329
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::LogStatement::tRelationSaveTime
static const std::string tRelationSaveTime(const std::string &relationName, const SrcLocation &srcLocation)
Definition: LogStatement.h:52
souffle::ast::analysis::getTypeQualifier
std::string getTypeQualifier(const Type &type)
Returns full type qualifier for a given type.
Definition: TypeSystem.cpp:204
souffle::RamFloatFromString
RamFloat RamFloatFromString(const std::string &str, std::size_t *position=nullptr)
Converts a string to a RamFloat.
Definition: StringUtil.h:93
souffle::ast::NumericConstant::Type::Float
@ Float
souffle::TypeAttribute::Float
@ Float
rel
void rel(size_t limit, bool showLimit=true)
Definition: Tui.h:1086
souffle::ast::analysis::PolymorphicObjectsAnalysis::getOverloadedOperator
BinaryConstraintOp getOverloadedOperator(const BinaryConstraint *bc) const
Definition: PolymorphicObjects.cpp:48
souffle::ast2ram::AstToRamTranslator::getOutputDirectives
std::vector< std::map< std::string, std::string > > getOutputDirectives(const ast::Relation *rel)
Definition: AstToRamTranslator.cpp:194
std::type
ElementType type
Definition: span.h:640
souffle::ast2ram::AstToRamTranslator::translateRecursiveRelation
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
Definition: AstToRamTranslator.cpp:554