@@ -215,7 +215,7 @@ exprt smt2_parsert::let_expression()
215215 return let_exprt (variables, values, where);
216216}
217217
218- exprt smt2_parsert::quantifier_expression (irep_idt id)
218+ std::pair<binding_exprt::variablest, exprt> smt2_parsert::binding (irep_idt id)
219219{
220220 if (next_token () != smt2_tokenizert::OPEN)
221221 throw error () << " expected bindings after " << id;
@@ -264,8 +264,6 @@ exprt smt2_parsert::quantifier_expression(irep_idt id)
264264 if (next_token () != smt2_tokenizert::CLOSE)
265265 throw error () << " expected ')' after " << id;
266266
267- exprt result=expr;
268-
269267 // remove bindings from id_map
270268 for (const auto &b : bindings)
271269 id_map.erase (b.get_identifier ());
@@ -274,14 +272,23 @@ exprt smt2_parsert::quantifier_expression(irep_idt id)
274272 for (auto &saved_id : saved_ids)
275273 id_map.insert (std::move (saved_id));
276274
277- // go backwards, build quantified expression
278- for (auto r_it=bindings.rbegin (); r_it!=bindings.rend (); r_it++)
279- {
280- quantifier_exprt quantifier (id, *r_it, result);
281- result=quantifier;
282- }
275+ return {std::move (bindings), std::move (expr)};
276+ }
283277
284- return result;
278+ exprt smt2_parsert::lambda_expression ()
279+ {
280+ auto binding = this ->binding (ID_lambda);
281+ return lambda_exprt (binding.first , binding.second );
282+ }
283+
284+ exprt smt2_parsert::quantifier_expression (irep_idt id)
285+ {
286+ auto binding = this ->binding (id);
287+
288+ if (binding.second .type ().id () != ID_bool)
289+ throw error () << id << " expects a boolean term" ;
290+
291+ return quantifier_exprt (id, binding.first , binding.second );
285292}
286293
287294exprt smt2_parsert::function_application (
@@ -971,6 +978,7 @@ void smt2_parsert::setup_expressions()
971978 return from_integer (ieee_floatt::ROUND_TO_ZERO, unsignedbv_typet (32 ));
972979 };
973980
981+ expressions[" lambda" ] = [this ] { return lambda_expression (); };
974982 expressions[" let" ] = [this ] { return let_expression (); };
975983 expressions[" exists" ] = [this ] { return quantifier_expression (ID_exists); };
976984 expressions[" forall" ] = [this ] { return quantifier_expression (ID_forall); };
@@ -1236,6 +1244,32 @@ void smt2_parsert::setup_expressions()
12361244 expressions[" fp.neg" ] = [this ] { return unary (ID_unary_minus, operands ()); };
12371245}
12381246
1247+ typet smt2_parsert::function_sort ()
1248+ {
1249+ std::vector<typet> sorts;
1250+
1251+ // (-> sort+ sort)
1252+ // The last sort is the co-domain.
1253+
1254+ while (smt2_tokenizer.peek () != smt2_tokenizert::CLOSE)
1255+ {
1256+ if (smt2_tokenizer.peek () == smt2_tokenizert::END_OF_FILE)
1257+ throw error () << " unexpected end-of-file in a function sort" ;
1258+
1259+ sorts.push_back (sort ()); // recursive call
1260+ }
1261+
1262+ next_token (); // eat the ')'
1263+
1264+ if (sorts.size () < 2 )
1265+ throw error () << " expected function sort to have at least 2 type arguments" ;
1266+
1267+ auto codomain = std::move (sorts.back ());
1268+ sorts.pop_back ();
1269+
1270+ return mathematical_function_typet (std::move (sorts), std::move (codomain));
1271+ }
1272+
12391273typet smt2_parsert::sort ()
12401274{
12411275 // a sort is one of the following three cases:
@@ -1334,6 +1368,8 @@ void smt2_parsert::setup_sorts()
13341368 else
13351369 throw error (" unsupported array sort" );
13361370 };
1371+
1372+ sorts[" ->" ] = [this ] { return function_sort (); };
13371373}
13381374
13391375smt2_parsert::signature_with_parameter_idst
0 commit comments