Skip to content

Commit 50fa5a2

Browse files
author
Thomas Kiley
authored
Merge pull request #5229 from thk123/test-simplify-boolean-expr
Unit tests for simplifying boolean and cast expressions
2 parents 14676e2 + a8c1571 commit 50fa5a2

File tree

1 file changed

+202
-0
lines changed

1 file changed

+202
-0
lines changed

unit/util/simplify_expr.cpp

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)