@@ -298,3 +298,205 @@ TEST_CASE("Simplify cast from bool", "[core][util]")
298
298
REQUIRE (simp == B);
299
299
}
300
300
}
301
+
302
+ TEST_CASE (" simplify_expr boolean expressions" , " [core][util]" )
303
+ {
304
+ symbol_tablet symbol_table;
305
+ namespacet ns{symbol_table};
306
+
307
+ SECTION (" Binary boolean operations" )
308
+ {
309
+ struct test_entryt
310
+ {
311
+ exprt lhs;
312
+ exprt rhs;
313
+ exprt expected_value;
314
+ };
315
+
316
+ SECTION (" AND" )
317
+ {
318
+ std::vector<test_entryt> test_values = {
319
+ {true_exprt (), true_exprt (), true_exprt ()},
320
+ {true_exprt (), false_exprt (), false_exprt ()},
321
+ {false_exprt (), true_exprt (), false_exprt ()},
322
+ {false_exprt (), false_exprt (), false_exprt ()},
323
+ };
324
+
325
+ for (const auto &entry : test_values)
326
+ {
327
+ const exprt result = simplify_expr (and_exprt{entry.lhs , entry.rhs }, ns);
328
+ REQUIRE (result == entry.expected_value );
329
+ }
330
+ }
331
+
332
+ SECTION (" OR" )
333
+ {
334
+ std::vector<test_entryt> test_values = {
335
+ {true_exprt (), true_exprt (), true_exprt ()},
336
+ {true_exprt (), false_exprt (), true_exprt ()},
337
+ {false_exprt (), true_exprt (), true_exprt ()},
338
+ {false_exprt (), false_exprt (), false_exprt ()},
339
+ };
340
+
341
+ for (const auto &entry : test_values)
342
+ {
343
+ const exprt result = simplify_expr (or_exprt{entry.lhs , entry.rhs }, ns);
344
+ REQUIRE (result == entry.expected_value );
345
+ }
346
+ }
347
+
348
+ SECTION (" Implies" )
349
+ {
350
+ std::vector<test_entryt> test_values = {
351
+ {true_exprt (), true_exprt (), true_exprt ()},
352
+ {true_exprt (), false_exprt (), false_exprt ()},
353
+ {false_exprt (), true_exprt (), true_exprt ()},
354
+ {false_exprt (), false_exprt (), true_exprt ()},
355
+ };
356
+
357
+ for (const auto &entry : test_values)
358
+ {
359
+ const exprt result =
360
+ simplify_expr (implies_exprt{entry.lhs , entry.rhs }, ns);
361
+ REQUIRE (result == entry.expected_value );
362
+ }
363
+ }
364
+ }
365
+ SECTION (" Not" )
366
+ {
367
+ REQUIRE (simplify_expr (not_exprt{true_exprt ()}, ns) == false_exprt ());
368
+ REQUIRE (simplify_expr (not_exprt{false_exprt ()}, ns) == true_exprt ());
369
+ }
370
+ SECTION (" Nested boolean expressions" )
371
+ {
372
+ INFO (" ((!true) || (false => false)) && true)" )
373
+ REQUIRE (
374
+ simplify_expr (
375
+ and_exprt{or_exprt{not_exprt{true_exprt{}},
376
+ implies_exprt{false_exprt{}, false_exprt{}}},
377
+ true_exprt{}},
378
+ ns) == true_exprt{});
379
+ }
380
+ SECTION (" Numeric comparisons" )
381
+ {
382
+ struct test_entryt
383
+ {
384
+ irep_idt comparison;
385
+ int lhs;
386
+ int rhs;
387
+ exprt expected;
388
+ };
389
+
390
+ std::vector<test_entryt> comparisons = {
391
+ {ID_lt, -1 , 1 , true_exprt ()},
392
+ {ID_lt, 1 , 1 , false_exprt ()},
393
+ {ID_lt, 1 , -1 , false_exprt ()},
394
+
395
+ {ID_le, -1 , 1 , true_exprt ()},
396
+ {ID_le, 1 , 1 , true_exprt ()},
397
+ {ID_le, 1 , -1 , false_exprt ()},
398
+
399
+ {ID_ge, -1 , 1 , false_exprt ()},
400
+ {ID_ge, 1 , 1 , true_exprt ()},
401
+ {ID_ge, 1 , -1 , true_exprt ()},
402
+
403
+ {ID_gt, -1 , 1 , false_exprt ()},
404
+ {ID_gt, 1 , 1 , false_exprt ()},
405
+ {ID_gt, 1 , -1 , true_exprt ()},
406
+ };
407
+
408
+ const auto binary_relation_from = [](const test_entryt &entry) {
409
+ const signedbv_typet int_type (32 );
410
+ return binary_relation_exprt{from_integer (entry.lhs , int_type),
411
+ entry.comparison ,
412
+ from_integer (entry.rhs , int_type)};
413
+ };
414
+
415
+ for (const test_entryt &test_entry : comparisons)
416
+ {
417
+ REQUIRE (
418
+ simplify_expr (binary_relation_from (test_entry), ns) ==
419
+ test_entry.expected );
420
+ }
421
+ }
422
+ }
423
+
424
+ TEST_CASE (" Simplifying cast expressions" , " [core][util]" )
425
+ {
426
+ symbol_tablet symbol_table;
427
+ namespacet ns (symbol_table);
428
+ const auto short_type = signedbv_typet (16 );
429
+ const auto int_type = signedbv_typet (32 );
430
+ const auto long_type = signedbv_typet (64 );
431
+ array_typet array_type (int_type, from_integer (5 , int_type));
432
+
433
+ symbolt a_symbol;
434
+ a_symbol.base_name = " a" ;
435
+ a_symbol.name = " a" ;
436
+ a_symbol.type = array_type;
437
+ a_symbol.is_lvalue = true ;
438
+ symbol_table.add (a_symbol);
439
+
440
+ symbolt i_symbol;
441
+ i_symbol.base_name = " i" ;
442
+ i_symbol.name = " i" ;
443
+ i_symbol.type = int_type;
444
+ i_symbol.is_lvalue = true ;
445
+ symbol_table.add (i_symbol);
446
+
447
+ config.set_arch (" none" );
448
+
449
+ SECTION (" Simplifying a[(signed long int)0]" )
450
+ {
451
+ // a[(signed long int)0]
452
+ index_exprt expr{symbol_exprt{" a" , array_type},
453
+ typecast_exprt{from_integer (0 , int_type), long_type}};
454
+ // cast is applied on the constant
455
+ const auto simplified_expr = simplify_expr (expr, ns);
456
+ REQUIRE (
457
+ simplified_expr ==
458
+ index_exprt{symbol_exprt{" a" , array_type}, from_integer (0 , long_type)});
459
+ }
460
+ SECTION (" Simplifying a[(signed long int)i]" )
461
+ {
462
+ // a[(signed long int)0]
463
+ index_exprt expr{symbol_exprt{" a" , array_type},
464
+ typecast_exprt{i_symbol.symbol_expr (), long_type}};
465
+ // Cast is not removed as up casting a symbol
466
+ const auto simplified_expr = simplify_expr (expr, ns);
467
+ REQUIRE (simplified_expr == expr);
468
+ }
469
+ SECTION (" Simplifying a[(signed int)i]" )
470
+ {
471
+ // a[(signed int)i]
472
+ index_exprt expr{symbol_exprt{" a" , array_type},
473
+ typecast_exprt{i_symbol.symbol_expr (), int_type}};
474
+
475
+ const auto simplified_expr = simplify_expr (expr, ns);
476
+ REQUIRE (
477
+ simplified_expr ==
478
+ index_exprt{symbol_exprt{" a" , array_type}, i_symbol.symbol_expr ()});
479
+ }
480
+ SECTION (" Simplifying a[(signed short)0]" )
481
+ {
482
+ // a[(signed short)0]
483
+ index_exprt expr{symbol_exprt{" a" , array_type},
484
+ typecast_exprt{from_integer (0 , int_type), short_type}};
485
+
486
+ // Can be simplified as the number is a constant
487
+ const auto simplified_expr = simplify_expr (expr, ns);
488
+ REQUIRE (
489
+ simplified_expr ==
490
+ index_exprt{symbol_exprt{" a" , array_type}, from_integer (0 , short_type)});
491
+ }
492
+ SECTION (" Simplifying a[(signed short)i]" )
493
+ {
494
+ // a[(signed short)i]
495
+ index_exprt expr{symbol_exprt{" a" , array_type},
496
+ typecast_exprt{i_symbol.symbol_expr (), short_type}};
497
+
498
+ // No simplification as the cast may have an effect
499
+ const auto simplified_expr = simplify_expr (expr, ns);
500
+ REQUIRE (simplified_expr == expr);
501
+ }
502
+ }
0 commit comments