LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/smt - context_manager.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 86 91 94.5 %
Date: 2026-03-04 11:41:08 Functions: 15 16 93.8 %
Branches: 42 66 63.6 %

           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                 :            :  * Utility for managing the contexts
      11                 :            :  */
      12                 :            : 
      13                 :            : #include "smt/context_manager.h"
      14                 :            : 
      15                 :            : #include "base/modal_exception.h"
      16                 :            : #include "options/base_options.h"
      17                 :            : #include "options/main_options.h"
      18                 :            : #include "options/option_exception.h"
      19                 :            : #include "options/smt_options.h"
      20                 :            : #include "smt/env.h"
      21                 :            : #include "smt/smt_driver.h"
      22                 :            : #include "smt/solver_engine_state.h"
      23                 :            : 
      24                 :            : namespace cvc5::internal {
      25                 :            : namespace smt {
      26                 :            : 
      27                 :      74598 : ContextManager::ContextManager(Env& env, SolverEngineState& state)
      28                 :            :     : EnvObj(env),
      29                 :      74598 :       d_state(state),
      30                 :      74598 :       d_smt(nullptr),
      31                 :      74598 :       d_pendingPops(0),
      32                 :      74598 :       d_needPostsolve(false)
      33                 :            : {
      34                 :      74598 : }
      35                 :            : 
      36                 :        687 : void ContextManager::notifyResetAssertions()
      37                 :            : {
      38                 :        687 :   doPendingPops();
      39         [ +  + ]:       1247 :   while (!d_userLevels.empty())
      40                 :            :   {
      41                 :        560 :     userPop();
      42                 :            :   }
      43                 :            :   // Remember the global push/pop around everything when beyond Start mode
      44                 :            :   // (see solver execution modes in the SMT-LIB standard)
      45 [ +  - ][ +  - ]:        687 :   Assert(d_userLevels.size() == 0 && userContext()->getLevel() == 1);
         [ -  + ][ -  + ]
                 [ -  - ]
      46                 :        687 :   popto(0);
      47                 :            :   // push the state to maintain global context around everything
      48                 :        687 :   push();
      49                 :        687 : }
      50                 :            : 
      51                 :      48694 : void ContextManager::notifyCheckSat(bool hasAssumptions)
      52                 :            : {
      53                 :            :   // push if there are assumptions
      54         [ +  + ]:      48694 :   if (hasAssumptions)
      55                 :            :   {
      56                 :       6416 :     internalPush();
      57                 :            :   }
      58                 :      48694 : }
      59                 :            : 
      60                 :      48635 : void ContextManager::notifyCheckSatResult(bool hasAssumptions)
      61                 :            : {
      62                 :      48635 :   d_needPostsolve = true;
      63                 :            :   // Pop the context
      64         [ +  + ]:      48635 :   if (hasAssumptions)
      65                 :            :   {
      66                 :       6408 :     internalPop();
      67                 :            :   }
      68                 :      48635 : }
      69                 :            : 
      70                 :      49974 : void ContextManager::setup(SmtDriver* smt)
      71                 :            : {
      72                 :      49974 :   d_smt = smt;
      73                 :            :   // push the state to maintain global context around everything
      74                 :      49974 :   push();
      75                 :      49974 : }
      76                 :            : 
      77                 :      69611 : void ContextManager::shutdown()
      78                 :            : {
      79                 :      69611 :   doPendingPops();
      80                 :            : 
      81 [ +  + ][ +  + ]:      70379 :   while (options().base.incrementalSolving && userContext()->getLevel() > 1)
                 [ +  + ]
      82                 :            :   {
      83                 :        768 :     internalPop(true);
      84                 :            :   }
      85                 :      69611 : }
      86                 :            : 
      87                 :      69611 : void ContextManager::cleanup()
      88                 :            : {
      89                 :            :   // pop to level zero
      90                 :      69611 :   popto(0);
      91                 :      69611 : }
      92                 :            : 
      93                 :       5079 : void ContextManager::userPush()
      94                 :            : {
      95                 :            :   // notify the state
      96                 :       5079 :   d_state.notifyUserPop();
      97                 :            : 
      98                 :       5079 :   d_userLevels.push_back(userContext()->getLevel());
      99                 :       5079 :   internalPush();
     100         [ +  - ]:      10158 :   Trace("userpushpop") << "ContextManager: pushed to level "
     101                 :       5079 :                        << userContext()->getLevel() << std::endl;
     102                 :       5079 : }
     103                 :            : 
     104                 :       4310 : void ContextManager::userPop()
     105                 :            : {
     106                 :            :   // notify the state
     107                 :       4310 :   d_state.notifyUserPush();
     108                 :            : 
     109         [ -  + ]:       4310 :   if (d_userLevels.size() == 0)
     110                 :            :   {
     111                 :          0 :     throw ModalException("Cannot pop beyond the first user frame");
     112                 :            :   }
     113                 :            : 
     114 [ -  + ][ -  + ]:       4310 :   AlwaysAssert(userContext()->getLevel() > 0);
                 [ -  - ]
     115 [ -  + ][ -  + ]:       4310 :   AlwaysAssert(d_userLevels.back() < userContext()->getLevel());
                 [ -  - ]
     116         [ +  + ]:       8620 :   while (d_userLevels.back() < userContext()->getLevel())
     117                 :            :   {
     118                 :       4310 :     internalPop(true);
     119                 :            :   }
     120                 :       4310 :   d_userLevels.pop_back();
     121                 :       4310 : }
     122                 :      50661 : void ContextManager::push()
     123                 :            : {
     124                 :      50661 :   userContext()->push();
     125                 :      50661 :   context()->push();
     126                 :      50661 : }
     127                 :            : 
     128                 :          0 : void ContextManager::pop()
     129                 :            : {
     130                 :          0 :   userContext()->pop();
     131                 :          0 :   context()->pop();
     132                 :          0 : }
     133                 :            : 
     134                 :      70298 : void ContextManager::popto(uint32_t toLevel)
     135                 :            : {
     136                 :      70298 :   context()->popto(toLevel);
     137                 :      70298 :   userContext()->popto(toLevel);
     138                 :      70298 : }
     139                 :            : 
     140                 :       3657 : size_t ContextManager::getNumUserLevels() const { return d_userLevels.size(); }
     141                 :            : 
     142                 :      11495 : void ContextManager::internalPush()
     143                 :            : {
     144         [ +  - ]:      11495 :   Trace("smt") << "ContextManager::internalPush()" << std::endl;
     145                 :      11495 :   doPendingPops();
     146         [ +  + ]:      11495 :   if (options().base.incrementalSolving)
     147                 :            :   {
     148                 :            :     // notifies the SolverEngine to process the assertions immediately
     149                 :       8216 :     d_smt->notifyPushPre();
     150                 :       8216 :     userContext()->push();
     151                 :            :     // the context push is done inside of the SAT solver
     152                 :       8216 :     d_smt->notifyPushPost();
     153                 :            :   }
     154                 :      11495 : }
     155                 :            : 
     156                 :      11486 : void ContextManager::internalPop(bool immediate)
     157                 :            : {
     158         [ +  - ]:      11486 :   Trace("smt") << "ContextManager::internalPop()" << std::endl;
     159         [ +  + ]:      11486 :   if (options().base.incrementalSolving)
     160                 :            :   {
     161                 :       8212 :     ++d_pendingPops;
     162                 :            :   }
     163         [ +  + ]:      11486 :   if (immediate)
     164                 :            :   {
     165                 :       5078 :     doPendingPops();
     166                 :            :   }
     167                 :      11486 : }
     168                 :            : 
     169                 :     360024 : void ContextManager::doPendingPops()
     170                 :            : {
     171         [ +  - ]:     360024 :   Trace("smt") << "ContextManager::doPendingPops()" << std::endl;
     172 [ +  + ][ +  - ]:     360024 :   Assert(d_pendingPops == 0 || options().base.incrementalSolving);
         [ -  + ][ -  + ]
                 [ -  - ]
     173                 :            :   // check to see if a postsolve() is pending
     174         [ +  + ]:     360024 :   if (d_needPostsolve)
     175                 :            :   {
     176                 :      48512 :     d_smt->notifyPostSolve();
     177                 :      48512 :     d_needPostsolve = false;
     178                 :            :   }
     179         [ +  + ]:     368233 :   while (d_pendingPops > 0)
     180                 :            :   {
     181                 :            :     // the context pop is done inside of the SAT solver
     182                 :       8209 :     d_smt->notifyPopPre();
     183                 :            :     // pop the context
     184                 :       8209 :     userContext()->pop();
     185                 :       8209 :     --d_pendingPops;
     186                 :            :     // no need for pop post (for now)
     187                 :            :   }
     188                 :     360024 : }
     189                 :            : 
     190                 :            : }  // namespace smt
     191                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14