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)
@@ -1528,6 +1474,30 @@ void smv_typecheckt::lower_node(exprt &expr) const
1528
1474
auto one = from_integer (1 , expr.type ());
1529
1475
expr = if_exprt{op, std::move (one), std::move (zero)};
1530
1476
}
1477
+
1478
+ // lower the type
1479
+ lower (expr.type ());
1480
+ }
1481
+
1482
+ /* ******************************************************************\
1483
+
1484
+ Function: smv_typecheckt::lower
1485
+
1486
+ Inputs:
1487
+
1488
+ Outputs:
1489
+
1490
+ Purpose:
1491
+
1492
+ \*******************************************************************/
1493
+
1494
+ void smv_typecheckt::lower (typet &type) const
1495
+ {
1496
+ // lower the type
1497
+ if (type.id () == ID_smv_enumeration)
1498
+ {
1499
+ type.id (ID_enumeration);
1500
+ }
1531
1501
}
1532
1502
1533
1503
/* ******************************************************************\
@@ -1643,33 +1613,40 @@ void smv_typecheckt::convert_expr_to(exprt &expr, const typet &dest_type)
1643
1613
}
1644
1614
}
1645
1615
}
1646
- else if (dest_type.id () == ID_enumeration )
1616
+ else if (dest_type.id () == ID_smv_enumeration )
1647
1617
{
1648
- auto &e_type = to_enumeration_type (dest_type);
1618
+ auto &dest_e_type = to_smv_enumeration_type (dest_type);
1649
1619
1650
- if (expr.id () == ID_constant && src_type .id () == ID_enumeration )
1620
+ if (expr.type () .id () == ID_smv_enumeration )
1651
1621
{
1652
- if (is_contained_in (to_enumeration_type (src_type), e_type))
1622
+ // subset?
1623
+ if (to_smv_enumeration_type (expr.type ()).is_subset_of (dest_e_type))
1653
1624
{
1654
- // re-type the constant
1655
- expr.type () = dest_type;
1656
- return ;
1657
- }
1658
- else
1659
- {
1660
- throw errort ().with_location (expr.find_source_location ())
1661
- << " enum " << to_string (expr) << " not a member of "
1662
- << to_string (dest_type);
1663
- }
1664
- }
1665
- else if (expr.id () == ID_typecast)
1666
- {
1667
- // created by type unions
1668
- auto &op = to_typecast_expr (expr).op ();
1669
- if (src_type.id () == ID_enumeration && op.type ().id () == ID_enumeration)
1670
- {
1671
- convert_expr_to (op, dest_type);
1672
- expr = std::move (op);
1625
+ // yes, it's a subset
1626
+ if (expr.is_constant ())
1627
+ {
1628
+ // re-type the constant
1629
+ expr.type () = dest_type;
1630
+ return ;
1631
+ }
1632
+ else if (expr.id () == ID_typecast)
1633
+ {
1634
+ // created by type unions
1635
+ auto &op = to_typecast_expr (expr).op ();
1636
+ if (
1637
+ expr.type ().id () == ID_smv_enumeration &&
1638
+ op.type ().id () == ID_smv_enumeration)
1639
+ {
1640
+ convert_expr_to (op, dest_type);
1641
+ expr = std::move (op);
1642
+ return ;
1643
+ }
1644
+ }
1645
+ else // anything else
1646
+ {
1647
+ expr = typecast_exprt{std::move (expr), dest_type};
1648
+ return ;
1649
+ }
1673
1650
}
1674
1651
}
1675
1652
}
@@ -2167,9 +2144,6 @@ void smv_typecheckt::convert(smv_parse_treet::modulet &smv_module)
2167
2144
transt{ID_trans, conjunction (trans_invar), conjunction (trans_init),
2168
2145
conjunction (trans_trans), module_symbol.type };
2169
2146
2170
- // lowering
2171
- lower (module_symbol.value );
2172
-
2173
2147
module_symbol.pretty_name = strip_smv_prefix (module_symbol.name );
2174
2148
2175
2149
symbol_table.add (module_symbol);
@@ -2208,12 +2182,21 @@ void smv_typecheckt::convert(smv_parse_treet::modulet &smv_module)
2208
2182
spec_symbol.pretty_name = strip_smv_prefix (spec_symbol.name );
2209
2183
2210
2184
// lowering
2211
- lower (spec_symbol.value );
2212
2185
2213
2186
symbol_table.add (spec_symbol);
2214
2187
}
2215
2188
}
2216
2189
}
2190
+
2191
+ // lowering
2192
+ for (auto v_it=symbol_table.symbol_module_map .lower_bound (smv_module.name );
2193
+ v_it!=symbol_table.symbol_module_map .upper_bound (smv_module.name );
2194
+ v_it++)
2195
+ {
2196
+ auto &symbol = symbol_table.get_writeable_ref (v_it->second );
2197
+ lower (symbol.type );
2198
+ lower (symbol.value );
2199
+ }
2217
2200
}
2218
2201
2219
2202
/* ******************************************************************\
0 commit comments