@@ -176,6 +176,88 @@ valid_smt_error_response(const irept &parse_tree)
176
176
validate_string_literal (parse_tree.get_sub ()[1 ]));
177
177
}
178
178
179
+ static bool all_subs_are_pairs (const irept &parse_tree)
180
+ {
181
+ return std::all_of (
182
+ parse_tree.get_sub ().cbegin (),
183
+ parse_tree.get_sub ().cend (),
184
+ [](const irept &sub) { return sub.get_sub ().size () == 2 ; });
185
+ }
186
+
187
+ static response_or_errort<irep_idt>
188
+ validate_smt_identifier (const irept &parse_tree)
189
+ {
190
+ if (!parse_tree.get_sub ().empty () || parse_tree.id ().empty ())
191
+ {
192
+ return response_or_errort<irep_idt>(
193
+ " Expected identifier, found - \" " + print_parse_tree (parse_tree) + " \" ." );
194
+ }
195
+ return response_or_errort<irep_idt>(parse_tree.id ());
196
+ }
197
+
198
+ static optionalt<smt_termt> valid_smt_bool (const irept &parse_tree)
199
+ {
200
+ if (!parse_tree.get_sub ().empty ())
201
+ return {};
202
+ if (parse_tree.id () == ID_true)
203
+ return {smt_bool_literal_termt{true }};
204
+ if (parse_tree.id () == ID_false)
205
+ return {smt_bool_literal_termt{false }};
206
+ return {};
207
+ }
208
+
209
+ static response_or_errort<smt_termt> validate_term (const irept &parse_tree)
210
+ {
211
+ if (const auto smt_bool = valid_smt_bool (parse_tree))
212
+ return response_or_errort<smt_termt>{*smt_bool};
213
+ return response_or_errort<smt_termt>{" Unrecognised SMT term - \" " +
214
+ print_parse_tree (parse_tree) + " \" ." };
215
+ }
216
+
217
+ static response_or_errort<smt_get_value_responset::valuation_pairt>
218
+ validate_valuation_pair (const irept &pair_parse_tree)
219
+ {
220
+ PRECONDITION (pair_parse_tree.get_sub ().size () == 2 );
221
+ const auto &descriptor = pair_parse_tree.get_sub ()[0 ];
222
+ const auto &value = pair_parse_tree.get_sub ()[1 ];
223
+ return validation_propagating<smt_get_value_responset::valuation_pairt>(
224
+ validate_smt_identifier (descriptor), validate_term (value));
225
+ }
226
+
227
+ // / \returns: A response or error in the case where the parse tree appears to be
228
+ // / a get-value command. Returns empty otherwise.
229
+ // / \note: Because this kind of response does not start with an identifying
230
+ // / keyword, it will be considered that the response is intended to be a
231
+ // / get-value response if it is composed of a collection of one or more pairs.
232
+ static optionalt<response_or_errort<smt_responset>>
233
+ valid_smt_get_value_response (const irept &parse_tree)
234
+ {
235
+ // Shape matching for does this look like a get value response?
236
+ if (!parse_tree.id ().empty ())
237
+ return {};
238
+ if (parse_tree.get_sub ().empty ())
239
+ return {};
240
+ if (!all_subs_are_pairs (parse_tree))
241
+ return {};
242
+ std::vector<std::string> error_messages;
243
+ std::vector<smt_get_value_responset::valuation_pairt> valuation_pairs;
244
+ for (const auto &pair : parse_tree.get_sub ())
245
+ {
246
+ const auto pair_validation_result = validate_valuation_pair (pair);
247
+ if (const auto error = pair_validation_result.get_if_error ())
248
+ error_messages.insert (error_messages.end (), error->begin (), error->end ());
249
+ if (const auto valid_pair = pair_validation_result.get_if_valid ())
250
+ valuation_pairs.push_back (*valid_pair);
251
+ }
252
+ if (!error_messages.empty ())
253
+ return {response_or_errort<smt_responset>{std::move (error_messages)}};
254
+ else
255
+ {
256
+ return {response_or_errort<smt_responset>{
257
+ smt_get_value_responset{valuation_pairs}}};
258
+ }
259
+ }
260
+
179
261
response_or_errort<smt_responset> validate_smt_response (const irept &parse_tree)
180
262
{
181
263
if (parse_tree.id () == " sat" )
@@ -193,6 +275,8 @@ response_or_errort<smt_responset> validate_smt_response(const irept &parse_tree)
193
275
return response_or_errort<smt_responset>{smt_success_responset{}};
194
276
if (parse_tree.id () == " unsupported" )
195
277
return response_or_errort<smt_responset>{smt_unsupported_responset{}};
278
+ if (const auto get_value_response = valid_smt_get_value_response (parse_tree))
279
+ return *get_value_response;
196
280
return response_or_errort<smt_responset>{" Invalid SMT response \" " +
197
281
id2string (parse_tree.id ()) + " \" " };
198
282
}
0 commit comments