Пример #1
0
bool solver_addclause(solver* s, lit* begin, lit* end)
{
    lit *i,*j;
    int maxvar;
    lbool* values;
    lit last;

    if (begin == end) return false;

    /* printlits(begin,end); printf("\n"); */
    /* insertion sort */
    maxvar = lit_var(*begin);
    for (i = begin + 1; i < end; i++){
        lit l = *i;
        maxvar = lit_var(l) > maxvar ? lit_var(l) : maxvar;
        for (j = i; j > begin && *(j-1) > l; j--)
            *j = *(j-1);
        *j = l;
    }
    solver_setnvars(s,maxvar+1);

    /* printlits(begin,end); printf("\n"); */
    values = s->assigns;

    /* delete duplicates */
    last = lit_Undef;
    for (i = j = begin; i < end; i++){
        /* printf("lit: "L_LIT", value = %d\n", L_lit(*i),
        (lit_sign(*i) ? -values[lit_var(*i)] : values[lit_var(*i)])); */
        lbool sig = !lit_sign(*i); sig += sig - 1;
        if (*i == lit_neg(last) || sig == values[lit_var(*i)])
            return true;   /* tautology */
        else if (*i != last && values[lit_var(*i)] == l_Undef)
            last = *j++ = *i;
    }

    /* printf("final: "); printlits(begin,j); printf("\n"); */

    if (j == begin)          /* empty clause */
        return false;
    else if (j - begin == 1) /* unit clause */
        return enqueue(s,*begin,(clause*)0);

    /* create new clause */
    vecp_push(&s->clauses,clause_new(s,begin,j,0));

    s->stats.clauses++;
    s->stats.clauses_literals += j - begin;

    return true;
}
Пример #2
0
bool solver_addclause(solver* s, lit* begin, lit* end)
{
    lit *i,*j;
    int maxvar;

    if (begin == end) return false; // Empty clause

    // insertion sort
    maxvar = lit_var(*begin);
    for (i = begin + 1; i < end; i++){
        lit l = *i;
        maxvar = lit_var(l) > maxvar ? lit_var(l) : maxvar;
        for (j = i; j > begin && *(j-1) > l; j--)
            *j = *(j-1);
        *j = l;
    }
    solver_setnvars(s,maxvar+1);

    // create new clause
    vecp_push(&s->clauses,clause_new(s,begin,end));
    s->tail++;  // tail == # of clauses at first.

    return true;
}
Пример #3
0
int glp_minisat1(glp_prob *P)
{     /* solve CNF-SAT problem with MiniSat solver */
      solver *s;
      GLPAIJ *aij;
      int i, j, len, ret, *ind;
      double sum;
      /* check problem object */
      if (P == NULL || P->magic != GLP_PROB_MAGIC)
         xerror("glp_minisat1: P = %p; invalid problem object\n",
            P);
      if (P->tree != NULL)
         xerror("glp_minisat1: operation not allowed\n");
      /* integer solution is currently undefined */
      P->mip_stat = GLP_UNDEF;
      P->mip_obj = 0.0;
      /* check that problem object encodes CNF-SAT instance */
      if (glp_check_cnfsat(P) != 0)
      {  xprintf("glp_minisat1: problem object does not encode CNF-SAT "
            "instance\n");
         ret = GLP_EDATA;
         goto done;
      }
#if 1 /* 07/XI-2015 */
      if (sizeof(void *) != sizeof(int))
      {  xprintf("glp_minisat1: sorry, MiniSat solver is not supported "
            "on 64-bit platforms\n");
         ret = GLP_EFAIL;
         goto done;
      }
#endif
      /* solve CNF-SAT problem */
      xprintf("Solving CNF-SAT problem...\n");
      xprintf("Instance has %d variable%s, %d clause%s, and %d literal%"
         "s\n", P->n, P->n == 1 ? "" : "s", P->m, P->m == 1 ? "" : "s",
         P->nnz, P->nnz == 1 ? "" : "s");
      /* if CNF-SAT has no clauses, it is satisfiable */
      if (P->m == 0)
      {  P->mip_stat = GLP_OPT;
         for (j = 1; j <= P->n; j++)
            P->col[j]->mipx = 0.0;
         goto fini;
      }
      /* if CNF-SAT has an empty clause, it is unsatisfiable */
      for (i = 1; i <= P->m; i++)
      {  if (P->row[i]->ptr == NULL)
         {  P->mip_stat = GLP_NOFEAS;
            goto fini;
         }
      }
      /* prepare input data for the solver */
      s = solver_new();
      solver_setnvars(s, P->n);
      ind = xcalloc(1+P->n, sizeof(int));
      for (i = 1; i <= P->m; i++)
      {  len = 0;
         for (aij = P->row[i]->ptr; aij != NULL; aij = aij->r_next)
         {  ind[++len] = toLit(aij->col->j-1);
            if (aij->val < 0.0)
               ind[len] = lit_neg(ind[len]);
         }
         xassert(len > 0);
         xassert(solver_addclause(s, &ind[1], &ind[1+len]));
      }
      xfree(ind);
      /* call the solver */
      s->verbosity = 1;
      if (solver_solve(s, 0, 0))
      {  /* instance is reported as satisfiable */
         P->mip_stat = GLP_OPT;
         /* copy solution to the problem object */
         xassert(s->model.size == P->n);
         for (j = 1; j <= P->n; j++)
         {  P->col[j]->mipx =
               s->model.ptr[j-1] == l_True ? 1.0 : 0.0;
         }
         /* compute row values */
         for (i = 1; i <= P->m; i++)
         {  sum = 0;
            for (aij = P->row[i]->ptr; aij != NULL; aij = aij->r_next)
               sum += aij->val * aij->col->mipx;
            P->row[i]->mipx = sum;
         }
         /* check integer feasibility */
         for (i = 1; i <= P->m; i++)
         {  if (P->row[i]->mipx < P->row[i]->lb)
            {  /* solution is wrong */
               P->mip_stat = GLP_UNDEF;
               break;
            }
         }
      }
      else
      {  /* instance is reported as unsatisfiable */
         P->mip_stat = GLP_NOFEAS;
      }
      solver_delete(s);
fini: /* report the instance status */
      if (P->mip_stat == GLP_OPT)
      {  xprintf("SATISFIABLE\n");
         ret = 0;
      }
      else if (P->mip_stat == GLP_NOFEAS)
      {  xprintf("UNSATISFIABLE\n");
         ret = 0;
      }
      else
      {  xprintf("glp_minisat1: solver failed\n");
         ret = GLP_EFAIL;
      }
done: return ret;
}