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 maintaining the state of the SMT engine. 11 : : */ 12 : : 13 : : #include "smt/solver_engine_state.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 : : 22 : : namespace cvc5::internal { 23 : : namespace smt { 24 : : 25 : 41359 : SolverEngineState::SolverEngineState(Env& env) 26 : : : EnvObj(env), 27 : 41359 : d_fullyInited(false), 28 : 41359 : d_queryMade(false), 29 : 41359 : d_status(), 30 : 41359 : d_statusSolver(nullptr), 31 : 41359 : d_expectedStatus(), 32 : 41359 : d_smtMode(SmtMode::START) 33 : : { 34 : 41359 : } 35 : : 36 : 8005 : void SolverEngineState::notifyExpectedStatus(const std::string& status) 37 : : { 38 [ + + ][ + + ]: 8005 : Assert(status == "sat" || status == "unsat" || status == "unknown") [ + + ][ + - ] [ - + ][ - + ] [ - - ] 39 : : << "SolverEngineState::notifyExpectedStatus: unexpected status string " 40 : 0 : << status; 41 : 8005 : d_expectedStatus = Result(status, options().driver.filename); 42 [ - + ][ - + ]: 8005 : Assert(d_expectedStatus.getStatus() != Result::NONE); [ - - ] 43 : 8005 : } 44 : : 45 : 345037 : void SolverEngineState::notifyDeclaration() 46 : : { 47 : : // go to ASSERT 48 : 345037 : d_smtMode = SmtMode::ASSERT; 49 : 345037 : } 50 : : 51 : 31935 : void SolverEngineState::notifyCheckSat() 52 : : { 53 : : // process the pending pops 54 [ + + ][ - + ]: 31935 : if (d_queryMade && !options().base.incrementalSolving) [ - + ] 55 : : { 56 : 0 : throw ModalException( 57 : : "Cannot make multiple queries unless " 58 : : "incremental solving is enabled " 59 : 0 : "(try --incremental)"); 60 : : } 61 : : 62 : : // Note we are in assert mode 63 : 31935 : d_smtMode = SmtMode::ASSERT; 64 : 31935 : } 65 : : 66 : 31915 : void SolverEngineState::notifyCheckSatResult(const Result& r, 67 : : SolverEngine* solver) 68 : : { 69 : : // Note that a query has been made 70 : 31915 : d_queryMade = true; 71 : : // Remember the status 72 : 31915 : d_status = r; 73 : : // Check against expected status, if it is set 74 [ + + ]: 31915 : if (d_expectedStatus.getStatus() != Result::NONE) 75 : : { 76 : : // unknown results don't give an error 77 [ + + ]: 15862 : if (!d_expectedStatus.isUnknown() && !d_status.isUnknown() 78 [ + + ][ + + ]: 15862 : && d_status != d_expectedStatus) [ + + ] 79 : : { 80 : 4 : std::stringstream ss; 81 : 4 : ss << "Expected result " << d_expectedStatus << " but got " << d_status; 82 : 4 : throw Exception(ss.str()); 83 : 4 : } 84 : : } 85 : : // clear expected status 86 : 31911 : d_expectedStatus = Result(); 87 : : // Update the SMT mode 88 [ + + ][ + ]: 31911 : switch (d_status.getStatus()) 89 : : { 90 : 18548 : case Result::UNSAT: d_smtMode = SmtMode::UNSAT; break; 91 : 12846 : case Result::SAT: d_smtMode = SmtMode::SAT; break; 92 : 517 : default: d_smtMode = SmtMode::SAT_UNKNOWN; 93 : : } 94 : : // store the status solver 95 : 31911 : d_statusSolver = solver; 96 : 31911 : } 97 : : 98 : 532 : void SolverEngineState::notifyCheckSynthResult(const SynthResult& r) 99 : : { 100 : 532 : d_queryMade = true; 101 [ + + ]: 532 : if (r.getStatus() == SynthResult::SOLUTION) 102 : : { 103 : : // successfully generated a synthesis solution, update to synth state 104 : 489 : d_smtMode = SmtMode::SYNTH; 105 : : } 106 : : else 107 : : { 108 : : // failed, we revert to the assert state 109 : 43 : d_smtMode = SmtMode::ASSERT; 110 : : } 111 : 532 : } 112 : : 113 : 93 : void SolverEngineState::notifyGetAbduct(bool success) 114 : : { 115 [ + + ]: 93 : if (success) 116 : : { 117 : : // successfully generated an abduct, update to abduct state 118 : 80 : d_smtMode = SmtMode::ABDUCT; 119 : : } 120 : : else 121 : : { 122 : : // failed, we revert to the assert state 123 : 13 : d_smtMode = SmtMode::ASSERT; 124 : : } 125 : 93 : } 126 : : 127 : 40 : void SolverEngineState::notifyGetInterpol(bool success) 128 : : { 129 [ + + ]: 40 : if (success) 130 : : { 131 : : // successfully generated an interpolant, update to interpol state 132 : 32 : d_smtMode = SmtMode::INTERPOL; 133 : : } 134 : : else 135 : : { 136 : : // failed, we revert to the assert state 137 : 8 : d_smtMode = SmtMode::ASSERT; 138 : : } 139 : 40 : } 140 : : 141 : 41 : void SolverEngineState::notifyFindSynth(bool success) 142 : : { 143 [ + + ]: 41 : if (success) 144 : : { 145 : 11 : d_smtMode = SmtMode::FIND_SYNTH; 146 : : } 147 : : else 148 : : { 149 : : // failed, we revert to the assert state 150 : 30 : d_smtMode = SmtMode::ASSERT; 151 : : } 152 : 41 : } 153 : : 154 : 28691 : void SolverEngineState::markFinishInit() 155 : : { 156 : : // set the flag to remember that we are fully initialized 157 : 28691 : d_fullyInited = true; 158 : 28691 : } 159 : : 160 : 3097 : void SolverEngineState::notifyUserPush() 161 : : { 162 [ - + ]: 3097 : if (!options().base.incrementalSolving) 163 : : { 164 : 0 : throw ModalException( 165 : 0 : "Cannot push when not solving incrementally (use --incremental)"); 166 : : } 167 : : // The problem isn't really "extended" yet, but this disallows 168 : : // get-model after a push, simplifying our lives somewhat and 169 : : // staying symmetric with pop. 170 : 3097 : d_smtMode = SmtMode::ASSERT; 171 : 3097 : } 172 : : 173 : 3702 : void SolverEngineState::notifyUserPop() 174 : : { 175 [ - + ]: 3702 : if (!options().base.incrementalSolving) 176 : : { 177 : 0 : throw ModalException( 178 : 0 : "Cannot pop when not solving incrementally (use --incremental)"); 179 : : } 180 : : // The problem isn't really "extended" yet, but this disallows 181 : : // get-model after a pop, simplifying our lives somewhat. It might 182 : : // not be strictly necessary to do so, since the pops occur lazily, 183 : : // but also it would be weird to have a legally-executed (get-model) 184 : : // that only returns a subset of the assignment (because the rest 185 : : // is no longer in scope!). 186 : 3702 : d_smtMode = SmtMode::ASSERT; 187 : 3702 : } 188 : : 189 : 17 : Result SolverEngineState::getStatus() const { return d_status; } 190 : : 191 : 35605 : SolverEngine* SolverEngineState::getStatusSolver() const 192 : : { 193 : 35605 : return d_statusSolver; 194 : : } 195 : : 196 : 702514 : bool SolverEngineState::isFullyInited() const { return d_fullyInited; } 197 : : 198 : 21065 : bool SolverEngineState::isQueryMade() const { return d_queryMade; } 199 : : 200 : 60566 : SmtMode SolverEngineState::getMode() const { return d_smtMode; } 201 : : 202 : : } // namespace smt 203 : : } // namespace cvc5::internal