bool interval_domaint::ai_simplify( exprt &condition, const namespacet &ns) const { bool unchanged=true; interval_domaint d(*this); // merge intervals to properly handle conjunction if(condition.id()==ID_and) // May be directly representable { interval_domaint a; a.make_top(); // a is everything a.assume(condition, ns); // Restrict a to an over-approximation // of when condition is true if(!a.join(d)) // If d (this) is included in a... { // Then the condition is always true unchanged=condition.is_true(); condition.make_true(); } } else if(condition.id()==ID_symbol) { // TODO: we have to handle symbol expression } else // Less likely to be representable { d.assume(not_exprt(condition), ns); // Restrict to when condition is false if(d.is_bottom()) // If there there are none... { // Then the condition is always true unchanged=condition.is_true(); condition.make_true(); } } return unchanged; }
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); } }
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); } }