souffle  2.0.2-371-g6315b36
Public Member Functions | Private Member Functions | Static Private Member Functions
souffle::ast::transform::MagicSetTransformer::LabelDatabaseTransformer::PositiveLabellingTransformer Class Reference

Runs the second stage of the labelling algorithm. More...

#include <MagicSet.h>

Inheritance diagram for souffle::ast::transform::MagicSetTransformer::LabelDatabaseTransformer::PositiveLabellingTransformer:
Inheritance graph
Collaboration diagram for souffle::ast::transform::MagicSetTransformer::LabelDatabaseTransformer::PositiveLabellingTransformer:
Collaboration graph

Public Member Functions

PositiveLabellingTransformerclone () const override
 
std::string getName () const override
 
- Public Member Functions inherited from souffle::ast::transform::Transformer
bool apply (TranslationUnit &translationUnit)
 
virtual ~Transformer ()=default
 

Private Member Functions

bool transform (TranslationUnit &translationUnit) override
 

Static Private Member Functions

static QualifiedName getPositiveLabel (const QualifiedName &name, size_t count)
 Provide a unique name for a positively labelled relation copy. More...
 

Detailed Description

Runs the second stage of the labelling algorithm.

Separates out the dependencies of negatively labelled atoms from the main SCC graph, preventing them from affecting stratification after magic. Note: Negative labelling must have been run first.

Definition at line 208 of file MagicSet.h.

Member Function Documentation

◆ clone()

PositiveLabellingTransformer* souffle::ast::transform::MagicSetTransformer::LabelDatabaseTransformer::PositiveLabellingTransformer::clone ( ) const
inlineoverridevirtual

Implements souffle::ast::transform::Transformer.

Definition at line 214 of file MagicSet.h.

214  {
215  return new PositiveLabellingTransformer();
216  }

◆ getName()

std::string souffle::ast::transform::MagicSetTransformer::LabelDatabaseTransformer::PositiveLabellingTransformer::getName ( ) const
inlineoverridevirtual

Implements souffle::ast::transform::Transformer.

Definition at line 210 of file MagicSet.h.

210  {
211  return "PositiveLabellingTransformer";
212  }

◆ getPositiveLabel()

QualifiedName souffle::ast::transform::PositiveLabellingTransformer::getPositiveLabel ( const QualifiedName name,
size_t  count 
)
staticprivate

Provide a unique name for a positively labelled relation copy.

Definition at line 787 of file MagicSet.cpp.

789  {
790  auto qualifiers = name.getQualifiers();
791  assert(!qualifiers.empty() && "unexpected empty qualifier list");
792  return qualifiers[0] == "@neglabel";
793 }

◆ transform()

bool souffle::ast::transform::PositiveLabellingTransformer::transform ( TranslationUnit translationUnit)
overrideprivatevirtual

Implements souffle::ast::transform::Transformer.

Definition at line 868 of file MagicSet.cpp.

871  {
872  size_t numNeggedRelations = 0;
873  const auto& stratumRels = sccGraph.getInternalRelations(stratum);
874 
875  // Count how many relations in this node are neglabelled
876  for (const auto* rel : stratumRels) {
877  if (isNegativelyLabelled(rel->getQualifiedName())) {
878  numNeggedRelations++;
879  }
880  }
881  assert((numNeggedRelations == 0 || numNeggedRelations == stratumRels.size()) &&
882  "stratum cannot contain a mix of neglabelled and unlabelled relations");
883 
884  if (numNeggedRelations > 0) {
885  // This is a neglabelled stratum that will not be copied
886  neglabelledStrata.insert(stratum);
887  } else {
888  // This is a regular stratum that may be copied
889  originalStrataCopyCount[stratum] = 0;
890  }
891  }
892 
893  // Keep track of strata that depend on each stratum
894  // e.g. T in dependentStrata[S] iff a relation in T depends on a relation in S
895  std::map<size_t, std::set<size_t>> dependentStrata;
896  for (size_t stratum = 0; stratum < sccGraph.getNumberOfSCCs(); stratum++) {
897  dependentStrata[stratum] = std::set<size_t>();
898  }
899  for (const auto* rel : program.getRelations()) {
900  size_t stratum = sccGraph.getSCC(rel);
901  precedenceGraph.visitDepthFirst(rel, [&](const auto* dependentRel) {
902  dependentStrata[stratum].insert(sccGraph.getSCC(dependentRel));
903  });
904  }
905 
906  // Label the positive derived literals in the clauses of neglabelled relations
907  // Need a new copy of those relations up to that point for each
908  for (size_t stratum = 0; stratum < sccGraph.getNumberOfSCCs(); stratum++) {
909  if (!contains(neglabelledStrata, stratum)) continue;
910 
911  // Rename in the current stratum
912  for (const auto* rel : sccGraph.getInternalRelations(stratum)) {
913  assert(isNegativelyLabelled(rel->getQualifiedName()) &&
914  "should only be looking at neglabelled strata");
915  const auto& clauses = getClauses(program, *rel);
916  std::set<QualifiedName> relsToCopy;
917 
918  // Get the unignored unlabelled relations appearing in the rules
919  for (const auto* clause : clauses) {
920  visitDepthFirst(*clause, [&](const Atom& atom) {
921  const auto& name = atom.getQualifiedName();
922  if (!contains(relationsToNotLabel, name) && !isNegativelyLabelled(name)) {
923  relsToCopy.insert(name);
924  }
925  });
926  }
927 
928  // Positively label them
929  for (auto* clause : clauses) {
930  std::map<QualifiedName, QualifiedName> labelledNames;
931  for (const auto& relName : relsToCopy) {
932  size_t relStratum = sccGraph.getSCC(getRelation(program, relName));
933  size_t copyCount = originalStrataCopyCount.at(relStratum) + 1;
934  labelledNames[relName] = getPositiveLabel(relName, copyCount);
935  }
936  renameAtoms(*clause, labelledNames);
937  }
938  }
939 
940  // Create the rules (from all previous strata) for the newly positive labelled literals
941  for (int preStratum = stratum - 1; preStratum >= 0; preStratum--) {
942  if (contains(neglabelledStrata, preStratum)) continue;
943  if (!contains(dependentStrata[preStratum], stratum)) continue;
944 
945  for (const auto* rel : sccGraph.getInternalRelations(preStratum)) {
946  if (contains(relationsToNotLabel, rel->getQualifiedName())) continue;
947 
948  for (const auto* clause : getClauses(program, rel->getQualifiedName())) {
949  // Grab the new names for all unignored unlabelled positive atoms
950  std::map<QualifiedName, QualifiedName> labelledNames;
951  visitDepthFirst(*clause, [&](const Atom& atom) {
952  const auto& relName = atom.getQualifiedName();
953  if (contains(relationsToNotLabel, relName) || isNegativelyLabelled(relName)) return;
954  size_t relStratum = sccGraph.getSCC(getRelation(program, relName));
955  size_t copyCount = originalStrataCopyCount.at(relStratum) + 1;
956  labelledNames[relName] = getPositiveLabel(relName, copyCount);
957  });
958 
959  // Rename atoms accordingly
960  auto labelledClause = souffle::clone(clause);
961  renameAtoms(*labelledClause, labelledNames);
962  program.addClause(std::move(labelledClause));
963  }
964  }
965 
966  originalStrataCopyCount[preStratum]++;
967  }
968  }
969 
970  // Add each copy for each relation in
971  bool changed = false;
972  for (const auto& [stratum, numCopies] : originalStrataCopyCount) {
973  const auto& stratumRels = sccGraph.getInternalRelations(stratum);
974  for (size_t copy = 0; copy < numCopies; copy++) {
975  for (auto* rel : stratumRels) {
976  auto newRelation = souffle::clone(rel);
977  newRelation->setQualifiedName(getPositiveLabel(newRelation->getQualifiedName(), copy + 1));
978  program.addRelation(std::move(newRelation));
979  changed = true;
980  }
981  }
982  }
983  return changed;
984 }
985 
986 bool MagicSetCoreTransformer::isAdorned(const QualifiedName& name) {
987  // Grab the final qualifier - this is where the adornment is if it exists
988  auto qualifiers = name.getQualifiers();
989  assert(!qualifiers.empty() && "unexpected empty qualifier list");
990  auto finalQualifier = qualifiers[qualifiers.size() - 1];

References rel().

Here is the call graph for this function:

The documentation for this class was generated from the following files:
souffle::ast::renameAtoms
bool renameAtoms(Node &node, const std::map< QualifiedName, QualifiedName > &oldToNew)
Rename all atoms hat appear in a node to a given name.
Definition: Utils.cpp:307
souffle::ast::transform::MagicSetTransformer::LabelDatabaseTransformer::isNegativelyLabelled
static bool isNegativelyLabelled(const QualifiedName &name)
Check if a relation is negatively labelled.
Definition: MagicSet.cpp:795
souffle::contains
bool contains(const C &container, const typename C::value_type &element)
A utility to check generically whether a given element is contained in a given container.
Definition: ContainerUtil.h:75
souffle::clone
auto clone(const std::vector< A * > &xs)
Definition: ContainerUtil.h:172
souffle::ast::getRelation
Relation * getRelation(const Program &program, const QualifiedName &name)
Returns the relation with the given name in the program.
Definition: Utils.cpp:101
clauses
std::vector< Own< Clause > > clauses
Definition: ComponentInstantiation.cpp:67
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::detail::brie::copy
auto copy(span< A, arity > s)
Definition: Brie.h:98
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
rel
void rel(size_t limit, bool showLimit=true)
Definition: Tui.h:1086
souffle::ast::transform::PositiveLabellingTransformer
MagicSetTransformer::LabelDatabaseTransformer::PositiveLabellingTransformer PositiveLabellingTransformer
Definition: MagicSet.cpp:68
souffle::ast::transform::MagicSetTransformer::LabelDatabaseTransformer::PositiveLabellingTransformer::getPositiveLabel
static QualifiedName getPositiveLabel(const QualifiedName &name, size_t count)
Provide a unique name for a positively labelled relation copy.
Definition: MagicSet.cpp:787
souffle::ast::transform::MagicSetTransformer::MagicSetCoreTransformer::isAdorned
static bool isAdorned(const QualifiedName &name)
Checks if a given relation name is adorned.
Definition: MagicSet.cpp:992