Skip to content

Commit 6b61b16

Browse files
author
Daniel Kroening
committed
add support for let_exprt
1 parent 435a6ee commit 6b61b16

File tree

9 files changed

+97
-9
lines changed

9 files changed

+97
-9
lines changed

src/ansi-c/expr2c.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -944,6 +944,26 @@ std::string expr2ct::convert_with(
944944
return dest;
945945
}
946946

947+
std::string expr2ct::convert_let(
948+
const let_exprt &src,
949+
unsigned precedence)
950+
{
951+
if(src.operands().size()<3)
952+
return convert_norep(src, precedence);
953+
954+
unsigned p0;
955+
std::string op0=convert_with_precedence(src.op0(), p0);
956+
957+
std::string dest="LET ";
958+
dest+=convert(src.symbol());
959+
dest+='=';
960+
dest+=convert(src.value());
961+
dest+=" IN ";
962+
dest+=convert(src.where());
963+
964+
return dest;
965+
}
966+
947967
std::string expr2ct::convert_update(
948968
const exprt &src,
949969
unsigned precedence)
@@ -3936,6 +3956,9 @@ std::string expr2ct::convert_with_precedence(
39363956
else if(src.id()==ID_sizeof)
39373957
return convert_sizeof(src, precedence);
39383958

3959+
else if(src.id()==ID_let)
3960+
return convert_let(to_let_expr(src), precedence=16);
3961+
39393962
else if(src.id()==ID_type)
39403963
return convert(src.type());
39413964

src/ansi-c/expr2c_class.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ class expr2ct
253253
std::string convert_designated_initializer(const exprt &src, unsigned &precedence);
254254
std::string convert_concatenation(const exprt &src, unsigned &precedence);
255255
std::string convert_sizeof(const exprt &src, unsigned &precedence);
256+
std::string convert_let(const let_exprt &, unsigned precedence);
256257

257258
std::string convert_struct(
258259
const exprt &src,

src/solvers/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ SRC = $(BOOLEFORCE_SRC) \
125125
flattening/boolbv_ieee_float_rel.cpp \
126126
flattening/boolbv_if.cpp \
127127
flattening/boolbv_index.cpp \
128+
flattening/boolbv_let.cpp \
128129
flattening/boolbv_map.cpp \
129130
flattening/boolbv_member.cpp \
130131
flattening/boolbv_mod.cpp \

src/solvers/flattening/boolbv.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -278,14 +278,10 @@ bvt boolbvt::convert_bitvector(const exprt &expr)
278278
else if(expr.id()==ID_array_of)
279279
return convert_array_of(to_array_of_expr(expr));
280280
else if(expr.id()==ID_let)
281-
{
282-
// const let_exprt &let_expr=to_let_expr(expr);
283-
throw "let is todo";
284-
}
281+
return convert_let(to_let_expr(expr));
285282
else if(expr.id()==ID_function_application)
286-
{
287-
return convert_function_application(to_function_application_expr(expr));
288-
}
283+
return convert_function_application(
284+
to_function_application_expr(expr));
289285
else if(expr.id()==ID_reduction_or || expr.id()==ID_reduction_and ||
290286
expr.id()==ID_reduction_nor || expr.id()==ID_reduction_nand ||
291287
expr.id()==ID_reduction_xor || expr.id()==ID_reduction_xnor)
@@ -463,6 +459,15 @@ literalt boolbvt::convert_rest(const exprt &expr)
463459
return convert_quantifier(expr);
464460
else if(expr.id()==ID_exists)
465461
return convert_quantifier(expr);
462+
else if(expr.id()==ID_let)
463+
{
464+
bvt bv=convert_let(to_let_expr(expr));
465+
466+
if(bv.size()!=1)
467+
throw "convert_let returned non-bool bitvector";
468+
469+
return bv[0];
470+
}
466471
else if(expr.id()==ID_index)
467472
{
468473
bvt bv=convert_index(to_index_expr(expr));

src/solvers/flattening/boolbv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ class boolbvt:public arrayst
145145
virtual bvt convert_complex_real(const exprt &expr);
146146
virtual bvt convert_complex_imag(const exprt &expr);
147147
virtual bvt convert_lambda(const exprt &expr);
148+
virtual bvt convert_let(const let_exprt &);
148149
virtual bvt convert_array_of(const array_of_exprt &expr);
149150
virtual bvt convert_union(const union_exprt &expr);
150151
virtual bvt convert_bv_typecast(const typecast_exprt &expr);

src/solvers/flattening/boolbv_let.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*******************************************************************\
2+
3+
Module:
4+
5+
Author: Daniel Kroening, [email protected]
6+
7+
\*******************************************************************/
8+
9+
#include "boolbv.h"
10+
11+
#include <util/std_expr.h>
12+
#include <util/std_types.h>
13+
14+
bvt boolbvt::convert_let(const let_exprt &expr)
15+
{
16+
const bvt value_bv=convert_bv(expr.value());
17+
18+
// We expect the bindings to be unique, and
19+
// thus, these can go straight into the symbol to literal map.
20+
// This property also allows us to cache any subexpressions.
21+
const irep_idt &id=expr.symbol().get_identifier();
22+
23+
map.set_literals(id, expr.symbol().type(), value_bv);
24+
bvt result_bv=convert_bv(expr.where());
25+
map.erase_literals(id, expr.symbol().type());
26+
27+
return result_bv;
28+
}

src/solvers/flattening/boolbv_map.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,3 +146,13 @@ void boolbv_mapt::set_literals(
146146
mb.l=literal;
147147
}
148148
}
149+
150+
void boolbv_mapt::erase_literals(
151+
const irep_idt &identifier,
152+
const typet &type)
153+
{
154+
map_entryt &map_entry=get_map_entry(identifier, type);
155+
156+
for(auto &l : map_entry.literal_map)
157+
l.is_set=false;
158+
}

src/solvers/flattening/boolbv_map.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ class boolbv_mapt
7575
const typet &type,
7676
const bvt &literals);
7777

78+
void erase_literals(
79+
const irep_idt &identifier,
80+
const typet &type);
81+
7882
protected:
7983
propt &prop;
8084
const namespacet &ns;

src/solvers/prop/prop_conv.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -327,8 +327,23 @@ literalt prop_conv_solvert::convert_bool(const exprt &expr)
327327
}
328328
else if(expr.id()==ID_let)
329329
{
330-
// const let_exprt &let_expr=to_let_expr(expr);
331-
throw "let is todo";
330+
const let_exprt &let_expr=to_let_expr(expr);
331+
332+
// first check whether this is all boolean
333+
if(let_expr.value().type().id()==ID_bool &&
334+
let_expr.where().type().id()==ID_bool)
335+
{
336+
literalt value=convert(let_expr.value());
337+
338+
// We expect the bindings to be unique, and
339+
// thus, these can go straight into the symbol map.
340+
// This property also allows us to cache any subexpressions.
341+
const irep_idt &id=let_expr.symbol().get_identifier();
342+
symbols[id]=value;
343+
literalt result=convert(let_expr.where());
344+
symbols.erase(id);
345+
return result;
346+
}
332347
}
333348

334349
return convert_rest(expr);

0 commit comments

Comments
 (0)