Esempio n. 1
0
void DeductionsImpl::perform_deductions(GraphBuilder *gb)
{
    Callees &callees = gb->getFunctions();
    for(Callee *e:callees) {
        if(!e->realtime_p() && !rt(e))
            continue;

        //Deduce all children must be realtime
        for(Call *c:gb->getCalls()) {
            if(c->first == e && !c->second->realtime_p()
                    && !rt(c->second))
                deduce(c);
        }
    }
}
Esempio n. 2
0
valuation solver::solve() {
    if (m_remaining_clauses == -1) // not satisfiable
        return { { } };

    // solver has to be fully constructed in order to store pointer to `this` somewhere
    if (m_options.guess == guess_mode::VSIDS) {
        m_vsids_score.resize(m_assignment.size());
        for (auto v = 0; v < m_assignment.size(); ++v)
            m_vsids_score[v] = std::make_pair(0.0, m_vsids_heap.push({ v, this }));
    }

    int level = 0;
    auto conflict_nb = 0;
    auto max_learnt = m_clauses.size() / 3;

    while (m_first || m_remaining_clauses > 0) {
        m_first = false;
        auto conflict = deduce(level);
        if (conflict != nullptr) {
#ifdef DEBUG
            std::cout << "conflict" << std::endl;
#endif
            ++conflict_nb;

            if (level == 0) {
                m_remaining_clauses = -1;
                return { { } };
            }

            auto old_level = level;

            detail::clause learnt;
            if (conflict != &m_dummy_clause && can_learn()) {
                auto knowledge = learn(conflict, level);
                level = knowledge.second + 1;
                learnt = std::move(knowledge.first);
            }

            if (conflict_nb % 100 == 0 && m_options.guess == guess_mode::VSIDS) {
                for (auto && v : m_vsids_score)
                    v.first /= 2.0;
            }

            if (conflict != &m_dummy_clause && m_options.cdcl == cdcl_mode::INTERACTIVE)
                interac(conflict, old_level, learnt.watch_0());

            auto lit = backtrack(level);
            --level;
#ifdef DEBUG
            std::cout << "go back to level " << level << std::endl;
#endif

            if (conflict != &m_dummy_clause && can_learn()) {
                lit = learnt.watch_0();
                auto reason = learnt.litterals().size() != 1 ?
                    add_clause(std::move(learnt)) : nullptr;
                enqueue(lit, level, reason);
            } else
                enqueue(detail::neg(lit), level, nullptr);
        } else {
            ++level;
#ifdef DEBUG
            std::cout << "level " << level << std::endl;
#endif

            // we have a full valuation
            if (m_remaining_variables == 0 || m_remaining_clauses == 0)
                break;

            if (m_options.forget && m_learnt.size() > max_learnt)
                remove_learnt(m_learnt.size() / 2); // remove half of the learnt clauses

            if (m_options.guess == guess_mode::MOMS) {
                m_min_clause = 2 * m_remaining_variables;
                for (auto && c : m_clauses) {
                    if (c.satisfied_by() != -1)
                        continue;
                    auto size = c.count();
                    if (size <= m_min_clause)
                        m_min_clause = size;
                }
            }

            auto lit = (this->*m_guess)();
            assert(lit != -1);

#ifdef DEBUG
            std::cout << "guess " << new_to_old_lit(lit) << std::endl;
#endif
            enqueue(lit, level, nullptr);
        }
    }

    m_remaining_clauses = 0;


    /* compute a mapping int -> bool out of our valuation stack */

#ifdef DEBUG
    std::cout << "satisfiable" << std::endl;
#endif

    std::unordered_map<int, bool> result;

    for (auto v = 0; v < m_assignment.size(); ++v) {
        result.emplace(
            m_old_variables[v],
            m_assignment[v].pol == detail::polarity::VTRUE ? true : false
        );
    }

    return result;
}