@@ -176,6 +176,88 @@ valid_smt_error_response(const irept &parse_tree)
176176 validate_string_literal (parse_tree.get_sub ()[1 ]));
177177}
178178
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+
179261response_or_errort<smt_responset> validate_smt_response (const irept &parse_tree)
180262{
181263 if (parse_tree.id () == " sat" )
@@ -193,6 +275,8 @@ response_or_errort<smt_responset> validate_smt_response(const irept &parse_tree)
193275 return response_or_errort<smt_responset>{smt_success_responset{}};
194276 if (parse_tree.id () == " unsupported" )
195277 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;
196280 return response_or_errort<smt_responset>{" Invalid SMT response \" " +
197281 id2string (parse_tree.id ()) + " \" " };
198282}
0 commit comments