Skip to content

Commit 2a8f28f

Browse files
committed
expr2smv: enum for precedence
This replaces the use of 'unsigned' and assorted integer literals for the expression precedence by an enum type.
1 parent 1975e77 commit 2a8f28f

File tree

3 files changed

+116
-85
lines changed

3 files changed

+116
-85
lines changed

regression/ebmc/smv/smv_iff2.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
CORE
22
smv_iff2.smv
33
--bdd
4-
^\[.*\] \(AG x != 5\) <-> \(x != 5 & AX AG x != 5\): PROVED$
4+
^\[.*\] AG x != 5 <-> x != 5 & AX AG x != 5: PROVED$
55
^EXIT=0$
66
^SIGNAL=0$
77
--

src/smvlang/expr2smv.cpp

Lines changed: 114 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -21,80 +21,99 @@ class expr2smvt
2121
{
2222
}
2323

24-
bool convert_nondet_choice(const exprt &src, std::string &dest, unsigned precedence);
24+
protected:
25+
// In NuSMV 2.6., ! (not) has a high precedence (above ::), whereas
26+
// in the CMU SMV implementation it has the same as other boolean operators.
27+
// We use the CMU SMV precedence for !.
28+
// Like CMU SMV, we give the same precedence to -> and <->, to avoid ambiguity.
29+
// Note that the precedence of mod in the CMU SMV differs from NuSMV's.
30+
// We use NuSMV's.
31+
enum class precedencet
32+
{
33+
MAX = 16,
34+
INDEX = 15, // [ ] , [ : ]
35+
CONCAT = 14, // ::
36+
UMINUS = 13, // - (unary minus)
37+
MULT = 12, // * / mod
38+
PLUS = 11, // + -
39+
SHIFT = 10, // << >>
40+
UNION = 9, // union
41+
IN = 8, // in
42+
REL = 7, // = != < > <= >=
43+
TEMPORAL = 6, // AX, AF, etc.
44+
NOT = 5, // !
45+
AND = 4, // &
46+
OR = 3, // | xor xnor
47+
IF = 2, // (• ? • : •)
48+
IFF = 1, // <->
49+
IMPLIES = 1 // ->
50+
};
51+
52+
/*
53+
From http://www.cs.cmu.edu/~modelcheck/smv/smvmanual.ps
54+
55+
The order of precedence from high to low is
56+
* /
57+
+ -
58+
mod
59+
= != < > <= >=
60+
!
61+
&
62+
|
63+
-> <->
64+
*/
2565

26-
bool convert_binary(const exprt &src, std::string &dest, const std::string &symbol, unsigned precedence);
66+
public:
67+
bool convert_nondet_choice(
68+
const exprt &src,
69+
std::string &dest,
70+
precedencet precedence);
71+
72+
bool convert_binary(
73+
const exprt &src,
74+
std::string &dest,
75+
const std::string &symbol,
76+
precedencet precedence);
2777

2878
bool convert_unary(
2979
const unary_exprt &,
3080
std::string &dest,
3181
const std::string &symbol,
32-
unsigned precedence);
82+
precedencet precedence);
3383

3484
bool
35-
convert_index(const index_exprt &, std::string &dest, unsigned precedence);
85+
convert_index(const index_exprt &, std::string &dest, precedencet precedence);
3686

37-
bool convert(const exprt &src, std::string &dest, unsigned &precedence);
87+
bool convert(const exprt &src, std::string &dest, precedencet &precedence);
3888

3989
bool convert(const exprt &src, std::string &dest);
4090

41-
bool
42-
convert_symbol(const symbol_exprt &, std::string &dest, unsigned &precedence);
91+
bool convert_symbol(
92+
const symbol_exprt &,
93+
std::string &dest,
94+
precedencet &precedence);
4395

44-
bool convert_next_symbol(const exprt &src, std::string &dest, unsigned &precedence);
96+
bool convert_next_symbol(
97+
const exprt &src,
98+
std::string &dest,
99+
precedencet &precedence);
45100

46-
bool convert_constant(const exprt &src, std::string &dest, unsigned &precedence);
101+
bool convert_constant(
102+
const exprt &src,
103+
std::string &dest,
104+
precedencet &precedence);
47105

48106
bool convert_cond(const exprt &src, std::string &dest);
49107

50-
bool convert_norep(const exprt &src, std::string &dest, unsigned &precedence);
108+
bool
109+
convert_norep(const exprt &src, std::string &dest, precedencet &precedence);
51110

52111
bool convert(const typet &src, std::string &dest);
53112

54113
protected:
55114
const namespacet &ns;
56115
};
57116

58-
/*
59-
From http://www.cs.cmu.edu/~modelcheck/smv/smvmanual.ps
60-
61-
The order of precedence from high to low is
62-
* /
63-
+ -
64-
mod
65-
= != < > <= >=
66-
!
67-
&
68-
|
69-
-> <->
70-
71-
SMV Operator Precedences:
72-
73-
1 %left COMMA
74-
2 %right IMPLIES
75-
3 %left IFF
76-
4 %left OR XOR XNOR
77-
5 %left AND
78-
6 %left NOT
79-
7 %left EX AX EF AF EG AG EE AA SINCE UNTIL TRIGGERED RELEASES EBF EBG ABF ABG BUNTIL MMIN MMAX
80-
8 %left OP_NEXT OP_GLOBAL OP_FUTURE
81-
9 %left OP_PREC OP_NOTPRECNOT OP_HISTORICAL OP_ONCE
82-
10 %left APATH EPATH
83-
11 %left EQUAL NOTEQUAL LT GT LE GE
84-
12 %left UNION
85-
13 %left SETIN
86-
14 %left MOD
87-
15 %left PLUS MINUS
88-
16 %left TIMES DIVIDE
89-
17 %left UMINUS
90-
18 %left NEXT SMALLINIT
91-
19 %left DOT
92-
20 [ ]
93-
21 = max
94-
95-
*/
96-
97-
#define SMV_MAX_PRECEDENCE 21
98117

99118
/*******************************************************************\
100119
@@ -111,7 +130,7 @@ Function: expr2smvt::convert_nondet_choice
111130
bool expr2smvt::convert_nondet_choice(
112131
const exprt &src,
113132
std::string &dest,
114-
unsigned precedence)
133+
precedencet precedence)
115134
{
116135
dest="{ ";
117136

@@ -187,7 +206,7 @@ bool expr2smvt::convert_binary(
187206
const exprt &src,
188207
std::string &dest,
189208
const std::string &symbol,
190-
unsigned precedence)
209+
precedencet precedence)
191210
{
192211
if(src.operands().size()<2)
193212
return convert_norep(src, dest, precedence);
@@ -206,7 +225,7 @@ bool expr2smvt::convert_binary(
206225
}
207226

208227
std::string op;
209-
unsigned p;
228+
precedencet p;
210229

211230
if(convert(*it, op, p)) return true;
212231

@@ -234,10 +253,10 @@ bool expr2smvt::convert_unary(
234253
const unary_exprt &src,
235254
std::string &dest,
236255
const std::string &symbol,
237-
unsigned precedence)
256+
precedencet precedence)
238257
{
239258
std::string op;
240-
unsigned p;
259+
precedencet p;
241260

242261
if(convert(src.op(), op, p))
243262
return true;
@@ -265,10 +284,10 @@ Function: expr2smvt::convert_index
265284
bool expr2smvt::convert_index(
266285
const index_exprt &src,
267286
std::string &dest,
268-
unsigned precedence)
287+
precedencet precedence)
269288
{
270289
std::string op;
271-
unsigned p;
290+
precedencet p;
272291

273292
if(convert(src.op0(), op, p)) return true;
274293

@@ -300,9 +319,9 @@ Function: expr2smvt::convert_norep
300319
bool expr2smvt::convert_norep(
301320
const exprt &src,
302321
std::string &dest,
303-
unsigned &precedence)
322+
precedencet &precedence)
304323
{
305-
precedence=SMV_MAX_PRECEDENCE;
324+
precedence = precedencet::MAX;
306325
dest=src.pretty();
307326
return false;
308327
}
@@ -322,9 +341,9 @@ Function: expr2smvt::convert_symbol
322341
bool expr2smvt::convert_symbol(
323342
const symbol_exprt &src,
324343
std::string &dest,
325-
unsigned &precedence)
344+
precedencet &precedence)
326345
{
327-
precedence=SMV_MAX_PRECEDENCE;
346+
precedence = precedencet::MAX;
328347

329348
auto &symbol = ns.lookup(src);
330349

@@ -348,7 +367,7 @@ Function: expr2smvt::convert_next_symbol
348367
bool expr2smvt::convert_next_symbol(
349368
const exprt &src,
350369
std::string &dest,
351-
unsigned &precedence)
370+
precedencet &precedence)
352371
{
353372
std::string tmp;
354373
convert_symbol(
@@ -374,9 +393,9 @@ Function: expr2smvt::convert_constant
374393
bool expr2smvt::convert_constant(
375394
const exprt &src,
376395
std::string &dest,
377-
unsigned &precedence)
396+
precedencet &precedence)
378397
{
379-
precedence=SMV_MAX_PRECEDENCE;
398+
precedence = precedencet::MAX;
380399

381400
const typet &type=src.type();
382401
const std::string &value=src.get_string(ID_value);
@@ -414,19 +433,19 @@ Function: expr2smvt::convert
414433
bool expr2smvt::convert(
415434
const exprt &src,
416435
std::string &dest,
417-
unsigned &precedence)
436+
precedencet &precedence)
418437
{
419-
precedence=SMV_MAX_PRECEDENCE;
438+
precedence = precedencet::MAX;
420439

421440
if(src.id()==ID_plus)
422-
return convert_binary(src, dest, "+", precedence=15);
441+
return convert_binary(src, dest, "+", precedence = precedencet::PLUS);
423442

424443
else if(src.id()==ID_minus)
425444
{
426445
if(src.operands().size()<2)
427446
return convert_norep(src, dest, precedence);
428-
else
429-
return convert_binary(src, dest, "-", precedence=15);
447+
else
448+
return convert_binary(src, dest, "-", precedence = precedencet::PLUS);
430449
}
431450

432451
else if(src.id()==ID_unary_minus)
@@ -435,55 +454,67 @@ bool expr2smvt::convert(
435454
return convert_norep(src, dest, precedence);
436455
else
437456
return convert_unary(
438-
to_unary_minus_expr(src), dest, "-", precedence = 17);
457+
to_unary_minus_expr(src), dest, "-", precedence = precedencet::UMINUS);
439458
}
440459

441460
else if(src.id()==ID_index)
442-
return convert_index(to_index_expr(src), dest, precedence = 20);
461+
return convert_index(
462+
to_index_expr(src), dest, precedence = precedencet::INDEX);
443463

444464
else if(src.id()==ID_mult || src.id()==ID_div)
445-
return convert_binary(src, dest, src.id_string(), precedence=16);
465+
return convert_binary(
466+
src, dest, src.id_string(), precedence = precedencet::MULT);
446467

447468
else if(src.id()==ID_lt || src.id()==ID_gt ||
448469
src.id()==ID_le || src.id()==ID_ge)
449-
return convert_binary(src, dest, src.id_string(), precedence=11);
470+
return convert_binary(
471+
src, dest, src.id_string(), precedence = precedencet::REL);
450472

451473
else if(src.id()==ID_equal)
452474
{
453475
if(src.get_bool(ID_C_smv_iff))
454-
return convert_binary(src, dest, "<->", precedence = 16);
476+
return convert_binary(src, dest, "<->", precedence = precedencet::IFF);
455477
else
456-
return convert_binary(src, dest, "=", precedence = 11);
478+
return convert_binary(src, dest, "=", precedence = precedencet::REL);
457479
}
458480

459481
else if(src.id()==ID_notequal)
460-
return convert_binary(src, dest, "!=", precedence=11);
482+
return convert_binary(src, dest, "!=", precedence = precedencet::REL);
461483

462484
else if(src.id()==ID_not)
463-
return convert_unary(to_not_expr(src), dest, "!", precedence = 6);
485+
return convert_unary(
486+
to_not_expr(src), dest, "!", precedence = precedencet::NOT);
464487

465488
else if(src.id()==ID_and)
466-
return convert_binary(src, dest, "&", precedence=5);
489+
return convert_binary(src, dest, "&", precedence = precedencet::AND);
467490

468491
else if(src.id()==ID_or)
469-
return convert_binary(src, dest, "|", precedence=4);
492+
return convert_binary(src, dest, "|", precedence = precedencet::OR);
470493

471494
else if(src.id()==ID_implies)
472-
return convert_binary(src, dest, "->", precedence=2);
495+
return convert_binary(src, dest, "->", precedence = precedencet::IMPLIES);
473496

474497
else if(
475498
src.id() == ID_AG || src.id() == ID_EG || src.id() == ID_AF ||
476499
src.id() == ID_EF || src.id() == ID_AX || src.id() == ID_EX ||
477500
src.id() == ID_G || src.id() == ID_F || src.id() == ID_X)
501+
{
478502
return convert_unary(
479-
to_unary_expr(src), dest, src.id_string() + " ", precedence = 7);
503+
to_unary_expr(src),
504+
dest,
505+
src.id_string() + " ",
506+
precedence = precedencet::TEMPORAL);
507+
}
480508

481509
else if(
482510
src.id() == ID_AU || src.id() == ID_EU || src.id() == ID_AR ||
483511
src.id() == ID_ER || src.id() == ID_U || src.id() == ID_R)
484512
{
485513
return convert_binary(
486-
to_binary_expr(src), dest, src.id_string(), precedence = 7);
514+
to_binary_expr(src),
515+
dest,
516+
src.id_string(),
517+
precedence = precedencet::TEMPORAL);
487518
}
488519

489520
else if(src.id()==ID_symbol)
@@ -530,7 +561,7 @@ Function: expr2smvt::convert
530561

531562
bool expr2smvt::convert(const exprt &src, std::string &dest)
532563
{
533-
unsigned precedence;
564+
precedencet precedence;
534565
return convert(src, dest, precedence);
535566
}
536567

src/smvlang/parser.y

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ static void new_module(YYSTYPE &module)
177177
%left EQUAL_Token NOTEQUAL_Token LT_Token GT_Token LE_Token GE_Token
178178
%left UNION_Token
179179
%left IN_Token NOTIN_Token
180-
%left MOD_Token
180+
%left MOD_Token /* Precedence from CMU SMV, different from NuSMV */
181181
%left PLUS_Token MINUS_Token
182182
%left TIMES_Token DIVIDE_Token
183183
%left UMINUS /* supplies precedence for unary minus */

0 commit comments

Comments
 (0)