1 /*-------------------------------------------------------------------------*/
2 /* Copyright 2010-2014 Armin Biere Johannes Kepler University Linz Austria */
3 /*-------------------------------------------------------------------------*/
16 #include "solver_interface.h"
18 static LGL * lgl4sigh;
19 static int catchedsig, verbose, ignmissingheader, ignaddcls;
21 static void (*sig_int_handler)(int);
22 static void (*sig_segv_handler)(int);
23 static void (*sig_abrt_handler)(int);
24 static void (*sig_term_handler)(int);
25 static void (*sig_bus_handler)(int);
26 static void (*sig_alrm_handler)(int);
28 static void resetsighandlers (void) {
29 (void) signal (SIGINT, sig_int_handler);
30 (void) signal (SIGSEGV, sig_segv_handler);
31 (void) signal (SIGABRT, sig_abrt_handler);
32 (void) signal (SIGTERM, sig_term_handler);
33 (void) signal (SIGBUS, sig_bus_handler);
36 static inline double cpuTime(void) {
38 getrusage(RUSAGE_SELF, &ru);
39 return (double)ru.ru_utime.tv_sec + (double)ru.ru_utime.tv_usec / 1000000;
42 static void caughtsigmsg (int sig) {
43 if (verbose < 0) return;
44 printf ("c\nc CAUGHT SIGNAL %d", sig);
46 case SIGINT: printf (" SIGINT"); break;
47 case SIGSEGV: printf (" SIGSEGV"); break;
48 case SIGABRT: printf (" SIGABRT"); break;
49 case SIGTERM: printf (" SIGTERM"); break;
50 case SIGBUS: printf (" SIGBUS"); break;
51 case SIGALRM: printf (" SIGALRM"); break;
58 static void catchsig (int sig) {
62 fputs ("c s UNKNOWN\n", stdout);
65 lglflushtimers (lgl4sigh);
71 if (!getenv ("LGLNABORT")) raise (sig); else exit (1);
74 static void setsighandlers (void) {
75 sig_int_handler = signal (SIGINT, catchsig);
76 sig_segv_handler = signal (SIGSEGV, catchsig);
77 sig_abrt_handler = signal (SIGABRT, catchsig);
78 sig_term_handler = signal (SIGTERM, catchsig);
79 sig_bus_handler = signal (SIGBUS, catchsig);
82 static int timelimit = -1, caughtalarm = 0;
84 static void catchalrm (int sig) {
85 assert (sig == SIGALRM);
90 printf ("c time limit of %d reached after %.1f seconds\nc\n",
91 timelimit, lglsec (lgl4sigh));
97 static int checkalarm (void * ptr) {
98 assert (ptr == (void*) &caughtalarm);
102 static int primes[] = {
103 200000033, 200000039, 200000051, 200000069, 200000081,
106 static int nprimes = sizeof primes / sizeof *primes;
118 if (offset>=length) {
122 ptr=read(0, buffer, sizeof(int)*IS_BUFFERSIZE);
126 ssize_t bytestoread=(4-(ptr & 3)) & 3;
127 while(bytestoread != 0) {
128 ssize_t p=read(0, &((char *)buffer)[ptr], bytestoread);
138 return buffer[offset++];
142 ssize_t bytestowrite=sizeof(int)*outoffset;
143 ssize_t byteswritten=0;
145 ssize_t n=write(IS_OUT_FD, &((char *)outbuffer)[byteswritten], bytestowrite);
147 fprintf(stderr, "Write failure\n");
152 } while(bytestowrite != 0);
156 void putInt(int value) {
157 if (outoffset>=IS_BUFFERSIZE) {
160 outbuffer[outoffset++]=value;
167 void readClauses(LGL *solver) {
168 bool haveClause = false;
186 void processCommands(LGL *solver) {
188 int command=getInt();
192 lglfreeze(solver, var);
196 int ret = lglsat(solver);
199 int numvars=lglmaxvar(solver);
201 for(int i=1;i<=numvars;i++) {
202 putInt(lglderef(solver, i) > 0);
204 } else if (ret == 20) {
213 fprintf(stderr, "Unreconized command\n");
219 void processSAT(LGL *solver) {
220 buffer=(int *) malloc(sizeof(int)*IS_BUFFERSIZE);
223 outbuffer=(int *) malloc(sizeof(int)*IS_BUFFERSIZE);
227 double initial_time = cpuTime();
229 double parse_time = cpuTime();
230 processCommands(solver);
231 double finish_time = cpuTime();
232 printf("Parse time: %12.2f s Solve time:%12.2f s\n", parse_time-initial_time, finish_time-parse_time);
238 int main (int argc, char ** argv) {
239 int res, i, j, val, len, lineno, simponly;
240 const char * pname, * match, * p, * thanks;
241 int nopts, simplevel;
246 res = simponly = simplevel = 0;
248 lgl4sigh = lgl = lglinit ();
250 for (i = 1; i < argc; i++) {
251 if (!strcmp (argv[i], "-h") || !strcmp (argv[i], "--help")) {
252 printf ("usage: lingeling [<option> ...][<file>[.gz]]\n");
254 printf ("where <option> is one of the following:\n");
256 printf ("-q be quiet (same as '--verbose=-1')\n");
257 printf ("-s only simplify and print to output file\n");
258 printf ("-O<L> set simplification level to <L>\n");
259 printf ("-p <options> read options from file\n");
261 printf ("-t <seconds> set time limit\n");
264 printf ("-h|--help print command line option summary\n");
265 printf ("-f|--force force reading even without header\n");
266 printf ("-i|--ignore ignore additional clauses\n");
267 printf ("-r|--ranges print value ranges of options\n");
268 printf ("-d|--defaults print default values of options\n");
269 printf ("-P|--pcs print (full) PCS file\n");
270 printf ("--pcs-mixed print mixed PCS file\n");
271 printf ("--pcs-reduced print reduced PCS file\n");
272 printf ("-e|--embedded ditto but in an embedded format print\n");
273 printf ("-n|--no-witness do not print solution (see '--witness')\n");
275 printf ("--thanks=<whom> alternative way of specifying the seed\n");
276 printf (" (inspired by Vampire)\n");
279 "The following options can also be used in the form '--<name>=<int>',\n"
280 "just '--<name>' for increment and '--no-<name>' for zero. They\n"
281 "can be embedded into the CNF file, set through the API or capitalized\n"
282 "with prefix 'LGL' instead of '--' through environment variables.\n"
283 "Their default values are displayed in square brackets.\n");
287 } else if (!strcmp (argv[i], "-s")) simponly = 1;
288 else if (argv[i][0] == '-' && argv[i][1] == 'O') {
290 fprintf (stderr, "*** lingeling error: multiple '-O..' options\n");
294 if ((simplevel = atoi (argv[i] + 2)) <= 0) {
296 "*** lingeling error: invalid '%s' option\n", argv[i]);
300 } else if (!strcmp (argv[i], "-q")) lglsetopt (lgl, "verbose", -1);
301 else if (!strcmp (argv[i], "-p")) {
303 fprintf (stderr, "*** lingeling error: argument to '-p' missing\n");
309 "*** lingeling error: "
310 "multiple option files '%s' and '%s'\n",
316 } else if (!strcmp (argv[i], "-t")) {
318 fprintf (stderr, "*** lingeling error: argument to '-t' missing\n");
322 if (timelimit >= 0) {
323 fprintf (stderr, "*** lingeling error: timit limit set twice\n");
327 for (p = argv[i]; *p && isdigit (*p); p++)
329 if (p == argv[i] || *p || (timelimit = atoi (argv[i])) < 0) {
331 "*** lingeling error: invalid time limit '-t %s'\n", argv[i]);
335 } else if (!strcmp (argv[i], "-d") || !strcmp (argv[i], "--defaults")) {
336 lglopts (lgl, "", 0);
338 } else if (!strcmp (argv[i], "-e") || !strcmp (argv[i], "--embedded")) {
339 lglopts (lgl, "c ", 1);
341 } else if (!strcmp (argv[i], "-r") || !strcmp (argv[i], "--ranges")) {
344 } else if (!strcmp (argv[i], "-P") || !strcmp (argv[i], "--pcs")) {
345 printf ("# generated by 'lingeling --pcs'\n");
346 printf ("# version %s\n", lglversion ());
349 } else if (!strcmp (argv[i], "--pcs-mixed")) {
350 printf ("# generated by 'lingeling --pcs-mixed'\n");
351 printf ("# version %s\n", lglversion ());
354 } else if (!strcmp (argv[i], "--pcs-reduced")) {
355 printf ("# generated by 'lingeling --pcs-reduced'\n");
356 printf ("# version %s\n", lglversion ());
359 } else if (!strcmp (argv[i], "-f") || !strcmp (argv[i], "--force")) {
360 ignmissingheader = 1;
361 } else if (!strcmp (argv[i], "-i") || !strcmp (argv[i], "--ignore")) {
363 } else if (!strcmp (argv[i], "-n") || !strcmp (argv[i], "no-witness")) {
364 lglsetopt (lgl, "witness", 0);
365 } else if (argv[i][0] == '-') {
366 if (argv[i][1] == '-') {
367 match = strchr (argv[i] + 2, '=');
370 if (*p == '-') p++; // TODO for what is this useful again?
372 if (!strncmp (argv[i], "--write-api-trace=", len)) {
373 // TODO not handled yet ...
375 } else if (!strncmp (argv[i], "--thanks=", len)) {
378 } else if (!isdigit (*p)) {
381 "*** lingeling error: invalid command line option '%s'\n",
386 while (*++p) if (!isdigit (*p)) goto ERR;
387 len = match - argv[i] - 2;
388 tmp = malloc (len + 1);
390 for (p = argv[i] + 2; *p != '='; p++) tmp[j++] = *p;
392 val = atoi (match + 1);
393 } else if (!strncmp (argv[i], "--no-", 5)) {
394 tmp = strdup (argv[i] + 5);
397 tmp = strdup (argv[i] + 2);
398 val = lglgetopt (lgl, tmp) + 1;
400 if (!lglhasopt (lgl, tmp)) { free (tmp); goto ERR; }
401 lglsetopt (lgl, tmp, val);
404 if (argv[i][2]) goto ERR;
405 if (!lglhasopt (lgl, argv[i] + 1)) goto ERR;
406 val = lglgetopt (lgl, argv[i] + 1) + 1;
407 lglsetopt (lgl, argv[i] + 1, val);
411 verbose = lglgetopt (lgl, "verbose");
413 lglbnr ("Lingeling SAT Solver", "c ", stdout);
414 if (simponly) printf ("c simplifying only\n");
415 if (simponly) fflush (stdout);
416 lglsetopt (lgl, "trep", 1);
419 unsigned seed = 0, i = 0, ch;
421 for (p = thanks; (ch = *p); p++) {
422 seed += primes[i++] * ch;
423 if (i == nprimes) i = 0;
425 if (seed >= (unsigned) INT_MAX) seed >>= 1;
426 assert (seed <= (unsigned) INT_MAX);
430 printf ("c will have to thank %s (--seed=%d)\nc\n",
432 lglsetopt (lgl, "seed", iseed);
435 printf ("c\nc options after command line parsing:\nc\n");
436 lglopts (lgl, "c ", 0);
443 pfile = fopen (pname, "r");
446 "*** lingeling error: can not read option file %s\n", pname);
451 printf ("c reading options file %s\n", pname);
454 nopts = lglreadopts (lgl, pfile);
456 printf ("c read and set %d options\nc\n", nopts), fflush (stdout);
464 if (verbose >= 2) printf ("c final options:\nc\n");
465 lglopts (lgl, "c ", 0);
467 if (timelimit >= 0) {
469 printf ("c\nc setting time limit of %d seconds\n", timelimit);
472 lglseterm (lgl, checkalarm, &caughtalarm);
473 sig_alrm_handler = signal (SIGALRM, catchalrm);
479 if (timelimit >= 0) {
481 (void) signal (SIGALRM, sig_alrm_handler);
483 if (verbose >= 0) fputs ("c\n", stdout), lglstats (lgl);