LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/prop - cryptominisat.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 80 119 67.2 %
Date: 2026-03-23 10:24:23 Functions: 16 24 66.7 %
Branches: 22 54 40.7 %

           Branch data     Line data    Source code
       1                 :            : /******************************************************************************
       2                 :            :  * This file is part of the cvc5 project.
       3                 :            :  *
       4                 :            :  * Copyright (c) 2009-2026 by the authors listed in the file AUTHORS
       5                 :            :  * in the top-level source directory and their institutional affiliations.
       6                 :            :  * All rights reserved.  See the file COPYING in the top-level source
       7                 :            :  * directory for licensing information.
       8                 :            :  * ****************************************************************************
       9                 :            :  *
      10                 :            :  * SAT Solver.
      11                 :            :  *
      12                 :            :  * Implementation of the cryptominisat for cvc5 (bit-vectors).
      13                 :            :  */
      14                 :            : 
      15                 :            : #include "prop/cryptominisat.h"
      16                 :            : 
      17                 :            : #ifdef CVC5_USE_CRYPTOMINISAT
      18                 :            : 
      19                 :            : #include <cryptominisat5/cryptominisat.h>
      20                 :            : 
      21                 :            : #include "util/resource_manager.h"
      22                 :            : #include "util/statistics_registry.h"
      23                 :            : 
      24                 :            : namespace cvc5::internal {
      25                 :            : namespace prop {
      26                 :            : 
      27                 :            : using CMSatVar = unsigned;
      28                 :            : 
      29                 :            : // helper functions
      30                 :            : namespace {
      31                 :            : 
      32                 :       6853 : CMSat::Lit toInternalLit(SatLiteral lit)
      33                 :            : {
      34         [ -  + ]:       6853 :   if (lit == undefSatLiteral)
      35                 :            :   {
      36                 :          0 :     return CMSat::lit_Undef;
      37                 :            :   }
      38                 :       6853 :   return CMSat::Lit(lit.getSatVariable(), lit.isNegated());
      39                 :            : }
      40                 :            : 
      41                 :          8 : SatLiteral toSatLiteral(CMSat::Lit lit)
      42                 :            : {
      43         [ -  + ]:          8 :   if (lit == CMSat::lit_Undef)
      44                 :            :   {
      45                 :          0 :     return undefSatLiteral;
      46                 :            :   }
      47                 :          8 :   return SatLiteral(lit.var(), lit.sign());
      48                 :            : }
      49                 :            : 
      50                 :        157 : SatValue toSatLiteralValue(CMSat::lbool res)
      51                 :            : {
      52         [ +  + ]:        157 :   if (res == CMSat::l_True) return SAT_VALUE_TRUE;
      53         [ -  + ]:        105 :   if (res == CMSat::l_Undef) return SAT_VALUE_UNKNOWN;
      54 [ -  + ][ -  + ]:        105 :   Assert(res == CMSat::l_False);
                 [ -  - ]
      55                 :        105 :   return SAT_VALUE_FALSE;
      56                 :            : }
      57                 :            : 
      58                 :       2700 : void toInternalClause(const SatClause& clause,
      59                 :            :                       std::vector<CMSat::Lit>& internal_clause)
      60                 :            : {
      61         [ +  + ]:       9530 :   for (const SatLiteral i : clause)
      62                 :            :   {
      63                 :       6830 :     internal_clause.push_back(toInternalLit(i));
      64                 :            :   }
      65 [ -  + ][ -  + ]:       2700 :   Assert(clause.size() == internal_clause.size());
                 [ -  - ]
      66                 :       2700 : }
      67                 :            : 
      68                 :            : }  // helper functions
      69                 :            : 
      70                 :         10 : CryptoMinisatSolver::CryptoMinisatSolver(StatisticsRegistry& registry,
      71                 :         10 :                                          const std::string& name)
      72                 :         10 :     : d_solver(new CMSat::SATSolver()),
      73                 :         10 :       d_numVariables(0),
      74                 :         10 :       d_okay(true),
      75                 :         10 :       d_statistics(registry, name),
      76                 :         10 :       d_resmgr(nullptr)
      77                 :            : {
      78                 :         10 : }
      79                 :            : 
      80                 :         10 : void CryptoMinisatSolver::initialize()
      81                 :            : {
      82                 :         10 :   d_true = newVar(false, true);
      83                 :         10 :   d_false = newVar(false, true);
      84                 :            : 
      85                 :         10 :   std::vector<CMSat::Lit> clause(1);
      86                 :         10 :   clause[0] = CMSat::Lit(d_true, false);
      87                 :         10 :   d_solver->add_clause(clause);
      88                 :            : 
      89                 :         10 :   clause[0] = CMSat::Lit(d_false, true);
      90                 :         10 :   d_solver->add_clause(clause);
      91                 :         10 : }
      92                 :            : 
      93                 :         20 : CryptoMinisatSolver::~CryptoMinisatSolver() {}
      94                 :            : 
      95                 :          0 : void CryptoMinisatSolver::setTimeLimit(ResourceManager* resmgr)
      96                 :            : {
      97                 :          0 :   d_resmgr = resmgr;
      98                 :          0 : }
      99                 :            : 
     100                 :         13 : void CryptoMinisatSolver::setMaxTime()
     101                 :            : {
     102         [ -  + ]:         13 :   if (d_resmgr)
     103                 :            :   {
     104                 :            :     // Set time limit to remaining number of seconds.
     105                 :          0 :     d_solver->set_max_time(d_resmgr->getRemainingTime() / 1000.0);
     106                 :            :   }
     107                 :         13 : }
     108                 :            : 
     109                 :          0 : ClauseId CryptoMinisatSolver::addXorClause(const SatClause& clause,
     110                 :            :                                            bool rhs,
     111                 :            :                                            CVC5_UNUSED bool removable)
     112                 :            : {
     113         [ -  - ]:          0 :   Trace("sat::cryptominisat") << "Add xor clause " << clause <<" = " << rhs << "\n";
     114                 :            : 
     115         [ -  - ]:          0 :   if (!d_okay) {
     116         [ -  - ]:          0 :     Trace("sat::cryptominisat") << "Solver unsat: not adding clause.\n";
     117                 :          0 :     return ClauseIdError;
     118                 :            :   }
     119                 :            : 
     120                 :          0 :   ++(d_statistics.d_xorClausesAdded);
     121                 :            : 
     122                 :            :   // ensure all sat literals have positive polarity by pushing
     123                 :            :   // the negation on the result
     124                 :          0 :   std::vector<CMSatVar> xor_clause;
     125         [ -  - ]:          0 :   for (unsigned i = 0; i < clause.size(); ++i) {
     126                 :          0 :     xor_clause.push_back(toInternalLit(clause[i]).var());
     127                 :          0 :     rhs ^= clause[i].isNegated();
     128                 :            :   }
     129                 :          0 :   const bool res = d_solver->add_xor_clause(xor_clause, rhs);
     130                 :          0 :   d_okay &= res;
     131                 :          0 :   return ClauseIdError;
     132                 :          0 : }
     133                 :            : 
     134                 :       2700 : ClauseId CryptoMinisatSolver::addClause(const SatClause& clause,
     135                 :            :                                         CVC5_UNUSED bool removable)
     136                 :            : {
     137         [ +  - ]:       2700 :   Trace("sat::cryptominisat") << "Add clause " << clause <<"\n";
     138                 :            : 
     139         [ -  + ]:       2700 :   if (!d_okay) {
     140         [ -  - ]:          0 :     Trace("sat::cryptominisat") << "Solver unsat: not adding clause.\n";
     141                 :          0 :     return ClauseIdError;
     142                 :            :   }
     143                 :            : 
     144                 :       2700 :   ++(d_statistics.d_clausesAdded);
     145                 :            : 
     146                 :       2700 :   std::vector<CMSat::Lit> internal_clause;
     147                 :       2700 :   toInternalClause(clause, internal_clause);
     148                 :       2700 :   const bool nowOkay = d_solver->add_clause(internal_clause);
     149                 :       2700 :   d_okay &= nowOkay;
     150                 :       2700 :   return ClauseIdError;
     151                 :       2700 : }
     152                 :            : 
     153                 :          0 : bool CryptoMinisatSolver::ok() const { return d_okay; }
     154                 :            : 
     155                 :       1029 : SatVariable CryptoMinisatSolver::newVar(CVC5_UNUSED bool isTheoryAtom,
     156                 :            :                                         CVC5_UNUSED bool canErase)
     157                 :            : {
     158                 :       1029 :   d_solver->new_var();
     159                 :       1029 :   ++d_numVariables;
     160 [ -  + ][ -  + ]:       1029 :   Assert(d_numVariables == d_solver->nVars());
                 [ -  - ]
     161                 :       1029 :   return d_numVariables - 1;
     162                 :            : }
     163                 :            : 
     164                 :          0 : SatVariable CryptoMinisatSolver::trueVar() {
     165                 :          0 :   return d_true;
     166                 :            : }
     167                 :            : 
     168                 :          0 : SatVariable CryptoMinisatSolver::falseVar() {
     169                 :          0 :   return d_false;
     170                 :            : }
     171                 :            : 
     172                 :          0 : void CryptoMinisatSolver::interrupt(){
     173                 :          0 :   d_solver->interrupt_asap();
     174                 :          0 : }
     175                 :            : 
     176                 :          0 : SatValue CryptoMinisatSolver::solve(){
     177                 :          0 :   TimerStat::CodeTimer codeTimer(d_statistics.d_solveTime);
     178                 :          0 :   ++d_statistics.d_statCallsToSolve;
     179                 :          0 :   setMaxTime();
     180                 :          0 :   return toSatLiteralValue(d_solver->solve());
     181                 :          0 : }
     182                 :            : 
     183                 :          0 : SatValue CryptoMinisatSolver::solve(CVC5_UNUSED long unsigned int& resource) {
     184                 :            :   // CMSat::SalverConf conf = d_solver->getConf();
     185                 :          0 :   Unreachable() << "Not sure how to set different limits for calls to solve in "
     186                 :          0 :                    "Cryptominisat";
     187                 :            :   return solve();
     188                 :            : }
     189                 :            : 
     190                 :         13 : SatValue CryptoMinisatSolver::solve(const std::vector<SatLiteral>& assumptions)
     191                 :            : {
     192                 :         13 :   TimerStat::CodeTimer codeTimer(d_statistics.d_solveTime);
     193                 :         13 :   std::vector<CMSat::Lit> assumpts;
     194         [ +  + ]:         36 :   for (const SatLiteral& lit : assumptions)
     195                 :            :   {
     196                 :         23 :     assumpts.push_back(toInternalLit(lit));
     197                 :            :   }
     198                 :         13 :   ++d_statistics.d_statCallsToSolve;
     199                 :         13 :   setMaxTime();
     200                 :         26 :   return toSatLiteralValue(d_solver->solve(&assumpts));
     201                 :         13 : }
     202                 :            : 
     203                 :          4 : void CryptoMinisatSolver::getUnsatAssumptions(
     204                 :            :     std::vector<SatLiteral>& assumptions)
     205                 :            : {
     206         [ +  + ]:         12 :   for (const CMSat::Lit& lit : d_solver->get_conflict())
     207                 :            :   {
     208                 :          8 :     assumptions.push_back(toSatLiteral(~lit));
     209                 :            :   }
     210                 :          4 : }
     211                 :            : 
     212                 :        144 : SatValue CryptoMinisatSolver::value(SatLiteral l){
     213                 :        144 :   const std::vector<CMSat::lbool> model = d_solver->get_model();
     214                 :        144 :   CMSatVar var = l.getSatVariable();
     215 [ -  + ][ -  + ]:        144 :   Assert(var < model.size());
                 [ -  - ]
     216                 :        144 :   CMSat::lbool value = model[var];
     217                 :        288 :   return toSatLiteralValue(value);
     218                 :        144 : }
     219                 :            : 
     220                 :        144 : SatValue CryptoMinisatSolver::modelValue(SatLiteral l) { return value(l); }
     221                 :            : 
     222                 :            : // Satistics for CryptoMinisatSolver
     223                 :            : 
     224                 :         10 : CryptoMinisatSolver::Statistics::Statistics(StatisticsRegistry& registry,
     225                 :         10 :                                             const std::string& prefix)
     226                 :         10 :     : d_statCallsToSolve(registry.registerInt(prefix + "cryptominisat::calls_to_solve")),
     227                 :         10 :       d_xorClausesAdded(registry.registerInt(prefix + "cryptominisat::xor_clauses")),
     228                 :         10 :       d_clausesAdded(registry.registerInt(prefix + "cryptominisat::clauses")),
     229                 :         10 :       d_solveTime(registry.registerTimer(prefix + "cryptominisat::solve_time"))
     230                 :            : {
     231                 :         10 : }
     232                 :            : 
     233                 :            : }  // namespace prop
     234                 :            : }  // namespace cvc5::internal
     235                 :            : #endif

Generated by: LCOV version 1.14