@@ -110,11 +110,27 @@ smt_sortt convert_type_to_smt_sort(const typet &type)
110110 {
111111 return convert_type_to_smt_sort (*array_type);
112112 }
113+ if (can_cast_type<mathematical_function_typet>(type))
114+ {
115+ // Mathematical function types are not directly converted to sorts.
116+ // They are used as function symbols in SMT and their applications
117+ // are handled via function_application_exprt.
118+ INVARIANT (
119+ false , " mathematical_function type should not be converted to a sort" );
120+ }
113121 UNIMPLEMENTED_FEATURE (" Generation of SMT formula for type: " + type.pretty ());
114122}
115123
116124static smt_termt convert_expr_to_smt (const symbol_exprt &symbol_expr)
117125{
126+ // Symbols with mathematical_function_typet represent uninterpreted functions.
127+ // They should not be converted to SMT terms directly - only their applications
128+ // (function_application_exprt) should be converted.
129+ INVARIANT (
130+ !can_cast_type<mathematical_function_typet>(symbol_expr.type ()),
131+ " Symbols with mathematical_function_typet should not be converted to SMT "
132+ " terms - only function applications should be converted" );
133+
118134 return smt_identifier_termt{symbol_expr.get_identifier (),
119135 convert_type_to_smt_sort (symbol_expr.type ())};
120136}
@@ -1405,6 +1421,67 @@ static smt_termt convert_expr_to_smt(
14051421 " Generation of SMT formula for vector expression: " + vector.pretty ());
14061422}
14071423
1424+ static smt_termt convert_expr_to_smt (
1425+ const function_application_exprt &function_application,
1426+ const sub_expression_mapt &converted)
1427+ {
1428+ // Get the function identifier - it should be a symbol with mathematical_function_typet
1429+ if (
1430+ const auto func_symbol =
1431+ expr_try_dynamic_cast<symbol_exprt>(function_application.function ()))
1432+ {
1433+ INVARIANT (
1434+ can_cast_type<mathematical_function_typet>(func_symbol->type ()),
1435+ " Function in function_application_exprt should have "
1436+ " mathematical_function_typet" );
1437+
1438+ const auto &math_func_type =
1439+ to_mathematical_function_type (func_symbol->type ());
1440+ const smt_sortt return_sort =
1441+ convert_type_to_smt_sort (math_func_type.codomain ());
1442+
1443+ // Convert function arguments
1444+ std::vector<smt_termt> argument_terms;
1445+ for (const auto &arg : function_application.arguments ())
1446+ {
1447+ argument_terms.push_back (converted.at (arg));
1448+ }
1449+
1450+ // Create a simple factory for uninterpreted functions
1451+ struct uninterpreted_functiont
1452+ {
1453+ irep_idt name;
1454+ smt_sortt return_type;
1455+
1456+ const char *identifier () const
1457+ {
1458+ return id2string (name).c_str ();
1459+ }
1460+
1461+ smt_sortt return_sort (const std::vector<smt_termt> &) const
1462+ {
1463+ return return_type;
1464+ }
1465+
1466+ void validate (const std::vector<smt_termt> &) const
1467+ {
1468+ // No validation needed for uninterpreted functions
1469+ }
1470+ };
1471+
1472+ const uninterpreted_functiont uninterpreted_function{
1473+ func_symbol->get_identifier (), return_sort};
1474+
1475+ return smt_function_application_termt::factoryt<uninterpreted_functiont>(
1476+ uninterpreted_function)(argument_terms);
1477+ }
1478+
1479+ UNIMPLEMENTED_FEATURE (
1480+ " Generation of SMT formula for function application with non-symbol "
1481+ " function: " +
1482+ function_application.pretty ());
1483+ }
1484+
14081485static smt_termt convert_expr_to_smt (
14091486 const object_size_exprt &object_size,
14101487 const sub_expression_mapt &converted,
@@ -1794,6 +1871,21 @@ static smt_termt dispatch_expr_to_smt_conversion(
17941871 {
17951872 return convert_expr_to_smt (*vector, converted);
17961873 }
1874+ if (expr.id () == ID_tuple)
1875+ {
1876+ // Tuple expressions are used internally by function_application_exprt to
1877+ // store arguments. They should not be converted directly to SMT.
1878+ INVARIANT (
1879+ false ,
1880+ " tuple expression should not be directly converted to SMT - it is used "
1881+ " internally by function_application_exprt" );
1882+ }
1883+ if (
1884+ const auto function_application =
1885+ expr_try_dynamic_cast<function_application_exprt>(expr))
1886+ {
1887+ return convert_expr_to_smt (*function_application, converted);
1888+ }
17971889 if (const auto object_size = expr_try_dynamic_cast<object_size_exprt>(expr))
17981890 {
17991891 return convert_expr_to_smt (*object_size, converted, call_object_size);
@@ -1956,11 +2048,27 @@ smt_termt convert_expr_to_smt(
19562048 // Avoiding the conversion side steps a need to convert arbitrary code to
19572049 // SMT terms.
19582050 const auto address_of = expr_try_dynamic_cast<address_of_exprt>(expr);
1959- if (!address_of)
1960- return true ;
1961- return !can_cast_type<code_typet>(address_of->object ().type ());
2051+ if (address_of && can_cast_type<code_typet>(address_of->object ().type ()))
2052+ return false ;
2053+
2054+ // Tuple expressions are internal to function_application_exprt and
2055+ // should not be traversed or converted directly
2056+ if (expr.id () == ID_tuple)
2057+ return false ;
2058+
2059+ return true ;
19622060 },
19632061 [&](const exprt &expr) {
2062+ // Skip tuple expressions entirely - they're internal to function_application
2063+ if (expr.id () == ID_tuple)
2064+ return ;
2065+
2066+ // Skip symbols with mathematical_function_typet - they're declarations, not terms
2067+ if (
2068+ can_cast_expr<symbol_exprt>(expr) &&
2069+ can_cast_type<mathematical_function_typet>(expr.type ()))
2070+ return ;
2071+
19642072 const auto find_result = sub_expression_map.find (expr);
19652073 if (find_result != sub_expression_map.cend ())
19662074 return ;
0 commit comments