예제 #1
0
void solver_reducedb(solver* s)
{
    int      i, j;
    double   extra_lim = s->cla_inc / vecp_size(&s->learnts);
             /* Remove any clause below this activity */
    clause** learnts = (clause**)vecp_begin(&s->learnts);
    clause** reasons = s->reasons;

    sort(vecp_begin(&s->learnts), vecp_size(&s->learnts), clause_cmp);

    for (i = j = 0; i < vecp_size(&s->learnts) / 2; i++){
        if (clause_size(learnts[i]) > 2
            && reasons[lit_var(*clause_begin(learnts[i]))]
               != learnts[i])
            clause_remove(s,learnts[i]);
        else
            learnts[j++] = learnts[i];
    }
    for (; i < vecp_size(&s->learnts); i++){
        if (clause_size(learnts[i]) > 2
            && reasons[lit_var(*clause_begin(learnts[i]))]
               != learnts[i]
            && clause_activity(learnts[i]) < extra_lim)
            clause_remove(s,learnts[i]);
        else
            learnts[j++] = learnts[i];
    }

    /* printf("reducedb deleted %d\n", vecp_size(&s->learnts) - j); */

    vecp_resize(&s->learnts,j);
}
예제 #2
0
static inline void    vecp_remove(vecp* v, void* e)
{
    void** ws = vecp_begin(v);
    int    j  = 0;

    for (; ws[j] != e  ; j++);
    assert(j < vecp_size(v));
    for (; j < vecp_size(v)-1; j++) ws[j] = ws[j+1];
    vecp_resize(v,vecp_size(v)-1);
}
예제 #3
0
static inline void act_clause_rescale(solver* s) {
    clause** cs = (clause**)vecp_begin(&s->learnts);
    int i;
    for (i = 0; i < vecp_size(&s->learnts); i++){
        float a = clause_activity(cs[i]);
        clause_setactivity(cs[i], a * (float)1e-20);
    }
    s->cla_inc *= (float)1e-20;
}
예제 #4
0
void printclauses(solver* s)
{
   int i;
   clause* c;
   printf("Printing clauses:\n");
   for(i = 0; i < vecp_size(&s->clauses); i++){
      c = vecp_begin(&s->clauses)[i];
      printf("Clause %d:\t\t",i);
      printvalues(c->lits,c->lits + c->size);
      printf("\t\tsize: %d\tlevel_sat: %d\n",c->size,c->level_sat);
   }
}
예제 #5
0
void solver_delete(solver* s)
{
    int i;
    for (i = 0; i < vecp_size(&s->clauses); i++)
        free(vecp_begin(&s->clauses)[i]);

    for (i = 0; i < vecp_size(&s->learnts); i++)
        free(vecp_begin(&s->learnts)[i]);

    /* delete vectors */
    vecp_delete(&s->clauses);
    vecp_delete(&s->learnts);
    veci_delete(&s->order);
    veci_delete(&s->trail_lim);
    veci_delete(&s->tagged);
    veci_delete(&s->stack);
    veci_delete(&s->model);
    free(s->binary);

    /* delete arrays */
    if (s->wlists != 0){
        int i;
        for (i = 0; i < s->size*2; i++)
            vecp_delete(&s->wlists[i]);

        /* if one is different from null, all are */
        free(s->wlists);
        free(s->activity );
        free(s->assigns  );
        free(s->orderpos );
        free(s->reasons  );
        free(s->levels   );
        free(s->trail    );
        free(s->tags     );
    }

    free(s);
}
예제 #6
0
// returns the level_choice of the level backtracked to
lit backtrack_once(solver* s){
   int i;
   clause* c;

   for(i = 0; i < s->size*2; i++){
      if(s->levels[i] == s->cur_level){
         s->assigns[i] = l_Undef;
         s->assigns[lit_neg(i)] = l_Undef;
         s->levels[i] = -1;
      }
   }
   for(i = s->tail; i < vecp_size(&s->clauses); i++){
      c = vecp_begin(&s->clauses)[i];
      if(c->level_sat == s->cur_level){
         c->level_sat = -1;
         s->tail++;
      }
      else break;
   }

   return s->level_choice[s->cur_level--];

}
예제 #7
0
void solver_delete(solver* s)
{
    int i;
    for (i = 0; i < vecp_size(&s->clauses); i++)  // free all clauses
        free(vecp_begin(&s->clauses)[i]);


    // delete vectors
    vecp_delete(&s->clauses);

    // delete arrays
    if (s->decisions != 0){

        // if one is different from null, all are
        free(s->decisions);
        free(s->level_choice);
        free(s->assigns  );
        free(s->levels   );
        free(s->counts   );
    }

    free(s);
}
예제 #8
0
bool   solver_simplify(solver* s)
{
    clause** reasons;
    int type;

    assert(solver_dlevel(s) == 0);

    if (solver_propagate(s) != 0)
        return false;

    if (s->qhead == s->simpdb_assigns || s->simpdb_props > 0)
        return true;

    reasons = s->reasons;
    for (type = 0; type < 2; type++){
        vecp*    cs  = type ? &s->learnts : &s->clauses;
        clause** cls = (clause**)vecp_begin(cs);

        int i, j;
        for (j = i = 0; i < vecp_size(cs); i++){
            if (reasons[lit_var(*clause_begin(cls[i]))] != cls[i] &&
                clause_simplify(s,cls[i]) == l_True)
                clause_remove(s,cls[i]);
            else
                cls[j++] = cls[i];
        }
        vecp_resize(cs,j);
    }

    s->simpdb_assigns = s->qhead;
    /* (shouldn't depend on 'stats' really, but it will do for now) */
    s->simpdb_props   = (int)(s->stats.clauses_literals
                              + s->stats.learnts_literals);

    return true;
}
예제 #9
0
static lbool solver_search(solver* s, int nof_conflicts,
                           int nof_learnts)
{
    int*    levels          = s->levels;
    double  var_decay       = 0.95;
    double  clause_decay    = 0.999;
    double  random_var_freq = 0.02;

    int     conflictC       = 0;
    veci    learnt_clause;

    assert(s->root_level == solver_dlevel(s));

    s->stats.starts++;
    s->var_decay = (float)(1 / var_decay   );
    s->cla_decay = (float)(1 / clause_decay);
    veci_resize(&s->model,0);
    veci_new(&learnt_clause);

    for (;;){
        clause* confl = solver_propagate(s);
        if (confl != 0){
            /* CONFLICT */
            int blevel;

#ifdef VERBOSEDEBUG
            printf(L_IND"**CONFLICT**\n", L_ind);
#endif
            s->stats.conflicts++; conflictC++;
            if (solver_dlevel(s) == s->root_level){
                veci_delete(&learnt_clause);
                return l_False;
            }

            veci_resize(&learnt_clause,0);
            solver_analyze(s, confl, &learnt_clause);
            blevel = veci_size(&learnt_clause) > 1
                     ? levels[lit_var(veci_begin(&learnt_clause)[1])]
                     : s->root_level;
            blevel = s->root_level > blevel ? s->root_level : blevel;
            solver_canceluntil(s,blevel);
            solver_record(s,&learnt_clause);
            act_var_decay(s);
            act_clause_decay(s);

        }else{
            /* NO CONFLICT */
            int next;

            if (nof_conflicts >= 0 && conflictC >= nof_conflicts){
                /* Reached bound on number of conflicts: */
                s->progress_estimate = solver_progress(s);
                solver_canceluntil(s,s->root_level);
                veci_delete(&learnt_clause);
                return l_Undef; }

            if (solver_dlevel(s) == 0)
                /* Simplify the set of problem clauses: */
                solver_simplify(s);

            if (nof_learnts >= 0
                && vecp_size(&s->learnts) - s->qtail >= nof_learnts)
                /* Reduce the set of learnt clauses: */
                solver_reducedb(s);

            /* New variable decision: */
            s->stats.decisions++;
            next = order_select(s,(float)random_var_freq);

            if (next == var_Undef){
                /* Model found: */
                lbool* values = s->assigns;
                int i;
                for (i = 0; i < s->size; i++)
                    veci_push(&s->model,(int)values[i]);
                solver_canceluntil(s,s->root_level);
                veci_delete(&learnt_clause);

                /*
                veci apa; veci_new(&apa);
                for (i = 0; i < s->size; i++)
                    veci_push(&apa,(int)(s->model.ptr[i] == l_True
                        ? toLit(i) : lit_neg(toLit(i))));
                printf("model: ");
                printlits((lit*)apa.ptr,
                    (lit*)apa.ptr + veci_size(&apa)); printf("\n");
                veci_delete(&apa);
                */

                return l_True;
            }

            assume(s,lit_neg(toLit(next)));
        }
    }

#if 0 /* by mao; unreachable code */
    return l_Undef; /* cannot happen */
#endif
}
예제 #10
0
clause* solver_propagate(solver* s)
{
    lbool*  values = s->assigns;
    clause* confl  = (clause*)0;
    lit*    lits;

    /* printf("solver_propagate\n"); */
    while (confl == 0 && s->qtail - s->qhead > 0){
        lit  p  = s->trail[s->qhead++];
        vecp* ws = solver_read_wlist(s,p);
        clause **begin = (clause**)vecp_begin(ws);
        clause **end   = begin + vecp_size(ws);
        clause **i, **j;

        s->stats.propagations++;
        s->simpdb_props--;

        /* printf("checking lit %d: "L_LIT"\n", veci_size(ws),
               L_lit(p)); */
        for (i = j = begin; i < end; ){
            if (clause_is_lit(*i)){
                *j++ = *i;
                if (!enqueue(s,clause_read_lit(*i),clause_from_lit(p))){
                    confl = s->binary;
                    (clause_begin(confl))[1] = lit_neg(p);
                    (clause_begin(confl))[0] = clause_read_lit(*i++);

                    /* Copy the remaining watches: */
                    while (i < end)
                        *j++ = *i++;
                }
            }else{
                lit false_lit;
                lbool sig;

                lits = clause_begin(*i);

                /* Make sure the false literal is data[1]: */
                false_lit = lit_neg(p);
                if (lits[0] == false_lit){
                    lits[0] = lits[1];
                    lits[1] = false_lit;
                }
                assert(lits[1] == false_lit);
                /* printf("checking clause: ");
                   printlits(lits, lits+clause_size(*i));
                   printf("\n"); */

                /* If 0th watch is true, then clause is already
                   satisfied. */
                sig = !lit_sign(lits[0]); sig += sig - 1;
                if (values[lit_var(lits[0])] == sig){
                    *j++ = *i;
                }else{
                    /* Look for new watch: */
                    lit* stop = lits + clause_size(*i);
                    lit* k;
                    for (k = lits + 2; k < stop; k++){
                        lbool sig = lit_sign(*k); sig += sig - 1;
                        if (values[lit_var(*k)] != sig){
                            lits[1] = *k;
                            *k = false_lit;
                            vecp_push(solver_read_wlist(s,
                                lit_neg(lits[1])),*i);
                            goto next; }
                    }

                    *j++ = *i;
                    /* Clause is unit under assignment: */
                    if (!enqueue(s,lits[0], *i)){
                        confl = *i++;
                        /* Copy the remaining watches: */
                        while (i < end)
                            *j++ = *i++;
                    }
                }
            }
        next:
            i++;
        }

        s->stats.inspects += j - (clause**)vecp_begin(ws);
        vecp_resize(ws,j - (clause**)vecp_begin(ws));
    }

    return confl;
}
예제 #11
0
int solver_nclauses(solver* s)
{
    return vecp_size(&s->clauses);
}