00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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
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
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
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
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
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
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
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
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
00146
00147
00148
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
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
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
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
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
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
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
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
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
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
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
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"
00312 << "1 9 1 1 1 \n"
00313 << "1 2 2 1 10 8 \n"
00314 << "1 10 1 1 2 \n"
00315 << "1 3 2 1 11 8 \n"
00316 << "1 11 1 1 3 \n"
00317 << "1 8 4 2 6 7 4 5 \n";
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
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
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
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
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
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
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
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
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
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"
00450 << "1 1 1 0 9 \n"
00451
00452 << "1 8 2 0 3 10 \n"
00453 << "1 8 1 0 11 \n"
00454 << "1 9 2 0 3 11 \n"
00455 << "1 9 1 0 12 \n"
00456
00457 << "1 10 1 0 4 \n"
00458 << "1 10 1 0 13 \n"
00459 << "1 11 2 0 4 13 \n"
00460 << "1 11 1 0 14 \n"
00461 << "1 12 2 0 4 14 \n"
00462 << "1 12 3 0 5 6 7 \n"
00463
00464 << "1 13 1 0 5 \n"
00465 << "1 13 1 0 15 \n"
00466 << "1 14 2 0 5 15 \n"
00467 << "1 14 2 0 6 7 \n"
00468
00469 << "1 15 1 0 6 \n"
00470 << "1 15 1 0 7 \n";
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
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
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
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
00514 << "1 1 1 0 2 \n"
00515 << "1 1 1 0 8 \n"
00516
00517 << "1 8 2 0 3 9 \n"
00518 << "1 8 1 0 10 \n"
00519
00520 << "1 9 1 0 4 \n"
00521 << "1 9 1 0 11 \n"
00522 << "1 10 2 0 4 12 \n"
00523 << "1 10 3 0 5 6 7 \n"
00524
00525 << "1 11 1 0 5 \n"
00526 << "1 12 1 0 5 \n"
00527 << "1 11 1 0 13 \n"
00528 << "1 12 2 0 6 7 \n"
00529
00530 << "1 13 1 0 6 \n"
00531 << "1 13 1 0 7 \n";
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
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"
00553 << "1 8 1 0 3 \n";
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
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"
00581 << "1 1 2 0 2 4 \n"
00582 << "1 1 2 0 3 4 \n";
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
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
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