void subsitute_invariants_rec( const invariant_sett::invariantst &invariants, exprt &dest) { if((dest.id()==ID_and || dest.id()==ID_or || dest.id()==ID_not) && dest.type().id()==ID_bool) { Forall_operands(it, dest) subsitute_invariants_rec(invariants, *it); } else { #if 0 for(invariant_sett::invariantst::expr_sett::const_iterator it=invariants.expr_set().begin(); it!=invariants.expr_set().end(); it++) std::cout << "I: " << it->pretty() << std::endl; std::cout << "DEST: " << dest.pretty() << std::endl; #endif if(invariants.expr_set().find(dest)!= invariants.expr_set().end()) { dest.make_true(); } else { // inverted? exprt tmp(dest); tmp.make_not(); if(invariants.expr_set().find(tmp)!= invariants.expr_set().end()) { dest.make_false(); } } } }
void gen_binary(exprt &expr, const std::string &id, bool default_value) { if(expr.operands().size()==0) { if(default_value) expr.make_true(); else expr.make_false(); } else if(expr.operands().size()==1) { exprt tmp; tmp.swap(expr.op0()); expr.swap(tmp); } else { expr.id(id); expr.type()=typet("bool"); } }
void make_it_a_predicate( const predicatest &predicates, exprt &expr, const namespacet &ns) { bool negation; canonicalize(expr, negation, ns); // see if we have it unsigned nr; if(predicates.find(expr, nr)) { // yes, we do! // see if it is a constant if(predicates[nr].is_true()) expr.make_true(); else if(predicates[nr].is_false()) expr.make_false(); else { expr=exprt(ID_predicate_symbol, typet(ID_bool)); expr.set(ID_identifier, nr); } if(negation) expr.make_not(); } else { // nah, we don't // make it nondeterministic choice exprt tmp(ID_nondet_symbol, typet(ID_bool)); tmp.add(ID_expression).swap(expr); expr.swap(tmp); } }
bool c_typecheck_baset::zero_initializer(exprt &value, const typet &type) const { const std::string &type_id = type.id_string(); if(type_id == "bool") { value.make_false(); return false; } if( type_id == "unsignedbv" || type_id == "signedbv" || type_id == "floatbv" || type_id == "fixedbv" || type_id == "pointer") { value = gen_zero(type); return false; } else if(type_id == "code") return false; else if(type_id == "c_enum" || type_id == "incomplete_c_enum") { value = exprt("constant", type); value.value(i2string(0)); return false; } else if(type_id == "array") { const array_typet &array_type = to_array_type(type); exprt tmpval; if(zero_initializer(tmpval, array_type.subtype())) return true; const exprt &size_expr = array_type.size(); if(size_expr.id() == "infinity") { } else { mp_integer size; if(to_integer(size_expr, size)) return true; // Permit GCC zero sized arrays; disallow negative sized arrays. // Cringe slightly when doing it though. if(size < 0) return true; } value = exprt("array_of", type); value.move_to_operands(tmpval); return false; } else if(type_id == "struct") { const irept::subt &components = type.components().get_sub(); value = exprt("struct", type); forall_irep(it, components) { exprt tmp; if(zero_initializer(tmp, (const typet &)it->type())) return true; value.move_to_operands(tmp); } return false; }
void abstract_expression( const predicatest &predicates, exprt &expr, const namespacet &ns) { if(expr.type().id()!=ID_bool) throw "abstract_expression expects expression of type Boolean"; simplify(expr, ns); if(is_valid(expr, ns)) { // If expr is valid, we can abstract it as 'true' expr.make_true(); } else if(is_unsatisfiable(expr, ns)) { // If expr is unsatisfiable, we can abstract it as 'false' expr.make_false(); } else if(expr.id()==ID_and || expr.id()==ID_or || expr.id()==ID_implies || expr.id()==ID_xor) { Forall_operands(it, expr) abstract_expression(predicates, *it, ns); } else if(expr.id()==ID_not) { assert(expr.operands().size()==1); abstract_expression(predicates, expr.op0(), ns); // remove double negation if(expr.op0().id()==ID_not && expr.op0().operands().size()==1) { exprt tmp; tmp.swap(expr.op0().op0()); expr.swap(tmp); } } else if(expr.id()==ID_if) { assert(expr.operands().size()==3); Forall_operands(it, expr) abstract_expression(predicates, *it, ns); exprt true_expr(ID_and, bool_typet()); true_expr.copy_to_operands(expr.op0(), expr.op1()); exprt false_expr(ID_and, bool_typet()); false_expr.copy_to_operands(gen_not(expr.op0()), expr.op2()); exprt or_expr(ID_or, bool_typet()); or_expr.move_to_operands(true_expr, false_expr); expr.swap(or_expr); } else if(expr.id()==ID_equal || expr.id()==ID_notequal) { if(expr.operands().size()!=2) throw expr.id_string()+" takes two operands"; // Is it equality on Booleans? if(expr.op0().type().id()==ID_bool && expr.op1().type().id()==ID_bool) { // leave it in Forall_operands(it, expr) abstract_expression(predicates, *it, ns); } else // other types, make it a predicate { if(has_non_boolean_if(expr)) { lift_if(expr); abstract_expression(predicates, expr, ns); } else make_it_a_predicate(predicates, expr, ns); } } else if(expr.is_constant()) { // leave it as is } else if(has_non_boolean_if(expr)) { lift_if(expr); abstract_expression(predicates, expr, ns); } else { make_it_a_predicate(predicates, expr, ns); } }