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>
@@ -83,8 +84,6 @@ class smv_typecheckt:public typecheckt
83
84
84
85
void check_type (const typet &);
85
86
smv_ranget convert_type (const typet &);
86
- static bool
87
- is_contained_in (const enumeration_typet &, const enumeration_typet &);
88
87
89
88
void convert (smv_parse_treet::modulet::itemt &);
90
89
void typecheck (smv_parse_treet::modulet::itemt &);
@@ -142,6 +141,8 @@ class smv_typecheckt:public typecheckt
142
141
143
142
void lower_node (exprt &) const ;
144
143
144
+ void lower (typet &) const ;
145
+
145
146
void lower (exprt &expr) const
146
147
{
147
148
expr.visit_post ([this ](exprt &expr) { lower_node (expr); });
@@ -150,40 +151,6 @@ class smv_typecheckt:public typecheckt
150
151
151
152
/* ******************************************************************\
152
153
153
- Function: smv_typecheckt::is_contained_in
154
-
155
- Inputs:
156
-
157
- Outputs:
158
-
159
- Purpose:
160
-
161
- \*******************************************************************/
162
-
163
- bool smv_typecheckt::is_contained_in (
164
- const enumeration_typet &type1,
165
- const enumeration_typet &type2)
166
- {
167
- // This is quadratic.
168
- for (auto &element1 : type1.elements ())
169
- {
170
- bool found = false ;
171
- for (auto &element2 : type2.elements ())
172
- if (element1.id () == element2.id ())
173
- {
174
- found = true ;
175
- break ;
176
- }
177
-
178
- if (!found)
179
- return false ;
180
- }
181
-
182
- return true ;
183
- }
184
-
185
- /* ******************************************************************\
186
-
187
154
Function: smv_typecheckt::convert_ports
188
155
189
156
Inputs:
@@ -499,15 +466,15 @@ smv_ranget smv_typecheckt::convert_type(const typet &src)
499
466
{
500
467
return smv_ranget::from_type (to_range_type (src));
501
468
}
502
- else if (src.id ()==ID_enumeration )
469
+ else if (src.id () == ID_smv_enumeration )
503
470
{
504
471
smv_ranget dest;
505
472
506
473
dest.from =0 ;
507
474
508
- std::size_t number_of_elements=
509
- to_enumeration_type (src).elements ().size ();
510
-
475
+ std::size_t number_of_elements =
476
+ to_smv_enumeration_type (src).elements ().size ();
477
+
511
478
if (number_of_elements==0 )
512
479
dest.to =0 ;
513
480
else
@@ -557,36 +524,16 @@ typet smv_typecheckt::type_union(
557
524
}
558
525
559
526
// both enums?
560
- if (type1.id ()==ID_enumeration && type2.id ()==ID_enumeration )
527
+ if (type1.id () == ID_smv_enumeration && type2.id () == ID_smv_enumeration )
561
528
{
562
- auto &e_type1 = to_enumeration_type (type1);
563
- auto &e_type2 = to_enumeration_type (type2);
564
-
565
- if (is_contained_in (e_type2, e_type1))
566
- return type1;
567
-
568
- if (is_contained_in (e_type1, e_type2))
569
- return type2;
570
-
571
- // make union
572
- std::set<irep_idt> enum_set;
573
-
574
- for (auto &e : e_type1.elements ())
575
- enum_set.insert (e.id ());
529
+ auto &e_type1 = to_smv_enumeration_type (type1);
530
+ auto &e_type2 = to_smv_enumeration_type (type2);
576
531
577
- for (auto &e : e_type2.elements ())
578
- enum_set.insert (e.id ());
579
-
580
- enumeration_typet union_type;
581
- union_type.elements ().reserve (enum_set.size ());
582
- for (auto &e : enum_set)
583
- union_type.elements ().push_back (irept{e});
584
-
585
- return std::move (union_type);
532
+ return ::type_union (e_type1, e_type2);
586
533
}
587
534
588
535
// one of them enum?
589
- if (type1.id () == ID_enumeration || type2.id () == ID_enumeration )
536
+ if (type1.id () == ID_smv_enumeration || type2.id () == ID_smv_enumeration )
590
537
{
591
538
throw errort ().with_location (source_location)
592
539
<< " no type union for types " << to_string (type1) << " and "
@@ -869,10 +816,9 @@ void smv_typecheckt::typecheck_expr_rec(exprt &expr, modet mode)
869
816
mp_integer int_value = string2integer (id2string (value));
870
817
expr.type () = range_typet{int_value, int_value};
871
818
}
872
- else if (type.id () == ID_enumeration )
819
+ else if (type.id () == ID_smv_enumeration )
873
820
{
874
- auto t = enumeration_typet{};
875
- t.elements ().push_back (irept{value});
821
+ auto t = smv_enumeration_typet{{value}};
876
822
expr.type () = std::move (t);
877
823
}
878
824
else if (type.id () == ID_bool)
@@ -1253,6 +1199,9 @@ Function: smv_typecheckt::lower_node
1253
1199
1254
1200
void smv_typecheckt::lower_node (exprt &expr) const
1255
1201
{
1202
+ // lower the type
1203
+ lower (expr.type ());
1204
+
1256
1205
if (expr.id () == ID_smv_extend)
1257
1206
{
1258
1207
auto &smv_extend = to_smv_extend_expr (expr);
@@ -1275,6 +1224,27 @@ void smv_typecheckt::lower_node(exprt &expr) const
1275
1224
1276
1225
/* ******************************************************************\
1277
1226
1227
+ Function: smv_typecheckt::lower
1228
+
1229
+ Inputs:
1230
+
1231
+ Outputs:
1232
+
1233
+ Purpose:
1234
+
1235
+ \*******************************************************************/
1236
+
1237
+ void smv_typecheckt::lower (typet &type) const
1238
+ {
1239
+ // lower the type
1240
+ if (type.id () == ID_smv_enumeration)
1241
+ {
1242
+ type.id (ID_enumeration);
1243
+ }
1244
+ }
1245
+
1246
+ /* ******************************************************************\
1247
+
1278
1248
Function: smv_typecheckt::convert_expr_to
1279
1249
1280
1250
Inputs:
@@ -1350,35 +1320,40 @@ void smv_typecheckt::convert_expr_to(exprt &expr, const typet &type)
1350
1320
}
1351
1321
}
1352
1322
}
1353
- else if (type.id () == ID_enumeration )
1323
+ else if (type.id () == ID_smv_enumeration )
1354
1324
{
1355
- auto &e_type = to_enumeration_type (type);
1325
+ auto &e_type = to_smv_enumeration_type (type);
1356
1326
1357
- if (expr.id () == ID_constant && expr. type ().id () == ID_enumeration )
1327
+ if (expr.type ().id () == ID_smv_enumeration )
1358
1328
{
1359
- if (is_contained_in (to_enumeration_type (expr.type ()), e_type))
1329
+ // subset?
1330
+ if (to_smv_enumeration_type (expr.type ()).is_subset_of (e_type))
1360
1331
{
1361
- // re-type the constant
1362
- expr.type () = type;
1363
- return ;
1364
- }
1365
- else
1366
- {
1367
- throw errort ().with_location (expr.find_source_location ())
1368
- << " enum " << to_string (expr) << " not a member of "
1369
- << to_string (type);
1370
- }
1371
- }
1372
- else if (expr.id () == ID_typecast)
1373
- {
1374
- // created by type unions
1375
- auto &op = to_typecast_expr (expr).op ();
1376
- if (
1377
- expr.type ().id () == ID_enumeration &&
1378
- op.type ().id () == ID_enumeration)
1379
- {
1380
- convert_expr_to (op, type);
1381
- expr = std::move (op);
1332
+ // yes, it's a subset
1333
+ if (expr.is_constant ())
1334
+ {
1335
+ // re-type the constant
1336
+ expr.type () = type;
1337
+ return ;
1338
+ }
1339
+ else if (expr.id () == ID_typecast)
1340
+ {
1341
+ // created by type unions
1342
+ auto &op = to_typecast_expr (expr).op ();
1343
+ if (
1344
+ expr.type ().id () == ID_smv_enumeration &&
1345
+ op.type ().id () == ID_smv_enumeration)
1346
+ {
1347
+ convert_expr_to (op, type);
1348
+ expr = std::move (op);
1349
+ return ;
1350
+ }
1351
+ }
1352
+ else // anything else
1353
+ {
1354
+ expr = typecast_exprt{std::move (expr), type};
1355
+ return ;
1356
+ }
1382
1357
}
1383
1358
}
1384
1359
}
@@ -1875,9 +1850,6 @@ void smv_typecheckt::convert(smv_parse_treet::modulet &smv_module)
1875
1850
transt{ID_trans, conjunction (trans_invar), conjunction (trans_init),
1876
1851
conjunction (trans_trans), module_symbol.type };
1877
1852
1878
- // lowering
1879
- lower (module_symbol.value );
1880
-
1881
1853
module_symbol.pretty_name = strip_smv_prefix (module_symbol.name );
1882
1854
1883
1855
symbol_table.add (module_symbol);
@@ -1916,12 +1888,21 @@ void smv_typecheckt::convert(smv_parse_treet::modulet &smv_module)
1916
1888
spec_symbol.pretty_name = strip_smv_prefix (spec_symbol.name );
1917
1889
1918
1890
// lowering
1919
- lower (spec_symbol.value );
1920
1891
1921
1892
symbol_table.add (spec_symbol);
1922
1893
}
1923
1894
}
1924
1895
}
1896
+
1897
+ // lowering
1898
+ for (auto v_it=symbol_table.symbol_module_map .lower_bound (smv_module.name );
1899
+ v_it!=symbol_table.symbol_module_map .upper_bound (smv_module.name );
1900
+ v_it++)
1901
+ {
1902
+ auto &symbol = symbol_table.get_writeable_ref (v_it->second );
1903
+ lower (symbol.type );
1904
+ lower (symbol.value );
1905
+ }
1925
1906
}
1926
1907
1927
1908
/* ******************************************************************\
0 commit comments