Exemple #1
0
int main (int argc, char ** argv) {
  int i, * p, n, oldn, red, nonred, res, round, printed, len;
  const char * err;
  const int * q;
  char * cmd;
  Cls * c;
#ifndef NDEBUG
  int tmp;
#endif
  start = picosat_time_stamp ();
  for (i = 1; i < argc; i++) {
    if (!strcmp (argv[i], "-h")) {
      fputs (USAGE, stdout);
      exit (0);
    } else if (!strcmp (argv[i], "-v")) {
      if (verbose < 0) die ("'-v' option after '-q'");
      verbose++;
    } else if (!strcmp (argv[i], "-q")) {
      if (verbose < 0) die ("two '-q' options");
      if (verbose > 0) die ("'-q' option after '-v'");
      verbose = -1;
    } else if (!strcmp (argv[i], "-n")) nowitness = 1;
    else if (argv[i][0] == '-' && argv[i][1])
      die ("invalid command line option '%s'", argv[i]);
    else if (output_name) die ("too many arguments");
    else if (!input_name) input_name = argv[i];
    else output_name = argv[i];
  }
  if (!output_name) warn ("no output file given");
  if (input_name && strcmp (input_name, "-")) {
    len = strlen (input_name);
    if (len >= 3 && !strcmp (input_name + len - 3, ".gz")) {
      cmd = malloc (len + 20);
      sprintf (cmd, "gunzip -c %s 2>/dev/null", input_name);
      input_file = popen (cmd, "r");
      pclose_input = 1;
      free (cmd);
    } else input_file = fopen (input_name, "r"), fclose_input = 1;
    if (!input_file) die ("can not read '%s'", input_name);
  } else input_file = stdin, input_name = "-";
  if ((err =  parse ())) {
    fprintf (stdout, "%s:%d: %s\n", input_name, lineno, err);
    fflush (stdout);
    exit (1);
  }
  if (fclose_input) fclose (input_file);
  if (pclose_input) pclose (input_file);
  ps = picosat_init ();
  picosat_set_prefix (ps, "c [picosat] ");
  picosat_set_output (ps, stdout);
  if (verbose > 1) picosat_set_verbosity (ps, verbose - 1);
  printed = 0;
  if (!picosat_enable_trace_generation (ps))
    warn ("PicoSAT compiled without trace generation"),
    warn ("core extraction disabled");
  else {
    n = nclauses;
    nonred = 0;
    for (round = 1; round <= MAXCOREROUNDS; round++) {
      if (verbose > 1)
        msg (1, "starting core extraction round %d", round);
      picosat_set_seed (ps, round);
      for (i = 0; i < nclauses; i++) {
        c = clauses + i;
        if (c->red) {
          picosat_add (ps, 1);
          picosat_add (ps, -1);
        } else {
          for (p = c->lits; *p; p++)
            picosat_add (ps, *p);
        }
#ifndef NDEBUG
        tmp =
#endif
        picosat_add (ps, 0);
        assert (tmp == i);
      }
      res = picosat_sat (ps, -1);
      if (res == 10) { assert (round == 1); goto SAT; }
      assert (res == 20);
      if (!printed) {
        assert (round == 1);
        printed = 1;
        if (verbose >= 0)
          printf ("s UNSATISFIABLE\n"),
          fflush (stdout);
      }
      for (i = 0; i < nclauses; i++) {
        c = clauses + i;
        if (c->red) { assert (!picosat_coreclause (ps, i)); continue; }
        if (picosat_coreclause (ps, i)) continue;
        c->red = 1;
      }
      oldn = n;
      n = 0;
      for (i = 0; i < nclauses; i++) if (!clauses[i].red) n++;
      msg (1, "extracted core %d of size %d = %0.f%% out of %d after %.1f sec",
           round, n, percent (n, nclauses), nclauses,
           picosat_time_stamp () - start);
      assert (oldn >= n);
      picosat_reset (ps);
      ps = picosat_init ();
      picosat_set_prefix (ps, "c [picosat] ");
      picosat_set_output (ps, stdout);
      if (round >= MINCOREROUNDS) {
        red = oldn - n;
        if (red < 10 && (100*red + 99)/oldn < 2) {
          nonred++;
          if (nonred > MAXNONREDROUNDS) break;
        }
      }
      if (round < MAXCOREROUNDS) picosat_enable_trace_generation (ps);
    }
  }
  for (i = 0; i < nclauses; i++) {
    c = clauses + i;
    if (c->red) {
      picosat_add (ps, 1);
      picosat_add (ps, -1);
#ifndef NDEBUG
      tmp =
#endif
      picosat_add (ps, 0);
      assert (tmp == i);
      continue;
    }
    c->lit = nvars + i + 1;
    picosat_add (ps, -c->lit);
    for (p = c->lits; *p; p++)
      (void) picosat_add (ps, *p);
#ifndef NDEBUG
    tmp =
#endif
    picosat_add (ps, 0);
    assert (tmp == i);
  }
  for (i = 0; i < nclauses; i++) {
    c = clauses + i;
    if (c->red) continue;
    picosat_assume (ps, c->lit);
  }
  res = picosat_sat (ps, -1);
  if (res == 20) {
    if (!printed && verbose >= 0)
      printf ("s UNSATISFIABLE\n"), fflush (stdout);
    for (i = 0; i < nclauses; i++) clauses[i].red = 1;
    q = picosat_mus_assumptions (ps, 0, callback, 1);
    while ((i = *q++)) {
      i -= nvars + 1;
      assert (0 <= i && i < nclauses);
      clauses[i].red = 0;
    }
  } else {
SAT:
    assert (res == 10);
    if (!printed && verbose >= 0)
      printf ("s SATISFIABLE\n"), fflush (stdout);
    if (!nowitness && verbose >= 0) {
      for (i = 1; i <= nvars; i++)
        printf ("v %d\n", ((picosat_deref (ps, i) < 0) ? -1 : 1) * i);
      printf ("v 0\n");
    }
  }
  if (verbose > 0) picosat_stats (ps);
  picosat_reset (ps);
  n = 0;
  for (i = 0; i < nclauses; i++) if (!clauses[i].red) n++;
  red = nclauses - n;
  msg (1, "found %d redundant clauses %.0f%%", red, percent (red, nclauses));
  if (res == 20)
    msg (0, "computed MUS of size %d out of %d (%.0f%%)",
         n, nclauses, percent (n, nclauses));
  if (output_name && strcmp (output_name, "-")) {
    output_file = fopen (output_name, "w");
    if (!output_file) die ("can not write '%s'", output_name);
    close_output = 1;
  } else if (output_name && !strcmp (output_name, "-")) output_file = stdout;
  if (output_file) {
    fprintf (output_file, "p cnf %d %d\n", nvars, n);
    for (i = 0; i < nclauses; i++)
      if (!clauses[i].red) {
        for (p = clauses[i].lits; *p; p++) fprintf (output_file, "%d ", *p);
        fprintf (output_file, "0\n");
      }
    if (close_output) fclose (output_file);
  }
  if (res == 20) {
    if (!nowitness && verbose >= 0) {
      for (i = 0; i < nclauses; i++)
        if (!clauses[i].red) printf ("v %d\n", i+1);
      printf ("v 0\n");
    }
  }
  msg (1, "%s %d irredundant clauses %.0f%%",
       output_file ? "printed" : "computed", n, percent (n, nclauses));
  for (i = 0; i < nclauses; i++) free (clauses[i].lits);
  free (clauses);
  free (lits);
  msg (1, "%d reductions in %.1f seconds",
       reductions, picosat_time_stamp () - start);
  return res;
}
CAMLprim value caml_picosat_enable_trace(value unit) {
    CAMLparam0 ();
    picosat_enable_trace_generation();
    CAMLreturn(Val_unit);
}