First C++ code written... I think it\'s quite efficient with all the test set included in path data.
The simplest data set looks like:
-1 -3 0 -1 -5 0 -3 -5 0 -2 -4 0 -2 -6 0 -4 -6 0 1 2 0 3 4 0 5 6 0
used vector saving clauses and map saving assignments.
the main recursive function looks like following:
/*
1. If the set of clauses is empty, it returns true
2. Otherwise, if the set of clauses contains an empty clause, it returns false
3. Otherwise, if there is a unit clause, it applies unit propagation and then calls itself recursively
4. Otherwise, if there is a pure literal, it applies the pure literal rule and then calls itself
recursively
5. Otherwise, it applies either the resolution rule or the splitting rule and calls itself recursively
*/
Find the attached zip folder. I have referred this code example in my project. It will solve your
problem.
Implement following code :
clause.cpp
#include
#include \"clause.h\"
using namespace std;
using namespace Sat;
void Clause::readClause(istream& is)
{
static int lit = 0;
if (lit != 0) addLiteral(lit);
while (!is.eof()) {
is >> lit;
if (lit == 0) break;
addLiteral(lit);
}
is >> lit;
}
void Clause::dumpClause() const
{
int i;
cout << \"(\";
for (i = 0; i < numLits() - 1; ++i) {
cout << getLit(i) << \", \";
}
if (numLits() != 0) {
cout << getLit(i);
}
cout << \")\" << endl;
}
Clause_impl.cpp
#include
#include
#include \"clause.h\"
#include \"clause_impl.h\"
using namespace std;
using namespace Sat;
//size_t ClauseImpl::clause_num = 0;
// Add a literal to the clause
void ClauseImpl::addLiteral(int lit){
add_lits(lit);
}
// Get the largest variable in the clause
int ClauseImpl::maxVar() const{
int max = -1;
for (int i = 0; i < lits.size(); ++ i) {
if(max < abs(lits[i]))
max = abs(lits[i]);
}
return max;
}
// Get the number of variables in the clause
int ClauseImpl::numLits() const{
return lits.size();
}
// Get the i^th literal in the clause
int ClauseImpl::getLit(int i) const{
return lits.at(i) ;
}
vector ClauseImpl::get_lits() const {return lits;}
void ClauseImpl::add_lits(int lit) {
lits.push_back(lit);
}
bool ClauseImpl::hasLit(int a) const {
for (int i = 0; i < lits.size(); ++ i) {
if (lits[i] == a) {
return true;
}
}
return false;
}
debug.cpp
#include
#include \"debug.h\"
using namespace std;
namespace DebugUtil {
ostream& operator<<(ostream& os, const Exception& e)
{
return os << e.toString();
}
void assertError(const string& file, int line,
const string& cond)
{
ostringstream ss;
ss << \"in \" << file << \":\" << line << \" (\" << cond << \")\ \";
throw Exception(ss.str());
}
} // end of namespace DebugUtil
formula.cpp
#include \"debug.h\"
#include \"clause.h\"
#include \"formula.h\"
using namespace std;
using namespace Sat;
void Formula::readClauses(istream& is)
{
while (!is.eof()) {
Clause& c = addClause();
c.readClause(is);
int tmp = c.maxVar();
if (tmp > maxVar) maxVar = tmp;
}
}
void Formula::dumpClauses()
{
for (int i = 0; i < numClauses(); ++i) {
getClause(i).dumpClause();
}
}
solver.cp.
First C++ code written... I think its quite efficient with all the.pdf
1. First C++ code written... I think it's quite efficient with all the test set included in path data.
The simplest data set looks like:
-1 -3 0 -1 -5 0 -3 -5 0 -2 -4 0 -2 -6 0 -4 -6 0 1 2 0 3 4 0 5 6 0
used vector saving clauses and map saving assignments.
the main recursive function looks like following:
/*
1. If the set of clauses is empty, it returns true
2. Otherwise, if the set of clauses contains an empty clause, it returns false
3. Otherwise, if there is a unit clause, it applies unit propagation and then calls itself recursively
4. Otherwise, if there is a pure literal, it applies the pure literal rule and then calls itself
recursively
5. Otherwise, it applies either the resolution rule or the splitting rule and calls itself recursively
*/
Find the attached zip folder. I have referred this code example in my project. It will solve your
problem.
Implement following code :
clause.cpp
#include
#include "clause.h"
using namespace std;
using namespace Sat;
void Clause::readClause(istream& is)
{
static int lit = 0;
if (lit != 0) addLiteral(lit);
while (!is.eof()) {
is >> lit;
if (lit == 0) break;
addLiteral(lit);
}
is >> lit;
2. }
void Clause::dumpClause() const
{
int i;
cout << "(";
for (i = 0; i < numLits() - 1; ++i) {
cout << getLit(i) << ", ";
}
if (numLits() != 0) {
cout << getLit(i);
}
cout << ")" << endl;
}
Clause_impl.cpp
#include
#include
#include "clause.h"
#include "clause_impl.h"
using namespace std;
using namespace Sat;
//size_t ClauseImpl::clause_num = 0;
// Add a literal to the clause
void ClauseImpl::addLiteral(int lit){
add_lits(lit);
}
// Get the largest variable in the clause
int ClauseImpl::maxVar() const{
int max = -1;
for (int i = 0; i < lits.size(); ++ i) {
if(max < abs(lits[i]))
max = abs(lits[i]);
}
return max;
}
3. // Get the number of variables in the clause
int ClauseImpl::numLits() const{
return lits.size();
}
// Get the i^th literal in the clause
int ClauseImpl::getLit(int i) const{
return lits.at(i) ;
}
vector ClauseImpl::get_lits() const {return lits;}
void ClauseImpl::add_lits(int lit) {
lits.push_back(lit);
}
bool ClauseImpl::hasLit(int a) const {
for (int i = 0; i < lits.size(); ++ i) {
if (lits[i] == a) {
return true;
}
}
return false;
}
debug.cpp
#include
#include "debug.h"
using namespace std;
namespace DebugUtil {
ostream& operator<<(ostream& os, const Exception& e)
{
return os << e.toString();
}
void assertError(const string& file, int line,
const string& cond)
{
ostringstream ss;
4. ss << "in " << file << ":" << line << " (" << cond << ") ";
throw Exception(ss.str());
}
} // end of namespace DebugUtil
formula.cpp
#include "debug.h"
#include "clause.h"
#include "formula.h"
using namespace std;
using namespace Sat;
void Formula::readClauses(istream& is)
{
while (!is.eof()) {
Clause& c = addClause();
c.readClause(is);
int tmp = c.maxVar();
if (tmp > maxVar) maxVar = tmp;
}
}
void Formula::dumpClauses()
{
for (int i = 0; i < numClauses(); ++i) {
getClause(i).dumpClause();
}
}
solver.cpp
#include "solver.h"
using namespace std;
using namespace Sat;
bool Solver::solve(FormulaImpl &f) {
//vector p = findPure(f);
//pureLit(f,p);
5. //int uni = getUnitProp(f.getClauses());
//unitProp(f, uni);
//return true;
return splitting (f);
}
/*
1. If the set of clauses is empty, it returns true
2. Otherwise, if the set of clauses contains an empty clause, it returns false
3. Otherwise, if there is a unit clause, it applies unit propagation and then calls itself recursively
4. Otherwise, if there is a pure literal, it applies the pure literal rule and then calls itself
recursively
5. Otherwise, it applies either the resolution rule or the splitting rule and calls itself recursively
*/
bool Solver::splitting (FormulaImpl &f) {
FormulaImpl c (f);
pair temp;
// condition 1
if (c.getClauses().size() == 0)
return true;
// condition 2
for (int i = 0; i < c.getClauses().size(); ++ i) {
if (c.getClause(i).numLits() == 0)
return false;
}
int uni = getUnitProp (c.getClauses());
// condition 3
if (uni != 0) {
temp = make_pair(uni, true);
assgn.insert(temp);
return splitting (unitProp(c, uni));
}
// condition 4
else {
vector p = getPure(c);
if (p.size() != 0) {
for(int i = 0; i < p.size(); ++ i) {
6. temp = make_pair(p[i], true);
assgn.insert(temp);
}
return splitting (pureLit(c, p));
}
// condition 5
else {
int firstLit = c.getClause(0).getLit(0);
temp = make_pair(firstLit, true);
assgn.insert (temp);
if (splitting (unitProp(c, firstLit)) == true)
return true;
else {
assgn.erase(firstLit);
temp = make_pair(firstLit, false);
assgn.insert (temp);
return splitting (unitProp(f, -firstLit));
}
}
}
}
/*
a literal and a list of clauses;
returns a new list of clauses resulting from applying the pure literal rule with the given literal.
*/
FormulaImpl& Solver::unitProp(FormulaImpl &f, int uni) {
vector lits;
while (uni != 0) {
pair temp;
temp = make_pair(uni, true);
assgn.insert(temp);
vector::iterator it;
for (it = f.clauses.begin(); it != f.clauses.end();) {
bool flag = false;
7. vector::iterator jt;
for (jt = it->lits.begin(); jt != it->lits.end(); ) {
if ((*jt) == -uni) {
jt = it->lits.erase(jt);
break;
}
else if ((*jt) == uni){
flag = true;
break;
} else {
++ jt;
}
}
if(flag == false)
++ it;
else {
//it->clearLits();
it = f.clauses.erase(it);
}
}
uni = getUnitProp (f.getClauses());
}
//f.setClauses (f.clauses);
return f;
}
int Solver::getUnitProp (vector& c) const {
for (int i = 0; i < c.size(); ++i) {
if(c[i].get_lits().size() == 1) {
return c[i].getLit(0);
}
}
return 0;
}
/*
if it creates a clause that contains both a variable and its negation, filter the clause out
*/
8. FormulaImpl& Solver::pureLit(FormulaImpl &f, vector p) {
vector::iterator it;
for (int i = 0; i < p.size(); ++ i) {
for (it = f.clauses.begin(); it != f.clauses.end();) {
if (it->hasLit(p[i])) {
pair temp;
temp = make_pair(p[i], true);
assgn.insert(temp);
it = f.clauses.erase(it);
} else {
++ it;
}
}
}
return f;
}
vector Solver::getPure (FormulaImpl &f) {
map litTable;
vector p;
vector::iterator it;
for (it = f.clauses.begin(); it != f.clauses.end(); ++it) {
vector::iterator jt;
for (jt = it->lits.begin(); jt != it->lits.end(); ++jt) {
if (litTable.find(abs(*jt))==litTable.end()) {
if (*jt < 0)
litTable.insert(pair(abs(*jt), -1));
else
litTable.insert(pair(abs(*jt), 1));
}
else {
if (litTable.find(abs(*jt))->second == -1 && *jt > 0) {
litTable.erase(*jt);
litTable.insert(pair(abs(*jt), 0));
} else if (litTable.find(abs(*jt))->second == 1 && *jt < 0) {
litTable.erase(abs(*jt));
litTable.insert(pair(abs(*jt),0));
9. }
}
}
}
map::iterator kt;
int lit;
for(kt = litTable.begin(); kt != litTable.end(); ++kt) {
if (kt->second != 0) {
lit = (kt->first) * (kt->second);
p.push_back(lit);
}
}
return p;
}
formula_imp.cpp
#include "debug.h"
#include "clause.h"
#include "clause_impl.h"
#include "formula.h"
#include "formula_impl.h"
using namespace std;
using namespace Sat;
// Add a new Clause to the Formula
// Return a reference to the new clause
Clause& FormulaImpl::addClause() {
ClauseImpl c;
clauses.push_back(c);
return clauses.back();
}
// Get the number of clauses
int FormulaImpl::numClauses() const {
return clauses.size();
}
// Get the i^th clause in the formula
10. Clause& FormulaImpl::getClause(int i) {
return clauses.at(i);
}
sat.cpp
#include
#include "debug.h"
#include "formula_impl.h"
#include "solver.h"
using namespace std;
using namespace Sat;
int main(int argc, char **argv)
{
if (argc != 2) {
cout << "Expected filename" << endl;
return 0;
}
istream* is = new ifstream(*(argv+1));
if (!(*is)) {
cout << "File not found" << endl;
return 0;
}
FormulaImpl f;
f.readClauses(*is);
Assert(f.numClauses() > 0);
f.dumpClauses();
Solver sat;
if (sat.solve(f)) {
cout << "Satisfiable" << endl;
}
else {
cout << "Unsatisfiable" << endl;
}
11. return 0;
}
This will help. Please import necessary files. I am not able to upload zip files.
Try this sample. If you find any difficulty please let me know.
Solution
First C++ code written... I think it's quite efficient with all the test set included in path data.
The simplest data set looks like:
-1 -3 0 -1 -5 0 -3 -5 0 -2 -4 0 -2 -6 0 -4 -6 0 1 2 0 3 4 0 5 6 0
used vector saving clauses and map saving assignments.
the main recursive function looks like following:
/*
1. If the set of clauses is empty, it returns true
2. Otherwise, if the set of clauses contains an empty clause, it returns false
3. Otherwise, if there is a unit clause, it applies unit propagation and then calls itself recursively
4. Otherwise, if there is a pure literal, it applies the pure literal rule and then calls itself
recursively
5. Otherwise, it applies either the resolution rule or the splitting rule and calls itself recursively
*/
Find the attached zip folder. I have referred this code example in my project. It will solve your
problem.
Implement following code :
clause.cpp
#include
#include "clause.h"
using namespace std;
using namespace Sat;
void Clause::readClause(istream& is)
{
static int lit = 0;
if (lit != 0) addLiteral(lit);
12. while (!is.eof()) {
is >> lit;
if (lit == 0) break;
addLiteral(lit);
}
is >> lit;
}
void Clause::dumpClause() const
{
int i;
cout << "(";
for (i = 0; i < numLits() - 1; ++i) {
cout << getLit(i) << ", ";
}
if (numLits() != 0) {
cout << getLit(i);
}
cout << ")" << endl;
}
Clause_impl.cpp
#include
#include
#include "clause.h"
#include "clause_impl.h"
using namespace std;
using namespace Sat;
//size_t ClauseImpl::clause_num = 0;
// Add a literal to the clause
void ClauseImpl::addLiteral(int lit){
add_lits(lit);
}
// Get the largest variable in the clause
int ClauseImpl::maxVar() const{
int max = -1;
13. for (int i = 0; i < lits.size(); ++ i) {
if(max < abs(lits[i]))
max = abs(lits[i]);
}
return max;
}
// Get the number of variables in the clause
int ClauseImpl::numLits() const{
return lits.size();
}
// Get the i^th literal in the clause
int ClauseImpl::getLit(int i) const{
return lits.at(i) ;
}
vector ClauseImpl::get_lits() const {return lits;}
void ClauseImpl::add_lits(int lit) {
lits.push_back(lit);
}
bool ClauseImpl::hasLit(int a) const {
for (int i = 0; i < lits.size(); ++ i) {
if (lits[i] == a) {
return true;
}
}
return false;
}
debug.cpp
#include
#include "debug.h"
using namespace std;
namespace DebugUtil {
ostream& operator<<(ostream& os, const Exception& e)
{
return os << e.toString();
14. }
void assertError(const string& file, int line,
const string& cond)
{
ostringstream ss;
ss << "in " << file << ":" << line << " (" << cond << ") ";
throw Exception(ss.str());
}
} // end of namespace DebugUtil
formula.cpp
#include "debug.h"
#include "clause.h"
#include "formula.h"
using namespace std;
using namespace Sat;
void Formula::readClauses(istream& is)
{
while (!is.eof()) {
Clause& c = addClause();
c.readClause(is);
int tmp = c.maxVar();
if (tmp > maxVar) maxVar = tmp;
}
}
void Formula::dumpClauses()
{
for (int i = 0; i < numClauses(); ++i) {
getClause(i).dumpClause();
}
}
solver.cpp
#include "solver.h"
15. using namespace std;
using namespace Sat;
bool Solver::solve(FormulaImpl &f) {
//vector p = findPure(f);
//pureLit(f,p);
//int uni = getUnitProp(f.getClauses());
//unitProp(f, uni);
//return true;
return splitting (f);
}
/*
1. If the set of clauses is empty, it returns true
2. Otherwise, if the set of clauses contains an empty clause, it returns false
3. Otherwise, if there is a unit clause, it applies unit propagation and then calls itself recursively
4. Otherwise, if there is a pure literal, it applies the pure literal rule and then calls itself
recursively
5. Otherwise, it applies either the resolution rule or the splitting rule and calls itself recursively
*/
bool Solver::splitting (FormulaImpl &f) {
FormulaImpl c (f);
pair temp;
// condition 1
if (c.getClauses().size() == 0)
return true;
// condition 2
for (int i = 0; i < c.getClauses().size(); ++ i) {
if (c.getClause(i).numLits() == 0)
return false;
}
int uni = getUnitProp (c.getClauses());
// condition 3
if (uni != 0) {
temp = make_pair(uni, true);
assgn.insert(temp);
return splitting (unitProp(c, uni));
16. }
// condition 4
else {
vector p = getPure(c);
if (p.size() != 0) {
for(int i = 0; i < p.size(); ++ i) {
temp = make_pair(p[i], true);
assgn.insert(temp);
}
return splitting (pureLit(c, p));
}
// condition 5
else {
int firstLit = c.getClause(0).getLit(0);
temp = make_pair(firstLit, true);
assgn.insert (temp);
if (splitting (unitProp(c, firstLit)) == true)
return true;
else {
assgn.erase(firstLit);
temp = make_pair(firstLit, false);
assgn.insert (temp);
return splitting (unitProp(f, -firstLit));
}
}
}
}
/*
a literal and a list of clauses;
returns a new list of clauses resulting from applying the pure literal rule with the given literal.
*/
FormulaImpl& Solver::unitProp(FormulaImpl &f, int uni) {
vector lits;
while (uni != 0) {
pair temp;
17. temp = make_pair(uni, true);
assgn.insert(temp);
vector::iterator it;
for (it = f.clauses.begin(); it != f.clauses.end();) {
bool flag = false;
vector::iterator jt;
for (jt = it->lits.begin(); jt != it->lits.end(); ) {
if ((*jt) == -uni) {
jt = it->lits.erase(jt);
break;
}
else if ((*jt) == uni){
flag = true;
break;
} else {
++ jt;
}
}
if(flag == false)
++ it;
else {
//it->clearLits();
it = f.clauses.erase(it);
}
}
uni = getUnitProp (f.getClauses());
}
//f.setClauses (f.clauses);
return f;
}
int Solver::getUnitProp (vector& c) const {
for (int i = 0; i < c.size(); ++i) {
if(c[i].get_lits().size() == 1) {
return c[i].getLit(0);
}
18. }
return 0;
}
/*
if it creates a clause that contains both a variable and its negation, filter the clause out
*/
FormulaImpl& Solver::pureLit(FormulaImpl &f, vector p) {
vector::iterator it;
for (int i = 0; i < p.size(); ++ i) {
for (it = f.clauses.begin(); it != f.clauses.end();) {
if (it->hasLit(p[i])) {
pair temp;
temp = make_pair(p[i], true);
assgn.insert(temp);
it = f.clauses.erase(it);
} else {
++ it;
}
}
}
return f;
}
vector Solver::getPure (FormulaImpl &f) {
map litTable;
vector p;
vector::iterator it;
for (it = f.clauses.begin(); it != f.clauses.end(); ++it) {
vector::iterator jt;
for (jt = it->lits.begin(); jt != it->lits.end(); ++jt) {
if (litTable.find(abs(*jt))==litTable.end()) {
if (*jt < 0)
litTable.insert(pair(abs(*jt), -1));
else
litTable.insert(pair(abs(*jt), 1));
}
else {
19. if (litTable.find(abs(*jt))->second == -1 && *jt > 0) {
litTable.erase(*jt);
litTable.insert(pair(abs(*jt), 0));
} else if (litTable.find(abs(*jt))->second == 1 && *jt < 0) {
litTable.erase(abs(*jt));
litTable.insert(pair(abs(*jt),0));
}
}
}
}
map::iterator kt;
int lit;
for(kt = litTable.begin(); kt != litTable.end(); ++kt) {
if (kt->second != 0) {
lit = (kt->first) * (kt->second);
p.push_back(lit);
}
}
return p;
}
formula_imp.cpp
#include "debug.h"
#include "clause.h"
#include "clause_impl.h"
#include "formula.h"
#include "formula_impl.h"
using namespace std;
using namespace Sat;
// Add a new Clause to the Formula
// Return a reference to the new clause
Clause& FormulaImpl::addClause() {
ClauseImpl c;
clauses.push_back(c);
return clauses.back();
20. }
// Get the number of clauses
int FormulaImpl::numClauses() const {
return clauses.size();
}
// Get the i^th clause in the formula
Clause& FormulaImpl::getClause(int i) {
return clauses.at(i);
}
sat.cpp
#include
#include "debug.h"
#include "formula_impl.h"
#include "solver.h"
using namespace std;
using namespace Sat;
int main(int argc, char **argv)
{
if (argc != 2) {
cout << "Expected filename" << endl;
return 0;
}
istream* is = new ifstream(*(argv+1));
if (!(*is)) {
cout << "File not found" << endl;
return 0;
}
FormulaImpl f;
f.readClauses(*is);
Assert(f.numClauses() > 0);
f.dumpClauses();
Solver sat;
if (sat.solve(f)) {
21. cout << "Satisfiable" << endl;
}
else {
cout << "Unsatisfiable" << endl;
}
return 0;
}
This will help. Please import necessary files. I am not able to upload zip files.
Try this sample. If you find any difficulty please let me know.