62 inline QualifiedName 
makeRelationName(
const QualifiedName& orig, 
const std::string& 
type, 
int num = -1) {
 
   63     QualifiedName newName(
toString(orig));
 
   66         newName.append((
const std::string&)std::to_string(num));
 
   79     infoRelation->setQualifiedName(name);
 
   84     auto infoClause = 
new Clause();
 
   85     auto infoClauseHead = 
new Atom();
 
   86     infoClauseHead->setQualifiedName(name);
 
   89     infoRelation->addAttribute(mk<Attribute>(
"clause_num", 
QualifiedName(
"number")));
 
   90     infoClauseHead->addArgument(mk<NumericConstant>(originalClauseNum));
 
   93     std::vector<std::string> headVariables;
 
   98     int functorNumber = 0;
 
   99     int aggregateNumber = 0;
 
  100     auto getArgInfo = [&](
Argument* arg) -> std::string {
 
  103         } 
else if (
auto* constant = 
dynamic_cast<Constant*
>(arg)) {
 
  106         if (isA<UnnamedVariable>(arg)) {
 
  109         if (isA<Functor>(arg)) {
 
  112         if (isA<Aggregator>(arg)) {
 
  116         fatal(
"Unhandled argument type");
 
  121         headVariables.push_back(getArgInfo(arg));
 
  125     std::stringstream headVariableString;
 
  126     headVariableString << 
join(headVariables, 
",");
 
  129     infoRelation->addAttribute(mk<Attribute>(std::string(
"head_vars"), QualifiedName(
"symbol")));
 
  130     infoClauseHead->addArgument(mk<StringConstant>(
toString(
join(headVariables, 
","))));
 
  136         const Atom* atom = 
nullptr;
 
  137         if (isA<Atom>(lit)) {
 
  138             atom = 
static_cast<Atom*
>(lit);
 
  139         } 
else if (isA<Negation>(lit)) {
 
  140             atom = 
static_cast<Negation*
>(lit)->getAtom();
 
  141         } 
else if (isA<ProvenanceNegation>(lit)) {
 
  142             atom = 
static_cast<ProvenanceNegation*
>(lit)->getAtom();
 
  146         if (atom != 
nullptr || isA<BinaryConstraint>(lit)) {
 
  147             infoRelation->addAttribute(
 
  148                     mk<Attribute>(std::string(
"rel_") + std::to_string(
i), QualifiedName(
"symbol")));
 
  151         if (atom != 
nullptr) {
 
  152             std::string relName = 
toString(atom->getQualifiedName());
 
  155             if (isA<Atom>(lit)) {
 
  156                 std::string atomDescription = relName;
 
  158                 for (
auto& arg : atom->getArguments()) {
 
  159                     atomDescription.append(
"," + getArgInfo(arg));
 
  162                 infoClauseHead->addArgument(mk<StringConstant>(atomDescription));
 
  164             } 
else if (isA<Negation>(lit)) {
 
  165                 infoClauseHead->addArgument(mk<StringConstant>(
"!" + relName));
 
  174         if (
auto con = 
dynamic_cast<BinaryConstraint*
>(lit)) {
 
  178             constraintDescription.append(
"," + getArgInfo(con->getLHS()));
 
  179             constraintDescription.append(
"," + getArgInfo(con->getRHS()));
 
  181             infoClauseHead->addArgument(mk<StringConstant>(constraintDescription));
 
  185     infoRelation->addAttribute(mk<Attribute>(
"clause_repr", QualifiedName(
"symbol")));
 
  186     infoClauseHead->addArgument(mk<StringConstant>(
toString(originalClause)));
 
  189     infoClause->setHead(Own<Atom>(infoClauseHead));
 
  190     Program& program = translationUnit.
getProgram();
 
  191     program.
addClause(Own<Clause>(infoClause));
 
  193     return Own<Relation>(infoRelation);
 
  199             "attempting to transform non-eqrel relation");
 
  200     assert(
rel.getArity() == 2 && 
"eqrel relation not binary");
 
  206     auto transitiveClause = 
new Clause();
 
  207     auto transitiveClauseHead = 
new Atom(
rel.getQualifiedName());
 
  208     transitiveClauseHead->addArgument(mk<ast::Variable>(
"x"));
 
  209     transitiveClauseHead->addArgument(mk<ast::Variable>(
"z"));
 
  211     auto transitiveClauseBody = 
new Atom(
rel.getQualifiedName());
 
  212     transitiveClauseBody->addArgument(mk<ast::Variable>(
"x"));
 
  213     transitiveClauseBody->addArgument(mk<ast::Variable>(
"y"));
 
  215     auto transitiveClauseBody2 = 
new Atom(
rel.getQualifiedName());
 
  216     transitiveClauseBody2->addArgument(mk<ast::Variable>(
"y"));
 
  217     transitiveClauseBody2->addArgument(mk<ast::Variable>(
"z"));
 
  219     transitiveClause->setHead(
Own<Atom>(transitiveClauseHead));
 
  220     transitiveClause->addToBody(
Own<Literal>(transitiveClauseBody));
 
  221     transitiveClause->addToBody(
Own<Literal>(transitiveClauseBody2));
 
  226     auto symClause = 
new Clause();
 
  227     auto symClauseHead = 
new Atom(
rel.getQualifiedName());
 
  228     symClauseHead->addArgument(mk<ast::Variable>(
"x"));
 
  229     symClauseHead->addArgument(mk<ast::Variable>(
"y"));
 
  231     auto symClauseBody = 
new Atom(
rel.getQualifiedName());
 
  232     symClauseBody->addArgument(mk<ast::Variable>(
"y"));
 
  233     symClauseBody->addArgument(mk<ast::Variable>(
"x"));
 
  235     symClause->setHead(
Own<Atom>(symClauseHead));
 
  241     auto reflexiveClause = 
new Clause();
 
  242     auto reflexiveClauseHead = 
new Atom(
rel.getQualifiedName());
 
  243     reflexiveClauseHead->addArgument(mk<ast::Variable>(
"x"));
 
  244     reflexiveClauseHead->addArgument(mk<ast::Variable>(
"x"));
 
  246     auto reflexiveClauseBody = 
new Atom(
rel.getQualifiedName());
 
  247     reflexiveClauseBody->addArgument(mk<ast::Variable>(
"x"));
 
  248     reflexiveClauseBody->addArgument(mk<UnnamedVariable>());
 
  250     reflexiveClause->setHead(
Own<Atom>(reflexiveClauseHead));
 
  251     reflexiveClause->addToBody(
Own<Literal>(reflexiveClauseBody));
 
  256 Own<Argument> getNextLevelNumber(
const std::vector<Argument*>& levels) {
 
  257     if (levels.empty()) 
return mk<NumericConstant>(0);
 
  259     auto max = levels.size() == 1
 
  263     return mk<IntrinsicFunctor>(
"+", std::move(max), mk<NumericConstant>(1));
 
  268     Program& program = translationUnit.getProgram();
 
  270     for (
auto relation : program.getRelations()) {
 
  277     for (
auto relation : program.getRelations()) {
 
  289         relation->addAttribute(mk<Attribute>(std::string(
"@rule_number"), QualifiedName(
"number")));
 
  290         relation->addAttribute(mk<Attribute>(std::string(
"@level_number"), QualifiedName(
"number")));
 
  296             struct M : 
public NodeMapper {
 
  297                 using NodeMapper::operator();
 
  299                 Own<Node> operator()(Own<Node> node)
 const override {
 
  301                     if (
auto atom = 
dynamic_cast<Atom*
>(node.get())) {
 
  302                         atom->addArgument(mk<UnnamedVariable>());
 
  303                         atom->addArgument(mk<UnnamedVariable>());
 
  304                     } 
else if (
auto neg = 
dynamic_cast<Negation*
>(node.get())) {
 
  305                         auto atom = neg->getAtom();
 
  306                         atom->addArgument(mk<UnnamedVariable>());
 
  307                         atom->addArgument(mk<UnnamedVariable>());
 
  317             clause->getHead()->apply(M());
 
  321                 clause->getHead()->addArgument(mk<NumericConstant>(0));
 
  322                 clause->getHead()->addArgument(mk<NumericConstant>(0));
 
  324                 std::vector<Argument*> bodyLevels;
 
  326                 for (
size_t i = 0; 
i < clause->getBodyLiterals().
size(); 
i++) {
 
  327                     auto lit = clause->getBodyLiterals()[
i];
 
  333                     if (
auto atom = 
dynamic_cast<Atom*
>(lit)) {
 
  334                         atom->addArgument(mk<UnnamedVariable>());
 
  335                         atom->addArgument(mk<ast::Variable>(
"@level_num_" + std::to_string(
i)));
 
  336                         bodyLevels.push_back(
new ast::Variable(
"@level_num_" + std::to_string(
i)));
 
  341                 clause->getHead()->addArgument(mk<NumericConstant>(clauseNum));
 
  342                 clause->getHead()->addArgument(getNextLevelNumber(bodyLevels));