Skip to content

Commit 35e2848

Browse files
author
Daniel Kroening
authored
Merge pull request diffblue#3208 from diffblue/format_expr_table
format_expr: use table and tweak precedences
2 parents 35af452 + 6dca32d commit 35e2848

File tree

4 files changed

+67
-24
lines changed

4 files changed

+67
-24
lines changed

regression/cbmc/show-vcc/main_prec.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
int main()
2+
{
3+
__CPROVER_bool a, b, c;
4+
int x, y, z;
5+
x = y + z;
6+
a = (b == c);
7+
__CPROVER_assert(0, "some property");
8+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
main_prec.c
3+
--show-vcc
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^some property$
7+
^\{-.*\} main::1::x!0@1#2 = main::1::y!0@1#1 \+ main::1::z!0@1#1$
8+
^\{-.*\} main::1::a!0@1#2 ⇔ \(main::1::b!0@1#1 ⇔ main::1::c!0@1#1\)$
9+
--

src/util/format_expr.cpp

Lines changed: 48 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,29 @@ Author: Daniel Kroening, [email protected]
3030
#include <ostream>
3131
#include <stack>
3232

33+
// expressions that are rendered with infix operators
34+
struct infix_opt
35+
{
36+
const char *rep;
37+
};
38+
39+
const std::map<irep_idt, infix_opt> infix_map = {
40+
{ID_plus, {"+"}},
41+
{ID_minus, {"-"}},
42+
{ID_mult, {"*"}},
43+
{ID_div, {"/"}},
44+
{ID_equal, {"="}},
45+
{ID_notequal, {u8"\u2260"}}, // /=, U+2260
46+
{ID_and, {u8"\u2227"}}, // wedge, U+2227
47+
{ID_or, {u8"\u2228"}}, // vee, U+2228
48+
{ID_xor, {u8"\u2295"}}, // + in circle, U+2295
49+
{ID_implies, {u8"\u21d2"}}, // =>, U+21D2
50+
{ID_le, {u8"\u2264"}}, // <=, U+2264
51+
{ID_ge, {u8"\u2265"}}, // >=, U+2265
52+
{ID_lt, {"<"}},
53+
{ID_gt, {">"}},
54+
};
55+
3356
/// We use the precendences that most readers expect
3457
/// (i.e., the ones you learn in primary school),
3558
/// and stay clear of the surprising ones that C has.
@@ -40,6 +63,10 @@ static bool bracket_subexpression(const exprt &sub_expr, const exprt &expr)
4063
if(!sub_expr.has_operands())
4164
return false;
4265

66+
// no need if subexpression isn't an infix operator
67+
if(infix_map.find(sub_expr.id()) == infix_map.end())
68+
return false;
69+
4370
// * and / bind stronger than + and -
4471
if(
4572
(sub_expr.id() == ID_mult || sub_expr.id() == ID_div) &&
@@ -54,6 +81,16 @@ static bool bracket_subexpression(const exprt &sub_expr, const exprt &expr)
5481
(expr.id() == ID_and || expr.id() == ID_or))
5582
return false;
5683

84+
// +, -, *, / bind stronger than ==, !=, <, <=, >, >=
85+
if(
86+
(sub_expr.id() == ID_plus || sub_expr.id() == ID_minus ||
87+
sub_expr.id() == ID_mult || sub_expr.id() == ID_div) &&
88+
(expr.id() == ID_equal || expr.id() == ID_notequal || expr.id() == ID_lt ||
89+
expr.id() == ID_gt || expr.id() == ID_le || expr.id() == ID_ge))
90+
{
91+
return false;
92+
}
93+
5794
return true;
5895
}
5996

@@ -63,31 +100,20 @@ static std::ostream &format_rec(std::ostream &os, const multi_ary_exprt &src)
63100
{
64101
bool first = true;
65102

66-
std::string operator_str;
67-
68-
if(src.id() == ID_and)
69-
operator_str = u8"\u2227"; // wedge, U+2227
70-
else if(src.id() == ID_or)
71-
operator_str = u8"\u2228"; // vee, U+2228
72-
else if(src.id() == ID_xor)
73-
operator_str = u8"\u2295"; // + in circle, U+2295
74-
else if(src.id() == ID_le)
75-
operator_str = u8"\u2264"; // <=, U+2264
76-
else if(src.id() == ID_ge)
77-
operator_str = u8"\u2265"; // >=, U+2265
78-
else if(src.id() == ID_notequal)
79-
operator_str = u8"\u2260"; // /=, U+2260
80-
else if(src.id() == ID_implies)
81-
operator_str = u8"\u21d2"; // =>, U+21D2
82-
else if(src.id() == ID_equal)
103+
std::string operator_str = id2string(src.id()); // default
104+
105+
if(
106+
src.id() == ID_equal && !src.operands().empty() &&
107+
src.op0().type().id() == ID_bool)
83108
{
84-
if(!src.operands().empty() && src.op0().type().id() == ID_bool)
85-
operator_str = u8"\u21d4"; // <=>, U+21D4
86-
else
87-
operator_str = "=";
109+
operator_str = u8"\u21d4"; // <=>, U+21D4
88110
}
89111
else
90-
operator_str = id2string(src.id());
112+
{
113+
auto infix_map_it = infix_map.find(src.id());
114+
if(infix_map_it != infix_map.end())
115+
operator_str = infix_map_it->second.rep;
116+
}
91117

92118
for(const auto &op : src.operands())
93119
{

unit/solvers/miniBDD/miniBDD.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ SCENARIO("miniBDD", "[core][solver][miniBDD]")
347347
{
348348
std::ostringstream oss;
349349
oss << format(o);
350-
REQUIRE(oss.str() == "(a ∧ b) ∨ (¬a)");
350+
REQUIRE(oss.str() == "(a ∧ b) ∨ ¬a");
351351
}
352352

353353
bdd_exprt t(ns);
@@ -356,7 +356,7 @@ SCENARIO("miniBDD", "[core][solver][miniBDD]")
356356
{
357357
std::ostringstream oss;
358358
oss << format(t.as_expr());
359-
REQUIRE(oss.str() == "(¬a) ∨ b");
359+
REQUIRE(oss.str() == "¬a ∨ b");
360360
}
361361
}
362362
}

0 commit comments

Comments
 (0)