/*++ Copyright (c) 2011 Microsoft Corporation Module Name: nnf_tactic.cpp Abstract: NNF tactic Author: Leonardo de Moura (leonardo) 2011-12-28. Revision History: --*/ #include"nnf.h" #include"tactical.h" class nnf_tactic : public tactic { params_ref m_params; nnf * m_nnf; struct set_nnf { nnf_tactic & m_owner; set_nnf(nnf_tactic & owner, nnf & n): m_owner(owner) { #pragma omp critical (nnf_tactic) { m_owner.m_nnf = &n; } } ~set_nnf() { #pragma omp critical (nnf_tactic) { m_owner.m_nnf = 0; } } }; public: nnf_tactic(params_ref const & p): m_params(p), m_nnf(0) { TRACE("nnf", tout << "nnf_tactic constructor: " << p << "\n";); } virtual tactic * translate(ast_manager & m) { return alloc(nnf_tactic, m_params); } virtual ~nnf_tactic() {} virtual void updt_params(params_ref const & p) { m_params = p; } virtual void collect_param_descrs(param_descrs & r) { nnf::get_param_descrs(r); } virtual void operator()(goal_ref const & g, goal_ref_buffer & result, model_converter_ref & mc, proof_converter_ref & pc, expr_dependency_ref & core) { TRACE("nnf", tout << "params: " << m_params << "\n"; g->display(tout);); SASSERT(g->is_well_sorted()); mc = 0; pc = 0; core = 0; tactic_report report("nnf", *g); bool produce_proofs = g->proofs_enabled(); ast_manager & m = g->m(); defined_names dnames(m); nnf local_nnf(m, dnames, m_params); set_nnf setter(*this, local_nnf); expr_ref_vector defs(m); proof_ref_vector def_prs(m); expr_ref new_curr(m); proof_ref new_pr(m); unsigned sz = g->size(); for (unsigned i = 0; i < sz; i++) { expr * curr = g->form(i); local_nnf(curr, defs, def_prs, new_curr, new_pr); if (produce_proofs) { proof * pr = g->pr(i); new_pr = m.mk_modus_ponens(pr, new_pr); } g->update(i, new_curr, new_pr, g->dep(i)); } sz = defs.size(); for (unsigned i = 0; i < sz; i++) { if (produce_proofs) g->assert_expr(defs.get(i), def_prs.get(i), 0); else g->assert_expr(defs.get(i), 0, 0); } g->inc_depth(); result.push_back(g.get()); TRACE("nnf", g->display(tout);); SASSERT(g->is_well_sorted()); } virtual void cleanup() {} virtual void set_cancel(bool f) { #pragma omp critical (nnf_tactic) { if (m_nnf) m_nnf->set_cancel(f); } } }; tactic * mk_snf_tactic(ast_manager & m, params_ref const & p) { return alloc(nnf_tactic, p); } tactic * mk_nnf_tactic(ast_manager & m, params_ref const & p) { params_ref new_p(p); new_p.set_sym(":nnf-mode", symbol("full")); TRACE("nnf", tout << "mk_nnf: " << new_p << "\n";); return using_params(mk_snf_tactic(m, p), new_p); }