|
2 | 2 |
|
3 | 3 | #include "smt2_incremental_decision_procedure.h"
|
4 | 4 |
|
| 5 | +#include <solvers/smt2_incremental/construct_value_expr_from_smt.h> |
5 | 6 | #include <solvers/smt2_incremental/convert_expr_to_smt.h>
|
6 | 7 | #include <solvers/smt2_incremental/smt_commands.h>
|
7 | 8 | #include <solvers/smt2_incremental/smt_core_theory.h>
|
@@ -163,9 +164,70 @@ exprt smt2_incremental_decision_proceduret::handle(const exprt &expr)
|
163 | 164 | return expr;
|
164 | 165 | }
|
165 | 166 |
|
| 167 | +static optionalt<smt_termt> get_identifier( |
| 168 | + const exprt &expr, |
| 169 | + const std::unordered_map<exprt, smt_identifier_termt, irep_hash> |
| 170 | + &expression_handle_identifiers, |
| 171 | + const std::unordered_map<exprt, smt_identifier_termt, irep_hash> |
| 172 | + &expression_identifiers) |
| 173 | +{ |
| 174 | + const auto handle_find_result = expression_handle_identifiers.find(expr); |
| 175 | + if(handle_find_result != expression_handle_identifiers.cend()) |
| 176 | + return handle_find_result->second; |
| 177 | + const auto expr_find_result = expression_identifiers.find(expr); |
| 178 | + if(expr_find_result != expression_identifiers.cend()) |
| 179 | + return expr_find_result->second; |
| 180 | + return {}; |
| 181 | +} |
| 182 | + |
166 | 183 | exprt smt2_incremental_decision_proceduret::get(const exprt &expr) const
|
167 | 184 | {
|
168 |
| - UNIMPLEMENTED_FEATURE("`get` of:\n " + expr.pretty(2, 0)); |
| 185 | + log.debug() << "`get` - \n " + expr.pretty(2, 0) << messaget::eom; |
| 186 | + optionalt<smt_termt> descriptor = |
| 187 | + get_identifier(expr, expression_handle_identifiers, expression_identifiers); |
| 188 | + if(!descriptor) |
| 189 | + { |
| 190 | + if(gather_dependent_expressions(expr).empty()) |
| 191 | + { |
| 192 | + descriptor = convert_expr_to_smt(expr); |
| 193 | + } |
| 194 | + else |
| 195 | + { |
| 196 | + const auto symbol_expr = expr_try_dynamic_cast<symbol_exprt>(expr); |
| 197 | + INVARIANT( |
| 198 | + symbol_expr, "Unhandled expressions are expected to be symbols"); |
| 199 | + // Note this case is currently expected to be encountered during trace |
| 200 | + // generation for - |
| 201 | + // * Steps which were removed via --slice-formula. |
| 202 | + // * Getting concurrency clock values. |
| 203 | + // The below implementation which returns the given expression was chosen |
| 204 | + // based on the implementation of `smt2_convt::get` in the non-incremental |
| 205 | + // smt2 decision procedure. |
| 206 | + log.warning() |
| 207 | + << "`get` attempted for unknown symbol, with identifier - \n" |
| 208 | + << symbol_expr->get_identifier() << messaget::eom; |
| 209 | + return expr; |
| 210 | + } |
| 211 | + } |
| 212 | + const smt_get_value_commandt get_value_command{*descriptor}; |
| 213 | + const smt_responset response = |
| 214 | + get_response_to_command(*solver_process, get_value_command); |
| 215 | + const auto get_value_response = response.cast<smt_get_value_responset>(); |
| 216 | + if(!get_value_response) |
| 217 | + { |
| 218 | + throw analysis_exceptiont{ |
| 219 | + "Expected get-value response from solver, but received - " + |
| 220 | + response.pretty()}; |
| 221 | + } |
| 222 | + if(get_value_response->pairs().size() > 1) |
| 223 | + { |
| 224 | + throw analysis_exceptiont{ |
| 225 | + "Expected single valuation pair in get-value response from solver, but " |
| 226 | + "received multiple pairs - " + |
| 227 | + response.pretty()}; |
| 228 | + } |
| 229 | + return construct_value_expr_from_smt( |
| 230 | + get_value_response->pairs()[0].get().value(), expr.type()); |
169 | 231 | }
|
170 | 232 |
|
171 | 233 | void smt2_incremental_decision_proceduret::print_assignment(
|
|
0 commit comments