rule_test.cpp
Go to the documentation of this file.
00001 // 
00002 // Copyright (c) 2006, Benjamin Kaufmann
00003 // 
00004 // This file is part of Clasp. See http://www.cs.uni-potsdam.de/clasp/ 
00005 // 
00006 // Clasp is free software; you can redistribute it and/or modify
00007 // it under the terms of the GNU General Public License as published by
00008 // the Free Software Foundation; either version 2 of the License, or
00009 // (at your option) any later version.
00010 // 
00011 // Clasp is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 // 
00016 // You should have received a copy of the GNU General Public License
00017 // along with Clasp; if not, write to the Free Software
00018 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00019 //
00020 #include "test.h"
00021 #include <clasp/logic_program.h>
00022 #include <clasp/solver.h>
00023 #include <utility>
00024 namespace Clasp { namespace Test {
00025 using namespace Clasp::Asp;
00026 class RuleTest : public CppUnit::TestFixture {
00027   CPPUNIT_TEST_SUITE(RuleTest);
00028         CPPUNIT_TEST(testHashIgnoresOrder);
00029         CPPUNIT_TEST(testRemoveDuplicateInNormal);
00030         CPPUNIT_TEST(testMergeDuplicateInExtended);
00031         CPPUNIT_TEST(testContraNormal);
00032         CPPUNIT_TEST(testNoContraExtended);
00033         CPPUNIT_TEST(testContraExtended);
00034         CPPUNIT_TEST(testMultiSimplify);
00035         CPPUNIT_TEST(testCardinalityIfAllWeightsEqual);
00036         CPPUNIT_TEST(testNormalIfMinWeightNeeded);
00037         CPPUNIT_TEST(testSelfblockNormal);
00038         CPPUNIT_TEST(testTautNormal);
00039 
00040         CPPUNIT_TEST(testTrivialDisjunctive);
00041         CPPUNIT_TEST(testEmptyDisjunctive);
00042         CPPUNIT_TEST(testDisjunctive);
00043         CPPUNIT_TEST(testRemoveDuplicateInDisjunctive);
00044         CPPUNIT_TEST(testDisjunctiveTAUT);
00045         CPPUNIT_TEST(testDisjunctiveBLOCK);
00046         CPPUNIT_TEST_SUITE_END();
00047 
00048 public:
00049         void setUp() {
00050                 prg.startProgram(ctx);
00051                 body.reset();
00052                 head.clear();
00053         }
00054 
00055         void testHashIgnoresOrder() {
00056                 Rule r1, r2, r3;
00057                 BodyInfo info1, info2, info3;
00058                 r1.setType(BASICRULE).addHead(1).addToBody(10, false).addToBody(20, true).addToBody(25, true);
00059                 r2.setType(BASICRULE).addHead(1).addToBody(20, true).addToBody(25, true).addToBody(10, false);
00060                 r3.setType(BASICRULE).addHead(1).addToBody(25, true).addToBody(10, false).addToBody(20, true);
00061                 prg.simplifyRule(r1, head, info1);
00062                 prg.simplifyRule(r2, head, info2);
00063                 prg.simplifyRule(r3, head, info3);
00064                 CPPUNIT_ASSERT(info1.hash == info2.hash && info2.hash == info3.hash);
00065         }
00066 
00067         void testRemoveDuplicateInNormal() {
00068                 // a :- b, b, not c -> a :- b, not c.
00069                 rule.setType(BASICRULE).addHead(1).addToBody(2, true).addToBody(2, true).addToBody(3, false);
00070                 prg.simplifyRule(rule, head, body);
00071                 CPPUNIT_ASSERT(2 == body.size());
00072                 CPPUNIT_ASSERT(1 == body.posSize());
00073         }
00074 
00075         void testMergeDuplicateInExtended() {
00076                 // a :- 2 {b, not c, b} -> a :- 2 [b=2, not c].
00077                 rule.setType(CONSTRAINTRULE).setBound(2).addHead(1).addToBody(2, true).addToBody(3, false).addToBody(2, true);
00078                 RuleType t = prg.simplifyRule(rule, head, body);
00079                 CPPUNIT_ASSERT(2 == body.size());
00080                 CPPUNIT_ASSERT(1 == body.posSize());
00081                 CPPUNIT_ASSERT(body[0].second == 2);
00082                 CPPUNIT_ASSERT(t == WEIGHTRULE);
00083                 CPPUNIT_ASSERT(body[1].second == 1);
00084 
00085                 
00086                 rule.clear(), body.reset();
00087                 // {b, not c, b} -> [b=2, not c].
00088                 rule.setType(OPTIMIZERULE).addToBody(2, true).addToBody(3, false).addToBody(2, true);
00089                 t = prg.simplifyRule(rule, head, body);
00090                 CPPUNIT_ASSERT(2 == body.size());
00091                 CPPUNIT_ASSERT(1 == body.posSize());
00092                 CPPUNIT_ASSERT(body[0].second == 2);
00093                 CPPUNIT_ASSERT(t == OPTIMIZERULE);
00094                 CPPUNIT_ASSERT(body[1].second == 1);
00095         }
00096 
00097         void testContraNormal() {
00098                 // a :- b, c, not b.
00099                 rule.setType(BASICRULE).addHead(1).addToBody(2, true).addToBody(3, true).addToBody(2, false);
00100                 RuleType t = prg.simplifyRule(rule, head, body);
00101                 CPPUNIT_ASSERT(t == ENDRULE);
00102         }
00103 
00104         void testNoContraExtended() {
00105                 // a :- 2 {b, c, not b}.
00106                 rule.setType(CONSTRAINTRULE).setBound(2).addHead(1).addToBody(2, true).addToBody(3, true).addToBody(2, false);
00107                 RuleType t = prg.simplifyRule(rule, head, body);
00108                 CPPUNIT_ASSERT(t == CONSTRAINTRULE);
00109 
00110                 // a :- 4 {not b, b, b, c, d}.
00111                 rule.clear(), body.reset();
00112                 rule.setType(CONSTRAINTRULE).setBound(4).addHead(1).addToBody(2, false).addToBody(2, true).addToBody(2, true).addToBody(3, true).addToBody(4, true);
00113                 t = prg.simplifyRule(rule, head, body);
00114                 CPPUNIT_ASSERT(t == WEIGHTRULE);
00115                 CPPUNIT_ASSERT(head[0] == 1);
00116                 
00117 
00118                 rule.clear(), body.reset();
00119                 // a :- 4 [b=2, c=1, not b=1, not c=2].
00120                 rule.setType(WEIGHTRULE).setBound(4).addHead(1).addToBody(2, true, 2).addToBody(3, true).addToBody(2, false).addToBody(3, false, 2);
00121                 t = prg.simplifyRule(rule, head, body);
00122                 CPPUNIT_ASSERT(t == WEIGHTRULE);
00123                 CPPUNIT_ASSERT(head[0] == 1);
00124 
00125                 rule.clear(), body.reset();
00126                 rule.setType(OPTIMIZERULE).addToBody(1, true).addToBody(1, false);
00127                 t = prg.simplifyRule(rule, head, body);
00128                 CPPUNIT_ASSERT(t == OPTIMIZERULE);
00129         }
00130 
00131         void testContraExtended() {
00132                 // a :- 3 {b, c, not b, not c}.
00133                 rule.setType(CONSTRAINTRULE).setBound(3).addHead(1).addToBody(2, true).addToBody(3, true).addToBody(2, false).addToBody(3, false);
00134                 RuleType t = prg.simplifyRule(rule, head, body);
00135                 CPPUNIT_ASSERT(t == ENDRULE);
00136 
00137                 rule.clear(), body.reset();
00138                 // a :- 4 [b=2, c=1, not b=1, not c=1].
00139                 rule.setType(WEIGHTRULE).setBound(4).addHead(1).addToBody(2, true, 2).addToBody(3, true).addToBody(2, false).addToBody(3, false);
00140                 t = prg.simplifyRule(rule, head, body);
00141                 CPPUNIT_ASSERT(t == ENDRULE);
00142         }
00143 
00144         void testMultiSimplify() {
00145                 // a :- 1 [b=0,c=0,d=2,e=0] -> a :- d.
00146                 //  - remove 0 weights: 1 [d=2]
00147                 //  - bound weights   : 1 [d=1]
00148                 //  - flatten         : d.
00149                 rule.setType(WEIGHTRULE).addHead(1).setBound(1).addToBody(2, true).addToBody(3, true).addToBody(4, true, 2).addToBody(5, true);
00150                 rule.body[0].second = 0;
00151                 rule.body[1].second = 0;
00152                 rule.body[3].second = 0;
00153                 RuleType t = prg.simplifyRule(rule, head, body);
00154                 CPPUNIT_ASSERT(t == BASICRULE);
00155                 CPPUNIT_ASSERT(body.posSize() == 1);
00156         }
00157 
00158         void testCardinalityIfAllWeightsEqual() {
00159                 // a :- 3 [b=2,c=2, d=2,e=0] -> 
00160                 rule.setType(WEIGHTRULE).addHead(1).setBound(3).addToBody(2, true, 2).addToBody(3, true, 2).addToBody(4, true, 2).addToBody(5, true);
00161                 rule.body[3].second = 0;
00162                 RuleType t = prg.simplifyRule(rule, head, body);
00163                 CPPUNIT_ASSERT(t  == CONSTRAINTRULE);
00164                 CPPUNIT_ASSERT(body.bound() == 2);
00165 
00166                 rule.clear(), body.reset();
00167                 // a :- 2 [b=1,c=2 b=1] -> 1 {b,c}
00168                 rule.setType(WEIGHTRULE).addHead(1).setBound(2).addToBody(2, true, 1).addToBody(3, true, 2).addToBody(2, true, 1);
00169                 t = prg.simplifyRule(rule, head, body);
00170                 CPPUNIT_ASSERT(t  == CONSTRAINTRULE);
00171                 CPPUNIT_ASSERT(body.bound() == 1);
00172 
00173         }
00174         
00175         void testNormalIfMinWeightNeeded() {
00176                 // a :- 8 [b=4,c=3, d=2,e=0] -> 
00177                 rule.setType(WEIGHTRULE).addHead(1).setBound(8).addToBody(2, true, 4).addToBody(3, true, 3).addToBody(4, true, 2).addToBody(5, true);
00178                 rule.body[3].second = 0;
00179                 RuleType t = prg.simplifyRule(rule, head, body);
00180                 CPPUNIT_ASSERT(t  == BASICRULE);
00181         }
00182 
00183         void testSelfblockNormal() {
00184                 // a :- not a.
00185                 rule.setType(BASICRULE);
00186                 rule.addHead(1).addToBody(1, false);
00187                 RuleType t = prg.simplifyRule(rule, head, body);
00188                 CPPUNIT_ASSERT(t == BASICRULE && head[0] == 0);         
00189         }       
00190 
00191         void testTautNormal() {
00192                 // a :- a, b.
00193                 rule.setType(BASICRULE).addHead(1).addToBody(1, true).addToBody(2, true);
00194                 RuleType t = prg.simplifyRule(rule, head, body);
00195                 CPPUNIT_ASSERT(t == ENDRULE && head.empty());
00196         }       
00197 
00198         void testTrivialDisjunctive() {
00199                 // a :- x.
00200                 rule.setType(DISJUNCTIVERULE).addHead(1).addToBody(2, true);
00201                 RuleType t = prg.simplifyRule(rule, head, body);
00202                 CPPUNIT_ASSERT(t == BASICRULE);
00203         }
00204         void testEmptyDisjunctive() {
00205                 rule.setType(DISJUNCTIVERULE).addToBody(2, true);
00206                 RuleType t = prg.simplifyRule(rule, head, body);
00207                 CPPUNIT_ASSERT(t == ENDRULE);
00208         }
00209         void testDisjunctive() {
00210                 // a | b :- x.
00211                 rule.setType(DISJUNCTIVERULE).addHead(1).addHead(2).addToBody(3, true);
00212                 RuleType t = prg.simplifyRule(rule, head, body);
00213                 CPPUNIT_ASSERT(t == DISJUNCTIVERULE && head.size() == 2);
00214         }
00215         
00216         void testRemoveDuplicateInDisjunctive() {
00217                 // a | b | a :- x, x.
00218                 rule.setType(DISJUNCTIVERULE).addHead(1).addHead(2).addHead(1).addToBody(3, true).addToBody(3, true);
00219                 RuleType t = prg.simplifyRule(rule, head, body);
00220                 CPPUNIT_ASSERT(t == DISJUNCTIVERULE && head.size() == 2);
00221                 CPPUNIT_ASSERT(body.size() == 1);
00222         }
00223         
00224         void testDisjunctiveTAUT() {
00225                 // a | b | c :- b, x.
00226                 rule.setType(DISJUNCTIVERULE).addHead(1).addHead(2).addHead(3).addToBody(4, true).addToBody(2, true);
00227                 RuleType t = prg.simplifyRule(rule, head, body);
00228                 CPPUNIT_ASSERT(t == ENDRULE);
00229         }
00230         
00231         void testDisjunctiveBLOCK() {
00232                 // a | b | c :- x, not b.
00233                 rule.setType(DISJUNCTIVERULE).addHead(1).addHead(2).addHead(3).addToBody(4, true).addToBody(2, false);
00234                 RuleType t = prg.simplifyRule(rule, head, body);
00235                 CPPUNIT_ASSERT(t == DISJUNCTIVERULE && head.size() == 2);
00236         }
00237 private:
00238         SharedContext ctx;
00239         LogicProgram  prg;
00240         VarVec        head;
00241         BodyInfo      body;
00242         Rule          rule;
00243 };
00244 
00245 class RuleTransformTest : public CppUnit::TestFixture {
00246   CPPUNIT_TEST_SUITE(RuleTransformTest);
00247         CPPUNIT_TEST(testChoiceRuleEmpty);
00248         CPPUNIT_TEST(testChoiceRuleOneHead);
00249         CPPUNIT_TEST(testChoiceRuleUseExtraHead);
00250         
00251         CPPUNIT_TEST(testTrivialConstraintRule);
00252         CPPUNIT_TEST(testUnsatConstraintRule);
00253         CPPUNIT_TEST(testDegeneratedConstraintRule);
00254         CPPUNIT_TEST(testBoundEqOneExp);
00255         CPPUNIT_TEST(testBoundEqOneQuad);
00256 
00257         CPPUNIT_TEST(testSixThreeExp);
00258         CPPUNIT_TEST(testSixThreeQuad);
00259         CPPUNIT_TEST(testWeightSixFourExp);
00260         CPPUNIT_TEST(testWeightSixFourQuad);
00261         CPPUNIT_TEST(testWeightBug);
00262         CPPUNIT_TEST(testDegeneratedWeightRule);
00263 
00264         CPPUNIT_TEST(testStupidWeightBug);
00265         CPPUNIT_TEST(testWeightBogusNormal);
00266 
00267         CPPUNIT_TEST(testShiftDisjunction);
00268         CPPUNIT_TEST_SUITE_END();
00269 
00270 public:
00271         void setUp() {
00272                 prg.start(ctx, LogicProgram::AspOptions().noEq().noScc());
00273                 prg.setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "c").setAtomName(4, "d")
00274                          .setAtomName(5, "e").setAtomName(6, "f").setAtomName(7, "g");
00275         }
00276         void testChoiceRuleEmpty() {
00277                 prg.setExtendedRuleMode(LogicProgram::mode_transform_choice);
00278                 rule.setType(CHOICERULE);
00279                 prg.addRule(rule);
00280                 CPPUNIT_ASSERT_EQUAL(0u, prg.stats.rules(CHOICERULE).second);
00281         }
00282         void testChoiceRuleOneHead() {
00283                 prg.setExtendedRuleMode(LogicProgram::mode_transform_choice);
00284                 
00285                 rule.setType(CHOICERULE);
00286                 rule.addHead(1);
00287                 prg.addRule(rule);
00288                 
00289                 prg.endProgram();
00290                 std::ostringstream out;
00291                 prg.write(out);
00292                 std::stringstream exp;
00293                 exp << "1 1 1 1 8 \n"
00294                           << "1 8 1 1 1 \n";
00295                 CPPUNIT_ASSERT(out.str().find(exp.str()) != std::string::npos);
00296         }
00297 
00298         void testChoiceRuleUseExtraHead() {
00299                 prg.startRule(CHOICERULE).addHead(4).addHead(5).addHead(6).addHead(7).endRule();
00300                 prg.setExtendedRuleMode(LogicProgram::mode_transform_choice);
00301                 rule.setType(CHOICERULE);
00302                 // {a, b, c} :- d, e, not f, not g.
00303                 rule.addHead(1).addHead(2).addHead(3)
00304                         .addToBody(4, true).addToBody(5, true).addToBody(6, false).addToBody(7, false);
00305 
00306                 prg.addRule(rule);
00307                 prg.endProgram();
00308                 std::ostringstream out;
00309                 prg.write(out);
00310                 std::stringstream exp;
00311                 exp << "1 1 2 1 9 8 \n"      // a    :- auxBody, not auxA.
00312                     << "1 9 1 1 1 \n"        // auxA :- not a.
00313                     << "1 2 2 1 10 8 \n"     // b    :- auxBody, not auxB.
00314                     << "1 10 1 1 2 \n"       // auxB :- not b.
00315                     << "1 3 2 1 11 8 \n"     // c    :- auxBody, not auxC.
00316                     << "1 11 1 1 3 \n"       // auxC :- not c.
00317                     << "1 8 4 2 6 7 4 5 \n"; // auxB :- d, e, not f, not g.
00318                 CPPUNIT_ASSERT(out.str().find(exp.str()) != std::string::npos);
00319         }
00320         
00321         void testTrivialConstraintRule() {
00322                 prg.setExtendedRuleMode(LogicProgram::mode_transform);
00323                 rule.setType(CONSTRAINTRULE);
00324                 rule.addHead(1);
00325                 rule.setBound(0);
00326                 prg.addRule(rule);
00327                 CPPUNIT_ASSERT_EQUAL(1u, prg.stats.rules(BASICRULE).second);
00328         }
00329         
00330         void testUnsatConstraintRule() {
00331                 prg.setExtendedRuleMode(LogicProgram::mode_transform);
00332                 rule.setType(CONSTRAINTRULE);
00333                 rule.addHead(1);
00334                 rule.addToBody(2, true);
00335                 rule.setBound(2);
00336                 prg.addRule(rule);
00337                 CPPUNIT_ASSERT_EQUAL(0u, prg.stats.rules());
00338 
00339                 rule.clear();
00340                 rule.setType(WEIGHTRULE);
00341                 rule.addHead(1);
00342                 rule.addToBody(2, true, 2);
00343                 rule.setBound(3);
00344                 prg.addRule(rule);
00345                 CPPUNIT_ASSERT_EQUAL(0u, prg.stats.rules());
00346         }
00347         
00348         void testDegeneratedConstraintRule() {
00349                 prg.setExtendedRuleMode(LogicProgram::mode_transform);
00350                 
00351                 prg.startRule(CHOICERULE).addHead(2).addHead(3).addHead(4).endRule();
00352                 rule.setType(CONSTRAINTRULE);
00353                 // a :- 3 { b, c, d }.
00354                 rule.addHead(1).addToBody(2, true).addToBody(3, true).addToBody(4, true).setBound(3);
00355                 prg.addRule(rule);
00356                 CPPUNIT_ASSERT_EQUAL(1u, prg.stats.rules(BASICRULE).second);
00357         }
00358         void testBoundEqOneExp() {
00359                 prg.setExtendedRuleMode(LogicProgram::mode_transform_weight);
00360                 prg.startRule(CHOICERULE).addHead(2).addHead(3).addHead(4).endRule();
00361                 rule.setType(CONSTRAINTRULE);
00362                 // a :- 1 { b, c, d }.
00363                 rule.addHead(1).addToBody(2, true).addToBody(3, true).addToBody(4, true).setBound(1);
00364                 prg.addRule(rule);
00365                 CPPUNIT_ASSERT_EQUAL(3u, prg.stats.rules(BASICRULE).second);
00366                 prg.endProgram();
00367                 std::ostringstream out;
00368                 prg.write(out);
00369                 std::stringstream exp;
00370                 exp << "1 1 1 0 2 \n"
00371                     << "1 1 1 0 3 \n"
00372                     << "1 1 1 0 4 \n";
00373                 CPPUNIT_ASSERT(out.str().find(exp.str()) != std::string::npos);
00374         }
00375         void testBoundEqOneQuad() {
00376                 prg.setExtendedRuleMode(LogicProgram::mode_transform_weight);
00377                 prg.startRule(CHOICERULE).addHead(2).addHead(3).addHead(4).endRule();
00378                 rule.setType(CONSTRAINTRULE);
00379                 // a :- 1 { b, c, d }.
00380                 rule.addHead(1).addToBody(2, true).addToBody(3, true).addToBody(4, true).setBound(1);
00381                 RuleTransform tm;
00382                 CPPUNIT_ASSERT_EQUAL(4u, tm.transform(prg, rule));
00383                 prg.endProgram();
00384                 std::ostringstream out;
00385                 prg.write(out);
00386                 std::stringstream exp;
00387                 exp << "1 1 1 0 2 \n"
00388                     << "1 1 1 0 8 \n"
00389                     << "1 8 1 0 3 \n"
00390                     << "1 8 1 0 4 \n";
00391                 CPPUNIT_ASSERT(out.str().find(exp.str()) != std::string::npos);
00392         }
00393         void testSixThreeExp() {
00394                 prg.setExtendedRuleMode(LogicProgram::mode_transform_weight);
00395                 prg.startRule(CHOICERULE).addHead(2).addHead(3).addHead(4).addHead(5).addHead(6).addHead(7).endRule();
00396                 rule.setType(CONSTRAINTRULE);
00397                 // a :- 3 {b, c, d, e, f, g}
00398                 rule.addHead(1).addToBody(2, true).addToBody(3, true).addToBody(4, true).addToBody(5, true).addToBody(6, true).addToBody(7, true);
00399                 rule.setBound(3);
00400                 RuleTransform tm;
00401                 CPPUNIT_ASSERT_EQUAL(20u, tm.transformNoAux(prg, rule));
00402                 prg.endProgram();
00403                 std::ostringstream out;
00404                 prg.write(out);
00405                 std::stringstream exp;
00406                 exp // starting with b
00407                         << "1 1 3 0 2 3 4 \n"
00408                         << "1 1 3 0 2 3 5 \n"
00409                         << "1 1 3 0 2 3 6 \n"
00410                         << "1 1 3 0 2 3 7 \n"
00411                         << "1 1 3 0 2 4 5 \n"
00412                         << "1 1 3 0 2 4 6 \n"
00413                         << "1 1 3 0 2 4 7 \n"
00414                         << "1 1 3 0 2 5 6 \n"
00415                         << "1 1 3 0 2 5 7 \n"
00416                         << "1 1 3 0 2 6 7 \n"
00417                         // starting with c
00418                         << "1 1 3 0 3 4 5 \n"
00419                         << "1 1 3 0 3 4 6 \n"
00420                         << "1 1 3 0 3 4 7 \n"
00421                         << "1 1 3 0 3 5 6 \n"
00422                         << "1 1 3 0 3 5 7 \n"
00423                         << "1 1 3 0 3 6 7 \n"
00424                         // starting with d
00425                         << "1 1 3 0 4 5 6 \n"
00426                         << "1 1 3 0 4 5 7 \n"
00427                         << "1 1 3 0 4 6 7 \n"
00428                         // starting with e
00429                         << "1 1 3 0 5 6 7 \n";
00430                 CPPUNIT_ASSERT(out.str().find(exp.str()) != std::string::npos);
00431         }
00432  
00433         void testSixThreeQuad() {
00434                 prg.setExtendedRuleMode(LogicProgram::mode_transform_weight);
00435                 prg.startRule(CHOICERULE).addHead(2).addHead(3).addHead(4).addHead(5).addHead(6).addHead(7).endRule();
00436                 rule.setType(CONSTRAINTRULE);
00437                 // a :- 3 {b, c, d, e, f, g}
00438                 rule.addHead(1).addToBody(2, true).addToBody(3, true).addToBody(4, true).addToBody(5, true).addToBody(6, true).addToBody(7, true);
00439                 rule.setBound(3);
00440                 RuleTransform tm;
00441                 CPPUNIT_ASSERT_EQUAL(18u, tm.transform(prg, rule));
00442                 CPPUNIT_ASSERT_EQUAL(15u, prg.numAtoms());
00443                 prg.endProgram();
00444                 std::ostringstream out;
00445                 prg.write(out);
00446                 std::string s = out.str();
00447                 std::stringstream exp;
00448                 exp 
00449                         << "1 1 2 0 2 8 \n"   // a     :- b, (c,2)
00450                         << "1 1 1 0 9 \n"     // a     :- (c,3)
00451 
00452                         << "1 8 2 0 3 10 \n"  // (c,2) :- c, (d,1)
00453                         << "1 8 1 0 11 \n"    // (c,2) :- (d,2)
00454                         << "1 9 2 0 3 11 \n"  // (c,3) :- c, (d,2)
00455                         << "1 9 1 0 12 \n"    // (c,3) :- (d,3)
00456 
00457                         << "1 10 1 0 4 \n"    // (d,1) :- d.
00458                         << "1 10 1 0 13 \n"   // (d,1) :- (e,1)
00459                         << "1 11 2 0 4 13 \n" // (d,2) :- d, (e,1).
00460                         << "1 11 1 0 14 \n"   // (d,2) :- (e,2).
00461                         << "1 12 2 0 4 14 \n" // (d,3) :- d, (e,2).
00462                         << "1 12 3 0 5 6 7 \n"// (d,3) :- (e,2).
00463 
00464                         << "1 13 1 0 5 \n"    // (e,1) :- e.
00465                         << "1 13 1 0 15 \n"   // (e,1) :- (f,1).
00466                         << "1 14 2 0 5 15 \n" // (e,2) :- e, (f,1).
00467                         << "1 14 2 0 6 7 \n"  // (e,2) :- f,g.
00468 
00469                         << "1 15 1 0 6 \n"    // (f,1) :- f
00470                         << "1 15 1 0 7 \n";   // (f,1) :- g
00471                 CPPUNIT_ASSERT(out.str().find(exp.str()) != std::string::npos);
00472         }
00473 
00474         void testWeightSixFourExp() {
00475                 prg.setExtendedRuleMode(LogicProgram::mode_transform_weight);
00476                 prg.startRule(CHOICERULE).addHead(2).addHead(3).addHead(4).addHead(5).addHead(6).addHead(7).endRule();
00477                 rule.setType(WEIGHTRULE);
00478                 // a :- 4 {b=4, c=3, d=2, e=2, f=1, g=1}
00479                 rule.addHead(1).addToBody(2, true,4).addToBody(3, true,3).addToBody(4, true,2).addToBody(5, true,2).addToBody(6, true,1).addToBody(7, true,1);
00480                 rule.setBound(4);
00481                 RuleTransform tm;
00482                 CPPUNIT_ASSERT_EQUAL(8u, tm.transformNoAux(prg, rule)); 
00483                 prg.endProgram();
00484                 std::ostringstream out;
00485                 prg.write(out);
00486                 std::stringstream exp;
00487                 exp // starting with b
00488                         << "1 1 1 0 2 \n"
00489                         << "1 1 2 0 3 4 \n"
00490                         << "1 1 2 0 3 5 \n"
00491                         << "1 1 2 0 3 6 \n"
00492                         << "1 1 2 0 3 7 \n"
00493                         << "1 1 2 0 4 5 \n"
00494                         << "1 1 3 0 4 6 7 \n"
00495                         << "1 1 3 0 5 6 7 \n";
00496                 CPPUNIT_ASSERT(out.str().find(exp.str()) != std::string::npos);
00497         }
00498         
00499         void testWeightSixFourQuad() {
00500                 prg.setExtendedRuleMode(LogicProgram::mode_transform_weight);
00501                 prg.startRule(CHOICERULE).addHead(2).addHead(3).addHead(4).addHead(5).addHead(6).addHead(7).endRule();
00502                 rule.setType(WEIGHTRULE);
00503                 // a :- 4 {b=4, c=3, d=2, e=2, f=1, g=1}
00504                 rule.addHead(1).addToBody(2, true,4).addToBody(3, true,3).addToBody(4, true,2).addToBody(5, true,2).addToBody(6, true,1).addToBody(7, true,1);
00505                 rule.setBound(4);
00506                 RuleTransform tm;
00507                 CPPUNIT_ASSERT_EQUAL(14u, tm.transform(prg, rule));
00508                 CPPUNIT_ASSERT(13u == prg.numAtoms());
00509                 prg.endProgram();
00510                 std::ostringstream out;
00511                 prg.write(out);
00512                 std::stringstream exp;
00513                 exp // head
00514                         << "1 1 1 0 2 \n"     // a     :- b.
00515                         << "1 1 1 0 8 \n"     // a     :- (c, 4)
00516 
00517                         << "1 8 2 0 3 9 \n"   // (c,4) :- c, (d,1).
00518                         << "1 8 1 0 10 \n"    // (c,4) :- (d, 4)
00519                         
00520                         << "1 9 1 0 4 \n"     // (d,1) :- d.
00521                         << "1 9 1 0 11 \n"    // (d,1) :- (e, 1)
00522                         << "1 10 2 0 4 12 \n" // (d,4) :- d, (e,2)
00523                         << "1 10 3 0 5 6 7 \n"// (d,4) :- e,f,g.
00524                         
00525                         << "1 11 1 0 5 \n"    // (e,1) :- e.
00526                         << "1 12 1 0 5 \n"    // (e,2) :- e.
00527                         << "1 11 1 0 13 \n"   // (e,1) :- (f,1).
00528                         << "1 12 2 0 6 7 \n"  // (e,2) :- f,g.
00529 
00530                         << "1 13 1 0 6 \n"    // (f,1) :- f.
00531                         << "1 13 1 0 7 \n";   // (f,1) :- g.
00532                         
00533                 CPPUNIT_ASSERT(out.str().find(exp.str()) != std::string::npos);
00534                 
00535         }
00536 
00537         void testWeightBug() {
00538                 prg.setExtendedRuleMode(LogicProgram::mode_transform_weight);
00539                 prg.startRule(CHOICERULE).addHead(2).addHead(3).addHead(4).endRule();
00540                 rule.setType(WEIGHTRULE);
00541                 // a :- 5 {b=3, c=3, d=1}
00542                 rule.addHead(1).addToBody(2, true,3).addToBody(3, true,3).addToBody(4, true,1);
00543                 rule.setBound(5);
00544                 RuleTransform tm;
00545                 CPPUNIT_ASSERT_EQUAL(2u, tm.transform(prg, rule));
00546                 CPPUNIT_ASSERT(8u == prg.numAtoms());
00547                 prg.endProgram();
00548                 std::ostringstream out;
00549                 prg.write(out);
00550                 std::stringstream exp;
00551                 exp 
00552                         << "1 1 2 0 2 8 \n"// a    :- b, (c, 2)
00553                         << "1 8 1 0 3 \n"; // (c,2):- c.
00554                 CPPUNIT_ASSERT(out.str().find(exp.str()) != std::string::npos);
00555         }
00556 
00557         void testDegeneratedWeightRule() {
00558                 prg.setExtendedRuleMode(LogicProgram::mode_transform_weight);
00559                 prg.startRule(CHOICERULE).addHead(2).addHead(3).addHead(4).endRule();
00560                 rule.setType(WEIGHTRULE);
00561                 // a :- 20 {b=18, c=18, d=18}
00562                 rule.addHead(1).addToBody(2, true,18).addToBody(3, true,18).addToBody(4, true,18);
00563                 rule.setBound(20);
00564                 VarVec   head;
00565                 BodyInfo body;
00566                 RuleType t = prg.simplifyRule(rule, head, body);
00567                 rule.clear();
00568                 rule.setType(t);
00569                 rule.setBound(body.bound());
00570                 rule.body  = body.lits;
00571                 rule.heads = head;
00572                 CPPUNIT_ASSERT(rule.type() == CONSTRAINTRULE);
00573                 RuleTransform tm;
00574                 CPPUNIT_ASSERT_EQUAL(3u, tm.transformNoAux(prg, rule));
00575                 prg.endProgram();
00576                 std::ostringstream out;
00577                 prg.write(out);
00578                 std::stringstream exp;
00579                 exp 
00580                         << "1 1 2 0 2 3 \n"  // a :- b, c
00581                         << "1 1 2 0 2 4 \n"  // a :- b, d
00582                         << "1 1 2 0 3 4 \n"; // a :- c, d
00583                 CPPUNIT_ASSERT(out.str().find(exp.str()) != std::string::npos);
00584         }
00585 
00586         void testStupidWeightBug() {
00587                 prg.setAtomName(8, "h").setAtomName(9, "x");
00588                 prg.setExtendedRuleMode(LogicProgram::mode_transform_weight);
00589                 prg.startRule(CHOICERULE).addHead(1).addHead(2).addHead(3).addHead(4).addHead(5).addHead(6).addHead(7).addHead(8).endRule();
00590                 rule.setType(WEIGHTRULE);
00591                 // x :- 24 {a=31, b=29, c=29, d=28, e=21, f=15, g=8, h=5}
00592                 rule.addHead(9).addToBody(1, true,31).addToBody(2, true,29).addToBody(3, true,29).addToBody(4, true,28).addToBody(5, true,21).addToBody(6, true,15)
00593                                .addToBody(7,true,8).addToBody(8,true,5);
00594 
00595                 rule.setBound(24);
00596                 RuleTransform tm;
00597                 uint32 prev = prg.numAtoms();
00598                 CPPUNIT_ASSERT_EQUAL(14u, tm.transform(prg, rule));
00599                 CPPUNIT_ASSERT(prg.numAtoms() == prev+6);
00600                 prg.endProgram();
00601                 std::ostringstream out;
00602                 prg.write(out);
00603                 std::stringstream exp;
00604                 exp  << "1 13 3 0 6 7 8 \n";
00605                 CPPUNIT_ASSERT(out.str().find(exp.str()) != std::string::npos);
00606         }
00607 
00608         void testWeightBogusNormal() {
00609                 prg.setExtendedRuleMode(LogicProgram::mode_transform_weight);
00610                 prg.startRule(CHOICERULE).addHead(1).addHead(2).addHead(3).endRule();
00611                 rule.setType(WEIGHTRULE);
00612                 // a :- 24 {b=12,c=12}.
00613                 rule.addHead(1).addToBody(2, true,12).addToBody(3, true,12);
00614 
00615                 rule.setBound(24);
00616                 RuleTransform tm;
00617                 uint32 prev = prg.numAtoms();
00618                 CPPUNIT_ASSERT_EQUAL(1u, tm.transform(prg, rule));
00619                 CPPUNIT_ASSERT(prg.numAtoms() == prev);
00620         }
00621 
00622         void testShiftDisjunction() {
00623                 prg.setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "x").setAtomName(4, "y");
00624                 rule.setType(DISJUNCTIVERULE).addHead(1).addHead(2).addToBody(3, true).addToBody(4, true);
00625                 RuleTransform tm;
00626                 uint32 nr = tm.transform(prg, rule);
00627                 CPPUNIT_ASSERT(3 == nr);
00628         }
00629 private:
00630         SharedContext ctx;
00631         LogicProgram  prg;
00632         Rule          rule;
00633 };
00634 
00635 CPPUNIT_TEST_SUITE_REGISTRATION(RuleTest);
00636 CPPUNIT_TEST_SUITE_REGISTRATION(RuleTransformTest);
00637 
00638 } } 
00639 


clasp
Author(s): Benjamin Kaufmann
autogenerated on Thu Aug 27 2015 12:41:39