@@ -29,6 +29,8 @@ Author: Daniel Kroening, kroening@kroening.com
2929#include < util/pointer_predicates.h>
3030#include < util/prefix.h>
3131#include < util/range.h>
32+ #include < util/rational.h>
33+ #include < util/rational_tools.h>
3234#include < util/simplify_expr.h>
3335#include < util/std_expr.h>
3436#include < util/string2int.h>
@@ -416,8 +418,7 @@ constant_exprt smt2_convt::parse_literal(
416418
417419 if (!src.id ().empty ())
418420 {
419- const std::string &s=src.id_string ();
420-
421+ const std::string &s = src.id_string ();
421422 if (s.size ()>=2 && s[0 ]==' #' && s[1 ]==' b' )
422423 {
423424 // Binary #b010101
@@ -430,8 +431,29 @@ constant_exprt smt2_convt::parse_literal(
430431 }
431432 else
432433 {
434+ std::size_t pos = s.find (" ." );
435+ if (pos != std::string::npos)
436+ {
437+ // Decimal, return as rational
438+ mp_integer first = string2integer (s.substr (0 , pos));
439+ mp_integer second = string2integer (s.substr (pos, std::string::npos));
440+ if (type.id () == ID_rational)
441+ {
442+ rationalt rational_value (first);
443+ rationalt second_rational (second);
444+ rationalt tmp = rational_value + second_rational / rationalt (100 );
445+ return from_rational (tmp);
446+ }
447+ else
448+ {
449+ UNREACHABLE_BECAUSE (
450+ " smt2_convt::parse_literal parsed a number with a decimal point "
451+ " in, which cannot be converted to type " +
452+ type.id_string ());
453+ }
454+ }
433455 // Numeral
434- value= string2integer (s);
456+ value = string2integer (s);
435457 }
436458 }
437459 else if (src.get_sub ().size ()==2 &&
@@ -527,6 +549,11 @@ constant_exprt smt2_convt::parse_literal(
527549 {
528550 return from_integer (value + to_range_type (type).get_from (), type);
529551 }
552+ else if (type.id () == ID_rational)
553+ {
554+ // TODO parse this literal back correctly.
555+ return from_integer (value, type);
556+ }
530557 else
531558 UNREACHABLE_BECAUSE (
532559 " smt2_convt::parse_literal should not be of unsupported type " +
@@ -3167,6 +3194,19 @@ void smt2_convt::convert_typecast(const typecast_exprt &expr)
31673194 convert_typecast (tmp);
31683195 }
31693196 }
3197+ else if (dest_type.id () == ID_rational)
3198+ {
3199+ if (src_type.id () == ID_signedbv)
3200+ {
3201+ // TODO: negative numbers
3202+ out << " (/ " ;
3203+ convert_expr (src);
3204+ out << " 1)" ;
3205+ }
3206+ else
3207+ UNEXPECTEDCASE (
3208+ " Unknown typecast " + src_type.id_string () + " -> rational" );
3209+ }
31703210 else
31713211 UNEXPECTEDCASE (
31723212 " TODO typecast8 " +src_type.id_string ()+" -> " +dest_type.id_string ());
@@ -3588,7 +3628,10 @@ void smt2_convt::convert_constant(const constant_exprt &expr)
35883628 const bool negative = has_prefix (value, " -" );
35893629
35903630 if (negative)
3631+ {
35913632 out << " (- " ;
3633+ value = value.substr (1 );
3634+ }
35923635
35933636 size_t pos=value.find (" /" );
35943637
@@ -4190,6 +4233,16 @@ void smt2_convt::convert_div(const div_exprt &expr)
41904233 // the rounding mode. See smt2_convt::convert_floatbv_div.
41914234 UNREACHABLE;
41924235 }
4236+ else if (
4237+ expr.type ().id () == ID_rational || expr.type ().id () == ID_integer ||
4238+ expr.type ().id () == ID_real)
4239+ {
4240+ out << " (/ " ;
4241+ convert_expr (expr.op0 ());
4242+ out << " " ;
4243+ convert_expr (expr.op1 ());
4244+ out << " )" ;
4245+ }
41934246 else
41944247 UNEXPECTEDCASE (" unsupported type for /: " +expr.type ().id_string ());
41954248}
0 commit comments