44 using namespace analysis;
 
   46 TEST(Transformers, GroundTermPropagation) {
 
   55                 p(a,b) :- p(x,y), r = [x,y], s = r, s = [w,v], [w,v] = [a,b]. 
   57             errorReport, debugReport); 
   59     Program& program = tu->getProgram(); 
   64     EXPECT_EQ(
"p(a,b) :- \n   p(x,y),\n   r = [x,y],\n   s = r,\n   s = [w,v],\n   [w,v] = [a,b].",
 
   71             "p(x,y) :- \n   p(x,y),\n   [x,y] = [x,y],\n   [x,y] = [x,y],\n   [x,y] = [x,y],\n   [x,y] = " 
   77 TEST(Transformers, GroundTermPropagation2) {
 
   86                p(a,b) :- p(x,y), x = y, x = a, y = b. 
   88             errorReport, debugReport); 
   90     Program& program = tu->getProgram(); 
  104 TEST(Transformers, ResolveGroundedAliases) {
 
  113                 p(a,b) :- p(x,y), r = [x,y], s = r, s = [w,v], [w,v] = [a,b]. 
  115             errorReport, debugReport); 
  117     Program& program = tu->getProgram(); 
  119     EXPECT_EQ("p(a,b) :- \n   p(x,y),\n   r = [x,y],\n   s = r,\n   s = [w,v],\n   [w,v] = [a,b].",
 
  122     mk<ResolveAliasesTransformer>()->apply(*tu);
 
  127 TEST(Transformers, ResolveAliasesWithTermsInAtoms) {
 
  136                 p(x,c) :- p(x,b), p(b,c), c = b+1, x=c+2. 
  138             errorReport, debugReport); 
  140     Program& program = tu->getProgram(); 
  142     EXPECT_EQ("p(x,c) :- \n   p(x,b),\n   p(b,c),\n   c = (b+1),\n   x = (c+2).",
 
  145     mk<ResolveAliasesTransformer>()->apply(*tu);
 
  147     EXPECT_EQ(
"p(x,c) :- \n   p(x,b),\n   p(b,c),\n   c = (b+1),\n   x = (c+2).",
 
  165 TEST(Transformers, RemoveRelationCopies) {
 
  181                 d(x,y) :- b(x,y), c(y,x). 
  184             errorReport, debugReport); 
  186     Program& program = tu->getProgram(); 
  210 TEST(Transformers, RemoveRelationCopiesOutput) {
 
  227                 d(x,y) :- b(x,y), c(y,x). 
  230             errorReport, debugReport); 
  232     Program& program = tu->getProgram(); 
  244 TEST(Transformers, CheckClausalEquivalence) {
 
  250                 .decl A(x:number, y:number) 
  260                 C(z) :- A(z,y), A(z,x), x != 3, x < y, !B(x), y > 3, B(y). 
  261                 C(r) :- A(r,y), A(r,x), x != 3, x < y, !B(y), y > 3, B(y), B(x), x < y. 
  262                 C(x) :- A(x,a), a != 3, !B(a), A(x,b), b > 3, B(c), a < b, c = b. 
  264             errorReport, debugReport); 
  266     const auto& program = tu->getProgram();
 
  269     mk<ResolveAliasesTransformer>()->
apply(*tu);
 
  283     EXPECT_EQ(
"C(z) :- \n   A(z,y),\n   A(z,x),\n   x != 3,\n   x < y,\n   !B(x),\n   y > 3,\n   B(y).",
 
  286             "C(r) :- \n   A(r,y),\n   A(r,x),\n   x != 3,\n   x < y,\n   !B(y),\n   y > 3,\n   B(y),\n   " 
  289     EXPECT_EQ(
"C(x) :- \n   A(x,a),\n   a != 3,\n   !B(a),\n   A(x,b),\n   b > 3,\n   B(b),\n   a < b.",
 
  311     mk<MinimiseProgramTransformer>()->apply(*tu);
 
  324     EXPECT_EQ(
"C(z) :- \n   A(z,y),\n   A(z,x),\n   x != 3,\n   x < y,\n   !B(x),\n   y > 3,\n   B(y).",
 
  327             "C(r) :- \n   A(r,y),\n   A(r,x),\n   x != 3,\n   x < y,\n   !B(y),\n   y > 3,\n   B(y),\n   " 
  335 TEST(Transformers, CheckAggregatorEquivalence) {
 
  341                 .decl A,B,C,D(X:number) input 
  342                 // first and second are equivalent 
  345                     X < max Y : { C(Y), B(Y), Y < 2 }, 
  347                     Z = sum A : { C(A), B(A), A > count : { A(M), C(M) } }. 
  352                     W = sum test1 : { C(test1), B(test1), test1 > count : { C(X), A(X) } }, 
  353                     V < max test2 : { C(test2), B(test2), test2 < 2 }. 
  355                 // third not equivalent 
  359                     W = min test1 : { C(test1), B(test1), test1 > count : { C(X), A(X) } }, 
  360                     V < max test2 : { C(test2), B(test2), test2 < 2 }. 
  364             errorReport, debugReport); 
  366     const auto& program = tu->getProgram();
 
  367     mk<MinimiseProgramTransformer>()->
apply(*tu);
 
  377     const auto& dClauses = 
getClauses(program, 
"D");
 
  380             "D(X) :- \n   B(X),\n   X < max Y : { C(Y),B(Y),Y < 2 },\n   A(Z),\n   Z = sum A : { C(A),B(A),A " 
  381             "> count : { A(M),C(M) } }.",
 
  384             "D(V) :- \n   B(V),\n   A(W),\n   W = min test1 : { C(test1),B(test1),test1 > count : { " 
  385             "C(X),A(X) } },\n   V < max test2 : { C(test2),B(test2),test2 < 2 }.",
 
  398 TEST(Transformers, RemoveClauseRedundancies) {
 
  404                 .decl a,b,c(X:number) 
  411                 a(X) :- a(X), X != 1. 
  418             errorReport, debugReport); 
  420     const auto& program = tu->getProgram();
 
  425     mk<RemoveRelationCopiesTransformer>()->
apply(*tu);
 
  427     auto bIntermediateClauses = 
getClauses(program, 
"b");
 
  428     EXPECT_EQ(2, bIntermediateClauses.size());
 
  433     mk<MinimiseProgramTransformer>()->apply(*tu);
 
  457 TEST(Transformers, MagicSetComprehensive) {
 
  463                 // Stratum 0 - Base Relations 
  464                 .decl BaseOne(X:number) magic 
  465                 .decl BaseTwo(X:number) magic 
  466                 .input BaseOne, BaseTwo 
  468                 // Stratum 1 [depends on: 0] 
  469                 .decl A(X:number) magic 
  470                 .decl B(X:number) magic 
  472                 A(X) :- BaseOne(X), B(X). 
  473                 B(X) :- BaseTwo(X), A(X). 
  475                 // Stratum 2 [depends on: 0,1] 
  476                 .decl C(X:number) magic 
  477                 C(X) :- BaseTwo(X), A(X), B(X), X != 1. 
  479                 // Stratum 3 [depends on: 0,1] 
  480                 .decl R(X:number) magic 
  481                 R(X) :- BaseTwo(X), A(X), B(X), X != 0. 
  483                 // Stratum 4 [depends on: 0,1,2,3] 
  484                 .decl D(X:number) magic 
  485                 D(X) :- BaseOne(X), A(X), !C(X), !R(X). 
  487                 // Stratum 4 - Query [depends on: 0,1,4] 
  488                 .decl Query(X:number) magic 
  490                 Query(X) :- BaseOne(X), D(X), A(X). 
  494     auto& program = tu->getProgram();
 
  497     auto mappifyRelations = [&](
const Program& program) {
 
  498         std::map<std::string, std::multiset<std::string>> result;
 
  500             std::multiset<std::string> clauseStrings;
 
  501             auto relName = 
rel->getQualifiedName();
 
  502             for (
const auto* clause : 
getClauses(program, 
rel->getQualifiedName())) {
 
  503                 clauseStrings.insert(
toString(*clause));
 
  505             result[
toString(relName)] = clauseStrings;
 
  509     auto checkRelMapEq = [&](
const std::map<std::string, std::multiset<std::string>> left,
 
  510                                  const std::map<std::string, std::multiset<std::string>> right) {
 
  512         for (
const auto& [name, 
clauses] : left) {
 
  520     mk<MagicSetTransformer::NormaliseDatabaseTransformer>()->apply(*tu);
 
  525     auto expectedNormalisation = std::map<std::string, std::multiset<std::string>>({
 
  528             {
"A", {
"A(X) :- \n   BaseOne(X).", 
"A(X) :- \n   BaseOne(X),\n   B(X)."}},
 
  529             {
"B", {
"B(X) :- \n   BaseTwo(X),\n   A(X)."}},
 
  530             {
"C", {
"C(X) :- \n   BaseTwo(X),\n   A(X),\n   B(X),\n   X != @abdul0,\n   @abdul0 = 1."}},
 
  531             {
"R", {
"R(X) :- \n   BaseTwo(X),\n   A(X),\n   B(X),\n   X != @abdul0,\n   @abdul0 = 0."}},
 
  532             {
"D", {
"D(X) :- \n   BaseOne(X),\n   A(X),\n   !C(X),\n   !R(X)."}},
 
  533             {
"Query", {
"Query(X) :- \n   BaseOne(X),\n   D(X),\n   A(X)."}},
 
  535     checkRelMapEq(expectedNormalisation, mappifyRelations(program));
 
  539     mk<MagicSetTransformer::LabelDatabaseTransformer::NegativeLabellingTransformer>()->apply(*tu);
 
  543     auto expectedNegLabelling = std::map<std::string, std::multiset<std::string>>({
 
  547             {
"A", {
"A(X) :- \n   BaseOne(X).", 
"A(X) :- \n   BaseOne(X),\n   B(X)."}},
 
  548             {
"B", {
"B(X) :- \n   BaseTwo(X),\n   A(X)."}},
 
  549             {
"C", {
"C(X) :- \n   BaseTwo(X),\n   A(X),\n   B(X),\n   X != @abdul0,\n   @abdul0 = 1."}},
 
  550             {
"R", {
"R(X) :- \n   BaseTwo(X),\n   A(X),\n   B(X),\n   X != @abdul0,\n   @abdul0 = 0."}},
 
  551             {
"D", {
"D(X) :- \n   BaseOne(X),\n   A(X),\n   !@neglabel.C(X),\n   !@neglabel.R(X)."}},
 
  552             {
"Query", {
"Query(X) :- \n   BaseOne(X),\n   D(X),\n   A(X)."}},
 
  555             {
"@neglabel.A", {
"@neglabel.A(X) :- \n   BaseOne(X).",
 
  556                                     "@neglabel.A(X) :- \n   BaseOne(X),\n   @neglabel.B(X)."}},
 
  557             {
"@neglabel.B", {
"@neglabel.B(X) :- \n   BaseTwo(X),\n   @neglabel.A(X)."}},
 
  558             {
"@neglabel.C", {
"@neglabel.C(X) :- \n   BaseTwo(X),\n   A(X),\n   B(X),\n   X != @abdul0,\n   " 
  560             {
"@neglabel.R", {
"@neglabel.R(X) :- \n   BaseTwo(X),\n   A(X),\n   B(X),\n   X != @abdul0,\n   " 
  562             {
"@neglabel.D", {
"@neglabel.D(X) :- \n   BaseOne(X),\n   A(X),\n   !@neglabel.C(X),\n   " 
  563                              "!@neglabel.R(X)."}},
 
  564             {
"@neglabel.Query", {
"@neglabel.Query(X) :- \n   BaseOne(X),\n   D(X),\n   A(X)."}},
 
  566     checkRelMapEq(expectedNegLabelling, mappifyRelations(program));
 
  569     mk<MagicSetTransformer::LabelDatabaseTransformer::PositiveLabellingTransformer>()->apply(*tu);
 
  573     auto expectedPosLabelling = std::map<std::string, std::multiset<std::string>>({
 
  577             {
"A", {
"A(X) :- \n   BaseOne(X).", 
"A(X) :- \n   BaseOne(X),\n   B(X)."}},
 
  578             {
"B", {
"B(X) :- \n   BaseTwo(X),\n   A(X)."}},
 
  579             {
"C", {
"C(X) :- \n   BaseTwo(X),\n   A(X),\n   B(X),\n   X != @abdul0,\n   @abdul0 = 1."}},
 
  580             {
"R", {
"R(X) :- \n   BaseTwo(X),\n   A(X),\n   B(X),\n   X != @abdul0,\n   @abdul0 = 0."}},
 
  581             {
"D", {
"D(X) :- \n   BaseOne(X),\n   A(X),\n   !@neglabel.C(X),\n   !@neglabel.R(X)."}},
 
  582             {
"Query", {
"Query(X) :- \n   BaseOne(X),\n   D(X),\n   A(X)."}},
 
  585             {
"@neglabel.A", {
"@neglabel.A(X) :- \n   BaseOne(X).",
 
  586                                     "@neglabel.A(X) :- \n   BaseOne(X),\n   @neglabel.B(X)."}},
 
  587             {
"@neglabel.B", {
"@neglabel.B(X) :- \n   BaseTwo(X),\n   @neglabel.A(X)."}},
 
  588             {
"@neglabel.C", {
"@neglabel.C(X) :- \n   BaseTwo(X),\n   @poscopy_1.A(X),\n   @poscopy_1.B(X),\n " 
  591             {
"@neglabel.R", {
"@neglabel.R(X) :- \n   BaseTwo(X),\n   @poscopy_2.A(X),\n   @poscopy_2.B(X),\n " 
  595                     {
"@neglabel.D(X) :- \n   BaseOne(X),\n   @poscopy_3.A(X),\n   !@neglabel.C(X),\n   " 
  596                      "!@neglabel.R(X)."}},
 
  598                     {
"@neglabel.Query(X) :- \n   BaseOne(X),\n   @poscopy_1.D(X),\n   @poscopy_4.A(X)."}},
 
  601             {
"@poscopy_1.BaseOne", {}},
 
  602             {
"@poscopy_1.BaseTwo", {}},
 
  603             {
"@poscopy_2.BaseOne", {}},
 
  604             {
"@poscopy_2.BaseTwo", {}},
 
  605             {
"@poscopy_3.BaseOne", {}},
 
  606             {
"@poscopy_3.BaseTwo", {}},
 
  607             {
"@poscopy_4.BaseOne", {}},
 
  608             {
"@poscopy_4.BaseTwo", {}},
 
  609             {
"@poscopy_5.BaseOne", {}},
 
  610             {
"@poscopy_5.BaseTwo", {}},
 
  613             {
"@poscopy_1.A", {
"@poscopy_1.A(X) :- \n   BaseOne(X).",
 
  614                                      "@poscopy_1.A(X) :- \n   BaseOne(X),\n   @poscopy_1.B(X)."}},
 
  615             {
"@poscopy_1.B", {
"@poscopy_1.B(X) :- \n   BaseTwo(X),\n   @poscopy_1.A(X)."}},
 
  616             {
"@poscopy_2.A", {
"@poscopy_2.A(X) :- \n   BaseOne(X).",
 
  617                                      "@poscopy_2.A(X) :- \n   BaseOne(X),\n   @poscopy_2.B(X)."}},
 
  618             {
"@poscopy_2.B", {
"@poscopy_2.B(X) :- \n   BaseTwo(X),\n   @poscopy_2.A(X)."}},
 
  619             {
"@poscopy_3.A", {
"@poscopy_3.A(X) :- \n   BaseOne(X).",
 
  620                                      "@poscopy_3.A(X) :- \n   BaseOne(X),\n   @poscopy_3.B(X)."}},
 
  621             {
"@poscopy_3.B", {
"@poscopy_3.B(X) :- \n   BaseTwo(X),\n   @poscopy_3.A(X)."}},
 
  622             {
"@poscopy_4.A", {
"@poscopy_4.A(X) :- \n   BaseOne(X).",
 
  623                                      "@poscopy_4.A(X) :- \n   BaseOne(X),\n   @poscopy_4.B(X)."}},
 
  624             {
"@poscopy_4.B", {
"@poscopy_4.B(X) :- \n   BaseTwo(X),\n   @poscopy_4.A(X)."}},
 
  627             {
"@poscopy_1.D", {
"@poscopy_1.D(X) :- \n   BaseOne(X),\n   @poscopy_4.A(X),\n   " 
  628                               "!@neglabel.C(X),\n   !@neglabel.R(X)."}},
 
  630     checkRelMapEq(expectedPosLabelling, mappifyRelations(program));
 
  633     mk<RemoveRedundantRelationsTransformer>()->apply(*tu);
 
  637     auto expectedFullLabelling = std::map<std::string, std::multiset<std::string>>({
 
  641             {
"A", {
"A(X) :- \n   BaseOne(X).", 
"A(X) :- \n   BaseOne(X),\n   B(X)."}},
 
  642             {
"B", {
"B(X) :- \n   BaseTwo(X),\n   A(X)."}},
 
  643             {
"D", {
"D(X) :- \n   BaseOne(X),\n   A(X),\n   !@neglabel.C(X),\n   !@neglabel.R(X)."}},
 
  644             {
"Query", {
"Query(X) :- \n   BaseOne(X),\n   D(X),\n   A(X)."}},
 
  647             {
"@neglabel.C", {
"@neglabel.C(X) :- \n   BaseTwo(X),\n   @poscopy_1.A(X),\n   @poscopy_1.B(X),\n " 
  650             {
"@neglabel.R", {
"@neglabel.R(X) :- \n   BaseTwo(X),\n   @poscopy_2.A(X),\n   @poscopy_2.B(X),\n " 
  655             {
"@poscopy_1.A", {
"@poscopy_1.A(X) :- \n   BaseOne(X).",
 
  656                                      "@poscopy_1.A(X) :- \n   BaseOne(X),\n   @poscopy_1.B(X)."}},
 
  657             {
"@poscopy_1.B", {
"@poscopy_1.B(X) :- \n   BaseTwo(X),\n   @poscopy_1.A(X)."}},
 
  658             {
"@poscopy_2.A", {
"@poscopy_2.A(X) :- \n   BaseOne(X).",
 
  659                                      "@poscopy_2.A(X) :- \n   BaseOne(X),\n   @poscopy_2.B(X)."}},
 
  660             {
"@poscopy_2.B", {
"@poscopy_2.B(X) :- \n   BaseTwo(X),\n   @poscopy_2.A(X)."}},
 
  662     checkRelMapEq(expectedFullLabelling, mappifyRelations(program));
 
  666     mk<MagicSetTransformer::AdornDatabaseTransformer>()->apply(*tu);
 
  670     auto expectedAdornment = std::map<std::string, std::multiset<std::string>>({
 
  673             {
"A", {
"A(X) :- \n   BaseOne(X).", 
"A(X) :- \n   BaseOne(X),\n   B(X)."}},
 
  674             {
"B", {
"B(X) :- \n   BaseTwo(X),\n   A(X)."}},
 
  675             {
"D", {
"D(X) :- \n   BaseOne(X),\n   A(X),\n   !@neglabel.C(X),\n   !@neglabel.R(X)."}},
 
  677             {
"@neglabel.C", {
"@neglabel.C(X) :- \n   BaseTwo(X),\n   @poscopy_1.A.{b}(X),\n   " 
  678                              "@poscopy_1.B.{b}(X),\n   X != @abdul0,\n   @abdul0 = 1."}},
 
  679             {
"@neglabel.R", {
"@neglabel.R(X) :- \n   BaseTwo(X),\n   @poscopy_2.A.{b}(X),\n   " 
  680                              "@poscopy_2.B.{b}(X),\n   X != @abdul0,\n   @abdul0 = 0."}},
 
  681             {
"@poscopy_1.A", {
"@poscopy_1.A(X) :- \n   BaseOne(X).",
 
  682                                      "@poscopy_1.A(X) :- \n   BaseOne(X),\n   @poscopy_1.B(X)."}},
 
  683             {
"@poscopy_1.B", {
"@poscopy_1.B(X) :- \n   BaseTwo(X),\n   @poscopy_1.A(X)."}},
 
  684             {
"@poscopy_2.A", {
"@poscopy_2.A(X) :- \n   BaseOne(X).",
 
  685                                      "@poscopy_2.A(X) :- \n   BaseOne(X),\n   @poscopy_2.B(X)."}},
 
  686             {
"@poscopy_2.B", {
"@poscopy_2.B(X) :- \n   BaseTwo(X),\n   @poscopy_2.A(X)."}},
 
  688             {
"Query", {
"Query(X) :- \n   BaseOne(X),\n   D.{b}(X),\n   A.{b}(X)."}},
 
  689             {
"A.{b}", {
"A.{b}(X) :- \n   BaseOne(X).", 
"A.{b}(X) :- \n   BaseOne(X),\n   B.{b}(X)."}},
 
  690             {
"B.{b}", {
"B.{b}(X) :- \n   BaseTwo(X),\n   A.{b}(X)."}},
 
  692                     {
"D.{b}(X) :- \n   BaseOne(X),\n   A.{b}(X),\n   !@neglabel.C(X),\n   !@neglabel.R(X)."}},
 
  693             {
"@poscopy_1.A.{b}", {
"@poscopy_1.A.{b}(X) :- \n   BaseOne(X).",
 
  694                                          "@poscopy_1.A.{b}(X) :- \n   BaseOne(X),\n   @poscopy_1.B.{b}(X)."}},
 
  695             {
"@poscopy_1.B.{b}", {
"@poscopy_1.B.{b}(X) :- \n   BaseTwo(X),\n   @poscopy_1.A.{b}(X)."}},
 
  696             {
"@poscopy_2.A.{b}", {
"@poscopy_2.A.{b}(X) :- \n   BaseOne(X).",
 
  697                                          "@poscopy_2.A.{b}(X) :- \n   BaseOne(X),\n   @poscopy_2.B.{b}(X)."}},
 
  698             {
"@poscopy_2.B.{b}", {
"@poscopy_2.B.{b}(X) :- \n   BaseTwo(X),\n   @poscopy_2.A.{b}(X)."}},
 
  701     checkRelMapEq(expectedAdornment, mappifyRelations(program));
 
  704     mk<RemoveRedundantRelationsTransformer>()->apply(*tu);
 
  708     auto expectedFinalAdornment = std::map<std::string, std::multiset<std::string>>({
 
  711             {
"@neglabel.C", {
"@neglabel.C(X) :- \n   BaseTwo(X),\n   @poscopy_1.A.{b}(X),\n   " 
  712                              "@poscopy_1.B.{b}(X),\n   X != @abdul0,\n   @abdul0 = 1."}},
 
  713             {
"@neglabel.R", {
"@neglabel.R(X) :- \n   BaseTwo(X),\n   @poscopy_2.A.{b}(X),\n   " 
  714                              "@poscopy_2.B.{b}(X),\n   X != @abdul0,\n   @abdul0 = 0."}},
 
  715             {
"Query", {
"Query(X) :- \n   BaseOne(X),\n   D.{b}(X),\n   A.{b}(X)."}},
 
  716             {
"A.{b}", {
"A.{b}(X) :- \n   BaseOne(X).", 
"A.{b}(X) :- \n   BaseOne(X),\n   B.{b}(X)."}},
 
  717             {
"B.{b}", {
"B.{b}(X) :- \n   BaseTwo(X),\n   A.{b}(X)."}},
 
  719                     {
"D.{b}(X) :- \n   BaseOne(X),\n   A.{b}(X),\n   !@neglabel.C(X),\n   !@neglabel.R(X)."}},
 
  720             {
"@poscopy_1.A.{b}", {
"@poscopy_1.A.{b}(X) :- \n   BaseOne(X).",
 
  721                                          "@poscopy_1.A.{b}(X) :- \n   BaseOne(X),\n   @poscopy_1.B.{b}(X)."}},
 
  722             {
"@poscopy_1.B.{b}", {
"@poscopy_1.B.{b}(X) :- \n   BaseTwo(X),\n   @poscopy_1.A.{b}(X)."}},
 
  723             {
"@poscopy_2.A.{b}", {
"@poscopy_2.A.{b}(X) :- \n   BaseOne(X).",
 
  724                                          "@poscopy_2.A.{b}(X) :- \n   BaseOne(X),\n   @poscopy_2.B.{b}(X)."}},
 
  725             {
"@poscopy_2.B.{b}", {
"@poscopy_2.B.{b}(X) :- \n   BaseTwo(X),\n   @poscopy_2.A.{b}(X)."}},
 
  728     checkRelMapEq(expectedFinalAdornment, mappifyRelations(program));
 
  731     mk<MagicSetTransformer::MagicSetCoreTransformer>()->apply(*tu);
 
  735     auto finalProgram = std::map<std::string, std::multiset<std::string>>({
 
  739             {
"@neglabel.C", {
"@neglabel.C(X) :- \n   BaseTwo(X),\n   @poscopy_1.A.{b}(X),\n   " 
  740                              "@poscopy_1.B.{b}(X),\n   X != @abdul0,\n   @abdul0 = 1."}},
 
  741             {
"@neglabel.R", {
"@neglabel.R(X) :- \n   BaseTwo(X),\n   @poscopy_2.A.{b}(X),\n   " 
  742                              "@poscopy_2.B.{b}(X),\n   X != @abdul0,\n   @abdul0 = 0."}},
 
  744             {
"A.{b}", {
"A.{b}(X) :- \n   @magic.A.{b}(X),\n   BaseOne(X),\n   B.{b}(X).",
 
  745                               "A.{b}(X) :- \n   @magic.A.{b}(X),\n   BaseOne(X)."}},
 
  746             {
"B.{b}", {
"B.{b}(X) :- \n   @magic.B.{b}(X),\n   BaseTwo(X),\n   A.{b}(X)."}},
 
  747             {
"D.{b}", {
"D.{b}(X) :- \n   @magic.D.{b}(X),\n   BaseOne(X),\n   A.{b}(X),\n   " 
  748                        "!@neglabel.C(X),\n   !@neglabel.R(X)."}},
 
  750             {
"@poscopy_1.A.{b}", {
"@poscopy_1.A.{b}(X) :- \n   @magic.@poscopy_1.A.{b}(X),\n   BaseOne(X).",
 
  751                                          "@poscopy_1.A.{b}(X) :- \n   @magic.@poscopy_1.A.{b}(X),\n   " 
  752                                          "BaseOne(X),\n   @poscopy_1.B.{b}(X)."}},
 
  753             {
"@poscopy_1.B.{b}", {
"@poscopy_1.B.{b}(X) :- \n   @magic.@poscopy_1.B.{b}(X),\n   BaseTwo(X),\n " 
  754                                   "  @poscopy_1.A.{b}(X)."}},
 
  755             {
"@poscopy_2.A.{b}", {
"@poscopy_2.A.{b}(X) :- \n   @magic.@poscopy_2.A.{b}(X),\n   BaseOne(X).",
 
  756                                          "@poscopy_2.A.{b}(X) :- \n   @magic.@poscopy_2.A.{b}(X),\n   " 
  757                                          "BaseOne(X),\n   @poscopy_2.B.{b}(X)."}},
 
  758             {
"@poscopy_2.B.{b}", {
"@poscopy_2.B.{b}(X) :- \n   @magic.@poscopy_2.B.{b}(X),\n   BaseTwo(X),\n " 
  759                                   "  @poscopy_2.A.{b}(X)."}},
 
  761             {
"Query", {
"Query(X) :- \n   BaseOne(X),\n   D.{b}(X),\n   A.{b}(X)."}},
 
  764             {
"@magic.A.{b}", {
"@magic.A.{b}(X) :- \n   @magic.B.{b}(X),\n   BaseTwo(X).",
 
  765                                      "@magic.A.{b}(X) :- \n   BaseOne(X),\n   D.{b}(X).",
 
  766                                      "@magic.A.{b}(X) :- \n   @magic.D.{b}(X),\n   BaseOne(X)."}},
 
  767             {
"@magic.B.{b}", {
"@magic.B.{b}(X) :- \n   @magic.A.{b}(X),\n   BaseOne(X)."}},
 
  768             {
"@magic.D.{b}", {
"@magic.D.{b}(X) :- \n   BaseOne(X)."}},
 
  769             {
"@magic.@poscopy_1.A.{b}", {
"@magic.@poscopy_1.A.{b}(X) :- \n   BaseTwo(X),\n   @abdul0 = 1.",
 
  770                                                 "@magic.@poscopy_1.A.{b}(X) :- \n   " 
  771                                                 "@magic.@poscopy_1.B.{b}(X),\n   BaseTwo(X)."}},
 
  772             {
"@magic.@poscopy_2.A.{b}", {
"@magic.@poscopy_2.A.{b}(X) :- \n   BaseTwo(X),\n   @abdul0 = 0.",
 
  773                                                 "@magic.@poscopy_2.A.{b}(X) :- \n   " 
  774                                                 "@magic.@poscopy_2.B.{b}(X),\n   BaseTwo(X)."}},
 
  775             {
"@magic.@poscopy_1.B.{b}",
 
  776                     {
"@magic.@poscopy_1.B.{b}(X) :- \n   BaseTwo(X),\n   @poscopy_1.A.{b}(X),\n   @abdul0 = " 
  778                             "@magic.@poscopy_1.B.{b}(X) :- \n   @magic.@poscopy_1.A.{b}(X),\n   " 
  780             {
"@magic.@poscopy_2.B.{b}",
 
  781                     {
"@magic.@poscopy_2.B.{b}(X) :- \n   BaseTwo(X),\n   @poscopy_2.A.{b}(X),\n   @abdul0 = " 
  783                             "@magic.@poscopy_2.B.{b}(X) :- \n   @magic.@poscopy_2.A.{b}(X),\n   " 
  786     checkRelMapEq(finalProgram, mappifyRelations(program));