19
19
#include " expr2smv.h"
20
20
#include " smv_expr.h"
21
21
#include " smv_range.h"
22
+ #include " smv_types.h"
22
23
23
24
#include < algorithm>
24
25
#include < cassert>
@@ -82,8 +83,6 @@ class smv_typecheckt:public typecheckt
82
83
83
84
void check_type (const typet &);
84
85
smv_ranget convert_type (const typet &);
85
- static bool
86
- is_contained_in (const enumeration_typet &, const enumeration_typet &);
87
86
88
87
void convert (smv_parse_treet::modulet::itemt &);
89
88
void typecheck (smv_parse_treet::modulet::itemt &);
@@ -141,6 +140,8 @@ class smv_typecheckt:public typecheckt
141
140
142
141
void lower_node (exprt &) const ;
143
142
143
+ void lower (typet &) const ;
144
+
144
145
void lower (exprt &expr) const
145
146
{
146
147
expr.visit_post ([this ](exprt &expr) { lower_node (expr); });
@@ -149,40 +150,6 @@ class smv_typecheckt:public typecheckt
149
150
150
151
/* ******************************************************************\
151
152
152
- Function: smv_typecheckt::is_contained_in
153
-
154
- Inputs:
155
-
156
- Outputs:
157
-
158
- Purpose:
159
-
160
- \*******************************************************************/
161
-
162
- bool smv_typecheckt::is_contained_in (
163
- const enumeration_typet &type1,
164
- const enumeration_typet &type2)
165
- {
166
- // This is quadratic.
167
- for (auto &element1 : type1.elements ())
168
- {
169
- bool found = false ;
170
- for (auto &element2 : type2.elements ())
171
- if (element1.id () == element2.id ())
172
- {
173
- found = true ;
174
- break ;
175
- }
176
-
177
- if (!found)
178
- return false ;
179
- }
180
-
181
- return true ;
182
- }
183
-
184
- /* ******************************************************************\
185
-
186
153
Function: smv_typecheckt::convert_ports
187
154
188
155
Inputs:
@@ -498,15 +465,15 @@ smv_ranget smv_typecheckt::convert_type(const typet &src)
498
465
{
499
466
return smv_ranget::from_type (to_range_type (src));
500
467
}
501
- else if (src.id ()==ID_enumeration )
468
+ else if (src.id () == ID_smv_enumeration )
502
469
{
503
470
smv_ranget dest;
504
471
505
472
dest.from =0 ;
506
473
507
- std::size_t number_of_elements=
508
- to_enumeration_type (src).elements ().size ();
509
-
474
+ std::size_t number_of_elements =
475
+ to_smv_enumeration_type (src).elements ().size ();
476
+
510
477
if (number_of_elements==0 )
511
478
dest.to =0 ;
512
479
else
@@ -556,36 +523,16 @@ typet smv_typecheckt::type_union(
556
523
}
557
524
558
525
// both enums?
559
- if (type1.id ()==ID_enumeration && type2.id ()==ID_enumeration )
526
+ if (type1.id () == ID_smv_enumeration && type2.id () == ID_smv_enumeration )
560
527
{
561
- auto &e_type1 = to_enumeration_type (type1);
562
- auto &e_type2 = to_enumeration_type (type2);
563
-
564
- if (is_contained_in (e_type2, e_type1))
565
- return type1;
566
-
567
- if (is_contained_in (e_type1, e_type2))
568
- return type2;
569
-
570
- // make union
571
- std::set<irep_idt> enum_set;
572
-
573
- for (auto &e : e_type1.elements ())
574
- enum_set.insert (e.id ());
575
-
576
- for (auto &e : e_type2.elements ())
577
- enum_set.insert (e.id ());
528
+ auto &e_type1 = to_smv_enumeration_type (type1);
529
+ auto &e_type2 = to_smv_enumeration_type (type2);
578
530
579
- enumeration_typet union_type;
580
- union_type.elements ().reserve (enum_set.size ());
581
- for (auto &e : enum_set)
582
- union_type.elements ().push_back (irept{e});
583
-
584
- return std::move (union_type);
531
+ return ::type_union (e_type1, e_type2);
585
532
}
586
533
587
534
// one of them enum?
588
- if (type1.id () == ID_enumeration || type2.id () == ID_enumeration )
535
+ if (type1.id () == ID_smv_enumeration || type2.id () == ID_smv_enumeration )
589
536
{
590
537
throw errort ().with_location (source_location)
591
538
<< " no type union for types " << to_string (type1) << " and "
@@ -868,10 +815,9 @@ void smv_typecheckt::typecheck_expr_rec(exprt &expr, modet mode)
868
815
mp_integer int_value = string2integer (id2string (value));
869
816
expr.type () = range_typet{int_value, int_value};
870
817
}
871
- else if (type.id () == ID_enumeration )
818
+ else if (type.id () == ID_smv_enumeration )
872
819
{
873
- auto t = enumeration_typet{};
874
- t.elements ().push_back (irept{value});
820
+ auto t = smv_enumeration_typet{{value}};
875
821
expr.type () = std::move (t);
876
822
}
877
823
else if (type.id () == ID_bool)
@@ -1252,6 +1198,9 @@ Function: smv_typecheckt::lower_node
1252
1198
1253
1199
void smv_typecheckt::lower_node (exprt &expr) const
1254
1200
{
1201
+ // lower the type
1202
+ lower (expr.type ());
1203
+
1255
1204
if (expr.id () == ID_smv_extend)
1256
1205
{
1257
1206
auto &smv_extend = to_smv_extend_expr (expr);
@@ -1274,6 +1223,27 @@ void smv_typecheckt::lower_node(exprt &expr) const
1274
1223
1275
1224
/* ******************************************************************\
1276
1225
1226
+ Function: smv_typecheckt::lower
1227
+
1228
+ Inputs:
1229
+
1230
+ Outputs:
1231
+
1232
+ Purpose:
1233
+
1234
+ \*******************************************************************/
1235
+
1236
+ void smv_typecheckt::lower (typet &type) const
1237
+ {
1238
+ // lower the type
1239
+ if (type.id () == ID_smv_enumeration)
1240
+ {
1241
+ type.id (ID_enumeration);
1242
+ }
1243
+ }
1244
+
1245
+ /* ******************************************************************\
1246
+
1277
1247
Function: smv_typecheckt::convert_expr_to
1278
1248
1279
1249
Inputs:
@@ -1340,35 +1310,40 @@ void smv_typecheckt::convert_expr_to(exprt &expr, const typet &type)
1340
1310
}
1341
1311
}
1342
1312
}
1343
- else if (type.id () == ID_enumeration )
1313
+ else if (type.id () == ID_smv_enumeration )
1344
1314
{
1345
- auto &e_type = to_enumeration_type (type);
1315
+ auto &e_type = to_smv_enumeration_type (type);
1346
1316
1347
- if (expr.id () == ID_constant && expr.type ().id () == ID_enumeration)
1348
- {
1349
- if (is_contained_in (to_enumeration_type (expr.type ()), e_type))
1350
- {
1351
- // re-type the constant
1352
- expr.type () = type;
1353
- return ;
1354
- }
1355
- else
1356
- {
1357
- throw errort ().with_location (expr.find_source_location ())
1358
- << " enum " << to_string (expr) << " not a member of "
1359
- << to_string (type);
1360
- }
1361
- }
1362
- else if (expr.id () == ID_typecast)
1317
+ if (expr.type ().id () == ID_smv_enumeration)
1363
1318
{
1364
- // created by type unions
1365
- auto &op = to_typecast_expr (expr).op ();
1366
- if (
1367
- expr.type ().id () == ID_enumeration &&
1368
- op.type ().id () == ID_enumeration)
1319
+ // subset?
1320
+ if (to_smv_enumeration_type (expr.type ()).is_subset_of (e_type))
1369
1321
{
1370
- convert_expr_to (op, type);
1371
- expr = std::move (op);
1322
+ // yes, it's a subset
1323
+ if (expr.is_constant ())
1324
+ {
1325
+ // re-type the constant
1326
+ expr.type () = type;
1327
+ return ;
1328
+ }
1329
+ else if (expr.id () == ID_typecast)
1330
+ {
1331
+ // created by type unions
1332
+ auto &op = to_typecast_expr (expr).op ();
1333
+ if (
1334
+ expr.type ().id () == ID_smv_enumeration &&
1335
+ op.type ().id () == ID_smv_enumeration)
1336
+ {
1337
+ convert_expr_to (op, type);
1338
+ expr = std::move (op);
1339
+ return ;
1340
+ }
1341
+ }
1342
+ else // anything else
1343
+ {
1344
+ expr = typecast_exprt{std::move (expr), type};
1345
+ return ;
1346
+ }
1372
1347
}
1373
1348
}
1374
1349
}
@@ -1862,6 +1837,7 @@ void smv_typecheckt::convert(smv_parse_treet::modulet &smv_module)
1862
1837
conjunction (trans_trans), module_symbol.type };
1863
1838
1864
1839
// lowering
1840
+ lower (module_symbol.type );
1865
1841
lower (module_symbol.value );
1866
1842
1867
1843
module_symbol.pretty_name = strip_smv_prefix (module_symbol.name );
@@ -1902,6 +1878,7 @@ void smv_typecheckt::convert(smv_parse_treet::modulet &smv_module)
1902
1878
spec_symbol.pretty_name = strip_smv_prefix (spec_symbol.name );
1903
1879
1904
1880
// lowering
1881
+ lower (spec_symbol.type );
1905
1882
lower (spec_symbol.value );
1906
1883
1907
1884
symbol_table.add (spec_symbol);
0 commit comments