diff --git a/libsolutil/BooleanLP.cpp b/libsolutil/BooleanLP.cpp index 7b0c97383..11d0da6a9 100644 --- a/libsolutil/BooleanLP.cpp +++ b/libsolutil/BooleanLP.cpp @@ -248,7 +248,7 @@ pair> BooleanLPSolver::check(vector cons } set previousConditionalConstraints; - auto theorySolver = [&](map const& _booleanAssignment) -> optional + auto theorySolver = [&](size_t /*_decisionLevel*/, map const& _booleanAssignment) -> optional { SolvingState lpStateToCheck = lpState; set conditionalConstraints; @@ -281,8 +281,9 @@ pair> BooleanLPSolver::check(vector cons else return nullopt; }; + auto backtrackNotify = [](size_t /*_decisionLevel*/) {}; - auto optionalModel = CDCL{move(booleanVariables), clauses, theorySolver}.solve(); + auto optionalModel = CDCL{move(booleanVariables), clauses, theorySolver, backtrackNotify}.solve(); if (!optionalModel) { cout << "==============> CDCL final result: unsatisfiable." << endl; diff --git a/libsolutil/CDCL.cpp b/libsolutil/CDCL.cpp index 58326a88e..25c730b52 100644 --- a/libsolutil/CDCL.cpp +++ b/libsolutil/CDCL.cpp @@ -32,9 +32,11 @@ using namespace solidity::util; CDCL::CDCL( vector _variables, vector const& _clauses, - std::function(std::map const&)> _theorySolver + std::function(size_t, std::map const&)> _theorySolver, + std::function _backtrackNotify ): m_theorySolver(_theorySolver), + m_backtrackNotify(_backtrackNotify), m_variables(move(_variables)), order(VarOrderLt(activity)) { @@ -69,7 +71,7 @@ bool CDCL::solve_loop(const uint32_t max_conflicts, CDCL::Model& model, int& sol optional conflictClause = propagate(); if (!conflictClause && m_theorySolver) { - conflictClause = m_theorySolver(m_assignments); + conflictClause = m_theorySolver(currentDecisionLevel(), m_assignments); // if (conflictClause) // cout << "Theory gave us conflict: " << toString(*conflictClause) << endl; } @@ -323,6 +325,8 @@ void CDCL::cancelUntil(size_t _backtrackLevel) } m_decisionPoints.resize(_backtrackLevel); m_assignmentQueuePointer = m_assignmentTrail.size(); + if (m_backtrackNotify) + m_backtrackNotify(currentDecisionLevel()); solAssert(currentDecisionLevel() == _backtrackLevel); } diff --git a/libsolutil/CDCL.h b/libsolutil/CDCL.h index 0c1ac1ccf..da8837eb6 100644 --- a/libsolutil/CDCL.h +++ b/libsolutil/CDCL.h @@ -59,7 +59,8 @@ public: CDCL( std::vector _variables, std::vector const& _clauses, - std::function(std::map const&)> _theoryPropagator = {} + std::function(size_t, std::map const&)> _theorySolver = {}, + std::function _backtrackNotify = {} ); std::optional solve(); @@ -102,7 +103,8 @@ private: /// Callback that receives an assignment and uses the theory to either returns nullopt ("satisfiable") /// or a conflict clause, i.e. a clauses that is false in the theory with the given assignments. - std::function(std::map)> m_theorySolver; + std::function(size_t, std::map)> m_theorySolver; + std::function m_backtrackNotify; std::vector m_variables; /// includes the learnt clauses