@@ -282,6 +282,7 @@ exprt smt2_convt::get(const exprt &expr) const
282
282
283
283
if (it!=identifier_map.end ())
284
284
return it->second .value ;
285
+ return expr;
285
286
}
286
287
else if (expr.id ()==ID_nondet_symbol)
287
288
{
@@ -472,31 +473,85 @@ constant_exprt smt2_convt::parse_literal(
472
473
exprt smt2_convt::parse_array (
473
474
const irept &src,
474
475
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)
475
521
{
476
522
if (src.get_sub ().size ()==4 && src.get_sub ()[0 ].id ()==" store" )
477
523
{
524
+ // This is the SMT syntax being parsed here
478
525
// (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);
487
545
}
488
546
else if (src.get_sub ().size ()==2 &&
489
547
src.get_sub ()[0 ].get_sub ().size ()==3 &&
490
548
src.get_sub ()[0 ].get_sub ()[0 ].id ()==" as" &&
491
549
src.get_sub ()[0 ].get_sub ()[1 ].id ()==" const" )
492
550
{
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);
497
554
}
498
- else
499
- return nil_exprt ();
500
555
}
501
556
502
557
exprt smt2_convt::parse_union (
0 commit comments