@@ -282,6 +282,7 @@ exprt smt2_convt::get(const exprt &expr) const
282282
283283 if (it!=identifier_map.end ())
284284 return it->second .value ;
285+ return expr;
285286 }
286287 else if (expr.id ()==ID_nondet_symbol)
287288 {
@@ -472,31 +473,85 @@ constant_exprt smt2_convt::parse_literal(
472473exprt smt2_convt::parse_array (
473474 const irept &src,
474475 const array_typet &type)
476+ {
477+ std::unordered_map<int64_t , exprt> operands_map;
478+ walk_array_tree (&operands_map, src, type);
479+ exprt::operandst operands;
480+ // Try to find the default value, if there is none then set it
481+ auto maybe_default_op = operands_map.find (-1 );
482+ exprt default_op;
483+ if (maybe_default_op == operands_map.end ())
484+ default_op = nil_exprt ();
485+ else
486+ default_op = maybe_default_op->second ;
487+ int64_t i = 0 ;
488+ auto maybe_size = numeric_cast<std::int64_t >(type.size ());
489+ if (maybe_size.has_value ())
490+ {
491+ while (i < maybe_size.value ())
492+ {
493+ auto found_op = operands_map.find (i);
494+ if (found_op != operands_map.end ())
495+ operands.emplace_back (found_op->second );
496+ else
497+ operands.emplace_back (default_op);
498+ i++;
499+ }
500+ }
501+ else
502+ {
503+ // Array size is unknown, keep adding with known indexes in order
504+ // until we fail to find one.
505+ auto found_op = operands_map.find (i);
506+ while (found_op != operands_map.end ())
507+ {
508+ operands.emplace_back (found_op->second );
509+ i++;
510+ found_op = operands_map.find (i);
511+ }
512+ operands.emplace_back (default_op);
513+ }
514+ return array_exprt (operands, type);
515+ }
516+
517+ void smt2_convt::walk_array_tree (
518+ std::unordered_map<int64_t , exprt> *operands_map,
519+ const irept &src,
520+ const array_typet &type)
475521{
476522 if (src.get_sub ().size ()==4 && src.get_sub ()[0 ].id ()==" store" )
477523 {
524+ // This is the SMT syntax being parsed here
478525 // (store array index value)
479- if (src.get_sub ().size ()!=4 )
480- return nil_exprt ();
481-
482- exprt array=parse_array (src.get_sub ()[1 ], type);
483- exprt index=parse_rec (src.get_sub ()[2 ], type.size ().type ());
484- exprt value=parse_rec (src.get_sub ()[3 ], type.subtype ());
485-
486- return with_exprt (array, index, value);
526+ // Recurse
527+ walk_array_tree (operands_map, src.get_sub ()[1 ], type);
528+ const auto index_expr = parse_rec (src.get_sub ()[2 ], type.size ().type ());
529+ const constant_exprt index_constant = to_constant_expr (index_expr);
530+ mp_integer tempint;
531+ bool failure = to_integer (index_constant, tempint);
532+ if (failure)
533+ return ;
534+ long index = tempint.to_long ();
535+ exprt value = parse_rec (src.get_sub ()[3 ], type.subtype ());
536+ operands_map->emplace (index, value);
537+ }
538+ else if (src.get_sub ().size () == 3 && src.get_sub ()[0 ].id () == " let" )
539+ {
540+ // This is produced by Z3
541+ // (let (....) (....))
542+ walk_array_tree (
543+ operands_map, src.get_sub ()[1 ].get_sub ()[0 ].get_sub ()[1 ], type);
544+ walk_array_tree (operands_map, src.get_sub ()[2 ], type);
487545 }
488546 else if (src.get_sub ().size ()==2 &&
489547 src.get_sub ()[0 ].get_sub ().size ()==3 &&
490548 src.get_sub ()[0 ].get_sub ()[0 ].id ()==" as" &&
491549 src.get_sub ()[0 ].get_sub ()[1 ].id ()==" const" )
492550 {
493- // This is produced by Z3.
494- // ((as const (Array (_ BitVec 64) (_ BitVec 8))) #x00)))
495- exprt value=parse_rec (src.get_sub ()[1 ], type.subtype ());
496- return array_of_exprt (value, type);
551+ // (as const type_info default_value)
552+ exprt default_value = parse_rec (src.get_sub ()[1 ], type.subtype ());
553+ operands_map->emplace (-1 , default_value);
497554 }
498- else
499- return nil_exprt ();
500555}
501556
502557exprt smt2_convt::parse_union (
0 commit comments