static void encode_clause (Clause * c) { int * p, lit; if (verbose >= 2) { printf ("c [picomcs] encode clause %d :", c->cid); printf (" %d", -clause2selvar (c)); for (p = c->lits; (lit = *p); p++) printf (" %d", lit); fputc ('\n', stdout), fflush (stdout); } picosat_add (ps, -clause2selvar (c)); for (p = c->lits; (lit = *p); p++) picosat_add (ps, lit); picosat_add (ps, 0); }
void feedClausesToPicosat(PicoSAT *p, int forMUS) { for (int cl = 0; cl < clausesptr; cl++) { struct clause *c = clauses + cl; if (forMUS) picosat_add(p, LASTVAR + cl); for (int i = 0; i < c->size; i++) { picosat_add(p, c->lits[i]); } picosat_add(p, 0); } }
static void blocksol (PicoSAT * picosat) { int max_idx = picosat_variables (picosat), i; if (!sol) { sol = malloc (max_idx + 1); memset (sol, 0, max_idx + 1); } for (i = 1; i <= max_idx; i++) sol[i] = (picosat_deref (picosat, i) > 0) ? 1 : -1; for (i = 1; i <= max_idx; i++) picosat_add (picosat, (sol[i] < 0) ? i : -i); picosat_add (picosat, 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; }
static void btor_picosat_add (BtorSATMgr * smgr, int lit) { (void) picosat_add (smgr->solver, lit); }
int main(int argc, char **argv) { int i,j,k,l,m; if (argc < 2) { fprintf(stderr, "usage: sudoku [puzzles]\n"); exit(1); } picosat_init(); /* picosat_enable_trace_generation(); */ mapFile = fopen("var-map.txt", "w"), assert(mapFile); cnfFile = fopen("general.cnf", "w"), assert(cnfFile); if (0 == strcmp(argv[1], "-") || argc <= 1) { inputFile = stdin; } else { inputFile = fopen(argv[1], "r"); } /* create vars */ for (j = 0; j < N; j++) { for (k = 0; k < N; k++) { for (i = 0; i < N; i++) { p[i][j][k] = picosat_inc_max_var(); fprintf(mapFile, "%d = p[%d][%d][%d]\n", p[i][j][k], i, j, k); } } } fprintf(stderr, "%d variables\n", picosat_variables()); /* each cell set to at least one value */ for (j = 0; j < N; j++) { for (k = 0; k < N; k++) { for (i = 0; i < N; i++) { picosat_add(p[i][j][k]); } picosat_add(0); } } /* each cell set to at most one value */ for (j = 0; j < N; j++) { for (k = 0; k < N; k++) { for (i = 0; i < N; i++) { for (l = 0; l < N; l++) { if (i != l) { /* pijk -> !pljk (when l!=i) */ picosat_add(-p[i][j][k]); picosat_add(-p[l][j][k]); picosat_add(0); } } } } } /* column: no cell has the same value */ LINE(i,0,N, j,0,N, k,0,N, { for (l = 0; l < N; l++) { if (l != j) { picosat_add(-p[i][j][k]); picosat_add(-p[i][l][k]); picosat_add(0); } } });
CAMLprim value caml_picosat_add(value lit) { CAMLparam1 (lit); picosat_add(Int_val(lit)); CAMLreturn(Val_unit); }
static const char * parse (PicoSAT * picosat, int force) { int ch, sign, lit, vars, clauses; lineno = 1; inputid = fileno (input); SKIP_COMMENTS: ch = next (); if (ch == 'c') { while ((ch = next ()) != EOF && ch != '\n') ; goto SKIP_COMMENTS; } if (isspace (ch)) goto SKIP_COMMENTS; if (ch != 'p') INVALID_HEADER: return "missing or invalid 'p cnf <variables> <clauses>' header"; if (!isspace (next ())) goto INVALID_HEADER; while (isspace (ch = next ())) ; if (ch != 'c' || next () != 'n' || next () != 'f' || !isspace (next ())) goto INVALID_HEADER; while (isspace (ch = next ())) ; if (!isdigit (ch)) goto INVALID_HEADER; vars = ch - '0'; while (isdigit (ch = next ())) vars = 10 * vars + (ch - '0'); if (!isspace (ch)) goto INVALID_HEADER; while (isspace (ch = next ())) ; if (!isdigit (ch)) goto INVALID_HEADER; clauses = ch - '0'; while (isdigit (ch = next ())) clauses = 10 * clauses + (ch - '0'); if (!isspace (ch) && ch != '\n' ) goto INVALID_HEADER; if (verbose) { fprintf (output, "c parsed header 'p cnf %d %d'\n", vars, clauses); fflush (output); } picosat_adjust (picosat, vars); if (incremental_rup_file) picosat_set_incremental_rup_file (picosat, incremental_rup_file, vars, clauses); lit = 0; READ_LITERAL: ch = next (); if (ch == 'c') { while ((ch = next ()) != EOF && ch != '\n') ; goto READ_LITERAL; } if (ch == EOF) { if (lit) return "trailing 0 missing"; if (clauses && !force) return "clause missing"; return 0; } if (isspace (ch)) goto READ_LITERAL; sign = 1; if (ch == '-') { sign = -1; ch = next (); } if (!isdigit (ch)) return "expected number"; lit = ch - '0'; while (isdigit (ch = next ())) lit = 10 * lit + (ch - '0'); if (!clauses && !force) return "too many clauses"; if (lit) { if (lit > vars && !force) return "maximal variable index exceeded"; lit *= sign; } else clauses--; picosat_add (picosat, lit); goto READ_LITERAL; }
int main (int argc, char ** argv) { int ch, nvars, sclauses, nclauses, sign, lit, group, res; const int * mus, * p; FILE * file; if (argc != 2) die ("usage: picogcnf <gcnf-file>"); if (!(file = fopen (argv[1], "r"))) die ("can not read '%s'", argv[1]); picosat_init (); HEADER: ch = getc (file); if (ch == 'c') { while ((ch = getc (file)) != '\n') if (ch == EOF) die ("unexpected EOF"); goto HEADER; } if (ch != 'p' || getc (file) != ' ' || fscanf (file, "gcnf %d %d %d", &nvars, &sclauses, &ngroups) != 3) die ("invalid header"); nclauses = lit = 0; group = INT_MAX; LOG ("p gcnf %d %d %d\n", nvars, sclauses, ngroups); LIT: ch = getc (file); if (ch == EOF) { if (lit) die ("zero missing"); if (nclauses < sclauses) die ("clauses missing"); goto DONE; } if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') goto LIT; if (lit) { if (ch == '-') { sign = -1; ch = getc (file); } else sign = 1; lit = ch - '0'; while (isdigit (ch = getc (file))) lit = 10 * lit + ch - '0'; if (lit > nvars) die ("maximum variable exceeded"); lit *= sign; if (lit) { LOG ("%d ", lit); } else { LOG ("0\n"); group = INT_MAX; nclauses++; } picosat_add (lit); } else if (ch == '{') { if (nclauses == sclauses) die ("too many clauses"); if (group < INT_MAX) die ("multiple groups per clause"); GROUP: ch = getc (file); if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') goto GROUP; if (!isdigit (ch)) die ("group does not start with digit"); group = ch - '0'; while (isdigit (ch = getc (file))) group = 10 * group + (ch - '0'); if (group > ngroups) die ("maximal group exceeded"); while (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') ch = getc (file); if (ch != '}') die ("expected '}'"); LOG ("{%d} ", group); if (group) picosat_add (-(nvars + group)); lit = INT_MAX; } else die ("expected '{'"); goto LIT; DONE: fclose (file); for (lit = nvars + 1; lit <= nvars + ngroups; lit++) picosat_assume (lit); res = picosat_sat (-1); msg ("first call to SAT solver returned"); if (res == 10) printf ("s SATISFIABLE\n"); else if (res == 20) printf ("s UNSATISFIABLE\n"); else printf ("s UNKNOWN\n"); fflush (stdout); if (res == 20) { mus = picosat_mus_assumptions (0, callback, 1); assert (mus); printf ("v"); for (p = mus; (lit = *p); p++) { assert (nvars + 1 <= lit && lit <= nvars + ngroups); printf (" %d", lit - nvars); } printf (" 0\n"); fflush (stdout); } msg ("max memory %.1f MB", picosat_max_bytes_allocated () / (double)(1<<20)); picosat_reset (); msg ("%d reductions", reductions); return res; }