/*++ Copyright (c) 2011 Microsoft Corporation Module Name: qe_tactic.cpp Abstract: Quantifier elimination front-end for tactic framework. Author: Leonardo de Moura (leonardo) 2011-12-28. Revision History: --*/ #include"tactical.h" #include"filter_model_converter.h" #include"cooperate.h" #include"qe.h" class qe_tactic : public tactic { struct imp { ast_manager & m; front_end_params m_fparams; volatile bool m_cancel; qe::expr_quant_elim m_qe; imp(ast_manager & _m, params_ref const & p): m(_m), m_qe(m, m_fparams) { updt_params(p); m_cancel = false; } void updt_params(params_ref const & p) { m_fparams.m_nlquant_elim = p.get_bool(":qe-nonlinear", false); m_qe.updt_params(p); } void collect_param_descrs(param_descrs & r) { m_qe.collect_param_descrs(r); } void set_cancel(bool f) { m_cancel = f; m_qe.set_cancel(f); } void checkpoint() { if (m_cancel) throw tactic_exception(TACTIC_CANCELED_MSG); cooperate("qe"); } void operator()(goal_ref const & g, goal_ref_buffer & result, model_converter_ref & mc, proof_converter_ref & pc, expr_dependency_ref & core) { SASSERT(g->is_well_sorted()); mc = 0; pc = 0; core = 0; tactic_report report("qe", *g); m_fparams.m_model = g->models_enabled(); proof_ref new_pr(m); expr_ref new_f(m); bool produce_proofs = g->proofs_enabled(); unsigned sz = g->size(); for (unsigned i = 0; i < sz; i++) { checkpoint(); if (g->inconsistent()) break; expr * f = g->form(i); if (!has_quantifiers(f)) continue; m_qe(m.mk_true(), f, new_f); new_pr = 0; if (produce_proofs) { new_pr = m.mk_modus_ponens(g->pr(i), new_pr); } g->update(i, new_f, new_pr, g->dep(i)); } g->inc_depth(); result.push_back(g.get()); TRACE("qe", g->display(tout);); SASSERT(g->is_well_sorted()); } }; imp * m_imp; params_ref m_params; public: qe_tactic(ast_manager & m, params_ref const & p): m_params(p) { m_imp = alloc(imp, m, p); } virtual tactic * translate(ast_manager & m) { return alloc(qe_tactic, m, m_params); } virtual ~qe_tactic() { dealloc(m_imp); } virtual void updt_params(params_ref const & p) { m_params = p; m_imp->updt_params(p); } virtual void collect_param_descrs(param_descrs & r) { r.insert(":qe-nonlinear", CPK_BOOL, "(default: false) enable virtual term substitution."); m_imp->collect_param_descrs(r); } virtual void operator()(goal_ref const & in, goal_ref_buffer & result, model_converter_ref & mc, proof_converter_ref & pc, expr_dependency_ref & core) { (*m_imp)(in, result, mc, pc, core); } virtual void cleanup() { ast_manager & m = m_imp->m; imp * d = m_imp; #pragma omp critical (tactic_cancel) { m_imp = 0; } dealloc(d); d = alloc(imp, m, m_params); #pragma omp critical (tactic_cancel) { m_imp = d; } } protected: virtual void set_cancel(bool f) { if (m_imp) m_imp->set_cancel(f); } }; tactic * mk_qe_tactic(ast_manager & m, params_ref const & p) { return clean(alloc(qe_tactic, m, p)); }