Exemple #1
0
void Solver::uncheckedEnqueue(Lit p, Clause* from)
{
#ifdef __PRINT  
  if (from) {
    printClause(*from);
  }
  
  printf("--> ");
  printLit(p);
  printf("\n");

  if (decisionLevel() == 0) {
    printf("Zl: ");
    printLit(p);
    printf("\n");

  }
#endif
    

  assigns [var(p)] = toInt(lbool(!sign(p)));  // <<== abstract but not uttermost effecient
  level   [var(p)] = decisionLevel();
  reason  [var(p)] = from;
  trail.push(p);
}
Exemple #2
0
void Engine::btToLevel(int level) {
	if (decisionLevel() == 0 && level == 0) return;
	assert(decisionLevel() > level);

	btToPos(trail_lim[level]);
  trail_lim.resize(level);
	dec_info.resize(level);
}
Exemple #3
0
double Solver::progressEstimate() const
{
    double  progress = 0;
    double  F = 1.0 / nVars();

    for (int i = 0; i <= decisionLevel(); i++){
        int beg = i == 0 ? 0 : trail_lim[i - 1];
        int end = i == decisionLevel() ? trail.size() : trail_lim[i];
        progress += pow(F, i) * (end - beg);
    }

    return progress / nVars();
}
Exemple #4
0
int MIP::doSimplex() {
//	printf("start simplex\n");
	int r = SIMPLEX_IN_PROGRESS;
	int steps = 0;
	int limit = getLimit();
	for ( ; steps < limit; steps++) {
		if ((r = simplex.simplex()) != SIMPLEX_IN_PROGRESS) break;
//		if (i == limit-1) printf("limit exceeded\n");
//		if (i%10 == 0) printf("Optimum = %.3f, ", optimum());
	}
	simplex.calcObjBound();

//	if (MIP_DEBUG) {
		int bound = (int) ceil((double) simplex.optimum());
		if (engine.opt_type == OPT_MAX) bound = -bound;
		if (steps) fprintf(stderr, "level = %d, %d simplex steps, status = %d, bound = %d\n", decisionLevel(), steps, r, bound);
//		fprintf(stderr, "%d simplex steps, status = %d, bound = %d\n", steps, r, bound);
//		fprintf(stderr, "%d %d\n", bound, engine.opt_type == OPT_MIN ? vars[0]->getMin() : -vars[0]->getMax());
//	}
		exit(0);


	if (decisionLevel() == 0) simplex.saveState(simplex.root);

	return r;
}
Exemple #5
0
bool Solver::addClause(vec<Lit>& ps)
{
    assert(decisionLevel() == 0);

    if (!ok)
        return false;
    else{
        // Check if clause is satisfied and remove false/duplicate literals:
        sort(ps);
        Lit p; int i, j;
        for (i = j = 0, p = lit_Undef; i < ps.size(); i++)
            if (value(ps[i]) == l_True || ps[i] == ~p)
                return true;
            else if (value(ps[i]) != l_False && ps[i] != p)
                ps[j++] = p = ps[i];
        ps.shrink(i - j);
    }

    if (ps.size() == 0)
        return ok = false;
    else if (ps.size() == 1){
        assert(value(ps[0]) == l_Undef);
        uncheckedEnqueue(ps[0]);
        return ok = (propagate() == NULL);
    }else{
        Clause* c = Clause_new(ps, false);
        clauses.push(c);
        attachClause(*c);
    }

    return true;
}
Exemple #6
0
bool SimpSMTSolver::asymm(Var v, Clause& c)
{
  assert(decisionLevel() == 0);

  if (c.mark() || satisfied(c)) return true;

  trail_lim.push(trail.size());
  Lit l = lit_Undef;
  for (int i = 0; i < c.size(); i++)
    if (var(c[i]) != v && value(c[i]) != l_False)
    {
      uncheckedEnqueue(~c[i]);
    }
    else
      l = c[i];

  if (propagate() != NULL){
    cancelUntil(0);
    asymm_lits++;
    if (!strengthenClause(c, l))
      return false;
  }else
    cancelUntil(0);

  return true;
}
Exemple #7
0
/*_________________________________________________________________________________________________
|
|  analyzeFinal : (p : Lit)  ->  [void]
|  
|  Description:
|    Specialized analysis procedure to express the final conflict in terms of assumptions.
|    Calculates the (possibly empty) set of assumptions that led to the assignment of 'p', and
|    stores the result in 'out_conflict'.
|________________________________________________________________________________________________@*/
void Solver::analyzeFinal(Lit p, vec<Lit>& out_conflict)
{
    out_conflict.clear();
    out_conflict.push(p);

    if (decisionLevel() == 0)
        return;

    seen[var(p)] = 1;

    for (int i = trail.size()-1; i >= trail_lim[0]; i--){
        Var x = var(trail[i]);
        if (seen[x]){
            if (reason[x] == NULL){
                assert(level[x] > 0);
                out_conflict.push(~trail[i]);
            }else{
                Clause& c = *reason[x];
                for (int j = 1; j < c.size(); j++)
                    if (level[var(c[j])] > 0)
                        seen[var(c[j])] = 1;
            }
            seen[x] = 0;
        }
    }

    seen[var(p)] = 0;
}
Exemple #8
0
void SAT::addClause(Clause& c, bool one_watch) {
	assert(c.size() > 0);
	if (c.size() == 1) {
		assert(decisionLevel() == 0);
		if (DEBUG) fprintf(stderr, "warning: adding length 1 clause!\n");
		if (value(c[0]) == l_False) TL_FAIL();
		if (value(c[0]) == l_Undef) enqueue(c[0]);
		free(&c);
		return;
	}
	if (!c.learnt) {
		if (c.size() == 2) bin_clauses++;
		else if (c.size() == 3) tern_clauses++;
		else long_clauses++;
	}

	// Mark lazy lits which are used
	if (c.learnt) for (int i = 0; i < c.size(); i++) incVarUse(var(c[i]));

	if (c.size() == 2) {
		if (!one_watch) watches[toInt(~c[0])].push(c[1]);
		watches[toInt(~c[1])].push(c[0]);
		if (!c.learnt) free(&c);
		return;
	}
	if (!one_watch) watches[toInt(~c[0])].push(&c);
	watches[toInt(~c[1])].push(&c);
	if (c.learnt) learnts_literals += c.size();
	else            clauses_literals += c.size();
        
	if (c.received) receiveds.push(&c);
        else if (c.learnt) learnts.push(&c);
	else            clauses.push(&c);
}
Exemple #9
0
/*_________________________________________________________________________________________________
|
|  simplify : [void]  ->  [bool]
|  
|  Description:
|    Simplify the clause database according to the current top-level assigment. Currently, the only
|    thing done here is the removal of satisfied clauses, but more things can be put here.
|________________________________________________________________________________________________@*/
bool MiniSATP::simplify()
{
    remove_satisfied = false;
    assert(decisionLevel() == 0);

    // Modified Lines
    // if (!ok || propagate() != NULL)
        // return ok = false;
    if (!ok) return false;
    Clause * confl = propagate( );
    if ( confl != NULL )
    {
      fillExplanation( confl );
      return ok = false;
    }

    if (nAssigns() == simpDB_assigns || (simpDB_props > 0))
        return true;

    // Remove satisfied clauses:
    removeSatisfied(learnts);
    if (remove_satisfied)        // Can be turned off.
        removeSatisfied(clauses);

    // Remove fixed variables from the variable heap:
    order_heap.filter(VarFilter(*this));

    simpDB_assigns = nAssigns();
    simpDB_props   = clauses_literals + learnts_literals;   // (shouldn't depend on stats really, but it will do for now)

    return true;
}
Exemple #10
0
inline void Engine::newDecisionLevel() {
	trail_inc++;
	trail_lim.push(trail.size());
	sat.newDecisionLevel();
	if (so.mip) mip->newDecisionLevel();
	assert(dec_info.size() == decisionLevel());
}
void SimpSolver::remember(Var v)
{
    assert(decisionLevel() == 0);
    assert(isEliminated(v));

    vec<Lit> clause;

    // Re-activate variable:
    elimtable[v].order = 0;
    setDecisionVar(v, true); // Not good if the variable wasn't a decision variable before. Not sure how to fix this right now.

    if (use_simplification)
        updateElimHeap(v);

    // Reintroduce all old clauses which may implicitly remember other clauses:
    for (int i = 0; i < elimtable[v].eliminated.size(); i++){
        Clause& c = *elimtable[v].eliminated[i];
        clause.clear();
        for (int j = 0; j < c.size(); j++)
            clause.push(c[j]);

        remembered_clauses++;
        check(addClause(clause));
        free(&c);
    }

    elimtable[v].eliminated.clear();
}
// Backward subsumption + backward subsumption resolution
bool SimpSolver::backwardSubsumptionCheck(bool verbose)
{
    int cnt = 0;
    int subsumed = 0;
    int deleted_literals = 0;
    assert(decisionLevel() == 0);

    while (subsumption_queue.size() > 0 || bwdsub_assigns < trail.size()){

        // Check top-level assignments by creating a dummy clause and placing it in the queue:
        if (subsumption_queue.size() == 0 && bwdsub_assigns < trail.size()){
            Lit l = trail[bwdsub_assigns++];
            (*bwdsub_tmpunit)[0] = l;
            bwdsub_tmpunit->calcAbstraction();
            assert(bwdsub_tmpunit->mark() == 0);
            subsumption_queue.insert(bwdsub_tmpunit); }

        Clause&  c = *subsumption_queue.peek(); subsumption_queue.pop();

        if (c.mark()) continue;

        if (verbose && verbosity >= 2 && cnt++ % 1000 == 0)
            reportf("subsumption left: %10d (%10d subsumed, %10d deleted literals)\r", subsumption_queue.size(), subsumed, deleted_literals);

        assert(c.size() > 1 || value(c[0]) == l_True);    // Unit-clauses should have been propagated before this point.

        // Find best variable to scan:
        Var best = var(c[0]);
        for (int i = 1; i < c.size(); i++)
            if (occurs[var(c[i])].size() < occurs[best].size())
                best = var(c[i]);

        // Search all candidates:
        vec<Clause*>& _cs = getOccurs(best);
        Clause**       cs = (Clause**)_cs;

        for (int j = 0; j < _cs.size(); j++)
            if (c.mark())
                break;
            else if (!cs[j]->mark() && cs[j] != &c){
                Lit l = c.subsumes(*cs[j]);

                if (l == lit_Undef)
                    subsumed++, removeClause(*cs[j]);
                else if (l != lit_Error){
                    deleted_literals++;

                    if (!strengthenClause(*cs[j], ~l))
                        return false;

                    // Did current candidate get deleted from cs? Then check candidate at index j again:
                    if (var(l) == best)
                        j--;
                }
            }
    }

    return true;
}
Exemple #13
0
void Solver::uncheckedEnqueue(Lit p, Clause* from)
{
    assert(value(p) == l_Undef);
    assigns [var(p)] = toInt(lbool(!sign(p)));  // <<== abstract but not uttermost effecient
    level   [var(p)] = decisionLevel();
    reason  [var(p)] = from;
    trail.push(p);
}
Exemple #14
0
// Can assume everything has been propagated! (esp. the first two literals are != l_False, unless
// the clause is binary and satisfied, in which case the first literal is true)
// Returns True if clause is satisfied (will be removed), False otherwise.
//
bool Solver::simplify(Clause* c) const
{
    assert(decisionLevel() == 0);
    for (int i = 0; i < c->size(); i++){
        if (value((*c)[i]) == l_True)
            return true;
    }
    return false;
}
Exemple #15
0
// Revert to the state at given level (keeping all assignment at 'level' but not beyond).
//
void Solver::cancelUntil(int level) {
    if (decisionLevel() > level){
        for (int c = trail.size()-1; c >= trail_lim[level]; c--){
            Var     x  = var(trail[c]);
            assigns[x] = toInt(l_Undef);
            insertVarOrder(x); }
        qhead = trail_lim[level];
        trail.shrink(trail.size() - trail_lim[level]);
        trail_lim.shrink(trail_lim.size() - level);
    } }
Exemple #16
0
// Revert to the state at given level.
void Solver::cancelUntil(int level) {
    if (decisionLevel() > level){
        for (int c = trail.size()-1; c >= trail_lim[level]; c--){
            Var     x  = var(trail[c]);
            assigns[x] = toInt(l_Undef);
            reason [x] = GClause_NULL;
            order.undo(x); }
        trail.shrink(trail.size() - trail_lim[level]);
        trail_lim.shrink(trail_lim.size() - level);
        qhead = trail.size(); } }
Exemple #17
0
void SAT::addClause(Lit p, Lit q) {
	if (value(p) == l_True || value(q) == l_True) return;
	if (value(p) == l_False && value(q) == l_False) {
		assert(false);
		TL_FAIL();
	}
	if (value(p) == l_False) {
		assert(decisionLevel() == 0);
		enqueue(q);
		return;
	}
	if (value(q) == l_False) {
		assert(decisionLevel() == 0);
		enqueue(p);
		return;
	}
	bin_clauses++;
	watches[toInt(~p)].push(q);
	watches[toInt(~q)].push(p);
}
Exemple #18
0
void SAT::addClause(Clause& c, bool one_watch) {
	assert(c.size() > 0);
	if (c.size() == 1) {
		assert(decisionLevel() == 0);
		if (DEBUG) fprintf(stderr, "warning: adding length 1 clause!\n");
		if (value(c[0]) == l_False) TL_FAIL();
		if (value(c[0]) == l_Undef) enqueue(c[0]);
		free(&c);
		return;
	}
	if (!c.learnt) {
		if (c.size() == 2) bin_clauses++;
		else if (c.size() == 3) tern_clauses++;
		else long_clauses++;
	}

	// Mark lazy lits which are used
	if (c.learnt) for (int i = 0; i < c.size(); i++) incVarUse(var(c[i]));

	if (c.size() == 2 && ((!c.learnt) || (so.bin_clause_opt))) {
		if (!one_watch) watches[toInt(~c[0])].push(c[1]);
		watches[toInt(~c[1])].push(c[0]);
		if (!c.learnt) free(&c);
		return;
	}
	if (!one_watch) watches[toInt(~c[0])].push(&c);
	watches[toInt(~c[1])].push(&c);
	if (c.learnt) learnts_literals += c.size();
	else            clauses_literals += c.size();
	if (c.learnt) {
          learnts.push(&c);
          if (so.learnt_stats) {
            std::set<int> levels;
            for (int i = 0 ; i < c.size() ; i++) {
              levels.insert(out_learnt_level[i]);
            }
            std::stringstream s;
            //            s << "learntclause,";
            s << c.clauseID() << "," << c.size() << "," << levels.size();
            if (so.learnt_stats_nogood) {
                s << ",";
                for (int i = 0 ; i < c.size() ; i++) {
                    s << (i == 0 ? "" : " ") << getLitString(toInt(c[i]));
              //              s << " (" << out_learnt_level[i] << ")";
                }
            }
            //std::cerr << "\n";
            learntClauseString[c.clauseID()] = s.str();
          }
        } else {
          clauses.push(&c);
        }
}
/*_________________________________________________________________________________________________
|
|  enqueue : (p : Lit) (from : Clause*)  ->  [bool]
|  
|  Description:
|    Puts a new fact on the propagation queue as well as immediately updating the variable's value.
|    Should a conflict arise, FALSE is returned.
|  
|  Input:
|    p    - The fact to enqueue
|    from - [Optional] Fact propagated from this (currently) unit clause. Stored in 'reason[]'.
|           Default value is NULL (no reason).
|  
|  Output:
|    TRUE if fact was enqueued without conflict, FALSE otherwise.
|________________________________________________________________________________________________@*/
bool Solver::enqueue(Lit p, GClause from)
{
    if (value(p) != l_Undef)
        return value(p) != l_False;
    else{
        assigns[var(p)] = toInt(lbool(!sign(p)));
        level  [var(p)] = decisionLevel();
        reason [var(p)] = from;
        trail.push(p);
        return true;
    }
}
Exemple #20
0
inline void SAT::untrailToPos(vec<Lit>& t, int p) {
	int dl = decisionLevel();

	for (int i = t.size(); i-- > p; ) {
		int x = var(t[i]);
		assigns[x] = toInt(l_Undef);
#if PHASE_SAVING
		if (so.phase_saving >= 1 || (so.phase_saving == 1 && dl >= l0))
			polarity[x] = sign(t[i]);
#endif
		insertVarOrder(x);
	}
	t.resize(p);
}
Exemple #21
0
void Solver::saveState()
{
    for (int i = 0; i < watchBackup.changed.size(); i++) {
        const int which = watchBackup.changed[i];

        assert(watchBackup.flags[which] == true);
        watchBackup.flags[which] = false;
    }
    watchBackup.changed.clear();

    backup.touchedClauses.clear();
    backup.sublevel = trail.size();
    backup.level = decisionLevel();
}
Exemple #22
0
void Solver::uncheckedEnqueue(Lit p, Clause* from)
{
    #ifdef RESTORE
    if (backup.stage == 0) {
        printf("setting lit "); printLit(p); printf(" decLevel: %d flag: %d detachedClause: %p\n", decisionLevel(), backup.stage, backup.detachedClause);
    }
    #endif

    assert(value(p) == l_Undef);
    assigns [var(p)] = toInt(lbool(!sign(p)));  // <<== abstract but not uttermost effecient
    level   [var(p)] = decisionLevel();
    reason  [var(p)] = from;
    polarity[var(p)] = sign(p);
    trail.push(p);
}
Exemple #23
0
void SAT::topLevelCleanUp() {
  assert(decisionLevel() == 0);

	for (int i = rtrail[0].size(); i-- > 0; ) free(rtrail[0][i]);
	rtrail[0].clear();

	if (so.sat_simplify && propagations >= next_simp_db) simplifyDB();

	for (int i = 0; i < trail[0].size(); i++) {
        seen[var(trail[0][i])] = true;
        trailpos[var(trail[0][i])] = -1;
    }
	trail[0].clear();
	qhead[0] = 0;

}
Exemple #24
0
void SAT::btToLevel(int level) {
  if (decisionLevel() <= level) return;

	for (int l = trail.size(); l-- > level+1; ) {
		untrailToPos(trail[l], 0);
		for (int i = rtrail[l].size(); i--; ) {
			free(rtrail[l][i]);
		}
	}
  trail.resize(level+1);
	qhead.resize(level+1);
	rtrail.resize(level+1);

	engine.btToLevel(level);
	if (so.mip) mip->btToLevel(level);

}
lbool SimpSolver::solve(const vec<Lit>& assumps, bool do_simp, bool turn_off_simp) {
    vec<Var> extra_frozen;
    lbool     result = l_True;

    do_simp &= use_simplification;
    do_simp &= (decisionLevel() == 0);

    if (do_simp){

        // Assumptions must be temporarily frozen to run variable elimination:
        for (int i = 0; i < assumps.size(); i++){
            Var v = var(assumps[i]);

            // If an assumption has been eliminated, remember it.
            if (isEliminated(v))
                remember(v);

            if (!frozen[v]){
                // Freeze and store.
                setFrozen(v, true);
                extra_frozen.push(v);
            } }

	if(eliminate(turn_off_simp))
	  result = l_True;
	else
	  result = l_False;
    }

    if (result == l_True) 
      result = Solver::solve(assumps);

    if (result == l_True) {
        extendModel();
#ifndef NDEBUG
        verifyModel();
#endif
    }

    if (do_simp)
        // Unfreeze the assumptions that were frozen:
        for (int i = 0; i < extra_frozen.size(); i++)
            setFrozen(extra_frozen[i], false);

    return result;
}
Exemple #26
0
// Revert to the state at given level (keeping all assignment at 'level' but not beyond).
//
void Solver::cancelUntil(int level) {
    #ifdef RESTORE
    printf("------------    Canceling until level %d\n", level);
    #endif
  if (decisionLevel() > level){
    for (int c = trail.size()-1; c >= trail_lim[level]; c--){
      Var     x  = var(trail[c]);
      assigns[x] = toInt(l_Undef);
      insertVarOrder(x);
      #ifdef RESTORE
      printf("Canceling lit ");printLit(trail[c]); printf("\n");
      #endif
    }
    qhead = trail_lim[level];
    trail.shrink(trail.size() - trail_lim[level]);
    trail_lim.shrink(trail_lim.size() - level);
  }
}
bool SimpSolver::implied(const vec<Lit>& c)
{
    assert(decisionLevel() == 0);

    trail_lim.push(trail.size());
    for (int i = 0; i < c.size(); i++)
        if (value(c[i]) == l_True){
            cancelUntil(0);
            return false;
        }else if (value(c[i]) != l_False){
            assert(value(c[i]) == l_Undef);
            uncheckedEnqueue(~c[i]);
        }

    bool result = propagate() != NULL;
    cancelUntil(0);
    return result;
}
bool SimpSolver::strengthenClause(Clause& c, Lit l)
{
    assert(decisionLevel() == 0);
    assert(c.mark() == 0);
    assert(!c.learnt());
    assert(find(watches[toInt(~c[0])], &c));
    assert(find(watches[toInt(~c[1])], &c));

    // FIX: this is too inefficient but would be nice to have (properly implemented)
    // if (!find(subsumption_queue, &c))
    subsumption_queue.insert(&c);

    // If l is watched, delete it from watcher list and watch a new literal
    if (c[0] == l || c[1] == l){
        Lit other = c[0] == l ? c[1] : c[0];
        if (c.size() == 2){
            removeClause(c);
            c.strengthen(l);
        }else{
            c.strengthen(l);
            remove(watches[toInt(~l)], &c);

            // Add a watch for the correct literal
            watches[toInt(~(c[1] == other ? c[0] : c[1]))].push(&c);

            // !! this version assumes that remove does not change the order !!
            //watches[toInt(~c[1])].push(&c);
            clauses_literals -= 1;
        }
    }
    else{
        c.strengthen(l);
        clauses_literals -= 1;
    }

    // if subsumption-indexing is active perform the necessary updates
    if (use_simplification){
        remove(occurs[var(l)], &c);
        n_occ[toInt(l)]--;
        updateElimHeap(var(l));
    }

    return c.size() == 1 ? enqueue(c[0]) && propagate() == NULL : true;
}
Exemple #29
0
void SAT::topLevelCleanUp() {
  assert(decisionLevel() == 0);

	for (int i = rtrail[0].size(); i-- > 0; ) free(rtrail[0][i]);
	rtrail[0].clear();

	if (so.sat_simplify && propagations >= next_simp_db) simplifyDB();

	for (int i = 0; i < trail[0].size(); i++) {
            if (so.debug) {
                std::cerr << "setting true at top-level: " << getLitString(toInt(trail[0][i])) << "\n";
            }
        seen[var(trail[0][i])] = true;
        trailpos[var(trail[0][i])] = -1;
    }
	trail[0].clear();
	qhead[0] = 0;

}
Exemple #30
0
void SAT::btToLevel(int level) {
#if DEBUG_VERBOSE
  std::cerr << "SAT::btToLevel( " << level << ")\n";
#endif
  if (decisionLevel() <= level) return;

	for (int l = trail.size(); l-- > level+1; ) {
		untrailToPos(trail[l], 0);
		for (int i = rtrail[l].size(); i--; ) {
			free(rtrail[l][i]);
		}
	}
  trail.resize(level+1);
	qhead.resize(level+1);
	rtrail.resize(level+1);

	engine.btToLevel(level);
	if (so.mip) mip->btToLevel(level);

}