void guardt::add(const exprt &expr) { assert(expr.type().id()==ID_bool); if(is_false() || expr.is_true()) return; else if(is_true() || expr.is_false()) { *this=expr; return; } else if(id()!=ID_and) { and_exprt a; a.copy_to_operands(*this); *this=a; } operandst &op=operands(); if(expr.id()==ID_and) op.insert(op.end(), expr.operands().begin(), expr.operands().end()); else op.push_back(expr); }
/// checks whether a termination argument implies termination threevalt summarizer_fw_termt::check_termination_argument(exprt expr) { if(expr.is_false()) return YES; // should be of the form /\_i g_i=> R_i if(expr.id()==ID_and) { threevalt result=YES; for(exprt::operandst::iterator it=expr.operands().begin(); it!=expr.operands().end(); it++) { if(it->is_true()) result=UNKNOWN; if(it->id()==ID_implies) { if(it->op1().is_true()) result=UNKNOWN; } } return result; } else { if(expr.id()==ID_implies) { if(expr.op1().is_true()) return UNKNOWN; } else return !expr.is_true() ? YES : UNKNOWN; } return YES; }
void invariant_sett::strengthen_rec(const exprt &expr) { if(expr.type().id()!=ID_bool) throw "non-Boolean argument to strengthen()"; #if 0 std::cout << "S: " << from_expr(*ns, "", expr) << '\n'; #endif if(is_false) { // we can't get any stronger return; } if(expr.is_true()) { // do nothing, it's useless } else if(expr.is_false()) { // wow, that's strong make_false(); } else if(expr.id()==ID_not) { // give up, we expect NNF } else if(expr.id()==ID_and) { forall_operands(it, expr) strengthen_rec(*it); } else if(expr.id()==ID_le || expr.id()==ID_lt) { assert(expr.operands().size()==2); // special rule: x <= (a & b) // implies: x<=a && x<=b if(expr.op1().id()==ID_bitand) { const exprt &bitand_op=expr.op1(); forall_operands(it, bitand_op) { exprt tmp(expr); tmp.op1()=*it; strengthen_rec(tmp); } return; }
void cvc_convt::convert_as_bv(const exprt &expr) { if(expr.type().id()==ID_bool) { if(expr.is_true()) out << "0bin1"; else if(expr.is_false()) out << "0bin0"; else { out << "IF "; convert_expr(expr); out << " THEN 0bin1 ELSE 0bin0 ENDIF"; } } else convert_expr(expr); }
void precondition( const namespacet &ns, value_setst &value_sets, const goto_programt::const_targett target, const symex_target_equationt &equation, const goto_symex_statet &s, exprt &dest) { for(symex_target_equationt::SSA_stepst::const_reverse_iterator it=equation.SSA_steps.rbegin(); it!=equation.SSA_steps.rend(); it++) { preconditiont precondition(ns, value_sets, target, *it, s); precondition.compute(dest); if(dest.is_false()) return; } }
void guardt::guard_expr(exprt &dest) const { if(is_true()) { // do nothing } else { if(dest.is_false()) { dest=as_expr(); dest.make_not(); } else { implies_exprt tmp; tmp.op0()=as_expr(); tmp.op1().swap(dest); dest.swap(tmp); } } }
literalt cvc_convt::convert(const exprt &expr) { //out << "%% E: " << expr << std::endl; if(expr.type().id()!=ID_bool) { std::string msg="cvc_convt::convert got " "non-boolean expression: "; msg+=expr.pretty(); throw msg; } // Three special cases in which we don't need to generate // a handle. if(expr.is_true()) return const_literal(true); else if(expr.is_false()) return const_literal(false); else if(expr.id()==ID_literal) return to_literal_expr(expr).get_literal(); // Generate new handle literalt l(no_boolean_variables, false); no_boolean_variables++; find_symbols(expr); // define new handle out << "ASSERT "; convert_literal(l); out << " <=> ("; convert_expr(expr); out << ");" << std::endl << std::endl; return l; }
void dplib_convt::convert_dplib_expr(const exprt &expr) { if(expr.id()==ID_symbol) { convert_identifier(expr.get_string(ID_identifier)); } else if(expr.id()==ID_nondet_symbol) { convert_identifier("nondet$"+expr.get_string(ID_identifier)); } else if(expr.id()==ID_typecast) { assert(expr.operands().size()==1); const exprt &op=expr.op0(); if(expr.type().id()==ID_bool) { if(op.type().id()==ID_signedbv || op.type().id()==ID_unsignedbv || op.type().id()==ID_pointer) { convert_dplib_expr(op); dplib_prop.out << "/="; convert_dplib_expr(gen_zero(op.type())); } else { throw "TODO typecast1 "+op.type().id_string()+" -> bool"; } } else if(expr.type().id()==ID_signedbv || expr.type().id()==ID_unsignedbv) { unsigned to_width=unsafe_string2unsigned(id2string(expr.type().get(ID_width))); if(op.type().id()==ID_signedbv) { unsigned from_width=unsafe_string2unsigned(id2string(op.type().get(ID_width))); if(from_width==to_width) convert_dplib_expr(op); else if(from_width<to_width) { dplib_prop.out << "SX("; convert_dplib_expr(op); dplib_prop.out << ", " << to_width << ")"; } else { dplib_prop.out << "("; convert_dplib_expr(op); dplib_prop.out << ")[" << (to_width-1) << ":0]"; } } else if(op.type().id()==ID_unsignedbv) { unsigned from_width=unsafe_string2unsigned(id2string(op.type().get(ID_width))); if(from_width==to_width) convert_dplib_expr(op); else if(from_width<to_width) { dplib_prop.out << "(0bin"; for(unsigned i=from_width; i<to_width; i++) dplib_prop.out << "0"; dplib_prop.out << " @ "; dplib_prop.out << "("; convert_dplib_expr(op); dplib_prop.out << "))"; } else { dplib_prop.out << "("; convert_dplib_expr(op); dplib_prop.out << ")[" << (to_width-1) << ":0]"; } } else if(op.type().id()==ID_bool) { if(to_width>1) { dplib_prop.out << "(0bin"; for(unsigned i=1; i<to_width; i++) dplib_prop.out << "0"; dplib_prop.out << " @ "; dplib_prop.out << "IF "; convert_dplib_expr(op); dplib_prop.out << " THEN 0bin1 ELSE 0bin0 ENDIF)"; } else { dplib_prop.out << "IF "; convert_dplib_expr(op); dplib_prop.out << " THEN 0bin1 ELSE 0bin0 ENDIF"; } } else { throw "TODO typecast2 "+op.type().id_string()+ " -> "+expr.type().id_string(); } } else if(expr.type().id()==ID_pointer) { if(op.type().id()==ID_pointer) { convert_dplib_expr(op); } else throw "TODO typecast3 "+op.type().id_string()+" -> pointer"; } else throw "TODO typecast4 ? -> "+expr.type().id_string(); } else if(expr.id()==ID_struct) { dplib_prop.out << "(# "; const struct_typet &struct_type=to_struct_type(expr.type()); const struct_typet::componentst &components= struct_type.components(); assert(components.size()==expr.operands().size()); unsigned i=0; for(struct_typet::componentst::const_iterator it=components.begin(); it!=components.end(); it++, i++) { if(i!=0) dplib_prop.out << ", "; dplib_prop.out << it->get(ID_name); dplib_prop.out << ":="; convert_dplib_expr(expr.operands()[i]); } dplib_prop.out << " #)"; } else if(expr.id()==ID_constant) { if(expr.type().id()==ID_unsignedbv || expr.type().id()==ID_signedbv || expr.type().id()==ID_bv) { dplib_prop.out << "0bin" << expr.get(ID_value); } else if(expr.type().id()==ID_pointer) { const irep_idt &value=expr.get(ID_value); if(value=="NULL") { dplib_prop.out << "(# object:=" << pointer_logic.get_null_object() << ", offset:=" << bin_zero(config.ansi_c.pointer_width) << " #)"; } else throw "unknown pointer constant: "+id2string(value); } else if(expr.type().id()==ID_bool) { if(expr.is_true()) dplib_prop.out << "TRUE"; else if(expr.is_false()) dplib_prop.out << "FALSE"; else throw "unknown boolean constant"; } else if(expr.type().id()==ID_array) { dplib_prop.out << "ARRAY (i: " << array_index_type() << "):"; assert(!expr.operands().empty()); unsigned i=0; forall_operands(it, expr) { if(i==0) dplib_prop.out << "\n IF "; else dplib_prop.out << "\n ELSIF "; dplib_prop.out << "i=" << array_index(i) << " THEN "; convert_array_value(*it); i++; } dplib_prop.out << "\n ELSE "; convert_dplib_expr(expr.op0()); dplib_prop.out << "\n ENDIF"; } else if(expr.type().id()==ID_integer ||
bool prop_convt::get_bool(const exprt &expr, tvt &value) const { // trivial cases if(expr.is_true()) { value=tvt(true); return false; } else if(expr.is_false()) { value=tvt(false); return false; } else if(expr.id()==ID_symbol) { symbolst::const_iterator result= symbols.find(to_symbol_expr(expr).get_identifier()); if(result==symbols.end()) return true; value=prop.l_get(result->second); return false; } // sub-expressions if(expr.id()==ID_not) { if(expr.type().id()==ID_bool && expr.operands().size()==1) { if(get_bool(expr.op0(), value)) return true; value=!value; return false; } } else if(expr.id()==ID_and || expr.id()==ID_or) { if(expr.type().id()==ID_bool && expr.operands().size()>=1) { value=tvt(expr.id()==ID_and); forall_operands(it, expr) { tvt tmp; if(get_bool(*it, tmp)) return true; if(expr.id()==ID_and) { if(tmp.is_false()) { value=tvt(false); return false; } value=value && tmp; } else // or { if(tmp.is_true()) { value=tvt(true); return false; } value=value || tmp; } } return false; }