@@ -12,9 +12,12 @@ Author: Daniel Kroening, kroening@kroening.com
1212
1313#include < solvers/floatbv/float_utils.h>
1414
15+ #include < algorithm>
16+ #include < iterator>
17+
1518#include " boolbv_type.h"
1619
17- bvt boolbvt::convert_unary_minus (const unary_exprt &expr)
20+ bvt boolbvt::convert_unary_minus (const unary_minus_exprt &expr)
1821{
1922 const typet &type=ns.follow (expr.type ());
2023
@@ -23,23 +26,12 @@ bvt boolbvt::convert_unary_minus(const unary_exprt &expr)
2326 if (width==0 )
2427 return conversion_failed (expr);
2528
26- const exprt::operandst &operands=expr.operands ();
27-
28- if (operands.size ()!=1 )
29- throw " unary minus takes one operand" ;
29+ const exprt &op = expr.op ();
3030
31- const exprt &op0=expr.op0 ();
32-
33- const bvt &op_bv=convert_bv (op0);
31+ const bvt &op_bv = convert_bv (op, width);
3432
3533 bvtypet bvtype=get_bvtype (type);
36- bvtypet op_bvtype=get_bvtype (op0.type ());
37- std::size_t op_width=op_bv.size ();
38-
39- bool no_overflow=(expr.id ()==" no-overflow-unary-minus" );
40-
41- if (op_width==0 || op_width!=width)
42- return conversion_failed (expr);
34+ bvtypet op_bvtype = get_bvtype (op.type ());
4335
4436 if (bvtype==bvtypet::IS_UNKNOWN &&
4537 (type.id ()==ID_vector || type.id ()==ID_complex))
@@ -48,68 +40,54 @@ bvt boolbvt::convert_unary_minus(const unary_exprt &expr)
4840
4941 std::size_t sub_width=boolbv_width (subtype);
5042
51- if (sub_width==0 || width%sub_width!=0 )
52- throw " unary-: unexpected vector operand width" ;
43+ INVARIANT (
44+ sub_width > 0 ,
45+ " bitvector representation of type needs to have at least one bit" );
46+
47+ INVARIANT (
48+ width % sub_width == 0 ,
49+ " total bitvector width needs to be a multiple of the component bitvector "
50+ " widths" );
5351
54- std::size_t size=width/sub_width;
5552 bvt bv;
56- bv.resize (width);
5753
58- for (std::size_t i= 0 ; i<size; i++ )
54+ for (std::size_t sub_idx = 0 ; sub_idx < width; sub_idx += sub_width )
5955 {
6056 bvt tmp_op;
61- tmp_op.resize (sub_width);
6257
63- for (std::size_t j=0 ; j<tmp_op.size (); j++)
64- {
65- assert (i*sub_width+j<op_bv.size ());
66- tmp_op[j]=op_bv[i*sub_width+j];
67- }
68-
69- bvt tmp_result;
58+ const auto sub_it = std::next (op_bv.begin (), sub_idx);
59+ std::copy_n (sub_it, sub_width, std::back_inserter (tmp_op));
7060
71- if (type.subtype ().id ()== ID_floatbv)
61+ if (type.subtype ().id () == ID_floatbv)
7262 {
7363 float_utilst float_utils (prop, to_floatbv_type (subtype));
74- tmp_result= float_utils.negate (tmp_op);
64+ tmp_op = float_utils.negate (tmp_op);
7565 }
7666 else
77- tmp_result= bv_utils.negate (tmp_op);
67+ tmp_op = bv_utils.negate (tmp_op);
7868
79- assert (tmp_result.size ()==sub_width);
69+ INVARIANT (
70+ tmp_op.size () == sub_width,
71+ " bitvector after negation shall have same bit width" );
8072
81- for (std::size_t j=0 ; j<tmp_result.size (); j++)
82- {
83- assert (i*sub_width+j<bv.size ());
84- bv[i*sub_width+j]=tmp_result[j];
85- }
73+ std::copy (tmp_op.begin (), tmp_op.end (), std::back_inserter (bv));
8674 }
8775
8876 return bv;
8977 }
9078 else if (bvtype==bvtypet::IS_FIXED && op_bvtype==bvtypet::IS_FIXED)
9179 {
92- if (no_overflow)
93- return bv_utils.negate_no_overflow (op_bv);
94- else
95- return bv_utils.negate (op_bv);
80+ return bv_utils.negate (op_bv);
9681 }
9782 else if (bvtype==bvtypet::IS_FLOAT && op_bvtype==bvtypet::IS_FLOAT)
9883 {
99- assert (!no_overflow);
10084 float_utilst float_utils (prop, to_floatbv_type (expr.type ()));
10185 return float_utils.negate (op_bv);
10286 }
10387 else if ((op_bvtype==bvtypet::IS_SIGNED || op_bvtype==bvtypet::IS_UNSIGNED) &&
10488 (bvtype==bvtypet::IS_SIGNED || bvtype==bvtypet::IS_UNSIGNED))
10589 {
106- if (no_overflow)
107- prop.l_set_to (bv_utils.overflow_negate (op_bv), false );
108-
109- if (no_overflow)
110- return bv_utils.negate_no_overflow (op_bv);
111- else
112- return bv_utils.negate (op_bv);
90+ return bv_utils.negate (op_bv);
11391 }
11492
11593 return conversion_failed (expr);
0 commit comments