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));