8 #define GUNZIP "gunzip -c %s"
9 #define GZIP "gzip -c -f > %s"
11 FILE * popen (const char *, const char*);
19 static char buffer
[100];
20 static char *bhead
= buffer
;
21 static const char *eob
= buffer
+ 80;
22 static FILE * incremental_rup_file
;
24 extern void picosat_enter (void);
25 extern void picosat_leave (void);
27 static char page
[4096];
39 if (end
< page
+ sizeof page
)
42 bytes
= fread (page
, 1, sizeof page
, input
);
61 int ch
, sign
, lit
, vars
, clauses
;
64 inputid
= fileno (input
);
70 while ((ch
= next ()) != EOF
&& ch
!= '\n')
80 return "missing or invalid 'p cnf <variables> <clauses>' header";
82 if (!isspace (next ()))
85 while (isspace (ch
= next ()))
88 if (ch
!= 'c' || next () != 'n' || next () != 'f' || !isspace (next ()))
91 while (isspace (ch
= next ()))
98 while (isdigit (ch
= next ()))
99 vars
= 10 * vars
+ (ch
- '0');
104 while (isspace (ch
= next ()))
111 while (isdigit (ch
= next ()))
112 clauses
= 10 * clauses
+ (ch
- '0');
114 if (!isspace (ch
) && ch
!= '\n' )
119 fprintf (output
, "c parsed header 'p cnf %d %d'\n", vars
, clauses
);
123 picosat_adjust (vars
);
125 if (incremental_rup_file
)
126 picosat_set_incremental_rup_file (incremental_rup_file
, vars
, clauses
);
134 while ((ch
= next ()) != EOF
&& ch
!= '\n')
142 return "trailing 0 missing";
144 if (clauses
&& !force
)
145 return "clause missing";
161 return "expected number";
164 while (isdigit (ch
= next ()))
165 lit
= 10 * lit
+ (ch
- '0');
167 if (!clauses
&& !force
)
168 return "too many clauses";
172 if (lit
> vars
&& !force
)
173 return "maximal variable index exceeded";
189 fputs (buffer
, output
);
190 fputc ('\n', output
);
204 l
= sprintf (bhead
, " %d", i
);
219 int max_idx
= picosat_variables (), i
, lit
;
221 assert (bhead
== buffer
);
223 for (i
= 1; i
<= max_idx
; i
++)
225 lit
= (picosat_deref (i
) > 0) ? i
: -i
;
235 has_suffix (const char *str
, const char *suffix
)
237 const char *tmp
= strstr (str
, suffix
);
241 return str
+ strlen (str
) - strlen (suffix
) == tmp
;
245 write_core_variables (FILE * file
)
247 int i
, max_idx
= picosat_variables ();
248 for (i
= 1; i
<= max_idx
; i
++)
249 if (picosat_corelit (i
))
250 fprintf (file
, "%d\n", i
);
254 write_to_file (const char *name
, const char *type
, void (*writer
) (FILE *))
256 int pclose_file
, zipped
= has_suffix (name
, ".gz");
262 cmd
= malloc (strlen (GZIP
) + strlen (name
));
263 sprintf (cmd
, GZIP
, name
);
264 file
= popen (cmd
, "w");
270 file
= fopen (name
, "w");
278 "c\nc writing %s%s to '%s'\n",
279 zipped
? "gzipped " : "", type
, name
);
289 fprintf (output
, "*** picosat: can not write to '%s'\n", name
);
293 "usage: picosat [ <option> ... ] [ <input> ]\n" \
295 "where <option> is one of the following\n" \
297 " -h print this command line option summary and exit\n" \
298 " --version print version and exit\n" \
299 " --config print build configuration and exit\n" \
301 " -v enable verbose output\n" \
302 " -f ignore invalid header\n" \
303 " -n do not print satisfying assignment\n" \
304 " -p print formula in DIMACS format and exit\n" \
305 " -a <lit> start with an assumption\n" \
306 " -l <limit> set decision limit (no limit per default)\n" \
307 " -i <0/1> force FALSE respectively TRUE as default phase\n" \
308 " -s <seed> set random number generator seed (default 0)\n" \
309 " -o <output> set output file (<stdout> per default)\n" \
310 " -t <trace> generate compact proof trace file\n" \
311 " -T <trace> generate extended proof trace file\n" \
312 " -r <trace> generate reverse unit propagation proof file\n" \
313 " -c <core> generate clausal core file in DIMACS format\n" \
314 " -V <core> generate file listing core variables\n" \
315 " -U <core> generate file listing used variables\n" \
317 "and <input> is an optional input file in DIMACS format.\n"
320 picosat_main (int argc
, char **argv
)
322 int res
, done
, err
, print_satisfying_assignment
, force
, print_formula
;
323 const char *compact_trace_name
, *extended_trace_name
, * rup_trace_name
;
324 const char * clausal_core_name
, * variable_core_name
;
325 int assumption
, assumptions
, defaultphase
;
326 const char *input_name
, *output_name
;
327 int close_input
, pclose_input
;
328 int i
, decision_limit
;
334 start_time
= picosat_time_stamp ();
336 clausal_core_name
= 0;
337 variable_core_name
= 0;
339 compact_trace_name
= 0;
340 extended_trace_name
= 0;
342 incremental_rup_file
= 0;
345 input_name
= "<stdin>";
357 top
= end
= page
+ sizeof page
;
359 print_satisfying_assignment
= 1;
362 for (i
= 1; !done
&& !err
&& i
< argc
; i
++)
364 if (!strcmp (argv
[i
], "-h"))
366 fputs (USAGE
, output
);
369 else if (!strcmp (argv
[i
], "--version"))
371 fprintf (output
, "%s\n", picosat_version ());
374 else if (!strcmp (argv
[i
], "--config"))
376 fprintf (output
, "%s\n", picosat_config ());
379 else if (!strcmp (argv
[i
], "-v"))
383 else if (!strcmp (argv
[i
], "-f"))
387 else if (!strcmp (argv
[i
], "-n"))
389 print_satisfying_assignment
= 0;
391 else if (!strcmp (argv
[i
], "-p"))
395 else if (!strcmp (argv
[i
], "-l"))
399 fprintf (output
, "*** picosat: argument to '-l' missing\n");
403 decision_limit
= atoi (argv
[i
]);
405 else if (!strcmp (argv
[i
], "-i"))
409 fprintf (output
, "*** picosat: argument to '-i' missing\n");
412 else if (!strcmp (argv
[i
], "0"))
416 else if (!strcmp (argv
[i
], "1"))
422 fprintf (output
, "*** picosat: invalid argument to '-i'\n");
426 else if (!strcmp (argv
[i
], "-a"))
430 fprintf (output
, "*** picosat: argument to '-a' missing\n");
433 else if (!atoi (argv
[i
]))
435 fprintf (output
, "*** picosat: argument to '-a' zero\n");
440 /* Handle assumptions further down
445 else if (!strcmp (argv
[i
], "-s"))
449 fprintf (output
, "*** picosat: argument to '-s' missing\n");
453 seed
= atoi (argv
[i
]);
455 else if (!strcmp (argv
[i
], "-o"))
461 "multiple output files '%s' and '%s'\n",
462 output_name
, argv
[i
]);
465 else if (++i
== argc
)
467 fprintf (output
, "*** picosat: argument ot '-o' missing\n");
470 else if (!(file
= fopen (argv
[i
], "w")))
474 "can not write output file '%s'\n", argv
[i
]);
479 output_name
= argv
[i
];
483 else if (!strcmp (argv
[i
], "-t"))
485 if (compact_trace_name
)
489 "multiple compact trace files '%s' and '%s'\n",
490 compact_trace_name
, argv
[i
]);
493 else if (++i
== argc
)
495 fprintf (output
, "*** picosat: argument ot '-t' missing\n");
500 compact_trace_name
= argv
[i
];
504 else if (!strcmp (argv
[i
], "-T"))
506 if (extended_trace_name
)
510 "multiple extended trace files '%s' and '%s'\n",
511 extended_trace_name
, argv
[i
]);
514 else if (++i
== argc
)
516 fprintf (output
, "*** picosat: argument ot '-T' missing\n");
521 extended_trace_name
= argv
[i
];
525 else if (!strcmp (argv
[i
], "-r"))
531 "multiple RUP trace files '%s' and '%s'\n",
532 rup_trace_name
, argv
[i
]);
535 else if (++i
== argc
)
537 fprintf (output
, "*** picosat: argument ot '-r' missing\n");
542 rup_trace_name
= argv
[i
];
546 else if (!strcmp (argv
[i
], "-R"))
552 "multiple RUP trace files '%s' and '%s'\n",
553 rup_trace_name
, argv
[i
]);
556 else if (++i
== argc
)
558 fprintf (output
, "*** picosat: argument ot '-R' missing\n");
561 else if (!(file
= fopen (argv
[i
], "w")))
564 "*** picosat: can not write to '%s'\n", argv
[i
]);
569 rup_trace_name
= argv
[i
];
570 incremental_rup_file
= file
;
573 else if (!strcmp (argv
[i
], "-c"))
575 if (clausal_core_name
)
579 "multiple clausal core files '%s' and '%s'\n",
580 clausal_core_name
, argv
[i
]);
583 else if (++i
== argc
)
585 fprintf (output
, "*** picosat: argument ot '-c' missing\n");
590 clausal_core_name
= argv
[i
];
594 else if (!strcmp (argv
[i
], "-V"))
596 if (variable_core_name
)
600 "multiple variable core files '%s' and '%s'\n",
601 variable_core_name
, argv
[i
]);
604 else if (++i
== argc
)
606 fprintf (output
, "*** picosat: argument ot '-V' missing\n");
611 variable_core_name
= argv
[i
];
615 else if (argv
[i
][0] == '-')
619 "unknown command line option '%s' (try '-h')\n", argv
[i
]);
622 else if (close_input
|| pclose_input
)
626 "multiple input files '%s' and '%s'\n",
627 input_name
, argv
[i
]);
630 else if (has_suffix (argv
[i
], ".gz"))
632 char *cmd
= malloc (strlen (GUNZIP
) + strlen (argv
[i
]));
633 sprintf (cmd
, GUNZIP
, argv
[i
]);
634 if ((file
= popen (cmd
, "r")))
636 input_name
= argv
[i
];
644 "can not read compressed input file '%s'\n", argv
[i
]);
649 else if (!(file
= fopen (argv
[i
], "r"))) /* TODO .gz ? */
652 "*** picosat: can not read input file '%s'\n", argv
[i
]);
657 input_name
= argv
[i
];
663 res
= PICOSAT_UNKNOWN
;
672 "c PicoSAT SAT Solver Version %s\n",
675 fprintf (output
, "c %s\n", picosat_copyright ());
676 fprintf (output
, "c %s\n", picosat_config ());
683 picosat_set_output (output
);
685 picosat_set_verbosity (verbose
);
687 if (verbose
&& (trace
|| defaultphase
))
688 fputs ("c\n", output
);
693 fprintf (output
, "c tracing proof\n");
694 picosat_enable_trace_generation ();
701 "c using %s as default phase\n",
702 defaultphase
< 0 ? "FALSE" : "TRUE");
704 picosat_set_global_default_phase (defaultphase
);
708 fprintf (output
, "c\nc parsing %s\n", input_name
);
710 if ((err_msg
= parse (force
)))
712 fprintf (output
, "%s:%d: %s\n", input_name
, lineno
, err_msg
);
719 for (i
= 1; i
< argc
; i
++)
721 if (!strcmp (argv
[i
], "-l") ||
722 !strcmp (argv
[i
], "-s") ||
723 !strcmp (argv
[i
], "-o") ||
724 !strcmp (argv
[i
], "-t") || !strcmp (argv
[i
], "-c"))
728 else if (!strcmp (argv
[i
], "-a"))
730 assert (i
+ 1 < argc
);
731 assumption
= atoi (argv
[++i
]);
734 picosat_assume (assumption
);
737 fprintf (output
, "c assumption %d\n", assumption
);
744 picosat_print (output
);
750 "c initialized %u variables\n"
751 "c found %u non trivial clauses\n",
752 picosat_variables (),
753 picosat_added_original_clauses ());
755 picosat_set_seed (seed
);
758 "c\nc random number generator seed %u\n",
761 res
= picosat_sat (decision_limit
);
763 if (res
== PICOSAT_UNSATISFIABLE
)
765 fputs ("s UNSATISFIABLE\n", output
);
767 if (compact_trace_name
)
768 write_to_file (compact_trace_name
,
770 picosat_write_compact_trace
);
772 if (extended_trace_name
)
773 write_to_file (extended_trace_name
,
775 picosat_write_extended_trace
);
777 if (!incremental_rup_file
&& rup_trace_name
)
778 write_to_file (rup_trace_name
,
780 picosat_write_rup_trace
);
782 if (clausal_core_name
)
783 write_to_file (clausal_core_name
,
785 picosat_write_clausal_core
);
787 if (variable_core_name
)
788 write_to_file (variable_core_name
,
789 "variable core", write_core_variables
);
791 else if (res
== PICOSAT_SATISFIABLE
)
793 fputs ("s SATISFIABLE\n", output
);
795 if (print_satisfying_assignment
)
799 fputs ("s UNKNOWN\n", output
);
805 fputs ("c\n", output
);
808 "c %.1f seconds total run time\n",
809 picosat_time_stamp () - start_time
);
816 if (incremental_rup_file
)
817 fclose (incremental_rup_file
);