Пример #1
0
 void Manager::View::cleanClause(Clause & clause) {
   exprView.sort(clause.begin(), clause.end());
   for (Clause::iterator it = clause.begin(); it != clause.end(); ) {
     if (*it == exprView.btrue())
       // [true lit]
       throw Trivial(true);
     else if (*it == exprView.bfalse())
       // [false lit]
       clause.erase(it);
     else if (it+1 != clause.end()) {
       if (*it == *(it+1)) {
         // [repetition of lit]
         clause.erase(it);
       }
       else if (*it == exprView.apply(Expr::Not, *(it+1)))
         // [var with both phases]
         // Relies on how Expr handles negation, so possibly a hack.
         // However, I meant for this property to be usable, so it
         // will be maintained.
         throw Trivial(true);
       else
         it++;
     }
     else
       it++;
   }
   if (clause.size() == 0)
     // empty clause
     throw Trivial(false);
 }
Пример #2
0
void HyperEngine::add_hyper_bin(const Lit p, const Clause& cl)
{
    assert(value(p.var()) == l_Undef);

    #ifdef VERBOSE_DEBUG_FULLPROP
    cout << "Enqueing " << p
    << " with ancestor clause: " << cl
    << endl;
     #endif

    currAncestors.clear();
    size_t i = 0;
    for (Clause::const_iterator
        it = cl.begin(), end = cl.end()
        ; it != end
        ; ++it, i++
    ) {
        if (*it != p) {
            assert(value(*it) == l_False);
            if (varData[it->var()].level != 0)
                currAncestors.push_back(~*it);
        }
    }

    add_hyper_bin(p);
}
Пример #3
0
PropResult PropEngine::prop_normal_helper(
    Clause& c
    , ClOffset offset
    , watch_subarray::iterator &j
    , const Lit p
) {
    #ifdef STATS_NEEDED
    c.stats.clause_looked_at++;
    c.stats.visited_literals++;
    #endif

    // Make sure the false literal is data[1]:
    if (c[0] == ~p) {
        std::swap(c[0], c[1]);
    }

    assert(c[1] == ~p);

    // If 0th watch is true, then clause is already satisfied.
    if (value(c[0]) == l_True) {
        *j = Watched(offset, c[0]);
        j++;
        return PROP_NOTHING;
    }

    // Look for new watch:
    #ifdef STATS_NEEDED
    uint32_t numLitVisited = 0;
    #endif

    for (Lit *k = c.begin() + 2, *end2 = c.end()
        ; k != end2
        ; k++
        #ifdef STATS_NEEDED
        , numLitVisited++
        #endif
    ) {
        //Literal is either unset or satisfied, attach to other watchlist
        if (value(*k) != l_False) {
            c[1] = *k;
            #ifdef STATS_NEEDED
            //propStats.bogoProps += numLitVisited/10;
            c.stats.visited_literals+= numLitVisited;
            #endif
            *k = ~p;
            watches[c[1].toInt()].push(Watched(offset, c[0]));
            return PROP_NOTHING;
        }
    }
    #ifdef STATS_NEEDED
    //propStats.bogoProps += numLitVisited/10;
    c.stats.visited_literals+= numLitVisited;
    #endif

    return PROP_TODO;
}
Пример #4
0
Requirement& Requirement::operator&=(DualClause rhs) {
  // Treat "falsity" like an empty clause
  if ( rhs == DualClause::falsity ) {
    return *this &= Clause();
  }

  // Now we can go through the dualclause like a
  // list. (DualClause::truth is just an empty DualClause)
  while ( rhs.size() != 0 ) {
    // Carefully preserve (steal) the allocated memory for *rhs.begin().
    Clause unitClause;
    unitClause.splice(unitClause.end(), rhs, rhs.begin());

    // DualClauses are stored with their elements negated.  Fix it.
    *unitClause.begin() = ~*unitClause.begin();

    // Add to the requirement
    *this &= move(unitClause);
  }

  return *this;
}
void DistillerLongWithImpl::strsub_with_cache_and_watch(
    bool alsoStrengthen
    , Clause& cl
) {
    //Go through each literal and subsume/strengthen with it
    Lit *lit2 = cl.begin();
    lit2++;
    for (const Lit
        *lit = cl.begin(), *end = cl.end()
        ; lit != end && !isSubsumed
        ; lit++, lit2++
    ) {
        if (lit2 < end) {
            solver->watches.prefetch(lit2->toInt());
        }

        bool subsumed = str_and_sub_clause_with_cache(*lit, alsoStrengthen);
        if (subsumed)
            break;

        str_and_sub_using_watch(cl, *lit, alsoStrengthen);
    }
    assert(lits2.size() > 1);
}
Пример #6
0
/**
@brief Helper function for replace_set()
*/
bool VarReplacer::handleUpdatedClause(
    Clause& c
    , const Lit origLit1
    , const Lit origLit2
) {
    bool satisfied = false;
    std::sort(c.begin(), c.end());
    Lit p;
    uint32_t i, j;
    const uint32_t origSize = c.size();
    for (i = j = 0, p = lit_Undef; i != origSize; i++) {
        assert(solver->varData[c[i].var()].removed == Removed::none);
        if (solver->value(c[i]) == l_True || c[i] == ~p) {
            satisfied = true;
            break;
        }
        else if (solver->value(c[i]) != l_False && c[i] != p)
            c[j++] = p = c[i];
    }
    c.shrink(i - j);
    c.setChanged();

    solver->detachModifiedClause(origLit1, origLit2, origSize, &c);

    #ifdef VERBOSE_DEBUG
    cout << "clause after replacing: " << c << endl;
    #endif

    if (satisfied) {
        (*solver->drup) << findelay;
        return true;
    }
    (*solver->drup) << c << fin << findelay;

    switch(c.size()) {
    case 0:
        solver->ok = false;
        return true;
    case 1 :
        solver->enqueue(c[0]);
        #ifdef STATS_NEEDED
        solver->propStats.propsUnit++;
        #endif
        solver->ok = (solver->propagate().isNULL());
        runStats.removedLongLits += origSize;
        return true;
    case 2:
        solver->attachBinClause(c[0], c[1], c.red());
        runStats.removedLongLits += origSize;
        return true;

    case 3:
        solver->attachTriClause(c[0], c[1], c[2], c.red());
        runStats.removedLongLits += origSize;
        return true;

    default:
        solver->attachClause(c);
        runStats.removedLongLits += origSize - c.size();
        return false;
    }

    assert(false);
    return false;
}