program_builder_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/solver.h>
00022 #include <clasp/minimize_constraint.h>
00023 #include <clasp/unfounded_check.h>
00024 
00025 #include <sstream>
00026 using namespace std;
00027 namespace Clasp { namespace Test {
00028 using namespace Clasp::Asp;
00029 struct ClauseObserver : public DecisionHeuristic {
00030         Literal doSelect(Solver&){return Literal();}
00031         void updateVar(const Solver&, Var, uint32) {}
00032         void newConstraint(const Solver&, const Literal* first, LitVec::size_type size, ConstraintType) {
00033                 Clause c;
00034                 for (LitVec::size_type i = 0; i < size; ++i, ++first) {
00035                         c.push_back(*first);
00036                 }
00037                 std::sort(c.begin(), c.end());
00038                 clauses_.push_back(c);
00039         }
00040         typedef std::vector<Literal> Clause;
00041         typedef std::vector<Clause> Clauses;
00042         Clauses clauses_;
00043 };
00044 
00045 class LogicProgramTest : public CppUnit::TestFixture {
00046   CPPUNIT_TEST_SUITE(LogicProgramTest);
00047         CPPUNIT_TEST(testMergeValue);
00048         CPPUNIT_TEST(testIgnoreRules);
00049         CPPUNIT_TEST(testDuplicateRule);
00050         CPPUNIT_TEST(testNotAChoice);
00051         CPPUNIT_TEST(testNotAChoiceMerge);
00052         CPPUNIT_TEST(testMergeToSelfblocker);
00053         CPPUNIT_TEST(testMergeToSelfblocker2);
00054         CPPUNIT_TEST(testDerivedTAUT);
00055         CPPUNIT_TEST(testOneLoop);
00056         CPPUNIT_TEST(testZeroLoop);
00057         CPPUNIT_TEST(testEqSuccs);
00058         CPPUNIT_TEST(testEqCompute);
00059         CPPUNIT_TEST(testFactsAreAsserted);
00060         CPPUNIT_TEST(testSelfblockersAreAsserted);
00061         CPPUNIT_TEST(testConstraintsAreAsserted);
00062         CPPUNIT_TEST(testConflictingCompute);
00063         CPPUNIT_TEST(testForceUnsuppAtomFails);
00064         CPPUNIT_TEST(testTrivialConflictsAreDeteced);
00065         CPPUNIT_TEST(testBuildEmpty);
00066         CPPUNIT_TEST(testAddOneFact);
00067         CPPUNIT_TEST(testTwoFactsOnlyOneVar);
00068         CPPUNIT_TEST(testDontAddOnePredsThatAreNotHeads);
00069         CPPUNIT_TEST(testDontAddDuplicateBodies);
00070         CPPUNIT_TEST(testDontAddDuplicateSumBodies);
00071         CPPUNIT_TEST(testDontAddUnsupported);
00072         CPPUNIT_TEST(testDontAddUnsupportedNoEq);
00073         CPPUNIT_TEST(testDontAddUnsupportedExtNoEq);
00074         CPPUNIT_TEST(testAssertSelfblockers);
00075         
00076         CPPUNIT_TEST(testCloneShare);
00077         CPPUNIT_TEST(testCloneShareSymbols);
00078         CPPUNIT_TEST(testCloneFull);
00079 
00080         CPPUNIT_TEST(testBug);
00081         CPPUNIT_TEST(testSatBodyBug);
00082         CPPUNIT_TEST(testDepBodyBug);
00083         CPPUNIT_TEST(testAddUnknownAtomToMinimize);
00084         CPPUNIT_TEST(testWriteWeakTrue);
00085         CPPUNIT_TEST(testSimplifyBodyEqBug);
00086         CPPUNIT_TEST(testNoEqSameLitBug);
00087 
00088         CPPUNIT_TEST(testAssertEqSelfblocker);
00089         CPPUNIT_TEST(testAddClauses);
00090         CPPUNIT_TEST(testAddCardConstraint);
00091         CPPUNIT_TEST(testAddWeightConstraint);
00092         CPPUNIT_TEST(testAddMinimizeConstraint);
00093         CPPUNIT_TEST(testAddEmptyMinimizeConstraint);
00094         CPPUNIT_TEST(testNonTight);
00095 
00096         CPPUNIT_TEST(testIgnoreCondFactsInLoops);
00097         CPPUNIT_TEST(testCrEqBug);
00098         CPPUNIT_TEST(testEqOverChoiceRule);
00099         CPPUNIT_TEST(testEqOverBodiesOfDiffType);
00100         CPPUNIT_TEST(testEqOverComp);
00101         CPPUNIT_TEST(testNoBodyUnification);
00102         CPPUNIT_TEST(testNoEqAtomReplacement);
00103         CPPUNIT_TEST(testAllBodiesSameLit);
00104         CPPUNIT_TEST(testAllBodiesSameLit2);
00105 
00106         CPPUNIT_TEST(testCompLit);
00107         CPPUNIT_TEST(testFunnySelfblockerOverEqByTwo);
00108 
00109         CPPUNIT_TEST(testRemoveKnownAtomFromWeightRule);
00110         CPPUNIT_TEST(testMergeEquivalentAtomsInConstraintRule);
00111         CPPUNIT_TEST(testMergeEquivalentAtomsInWeightRule);
00112         CPPUNIT_TEST(testBothLitsInConstraintRule);
00113         CPPUNIT_TEST(testBothLitsInWeightRule);
00114         CPPUNIT_TEST(testWeightlessAtomsInWeightRule);
00115         CPPUNIT_TEST(testSimplifyToNormal);
00116         CPPUNIT_TEST(testSimplifyToCardBug);
00117         CPPUNIT_TEST(testSimplifyCompBug);
00118 
00119         CPPUNIT_TEST(testBPWeight);
00120 
00121         CPPUNIT_TEST(testExtLitsAreFrozen);     
00122         CPPUNIT_TEST(writeIntegrityConstraint);
00123         CPPUNIT_TEST(testComputeTrueBug);
00124         CPPUNIT_TEST(testBackprop);
00125 
00126         CPPUNIT_TEST(testSimpleIncremental);
00127         CPPUNIT_TEST(testIncrementalFreeze);
00128         CPPUNIT_TEST(testIncrementalFreezeValue);
00129         CPPUNIT_TEST(testIncrementalKeepFrozen);
00130         CPPUNIT_TEST(testIncrementalUnfreezeUnsupp);
00131         CPPUNIT_TEST(testIncrementalUnfreezeCompute);
00132         CPPUNIT_TEST(testIncrementalCompute);
00133         CPPUNIT_TEST(testIncrementalComputeBackprop);
00134         CPPUNIT_TEST(testIncrementalBackpropStep);
00135         CPPUNIT_TEST(testIncrementalEq);
00136         CPPUNIT_TEST(testIncrementalEqUnfreeze);
00137         CPPUNIT_TEST(testIncrementalEqComplement);
00138         CPPUNIT_TEST(testIncrementalEqUpdateAssigned);
00139         CPPUNIT_TEST(testIncrementalEqResetState);
00140         CPPUNIT_TEST(testIncrementalUnfreezeUnsuppEq);
00141         CPPUNIT_TEST(testIncrementalUnfreezeEq);
00142         CPPUNIT_TEST(testIncrementalStats);
00143         CPPUNIT_TEST(testIncrementalTransform);
00144         CPPUNIT_TEST(testIncrementalBackpropCompute);
00145         CPPUNIT_TEST(testIncrementalFreezeUnfreeze);
00146         CPPUNIT_TEST(testIncrementalSymbolUpdate);
00147         CPPUNIT_TEST(testIncrementalBackpropSolver);
00148         CPPUNIT_TEST(testIncrementalFreezeDefined);
00149         CPPUNIT_TEST(testIncrementalUnfreezeDefined);
00150         CPPUNIT_TEST(testIncrementalImplicitUnfreeze);
00151         CPPUNIT_TEST(testIncrementalRedefine);
00152         CPPUNIT_TEST(testIncrementalGetAssumptions);
00153         CPPUNIT_TEST(testIncrementalSimplifyCard);
00154         CPPUNIT_TEST(testIncrementalSimplifyMinimize);
00155         CPPUNIT_TEST_SUITE_END();       
00156 public:
00157         void tearDown(){
00158                 ctx.reset();
00159         }
00160         void testMergeValue() {
00161                 PrgAtom lhs(0), rhs(1);
00162                 ValueRep ok[15] = {
00163                         value_free, value_free, value_free,
00164                         value_free, value_true, value_true,
00165                         value_free, value_false, value_false,
00166                         value_free, value_weak_true, value_weak_true,
00167                         value_true, value_weak_true, value_true
00168                 };
00169                 ValueRep fail[4] = { value_true, value_false, value_weak_true, value_false };
00170                 for (uint32 x = 0; x != 2; ++x) {
00171                         for (uint32 i = 0; i != 15; i += 3) {
00172                                 lhs.clearLiteral(true);
00173                                 rhs.clearLiteral(true);
00174                                 CPPUNIT_ASSERT(lhs.assignValue(ok[i+x]));
00175                                 CPPUNIT_ASSERT(rhs.assignValue(ok[i+(!x)]));
00176                                 CPPUNIT_ASSERT(mergeValue(&lhs, &rhs));
00177                                 CPPUNIT_ASSERT(lhs.value() == ok[i+2] && rhs.value() == ok[i+2]);
00178                         }
00179                 }
00180                 for (uint32 x = 0; x != 2; ++x) {
00181                         for (uint32 i = 0; i != 4; i+=2) {
00182                                 lhs.clearLiteral(true);
00183                                 rhs.clearLiteral(true);
00184                                 CPPUNIT_ASSERT(lhs.assignValue(fail[i+x]));
00185                                 CPPUNIT_ASSERT(rhs.assignValue(fail[i+(!x)]));
00186                                 CPPUNIT_ASSERT(!mergeValue(&lhs, &rhs));
00187                         }
00188                 }
00189         }
00190         void testIgnoreRules() {
00191                 builder.start(ctx)
00192                         .setAtomName(1, "a").setAtomName(2, "b")
00193                         .startRule().addHead(1).addToBody(1, true).endRule()  // a :- a.
00194                         .startRule().addHead(2).addToBody(1, true).endRule()  // b :- a.
00195                 ;
00196                 CPPUNIT_ASSERT_EQUAL(1u, builder.stats.rules());
00197         }
00198 
00199         void testDuplicateRule() {
00200                 builder.start(ctx, LogicProgram::AspOptions().iterations(1))
00201                         .setAtomName(1, "a").setAtomName(2, "b")
00202                         .startRule(CHOICERULE).addHead(2).endRule()  // {b}.
00203                         .startRule().addHead(1).addToBody(2, true).endRule()  // a :- b.
00204                         .startRule().addHead(1).addToBody(2, true).endRule()  // a :- b.
00205                 ;
00206                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
00207                 CPPUNIT_ASSERT(ctx.symbolTable()[1].lit == ctx.symbolTable()[2].lit);
00208         }
00209 
00210         void testNotAChoice() {
00211                 // {b}.
00212                 // {a} :- not b.
00213                 // a :- not b.
00214                 builder.start(ctx)
00215                         .setAtomName(1, "a").setAtomName(2, "b")
00216                         .startRule(CHOICERULE).addHead(2).endRule()
00217                         .startRule(CHOICERULE).addHead(1).addToBody(2, false).endRule()
00218                         .startRule().addHead(1).addToBody(2, false).endRule()
00219                 ;
00220                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
00221                 const SymbolTable& index = ctx.symbolTable();
00222                 ctx.master()->assume(~index[2].lit) && ctx.master()->propagate();
00223                 // if b is false, a must be true because a :- not b. is stronger than {a} :- not b.
00224                 CPPUNIT_ASSERT_EQUAL(true, ctx.master()->isTrue(index[1].lit));
00225         }
00226 
00227         void testNotAChoiceMerge() {
00228                 // {b}.
00229                 // {a} :- b.
00230                 // a :- b, not c.
00231                 builder.start(ctx)
00232                         .setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "c")
00233                         .startRule(CHOICERULE).addHead(2).endRule()
00234                         .startRule(CHOICERULE).addHead(1).addToBody(2, true).endRule()
00235                         .startRule().addHead(1).addToBody(2, true).addToBody(3, false).endRule()
00236                 ;
00237                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
00238                 const SymbolTable& index = ctx.symbolTable();
00239                 CPPUNIT_ASSERT(index[1].lit == index[2].lit);
00240         }
00241         
00242         void testMergeToSelfblocker() {
00243                 // a :- not b.
00244                 // b :- a.
00245                 builder.start(ctx)
00246                         .setAtomName(1, "a").setAtomName(2, "b")
00247                         .startRule().addHead(1).addToBody(2, false).endRule()
00248                         .startRule().addHead(2).addToBody(1, true).endRule()
00249                 ;
00250                 CPPUNIT_ASSERT_EQUAL(false, builder.endProgram() && ctx.endInit());
00251         }
00252         
00253         void testMergeToSelfblocker2() {
00254                 // a :- not z.
00255                 // a :- not x.
00256                 // q :- not x.
00257                 // x :- a.
00258                 builder.start(ctx)
00259                         .setAtomName(1, "a").setAtomName(2, "q").setAtomName(3, "x").setAtomName(4, "z")
00260                         .startRule().addHead(1).addToBody(4, false).endRule()
00261                         .startRule().addHead(1).addToBody(3, false).endRule()
00262                         .startRule().addHead(2).addToBody(3, false).endRule()
00263                         .startRule().addHead(3).addToBody(1, true).endRule()
00264                 ;
00265                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
00266                 CPPUNIT_ASSERT_EQUAL(true, ctx.master()->isTrue(ctx.symbolTable()[1].lit));
00267                 CPPUNIT_ASSERT(ctx.numVars() == 0);
00268         }
00269 
00270         void testDerivedTAUT() {
00271                 // {y, z}.
00272                 // a :- not z.
00273                 // x :- a.
00274                 // a :- x, y.
00275                 builder.start(ctx)
00276                         .setAtomName(1, "y").setAtomName(2, "z").setAtomName(3, "a").setAtomName(4, "x")
00277                         .startRule(CHOICERULE).addHead(1).addHead(2).endRule()
00278                         .startRule().addHead(3).addToBody(2, false).endRule()
00279                         .startRule().addHead(4).addToBody(3, true).endRule()
00280                         .startRule().addHead(3).addToBody(1, true).addToBody(4, true).endRule()
00281                 ;
00282                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
00283                 CPPUNIT_ASSERT(ctx.numVars() == 2);
00284         }
00285 
00286         void testOneLoop() {
00287                 // a :- not b.
00288                 // b :- not a.
00289                 builder.start(ctx)
00290                         .setAtomName(1, "a").setAtomName(2, "b")
00291                         .startRule().addHead(1).addToBody(2, false).endRule()
00292                         .startRule().addHead(2).addToBody(1, false).endRule()
00293                 ;
00294                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
00295                 CPPUNIT_ASSERT_EQUAL( 1u, ctx.numVars() );
00296                 CPPUNIT_ASSERT_EQUAL( 0u, ctx.numConstraints() );
00297                 CPPUNIT_ASSERT( ctx.symbolTable()[1].lit == ~ctx.symbolTable()[2].lit );
00298         }
00299 
00300         void testZeroLoop() {
00301                 // a :- b.
00302                 // b :- a.
00303                 // a :- not x.
00304                 // x :- not a.
00305                 builder.start(ctx)
00306                         .setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "x")
00307                         .startRule().addHead(1).addToBody(2, true).endRule()
00308                         .startRule().addHead(2).addToBody(1, true).endRule()
00309                         .startRule().addHead(1).addToBody(3, false).endRule()
00310                         .startRule().addHead(3).addToBody(1, false).endRule()
00311                 ;
00312                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
00313                 CPPUNIT_ASSERT_EQUAL( 1u, ctx.numVars() );
00314                 CPPUNIT_ASSERT_EQUAL( 0u, ctx.numConstraints() );
00315                 CPPUNIT_ASSERT( ctx.symbolTable()[1].lit == ctx.symbolTable()[2].lit );
00316         }
00317 
00318         void testEqSuccs() {
00319                 // {a,b}.
00320                 // c :- a, b.
00321                 // d :- a, b.
00322                 builder.start(ctx)
00323                         .setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "c").setAtomName(4, "d")
00324                         .startRule(CHOICERULE).addHead(1).addHead(2).endRule()
00325                         .startRule().addHead(3).addToBody(1, true).addToBody(2, true).endRule()
00326                         .startRule().addHead(4).addToBody(1, true).addToBody(2, true).endRule()
00327                 ;
00328                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
00329                 CPPUNIT_ASSERT_EQUAL( 3u, ctx.numVars() );
00330                 CPPUNIT_ASSERT_EQUAL( 3u, ctx.numConstraints() );
00331                 CPPUNIT_ASSERT( ctx.symbolTable()[3].lit == ctx.symbolTable()[4].lit );
00332         }
00333 
00334         void testEqCompute() {
00335                 // {x}.
00336                 // a :- not x.
00337                 // a :- b.
00338                 // b :- a.
00339                 // compute{b}.
00340                 builder.start(ctx)
00341                         .setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "x")
00342                         .startRule(CHOICERULE).addHead(3).endRule()
00343                         .startRule().addHead(1).addToBody(3, false).endRule()
00344                         .startRule().addHead(1).addToBody(2, true).endRule()
00345                         .startRule().addHead(2).addToBody(1, true).endRule()
00346                         .setCompute(2, true);
00347                 ;
00348                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
00349                 CPPUNIT_ASSERT_EQUAL(true, ctx.master()->isTrue(ctx.symbolTable()[1].lit));
00350                 PrgAtom* a = builder.getAtom(1);
00351                 CPPUNIT_ASSERT(builder.getEqAtom(2) == 1);
00352                 CPPUNIT_ASSERT(a->value() == value_true);
00353         }
00354 
00355         void testFactsAreAsserted() {
00356                 // a :- not x.
00357                 // y.
00358                 builder.start(ctx)
00359                         .setAtomName(1, "a").setAtomName(2, "x").setAtomName(3, "y")
00360                         .startRule().addHead(1).addToBody(2, false).endRule()   // dynamic fact
00361                         .startRule().addHead(3).endRule()
00362                 ;
00363                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
00364                 CPPUNIT_ASSERT_EQUAL(true, ctx.master()->isTrue(ctx.symbolTable()[1].lit));
00365                 CPPUNIT_ASSERT_EQUAL(true, ctx.master()->isTrue(ctx.symbolTable()[3].lit));
00366         }
00367         void testSelfblockersAreAsserted() {
00368                 // a :- not a.
00369                 // b :- not a.
00370                 builder.start(ctx)
00371                         .setAtomName(1, "a").setAtomName(2, "b")
00372                         .startRule().addHead(1).addToBody(1, false).endRule()
00373                         .startRule().addHead(2).addToBody(1, false).endRule()
00374                 ;
00375                 CPPUNIT_ASSERT_EQUAL(false, builder.endProgram() && ctx.endInit());
00376         }
00377         void testConstraintsAreAsserted() {
00378                 builder.start(ctx)
00379                         .setAtomName(1, "a").setAtomName(2, "b")
00380                         .startRule().addHead(1).addToBody(2, false).endRule()   // a :- not b.
00381                         .startRule().addHead(2).addToBody(1, false).endRule()   // b :- not a.
00382                         .setCompute(1, false)   // force not a
00383                 ;
00384                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
00385                 CPPUNIT_ASSERT_EQUAL(true, ctx.master()->isFalse(ctx.symbolTable()[1].lit));
00386         }
00387         
00388         void testConflictingCompute() {
00389                 builder.start(ctx)
00390                         .setAtomName(1, "a").setAtomName(2, "b")
00391                         .startRule().addHead(1).addToBody(2, false).endRule()   // a :- not b.
00392                         .startRule().addHead(2).addToBody(1, false).endRule()   // b :- not a.
00393                         .setCompute(1, false)   // force not a
00394                         .setCompute(1, true)    // force a
00395                 ;
00396                 CPPUNIT_ASSERT_EQUAL(false, builder.endProgram() && ctx.endInit());
00397                 CPPUNIT_ASSERT(!ctx.ok());
00398         }
00399         void testForceUnsuppAtomFails() {
00400                 builder.start(ctx)
00401                         .setAtomName(1, "a").setAtomName(2, "b")
00402                         .startRule().addHead(1).addToBody(2, false).endRule()   // a :- not b.
00403                         .setCompute(2, true)    // force b
00404                 ;
00405                 CPPUNIT_ASSERT_EQUAL(false, builder.endProgram() && ctx.endInit());
00406         }
00407 
00408         void testTrivialConflictsAreDeteced() {
00409                 builder.start(ctx)
00410                         .setAtomName(1, "a")
00411                         .startRule().addHead(1).addToBody(1, false).endRule()   // a :- not a.
00412                         .setCompute(1, true)
00413                 ;
00414                 CPPUNIT_ASSERT_EQUAL(false, builder.endProgram() && ctx.endInit());
00415 
00416         }
00417         void testBuildEmpty() {
00418                 builder.start(ctx);
00419                 builder.endProgram();
00420                 builder.write(str);
00421                 CPPUNIT_ASSERT_EQUAL(0u, ctx.numVars());
00422                 CPPUNIT_ASSERT(str.str() == "0\n0\nB+\n0\nB-\n0\n1\n");
00423         }
00424         void testAddOneFact() {
00425                 builder.start(ctx);
00426                 builder.startRule().addHead(1).endRule().setAtomName(1, "A");
00427                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
00428                 CPPUNIT_ASSERT_EQUAL(0u, ctx.numVars());
00429                 builder.write(str);
00430                 std::string lp = "1 1 0 0 \n0\n1 A\n0\nB+\n1\n0\nB-\n0\n1\n";
00431                 CPPUNIT_ASSERT_EQUAL(lp, str.str());
00432 
00433                 // a fact does not introduce a constraint, it is just a top-level assignment
00434                 CPPUNIT_ASSERT_EQUAL(0u, ctx.numConstraints());
00435         }
00436         
00437         void testTwoFactsOnlyOneVar() {
00438                 builder.start(ctx)
00439                         .startRule().addHead(1).endRule()
00440                         .startRule().addHead(2).endRule()
00441                         .setAtomName(1, "A").setAtomName(2, "B")
00442                 ;
00443                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
00444                 CPPUNIT_ASSERT_EQUAL(0u, ctx.numVars());
00445                 builder.write(str);
00446                 std::string lp = "1 1 0 0 \n1 2 1 0 1 \n0\n1 A\n2 B\n0\nB+\n1\n0\nB-\n0\n1\n";
00447                 CPPUNIT_ASSERT_EQUAL(lp, str.str());
00448         }
00449 
00450         void testDontAddOnePredsThatAreNotHeads() {
00451                 // a :- not b, not c.
00452                 // c.
00453                 builder.start(ctx)
00454                         .startRule().addHead(1).addToBody(2, false).addToBody(3, false).endRule()
00455                         .startRule().addHead(3).endRule()
00456                         .setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "c")
00457                 ;
00458                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
00459                 CPPUNIT_ASSERT_EQUAL(0u, ctx.numVars());
00460                 builder.write(str);
00461                 std::string lp = "1 3 0 0 \n0\n3 c\n0\nB+\n3\n0\nB-\n0\n1\n"; 
00462                 CPPUNIT_ASSERT_EQUAL(lp, str.str());
00463         }
00464 
00465         void testDontAddDuplicateBodies() {
00466                 // a :- b, not c.
00467                 // d :- b, not c.
00468                 // b.
00469                 // c.
00470                 builder.start(ctx)
00471                         .setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "c").setAtomName(4, "d")
00472                         .startRule().addHead(1).addToBody(2, true).addToBody(3, false).endRule()
00473                         .startRule().addHead(4).addToBody(2, true).addToBody(3, false).endRule()
00474                         .startRule().addHead(2).addHead(3).endRule()            
00475                 ;
00476                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
00477                 CPPUNIT_ASSERT_EQUAL(0u, ctx.numVars());
00478                 builder.write(str);
00479                 std::string lp = "1 2 0 0 \n1 3 1 0 2 \n0\n2 b\n3 c\n0\nB+\n2\n0\nB-\n0\n1\n";
00480                 
00481                 CPPUNIT_ASSERT_EQUAL(lp, str.str());
00482         }
00483 
00484         void testDontAddDuplicateSumBodies() {
00485                 // {a, b, c}.
00486                 // x :- 2 [a=1, b=2, not c=1].
00487                 // y :- 2 [a=1, b=2, not c=1].
00488                 builder.start(ctx)
00489                         .setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "c").setAtomName(4, "x").setAtomName(5, "y")
00490                         .startRule(CHOICERULE).addHead(1).addHead(2).addHead(3).endRule()
00491                         .startRule(WEIGHTRULE, 2).addHead(4).addToBody(1, true, 1).addToBody(2, true, 2).addToBody(3, false, 1).endRule()
00492                         .startRule(WEIGHTRULE, 2).addHead(5).addToBody(1, true, 1).addToBody(2, true, 2).addToBody(3, false, 1).endRule()
00493                 ;
00494                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
00495                 CPPUNIT_ASSERT(builder.stats.bodies == 2);      
00496         }
00497 
00498         void testDontAddUnsupported() {
00499                 // a :- c, b.
00500                 // c :- not d.
00501                 // b :- a.
00502                 builder.start(ctx)
00503                         .setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "c").setAtomName(4, "d")
00504                         .startRule().addHead(1).addToBody(3, true).addToBody(2, true).endRule()
00505                         .startRule().addHead(3).addToBody(4, false).endRule()
00506                         .startRule().addHead(2).addToBody(1, true).endRule()            
00507                 ;
00508                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
00509                 builder.write(str);
00510                 std::string lp = "1 3 0 0 \n0";
00511                 CPPUNIT_ASSERT(str.str().find(lp) != std::string::npos);
00512         }
00513 
00514         void testDontAddUnsupportedNoEq() {
00515                 // a :- c, b.
00516                 // c :- not d.
00517                 // b :- a.
00518                 builder.start(ctx, LogicProgram::AspOptions().noEq())
00519                         .setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "c").setAtomName(4, "d")
00520                         .startRule().addHead(1).addToBody(3, true).addToBody(2, true).endRule()
00521                         .startRule().addHead(3).addToBody(4, false).endRule()
00522                         .startRule().addHead(2).addToBody(1, true).endRule()            
00523                 ;
00524                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
00525                 CPPUNIT_ASSERT(ctx.numVars() <= 2u);
00526                 builder.write(str);
00527                 std::string lp = "1 3 0 0 \n0\n3 c\n0\nB+\n0\nB-\n0\n1\n";
00528                 CPPUNIT_ASSERT_EQUAL(lp, str.str());
00529         }
00530 
00531         void testDontAddUnsupportedExtNoEq() {
00532                 // a :- not x.
00533                 // c :- a, x.
00534                 // b :- 2 {a, c, not x}.
00535                 // -> 2 {a, c, not x} -> {a}
00536                 builder.start(ctx, LogicProgram::AspOptions().noEq())
00537                         .setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "c").setAtomName(4, "x")
00538                         .startRule().addHead(1).addToBody(4, false).endRule() // a :- not x
00539                         .startRule().addHead(3).addToBody(1, true).addToBody(4, true).endRule() // c :- a, x
00540                         .startRule(CONSTRAINTRULE, 2).addHead(2).addToBody(1, true).addToBody(3, true).addToBody(4, false).endRule()
00541                 ;
00542                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
00543                 CPPUNIT_ASSERT_EQUAL(true, ctx.master()->isFalse(ctx.symbolTable()[3].lit));
00544                 CPPUNIT_ASSERT_EQUAL(true, ctx.master()->isTrue(ctx.symbolTable()[1].lit));
00545                 CPPUNIT_ASSERT_EQUAL(true, ctx.master()->isTrue(ctx.symbolTable()[2].lit));
00546         }
00547 
00548         void testAssertSelfblockers() {
00549                 // a :- b, not c.
00550                 // c :- b, not c.
00551                 // b.
00552                 builder.start(ctx)
00553                         .setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "c")
00554                         .startRule().addHead(1).addToBody(2, true).addToBody(3, false).endRule()
00555                         .startRule().addHead(3).addToBody(2, true).addToBody(3, false).endRule()
00556                         .startRule().addHead(2).endRule()               
00557                 ;
00558                 // Program is unsat because b must be true and false at the same time.
00559                 CPPUNIT_ASSERT_EQUAL(false, builder.endProgram() && ctx.endInit());
00560         }
00561 
00562         void testCloneShare() {
00563                 // {a, b, c}.
00564                 // d :- a, b, c. 
00565                 builder.start(ctx, LogicProgram::AspOptions().noEq()) // no prepro
00566                         .setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "c").setAtomName(4, "d")
00567                         .startRule(CHOICERULE).addHead(1).addHead(2).addHead(3).endRule()
00568                         .startRule().addHead(4).addToBody(1, true).addToBody(2, true).addToBody(3, true).endRule()
00569                 ;
00570                 ctx.setConcurrency(2);
00571                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
00572                 CPPUNIT_ASSERT( uint32(4) >= ctx.numVars() );
00573                 CPPUNIT_ASSERT( uint32(4) >= ctx.numConstraints() );
00574 
00575                 Solver& solver2 = ctx.addSolver();
00576                 ctx.attach(solver2);
00577                 
00578                 CPPUNIT_ASSERT_EQUAL( ctx.numVars(), solver2.numVars() );
00579                 CPPUNIT_ASSERT_EQUAL( ctx.numConstraints(), solver2.numConstraints() );
00580 
00581                 CPPUNIT_ASSERT(ctx.isShared());
00582         }
00583 
00584         void testCloneShareSymbols() {
00585                 // {a, b, c}.
00586                 // d :- a, b, c. 
00587                 builder.start(ctx, LogicProgram::AspOptions().noEq()) // no prepro
00588                         .setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "c").setAtomName(4, "d")
00589                         .startRule(CHOICERULE).addHead(1).addHead(2).addHead(3).endRule()
00590                         .startRule().addHead(4).addToBody(1, true).addToBody(2, true).addToBody(3, true).endRule()
00591                 ;
00592                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
00593                 CPPUNIT_ASSERT( uint32(4) >= ctx.numVars() );
00594                 CPPUNIT_ASSERT( uint32(4) >= ctx.numConstraints() );
00595 
00596                 SharedContext ctx2;
00597                 CPPUNIT_ASSERT_EQUAL(true, builder.clone(ctx2, true) && ctx2.endInit());
00598                 CPPUNIT_ASSERT_EQUAL( ctx.numVars(), ctx2.numVars() );
00599                 CPPUNIT_ASSERT_EQUAL( ctx.numConstraints(), ctx2.numConstraints() );
00600                 CPPUNIT_ASSERT(!ctx.isShared());
00601                 CPPUNIT_ASSERT(!ctx2.isShared());
00602                 CPPUNIT_ASSERT( &ctx.symbolTable() == &ctx2.symbolTable() );
00603         }
00604         void testCloneFull() {
00605                 // {a, b, c}.
00606                 // d :- a, b, c. 
00607                 builder.start(ctx, LogicProgram::AspOptions().noEq()) // no prepro
00608                         .setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "c").setAtomName(4, "d")
00609                         .startRule(CHOICERULE).addHead(1).addHead(2).addHead(3).endRule()
00610                         .startRule().addHead(4).addToBody(1, true).addToBody(2, true).addToBody(3, true).endRule()
00611                 ;
00612                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
00613                 CPPUNIT_ASSERT( uint32(4) >= ctx.numVars() );
00614                 CPPUNIT_ASSERT( uint32(4) >= ctx.numConstraints() );
00615 
00616                 SharedContext ctx2;
00617                 CPPUNIT_ASSERT_EQUAL(true, builder.clone(ctx2) && ctx2.endInit());
00618                 CPPUNIT_ASSERT_EQUAL( ctx.numVars(), ctx2.numVars() );
00619                 CPPUNIT_ASSERT_EQUAL( ctx.numConstraints(), ctx2.numConstraints() );
00620                 CPPUNIT_ASSERT(!ctx.isShared());
00621                 CPPUNIT_ASSERT(!ctx2.isShared());
00622                 CPPUNIT_ASSERT( &ctx.symbolTable() != &ctx2.symbolTable() );
00623         }
00624 
00625         void testBug() {
00626                 builder.start(ctx)
00627                         .setAtomName(1, "d").setAtomName(2, "c").setAtomName(3, "b").setAtomName(4, "a")
00628                         .startRule().addHead(1).addToBody(2, true).endRule()                                                            // d :- c
00629                         .startRule().addHead(2).addToBody(3, true).addToBody(1, true).endRule() // c :- b, d.
00630                         .startRule().addHead(3).addToBody(4, true).endRule()                                                            // b:-a.
00631                         .startRule().addHead(4).addToBody(3, false).endRule()                                                           // a:-not b.
00632                 ;
00633                 CPPUNIT_ASSERT_EQUAL(false, builder.endProgram() && ctx.endInit());
00634         }
00635 
00636         void testSatBodyBug() {
00637                 builder.start(ctx)
00638                         .setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "c").setAtomName(4, "d")
00639                         .startRule(CHOICERULE).addHead(3).addHead(2).addHead(1).endRule()
00640                         .startRule().addHead(1).endRule()               // a.
00641                         .startRule(CONSTRAINTRULE).setBound(1).addHead(2).addToBody(1, true).addToBody(3, true).endRule() // b :- 1 {a, c}.
00642                         .startRule().addHead(4).addToBody(2, true).addToBody(3, true).endRule()
00643                 ;
00644                 CPPUNIT_ASSERT(std::distance(builder.getAtom(3)->deps_begin(), builder.getAtom(3)->deps_end()) == 2u);
00645                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
00646                 CPPUNIT_ASSERT(std::distance(builder.getAtom(3)->deps_begin(), builder.getAtom(3)->deps_end()) == 1u);
00647                 CPPUNIT_ASSERT(std::distance(builder.getAtom(2)->deps_begin(), builder.getAtom(2)->deps_end()) == 0u);
00648                 CPPUNIT_ASSERT_EQUAL(value_free, ctx.master()->value(ctx.symbolTable()[3].lit.var()));
00649         }
00650         void testDepBodyBug() {
00651                 builder.start(ctx)
00652                         .setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "c").setAtomName(4, "x").setAtomName(5, "y").setAtomName(6, "z")
00653                         .startRule(CHOICERULE).addHead(4).addHead(5).addHead(6).endRule()
00654                         .startRule().addHead(1).addToBody(4, true).addToBody(5, true).endRule()
00655                         .startRule().addHead(2).addToBody(1, true).endRule()
00656                         .startRule().addHead(3).addToBody(2, true).addToBody(6, true).addToBody(1, true).endRule()
00657                 ;
00658                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
00659                 CPPUNIT_ASSERT((builder.getAtom(1)->deps_end() - builder.getAtom(1)->deps_begin()) == 2);
00660         }
00661 
00662         void testAddUnknownAtomToMinimize() {
00663                 builder.start(ctx)
00664                         .startRule(OPTIMIZERULE).addToBody(1, true, 1).endRule()
00665                 ;
00666                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
00667                 CPPUNIT_ASSERT_EQUAL(true, builder.hasMinimize());
00668         }
00669 
00670         void testWriteWeakTrue() {
00671                 // {z}.
00672                 // x :- not y, z.
00673                 // y :- not x.
00674                 // compute{x}.
00675                 builder.start(ctx)
00676                         .setAtomName(1, "x").setAtomName(2, "y").setAtomName(3, "z")
00677                         .startRule(CHOICERULE).addHead(3).endRule()
00678                         .startRule().addHead(1).addToBody(2, false).addToBody(3, true).endRule()
00679                         .startRule().addHead(2).addToBody(1, false).endRule()
00680                         .setCompute(1, true)
00681                 ; 
00682                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
00683                 builder.write(str);
00684                 std::string bp("B+\n1\n");
00685                 CPPUNIT_ASSERT(str.str().find(bp) != std::string::npos);
00686         }
00687 
00688         void testSimplifyBodyEqBug() {
00689                 // {x,y,z}.
00690                 // a :- x,z.
00691                 // b :- x,z.
00692                 // c :- a, y, b.
00693                 builder.start(ctx)
00694                         .setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "c").setAtomName(4, "x").setAtomName(5, "y").setAtomName(6, "z")
00695                         .startRule(CHOICERULE).addHead(4).addHead(5).addHead(6).endRule()
00696                         .startRule().addHead(1).addToBody(4, true).addToBody(6, true).endRule()
00697                         .startRule().addHead(2).addToBody(4, true).addToBody(6, true).endRule()
00698                         .startRule().addHead(3).addToBody(1, true).addToBody(5, true).addToBody(2, true).endRule()
00699                 ; 
00700                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
00701                 PrgAtom* a = builder.getAtom(1);
00702                 PrgAtom* b = builder.getAtom(2);
00703                 CPPUNIT_ASSERT(b->eq() && b->id() == 1);
00704                 CPPUNIT_ASSERT((a->deps_end() - a->deps_begin()) == 1);
00705         }
00706 
00707         void testNoEqSameLitBug() {
00708                 // {x,y}.
00709                 // a :- x,y.
00710                 // b :- x,y.
00711                 // c :- a, b.
00712                 builder.start(ctx, LogicProgram::AspOptions().noEq())
00713                         .setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "c").setAtomName(4, "x").setAtomName(5, "y")
00714                         .startRule(CHOICERULE).addHead(4).addHead(5).endRule()
00715                         .startRule().addHead(1).addToBody(4, true).addToBody(5, true).endRule()
00716                         .startRule().addHead(2).addToBody(4, true).addToBody(5, true).endRule()
00717                         .startRule().addHead(3).addToBody(1, true).addToBody(2, true).endRule()
00718                 ; 
00719                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
00720                 CPPUNIT_ASSERT(ctx.numTernary() == 1);
00721         }
00722 
00723         void testAssertEqSelfblocker() {
00724                 builder.start(ctx)
00725                         .setAtomName(1, "a").setAtomName(2, "x").setAtomName(3, "y").setAtomName(4, "q").setAtomName(5, "r")
00726                         .startRule().addHead(1).addToBody(2, false).addToBody(3, false).endRule()       // a :- not x, not y.
00727                         .startRule().addHead(1).addToBody(4, false).addToBody(5, false).endRule()       // a :- not q, not r.
00728                         .startRule().addHead(2).addToBody(3, false).endRule() // x :- not y.
00729                         .startRule().addHead(3).addToBody(2, false).endRule()   // y :- not x.
00730                         .startRule().addHead(4).addToBody(5, false).endRule() // q :- not r.
00731                         .startRule().addHead(5).addToBody(4, false).endRule()   // r :- not q.                                                          
00732                 ;
00733                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
00734                 CPPUNIT_ASSERT_EQUAL(2u, ctx.numVars());
00735                 CPPUNIT_ASSERT_EQUAL(true, ctx.master()->isFalse(ctx.symbolTable()[1].lit));
00736         }
00737 
00738         void testAddClauses() {
00739                 ClauseObserver* o = new ClauseObserver;
00740                 ctx.master()->heuristic().reset(o);
00741                 builder.start(ctx)
00742                         .setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "c")
00743                         .startRule().addHead(1).addToBody(2, false).endRule()                                                           // a :- not b.
00744                         .startRule().addHead(1).addToBody(2, true).addToBody(3, true).endRule() // a :- b, c.
00745                         .startRule().addHead(2).addToBody(1, false).endRule()                                                           // b :- not a.
00746                         .startRule().addHead(3).addToBody(2, false).endRule()                                                           // c :- not b.
00747                 ;
00748                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
00749                 CPPUNIT_ASSERT_EQUAL(3u, ctx.numVars());
00750                 CPPUNIT_ASSERT_EQUAL(0u, ctx.master()->numAssignedVars());
00751         
00752                 CPPUNIT_ASSERT_EQUAL(8u, ctx.numConstraints());
00753 
00754                 Var bodyNotB = 1;
00755                 Var bodyBC = 3;
00756                 CPPUNIT_ASSERT_EQUAL(Var_t::body_var, ctx.varInfo(3).type());
00757                 Literal a = ctx.symbolTable()[1].lit;
00758                 CPPUNIT_ASSERT(ctx.symbolTable()[2].lit == ~ctx.symbolTable()[1].lit);
00759 
00760                 // a - HeadClauses
00761                 ClauseObserver::Clause ac;
00762                 ac.push_back(~a);
00763                 ac.push_back(posLit(bodyNotB));
00764                 ac.push_back(posLit(bodyBC));
00765                 std::sort(ac.begin(), ac.end());
00766                 CPPUNIT_ASSERT(std::find(o->clauses_.begin(), o->clauses_.end(), ac) != o->clauses_.end());
00767                 
00768                 // bodyNotB - Body clauses
00769                 ClauseObserver::Clause cl;
00770                 cl.push_back(negLit(bodyNotB)); cl.push_back(~ctx.symbolTable()[2].lit);
00771                 std::sort(cl.begin(), cl.end());
00772                 CPPUNIT_ASSERT(std::find(o->clauses_.begin(), o->clauses_.end(), cl) != o->clauses_.end());
00773                 cl.clear();
00774                 cl.push_back(posLit(bodyNotB)); cl.push_back(ctx.symbolTable()[2].lit);
00775                 std::sort(cl.begin(), cl.end());
00776                 CPPUNIT_ASSERT(std::find(o->clauses_.begin(), o->clauses_.end(), cl) != o->clauses_.end());
00777                 cl.clear();
00778                 cl.push_back(negLit(bodyNotB)); cl.push_back(a);
00779                 std::sort(cl.begin(), cl.end());
00780                 CPPUNIT_ASSERT(std::find(o->clauses_.begin(), o->clauses_.end(), cl) != o->clauses_.end());
00781                 
00782                 // bodyBC - Body clauses
00783                 cl.clear();
00784                 cl.push_back(negLit(bodyBC)); cl.push_back(ctx.symbolTable()[2].lit);
00785                 std::sort(cl.begin(), cl.end());
00786                 CPPUNIT_ASSERT(std::find(o->clauses_.begin(), o->clauses_.end(), cl) != o->clauses_.end());
00787                 cl.clear();
00788                 cl.push_back(negLit(bodyBC)); cl.push_back(ctx.symbolTable()[3].lit);
00789                 std::sort(cl.begin(), cl.end());
00790                 CPPUNIT_ASSERT(std::find(o->clauses_.begin(), o->clauses_.end(), cl) != o->clauses_.end());
00791                 cl.clear();
00792                 cl.push_back(posLit(bodyBC)); cl.push_back(~ctx.symbolTable()[2].lit); cl.push_back(~ctx.symbolTable()[3].lit);
00793                 std::sort(cl.begin(), cl.end());
00794                 CPPUNIT_ASSERT(std::find(o->clauses_.begin(), o->clauses_.end(), cl) != o->clauses_.end());
00795                 cl.clear();
00796                 cl.push_back(negLit(bodyBC)); cl.push_back(a);
00797                 std::sort(cl.begin(), cl.end());
00798                 CPPUNIT_ASSERT(std::find(o->clauses_.begin(), o->clauses_.end(), cl) != o->clauses_.end());
00799         }
00800 
00801         void testAddCardConstraint() {
00802                 builder.start(ctx)
00803                         .setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "c").setAtomName(4, "d")
00804                         // a :- 1 { not b, c, d }
00805                         // {b,c}.
00806                         .startRule(CONSTRAINTRULE).setBound(1).addHead(1).addToBody(2, false).addToBody(3, true).addToBody(4, true).endRule()
00807                         .startRule(CHOICERULE).addHead(2).addHead(3).endRule();
00808                 ;
00809                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
00810                 CPPUNIT_ASSERT_EQUAL(3u, ctx.numVars());
00811 
00812                 builder.write(str);
00813                 std::string exp = "2 1 2 1 1 2 3 \n3 2 2 3 0 0 \n0\n1 a\n2 b\n3 c\n0\nB+\n0\nB-\n0\n1\n";
00814                 CPPUNIT_ASSERT_EQUAL(exp, str.str());           
00815         }
00816 
00817         void testAddWeightConstraint() {
00818                 builder.start(ctx)
00819                         .setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "c").setAtomName(4, "d")
00820                         // a :- 2 [not b=1, c=2, d=2 ]
00821                         .startRule(WEIGHTRULE).setBound(2).addHead(1).addToBody(2, false, 1).addToBody(3, true, 2).addToBody(4, true, 2).endRule()
00822                         .startRule(CHOICERULE).addHead(2).addHead(3).endRule();
00823                 ;
00824                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
00825                 CPPUNIT_ASSERT_EQUAL(3u, ctx.numVars());
00826 
00827                 builder.write(str);
00828                 std::string exp = "5 1 2 2 1 2 3 1 2 \n3 2 2 3 0 0 \n0\n1 a\n2 b\n3 c\n0\nB+\n0\nB-\n0\n1\n";
00829                 CPPUNIT_ASSERT_EQUAL(exp, str.str());           
00830         }
00831         void testAddMinimizeConstraint() {
00832                 builder.start(ctx)
00833                         .setAtomName(1, "a").setAtomName(2, "b")
00834                         .startRule(BASICRULE).addHead(1).addToBody(2, false).endRule()
00835                         .startRule(BASICRULE).addHead(2).addToBody(1, false).endRule()
00836                         .startRule(OPTIMIZERULE).addToBody(1, true).endRule()
00837                         .startRule(OPTIMIZERULE).addToBody(2, true).endRule()
00838                 ;
00839                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
00840                 builder.write(str);
00841                 std::stringstream exp; 
00842                 exp
00843                         << "6 0 1 0 1 1 \n"
00844                         << "6 0 1 0 2 1 \n"
00845                         << "1 1 1 1 2 \n"
00846                         << "1 2 1 1 1 \n"
00847                         << "0\n1 a\n2 b\n0\nB+\n0\nB-\n0\n1\n";
00848                 CPPUNIT_ASSERT_EQUAL(exp.str(), str.str());
00849         }
00850         void testAddEmptyMinimizeConstraint() {
00851                 builder.start(ctx)
00852                         .startRule(OPTIMIZERULE).endRule()
00853                 ;
00854                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
00855                 CPPUNIT_ASSERT(builder.getMinimizeConstraint() != 0);
00856         }
00857 
00858         void testNonTight() {
00859                 // p :- q.
00860                 // q :- p.
00861                 // p :- not a.
00862                 // q :- not a.
00863                 // a :- not p.
00864                 builder.start(ctx)
00865                         .setAtomName(1, "a").setAtomName(2, "p").setAtomName(3, "q")
00866                         .startRule().addHead(2).addToBody(3, true).endRule()
00867                         .startRule().addHead(3).addToBody(2, true).endRule()
00868                         .startRule().addHead(2).addToBody(1, false).endRule()
00869                         .startRule().addHead(3).addToBody(1, false).endRule()
00870                         .startRule().addHead(1).addToBody(2, false).endRule()
00871                 ;
00872                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
00873                 CPPUNIT_ASSERT( builder.stats.sccs != 0 );
00874         }
00875 
00876         void testIgnoreCondFactsInLoops() {
00877                 // {a}.
00878                 // b :- a.
00879                 // a :- b.
00880                 builder.start(ctx)
00881                         .setAtomName(1, "a").setAtomName(2, "b")
00882                         .startRule(CHOICERULE).addHead(1).endRule()
00883                         .startRule().addHead(2).addToBody(1, true).endRule()
00884                         .startRule().addHead(1).addToBody(2, true).endRule()
00885                 ;
00886                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
00887                 CPPUNIT_ASSERT( builder.stats.sccs == 0);
00888         }
00889 
00890         void testCrEqBug() {
00891                 // a.
00892                 // {b}.
00893                 builder.start(ctx)
00894                         .setAtomName(1, "a").setAtomName(2, "b")
00895                         .startRule().addHead(1).endRule()
00896                         .startRule(CHOICERULE).addHead(2).endRule()
00897                 ;
00898                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
00899                 CPPUNIT_ASSERT_EQUAL(1u, ctx.numVars());
00900                 CPPUNIT_ASSERT_EQUAL(value_free, ctx.master()->value(ctx.symbolTable()[2].lit.var()));
00901         }
00902 
00903         void testEqOverChoiceRule() {
00904                 // {a}.
00905                 // b :- a.
00906                 builder.start(ctx)
00907                         .setAtomName(1, "a").setAtomName(2, "b")
00908                         .startRule(CHOICERULE).addHead(1).endRule()
00909                         .startRule().addHead(2).addToBody(1, true).endRule()    
00910                 ;
00911                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
00912                 CPPUNIT_ASSERT_EQUAL(1u, ctx.numVars());
00913                 builder.write(str);
00914                 std::stringstream exp; 
00915                 exp
00916                         << "3 1 1 0 0 \n"
00917                         << "1 2 1 0 1 \n"
00918                         << "0\n1 a\n2 b\n0\nB+\n0\nB-\n0\n1\n";
00919                 CPPUNIT_ASSERT_EQUAL(exp.str(), str.str());
00920         }
00921 
00922         void testEqOverComp() {
00923                 // x1 :- not x2.
00924                 // x1 :- x2.
00925                 // x2 :- not x3.
00926                 // x3 :- not x1.
00927                 builder.start(ctx)
00928                         .setAtomName(1, "x1").setAtomName(2, "x2").setAtomName(3, "x3")
00929                         .startRule().addHead(1).addToBody(2, false).endRule()
00930                         .startRule().addHead(1).addToBody(2, true).endRule()
00931                         .startRule().addHead(2).addToBody(3, false).endRule()
00932                         .startRule().addHead(3).addToBody(1, false).endRule()
00933                 ;
00934                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
00935                 CPPUNIT_ASSERT_EQUAL(ctx.symbolTable()[1].lit, ctx.symbolTable()[2].lit);
00936                 CPPUNIT_ASSERT(ctx.master()->numFreeVars() == 0 && ctx.master()->isTrue(ctx.symbolTable()[1].lit));
00937         }
00938 
00939         void testEqOverBodiesOfDiffType() {
00940                 builder.start(ctx)
00941                         .setAtomName(1, "z").setAtomName(2, "y").setAtomName(3, "x").setAtomName(4, "t")
00942                         .startRule(CHOICERULE).addHead(1).addHead(2).endRule() // {z,y}
00943                         .startRule(CONSTRAINTRULE,2).addHead(4).addToBody(1,true).addToBody(2,true).addToBody(3,true).endRule()
00944                         .startRule().addHead(3).addToBody(4,true).endRule()
00945                         .setCompute(2, false)
00946                 ;
00947                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
00948                 CPPUNIT_ASSERT(3u >= ctx.numVars());
00949                 CPPUNIT_ASSERT(ctx.master()->isFalse(ctx.symbolTable()[2].lit));
00950                 CPPUNIT_ASSERT(ctx.master()->isFalse(ctx.symbolTable()[3].lit));
00951                 CPPUNIT_ASSERT(ctx.master()->isFalse(ctx.symbolTable()[4].lit));
00952         }
00953 
00954 
00955         void testNoBodyUnification() {
00956                 // {x, y, z}.
00957                 // p :- x, s.
00958                 // p :- y.
00959                 // q :- not p.
00960                 // r :- not q.
00961                 // s :- p.
00962                 // s :- z. 
00963                 builder.start(ctx)
00964                         .setAtomName(1, "x").setAtomName(2, "y").setAtomName(3, "z")
00965                         .setAtomName(4, "p").setAtomName(5, "q").setAtomName(6, "r").setAtomName(7, "s")
00966                         .startRule(CHOICERULE).addHead(1).addHead(2).addHead(3).endRule()
00967                         .startRule().addHead(4).addToBody(1, true).addToBody(7,true).endRule()
00968                         .startRule().addHead(4).addToBody(2, true).endRule()
00969                         .startRule().addHead(5).addToBody(4, false).endRule()
00970                         .startRule().addHead(6).addToBody(5, false).endRule()
00971                         .startRule().addHead(7).addToBody(4, true).endRule()
00972                         .startRule().addHead(7).addToBody(3, true).endRule()
00973                 ;
00974                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
00975                 ctx.master()->addPost(new DefaultUnfoundedCheck());
00976                 CPPUNIT_ASSERT_EQUAL(true, ctx.endInit());
00977                 ctx.master()->assume(~ctx.symbolTable()[2].lit);        // ~y
00978                 ctx.master()->propagate();
00979                 ctx.master()->assume(~ctx.symbolTable()[3].lit);        // ~z
00980                 ctx.master()->propagate();
00981                 CPPUNIT_ASSERT_EQUAL(true, ctx.master()->isFalse(ctx.symbolTable()[7].lit));
00982         }
00983 
00984         void testNoEqAtomReplacement() {
00985                 // {x, y}.
00986                 // p :- x.
00987                 // p :- y.
00988                 // q :- not p.
00989                 // r :- not q.
00990                 builder.start(ctx)
00991                         .setAtomName(1, "x").setAtomName(2, "y").setAtomName(3, "p")
00992                         .setAtomName(4, "q").setAtomName(5, "r")
00993                         .startRule(CHOICERULE).addHead(1).addHead(2).endRule()
00994                         .startRule().addHead(3).addToBody(1, true).endRule()
00995                         .startRule().addHead(3).addToBody(2, true).endRule()
00996                         .startRule().addHead(4).addToBody(3, false).endRule()
00997                         .startRule().addHead(5).addToBody(4, false).endRule()
00998                 ;
00999                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
01000                 ctx.master()->assume(~ctx.symbolTable()[1].lit);        // ~x
01001                 ctx.master()->propagate();
01002                 ctx.master()->assume(~ctx.symbolTable()[2].lit);        // ~y
01003                 ctx.master()->propagate();
01004                 CPPUNIT_ASSERT_EQUAL(true, ctx.master()->isFalse(ctx.symbolTable()[3].lit));
01005         }
01006 
01007         void testAllBodiesSameLit() {
01008                 // {z}.
01009                 // r :- not z.
01010                 // q :- not r.
01011                 // s :- r.
01012                 // s :- not q.
01013                 // r :- s.
01014                 builder.start(ctx)
01015                         .setAtomName(1, "z").setAtomName(2, "r").setAtomName(3, "q").setAtomName(4, "s")
01016                         .startRule(CHOICERULE).addHead(1).endRule()
01017                         .startRule().addHead(2).addToBody(1, false).endRule()
01018                         .startRule().addHead(3).addToBody(2, false).endRule()
01019                         .startRule().addHead(4).addToBody(2, true).endRule()
01020                         .startRule().addHead(4).addToBody(3, false).endRule()
01021                         .startRule().addHead(2).addToBody(4, true).endRule()
01022                 ;
01023                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
01024                 CPPUNIT_ASSERT_EQUAL(ctx.symbolTable()[2].lit, ctx.symbolTable()[4].lit);
01025                 CPPUNIT_ASSERT(ctx.symbolTable()[1].lit != ctx.symbolTable()[3].lit);
01026                 ctx.master()->assume(ctx.symbolTable()[1].lit) && ctx.master()->propagate();
01027                 CPPUNIT_ASSERT(ctx.master()->value(ctx.symbolTable()[3].lit.var()) == value_free);
01028                 ctx.master()->assume(~ctx.symbolTable()[3].lit) && ctx.master()->propagate();
01029                 CPPUNIT_ASSERT(ctx.master()->numFreeVars() == 0 && ctx.master()->isTrue(ctx.symbolTable()[2].lit));
01030         }
01031 
01032         void testAllBodiesSameLit2() {
01033                 // {z, y}.
01034                 // r :- not z.
01035                 // q :- not r.
01036                 // s :- r.
01037                 // s :- not q.
01038                 // r :- s, y.
01039                 builder.start(ctx)
01040                         .setAtomName(1, "z").setAtomName(2, "r").setAtomName(3, "q").setAtomName(4, "s").setAtomName(5, "y")
01041                         .startRule(CHOICERULE).addHead(1).addHead(5).endRule()
01042                         .startRule().addHead(2).addToBody(1, false).endRule()
01043                         .startRule().addHead(3).addToBody(2, false).endRule()
01044                         .startRule().addHead(4).addToBody(2, true).endRule()
01045                         .startRule().addHead(4).addToBody(3, false).endRule()
01046                         .startRule().addHead(2).addToBody(4, true).addToBody(5, true).endRule()
01047                 ;
01048                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
01049                 CPPUNIT_ASSERT_EQUAL(ctx.symbolTable()[2].lit, ctx.symbolTable()[4].lit);
01050                 CPPUNIT_ASSERT(ctx.symbolTable()[1].lit != ctx.symbolTable()[3].lit);
01051                 ctx.master()->assume(ctx.symbolTable()[1].lit) && ctx.master()->propagate();
01052                 CPPUNIT_ASSERT(ctx.master()->value(ctx.symbolTable()[3].lit.var()) == value_free);
01053                 ctx.master()->assume(~ctx.symbolTable()[3].lit) && ctx.master()->propagate();
01054                 CPPUNIT_ASSERT(ctx.master()->numFreeVars() == 0 && ctx.master()->isTrue(ctx.symbolTable()[2].lit));
01055                 CPPUNIT_ASSERT(ctx.numVars() == 4);
01056         }
01057         
01058         void testCompLit() {
01059                 // {y}.
01060                 // a :- not x.
01061                 // x :- not a.
01062                 // b :- a, x.
01063                 // c :- a, y, not x
01064                 // -> a == ~x -> {a,x} = F -> {a, not x} = {a, y}
01065                 builder.start(ctx)
01066                         .setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "x").setAtomName(4, "y").setAtomName(5, "c")
01067                         .startRule(CHOICERULE).addHead(4).endRule()
01068                         .startRule().addHead(1).addToBody(3, false).endRule()
01069                         .startRule().addHead(3).addToBody(1, false).endRule()
01070                         .startRule().addHead(2).addToBody(1, true).addToBody(3, true).endRule()
01071                         .startRule().addHead(5).addToBody(1, true).addToBody(4, true).addToBody(3, false).endRule()
01072                 ;
01073                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
01074                 CPPUNIT_ASSERT_EQUAL(3u, ctx.numVars());
01075                 CPPUNIT_ASSERT(ctx.master()->isFalse(ctx.symbolTable()[2].lit));
01076         }
01077 
01078         void testFunnySelfblockerOverEqByTwo() {
01079                 // {x,y,z}.
01080                 // q :- x, y.
01081                 // d :- x, y.
01082                 // c :- y, z.
01083                 // a :- y, z.
01084                 // c :- q, not c.
01085                 // r :- d, not a.
01086                 // s :- x, r.
01087                 // -> q == d, c == a -> {d, not a} == {q, not c} -> F
01088                 // -> r == s are both unsupported!
01089                 builder.start(ctx)
01090                         .setAtomName(1, "x").setAtomName(2, "y").setAtomName(3, "z").setAtomName(4, "q")
01091                         .setAtomName(5, "d").setAtomName(6, "c").setAtomName(7, "a").setAtomName(8, "r").setAtomName(9, "s")
01092                         .startRule(CHOICERULE).addHead(1).addHead(2).addHead(3).endRule()
01093                         .startRule().addHead(4).addToBody(1, true).addToBody(2,true).endRule()
01094                         .startRule().addHead(5).addToBody(1, true).addToBody(2,true).endRule()
01095                         .startRule().addHead(6).addToBody(2, true).addToBody(3,true).endRule()
01096                         .startRule().addHead(7).addToBody(2, true).addToBody(3,true).endRule()
01097                         .startRule().addHead(6).addToBody(4, true).addToBody(6, false).endRule()
01098                         .startRule().addHead(8).addToBody(5, true).addToBody(7, false).endRule()
01099                         .startRule().addHead(9).addToBody(1, true).addToBody(8, true).endRule()
01100                 ;
01101                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
01102                 CPPUNIT_ASSERT(ctx.master()->isFalse(ctx.symbolTable()[8].lit));
01103                 CPPUNIT_ASSERT(ctx.master()->isFalse(ctx.symbolTable()[9].lit));
01104         }
01105         
01106         void testRemoveKnownAtomFromWeightRule() {
01107                 // {q, r}.
01108                 // a.
01109                 // x :- 5 [a = 2, not b = 2, q = 1, r = 1].
01110                 builder.start(ctx)
01111                         .setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "q").setAtomName(4, "r").setAtomName(5, "x")
01112                         .startRule(CHOICERULE).addHead(3).addHead(4).endRule()
01113                         .startRule().addHead(1).endRule()
01114                         .startRule(WEIGHTRULE).addHead(5).setBound(5).addToBody(1, true,2).addToBody(2, false,2).addToBody(3, true).addToBody(4, true).endRule()
01115                 ;
01116                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
01117                 builder.write(str);
01118                 // {q, r}.
01119                 // a. 
01120                 // x :- 1 [ q=1, r=1 ].
01121                 std::stringstream exp; 
01122                 exp
01123                         << "1 1 0 0 \n"
01124                         << "3 2 3 4 0 0 \n"
01125                         << "5 5 1 2 0 3 4 1 1 \n"
01126                         << "0\n1 a\n3 q\n4 r\n5 x\n0\nB+\n1\n0\nB-\n0\n1\n";
01127                 CPPUNIT_ASSERT_EQUAL(exp.str(), str.str());
01128         }
01129 
01130         void testMergeEquivalentAtomsInConstraintRule() {
01131                 // {a, c}.
01132                 // a :- b.
01133                 // b :- a.
01134                 // x :-  2 {a, b, c}.
01135                 builder.start(ctx)
01136                         .setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "c").setAtomName(4, "x")
01137                         .startRule(CHOICERULE).addHead(1).addHead(3).endRule()
01138                         .startRule().addHead(1).addToBody(2, true).endRule()
01139                         .startRule().addHead(2).addToBody(1, true).endRule()
01140                         .startRule(CONSTRAINTRULE).addHead(4).setBound(2).addToBody(1, true).addToBody(2, true).addToBody(3, true).endRule()
01141                 ;
01142                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
01143                 builder.write(str);
01144                 std::string x = str.str();
01145                 // x :-  2 [a=2, c].
01146                 CPPUNIT_ASSERT(x.find("5 4 2 2 0 1 3 2 1") != std::string::npos);
01147         }
01148 
01149         void testMergeEquivalentAtomsInWeightRule() {
01150                 // {a, c, d}.
01151                 // a :- b.
01152                 // b :- a.
01153                 // x :-  3 [a = 1, c = 4, b = 2, d=1].
01154                 builder.start(ctx)
01155                         .setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "c").setAtomName(4, "x").setAtomName(5, "d")
01156                         .startRule(CHOICERULE).addHead(1).addHead(3).addHead(5).endRule()
01157                         .startRule().addHead(1).addToBody(2, true).endRule()
01158                         .startRule().addHead(2).addToBody(1, true).endRule()
01159                         .startRule(WEIGHTRULE).addHead(4).setBound(3).addToBody(1, true,1).addToBody(3, true,4).addToBody(2, true,2).addToBody(5, true, 1).endRule()
01160                 ;
01161                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
01162                 builder.write(str);
01163                 std::string x = str.str();
01164                 // x :-  3 [a=3, c=3,d=1].
01165                 CPPUNIT_ASSERT(x.find("5 4 3 3 0 1 3 5 3 3 1") != std::string::npos);
01166         }
01167 
01168 
01169         void testBothLitsInConstraintRule() {
01170                 // {a}.
01171                 // b :- a.
01172                 // c :- b.
01173                 // x :-  1 {a, b, not b, not c}.
01174                 builder.start(ctx)
01175                         .setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "c").setAtomName(4, "x")
01176                         .startRule(CHOICERULE).addHead(1).endRule()
01177                         .startRule().addHead(2).addToBody(1, true).endRule()
01178                         .startRule().addHead(3).addToBody(2, true).endRule()
01179                         .startRule(CONSTRAINTRULE).addHead(4).setBound(1).addToBody(1, true).addToBody(2, false).addToBody(2, true,2).addToBody(3,false).endRule()
01180                 ;
01181                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
01182                 builder.write(str);
01183                 std::string x = str.str();
01184                 // x :-  1 [a=2, not a=2].
01185                 CPPUNIT_ASSERT(x.find("5 4 1 2 1 1 1 2 2") != std::string::npos);
01186         }
01187 
01188         void testBothLitsInWeightRule() {
01189                 // {a, d}.
01190                 // b :- a.
01191                 // c :- b.
01192                 // x :-  3 [a=3, not b=1, not c=3, d=2].
01193                 builder.start(ctx)
01194                         .setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "c").setAtomName(4, "x").setAtomName(5, "d")
01195                         .startRule(CHOICERULE).addHead(1).addHead(5).endRule()
01196                         .startRule().addHead(2).addToBody(1, true).endRule()
01197                         .startRule().addHead(3).addToBody(2, true).endRule()
01198                         .startRule(WEIGHTRULE).addHead(4).setBound(3).addToBody(1, true,3).addToBody(2, false,1).addToBody(3,false,3).addToBody(5, true, 2).endRule()
01199                 ;
01200                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
01201                 builder.write(str);
01202                 std::string x = str.str();
01203                 // x :-  3 [a=3, not a=4, d=2].
01204                 CPPUNIT_ASSERT(x.find("5 4 3 3 1 1 1 5 4 3 2") != std::string::npos);
01205         }
01206 
01207         void testWeightlessAtomsInWeightRule() {
01208                 // {a, b, c}.
01209                 // x :-  1 [a=1, b=1, c=0].
01210                 builder.start(ctx)
01211                         .setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "c").setAtomName(4, "x")
01212                         .startRule(CHOICERULE).addHead(1).addHead(2).addHead(3).endRule()
01213                         .startRule(WEIGHTRULE).addHead(4).setBound(1).addToBody(1, true,1).addToBody(2, true,1).addToBody(3,true,0).endRule()
01214                 ;
01215                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
01216                 builder.write(str);
01217                 std::string x = str.str();
01218                 // x :-  1 {a, b}.
01219                 CPPUNIT_ASSERT(x.find("2 4 2 0 1 1 2 ") != std::string::npos);
01220         }
01221 
01222         void testSimplifyToNormal() {
01223                 // {a}.
01224                 // b :-  2 [a=2,not c=1].
01225                 builder.start(ctx)
01226                         .setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "c")
01227                         .startRule(CHOICERULE).addHead(1).endRule()
01228                         .startRule(WEIGHTRULE).addHead(2).setBound(2).addToBody(1, true,2).addToBody(3, false,1).endRule()
01229                 ;
01230                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
01231                 builder.write(str);
01232                 std::string x = str.str();
01233                 // b :-  a.
01234                 CPPUNIT_ASSERT(x.find("1 2 1 0 1 ") != std::string::npos);
01235         }
01236 
01237         void testSimplifyToCardBug() {
01238                 // x1.
01239                 // x2.
01240                 // t :- 168 [not x1 = 576, not x2=381].
01241                 // compute { not t }.
01242                 builder.start(ctx)
01243                         .setAtomName(1, "x1").setAtomName(2, "x2").setAtomName(3, "t")
01244                         .startRule().addHead(1).addHead(2).endRule()
01245                         .startRule(WEIGHTRULE).addHead(3).setBound(168).addToBody(1,false,576).addToBody(2,false,381).endRule()
01246                         .setCompute(3, false)
01247                 ;
01248                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
01249                 CPPUNIT_ASSERT(ctx.master()->numFreeVars() == 0);
01250         }
01251 
01252         void testSimplifyCompBug() {
01253                 // x1 :- not x2.
01254                 // x1 :- x2.
01255                 // x2 :- not x3.
01256                 // x3 :- not x1.
01257                 // a. b. f.
01258                 // x4 :- a, b, x2, e, f.
01259                 builder.start(ctx, LogicProgram::AspOptions().iterations(1))
01260                         .setAtomName(1, "x1").setAtomName(2, "x2").setAtomName(3, "x3")
01261                         .setAtomName(4, "a").setAtomName(5, "b").setAtomName(6, "e").setAtomName(7, "f")
01262                         .startRule().addHead(1).addToBody(2, false).endRule()
01263                         .startRule().addHead(1).addToBody(2, true).endRule()
01264                         .startRule().addHead(2).addToBody(3, false).endRule()
01265                         .startRule().addHead(3).addToBody(1, false).endRule()
01266                         .startRule().addHead(4).addHead(5).addHead(7).endRule()
01267                         .startRule(CHOICERULE).addHead(6).endRule()
01268                         .startRule().addHead(8).addToBody(4, true).addToBody(5, true).addToBody(2, true).addToBody(6, true).addToBody(7, true).endRule()
01269                 ;
01270                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
01271                 PrgAtom* x = builder.getAtom(8);
01272                 PrgBody* B = builder.getBody(x->supps_begin()->node());
01273                 CPPUNIT_ASSERT(B->size() == 2 && !B->goal(0).sign() && B->goal(1).sign());
01274                 CPPUNIT_ASSERT(B->goal(0).var() == 6);
01275                 CPPUNIT_ASSERT(B->goal(1).var() == 3);
01276         }
01277 
01278         void testBPWeight() {
01279                 // {a, b, c, d}.
01280                 // x :-  2 [a=1, b=2, not c=2, d=1].
01281                 builder.start(ctx)
01282                         .setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "c").setAtomName(4, "d").setAtomName(5, "x")
01283                         .startRule(CHOICERULE).addHead(1).addHead(2).addHead(3).addHead(4).endRule()
01284                         .startRule(WEIGHTRULE).addHead(5).setBound(2).addToBody(1, true,1).addToBody(2, true,2).addToBody(3,false,2).addToBody(4, true, 1).endRule()
01285                         .setCompute(5, false)
01286                 ;
01287                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
01288                 CPPUNIT_ASSERT_EQUAL(true, ctx.master()->isFalse(ctx.symbolTable()[2].lit));
01289                 CPPUNIT_ASSERT_EQUAL(true, ctx.master()->isTrue(ctx.symbolTable()[3].lit));
01290         }
01291 
01292         void testExtLitsAreFrozen() {
01293                 // {a, b, c, d, e, f, g}.
01294                 // x :- 2 {b, c, d}.
01295                 // y :- 2 [c=1, d=2, e=1].
01296                 // minimize {f, g}.
01297                 builder.start(ctx)
01298                         .setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "c")
01299                         .setAtomName(4, "d").setAtomName(5, "e").setAtomName(6, "f")
01300                         .setAtomName(7, "g").setAtomName(8, "x").setAtomName(9, "y")
01301                         .startRule(CHOICERULE).addHead(1).addHead(2).addHead(3).addHead(4).addHead(5).addHead(6).addHead(7).endRule()
01302                         .startRule(CONSTRAINTRULE,2).addHead(8).addToBody(2, true).addToBody(3,true).addToBody(4, true).endRule()
01303                         .startRule(WEIGHTRULE,2).addHead(9).addToBody(3, true,1).addToBody(4,true,2).addToBody(5, true,1).endRule()
01304                         .startRule(OPTIMIZERULE).addToBody(6,true).addToBody(7,true).endRule()
01305                 ;
01306                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
01307                 CPPUNIT_ASSERT_EQUAL(false, ctx.varInfo(ctx.symbolTable()[1].lit.var()).frozen());
01308                 CPPUNIT_ASSERT_EQUAL(true, ctx.varInfo(ctx.symbolTable()[2].lit.var()).frozen());
01309                 CPPUNIT_ASSERT_EQUAL(true, ctx.varInfo(ctx.symbolTable()[3].lit.var()).frozen());
01310                 CPPUNIT_ASSERT_EQUAL(true, ctx.varInfo(ctx.symbolTable()[4].lit.var()).frozen());
01311                 CPPUNIT_ASSERT_EQUAL(true, ctx.varInfo(ctx.symbolTable()[5].lit.var()).frozen());
01312                 CPPUNIT_ASSERT_EQUAL(true, ctx.varInfo(ctx.symbolTable()[8].lit.var()).frozen());
01313                 CPPUNIT_ASSERT_EQUAL(true, ctx.varInfo(ctx.symbolTable()[9].lit.var()).frozen());
01314 
01315                 // minimize lits only frozen if constraint is actually used
01316                 CPPUNIT_ASSERT_EQUAL(false, ctx.varInfo(ctx.symbolTable()[6].lit.var()).frozen());
01317                 CPPUNIT_ASSERT_EQUAL(false, ctx.varInfo(ctx.symbolTable()[7].lit.var()).frozen());
01318                 builder.getMinimizeConstraint();
01319                 CPPUNIT_ASSERT_EQUAL(true, ctx.varInfo(ctx.symbolTable()[6].lit.var()).frozen());
01320                 CPPUNIT_ASSERT_EQUAL(true, ctx.varInfo(ctx.symbolTable()[7].lit.var()).frozen());
01321         }
01322 
01323         void writeIntegrityConstraint() {
01324                 builder.start(ctx)
01325                         .setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "x")
01326                         .startRule(CHOICERULE).addHead(1).addHead(2).addHead(3).endRule()
01327                         .startRule(BASICRULE).addHead(1).addToBody(3, true).addToBody(2, false).endRule()
01328                         .startRule(BASICRULE).addHead(2).addToBody(3, true).addToBody(2, false).endRule();
01329                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
01330                 
01331                 builder.write(str);
01332                 
01333                 // falseAtom :- x, not b.
01334                 CPPUNIT_ASSERT(str.str().find("1 4 2 1 2 3") != std::string::npos);
01335                 // compute {not falseAtom}.
01336                 CPPUNIT_ASSERT(str.str().find("B-\n4") != std::string::npos);
01337         }
01338 
01339         void testComputeTrueBug() {
01340                 // a :- not b.
01341                 // b :- a.
01342                 // a :- y.
01343                 // y :- a.
01344                 // compute{a}.
01345                 builder.start(ctx)
01346                         .setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "y")
01347                         .startRule().addHead(1).addToBody(2, false).endRule()
01348                         .startRule().addHead(2).addToBody(1, true).endRule()
01349                         .startRule().addHead(1).addToBody(3, true).endRule()
01350                         .startRule().addHead(3).addToBody(1, true).endRule()
01351                         .setCompute(1, true)
01352                 ;
01353                 CPPUNIT_ASSERT_EQUAL(false, builder.endProgram() && ctx.endInit());
01354         }
01355 
01356         void testBackprop() {
01357                 builder.start(ctx, LogicProgram::AspOptions().backpropagate())
01358                         .setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "c").setAtomName(4, "d")
01359                         .setAtomName(5, "x").setAtomName(6, "y").setAtomName(7, "z").setAtomName(8, "_false")
01360                         .startRule(CHOICERULE).addHead(5).addHead(6).addHead(7).endRule()       // {x,y,z}.
01361                         .startRule().addHead(4).addToBody(5, true).addToBody(1, true).endRule() // d :- x,a
01362                         .startRule().addHead(1).addToBody(6, true).addToBody(4, true).endRule() // a :- y,d
01363                         .startRule().addHead(2).addToBody(5, true).addToBody(7, true).endRule() // b :- x,z
01364                         .startRule().addHead(3).addToBody(6, true).addToBody(7, true).endRule() // c :- y,z
01365                         .startRule().addHead(8).addToBody(5, true).addToBody(4, false).endRule() //  :- x,not d
01366                         .startRule().addHead(8).addToBody(6, true).addToBody(2, false).endRule() //  :- y,not b
01367                         .startRule().addHead(8).addToBody(7, true).addToBody(3, false).endRule() //  :- z,not c
01368                         .setCompute(8, false)
01369                 ;
01370                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
01371                 CPPUNIT_ASSERT(ctx.numVars() == 0);
01372         }
01373 
01374         void testSimpleIncremental() {
01375                 builder.start(ctx);
01376                 // I1: 
01377                 // a :- not b.
01378                 // b :- not a.
01379                 builder.updateProgram();
01380                 builder.setAtomName(1, "a").setAtomName(2, "b")
01381                         .startRule().addHead(1).addToBody(2, false).endRule()
01382                         .startRule().addHead(2).addToBody(1, false).endRule()
01383                 ;
01384                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
01385                 CPPUNIT_ASSERT(ctx.numVars() == 1);
01386                 CPPUNIT_ASSERT(ctx.symbolTable()[1].lit == ~ctx.symbolTable()[2].lit);
01387         
01388                 // I2: 
01389                 // c :- a, not d.
01390                 // d :- b, not c.
01391                 // x :- d.
01392                 builder.updateProgram();
01393                 builder.setAtomName(3, "c").setAtomName(4, "d").setAtomName(5, "x")
01394                         .startRule().addHead(3).addToBody(1, true).addToBody(4, false).endRule()
01395                         .startRule().addHead(4).addToBody(2, true).addToBody(3, false).endRule()
01396                         .startRule().addHead(5).addToBody(4, true).endRule()
01397                 ;
01398                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
01399                 CPPUNIT_ASSERT(ctx.numVars() == 3);
01400                 CPPUNIT_ASSERT(ctx.symbolTable()[1].lit == ~ctx.symbolTable()[2].lit);
01401                 CPPUNIT_ASSERT(ctx.symbolTable()[5].lit == ctx.symbolTable()[4].lit);
01402         }
01403 
01404         void testIncrementalFreeze() {
01405                 builder.start(ctx, LogicProgram::AspOptions().noEq());
01406                 // I1:
01407                 // {y}.
01408                 // a :- not x.
01409                 // b :- a, y.
01410                 // freeze(x)
01411                 builder.updateProgram();
01412                 builder.setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "x").setAtomName(4, "y")
01413                         .startRule(CHOICERULE).addHead(4).endRule()
01414                         .startRule().addHead(1).addToBody(3, false).endRule()
01415                         .startRule().addHead(2).addToBody(1, true).addToBody(4, true).endRule()
01416                         .freeze(3)
01417                 ;
01418                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
01419                 CPPUNIT_ASSERT(ctx.symbolTable()[3].lit != negLit(0));
01420                 Solver& solver = *ctx.master();
01421                 solver.assume(ctx.symbolTable()[3].lit);
01422                 solver.propagate();
01423                 CPPUNIT_ASSERT(ctx.master()->isFalse(ctx.symbolTable()[2].lit));
01424                 solver.undoUntil(0);
01425                 // I2: 
01426                 // {z}.
01427                 // x :- z.
01428                 // unfreeze(x)
01429                 builder.updateProgram();
01430                 builder.setAtomName(5, "z")
01431                         .startRule(CHOICERULE).addHead(5).endRule()
01432                         .startRule().addHead(3).addToBody(5, true).endRule()
01433                         .unfreeze(3)
01434                 ;
01435                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
01436                 solver.assume(ctx.symbolTable()[5].lit);
01437                 solver.propagate();
01438                 CPPUNIT_ASSERT(ctx.master()->isFalse(ctx.symbolTable()[2].lit));
01439                 solver.undoUntil(0);
01440                 solver.assume(~ctx.symbolTable()[5].lit);       // ~z
01441                 solver.propagate();
01442                 CPPUNIT_ASSERT(ctx.master()->isFalse(ctx.symbolTable()[3].lit));
01443                 solver.assume(ctx.symbolTable()[4].lit);        // y
01444                 solver.propagate();
01445                 CPPUNIT_ASSERT(ctx.master()->isTrue(ctx.symbolTable()[2].lit));
01446         }
01447 
01448         void testIncrementalFreezeValue() {
01449                 builder.start(ctx, LogicProgram::AspOptions().noEq());
01450                 // I1:
01451                 // freeze(x)
01452                 // freeze(y, true)
01453                 // freeze(z, false)
01454                 builder.updateProgram();
01455                 builder.setAtomName(1, "x").setAtomName(2, "y").setAtomName(3, "z")
01456                         .freeze(1).freeze(2, value_true).freeze(3, value_false)
01457                 ;
01458                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
01459                 LitVec assume;
01460                 builder.getAssumptions(assume);
01461                 Solver& solver = *ctx.master();
01462                 solver.pushRoot(assume);
01463                 CPPUNIT_ASSERT(solver.isFalse(ctx.symbolTable()[1].lit));
01464                 CPPUNIT_ASSERT(solver.isTrue(ctx.symbolTable()[2].lit));
01465                 CPPUNIT_ASSERT(solver.isFalse(ctx.symbolTable()[3].lit));
01466                 solver.popRootLevel(solver.decisionLevel());
01467                 
01468                 // I2: 
01469                 // unfreeze(x)
01470                 // freeze(z, value_true)
01471                 // freeze(y, value_true)
01472                 // freeze(y, value_false)
01473                 builder.updateProgram();
01474                 builder.unfreeze(1).freeze(3, value_true).freeze(2, value_true).freeze(2, value_false);
01475                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
01476                 assume.clear();
01477                 builder.getAssumptions(assume);
01478                 CPPUNIT_ASSERT(assume.size() == 2 && solver.isFalse(ctx.symbolTable()[1].lit));
01479                 solver.pushRoot(assume);
01480                 CPPUNIT_ASSERT(solver.isFalse(ctx.symbolTable()[2].lit));
01481                 CPPUNIT_ASSERT(solver.isTrue(ctx.symbolTable()[3].lit));
01482         }
01483         void testIncrementalKeepFrozen() {
01484                 builder.start(ctx);
01485                 // I0:
01486                 // freeze{x}.
01487                 builder.updateProgram();
01488                 builder.setAtomName(1, "x")
01489                         .freeze(1)
01490                 ;
01491                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
01492                 PrgAtom* x   = builder.getAtom(1);
01493                 Literal xLit = x->literal();
01494                 // I1:
01495                 builder.updateProgram();
01496                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
01497                 CPPUNIT_ASSERT(x->literal() == xLit);
01498                 CPPUNIT_ASSERT(x->frozen());
01499         }
01500         void testIncrementalUnfreezeUnsupp() {
01501                 builder.start(ctx, LogicProgram::AspOptions().noEq());
01502                 // I1:
01503                 // a :- not x.
01504                 // freeze(x)
01505                 builder.updateProgram();
01506                 builder.setAtomName(1, "a").setAtomName(2, "x")
01507                         .startRule().addHead(1).addToBody(2, false).endRule()
01508                         .freeze(2)
01509                 ;
01510                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
01511                 DefaultUnfoundedCheck* ufsCheck = new DefaultUnfoundedCheck();
01512                 if (ctx.sccGraph.get()) {
01513                         ctx.master()->addPost(ufsCheck);
01514                         ufsCheck = 0;
01515                 }
01516                 ctx.endInit();;
01517                 // I2: 
01518                 // x :- y.
01519                 // y :- x.
01520                 // -> unfreeze(x)
01521                 builder.updateProgram();
01522                 builder.setAtomName(3, "y")
01523                         .startRule().addHead(3).addToBody(2, true).endRule()
01524                         .startRule().addHead(2).addToBody(3, true).endRule()
01525                         .unfreeze(2)
01526                 ;
01527                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
01528                 if (ctx.sccGraph.get() && ufsCheck) {
01529                         ctx.master()->addPost(ufsCheck);
01530                         ufsCheck = 0;
01531                 }
01532                 ctx.endInit();
01533                 delete ufsCheck;
01534                 CPPUNIT_ASSERT(ctx.master()->isTrue(ctx.symbolTable()[1].lit));
01535                 CPPUNIT_ASSERT(ctx.master()->isFalse(ctx.symbolTable()[2].lit));
01536                 CPPUNIT_ASSERT(ctx.master()->isFalse(ctx.symbolTable()[3].lit));
01537         }
01538 
01539         void testIncrementalUnfreezeCompute() {
01540                 builder.start(ctx, LogicProgram::AspOptions().noEq());
01541                 // I1:
01542                 // {z}.
01543                 // a :- x, y.
01544                 // x :- z.
01545                 // freeze(y)
01546                 builder.updateProgram();
01547                 builder.setAtomName(1, "a").setAtomName(2, "x").setAtomName(3, "y").setAtomName(4, "z")
01548                         .startRule(CHOICERULE).addHead(4).endRule()
01549                         .startRule().addHead(1).addToBody(2,true).addToBody(3, true).endRule()
01550                         .startRule().addHead(2).addToBody(4,true).endRule()
01551                         .freeze(3)
01552                 ;
01553                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
01554                 CPPUNIT_ASSERT_EQUAL(3u, ctx.numConstraints());
01555                 
01556                 builder.updateProgram();
01557                 builder.unfreeze(3);
01558                 builder.setCompute(3, false);
01559                 
01560                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
01561                 CPPUNIT_ASSERT(3u >= ctx.numConstraints());
01562                 CPPUNIT_ASSERT(ctx.master()->numFreeVars() == 1);
01563         }
01564 
01565         void testIncrementalCompute() {
01566                 builder.start(ctx, LogicProgram::AspOptions());
01567                 // I1: 
01568                 // {a, b}.
01569                 // FALSE :- a, b.
01570                 builder.updateProgram();
01571                 builder.setAtomName(1, "FALSE").setAtomName(2, "a").setAtomName(3, "b")
01572                         .startRule(CHOICERULE).addHead(2).addHead(3).endRule()
01573                         .startRule().addHead(1).addToBody(2, true).addToBody(3, true).endRule()
01574                         .setCompute(1, false)
01575                 ;
01576                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
01577                 // I2:
01578                 // {c}.
01579                 // FALSE :- a, c.
01580                 builder.updateProgram();
01581                 builder.setAtomName(4, "c")
01582                         .startRule(CHOICERULE).addHead(4).endRule()
01583                         .startRule().addHead(1).addToBody(2, true).addToBody(4, true).endRule()
01584                 ;
01585                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
01586                 ctx.master()->assume(ctx.symbolTable()[2].lit);
01587                 ctx.master()->propagate();
01588                 CPPUNIT_ASSERT(ctx.master()->isFalse(ctx.symbolTable()[3].lit));
01589                 CPPUNIT_ASSERT(ctx.master()->isFalse(ctx.symbolTable()[4].lit));
01590         }
01591 
01592         void testIncrementalComputeBackprop() {
01593                 builder.start(ctx, LogicProgram::AspOptions().backpropagate());
01594                 // I1: 
01595                 // a :- not b.
01596                 // b :- not a.
01597                 builder.updateProgram();
01598                 builder.setAtomName(1, "a").setAtomName(2, "b")
01599                         .startRule().addHead(1).addToBody(2, false).endRule()
01600                         .startRule().addHead(2).addToBody(1, false).endRule()
01601                         .setCompute(1, true)
01602                 ;
01603                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
01604                 // I2:
01605                 builder.updateProgram();
01606                 builder.setAtomName(3, "c").setAtomName(4, "d");
01607                 builder.startRule().addHead(3).addToBody(2, true).endRule();
01608                 builder.startRule().addHead(4).addToBody(2, false).endRule();
01609                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
01610                 CPPUNIT_ASSERT_EQUAL(false, builder.getAtom(3)->hasVar());
01611                 CPPUNIT_ASSERT_EQUAL(posLit(0), builder.getLiteral(4));
01612         }
01613 
01614         void testIncrementalBackpropStep() {
01615                 builder.start(ctx);
01616                 // I1: 
01617                 // {x}.
01618                 builder.updateProgram();
01619                 builder.setAtomName(1, "x")
01620                         .startRule(CHOICERULE).addHead(1).endRule()
01621                 ;
01622                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
01623                 // I2:
01624                 // a :- x, y.
01625                 // compute a.
01626                 builder.updateProgram();
01627                 builder.setAtomName(2, "a").setAtomName(3, "y")
01628                         .startRule(CHOICERULE).addHead(3).endRule()
01629                         .startRule().addHead(2).addToBody(1, true).addToBody(3, true).endRule()
01630                         .setCompute(2, true)
01631                 ;
01632                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
01633                 CPPUNIT_ASSERT(ctx.master()->isTrue(builder.getAtom(1)->literal()));
01634         }
01635 
01636         void testIncrementalEq() {
01637                 builder.start(ctx);
01638                 builder.updateProgram();
01639                 builder.setAtomName(1, "a").setAtomName(2, "b").setAtomName(3,"x").setAtomName(4, "y")
01640                         .startRule(CHOICERULE).addHead(3).addHead(4).endRule() // {x, y}
01641                         .startRule().addHead(1).addToBody(3, true).endRule() // a :- x.
01642                         .startRule().addHead(1).addToBody(4, true).endRule() // a :- y.
01643                         .startRule().addHead(2).addToBody(1, true).endRule() // b :- a.
01644                 ;
01645                 // b == a
01646                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
01647                 builder.write(str);
01648                 CPPUNIT_ASSERT(str.str().find("1 2 1 0 1") != std::string::npos);
01649                 builder.updateProgram();
01650                 builder.setAtomName(5, "c")
01651                         .startRule().addHead(5).addToBody(1, true).addToBody(2, true).endRule() // c :- a,b --> c :- a
01652                 ;
01653                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
01654                 builder.write(str);
01655                 CPPUNIT_ASSERT(str.str().find("1 5 1 0 1") != std::string::npos);
01656         }
01657 
01658         void testIncrementalEqUnfreeze() {
01659                 builder.start(ctx);
01660                 builder.updateProgram();
01661                 builder.setAtomName(1, "a")
01662                         .freeze(1)
01663                 ;
01664                 builder.endProgram();
01665                 // I1:
01666                 // {x}.
01667                 // a :- c.
01668                 // b :- x, not a.
01669                 builder.updateProgram();
01670                 builder.setAtomName(2, "b").setAtomName(3, "c").setAtomName(4, "x")
01671                         .startRule(CHOICERULE).addHead(4).endRule()
01672                         .startRule().addHead(1).addToBody(3, true).endRule()
01673                         .startRule().addHead(2).addToBody(4, true).addToBody(1, false).endRule()
01674                         .unfreeze(1)
01675                 ;
01676                 builder.endProgram();
01677                 CPPUNIT_ASSERT(ctx.numVars() == 2 && ctx.master()->numFreeVars() == 1);
01678                 const SymbolTable& index = ctx.symbolTable();
01679                 CPPUNIT_ASSERT(index[2].lit == index[4].lit);
01680         }
01681 
01682         void testIncrementalEqComplement() {
01683                 builder.start(ctx);
01684                 // I0:
01685                 // a :- not b.
01686                 // b :- not a.
01687                 builder.updateProgram();
01688                 builder.setAtomName(1, "a").setAtomName(2, "b")
01689                         .startRule().addHead(1).addToBody(2, false).endRule()
01690                         .startRule().addHead(2).addToBody(1, false).endRule()
01691                 ;
01692                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
01693                 PrgAtom* a = builder.getAtom(1);
01694                 PrgAtom* b = builder.getAtom(2);
01695                 CPPUNIT_ASSERT(b->literal() == ~a->literal());
01696                 // I1: 
01697                 // c :- a, b.
01698                 builder.updateProgram();
01699                 builder.setAtomName(3, "c")
01700                         .startRule().addHead(3).addToBody(1, false).addToBody(2, false).endRule()
01701                 ;
01702                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());               
01703                 PrgAtom* c = builder.getAtom(3);
01704                 CPPUNIT_ASSERT(c->hasVar() == false);
01705         }
01706 
01707         void testIncrementalEqUpdateAssigned() {
01708                 builder.start(ctx);
01709                 // I0:
01710                 // freeze{x}.
01711                 builder.updateProgram();
01712                 builder.setAtomName(1, "x")
01713                         .freeze(1)
01714                 ;
01715                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
01716                 
01717                 // I1: 
01718                 // x :- y.
01719                 // y :- x.
01720                 // unfreeze{x}.
01721                 builder.updateProgram();
01722                 builder.setAtomName(2, "y")
01723                         .startRule().addHead(1).addToBody(2, true).endRule()
01724                         .startRule().addHead(2).addToBody(1, true).endRule()
01725                         .unfreeze(1)
01726                 ;
01727                 PrgAtom* x = builder.getAtom(1);
01728                 x->setValue(value_weak_true);
01729                 builder.endProgram();
01730                 // only weak-true so still relevant in bodies!
01731                 CPPUNIT_ASSERT(x->deps_begin()->sign() == false);
01732         }
01733 
01734         void testIncrementalEqResetState() {
01735                 builder.start(ctx);
01736                 // I0:
01737                 // {a,b}.
01738                 builder.updateProgram();
01739                 builder.setAtomName(1, "a").setAtomName(2, "b")
01740                         .startRule(CHOICERULE).addHead(1).addHead(2).endRule()
01741                 ;
01742                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
01743                 
01744                 // I1: 
01745                 // {z}.
01746                 // x :- c.
01747                 // x :- y, a.
01748                 // y :- d.
01749                 // y :- x, b.
01750                 // c :- z, not s.
01751                 // d :- z, not r.
01752                 builder.updateProgram();
01753                 builder.setAtomName(3, "x").setAtomName(4, "y").setAtomName(5, "z").setAtomName(6, "c").setAtomName(7, "d")
01754                         .startRule().addHead(3).addToBody(6, true).endRule() // x :- c.
01755                         .startRule().addHead(4).addToBody(7, true).endRule() // y :- d.
01756                         
01757                         .startRule().addHead(3).addToBody(4, true).addToBody(1, true).endRule() // x :- y, a.
01758                         .startRule().addHead(4).addToBody(3, true).addToBody(2, true).endRule() // y :- x, b.
01759 
01760                         .startRule().addHead(6).addToBody(5, true).addToBody(8, false).endRule() // c :- z, not r.
01761                         .startRule().addHead(7).addToBody(5, true).addToBody(9, false).endRule() // d :- z, not s.
01762                         .startRule(CHOICERULE).addHead(5).endRule() // {z}.
01763                 ;
01764                 builder.endProgram();
01765                 CPPUNIT_ASSERT(builder.getAtom(3)->scc() == 0);
01766                 CPPUNIT_ASSERT(builder.getAtom(4)->scc() == 0);
01767         }
01768 
01769         void testIncrementalUnfreezeUnsuppEq() {
01770                 builder.start(ctx, LogicProgram::AspOptions().noScc());
01771                 // I0:
01772                 // freeze{x}.
01773                 builder.updateProgram();
01774                 builder.setAtomName(1, "x")
01775                         .freeze(1)
01776                 ;
01777                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
01778                 // I1: 
01779                 // {z}.
01780                 // x :- y.
01781                 // y :- x, z.
01782                 // unfreeze{x}.
01783                 builder.updateProgram();
01784                 builder.setAtomName(2, "y").setAtomName(3, "z")
01785                         .startRule().addHead(1).addToBody(2, true).endRule()
01786                         .startRule().addHead(2).addToBody(1, true).addToBody(3, true).endRule()
01787                         .startRule(CHOICERULE).addHead(3).endRule()
01788                         .unfreeze(1)
01789                 ;
01790                 builder.endProgram();
01791                 PrgAtom* x = builder.getAtom(1);
01792                 PrgAtom* y = builder.getAtom(2);
01793                 CPPUNIT_ASSERT(ctx.master()->isFalse(x->literal()));
01794                 CPPUNIT_ASSERT(ctx.master()->isFalse(y->literal()));
01795         }
01796 
01797         void testIncrementalUnfreezeEq() {
01798                 builder.start(ctx);
01799                 // I0:
01800                 // freeze{x}.
01801                 builder.updateProgram();
01802                 builder.setAtomName(1, "x")
01803                         .freeze(1)
01804                 ;
01805                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
01806                 // I1: 
01807                 // {z}.
01808                 // y :- z.
01809                 // x :- y.
01810                 // unfreeze{x}.
01811                 builder.updateProgram();
01812                 builder.setAtomName(2, "y").setAtomName(3, "z")
01813                         .startRule(CHOICERULE).addHead(3).endRule()
01814                         .startRule().addHead(2).addToBody(3, true).endRule()
01815                         .startRule().addHead(1).addToBody(2, true).endRule()
01816                         .unfreeze(1)
01817                 ;
01818                 PrgAtom* x = builder.getAtom(1);
01819                 builder.endProgram();
01820                 // body {y} is eq to body {z} 
01821                 CPPUNIT_ASSERT(ctx.master()->value(x->var()) == value_free);
01822                 CPPUNIT_ASSERT(x->supports() == 1 && x->supps_begin()->node() == 1);
01823         }
01824 
01825         void testIncrementalStats() {
01826                 LpStats incStats;
01827                 builder.start(ctx, LogicProgram::AspOptions().noEq());
01828                 // I1:
01829                 // a :- not b.
01830                 // b :- not a.
01831                 // freeze(c).
01832                 builder.updateProgram();
01833                 builder.setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "c")
01834                         .startRule().addHead(1).addToBody(2, false).endRule()
01835                         .startRule().addHead(2).addToBody(1, false).endRule()
01836                         .freeze(3)
01837                 ;
01838                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
01839                 incStats = builder.stats;
01840                 CPPUNIT_ASSERT_EQUAL(uint32(3), incStats.atoms);
01841                 CPPUNIT_ASSERT_EQUAL(uint32(2), incStats.bodies);
01842                 CPPUNIT_ASSERT_EQUAL(uint32(2), incStats.rules());
01843                 CPPUNIT_ASSERT_EQUAL(uint32(0), incStats.ufsNodes);
01844                 CPPUNIT_ASSERT_EQUAL(uint32(0), incStats.sccs);
01845                 
01846                 // I2:
01847                 // {c, z}
01848                 // x :- not c.
01849                 // x :- y, z.
01850                 // y :- x, z.
01851                 builder.updateProgram();
01852                 builder.setAtomName(4, "x").setAtomName(5, "y").setAtomName(6, "z")
01853                         .startRule(CHOICERULE).addHead(3).addHead(6).endRule()
01854                         .startRule().addHead(4).addToBody(3, false).endRule()
01855                         .startRule().addHead(4).addToBody(5, true).addToBody(6, true).endRule()
01856                         .startRule().addHead(5).addToBody(4, true).addToBody(6, true).endRule()
01857                         .unfreeze(3)
01858                 ;
01859                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
01860                 incStats.accu(builder.stats);
01861                 CPPUNIT_ASSERT_EQUAL(uint32(6), incStats.atoms);
01862                 CPPUNIT_ASSERT_EQUAL(uint32(6), incStats.bodies);
01863                 CPPUNIT_ASSERT_EQUAL(uint32(6), incStats.rules());
01864                 CPPUNIT_ASSERT_EQUAL(uint32(1), incStats.sccs);
01865                 // I3:
01866                 // a :- x, not r.
01867                 // r :- not a.
01868                 // a :- b.
01869                 // b :- a, not z.
01870                 builder.updateProgram();
01871                 builder.setAtomName(7, "a").setAtomName(8, "b").setAtomName(9, "r")
01872                         .startRule().addHead(7).addToBody(4, true).addToBody(9, false).endRule()
01873                         .startRule().addHead(9).addToBody(7, false).endRule()
01874                         .startRule().addHead(7).addToBody(8, true).endRule()
01875                         .startRule().addHead(8).addToBody(7, true).addToBody(6, false).endRule()
01876                 ;
01877                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
01878                 incStats.accu(builder.stats);
01879                 CPPUNIT_ASSERT_EQUAL(uint32(9), incStats.atoms);
01880                 // +1 because of support body for atoms from previous steps
01881                 CPPUNIT_ASSERT_EQUAL(uint32(10) + 1, incStats.bodies);
01882                 CPPUNIT_ASSERT_EQUAL(uint32(10), incStats.rules());
01883                 CPPUNIT_ASSERT_EQUAL(uint32(2), incStats.sccs);
01884         }
01885 
01886         void testIncrementalTransform() {
01887                 builder.start(ctx, LogicProgram::AspOptions().noEq());
01888                 builder.setExtendedRuleMode(LogicProgram::mode_transform);
01889                 // I1:
01890                 // {a}.
01891                 // --> 
01892                 // a :- not a'
01893                 // a':- not a.
01894                 builder.updateProgram();
01895                 builder.setAtomName(1, "a")
01896                         .startRule(CHOICERULE).addHead(1).endRule()
01897                 ;
01898                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
01899                 CPPUNIT_ASSERT(ctx.sccGraph.get() == 0);
01900                 // I2:
01901                 // b :- a.
01902                 // b :- c.
01903                 // c :- b.
01904                 // NOTE: b must not have the same id as a'
01905                 builder.updateProgram();
01906                 builder.setAtomName(2, "b").setAtomName(3, "c")
01907                         .startRule().addHead(2).addToBody(1, true).endRule()
01908                         .startRule().addHead(2).addToBody(3, true).endRule()
01909                         .startRule().addHead(3).addToBody(2, true).endRule()
01910                 ;
01911                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram() && ctx.endInit());
01912                 CPPUNIT_ASSERT(ctx.sccGraph.get() != 0);
01913         }
01914 
01915         void testIncrementalBackpropCompute() {
01916                 builder.start(ctx);
01917                 // I0:
01918                 // a :- x.
01919                 // freeze{x}.
01920                 // compute{a}.
01921                 builder.updateProgram();
01922                 builder.setAtomName(1, "a").setAtomName(2, "x")
01923                         .startRule().addHead(1).addToBody(2, true).endRule()
01924                         .setCompute(1, true)
01925                         .freeze(2)
01926                 ;
01927                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
01928                 CPPUNIT_ASSERT(builder.getEqAtom(1) == 2);
01929                 PrgAtom* x = builder.getAtom(2);
01930                 CPPUNIT_ASSERT(x->value() == value_weak_true);
01931                 // I1: 
01932                 // x :- y.
01933                 // y :- x.
01934                 // unfreeze{x}.
01935                 builder.updateProgram();
01936                 builder.setAtomName(3, "y")
01937                         .startRule().addHead(3).addToBody(2, true).endRule()
01938                         .startRule().addHead(2).addToBody(3, true).endRule()
01939                         .unfreeze(2)
01940                 ;
01941                 // UNSAT: no support for x,y
01942                 CPPUNIT_ASSERT_EQUAL(false, builder.endProgram());
01943         }
01944 
01945         void testIncrementalBackpropSolver() {
01946                 builder.start(ctx);
01947                 // I0:
01948                 // {a}.
01949                 // freeze{x}.
01950                 builder.updateProgram();
01951                 builder.setAtomName(1, "a").setAtomName(2, "x")
01952                         .startRule(CHOICERULE).addHead(1).endRule()
01953                         .setCompute(1, true)
01954                         .setCompute(2, true)
01955                         .freeze(2)
01956                 ;
01957                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
01958                 PrgAtom* a = builder.getAtom(1);
01959                 PrgAtom* x = builder.getAtom(2);
01960                 CPPUNIT_ASSERT(a->value() == value_true);
01961                 CPPUNIT_ASSERT(x->value() == value_weak_true);
01962                 // I1: 
01963                 builder.updateProgram();
01964                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
01965                 CPPUNIT_ASSERT(a->value() == value_true);
01966                 CPPUNIT_ASSERT(x->value() == value_weak_true);
01967         }
01968 
01969         void testIncrementalFreezeUnfreeze() {
01970                 builder.start(ctx);
01971                 // I0:
01972                 // {a}.
01973                 // freeze{x}.
01974                 // unfreeze{x}.
01975                 builder.updateProgram();
01976                 builder.setAtomName(1, "a").setAtomName(2, "x")
01977                         .startRule(CHOICERULE).addHead(1).endRule()
01978                         .freeze(2)
01979                         .unfreeze(2)
01980                 ;
01981                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
01982                 CPPUNIT_ASSERT_EQUAL(negLit(0), ctx.symbolTable()[2].lit);
01983                 // I1:
01984                 // freeze(y).
01985                 // y :- x.
01986                 builder.updateProgram();
01987                 builder.setAtomName(3, "y")
01988                         .freeze(3)
01989                         .startRule().addHead(3).addToBody(2, true).endRule()
01990                 ;
01991                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
01992                 CPPUNIT_ASSERT_EQUAL(true, ctx.master()->isFalse(ctx.symbolTable()[2].lit));
01993         }
01994         void testIncrementalSymbolUpdate() {
01995                 builder.start(ctx);
01996                 // I0:
01997                 // {a}.
01998                 builder.updateProgram();
01999                 builder.setAtomName(1, "a")
02000                         .startRule(CHOICERULE).addHead(1).endRule()
02001                 ;
02002                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
02003                 // I1:
02004                 // {_unnamed, b}.
02005                 builder.updateProgram();
02006                 builder.setAtomName(3, "b")
02007                         .startRule(CHOICERULE).addHead(2).addHead(3).endRule()
02008                 ;
02009                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
02010                 CPPUNIT_ASSERT(ctx.symbolTable().find(2) == 0);
02011                 CPPUNIT_ASSERT(!isSentinel(ctx.symbolTable()[3].lit));
02012         }
02013         void testIncrementalFreezeDefined() {
02014                 builder.start(ctx);
02015                 // I0:
02016                 // {a}.
02017                 builder.updateProgram();
02018                 builder.setAtomName(1, "a")
02019                         .startRule(CHOICERULE).addHead(1).endRule()
02020                 ;
02021                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
02022                 // I1:
02023                 builder.updateProgram();
02024                 builder.freeze(1);
02025                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
02026                 CPPUNIT_ASSERT(builder.getAtom(1)->frozen() == false);
02027         }
02028         void testIncrementalUnfreezeDefined() {
02029                 builder.start(ctx);
02030                 // I0:
02031                 // {a}.
02032                 builder.updateProgram();
02033                 builder.setAtomName(1, "a")
02034                         .startRule(CHOICERULE).addHead(1).endRule()
02035                 ;
02036                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
02037                 // I1:
02038                 builder.updateProgram();
02039                 builder.unfreeze(1);
02040                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
02041                 CPPUNIT_ASSERT(!ctx.master()->isFalse(builder.getLiteral(1)));
02042         }
02043         void testIncrementalImplicitUnfreeze() {
02044                 builder.start(ctx);
02045                 // I0:
02046                 // freeze(a).
02047                 builder.updateProgram();
02048                 builder.setAtomName(1, "a")
02049                         .freeze(1)
02050                 ;
02051                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
02052                 CPPUNIT_ASSERT(builder.getAtom(1)->frozen() == true);
02053                 CPPUNIT_ASSERT(!ctx.master()->isFalse(builder.getLiteral(1)));
02054                 // I1:
02055                 // {a}.
02056                 builder.updateProgram();
02057                 builder.startRule(CHOICERULE).addHead(1).endRule();
02058                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
02059                 CPPUNIT_ASSERT(builder.getAtom(1)->frozen() == false);
02060         }
02061         void testIncrementalRedefine() {
02062                 builder.start(ctx);
02063                 // I0:
02064                 // {a}.
02065                 builder.updateProgram();
02066                 builder.setAtomName(1, "a")
02067                         .startRule(CHOICERULE).addHead(1).endRule()
02068                 ;
02069                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
02070                 // I1:
02071                 // {a}.
02072                 builder.updateProgram();
02073                 CPPUNIT_ASSERT_THROW(builder.startRule(CHOICERULE).addHead(1).endRule(), RedefinitionError);
02074         }
02075         void testIncrementalGetAssumptions() {
02076                 builder.start(ctx);
02077                 // I0:
02078                 builder.updateProgram();
02079                 builder.setAtomName(1, "a").setAtomName(2, "b")
02080                         .freeze(1).freeze(2)
02081                 ;
02082                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
02083                 LitVec a;
02084                 builder.getAssumptions(a);
02085                 CPPUNIT_ASSERT(a.size() == 2 && a[0] == ~builder.getLiteral(1) && a[1] == ~builder.getLiteral(2));
02086         }
02087 
02088         void testIncrementalSimplifyCard() {
02089                 builder.start(ctx);
02090                 // I0:
02091                 builder.updateProgram();
02092                 builder.setAtomName(1, "a")
02093                         .startRule().addHead(1).endRule()
02094                 ;
02095                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
02096                 builder.updateProgram();
02097                 builder.setAtomName(2, "b").setAtomName(3, "c").setAtomName(4, "d")
02098                         .startRule(CONSTRAINTRULE,1).addHead(2).addToBody(3, true).addToBody(1, true).endRule()
02099                         .startRule(CONSTRAINTRULE,1).addHead(4).addToBody(3, true).addToBody(2, true).endRule()
02100                         .startRule(BASICRULE).addHead(3).addToBody(1, true,2).addToBody(2,true).endRule()
02101                 ;
02102                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
02103         }
02104 
02105         void testIncrementalSimplifyMinimize() {
02106                 builder.start(ctx);
02107                 // I0:
02108                 builder.updateProgram();
02109                 builder.setAtomName(1, "a")
02110                         .startRule().addHead(1).endRule() // a.
02111                         .startRule(OPTIMIZERULE).addToBody(1, true).endRule()
02112                 ;
02113                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
02114                 CPPUNIT_ASSERT(builder.getMinimizeConstraint()->adjust(0) == 1);
02115                 builder.disposeMinimizeConstraint();
02116                 
02117                 builder.updateProgram();
02118                 builder.startRule(OPTIMIZERULE).addToBody(1, true).endRule();
02119                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
02120                 CPPUNIT_ASSERT(builder.getMinimizeConstraint());
02121                 CPPUNIT_ASSERT(builder.getMinimizeConstraint()->adjust(0) == 1);
02122                 CPPUNIT_ASSERT_EQUAL(true, builder.endProgram());
02123         }
02124 private:
02125         typedef SharedDependencyGraph DG;
02126         SharedContext ctx;
02127         LogicProgram  builder;
02128         stringstream  str;
02129 };
02130 
02131 class SatBuilderTest : public CppUnit::TestFixture {
02132         CPPUNIT_TEST_SUITE(SatBuilderTest);
02133         CPPUNIT_TEST(testPrepare);
02134         CPPUNIT_TEST(testNoClauses);
02135         CPPUNIT_TEST(testAddClause);
02136         CPPUNIT_TEST(testAddSoftClause);
02137         CPPUNIT_TEST(testAddConflicting);
02138         CPPUNIT_TEST_SUITE_END();
02139 public:
02140         void setUp() {
02141                 builder.startProgram(ctx);
02142         }
02143         void testPrepare() {
02144                 builder.prepareProblem(10);
02145                 builder.endProgram();
02146                 CPPUNIT_ASSERT(ctx.numVars() == 10);
02147         }
02148         void testNoClauses() {
02149                 builder.prepareProblem(2);
02150                 builder.endProgram();
02151                 CPPUNIT_ASSERT(ctx.master()->numFreeVars() == 0);
02152         }
02153         void testAddClause() {
02154                 builder.prepareProblem(2);
02155                 LitVec clause; clause.push_back(posLit(1)); clause.push_back(posLit(2));
02156                 builder.addClause(clause);
02157                 builder.endProgram();
02158                 CPPUNIT_ASSERT(ctx.numConstraints() == 1);
02159                 CPPUNIT_ASSERT(!builder.getMinimizeConstraint());
02160         }
02161         void testAddSoftClause() {
02162                 builder.prepareProblem(3);
02163                 LitVec clause;
02164                 clause.push_back(posLit(1));
02165                 builder.addClause(clause, 1);
02166                 clause.clear();
02167                 clause.push_back(negLit(1));
02168                 clause.push_back(posLit(2));
02169                 clause.push_back(negLit(3));
02170                 builder.addClause(clause, 2);
02171                 builder.endProgram();
02172                 CPPUNIT_ASSERT(ctx.numConstraints() == 1);
02173                 CPPUNIT_ASSERT(builder.getMinimizeConstraint()->numRules() == 1);
02174                 CPPUNIT_ASSERT(ctx.numVars() > 3);
02175         }
02176         void testAddConflicting() {
02177                 builder.prepareProblem(3);
02178                 LitVec clause;
02179                 clause.push_back(posLit(1));
02180                 CPPUNIT_ASSERT(builder.addClause(clause));
02181                 clause.clear();
02182                 clause.push_back(negLit(1));
02183                 CPPUNIT_ASSERT(builder.addClause(clause) == false);
02184                 clause.clear();
02185                 clause.push_back(posLit(2));
02186                 clause.push_back(posLit(3));
02187                 CPPUNIT_ASSERT(builder.addClause(clause) == false);
02188                 CPPUNIT_ASSERT(builder.endProgram() == false);
02189                 CPPUNIT_ASSERT(ctx.ok() == false);
02190         }
02191 private:
02192         SharedContext ctx;
02193         SatBuilder    builder;
02194 };
02195 
02196 class PBBuilderTest : public CppUnit::TestFixture {
02197         CPPUNIT_TEST_SUITE(PBBuilderTest);
02198         CPPUNIT_TEST(testPrepare);
02199         CPPUNIT_TEST(testNegativeWeight);
02200         CPPUNIT_TEST(testProduct);
02201         CPPUNIT_TEST(testProductTrue);
02202         CPPUNIT_TEST(testProductFalse);
02203         CPPUNIT_TEST_SUITE_END();
02204 public:
02205         void setUp() {
02206                 builder.startProgram(ctx);
02207         }
02208         void testPrepare() {
02209                 builder.prepareProblem(10, 0, 0);
02210                 builder.endProgram();
02211                 CPPUNIT_ASSERT(ctx.numVars() == 10);
02212         }
02213         void testNegativeWeight() {
02214                 builder.prepareProblem(5, 0, 0);
02215                 WeightLitVec con;
02216                 con.push_back(WeightLiteral(posLit(1), 2));
02217                 con.push_back(WeightLiteral(posLit(2), -2));
02218                 con.push_back(WeightLiteral(posLit(3), -1));
02219                 con.push_back(WeightLiteral(posLit(4), 1));
02220                 con.push_back(WeightLiteral(posLit(5), 1));
02221                 builder.addConstraint(con, 2);
02222                 builder.endProgram();
02223                 CPPUNIT_ASSERT(ctx.numConstraints() == 1);
02224                 CPPUNIT_ASSERT(ctx.master()->numAssignedVars() == 0);
02225                 ctx.master()->assume(negLit(1)) && ctx.master()->propagate();
02226                 CPPUNIT_ASSERT(ctx.master()->numFreeVars() == 0);
02227         }
02228         void testProduct() {
02229                 builder.prepareProblem(3, 1, 1);
02230                 LitVec p1(3), p2;
02231                 p1[0] = posLit(1);
02232                 p1[1] = posLit(2);
02233                 p1[2] = posLit(3);
02234                 p2    = p1;
02235                 Literal x = builder.addProduct(p1);
02236                 Literal y = builder.addProduct(p2);
02237                 CPPUNIT_ASSERT(x.var() == 4 && x == y);
02238         }
02239         void testProductTrue() {
02240                 builder.prepareProblem(3, 1, 1);
02241                 LitVec p1(3);
02242                 p1[0] = posLit(1);
02243                 p1[1] = posLit(2);
02244                 p1[2] = posLit(3);
02245                 ctx.master()->force(posLit(1), 0);
02246                 ctx.master()->force(posLit(2), 0);
02247                 ctx.master()->force(posLit(3), 0);
02248                 Literal x = builder.addProduct(p1);
02249                 CPPUNIT_ASSERT(x == posLit(0));
02250         }
02251         void testProductFalse() {
02252                 builder.prepareProblem(3, 1, 1);
02253                 LitVec p1(3);
02254                 p1[0] = posLit(1);
02255                 p1[1] = posLit(2);
02256                 p1[2] = posLit(3);
02257                 ctx.master()->force(negLit(2), 0);
02258                 Literal x = builder.addProduct(p1);
02259                 CPPUNIT_ASSERT(x == negLit(0));
02260         }
02261 private:
02262         SharedContext ctx;
02263         PBBuilder     builder;
02264 };
02265 CPPUNIT_TEST_SUITE_REGISTRATION(LogicProgramTest);
02266 CPPUNIT_TEST_SUITE_REGISTRATION(SatBuilderTest);
02267 CPPUNIT_TEST_SUITE_REGISTRATION(PBBuilderTest);
02268  } } 


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