bool simplify_exprt::simplify_sign(exprt &expr) { if(expr.operands().size()!=1) return true; if(expr.op0().is_constant()) { const typet &type=ns.follow(expr.op0().type()); if(type.id()==ID_floatbv) { ieee_floatt value(to_constant_expr(expr.op0())); expr.make_bool(value.get_sign()); return false; } else if(type.id()==ID_signedbv || type.id()==ID_unsignedbv) { mp_integer value; if(!to_integer(expr.op0(), value)) { expr.make_bool(value>=0); return false; } } } return true; }
bool simplify_exprt::simplify_ieee_float_relation(exprt &expr) { assert(expr.id()==ID_ieee_float_equal || expr.id()==ID_ieee_float_notequal); exprt::operandst &operands=expr.operands(); if(expr.type().id()!=ID_bool) return true; if(operands.size()!=2) return true; // types must match if(expr.op0().type()!=expr.op1().type()) return true; if(expr.op0().type().id()!=ID_floatbv) return true; // first see if we compare to a constant if(expr.op0().is_constant() && expr.op1().is_constant()) { ieee_floatt f0(to_constant_expr(expr.op0())); ieee_floatt f1(to_constant_expr(expr.op1())); if(expr.id()==ID_ieee_float_notequal) expr.make_bool(f0.ieee_not_equal(f1)); else if(expr.id()==ID_ieee_float_equal) expr.make_bool(f0.ieee_equal(f1)); else assert(false); return false; } if(expr.op0()==expr.op1()) { // x!=x is the same as saying isnan(op) exprt isnan(ID_isnan, bool_typet()); isnan.copy_to_operands(expr.op0()); if(expr.id()==ID_ieee_float_notequal) { } else if(expr.id()==ID_ieee_float_equal) isnan.make_not(); else assert(false); expr.swap(isnan); return false; } return true; }
bool simplify_exprt::simplify_isnormal(exprt &expr) { if(expr.operands().size()!=1) return true; if(expr.op0().is_constant()) { ieee_floatt value(to_constant_expr(expr.op0())); expr.make_bool(value.is_normal()); return false; } return true; }
bool simplify_exprt::simplify_isinf(exprt &expr) { if(expr.operands().size()!=1) return true; if(ns.follow(expr.op0().type()).id()!=ID_floatbv) return true; if(expr.op0().is_constant()) { ieee_floatt value(to_constant_expr(expr.op0())); expr.make_bool(value.is_infinity()); return false; } return true; }
bool simplify_exprt::simplify_inequality_address_of(exprt &expr) { assert(expr.type().id()==ID_bool); assert(expr.operands().size()==2); assert(expr.id()==ID_equal || expr.id()==ID_notequal); exprt tmp0=expr.op0(); if(tmp0.id()==ID_typecast) tmp0=expr.op0().op0(); if(tmp0.op0().id()==ID_index && to_index_expr(tmp0.op0()).index().is_zero()) tmp0=address_of_exprt(to_index_expr(tmp0.op0()).array()); exprt tmp1=expr.op1(); if(tmp1.id()==ID_typecast) tmp1=expr.op1().op0(); if(tmp1.op0().id()==ID_index && to_index_expr(tmp1.op0()).index().is_zero()) tmp1=address_of_exprt(to_index_expr(tmp1.op0()).array()); assert(tmp0.id()==ID_address_of); assert(tmp1.id()==ID_address_of); if(tmp0.operands().size()!=1) return true; if(tmp1.operands().size()!=1) return true; if(tmp0.op0().id()==ID_symbol && tmp1.op0().id()==ID_symbol) { bool equal= tmp0.op0().get(ID_identifier)== tmp1.op0().get(ID_identifier); expr.make_bool(expr.id()==ID_equal?equal:!equal); return false; } return true; }