Skip to content

Commit 2192b39

Browse files
committed
SMV: avoid ambiguity when generating binary expression strings
1 parent 78d038d commit 2192b39

File tree

2 files changed

+46
-29
lines changed

2 files changed

+46
-29
lines changed

src/smvlang/expr2smv.cpp

+41-27
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ Function: expr2smvt::convert_binary
9090
expr2smvt::resultt expr2smvt::convert_binary(
9191
const exprt &src,
9292
const std::string &symbol,
93-
precedencet precedence)
93+
precedencet precedence,
94+
bool is_associative)
9495
{
9596
if(src.operands().size()<2)
9697
return convert_norep(src);
@@ -112,10 +113,18 @@ expr2smvt::resultt expr2smvt::convert_binary(
112113

113114
auto op_rec = convert_rec(*it);
114115

115-
if(precedence > op_rec.p)
116+
// clang-format off
117+
bool use_parentheses =
118+
src.id() == it->id() && is_associative ? false
119+
: precedence >= op_rec.p;
120+
// clang-format on
121+
122+
if(use_parentheses)
116123
dest += '(';
124+
117125
dest += op_rec.s;
118-
if(precedence > op_rec.p)
126+
127+
if(use_parentheses)
119128
dest += ')';
120129
}
121130

@@ -434,14 +443,14 @@ Function: expr2smvt::convert_rec
434443
expr2smvt::resultt expr2smvt::convert_rec(const exprt &src)
435444
{
436445
if(src.id()==ID_plus)
437-
return convert_binary(src, "+", precedencet::PLUS);
446+
return convert_binary(src, "+", precedencet::PLUS, true);
438447

439448
else if(src.id()==ID_minus)
440449
{
441450
if(src.operands().size()<2)
442451
return convert_norep(src);
443452
else
444-
return convert_binary(src, "-", precedencet::PLUS);
453+
return convert_binary(src, "-", precedencet::PLUS, true);
445454
}
446455

447456
else if(src.id()==ID_unary_minus)
@@ -455,57 +464,60 @@ expr2smvt::resultt expr2smvt::convert_rec(const exprt &src)
455464
else if(src.id()==ID_index)
456465
return convert_index(to_index_expr(src), precedencet::INDEX);
457466

458-
else if(src.id()==ID_mult || src.id()==ID_div)
459-
return convert_binary(src, src.id_string(), precedencet::MULT);
467+
else if(src.id() == ID_mult)
468+
return convert_binary(src, src.id_string(), precedencet::MULT, true);
469+
470+
else if(src.id() == ID_div)
471+
return convert_binary(src, src.id_string(), precedencet::MULT, false);
460472

461473
else if(src.id() == ID_mod)
462-
return convert_binary(src, src.id_string(), precedencet::MULT);
474+
return convert_binary(src, src.id_string(), precedencet::MULT, false);
463475

464476
else if(src.id() == ID_smv_setin)
465-
return convert_binary(src, "in", precedencet::IN);
477+
return convert_binary(src, "in", precedencet::IN, false);
466478

467479
else if(src.id() == ID_smv_setnotin)
468-
return convert_binary(src, "notin", precedencet::IN);
480+
return convert_binary(src, "notin", precedencet::IN, false);
469481

470482
else if(src.id() == ID_smv_union)
471-
return convert_binary(src, "union", precedencet::UNION);
483+
return convert_binary(src, "union", precedencet::UNION, false);
472484

473485
else if(src.id()==ID_lt || src.id()==ID_gt ||
474486
src.id()==ID_le || src.id()==ID_ge)
475-
return convert_binary(src, src.id_string(), precedencet::REL);
487+
return convert_binary(src, src.id_string(), precedencet::REL, false);
476488

477489
else if(src.id()==ID_equal)
478490
{
479491
if(src.get_bool(ID_C_smv_iff))
480-
return convert_binary(src, "<->", precedencet::IFF);
492+
return convert_binary(src, "<->", precedencet::IFF, false);
481493
else
482-
return convert_binary(src, "=", precedencet::REL);
494+
return convert_binary(src, "=", precedencet::REL, false);
483495
}
484496

485497
else if(src.id()==ID_notequal)
486-
return convert_binary(src, "!=", precedencet::REL);
498+
return convert_binary(src, "!=", precedencet::REL, false);
487499

488500
else if(src.id()==ID_not)
489501
return convert_unary(to_not_expr(src), "!", precedencet::NOT);
490502

491503
else if(src.id() == ID_and || src.id() == ID_bitand)
492-
return convert_binary(src, "&", precedencet::AND);
504+
return convert_binary(src, "&", precedencet::AND, true);
493505

494506
else if(src.id() == ID_or || src.id() == ID_bitor)
495-
return convert_binary(src, "|", precedencet::OR);
507+
return convert_binary(src, "|", precedencet::OR, true);
496508

497509
else if(src.id() == ID_implies || src.id() == ID_smv_bitimplies)
498-
return convert_binary(src, "->", precedencet::IMPLIES);
510+
return convert_binary(src, "->", precedencet::IMPLIES, false);
499511

500512
else if(src.id() == ID_xor || src.id() == ID_bitxor)
501-
return convert_binary(src, "xor", precedencet::OR);
513+
return convert_binary(src, "xor", precedencet::OR, true);
502514

503515
else if(src.id() == ID_xnor || src.id() == ID_bitxnor)
504516
{
505517
if(src.get_bool(ID_C_smv_iff))
506-
return convert_binary(src, "<->", precedencet::IFF);
518+
return convert_binary(src, "<->", precedencet::IFF, false);
507519
else
508-
return convert_binary(src, "xnor", precedencet::OR);
520+
return convert_binary(src, "xnor", precedencet::OR, false);
509521
}
510522

511523
else if(
@@ -540,7 +552,7 @@ expr2smvt::resultt expr2smvt::convert_rec(const exprt &src)
540552
src.id() == ID_ER || src.id() == ID_U)
541553
{
542554
return convert_binary(
543-
to_binary_expr(src), src.id_string(), precedencet::TEMPORAL);
555+
to_binary_expr(src), src.id_string(), precedencet::TEMPORAL, false);
544556
}
545557

546558
else if(
@@ -565,15 +577,17 @@ expr2smvt::resultt expr2smvt::convert_rec(const exprt &src)
565577
else if(src.id() == ID_R)
566578
{
567579
// LTL release is "V" in NuSMV
568-
return convert_binary(to_binary_expr(src), "V", precedencet::TEMPORAL);
580+
return convert_binary(
581+
to_binary_expr(src), "V", precedencet::TEMPORAL, false);
569582
}
570583

571584
else if(src.id() == ID_smv_S || src.id() == ID_smv_T)
572585
{
573586
return convert_binary(
574587
to_binary_expr(src),
575588
std::string(src.id_string(), 4, std::string::npos),
576-
precedencet::TEMPORAL);
589+
precedencet::TEMPORAL,
590+
false);
577591
}
578592

579593
else if(src.id() == ID_if)
@@ -608,17 +622,17 @@ expr2smvt::resultt expr2smvt::convert_rec(const exprt &src)
608622

609623
else if(src.id() == ID_concatenation)
610624
{
611-
return convert_binary(to_binary_expr(src), "::", precedencet::CONCAT);
625+
return convert_binary(to_binary_expr(src), "::", precedencet::CONCAT, true);
612626
}
613627

614628
else if(src.id() == ID_shl)
615629
{
616-
return convert_binary(to_binary_expr(src), "<<", precedencet::SHIFT);
630+
return convert_binary(to_binary_expr(src), "<<", precedencet::SHIFT, false);
617631
}
618632

619633
else if(src.id() == ID_lshr || src.id() == ID_ashr)
620634
{
621-
return convert_binary(to_binary_expr(src), ">>", precedencet::SHIFT);
635+
return convert_binary(to_binary_expr(src), ">>", precedencet::SHIFT, false);
622636
}
623637

624638
else if(src.id() == ID_smv_extend)

src/smvlang/expr2smv_class.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,11 @@ class expr2smvt
8787

8888
resultt convert_nondet_choice(const exprt &);
8989

90-
resultt
91-
convert_binary(const exprt &src, const std::string &symbol, precedencet);
90+
resultt convert_binary(
91+
const exprt &src,
92+
const std::string &symbol,
93+
precedencet,
94+
bool is_associative);
9295

9396
resultt convert_rtctl(
9497
const ternary_exprt &src,

0 commit comments

Comments
 (0)