Skip to content

Commit 587ad75

Browse files
committed
SMV: add a lowering pass
We currently expect that our solver backends support all expressions generated by the SMV-front-end as-is. To avoid introducing additional, redundant expressions, this adds a lowering pass to the SMV type checker. The lowering pass lowers SMV extend expressions to typecast expressions.
1 parent bb675f6 commit 587ad75

File tree

5 files changed

+86
-3
lines changed

5 files changed

+86
-3
lines changed

regression/smv/word/extend1.desc

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
KNOWNBUG
1+
CORE
22
extend1.smv
33

4+
^\[p0\] 0ud1_1 = 0ud8_1: PROVED$
5+
^\[p1\] -0sd1_1 = -0sd8_1: PROVED$
46
^EXIT=0$
57
^SIGNAL=0$
68
--

regression/smv/word/extend1.smv

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
MODULE main
22

3-
SPEC extend(uwconst(1, 1), 7) = uwconst(1, 8)
4-
SPEC extend(swconst(-1, 1), 7) = swconst(-1, 8)
3+
SPEC NAME p0 := extend(uwconst(1, 1), 7) = uwconst(1, 8)
4+
SPEC NAME p1 := extend(swconst(-1, 1), 7) = swconst(-1, 8)

src/smvlang/expr2smv.cpp

+42
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,43 @@ expr2smvt::resultt expr2smvt::convert_binary(
124124

125125
/*******************************************************************\
126126
127+
Function: expr2smvt::convert_function_application
128+
129+
Inputs:
130+
131+
Outputs:
132+
133+
Purpose:
134+
135+
\*******************************************************************/
136+
137+
expr2smvt::resultt expr2smvt::convert_function_application(
138+
const std::string &symbol,
139+
const exprt &src)
140+
{
141+
bool first = true;
142+
143+
std::string dest = symbol + '(';
144+
145+
for(auto &op : src.operands())
146+
{
147+
if(first)
148+
first = false;
149+
else
150+
{
151+
dest += ',';
152+
dest += ' ';
153+
}
154+
155+
auto op_rec = convert_rec(op);
156+
dest += op_rec.s;
157+
}
158+
159+
return {precedencet::MAX, dest + ')'};
160+
}
161+
162+
/*******************************************************************\
163+
127164
Function: expr2smvt::convert_rtctl
128165
129166
Inputs:
@@ -584,6 +621,11 @@ expr2smvt::resultt expr2smvt::convert_rec(const exprt &src)
584621
return convert_binary(to_binary_expr(src), ">>", precedencet::SHIFT);
585622
}
586623

624+
else if(src.id() == ID_smv_extend)
625+
{
626+
return convert_function_application("extend", src);
627+
}
628+
587629
else if(src.id() == ID_typecast)
588630
{
589631
return convert_rec(to_typecast_expr(src).op());

src/smvlang/expr2smv_class.h

+3
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,9 @@ class expr2smvt
116116

117117
resultt convert_cond(const exprt &);
118118

119+
resultt
120+
convert_function_application(const std::string &symbol, const exprt &);
121+
119122
resultt convert_norep(const exprt &);
120123
};
121124

src/smvlang/smv_typecheck.cpp

+36
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,12 @@ class smv_typecheckt:public typecheckt
137137
else
138138
return id;
139139
}
140+
141+
void lower_node(exprt &) const;
142+
void lower(exprt &expr) const
143+
{
144+
expr.visit_post([this](exprt &expr) { lower_node(expr); });
145+
}
140146
};
141147

142148
/*******************************************************************\
@@ -1227,6 +1233,27 @@ void smv_typecheckt::typecheck_expr_rec(exprt &expr, modet mode)
12271233

12281234
/*******************************************************************\
12291235
1236+
Function: smv_typecheckt::lower_node
1237+
1238+
Inputs:
1239+
1240+
Outputs:
1241+
1242+
Purpose:
1243+
1244+
\*******************************************************************/
1245+
1246+
void smv_typecheckt::lower_node(exprt &expr) const
1247+
{
1248+
if(expr.id() == ID_smv_extend)
1249+
{
1250+
auto &binary = to_binary_expr(expr);
1251+
expr = typecast_exprt{binary.lhs(), expr.type()};
1252+
}
1253+
}
1254+
1255+
/*******************************************************************\
1256+
12301257
Function: smv_typecheckt::convert_expr_to
12311258
12321259
Inputs:
@@ -1497,53 +1524,62 @@ void smv_typecheckt::typecheck(
14971524
case smv_parse_treet::modulet::itemt::INIT:
14981525
typecheck(item.expr, INIT);
14991526
convert_expr_to(item.expr, bool_typet{});
1527+
lower(item.expr);
15001528
return;
15011529

15021530
case smv_parse_treet::modulet::itemt::TRANS:
15031531
typecheck(item.expr, TRANS);
15041532
convert_expr_to(item.expr, bool_typet{});
1533+
lower(item.expr);
15051534
return;
15061535

15071536
case smv_parse_treet::modulet::itemt::CTLSPEC:
15081537
typecheck(item.expr, CTL);
15091538
convert_expr_to(item.expr, bool_typet{});
1539+
lower(item.expr);
15101540
return;
15111541

15121542
case smv_parse_treet::modulet::itemt::LTLSPEC:
15131543
typecheck(item.expr, LTL);
15141544
convert_expr_to(item.expr, bool_typet{});
1545+
lower(item.expr);
15151546
return;
15161547

15171548
case smv_parse_treet::modulet::itemt::INVAR:
15181549
case smv_parse_treet::modulet::itemt::FAIRNESS:
15191550
typecheck(item.expr, OTHER);
15201551
convert_expr_to(item.expr, bool_typet{});
1552+
lower(item.expr);
15211553
return;
15221554

15231555
case smv_parse_treet::modulet::itemt::ASSIGN_CURRENT:
15241556
typecheck(item.equal_expr().lhs(), OTHER);
15251557
typecheck(item.equal_expr().rhs(), OTHER);
15261558
convert_expr_to(item.equal_expr().rhs(), item.equal_expr().lhs().type());
15271559
item.equal_expr().type() = bool_typet{};
1560+
lower(item.expr);
15281561
return;
15291562

15301563
case smv_parse_treet::modulet::itemt::ASSIGN_INIT:
15311564
typecheck(item.equal_expr().lhs(), INIT);
15321565
typecheck(item.equal_expr().rhs(), INIT);
15331566
convert_expr_to(item.equal_expr().rhs(), item.equal_expr().lhs().type());
15341567
item.equal_expr().type() = bool_typet{};
1568+
lower(item.expr);
15351569
return;
15361570

15371571
case smv_parse_treet::modulet::itemt::ASSIGN_NEXT:
15381572
typecheck(item.equal_expr().lhs(), TRANS);
15391573
typecheck(item.equal_expr().rhs(), TRANS);
15401574
convert_expr_to(item.equal_expr().rhs(), item.equal_expr().lhs().type());
15411575
item.equal_expr().type() = bool_typet{};
1576+
lower(item.expr);
15421577
return;
15431578

15441579
case smv_parse_treet::modulet::itemt::DEFINE:
15451580
typecheck(item.expr, OTHER);
15461581
item.equal_expr().type() = bool_typet{};
1582+
lower(item.expr);
15471583
return;
15481584
}
15491585
}

0 commit comments

Comments
 (0)