void bv_cbmct::convert_waitfor_symbol(const exprt &expr, bvt &bv) { if(expr.operands().size()!=1) throw "waitfor_symbol expected to have one operand"; exprt result; const exprt &bound=expr.op0(); make_free_bv_expr(expr.type(), result); // constraint: result<=bound exprt rel_expr(ID_le, bool_typet()); rel_expr.copy_to_operands(result, bound); set_to_true(rel_expr); return convert_bitvector(result, bv); }
void arrayst::add_array_constraints_array_of( const index_sett &index_set, const array_of_exprt &expr) { // we got x=array_of[v] // get other array index applications // and add constraint x[i]=v for(index_sett::const_iterator it=index_set.begin(); it!=index_set.end(); it++) { index_exprt index_expr; index_expr.type()=ns.follow(expr.type()).subtype(); index_expr.array()=expr; index_expr.index()=*it; assert(base_type_eq(index_expr.type(), expr.op0().type(), ns)); // add constraint set_to_true(equality_exprt(index_expr, expr.op0())); } }
void arrayst::add_array_constraints_with( const index_sett &index_set, const with_exprt &expr) { // we got x=(y with [i:=v]) // add constaint x[i]=v const exprt &index=expr.where(); const exprt &value=expr.new_value(); { index_exprt index_expr; index_expr.type()=ns.follow(expr.type()).subtype(); index_expr.array()=expr; index_expr.index()=index; if(index_expr.type()!=value.type()) { std::cout << expr.pretty() << std::endl; assert(false); } set_to_true(equality_exprt(index_expr, value)); } // use other array index applications for "else" case // add constraint x[I]=y[I] for I!=i for(index_sett::const_iterator it=index_set.begin(); it!=index_set.end(); it++) { exprt other_index=*it; if(other_index!=index) { // we first build the guard if(other_index.type()!=index.type()) other_index.make_typecast(index.type()); literalt guard_lit=convert(equality_exprt(index, other_index)); if(guard_lit!=const_literal(true)) { index_exprt index_expr1; index_expr1.type()=ns.follow(expr.type()).subtype(); index_expr1.array()=expr; index_expr1.index()=other_index; index_exprt index_expr2; index_expr2.type()=ns.follow(expr.type()).subtype(); index_expr2.array()=expr.op0(); index_expr2.index()=other_index; assert(index_expr1.type()==index_expr2.type()); equality_exprt equality_expr(index_expr1, index_expr2); literalt equality_lit=convert(equality_expr); // add constraint bvt bv; bv.reserve(2); bv.push_back(equality_lit); bv.push_back(guard_lit); prop.lcnf(bv); } } } }
void bv_cbmct::convert_waitfor(const exprt &expr, bvt &bv) { if(expr.operands().size()!=4) throw "waitfor expected to have four operands"; exprt new_cycle; const exprt &old_cycle=expr.op0(); const exprt &cycle_var=expr.op1(); const exprt &bound=expr.op2(); const exprt &predicate=expr.op3(); make_free_bv_expr(expr.type(), new_cycle); mp_integer bound_value; if(to_integer(bound, bound_value)) throw "waitfor bound must be a constant"; { // constraint: new_cycle>=old_cycle exprt rel_expr(ID_ge, bool_typet()); rel_expr.copy_to_operands(new_cycle, old_cycle); set_to_true(rel_expr); } { // constraint: new_cycle<=bound+1 exprt one=from_integer(1, bound.type()); exprt bound_plus1(ID_plus, bound.type()); bound_plus1.reserve_operands(2); bound_plus1.copy_to_operands(bound); bound_plus1.move_to_operands(one); exprt rel_expr(ID_le, bool_typet()); rel_expr.copy_to_operands(new_cycle, bound_plus1); set_to_true(rel_expr); } for(mp_integer i=0; i<=bound_value; i=i+1) { // replace cycle_var by old_cycle+i; exprt old_cycle_plus_i(ID_plus, old_cycle.type()); old_cycle_plus_i.operands().resize(2); old_cycle_plus_i.op0()=old_cycle; old_cycle_plus_i.op1()=from_integer(i, old_cycle.type()); exprt tmp_predicate=predicate; replace_expr(cycle_var, old_cycle_plus_i, tmp_predicate); // CONSTRAINT: // if((cycle)<=bound) { // if((cycle)<new_cycle) // assume(!property); // else if((cycle)==new_cycle) // assume(property); { exprt cycle_le_bound(ID_le, bool_typet()); cycle_le_bound.operands().resize(2); cycle_le_bound.op0()=old_cycle_plus_i; cycle_le_bound.op1()=bound; exprt cycle_lt_new_cycle(ID_lt, bool_typet()); cycle_lt_new_cycle.operands().resize(2); cycle_lt_new_cycle.op0()=old_cycle_plus_i; cycle_lt_new_cycle.op1()=new_cycle; exprt and_expr(ID_and, bool_typet()); and_expr.operands().resize(2); and_expr.op0().swap(cycle_le_bound); and_expr.op1().swap(cycle_lt_new_cycle); exprt top_impl(ID_implies, bool_typet()); top_impl.reserve_operands(2); top_impl.move_to_operands(and_expr); top_impl.copy_to_operands(tmp_predicate); top_impl.op1().make_not(); set_to_true(top_impl); } { exprt cycle_le_bound(ID_le, bool_typet()); cycle_le_bound.operands().resize(2); cycle_le_bound.op0()=old_cycle_plus_i; cycle_le_bound.op1()=bound; exprt cycle_eq_new_cycle(ID_equal, bool_typet()); cycle_eq_new_cycle.operands().resize(2); cycle_eq_new_cycle.op0()=old_cycle_plus_i; cycle_eq_new_cycle.op1()=new_cycle; exprt and_expr(ID_and, bool_typet()); and_expr.operands().resize(2); and_expr.op0().swap(cycle_le_bound); and_expr.op1().swap(cycle_eq_new_cycle); exprt top_impl(ID_implies, bool_typet()); top_impl.reserve_operands(2); top_impl.move_to_operands(and_expr); top_impl.copy_to_operands(tmp_predicate); set_to_true(top_impl); } } // result: new_cycle return convert_bitvector(new_cycle, bv); }