@@ -21,81 +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+ */
65+
66+ public:
67+ bool convert_nondet_choice (
68+ const exprt &src,
69+ std::string &dest,
70+ precedencet precedence);
2571
26- bool convert_binary (const exprt &src, std::string &dest, const std::string &symbol, unsigned precedence);
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
54113protected:
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
98-
99117/* ******************************************************************\
100118
101119Function: expr2smvt::convert_nondet_choice
@@ -111,7 +129,7 @@ Function: expr2smvt::convert_nondet_choice
111129bool expr2smvt::convert_nondet_choice (
112130 const exprt &src,
113131 std::string &dest,
114- unsigned precedence)
132+ precedencet precedence)
115133{
116134 dest=" { " ;
117135
@@ -187,7 +205,7 @@ bool expr2smvt::convert_binary(
187205 const exprt &src,
188206 std::string &dest,
189207 const std::string &symbol,
190- unsigned precedence)
208+ precedencet precedence)
191209{
192210 if (src.operands ().size ()<2 )
193211 return convert_norep (src, dest, precedence);
@@ -206,7 +224,7 @@ bool expr2smvt::convert_binary(
206224 }
207225
208226 std::string op;
209- unsigned p;
227+ precedencet p;
210228
211229 if (convert (*it, op, p)) return true ;
212230
@@ -234,10 +252,10 @@ bool expr2smvt::convert_unary(
234252 const unary_exprt &src,
235253 std::string &dest,
236254 const std::string &symbol,
237- unsigned precedence)
255+ precedencet precedence)
238256{
239257 std::string op;
240- unsigned p;
258+ precedencet p;
241259
242260 if (convert (src.op (), op, p))
243261 return true ;
@@ -265,10 +283,10 @@ Function: expr2smvt::convert_index
265283bool expr2smvt::convert_index (
266284 const index_exprt &src,
267285 std::string &dest,
268- unsigned precedence)
286+ precedencet precedence)
269287{
270288 std::string op;
271- unsigned p;
289+ precedencet p;
272290
273291 if (convert (src.op0 (), op, p)) return true ;
274292
@@ -300,9 +318,9 @@ Function: expr2smvt::convert_norep
300318bool expr2smvt::convert_norep (
301319 const exprt &src,
302320 std::string &dest,
303- unsigned &precedence)
321+ precedencet &precedence)
304322{
305- precedence=SMV_MAX_PRECEDENCE ;
323+ precedence = precedencet::MAX ;
306324 dest=src.pretty ();
307325 return false ;
308326}
@@ -322,9 +340,9 @@ Function: expr2smvt::convert_symbol
322340bool expr2smvt::convert_symbol (
323341 const symbol_exprt &src,
324342 std::string &dest,
325- unsigned &precedence)
343+ precedencet &precedence)
326344{
327- precedence=SMV_MAX_PRECEDENCE ;
345+ precedence = precedencet::MAX ;
328346
329347 auto &symbol = ns.lookup (src);
330348
@@ -348,7 +366,7 @@ Function: expr2smvt::convert_next_symbol
348366bool expr2smvt::convert_next_symbol (
349367 const exprt &src,
350368 std::string &dest,
351- unsigned &precedence)
369+ precedencet &precedence)
352370{
353371 std::string tmp;
354372 convert_symbol (
@@ -374,9 +392,9 @@ Function: expr2smvt::convert_constant
374392bool expr2smvt::convert_constant (
375393 const exprt &src,
376394 std::string &dest,
377- unsigned &precedence)
395+ precedencet &precedence)
378396{
379- precedence=SMV_MAX_PRECEDENCE ;
397+ precedence = precedencet::MAX ;
380398
381399 const typet &type=src.type ();
382400 const std::string &value=src.get_string (ID_value);
@@ -414,19 +432,19 @@ Function: expr2smvt::convert
414432bool expr2smvt::convert (
415433 const exprt &src,
416434 std::string &dest,
417- unsigned &precedence)
435+ precedencet &precedence)
418436{
419- precedence=SMV_MAX_PRECEDENCE ;
437+ precedence = precedencet::MAX ;
420438
421439 if (src.id ()==ID_plus)
422- return convert_binary (src, dest, " +" , precedence= 15 );
440+ return convert_binary (src, dest, " +" , precedence = precedencet::PLUS );
423441
424442 else if (src.id ()==ID_minus)
425443 {
426444 if (src.operands ().size ()<2 )
427445 return convert_norep (src, dest, precedence);
428- else
429- return convert_binary (src, dest, " -" , precedence= 15 );
446+ else
447+ return convert_binary (src, dest, " -" , precedence = precedencet::PLUS );
430448 }
431449
432450 else if (src.id ()==ID_unary_minus)
@@ -435,55 +453,67 @@ bool expr2smvt::convert(
435453 return convert_norep (src, dest, precedence);
436454 else
437455 return convert_unary (
438- to_unary_minus_expr (src), dest, " -" , precedence = 17 );
456+ to_unary_minus_expr (src), dest, " -" , precedence = precedencet::UMINUS );
439457 }
440458
441459 else if (src.id ()==ID_index)
442- return convert_index (to_index_expr (src), dest, precedence = 20 );
460+ return convert_index (
461+ to_index_expr (src), dest, precedence = precedencet::INDEX);
443462
444463 else if (src.id ()==ID_mult || src.id ()==ID_div)
445- return convert_binary (src, dest, src.id_string (), precedence=16 );
464+ return convert_binary (
465+ src, dest, src.id_string (), precedence = precedencet::MULT);
446466
447467 else if (src.id ()==ID_lt || src.id ()==ID_gt ||
448468 src.id ()==ID_le || src.id ()==ID_ge)
449- return convert_binary (src, dest, src.id_string (), precedence=11 );
469+ return convert_binary (
470+ src, dest, src.id_string (), precedence = precedencet::REL);
450471
451472 else if (src.id ()==ID_equal)
452473 {
453474 if (src.get_bool (ID_C_smv_iff))
454- return convert_binary (src, dest, " <->" , precedence = 16 );
475+ return convert_binary (src, dest, " <->" , precedence = precedencet::IFF );
455476 else
456- return convert_binary (src, dest, " =" , precedence = 11 );
477+ return convert_binary (src, dest, " =" , precedence = precedencet::REL );
457478 }
458479
459480 else if (src.id ()==ID_notequal)
460- return convert_binary (src, dest, " !=" , precedence= 11 );
481+ return convert_binary (src, dest, " !=" , precedence = precedencet::REL );
461482
462483 else if (src.id ()==ID_not)
463- return convert_unary (to_not_expr (src), dest, " !" , precedence = 6 );
484+ return convert_unary (
485+ to_not_expr (src), dest, " !" , precedence = precedencet::NOT);
464486
465487 else if (src.id ()==ID_and)
466- return convert_binary (src, dest, " &" , precedence= 5 );
488+ return convert_binary (src, dest, " &" , precedence = precedencet::AND );
467489
468490 else if (src.id ()==ID_or)
469- return convert_binary (src, dest, " |" , precedence= 4 );
491+ return convert_binary (src, dest, " |" , precedence = precedencet::OR );
470492
471493 else if (src.id ()==ID_implies)
472- return convert_binary (src, dest, " ->" , precedence= 2 );
494+ return convert_binary (src, dest, " ->" , precedence = precedencet::IMPLIES );
473495
474496 else if (
475497 src.id () == ID_AG || src.id () == ID_EG || src.id () == ID_AF ||
476498 src.id () == ID_EF || src.id () == ID_AX || src.id () == ID_EX ||
477499 src.id () == ID_G || src.id () == ID_F || src.id () == ID_X)
500+ {
478501 return convert_unary (
479- to_unary_expr (src), dest, src.id_string () + " " , precedence = 7 );
502+ to_unary_expr (src),
503+ dest,
504+ src.id_string () + " " ,
505+ precedence = precedencet::TEMPORAL);
506+ }
480507
481508 else if (
482509 src.id () == ID_AU || src.id () == ID_EU || src.id () == ID_AR ||
483510 src.id () == ID_ER || src.id () == ID_U || src.id () == ID_R)
484511 {
485512 return convert_binary (
486- to_binary_expr (src), dest, src.id_string (), precedence = 7 );
513+ to_binary_expr (src),
514+ dest,
515+ src.id_string (),
516+ precedence = precedencet::TEMPORAL);
487517 }
488518
489519 else if (src.id ()==ID_symbol)
@@ -530,7 +560,7 @@ Function: expr2smvt::convert
530560
531561bool expr2smvt::convert (const exprt &src, std::string &dest)
532562{
533- unsigned precedence;
563+ precedencet precedence;
534564 return convert (src, dest, precedence);
535565}
536566
0 commit comments