diff --git a/CHANGELOG b/CHANGELOG index 414302293..588bb7859 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -4,6 +4,7 @@ # EBMC 5.8 +* SMV: use NuSMV's operator precedence, as opposed to CMU SMV's * AIG/netlist engine: fix for conversion of extract bits operator * Verilog: semantic fix for output register ports * SystemVerilog: cover sequence diff --git a/regression/ebmc/smv-netlist/s_until1.desc b/regression/ebmc/smv-netlist/s_until1.desc index b491f34dc..c5391e203 100644 --- a/regression/ebmc/smv-netlist/s_until1.desc +++ b/regression/ebmc/smv-netlist/s_until1.desc @@ -1,8 +1,8 @@ CORE s_until1.sv --smv-netlist -^LTLSPEC \(\!node144\) U node151$ -^LTLSPEC \(TRUE\) U node158$ +^LTLSPEC \!node144 U node151$ +^LTLSPEC TRUE U node158$ ^EXIT=0$ ^SIGNAL=0$ -- diff --git a/regression/ebmc/smv-word-level/smv1.desc b/regression/ebmc/smv-word-level/smv1.desc index 1e66f7e3c..1386a27eb 100644 --- a/regression/ebmc/smv-word-level/smv1.desc +++ b/regression/ebmc/smv-word-level/smv1.desc @@ -10,7 +10,7 @@ smv1.smv ^INIT range_type = 1$ ^INIT signed_bit_vector = 0sd20_1$ ^INIT unsigned_bit_vector = 0ud20_1$ -^TRANS next\(bool_type\) = \(!bool_type\)$ +^TRANS next\(bool_type\) = !bool_type$ ^TRANS next\(range_type\) = 2$ ^TRANS next\(signed_bit_vector\) = 0sd20_2$ ^TRANS next\(unsigned_bit_vector\) = 0ud20_2$ diff --git a/regression/smv/word/bitwise1.desc b/regression/smv/word/bitwise1.desc index cba35572a..1b8f5f455 100644 --- a/regression/smv/word/bitwise1.desc +++ b/regression/smv/word/bitwise1.desc @@ -1,8 +1,8 @@ CORE bitwise1.smv -^\[.*\] \(!0ud8_123\) = 0ud8_132: PROVED .*$ -^\[.*\] \(!0sd8_123\) = -0sd8_124: PROVED .*$ +^\[.*\] !0ud8_123 = 0ud8_132: PROVED .*$ +^\[.*\] !0sd8_123 = -0sd8_124: PROVED .*$ ^\[.*\] \(0ud8_123 \& 0ud8_7\) = 0ud8_3: PROVED .*$ ^\[.*\] \(0ud8_123 \| 0ud8_7\) = 0ud8_127: PROVED .*$ ^\[.*\] \(0ud8_123 xor 0ud8_7\) = 0ud8_124: PROVED .*$ diff --git a/regression/smv/word/bitwise1.smv b/regression/smv/word/bitwise1.smv index d80dbc400..4d2884b73 100644 --- a/regression/smv/word/bitwise1.smv +++ b/regression/smv/word/bitwise1.smv @@ -1,8 +1,8 @@ MODULE main -- negation -SPEC (!uwconst(123, 8)) = uwconst(132, 8) -SPEC (!swconst(123, 8)) = swconst(-124, 8) +SPEC !uwconst(123, 8) = uwconst(132, 8) +SPEC !swconst(123, 8) = swconst(-124, 8) -- and SPEC (uwconst(123, 8) & uwconst(7, 8)) = uwconst(3, 8) diff --git a/src/smvlang/expr2smv_class.h b/src/smvlang/expr2smv_class.h index 73e5ce6f3..ab7245f9f 100644 --- a/src/smvlang/expr2smv_class.h +++ b/src/smvlang/expr2smv_class.h @@ -35,7 +35,7 @@ class expr2smvt // In NuSMV 2.6., ! (not) has a high precedence (above ::), whereas // in the CMU SMV implementation it has the same as other boolean operators. - // We use the CMU SMV precedence for !. + // We use the NuSMV precedence for !. // Like CMU SMV, we give the same precedence to -> and <->, to avoid ambiguity. // Note that the precedence of mod in the CMU SMV differs from NuSMV's. // We use NuSMV's. @@ -43,16 +43,16 @@ class expr2smvt { MAX = 16, INDEX = 15, // [ ] , [ : ] - CONCAT = 14, // :: + NOT = 14, // ! UMINUS = 13, // - (unary minus) - MULT = 12, // * / mod - PLUS = 11, // + - - SHIFT = 10, // << >> - UNION = 9, // union - IN = 8, // in - REL = 7, // = != < > <= >= - TEMPORAL = 6, // AX, AF, etc. - NOT = 5, // ! + CONCAT = 12, // :: + MULT = 11, // * / mod + PLUS = 10, // + - + SHIFT = 9, // << >> + UNION = 8, // union + IN = 7, // in + REL = 6, // = != < > <= >= + TEMPORAL = 5, // AX, AF, etc. AND = 4, // & OR = 3, // | xor xnor IF = 2, // (• ? • : •) @@ -74,6 +74,26 @@ class expr2smvt -> <-> */ + /* From https://nusmv.fbk.eu/userman/v27/nusmv.pdf + + The order of parsing precedence for operators from high to low is: + [ ] , [ : ] + ! + - (unary minus) + :: + * / mod + + - + << >> + union + in + = != < > <= >= + & + | xor xnor + (• ? • : •) + <-> + -> + */ + struct resultt { resultt(precedencet _p, std::string _s) : p(_p), s(std::move(_s)) diff --git a/src/smvlang/parser.y b/src/smvlang/parser.y index d876587d1..2030c7533 100644 --- a/src/smvlang/parser.y +++ b/src/smvlang/parser.y @@ -328,20 +328,18 @@ static smv_parse_treet::modulet &new_module(YYSTYPE &module_name) %right IMPLIES_Token %left EQUIV_Token %left IF_Token -%left xor_Token xnor_Token -%left OR_Token +%left OR_Token xor_Token xnor_Token %left AND_Token -%left NOT_Token %left EX_Token AX_Token EF_Token AF_Token EG_Token AG_Token E_Token A_Token U_Token R_Token V_Token F_Token G_Token H_Token O_Token S_Token T_Token X_Token Y_Token Z_Token EBF_Token ABF_Token EBG_Token ABG_Token %left EQUAL_Token NOTEQUAL_Token LT_Token GT_Token LE_Token GE_Token %left union_Token %left in_Token -%left mod_Token /* Precedence from CMU SMV, different from NuSMV */ %left LTLT_Token GTGT_Token %left PLUS_Token MINUS_Token -%left TIMES_Token DIVIDE_Token +%left TIMES_Token DIVIDE_Token mod_Token /* mod precedence from NuSMV, different from CMU SMV */ %left COLONCOLON_Token %left UMINUS /* supplies precedence for unary minus */ +%left NOT_Token /* precedence from NuSMV, different from CMU SMV */ %left DOT_Token '[' '(' %%