@@ -298,3 +298,205 @@ TEST_CASE("Simplify cast from bool", "[core][util]")
298298 REQUIRE (simp == B);
299299 }
300300}
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