Branch data Line data Source code
1 : : /****************************************************************************** 2 : : * Top contributors (to current version): 3 : : * Andrew Reynolds, Morgan Deters, Aina Niemetz 4 : : * 5 : : * This file is part of the cvc5 project. 6 : : * 7 : : * Copyright (c) 2009-2025 by the authors listed in the file AUTHORS 8 : : * in the top-level source directory and their institutional affiliations. 9 : : * All rights reserved. See the file COPYING in the top-level source 10 : : * directory for licensing information. 11 : : * **************************************************************************** 12 : : * 13 : : * Utility for maintaining the state of the SMT engine. 14 : : */ 15 : : 16 : : #include "smt/solver_engine_state.h" 17 : : 18 : : #include "base/modal_exception.h" 19 : : #include "options/base_options.h" 20 : : #include "options/main_options.h" 21 : : #include "options/option_exception.h" 22 : : #include "options/smt_options.h" 23 : : #include "smt/env.h" 24 : : 25 : : namespace cvc5::internal { 26 : : namespace smt { 27 : : 28 : 74479 : SolverEngineState::SolverEngineState(Env& env) 29 : : : EnvObj(env), 30 : 74479 : d_fullyInited(false), 31 : 74479 : d_queryMade(false), 32 : 74479 : d_status(), 33 : 74479 : d_expectedStatus(), 34 : 74479 : d_smtMode(SmtMode::START) 35 : : { 36 : 74479 : } 37 : : 38 : 8439 : void SolverEngineState::notifyExpectedStatus(const std::string& status) 39 : : { 40 [ + + ][ + + ]: 8439 : Assert(status == "sat" || status == "unsat" || status == "unknown") [ + + ][ + - ] [ - + ][ - + ] [ - - ] 41 : : << "SolverEngineState::notifyExpectedStatus: unexpected status string " 42 : 0 : << status; 43 : 8439 : d_expectedStatus = Result(status, options().driver.filename); 44 [ - + ][ - + ]: 8439 : Assert(d_expectedStatus.getStatus() != Result::NONE); [ - - ] 45 : 8439 : } 46 : : 47 : 348774 : void SolverEngineState::notifyDeclaration() 48 : : { 49 : : // go to ASSERT 50 : 348774 : d_smtMode = SmtMode::ASSERT; 51 : 348774 : } 52 : : 53 : 48209 : void SolverEngineState::notifyCheckSat() 54 : : { 55 : : // process the pending pops 56 [ + + ][ - + ]: 48209 : if (d_queryMade && !options().base.incrementalSolving) [ - + ] 57 : : { 58 : 0 : throw ModalException( 59 : : "Cannot make multiple queries unless " 60 : : "incremental solving is enabled " 61 : 0 : "(try --incremental)"); 62 : : } 63 : : 64 : : // Note we are in assert mode 65 : 48209 : d_smtMode = SmtMode::ASSERT; 66 : 48209 : } 67 : : 68 : 48150 : void SolverEngineState::notifyCheckSatResult(const Result& r) 69 : : { 70 : : // Note that a query has been made 71 : 48150 : d_queryMade = true; 72 : : // Remember the status 73 : 48150 : d_status = r; 74 : : // Check against expected status, if it is set 75 [ + + ]: 48150 : if (d_expectedStatus.getStatus() != Result::NONE) 76 : : { 77 : : // unknown results don't give an error 78 [ + + ]: 15836 : if (!d_expectedStatus.isUnknown() && !d_status.isUnknown() 79 [ + + ][ + + ]: 15836 : && d_status != d_expectedStatus) [ + + ] 80 : : { 81 : 4 : std::stringstream ss; 82 : 4 : ss << "Expected result " << d_expectedStatus << " but got " << d_status; 83 : 4 : throw Exception(ss.str()); 84 : 4 : } 85 : : } 86 : : // clear expected status 87 : 48146 : d_expectedStatus = Result(); 88 : : // Update the SMT mode 89 [ + + ][ + ]: 48146 : switch (d_status.getStatus()) 90 : : { 91 : 24832 : case Result::UNSAT: d_smtMode = SmtMode::UNSAT; break; 92 : 21921 : case Result::SAT: d_smtMode = SmtMode::SAT; break; 93 : 1393 : default: d_smtMode = SmtMode::SAT_UNKNOWN; 94 : : } 95 : 48146 : } 96 : : 97 : 1181 : void SolverEngineState::notifyCheckSynthResult(const SynthResult& r) 98 : : { 99 : 1181 : d_queryMade = true; 100 [ + + ]: 1181 : if (r.getStatus() == SynthResult::SOLUTION) 101 : : { 102 : : // successfully generated a synthesis solution, update to synth state 103 : 1097 : d_smtMode = SmtMode::SYNTH; 104 : : } 105 : : else 106 : : { 107 : : // failed, we revert to the assert state 108 : 84 : d_smtMode = SmtMode::ASSERT; 109 : : } 110 : 1181 : } 111 : : 112 : 504 : void SolverEngineState::notifyGetAbduct(bool success) 113 : : { 114 [ + + ]: 504 : if (success) 115 : : { 116 : : // successfully generated an abduct, update to abduct state 117 : 491 : d_smtMode = SmtMode::ABDUCT; 118 : : } 119 : : else 120 : : { 121 : : // failed, we revert to the assert state 122 : 13 : d_smtMode = SmtMode::ASSERT; 123 : : } 124 : 504 : } 125 : : 126 : 513 : void SolverEngineState::notifyGetInterpol(bool success) 127 : : { 128 [ + + ]: 513 : if (success) 129 : : { 130 : : // successfully generated an interpolant, update to interpol state 131 : 505 : d_smtMode = SmtMode::INTERPOL; 132 : : } 133 : : else 134 : : { 135 : : // failed, we revert to the assert state 136 : 8 : d_smtMode = SmtMode::ASSERT; 137 : : } 138 : 513 : } 139 : : 140 : 85 : void SolverEngineState::notifyFindSynth(bool success) 141 : : { 142 [ + + ]: 85 : if (success) 143 : : { 144 : 55 : d_smtMode = SmtMode::FIND_SYNTH; 145 : : } 146 : : else 147 : : { 148 : : // failed, we revert to the assert state 149 : 30 : d_smtMode = SmtMode::ASSERT; 150 : : } 151 : 85 : } 152 : : 153 : 49892 : void SolverEngineState::markFinishInit() 154 : : { 155 : : // set the flag to remember that we are fully initialized 156 : 49892 : d_fullyInited = true; 157 : 49892 : } 158 : : 159 : 4310 : void SolverEngineState::notifyUserPush() 160 : : { 161 [ - + ]: 4310 : if (!options().base.incrementalSolving) 162 : : { 163 : 0 : throw ModalException( 164 : 0 : "Cannot push when not solving incrementally (use --incremental)"); 165 : : } 166 : : // The problem isn't really "extended" yet, but this disallows 167 : : // get-model after a push, simplifying our lives somewhat and 168 : : // staying symmetric with pop. 169 : 4310 : d_smtMode = SmtMode::ASSERT; 170 : 4310 : } 171 : : 172 : 5079 : void SolverEngineState::notifyUserPop() 173 : : { 174 [ - + ]: 5079 : if (!options().base.incrementalSolving) 175 : : { 176 : 0 : throw ModalException( 177 : 0 : "Cannot pop when not solving incrementally (use --incremental)"); 178 : : } 179 : : // The problem isn't really "extended" yet, but this disallows 180 : : // get-model after a pop, simplifying our lives somewhat. It might 181 : : // not be strictly necessary to do so, since the pops occur lazily, 182 : : // but also it would be weird to have a legally-executed (get-model) 183 : : // that only returns a subset of the assignment (because the rest 184 : : // is no longer in scope!). 185 : 5079 : d_smtMode = SmtMode::ASSERT; 186 : 5079 : } 187 : : 188 : 15 : Result SolverEngineState::getStatus() const { return d_status; } 189 : : 190 : 710225 : bool SolverEngineState::isFullyInited() const { return d_fullyInited; } 191 : : 192 : 34425 : bool SolverEngineState::isQueryMade() const { return d_queryMade; } 193 : : 194 : 81413 : SmtMode SolverEngineState::getMode() const { return d_smtMode; } 195 : : 196 : : } // namespace smt 197 : : } // namespace cvc5::internal