Skip to content

Commit

Permalink
Fix issue #18
Browse files Browse the repository at this point in the history
 * External atoms and assumptions must be marked as exempt
   from variable elimination.

 * Additionally simplify output of externals - only print
   those externals that are still external after preprocessing.
  • Loading branch information
BenKaufmann committed Jan 10, 2018
1 parent 9f3fc82 commit e824750
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 0 deletions.
1 change: 1 addition & 0 deletions clasp/logic_program.h
Original file line number Diff line number Diff line change
Expand Up @@ -581,6 +581,7 @@ class LogicProgram : public ProgramBuilder {
bool addConstraints();
void addAcycConstraint();
void addDomRules();
void freezeAssumptions();
// ------------------------------------------------------------------------
void deleteAtoms(uint32 start);
PrgAtom* getTrueAtom() const { return atoms_[0]; }
Expand Down
13 changes: 13 additions & 0 deletions src/logic_program.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1040,6 +1040,7 @@ void LogicProgram::prepareExternals() {
*j++ = encodeExternal(id, value);
}
}
external.erase(j, external.end());
for (VarVec::const_iterator it = external.begin(), end = external.end(); it != end; ++it) {
atomState_.clearRule(decodeExternal(*it).first);
}
Expand Down Expand Up @@ -1143,6 +1144,7 @@ void LogicProgram::prepareProgram(bool checkSccs) {
finalizeDisjunctions(p, sccs);
prepareComponents();
prepareOutputTable();
freezeAssumptions();
if (incData_ && options().distTrue) {
for (Var a = startAtom(), end = startAuxAtom(); a != end; ++a) {
if (isSentinel(getRootAtom(a)->literal())) {
Expand Down Expand Up @@ -1407,6 +1409,17 @@ void LogicProgram::prepareOutputTable() {
}
}
}

// Make assumptions/externals exempt from sat-preprocessing
void LogicProgram::freezeAssumptions() {
for (VarVec::const_iterator it = frozen_.begin(), end = frozen_.end(); it != end; ++it) {
ctx()->setFrozen(getRootAtom(*it)->var(), true);
}
for (Potassco::LitVec::const_iterator it = auxData_->assume.begin(), end = auxData_->assume.end(); it != end; ++it) {
ctx()->setFrozen(getLiteral(Potassco::id(*it)).var(), true);
}
}

// add (completion) nogoods
bool LogicProgram::addConstraints() {
ClauseCreator gc(ctx()->master());
Expand Down
43 changes: 43 additions & 0 deletions tests/program_builder_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -757,6 +757,14 @@ TEST_CASE("Logic program", "[asp]") {
REQUIRE(ctx.varInfo(lp.getLiteral(g).var()).frozen());
}

SECTION("testExternalsAreFrozen") {
lpAdd(lp.start(ctx),
"#external a.\n");
REQUIRE(lp.endProgram());
REQUIRE(lp.getLiteral(a).var() == 1);
REQUIRE(ctx.varInfo(lp.getLiteral(a).var()).frozen());
}

SECTION("testComputeTrueBug") {
lpAdd(lp.start(ctx),
"a :- not b.\n"
Expand Down Expand Up @@ -1956,6 +1964,32 @@ TEST_CASE("Incremental logic program", "[asp]") {
}
REQUIRE((!foundA && foundB));
}

SECTION("testWriteExternalBug") {
lp.start(ctx);
lp.updateProgram();
lpAdd(lp,
"#external a."
"#external b."
"#external c."
"#external d."
"b.");
lp.endProgram();
std::stringstream str;
AspParser::write(lp, str, AspParser::format_aspif);
int foundA = 0, foundB = 0, foundC = 0, foundD = 0;
for (std::string x; std::getline(str, x);) {
if (x.find("5 1 2") == 0) { ++foundA; }
if (x.find("5 2 2") == 0) { ++foundB; }
if (x.find("5 3 2") == 0) { ++foundC; }
if (x.find("5 4 2") == 0) { ++foundD; }
}
REQUIRE(foundA == 1);
REQUIRE(foundB == 0);
REQUIRE(foundC == 1);
REQUIRE(foundD == 1);
}

SECTION("testWriteUnfreeze") {
lp.start(ctx);
lp.updateProgram();
Expand Down Expand Up @@ -2046,6 +2080,7 @@ TEST_CASE("Incremental logic program", "[asp]") {
lp.endProgram();
REQUIRE_FALSE(lp.isExternal(a));
}

SECTION("testAssumptionsAreVolatile") {
lp.start(ctx);
lp.updateProgram();
Expand All @@ -2061,6 +2096,14 @@ TEST_CASE("Incremental logic program", "[asp]") {
lp.getAssumptions(assume);
REQUIRE((assume.size() == 1 && assume[0] == ~lp.getLiteral(a)));
}

SECTION("testAssumptionsAreFrozen") {
lpAdd(lp.start(ctx), "{a}. #assume{a}.");
REQUIRE(lp.endProgram());
REQUIRE(lp.getLiteral(a).var() == 1);
REQUIRE(ctx.varInfo(lp.getLiteral(a).var()).frozen());
}

SECTION("testProjectionIsExplicitAndCumulative") {
lp.start(ctx);
lp.updateProgram();
Expand Down

0 comments on commit e824750

Please sign in to comment.