-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdriver.cpp
117 lines (109 loc) · 4.53 KB
/
driver.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
// ----------------------------------------------------------------------------
// Implementation file for the driver class. driver.cpp
// Created by Ferhat Erata <[email protected]> on November 26, 2019.
// Copyright (c) 2019 Yale University. All rights reserved.
// -----------------------------------------------------------------------------
#include "driver.hpp"
#include "tools.hpp"
#include <utility>
using namespace microsat;
// -----------------------------------------------------------------------------
//
driver::driver(std::string file, bool stats)
: filename(std::move(file)), stats(stats) {
if (parse() == UNSAT) {
std::cout << "unsat";
}
// Solve without limit (number of conflicts)
else if (solver->solve() == UNSAT) {
std::cout << "unsat";
}
// And print whether the formula has a solution
else {
std::cout << "sat ";
for (int i = 1; i <= solver->nVars; i++) {
if (solver->model[i])
std::cout << i << " ";
else
std::cout << "-" << i << " ";
}
std::cout << "\n";
}
// Print the statistics
if (stats)
std::cout << "statistics of " << filename << ":\n"
<< "[ mem_used: " << solver->mem_used()
<< ", conflicts: " << solver->nConflicts
<< ", lemmas: " << solver->nLemmas
<< ", max_lemmas: " << solver->maxLemmas << " ]\n";
P("c--------------------------------------------------------------\n"
<< "c statistics of " << filename << ":\n"
<< "c [ mem_used: " << solver->mem_used() << ", conflicts: "
<< solver->nConflicts << ", lemmas: " << solver->nLemmas
<< ", max_lemmas: " << solver->maxLemmas << " ]");
}
// -----------------------------------------------------------------------------
// Parse the DIMACS file
int driver::parse() {
std::ifstream in(filename);
if (in) { // checks if the file is open
string line;
while (!in.eof()) {
getline(in, line);
if (line.length() == 0 || line[0] == 'c') {
continue;
} else if (line[0] == 'p') {
std::size_t pos = line.find("cnf", 0);
if (pos != std::string::npos) {
std::string str = line.substr(pos + 4, line.length());
int nVars, nClauses;
std::istringstream ss(str);
if (!(ss >> nVars >> nClauses)) // extract vars and clausesS
throw Fatal("can't extract nVars and nClauses!");
P("c p cnf " << nVars << " " << nClauses);
// late binding of the solver
solver = std::make_unique<Solver>(nVars, nClauses);
}
} else {
std::istringstream ss(line);
auto& s = *solver;
int size = 0, literal = 0;
P("c ");
do { // for each clause in the file
if (ss >> literal) { // !in.fail()
if (literal == 0)
break;
s.buffer[size++] = literal;
P(literal << " ");
}
} while (ss.good());
P("\n");
if (!ss.eof())
throw Fatal(
"I/O error or bad data during clause extraction");
// reached the end of the clause; add the clause to database
int* clause = s.addClause(s.buffer, size, 1);
// Check for empty clause or conflicting unit
// If either is found return UNSAT
if (!size || ((size == 1) && s.false_[clause[0]]))
return UNSAT; //
// Check for a new unit
if ((size == 1) && !s.false_[-clause[0]]) {
s.assign(clause, 1);
} // Directly assign new units (forced = 1)
} // Reset buffer
}
} // End While
in.close();
return SAT; // Return that no conflict was observed
}
// -----------------------------------------------------------------------------
// driver instructions
void driver::instructions() {
std::cout << "\nUsage: microsat++ <options>"
"\n\nOption(s):\n"
"\t-h,--help\tShow this help message\n"
"\t-f <file>\tDIMACS cnf file\n"
"\t-s,--stats\tPrint statistics\n"
<< std::endl;
}