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