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); } } }
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; }