#include "ast/for_each_expr.h"
#include "muz/spacer/spacer_context.h"
#include "muz/spacer/spacer_util.h"
namespace spacer {
bool is_mono_var_lit(expr *lit, ast_manager &m) {
expr *e;
bv_util bv(m);
arith_util a_util(m);
if (m.is_not(lit, e)) return is_mono_var_lit(e, m);
if (a_util.is_arith_expr(lit) || bv.is_bv_ule(lit) ||
bv.is_bv_sle(lit)) {
return get_num_vars(lit) == 1 && !has_nonlinear_var_mul(lit, m);
}
return false;
}
bool find_unique_mono_var_lit(const expr_ref &pattern, expr_ref &res) {
if (get_num_vars(pattern) != 1) return false;
ast_manager &m = res.m();
expr_ref_vector conj(m);
conj.push_back(pattern);
flatten_and(conj);
unsigned count = 0;
for (auto *lit : conj) {
if (is_mono_var_lit(lit, m)) {
if (count) return false;
res = lit;
count++;
}
}
SASSERT(count <= 1);
return count == 1;
}
bool filter_out_lit(const expr_ref_vector &vec, const expr_ref &lit, expr_ref_vector &out) {
ast_manager &m = vec.get_manager();
bool dirty = false, pos = false;
sem_matcher matcher(m);
substitution sub(m);
out.reset();
unsigned lit_num_vars = get_num_vars(lit.get());
SASSERT(!(m.is_not(lit) && m.is_eq(to_app(lit)->get_arg(0))));
for (auto &c : vec) {
sub.reset();
sub.reserve(1, lit_num_vars);
matcher.reset();
if (matcher(lit, c, sub, pos) && pos) {
if (is_numeric_sub(sub)) {
dirty = true;
continue;
}
}
out.push_back(c);
}
CTRACE(global, dirty,
tout << "Filtered " << lit << " from " << vec << "\n got " << out << "\n";);
return dirty;
}
}