pair<integer::mapit,integer::mapit> integer::get_locs(const z3::expr& hb, bool& possibly_equal) const { // we need to flip that bool parameter in to know if we are sure about this result or not (two locations can be assigned an equal integer) auto loc1 = location_lookup.end(); auto loc2 = location_lookup.end(); switch(hb.kind()) { case Z3_APP_AST: { z3::func_decl d = hb.decl(); Z3_decl_kind dk = d.decl_kind(); switch(dk) { case Z3_OP_LE: possibly_equal = true; // fallthrough case Z3_OP_LT: if (hb.arg(1).kind() == Z3_NUMERAL_AST) return get_locs(hb.arg(0), possibly_equal); loc1 = location_lookup.find(hb.arg(0)); loc2 = location_lookup.find(hb.arg(1)); break; case Z3_OP_GE: possibly_equal = true; // fallthrough case Z3_OP_GT: if (hb.arg(1).kind() == Z3_NUMERAL_AST) { return swap_pair(get_locs(hb.arg(0), possibly_equal)); } loc1 = location_lookup.find(hb.arg(1)); loc2 = location_lookup.find(hb.arg(0)); break; case Z3_OP_NOT: { auto res = swap_pair(get_locs(hb.arg(0), possibly_equal)); possibly_equal = !possibly_equal; return res; break; } case Z3_OP_ADD: { loc1 = location_lookup.find(hb.arg(0)); z3::expr t1 = hb.arg(1); if (t1.decl().decl_kind() == Z3_OP_MUL) { loc2 = location_lookup.find(t1.arg(1)); } } default: break; } break; } default: break; } return make_pair<integer::mapit,integer::mapit>(std::move(loc1),std::move(loc2)); }
hb_ptr integer::get_hb(const z3::expr& hb, bool allow_equal) const { bool possibly_equal = false; bool is_partial = false; z3::expr hb_p = hb; if( z3.is_implies( hb ) ) { hb_p = hb.arg(1); } if( z3.is_bool_const( hb_p ) ) { auto it = current_rf_map.find( z3.get_top_func_name( hb_p ) ); if( it != current_rf_map.end() ) { return it->second; } } auto p = get_locs(hb, possibly_equal, is_partial); integer::mapit loc1 = p.first, loc2 = p.second, end = tstamp_lookup.end(); if( (!possibly_equal || allow_equal || is_partial) && loc1!=end && loc2!=end){ hb_enc::tstamp_ptr l1 = get<1>(*loc1); hb_enc::tstamp_ptr l2 = get<1>(*loc2); se_ptr e1; if( event_lookup.find( l1->expr ) != event_lookup.end() ) e1 = event_lookup.at( l1->expr ); se_ptr e2; if( event_lookup.find( l2->expr ) != event_lookup.end() ) e2 = event_lookup.at( l2->expr ); if( is_partial ){ return shared_ptr<hb_enc::hb>(new hb_enc::hb( e1, l1, e2, l2, hb, possibly_equal,is_partial)); }else{ return shared_ptr<hb_enc::hb>(new hb_enc::hb(e1, l1, e2, l2, hb, possibly_equal)); } } else return shared_ptr<hb_enc::hb>(); }
pair<integer::mapit,integer::mapit> integer::get_locs( const z3::expr& hb, bool& possibly_equal, bool& is_partial ) const { // we need to flip that bool parameter in to know if we are sure about // this result or not (two tstamps can be assigned an equal integer) auto loc1 = tstamp_lookup.end(); auto loc2 = tstamp_lookup.end(); switch(hb.kind()) { case Z3_APP_AST: { z3::func_decl d = hb.decl(); Z3_decl_kind dk = d.decl_kind(); switch(dk) { case Z3_OP_LE: possibly_equal = true; // fallthrough case Z3_OP_LT: if (hb.arg(1).kind() == Z3_NUMERAL_AST) return get_locs(hb.arg(0), possibly_equal, is_partial); loc1 = tstamp_lookup.find(hb.arg(0)); loc2 = tstamp_lookup.find(hb.arg(1)); break; case Z3_OP_GE: possibly_equal = true; // fallthrough case Z3_OP_GT: if (hb.arg(1).kind() == Z3_NUMERAL_AST) { return swap_pair(get_locs(hb.arg(0), possibly_equal, is_partial)); } loc1 = tstamp_lookup.find(hb.arg(1)); loc2 = tstamp_lookup.find(hb.arg(0)); break; case Z3_OP_NOT: { auto neg_hb = get_locs(hb.arg(0), possibly_equal, is_partial); auto res = swap_pair( neg_hb ); possibly_equal = !possibly_equal; return res; break; } case Z3_OP_ADD: { loc1 = tstamp_lookup.find(hb.arg(0)); z3::expr t1 = hb.arg(1); if (t1.decl().decl_kind() == Z3_OP_MUL) { // todo: check the the other multiplicant is -1 loc2 = tstamp_lookup.find(t1.arg(1)); } break; } case Z3_OP_SPECIAL_RELATION_PO: { is_partial = true; loc1 = tstamp_lookup.find(hb.arg(0)); loc2 = tstamp_lookup.find(hb.arg(1)); break; } default: break; } break; } default: break; } return make_pair<integer::mapit,integer::mapit>(std::move(loc1),std::move(loc2)); }