This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
yap-6.3/packages/bee/cryptominisat-2.5.1/Solver/Main.C
Vitor Santos Costa 16015bd8e6 bee
2019-04-22 12:15:21 +01:00

879 lines
35 KiB
C
Executable File

/******************************************************************************************[Main.C]
MiniSat -- Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
CryptoMiniSat -- Copyright (c) 2009 Mate Soos
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************************************/
#include <ctime>
#include <cstring>
#include <errno.h>
#include <string.h>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <vector>
#ifdef _MSC_VER
#include <msvc/stdint.h>
#else
#include <stdint.h>
#endif //_MSC_VER
#include <signal.h>
#ifndef DISABLE_ZLIB
#include <zlib.h>
#endif // DISABLE_ZLIB
#include "Logger.h"
#include "Solver.h"
#include "time_mem.h"
#include "constants.h"
using std::cout;
using std::endl;
/*************************************************************************************/
#if defined(__linux__)
#include <fpu_control.h>
#endif
static bool grouping = false;
static bool debugLib = false;
static bool debugNewVar = false;
static char learnts_filename[500];
static bool dumpLearnts = false;
static uint32_t maxLearntsSize = std::numeric_limits<uint32_t>::max();
static bool printResult = true;
//=================================================================================================
// DIMACS Parser:
#define CHUNK_LIMIT 1048576
#define MAX_NAMES_SIZE 1000
class StreamBuffer
{
#ifdef DISABLE_ZLIB
FILE * in;
#else
gzFile in;
#endif // DISABLE_ZLIB
char buf[CHUNK_LIMIT];
int pos;
int size;
void assureLookahead() {
if (pos >= size) {
pos = 0;
#ifdef DISABLE_ZLIB
#ifdef VERBOSE_DEBUG
printf("buf = %08X\n", buf);
printf("sizeof(buf) = %u\n", sizeof(buf));
#endif //VERBOSE_DEBUG
size = fread(buf, 1, sizeof(buf), in);
#else
size = gzread(in, buf, sizeof(buf));
#endif // DISABLE_ZLIB
}
}
public:
#ifdef DISABLE_ZLIB
StreamBuffer(FILE * i) : in(i), pos(0), size(0) {
#else
StreamBuffer(gzFile i) : in(i), pos(0), size(0) {
#endif // DISABLE_ZLIB
assureLookahead();
}
int operator * () {
return (pos >= size) ? EOF : buf[pos];
}
void operator ++ () {
pos++;
assureLookahead();
}
};
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<class B>
static void skipWhitespace(B& in)
{
while ((*in >= 9 && *in <= 13) || *in == 32)
++in;
}
template<class B>
static void skipLine(B& in)
{
for (;;) {
if (*in == EOF || *in == '\0') return;
if (*in == '\n') {
++in;
return;
}
++in;
}
}
template<class B>
static void untilEnd(B& in, char* ret)
{
uint32_t sizeRead = 0;
for (;sizeRead < MAX_NAMES_SIZE-1; sizeRead++) {
if (*in == EOF || *in == '\0') return;
if (*in == '\n') {
return;
}
*ret = *in;
ret++;
*ret = '\0';
++in;
}
}
template<class B>
static int parseInt(B& in)
{
int val = 0;
bool neg = false;
skipWhitespace(in);
if (*in == '-') neg = true, ++in;
else if (*in == '+') ++in;
if (*in < '0' || *in > '9') printf("PARSE ERROR! Unexpected char: %c\n", *in), exit(3);
while (*in >= '0' && *in <= '9')
val = val*10 + (*in - '0'),
++in;
return neg ? -val : val;
}
inline std::string stringify(uint x)
{
std::ostringstream o;
o << x;
return o.str();
}
template<class B>
static void parseString(B& in, std::string& str)
{
str.clear();
skipWhitespace(in);
while (*in != ' ' && *in != '\n') {
str += *in;
++in;
}
}
template<class B>
static void readClause(B& in, Solver& S, vec<Lit>& lits)
{
int parsed_lit;
Var var;
lits.clear();
for (;;) {
parsed_lit = parseInt(in);
if (parsed_lit == 0) break;
var = abs(parsed_lit)-1;
if (!debugNewVar) {
while (var >= S.nVars()) S.newVar();
}
lits.push( (parsed_lit > 0) ? Lit(var, false) : Lit(var, true) );
}
}
template<class B>
static bool match(B& in, const char* str)
{
for (; *str != 0; ++str, ++in)
if (*str != *in)
return false;
return true;
}
template<class B>
static void parse_DIMACS_main(B& in, Solver& S)
{
vec<Lit> lits;
int group = 0;
string str;
uint debugLibPart = 1;
char name[MAX_NAMES_SIZE];
for (;;) {
skipWhitespace(in);
switch (*in) {
case EOF:
return;
case 'p':
if (match(in, "p cnf")) {
int vars = parseInt(in);
int clauses = parseInt(in);
if (S.verbosity >= 1) {
printf("c | Number of variables: %-12d |\n", vars);
printf("c | Number of clauses: %-12d |\n", clauses);
}
} else {
printf("PARSE ERROR! Unexpected char: %c\n", *in), exit(3);
}
break;
case 'c':
++in;
parseString(in, str);
if (str == "v" || str == "var") {
int var = parseInt(in);
skipWhitespace(in);
if (var <= 0) cout << "PARSE ERROR! Var number must be a positive integer" << endl, exit(3);
name[0] = '\0';
untilEnd(in, name);
S.setVariableName(var-1, name);
} else if (debugLib && str == "Solver::solve()") {
lbool ret = S.solve();
std::string s = "debugLibPart" + stringify(debugLibPart) +".output";
FILE* res = fopen(s.c_str(), "w");
if (ret == l_True) {
fprintf(res, "SAT\n");
for (Var i = 0; i != S.nVars(); i++)
if (S.model[i] != l_Undef)
fprintf(res, "%s%s%d", (i==0)?"":" ", (S.model[i]==l_True)?"":"-", i+1);
fprintf(res, " 0\n");
} else if (ret == l_False) {
fprintf(res, "UNSAT\n");
} else if (ret == l_Undef) {
assert(false);
} else {
assert(false);
}
fclose(res);
debugLibPart++;
} else if (debugNewVar && str == "Solver::newVar()") {
S.newVar();
} else {
//printf("didn't understand in CNF file: 'c %s'\n", str.c_str());
skipLine(in);
}
break;
default:
bool xor_clause = false;
if ( *in == 'x') xor_clause = true, ++in;
readClause(in, S, lits);
skipLine(in);
name[0] = '\0';
if (!grouping) group++;
else {
if (*in != 'c') {
cout << "PARSE ERROR! Group must be present after earch clause ('c' missing after clause line)" << endl;
exit(3);
}
++in;
parseString(in, str);
if (str != "g" && str != "group") {
cout << "PARSE ERROR! Group must be present after each clause('group' missing)!" << endl;
cout << "Instead of 'group' there was:" << str << endl;
exit(3);
}
group = parseInt(in);
if (group <= 0) printf("PARSE ERROR! Group number must be a positive integer\n"), exit(3);
skipWhitespace(in);
untilEnd(in, name);
}
if (xor_clause) {
bool xor_clause_inverted = false;
for (uint32_t i = 0; i < lits.size(); i++) {
xor_clause_inverted ^= lits[i].sign();
}
S.addXorClause(lits, xor_clause_inverted, group, name);
} else
S.addClause(lits, group, name);
break;
}
}
}
// Inserts problem into solver.
//
#ifdef DISABLE_ZLIB
static void parse_DIMACS(FILE * input_stream, Solver& S)
#else
static void parse_DIMACS(gzFile input_stream, Solver& S)
#endif // DISABLE_ZLIB
{
StreamBuffer in(input_stream);
parse_DIMACS_main(in, S);
}
//=================================================================================================
template<class T, class T2>
inline void printStatsLine(string left, T value, T2 value2, string extra)
{
cout << std::fixed << std::left << std::setw(24) << left << ": " << std::setw(11) << std::setprecision(2) << value << " (" << std::left << std::setw(9) << std::setprecision(2) << value2 << " " << extra << ")" << std::endl;
}
template<class T>
inline void printStatsLine(string left, T value, string extra = "")
{
cout << std::fixed << std::left << std::setw(24) << left << ": " << std::setw(11) << std::setprecision(2) << value << extra << std::endl;
}
void printStats(Solver& solver)
{
double cpu_time = cpuTime();
uint64_t mem_used = memUsed();
//Restarts stats
printStatsLine("c restarts", solver.starts);
printStatsLine("c dynamic restarts", solver.dynStarts);
printStatsLine("c static restarts", solver.staticStarts);
printStatsLine("c full restarts", solver.fullStarts);
//Learnts stats
printStatsLine("c learnts DL2", solver.nbDL2);
printStatsLine("c learnts size 2", solver.nbBin);
printStatsLine("c learnts size 1", solver.get_unitary_learnts_num(), (double)solver.get_unitary_learnts_num()/(double)solver.nVars()*100.0, "% of vars");
//Subsumer stats
printStatsLine("c v-elim SatELite", solver.getNumElimSubsume(), (double)solver.getNumElimSubsume()/(double)solver.nVars()*100.0, "% vars");
printStatsLine("c SatELite time", solver.getTotalTimeSubsumer(), solver.getTotalTimeSubsumer()/cpu_time*100.0, "% time");
//XorSubsumer stats
printStatsLine("c v-elim xor", solver.getNumElimXorSubsume(), (double)solver.getNumElimXorSubsume()/(double)solver.nVars()*100.0, "% vars");
printStatsLine("c xor elim time", solver.getTotalTimeXorSubsumer(), solver.getTotalTimeXorSubsumer()/cpu_time*100.0, "% time");
//VarReplacer stats
printStatsLine("c num binary xor trees", solver.getNumXorTrees());
printStatsLine("c binxor trees' crown", solver.getNumXorTreesCrownSize(), (double)solver.getNumXorTreesCrownSize()/(double)solver.getNumXorTrees(), "leafs/tree");
//OTF clause improvement stats
printStatsLine("c OTF clause improved", solver.improvedClauseNo, (double)solver.improvedClauseNo/(double)solver.conflicts, "clauses/conflict");
printStatsLine("c OTF impr. size diff", solver.improvedClauseSize, (double)solver.improvedClauseSize/(double)solver.improvedClauseNo, " lits/clause");
#ifdef USE_GAUSS
if (solver.gaussconfig.decision_until > 0) {
std::cout << "c " << std::endl;
printStatsLine("c gauss unit truths ", solver.get_sum_gauss_unit_truths());
printStatsLine("c gauss called", solver.get_sum_gauss_called());
printStatsLine("c gauss conflicts ", solver.get_sum_gauss_confl(), (double)solver.get_sum_gauss_confl() / (double)solver.get_sum_gauss_called() * 100.0, " %");
printStatsLine("c gauss propagations ", solver.get_sum_gauss_prop(), (double)solver.get_sum_gauss_prop() / (double)solver.get_sum_gauss_called() * 100.0, " %");
printStatsLine("c gauss useful", ((double)solver.get_sum_gauss_prop() + (double)solver.get_sum_gauss_confl())/ (double)solver.get_sum_gauss_called() * 100.0, " %");
std::cout << "c " << std::endl;
}
#endif
//Search stats
printStatsLine("c conflicts", solver.conflicts, (double)solver.conflicts/cpu_time, "/ sec");
printStatsLine("c decisions", solver.decisions, (double)solver.rnd_decisions*100.0/(double)solver.decisions, "% random");
printStatsLine("c propagations", solver.propagations, (double)solver.propagations/cpu_time, "/ sec");
printStatsLine("c conflict literals", solver.tot_literals, (double)(solver.max_literals - solver.tot_literals)*100.0/ (double)solver.max_literals, "% deleted");
//General stats
printStatsLine("c Memory used", (double)mem_used / 1048576.0, " MB");
printStatsLine("c CPU time", cpu_time, " s");
}
Solver* solver;
static void SIGINT_handler(int signum)
{
printf("\n");
printf("*** INTERRUPTED ***\n");
printStats(*solver);
if (dumpLearnts) {
solver->dumpSortedLearnts(learnts_filename, maxLearntsSize);
cout << "c Sorted learnt clauses dumped to file '" << learnts_filename << "'" << endl;
}
printf("\n");
printf("*** INTERRUPTED ***\n");
exit(1);
}
//=================================================================================================
// Main:
void printUsage(char** argv, Solver& S)
{
#ifdef DISABLE_ZLIB
printf("USAGE: %s [options] <input-file> <result-output-file>\n\n where input is plain DIMACS.\n\n", argv[0]);
#else
printf("USAGE: %s [options] <input-file> <result-output-file>\n\n where input may be either in plain or gzipped DIMACS.\n\n", argv[0]);
#endif // DISABLE_ZLIB
printf("OPTIONS:\n\n");
printf(" --polarity-mode = {true,false,rnd,auto} [default: auto]. Selects the default\n");
printf(" polarity mode. Auto is the Jeroslow&Wang method\n");
//printf(" -decay = <num> [ 0 - 1 ]\n");
printf(" --rnd-freq = <num> [ 0 - 1 ]\n");
printf(" --verbosity = {0,1,2}\n");
#ifdef STATS_NEEDED
printf(" --proof-log = Logs the proof into files 'proofN.dot', where N is the\n");
printf(" restart number. The log can then be visualized using\n");
printf(" the 'dot' program from the graphviz package\n");
printf(" --grouping = Lets you group clauses, and customize the groups' names.\n");
printf(" This helps when printing statistics\n");
printf(" --stats = Computes and prints statistics during the search\n");
#endif
printf(" --randomize = <seed> [0 - 2^32-1] Sets random seed, used for picking\n");
printf(" decision variables (default = 0)\n");
printf(" --restrict = <num> [1 - varnum] when picking random variables to branch\n");
printf(" on, pick one that in the 'num' most active vars useful\n");
printf(" for cryptographic problems, where the question is the key,\n");
printf(" which is usually small (e.g. 80 bits)\n");
printf(" --restarts = <num> [1 - 2^32-1] No more than the given number of\n");
printf(" restarts will be performed during search\n");
printf(" --nonormxorfind = Don't find and collect >2-long xor-clauses from\n");
printf(" regular clauses\n");
printf(" --nobinxorfind = Don't find and collect 2-long xor-clauses from\n");
printf(" regular clauses\n");
printf(" --noregbxorfind = Don't regularly find and collect 2-long xor-clauses\n");
printf(" from regular clauses\n");
printf(" --noconglomerate = Don't conglomerate 2 xor clauses when one var is dependent\n");
printf(" --nosimplify = Don't do regular simplification rounds\n");
printf(" --greedyunbound = Greedily unbound variables that are not needed for SAT\n");
printf(" --debuglib = Solve at specific 'c Solver::solve()' points in the CNF\n");
printf(" file. Used to debug file generated by Solver's\n");
printf(" needLibraryCNFFile() function\n");
printf(" --debugnewvar = Add new vars at specific 'c Solver::newVar()' points in \n");
printf(" the CNF file. Used to debug file generated by Solver's\n");
printf(" needLibraryCNFFile() function.\n");
printf(" --novarreplace = Don't perform variable replacement. Needed for programmable\n");
printf(" solver feature\n");
printf(" --restart = {auto, static, dynamic} Which kind of restart strategy to\n");
printf(" follow. Default is auto\n");
printf(" --dumplearnts = <filename> If interrupted or reached restart limit, dump\n");
printf(" the learnt clauses to the specified file. Maximum size of\n");
printf(" dumped clauses can be specified with next option.\n");
printf(" --maxdumplearnts = [0 - 2^32-1] When dumping the learnts to file, what\n");
printf(" should be maximum length of the clause dumped. Useful\n");
printf(" to make the resulting file smaller. Default is 2^32-1\n");
printf(" note: 2-long XOR-s are always dumped.\n");
printf(" --maxsolutions = Search for given amount of solutions\n");
printf(" --nofailedvar = Don't search for failed vars, and don't search for vars\n");
printf(" doubly propagated to the same value\n");
printf(" --noheuleprocess = Don't try to minimise XORs by XOR-ing them together.\n");
printf(" Algo. as per global/local substitution in Heule's thesis\n");
printf(" --nosatelite = Don't do clause subsumption, clause strengthening and\n");
printf(" variable elimination (implies -novarelim and -nosubsume1).\n");
printf(" --noxorsubs = Don't try to subsume xor-clauses.\n");
printf(" --nohyperbinres = Don't carry out hyper-binary resolution\n");
printf(" --nosolprint = Don't print the satisfying assignment if the solution\n");
printf(" is SAT\n");
printf(" --novarelim = Don't perform variable elimination as per Een and Biere\n");
printf(" --nosubsume1 = Don't perform clause contraction through resolution\n");
printf(" --noparthander = Don't find and solve subroblems with subsolvers\n");
#ifdef USE_GAUSS
printf(" --gaussuntil = <num> Depth until which Gaussian elimination is active.\n");
printf(" Giving 0 switches off Gaussian elimination\n");
printf(" --nomatrixfind = Don't find distinct matrixes. Put all xors into one\n");
printf(" big matrix\n");
printf(" --noiterreduce = Don't reduce iteratively the matrix that is updated\n");
printf(" --noordercol = Don't order variables in the columns of Gaussian\n");
printf(" elimination. Effectively disables iterative reduction\n");
printf(" of the matrix\n");
printf(" --maxmatrixrows = [0 - 2^32-1] Set maximum no. of rows for gaussian matrix.\n");
printf(" Too large matrixes should bee discarded for\n");
printf(" reasons of efficiency. Default: %d\n", S.gaussconfig.maxMatrixRows);
printf(" --minmatrixrows = [0 - 2^32-1] Set minimum no. of rows for gaussian matrix.\n");
printf(" Normally, too small matrixes are discarded for\n");
printf(" reasons of efficiency. Default: %d\n", S.gaussconfig.minMatrixRows);
printf(" --savematrix = [0 - 2^32-1] Save matrix every Nth decision level.\n");
printf(" Default: %d\n", S.gaussconfig.only_nth_gauss_save);
#endif //USE_GAUSS
//printf(" --addoldlearnts = Readd old learnts for failed variable searching.\n");
//printf(" These learnts are usually deleted, but may help\n");
printf(" --noextrabins = Don't add binary clauses when doing failed lit probing.\n");
printf(" --noremovebins = Don't remove useless binary clauses\n");
printf(" --noregremovebins= Don't remove useless binary clauses regularly\n");
printf(" --nosubswithbins = Don't subsume with non-existent bins\n");
printf(" --norsubswithbins= Don't subsume regularly with non-existent bins\n");
printf("\n");
}
const char* hasPrefix(const char* str, const char* prefix)
{
int len = strlen(prefix);
if (strncmp(str, prefix, len) == 0)
return str + len;
else
return NULL;
}
int main(int argc, char** argv)
{
Solver S;
S.verbosity = 2;
const char* value;
int j = 0;
unsigned long max_nr_of_solutions = 1;
unsigned long current_nr_of_solutions = 1;
for (int i = 0; i < argc; i++) {
if ((value = hasPrefix(argv[i], "--polarity-mode="))) {
if (strcmp(value, "true") == 0)
S.polarity_mode = Solver::polarity_true;
else if (strcmp(value, "false") == 0)
S.polarity_mode = Solver::polarity_false;
else if (strcmp(value, "rnd") == 0)
S.polarity_mode = Solver::polarity_rnd;
else if (strcmp(value, "auto") == 0)
S.polarity_mode = Solver::polarity_auto;
else {
printf("ERROR! unknown polarity-mode %s\n", value);
exit(0);
}
} else if ((value = hasPrefix(argv[i], "--rnd-freq="))) {
double rnd;
if (sscanf(value, "%lf", &rnd) <= 0 || rnd < 0 || rnd > 1) {
printf("ERROR! illegal rnd-freq constant %s\n", value);
exit(0);
}
S.random_var_freq = rnd;
/*} else if ((value = hasPrefix(argv[i], "--decay="))) {
double decay;
if (sscanf(value, "%lf", &decay) <= 0 || decay <= 0 || decay > 1) {
printf("ERROR! illegal decay constant %s\n", value);
exit(0);
}
S.var_decay = 1 / decay;*/
} else if ((value = hasPrefix(argv[i], "--verbosity="))) {
int verbosity = (int)strtol(value, NULL, 10);
if (verbosity == EINVAL || verbosity == ERANGE) {
printf("ERROR! illegal verbosity level %s\n", value);
exit(0);
}
S.verbosity = verbosity;
#ifdef STATS_NEEDED
} else if ((value = hasPrefix(argv[i], "--grouping"))) {
grouping = true;
} else if ((value = hasPrefix(argv[i], "--proof-log"))) {
S.needProofGraph();
} else if ((value = hasPrefix(argv[i], "--stats"))) {
S.needStats();
#endif //STATS_NEEDED
} else if ((value = hasPrefix(argv[i], "--randomize="))) {
uint32_t seed;
if (sscanf(value, "%d", &seed) < 0) {
printf("ERROR! illegal seed %s\n", value);
exit(0);
}
cout << "c seed:" << seed << endl;
S.setSeed(seed);
} else if ((value = hasPrefix(argv[i], "--restrict="))) {
uint branchTo;
if (sscanf(value, "%d", &branchTo) < 0 || branchTo < 1) {
printf("ERROR! illegal restricted pick branch number %d\n", branchTo);
exit(0);
}
S.restrictedPickBranch = branchTo;
} else if ((value = hasPrefix(argv[i], "--restarts="))) {
uint maxrest;
if (sscanf(value, "%d", &maxrest) < 0 || maxrest == 0) {
printf("ERROR! illegal maximum restart number %d\n", maxrest);
exit(0);
}
S.setMaxRestarts(maxrest);
} else if ((value = hasPrefix(argv[i], "--dumplearnts="))) {
if (sscanf(value, "%400s", learnts_filename) < 0 || strlen(learnts_filename) == 0) {
printf("ERROR! wrong filename '%s'\n", learnts_filename);
exit(0);
}
dumpLearnts = true;
} else if ((value = hasPrefix(argv[i], "--maxdumplearnts="))) {
if (!dumpLearnts) {
printf("ERROR! -dumplearnts=<filename> must be first activated before issuing -maxdumplearnts=<size>\n");
exit(0);
}
int tmp;
if (sscanf(value, "%d", &tmp) < 0 || tmp < 0) {
cout << "ERROR! wrong maximum dumped learnt clause size is illegal: " << tmp << endl;
exit(0);
}
maxLearntsSize = (uint32_t)tmp;
} else if ((value = hasPrefix(argv[i], "--maxsolutions="))) {
int tmp;
if (sscanf(value, "%d", &tmp) < 0 || tmp < 0) {
cout << "ERROR! wrong maximum number of solutions is illegal: " << tmp << endl;
exit(0);
}
max_nr_of_solutions = (uint32_t)tmp;
#ifdef USE_GAUSS
} else if ((value = hasPrefix(argv[i], "--gaussuntil="))) {
uint32_t until;
if (sscanf(value, "%d", &until) < 0) {
printf("ERROR! until %s\n", value);
exit(0);
}
S.gaussconfig.decision_until = until;
} else if ((value = hasPrefix(argv[i], "--nodisablegauss"))) {
S.gaussconfig.dontDisable = true;
} else if ((value = hasPrefix(argv[i], "--nomatrixfind"))) {
S.gaussconfig.noMatrixFind = true;
} else if ((value = hasPrefix(argv[i], "--noiterreduce"))) {
S.gaussconfig.iterativeReduce = false;
} else if ((value = hasPrefix(argv[i], "--noordercol"))) {
S.gaussconfig.orderCols = false;
} else if ((value = hasPrefix(argv[i], "--maxmatrixrows"))) {
uint32_t rows;
if (sscanf(value, "%d", &rows) < 0) {
printf("ERROR! maxmatrixrows: %s\n", value);
exit(0);
}
S.gaussconfig.maxMatrixRows = rows;
} else if ((value = hasPrefix(argv[i], "--minmatrixrows"))) {
uint32_t rows;
if (sscanf(value, "%d", &rows) < 0) {
printf("ERROR! minmatrixrows: %s\n", value);
exit(0);
}
S.gaussconfig.minMatrixRows = rows;
} else if ((value = hasPrefix(argv[i], "--savematrix"))) {
uint32_t every;
if (sscanf(value, "%d", &every) < 0) {
printf("ERROR! savematrix: %s\n", value);
exit(0);
}
cout << "c Matrix saved every " << every << " decision levels" << endl;
S.gaussconfig.only_nth_gauss_save = every;
#endif //USE_GAUSS
} else if ((value = hasPrefix(argv[i], "--greedyunbound"))) {
S.greedyUnbound = true;
} else if ((value = hasPrefix(argv[i], "--nonormxorfind"))) {
S.findNormalXors = false;
} else if ((value = hasPrefix(argv[i], "--nobinxorfind"))) {
S.findBinaryXors = false;
} else if ((value = hasPrefix(argv[i], "--noregbxorfind"))) {
S.regularlyFindBinaryXors = false;
} else if ((value = hasPrefix(argv[i], "--noconglomerate"))) {
S.conglomerateXors = false;
} else if ((value = hasPrefix(argv[i], "--nosimplify"))) {
S.schedSimplification = false;
} else if ((value = hasPrefix(argv[i], "--debuglib"))) {
debugLib = true;
} else if ((value = hasPrefix(argv[i], "--debugnewvar"))) {
debugNewVar = true;
} else if ((value = hasPrefix(argv[i], "--novarreplace"))) {
S.performReplace = false;
} else if ((value = hasPrefix(argv[i], "--nofailedvar"))) {
S.failedVarSearch = false;
} else if ((value = hasPrefix(argv[i], "--noheuleprocess"))) {
S.heuleProcess = false;
} else if ((value = hasPrefix(argv[i], "--nosatelite"))) {
S.doSubsumption = false;
} else if ((value = hasPrefix(argv[i], "--noparthandler"))) {
S.doPartHandler = false;
} else if ((value = hasPrefix(argv[i], "--noxorsubs"))) {
S.doXorSubsumption = false;
} else if ((value = hasPrefix(argv[i], "--nohyperbinres"))) {
S.doHyperBinRes = false;
} else if ((value = hasPrefix(argv[i], "--noblockedclause"))) {
S.doBlockedClause = false;
} else if ((value = hasPrefix(argv[i], "--novarelim"))) {
S.doVarElim = false;
} else if ((value = hasPrefix(argv[i], "--nosubsume1"))) {
S.doSubsume1 = false;
} else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "-help") == 0 || strcmp(argv[i], "--help") == 0) {
printUsage(argv, S);
exit(0);
} else if ((value = hasPrefix(argv[i], "--restart="))) {
if (strcmp(value, "auto") == 0)
S.fixRestartType = auto_restart;
else if (strcmp(value, "static") == 0)
S.fixRestartType = static_restart;
else if (strcmp(value, "dynamic") == 0)
S.fixRestartType = dynamic_restart;
else {
printf("ERROR! unknown restart type %s\n", value);
exit(0);
}
} else if ((value = hasPrefix(argv[i], "--nosolprint"))) {
printResult = false;
//} else if ((value = hasPrefix(argv[i], "--addoldlearnts"))) {
// S.readdOldLearnts = true;
} else if ((value = hasPrefix(argv[i], "--noextrabins"))) {
S.addExtraBins = false;
} else if ((value = hasPrefix(argv[i], "--noremovebins"))) {
S.removeUselessBins = false;
} else if ((value = hasPrefix(argv[i], "--noregremovebins"))) {
S.regularRemoveUselessBins = false;
} else if ((value = hasPrefix(argv[i], "--nosubswithbins"))) {
S.subsumeWithNonExistBinaries = false;
} else if ((value = hasPrefix(argv[i], "--norsubswithbins"))) {
S.regularSubsumeWithNonExistBinaries = false;
} else if (strncmp(argv[i], "-", 1) == 0 || strncmp(argv[i], "--", 2) == 0) {
printf("ERROR! unknown flag %s\n", argv[i]);
exit(0);
} else
argv[j++] = argv[i];
}
argc = j;
if (!debugLib) S.libraryUsage = false;
if (S.verbosity >= 1)
printf("c This is CryptoMiniSat %s\n", VERSION);
#if defined(__linux__)
fpu_control_t oldcw, newcw;
_FPU_GETCW(oldcw);
newcw = (oldcw & ~_FPU_EXTENDED) | _FPU_DOUBLE;
_FPU_SETCW(newcw);
if (S.verbosity >= 1) printf("c WARNING: for repeatability, setting FPU to use double precision\n");
#endif
double cpu_time = cpuTime();
solver = &S;
signal(SIGINT,SIGINT_handler);
//signal(SIGHUP,SIGINT_handler);
if (argc == 1)
printf("c Reading from standard input... Use '-h' or '--help' for help.\n");
#ifdef DISABLE_ZLIB
FILE * in = (argc == 1) ? fopen(0, "rb") : fopen(argv[1], "rb");
#else
gzFile in = (argc == 1) ? gzdopen(0, "rb") : gzopen(argv[1], "rb");
#endif // DISABLE_ZLIB
if (in == NULL) {
printf("ERROR! Could not open file: %s\n", argc == 1 ? "<stdin>" : argv[1]);
exit(1);
}
if (S.verbosity >= 1) {
printf("c =================================[ Problem Statistics ]==================================\n");
printf("c | |\n");
}
parse_DIMACS(in, S);
#ifdef DISABLE_ZLIB
fclose(in);
#else
gzclose(in);
#endif // DISABLE_ZLIB
if (argc >= 3)
printf("c Outputting solution to file: %s\n" , argv[2]);
double parse_time = cpuTime() - cpu_time;
if (S.verbosity >= 1)
printf("c | Parsing time: %-12.2f s |\n", parse_time);
lbool ret;
while(1)
{
ret = S.solve();
if ( ret != l_True ) break;
std::cout << "c " << std::setw(8) << current_nr_of_solutions++ << " solution(s) found" << std::endl;
if (current_nr_of_solutions > max_nr_of_solutions) break;
printf("c Prepare for next run...\n");
vec<Lit> lits;
if (printResult) printf("v ");
for (Var var = 0; var != S.nVars(); var++) {
if (S.model[var] != l_Undef) {
lits.push( Lit(var, (S.model[var] == l_True)? true : false) );
if (printResult) printf("%s%d ", (S.model[var] == l_True)? "" : "-", var+1);
}
}
if (printResult) printf("\n");
S.addClause(lits);
}
printStats(S);
printf("c \n");
if (dumpLearnts) {
S.dumpSortedLearnts(learnts_filename, maxLearntsSize);
cout << "c Sorted learnt clauses dumped to file '" << learnts_filename << "'" << endl;
}
if (ret == l_Undef)
printf("c Not finished running -- maximum restart reached\n");
FILE* res = NULL;
if (argc >= 3) {
res = fopen(argv[2], "wb");
if (res == NULL) {
int backup_errno = errno;
printf("Cannot open %s for writing. Problem: %s", argv[2], strerror(backup_errno));
exit(1);
}
}
if (res != NULL) {
if (ret == l_True) {
printf("c SAT\n");
fprintf(res, "SAT\n");
if (printResult) {
for (Var var = 0; var != S.nVars(); var++)
if (S.model[var] != l_Undef)
fprintf(res, "%s%d ", (S.model[var] == l_True)? "" : "-", var+1);
fprintf(res, "0\n");
}
} else if (ret == l_False) {
printf("c UNSAT\n");
fprintf(res, "UNSAT\n");
} else {
printf("c INCONCLUSIVE\n");
fprintf(res, "INCONCLUSIVE\n");
}
fclose(res);
} else {
if (ret == l_True)
printf("s SATISFIABLE\n");
else if (ret == l_False)
printf("s UNSATISFIABLE\n");
if(ret == l_True && printResult) {
printf("v ");
for (Var var = 0; var != S.nVars(); var++)
if (S.model[var] != l_Undef)
printf("%s%d ", (S.model[var] == l_True)? "" : "-", var+1);
printf("0\n");
}
}
#ifdef NDEBUG
exit(ret == l_True ? 10 : 20); // (faster than "return", which will invoke the destructor for 'Solver')
#endif
if (ret == l_True) return 10;
if (ret == l_False) return 20;
if (ret == l_Undef) return 15;
assert(false);
return 0;
}