@@ -215,7 +215,7 @@ exprt smt2_parsert::let_expression()
215
215
return let_exprt (variables, values, where);
216
216
}
217
217
218
- exprt smt2_parsert::quantifier_expression (irep_idt id)
218
+ std::pair<binding_exprt::variablest, exprt> smt2_parsert::binding (irep_idt id)
219
219
{
220
220
if (next_token () != smt2_tokenizert::OPEN)
221
221
throw error () << " expected bindings after " << id;
@@ -264,8 +264,6 @@ exprt smt2_parsert::quantifier_expression(irep_idt id)
264
264
if (next_token () != smt2_tokenizert::CLOSE)
265
265
throw error () << " expected ')' after " << id;
266
266
267
- exprt result=expr;
268
-
269
267
// remove bindings from id_map
270
268
for (const auto &b : bindings)
271
269
id_map.erase (b.get_identifier ());
@@ -274,14 +272,23 @@ exprt smt2_parsert::quantifier_expression(irep_idt id)
274
272
for (auto &saved_id : saved_ids)
275
273
id_map.insert (std::move (saved_id));
276
274
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
+ }
283
277
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 );
285
292
}
286
293
287
294
exprt smt2_parsert::function_application (
@@ -971,6 +978,7 @@ void smt2_parsert::setup_expressions()
971
978
return from_integer (ieee_floatt::ROUND_TO_ZERO, unsignedbv_typet (32 ));
972
979
};
973
980
981
+ expressions[" lambda" ] = [this ] { return lambda_expression (); };
974
982
expressions[" let" ] = [this ] { return let_expression (); };
975
983
expressions[" exists" ] = [this ] { return quantifier_expression (ID_exists); };
976
984
expressions[" forall" ] = [this ] { return quantifier_expression (ID_forall); };
@@ -1236,6 +1244,32 @@ void smt2_parsert::setup_expressions()
1236
1244
expressions[" fp.neg" ] = [this ] { return unary (ID_unary_minus, operands ()); };
1237
1245
}
1238
1246
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
+
1239
1273
typet smt2_parsert::sort ()
1240
1274
{
1241
1275
// a sort is one of the following three cases:
@@ -1334,6 +1368,8 @@ void smt2_parsert::setup_sorts()
1334
1368
else
1335
1369
throw error (" unsupported array sort" );
1336
1370
};
1371
+
1372
+ sorts[" ->" ] = [this ] { return function_sort (); };
1337
1373
}
1338
1374
1339
1375
smt2_parsert::signature_with_parameter_idst
0 commit comments