void elim_bounds::operator()(quantifier * q, expr_ref & r) { if (!q->is_forall()) { r = q; return; } expr * n = q->get_expr(); ptr_buffer<expr> atoms; if (m_manager.is_or(n)) atoms.append(to_app(n)->get_num_args(), to_app(n)->get_args()); else atoms.push_back(n); used_vars m_used_vars; // collect non-candidates unsigned sz = atoms.size(); for (unsigned i = 0; i < sz; i++) { expr * a = atoms[i]; if (!is_bound(a)) m_used_vars.process(a); } if (m_used_vars.uses_all_vars(q->get_num_decls())) { r = q; return; } // collect candidates obj_hashtable<var> m_lowers; obj_hashtable<var> m_uppers; obj_hashtable<var> m_candidate_set; ptr_buffer<var> m_candidates; #define ADD_CANDIDATE(V) if (!m_lowers.contains(V) && !m_uppers.contains(V)) { m_candidate_set.insert(V); m_candidates.push_back(V); } for (unsigned i = 0; i < sz; i++) { expr * a = atoms[i]; var * lower = 0; var * upper = 0; if (is_bound(a, lower, upper)) { if (lower != 0 && !m_used_vars.contains(lower->get_idx())) { ADD_CANDIDATE(lower); m_lowers.insert(lower); } if (upper != 0 && !m_used_vars.contains(upper->get_idx())) { ADD_CANDIDATE(upper); m_uppers.insert(upper); } } } TRACE("elim_bounds", tout << "candidates:\n"; for (unsigned i = 0; i < m_candidates.size(); i++) tout << mk_pp(m_candidates[i], m_manager) << "\n";);
bool elim_bounds_cfg::reduce_quantifier(quantifier * q, expr * n, expr * const * new_patterns, expr * const * new_no_patterns, expr_ref & result, proof_ref & result_pr) { if (!is_forall(q)) { return false; } unsigned num_vars = q->get_num_decls(); ptr_buffer<expr> atoms; if (m.is_or(n)) atoms.append(to_app(n)->get_num_args(), to_app(n)->get_args()); else atoms.push_back(n); used_vars used_vars; // collect non-candidates for (expr * a : atoms) { if (!is_bound(a)) used_vars.process(a); } if (used_vars.uses_all_vars(q->get_num_decls())) { return false; } // collect candidates obj_hashtable<var> lowers; obj_hashtable<var> uppers; obj_hashtable<var> candidate_set; ptr_buffer<var> candidates; #define ADD_CANDIDATE(V) if (!lowers.contains(V) && !uppers.contains(V)) { candidate_set.insert(V); candidates.push_back(V); } for (expr * a : atoms) { var * lower = nullptr; var * upper = nullptr; if (is_bound(a, lower, upper)) { if (lower != nullptr && !used_vars.contains(lower->get_idx()) && lower->get_idx() < num_vars) { ADD_CANDIDATE(lower); lowers.insert(lower); } if (upper != nullptr && !used_vars.contains(upper->get_idx()) && upper->get_idx() < num_vars) { ADD_CANDIDATE(upper); uppers.insert(upper); } } } TRACE("elim_bounds", tout << "candidates:\n"; for (unsigned i = 0; i < candidates.size(); i++) tout << mk_pp(candidates[i], m) << "\n";);