virtual void operator()(goal_ref const & in, goal_ref_buffer & result, model_converter_ref & mc, proof_converter_ref & pc, expr_dependency_ref & core) { bool models_enabled = in->models_enabled(); bool proofs_enabled = in->proofs_enabled(); bool cores_enabled = in->unsat_core_enabled(); ast_manager & m = in->m(); goal_ref_buffer r1; model_converter_ref mc1; proof_converter_ref pc1; expr_dependency_ref core1(m); result.reset(); mc = 0; pc = 0; core = 0; m_t1->operator()(in, r1, mc1, pc1, core1); SASSERT(!is_decided(r1) || (!pc1 && !core1)); // the pc and core of decided goals is 0 unsigned r1_size = r1.size(); SASSERT(r1_size > 0); checkpoint(); if (r1_size == 1) { if (r1[0]->is_decided()) { result.push_back(r1[0]); if (models_enabled) mc = mc1; SASSERT(!pc); SASSERT(!core); return; } goal_ref r1_0 = r1[0]; m_t2->operator()(r1_0, result, mc, pc, core); if (models_enabled) mc = concat(mc1.get(), mc.get()); if (proofs_enabled) pc = concat(pc1.get(), pc.get()); if (cores_enabled) core = m.mk_join(core1.get(), core); } else { if (cores_enabled) core = core1; proof_converter_ref_buffer pc_buffer; model_converter_ref_buffer mc_buffer; sbuffer<unsigned> sz_buffer; goal_ref_buffer r2; for (unsigned i = 0; i < r1_size; i++) { checkpoint(); goal_ref g = r1[i]; r2.reset(); model_converter_ref mc2; proof_converter_ref pc2; expr_dependency_ref core2(m); m_t2->operator()(g, r2, mc2, pc2, core2); if (is_decided(r2)) { SASSERT(r2.size() == 1); if (is_decided_sat(r2)) { // found solution... result.push_back(r2[0]); if (models_enabled) { // mc2 contains the actual model model_ref md; md = alloc(model, m); apply(mc2, md, 0); apply(mc1, md, i); mc = model2model_converter(md.get()); } SASSERT(!pc); SASSERT(!core); return; } else { SASSERT(is_decided_unsat(r2)); // the proof and unsat core of a decided_unsat goal are stored in the node itself. // pc2 and core2 must be 0. SASSERT(!pc2); SASSERT(!core2); if (models_enabled) mc_buffer.push_back(0); if (proofs_enabled) pc_buffer.push_back(proof2proof_converter(m, r2[0]->pr(0))); if (models_enabled || proofs_enabled) sz_buffer.push_back(0); if (cores_enabled) core = m.mk_join(core.get(), r2[0]->dep(0)); } } else { result.append(r2.size(), r2.c_ptr()); if (models_enabled) mc_buffer.push_back(mc2.get()); if (proofs_enabled) pc_buffer.push_back(pc2.get()); if (models_enabled || proofs_enabled) sz_buffer.push_back(r2.size()); if (cores_enabled) core = m.mk_join(core.get(), core2.get()); } } if (result.empty()) { // all subgoals were shown to be unsat. // create an decided_unsat goal with the proof in->reset_all(); proof_ref pr(m); if (proofs_enabled) apply(m, pc1, pc_buffer, pr); SASSERT(cores_enabled || core == 0); in->assert_expr(m.mk_false(), pr, core); core = 0; result.push_back(in.get()); SASSERT(!mc); SASSERT(!pc); SASSERT(!core); } else { if (models_enabled) mc = concat(mc1.get(), mc_buffer.size(), mc_buffer.c_ptr(), sz_buffer.c_ptr()); if (proofs_enabled) pc = concat(pc1.get(), pc_buffer.size(), pc_buffer.c_ptr(), sz_buffer.c_ptr()); SASSERT(cores_enabled || core == 0); } } }
bool goal::is_decided() const { return is_decided_sat() || is_decided_unsat(); }