bool compatible_sort(app * n) const { if (m.is_bool(n)) return true; if (m_int && m_arith_util.is_int(n)) return true; if (m_real && m_arith_util.is_real(n)) return true; if (m_array_util.is_array(n)) return true; return false; }
void operator()(app* n) { ast_manager& m = m_manager; unsigned num_args = n->get_num_args(); ptr_buffer<expr> args; for (unsigned i = 0; i < num_args; ++i) { args.push_back(find(n->get_arg(i))); } if (m_manager.is_eq(n) && m_util.is_array(args[0])) { visit_eq(n); return; } if (m_manager.is_distinct(n) && num_args > 0 && m_util.is_array(args[0])) { ptr_buffer<expr> eqs; for (unsigned i = 0; i < num_args; ++i) { for (unsigned j = i + 1; j < num_args; ++j) { eqs.push_back(m.mk_not(m.mk_eq(args[i], args[j]))); } } insert(n, m.mk_and(eqs.size(), eqs.c_ptr())); return; } if (m_util.is_select(n)) { SASSERT(num_args > 0); // select(store(A,i,v),j) -> ite(i = j, v, select(A,j)) if (m_util.is_store(args[0])) { app* a = to_app(args[0]); expr* b = find(a->get_arg(0)); expr* v = find(a->get_arg(a->get_num_args()-1)); ptr_buffer<expr> eqs; SASSERT(num_args + 1 == a->get_num_args()); for (unsigned i = 1; i < num_args; ++i) { eqs.push_back(m.mk_eq(args[i], find(a->get_arg(i)))); } expr* r = m.mk_ite(m.mk_and(eqs.size(), eqs.c_ptr()), v, mk_select(b, num_args-1, args.c_ptr()+1)); insert(n, r); return; } // select(ite(a,b,c),i) -> ite(a, select(b,i), select(c, i)) if (m.is_ite(args[0])) { app* k = to_app(args[0]); expr* a = k->get_arg(0); expr* b = mk_select(k->get_arg(1), args.size()-1, args.c_ptr()+1); expr* c = mk_select(k->get_arg(2), args.size()-1, args.c_ptr()+1); expr* r = m.mk_ite(a, b, c); insert(n, r); return; } // select(map_f(A,B),i) -> f(select(A,i), select(B,i)) if (m_util.is_map(args[0])) { app* a = to_app(args[0]); func_decl* f = a->get_decl(); SASSERT(f->get_num_parameters() == 1); SASSERT(f->get_parameter(0).is_ast()); SASSERT(is_func_decl(f->get_parameter(0).get_ast())); parameter p = f->get_parameter(0); func_decl* d = to_func_decl(p.get_ast()); ptr_buffer<expr> args2; for (unsigned i = 0; i < a->get_num_args(); ++i) { args2.push_back(mk_select(find(a->get_arg(i)), args.size()-1, args.c_ptr()+1)); } expr* r = m.mk_app(d, args2.size(), args2.c_ptr()); insert(n, r); return; } // select(const v, i) -> v if (m_util.is_const(args[0])) { insert(n, to_app(args[0])->get_arg(0)); return; } } expr* r = m_manager.mk_app(n->get_decl(), args.size(), args.c_ptr()); insert(n, r); }