mirror of
				https://github.com/Z3Prover/z3
				synced 2025-11-04 13:29:11 +00:00 
			
		
		
		
	enable unsat core extraction in nlsat_tactic
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
		
							parent
							
								
									84172302a2
								
							
						
					
					
						commit
						305e080239
					
				
					 9 changed files with 46 additions and 20 deletions
				
			
		| 
						 | 
					@ -1283,7 +1283,7 @@ namespace nlsat {
 | 
				
			||||||
            if (r == l_false) {
 | 
					            if (r == l_false) {
 | 
				
			||||||
                // collect used literals from m_lemma_assumptions
 | 
					                // collect used literals from m_lemma_assumptions
 | 
				
			||||||
                vector<assumption, false> deps;
 | 
					                vector<assumption, false> deps;
 | 
				
			||||||
                m_asm.linearize(m_lemma_assumptions.get(), deps);
 | 
					                get_core(deps);
 | 
				
			||||||
                for (unsigned i = 0; i < deps.size(); ++i) {
 | 
					                for (unsigned i = 0; i < deps.size(); ++i) {
 | 
				
			||||||
                    literal const* lp = (literal const*)(deps[i]);
 | 
					                    literal const* lp = (literal const*)(deps[i]);
 | 
				
			||||||
                    if (ptr <= lp && lp < ptr + sz) {
 | 
					                    if (ptr <= lp && lp < ptr + sz) {
 | 
				
			||||||
| 
						 | 
					@ -1299,6 +1299,10 @@ namespace nlsat {
 | 
				
			||||||
            return r;
 | 
					            return r;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        void get_core(vector<assumption, false>& deps) {
 | 
				
			||||||
 | 
					            m_asm.linearize(m_lemma_assumptions.get(), deps);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void collect(literal_vector const& assumptions, clause_vector& clauses) {
 | 
					        void collect(literal_vector const& assumptions, clause_vector& clauses) {
 | 
				
			||||||
            unsigned n = clauses.size();
 | 
					            unsigned n = clauses.size();
 | 
				
			||||||
            unsigned j  = 0;
 | 
					            unsigned j  = 0;
 | 
				
			||||||
| 
						 | 
					@ -2712,6 +2716,10 @@ namespace nlsat {
 | 
				
			||||||
        return m_imp->check(assumptions);
 | 
					        return m_imp->check(assumptions);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void solver::get_core(vector<assumption, false>& assumptions) {
 | 
				
			||||||
 | 
					        return m_imp->get_core(assumptions);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void solver::reset() {
 | 
					    void solver::reset() {
 | 
				
			||||||
        m_imp->reset();
 | 
					        m_imp->reset();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -195,6 +195,14 @@ namespace nlsat {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        lbool value(literal l) const;
 | 
					        lbool value(literal l) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // -----------------------
 | 
				
			||||||
 | 
					        //
 | 
				
			||||||
 | 
					        // Core
 | 
				
			||||||
 | 
					        //
 | 
				
			||||||
 | 
					        // -----------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        void get_core(vector<assumption, false>& deps);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // -----------------------
 | 
					        // -----------------------
 | 
				
			||||||
        //
 | 
					        //
 | 
				
			||||||
        // Misc
 | 
					        // Misc
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -147,6 +147,7 @@ class nlsat_tactic : public tactic {
 | 
				
			||||||
            TRACE("nlsat", g->display(tout););
 | 
					            TRACE("nlsat", g->display(tout););
 | 
				
			||||||
            expr2var  a2b(m);
 | 
					            expr2var  a2b(m);
 | 
				
			||||||
            expr2var  t2x(m);
 | 
					            expr2var  t2x(m);
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
            m_g2nl(*g, m_params, m_solver, a2b, t2x);
 | 
					            m_g2nl(*g, m_params, m_solver, a2b, t2x);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            m_display_var.m_var2expr.reset();
 | 
					            m_display_var.m_var2expr.reset();
 | 
				
			||||||
| 
						 | 
					@ -172,9 +173,19 @@ class nlsat_tactic : public tactic {
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else {
 | 
					            else {
 | 
				
			||||||
                // TODO: extract unsat core
 | 
					                expr_dependency* lcore = 0;
 | 
				
			||||||
                g->assert_expr(m.mk_false(), 0, 0);
 | 
					                if (g->unsat_core_enabled()) {
 | 
				
			||||||
 | 
					                    vector<nlsat::assumption, false> assumptions;
 | 
				
			||||||
 | 
					                    m_solver.get_core(assumptions);
 | 
				
			||||||
 | 
					                    for (unsigned i = 0; i < assumptions.size(); ++i) {
 | 
				
			||||||
 | 
					                        expr_dependency* d = static_cast<expr_dependency*>(assumptions[i]);
 | 
				
			||||||
 | 
					                        lcore = m.mk_join(lcore, d);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                g->assert_expr(m.mk_false(), 0, lcore);
 | 
				
			||||||
 | 
					                core = lcore;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
            g->inc_depth();
 | 
					            g->inc_depth();
 | 
				
			||||||
            result.push_back(g.get());
 | 
					            result.push_back(g.get());
 | 
				
			||||||
            TRACE("nlsat", g->display(tout););
 | 
					            TRACE("nlsat", g->display(tout););
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -73,14 +73,15 @@ class sat_tactic : public tactic {
 | 
				
			||||||
            if (r == l_false) {
 | 
					            if (r == l_false) {
 | 
				
			||||||
                expr_dependency * lcore = 0;
 | 
					                expr_dependency * lcore = 0;
 | 
				
			||||||
                if (produce_core) {
 | 
					                if (produce_core) {
 | 
				
			||||||
                    sat::literal_vector const& core = m_solver.get_core();
 | 
					                    sat::literal_vector const& ucore = m_solver.get_core();
 | 
				
			||||||
                    u_map<expr*> asm2dep;
 | 
					                    u_map<expr*> asm2dep;
 | 
				
			||||||
                    mk_asm2dep(dep2asm, asm2dep);
 | 
					                    mk_asm2dep(dep2asm, asm2dep);
 | 
				
			||||||
                    for (unsigned i = 0; i < core.size(); ++i) {
 | 
					                    for (unsigned i = 0; i < ucore.size(); ++i) {
 | 
				
			||||||
                        sat::literal lit = core[i];
 | 
					                        sat::literal lit = ucore[i];
 | 
				
			||||||
                        expr* dep = asm2dep.find(lit.index());
 | 
					                        expr* dep = asm2dep.find(lit.index());
 | 
				
			||||||
                        lcore = m.mk_join(lcore, m.mk_leaf(dep));                        
 | 
					                        lcore = m.mk_join(lcore, m.mk_leaf(dep));                        
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					                    core = lcore;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                g->assert_expr(m.mk_false(), 0, lcore);
 | 
					                g->assert_expr(m.mk_false(), 0, lcore);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -138,6 +138,7 @@ public:
 | 
				
			||||||
                            proof_converter_ref & pc,
 | 
					                            proof_converter_ref & pc,
 | 
				
			||||||
                            expr_dependency_ref & core) {
 | 
					                            expr_dependency_ref & core) {
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
 | 
					            mc = 0; pc = 0; core = 0;
 | 
				
			||||||
            SASSERT(in->is_well_sorted());
 | 
					            SASSERT(in->is_well_sorted());
 | 
				
			||||||
            ast_manager & m = in->m();
 | 
					            ast_manager & m = in->m();
 | 
				
			||||||
            TRACE("smt_tactic", tout << this << "\nAUTO_CONFIG: " << fparams().m_auto_config << " HIDIV0: " << fparams().m_hi_div0 << " "
 | 
					            TRACE("smt_tactic", tout << this << "\nAUTO_CONFIG: " << fparams().m_auto_config << " HIDIV0: " << fparams().m_hi_div0 << " "
 | 
				
			||||||
| 
						 | 
					@ -206,8 +207,6 @@ public:
 | 
				
			||||||
                    mc = model2model_converter(md.get());
 | 
					                    mc = model2model_converter(md.get());
 | 
				
			||||||
                    mc = concat(fmc.get(), mc.get());
 | 
					                    mc = concat(fmc.get(), mc.get());
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                pc = 0;
 | 
					 | 
				
			||||||
                core = 0;
 | 
					 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            case l_false: {
 | 
					            case l_false: {
 | 
				
			||||||
| 
						 | 
					@ -229,12 +228,10 @@ public:
 | 
				
			||||||
                        expr * d = bool2dep.find(b);
 | 
					                        expr * d = bool2dep.find(b);
 | 
				
			||||||
                        lcore = m.mk_join(lcore, m.mk_leaf(d));
 | 
					                        lcore = m.mk_join(lcore, m.mk_leaf(d));
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					                    core = lcore;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                in->assert_expr(m.mk_false(), pr, lcore);
 | 
					                in->assert_expr(m.mk_false(), pr, lcore);
 | 
				
			||||||
                result.push_back(in.get());
 | 
					                result.push_back(in.get());
 | 
				
			||||||
                mc   = 0;
 | 
					 | 
				
			||||||
                pc   = 0;
 | 
					 | 
				
			||||||
                core = 0;
 | 
					 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            case l_undef:
 | 
					            case l_undef:
 | 
				
			||||||
| 
						 | 
					@ -257,8 +254,6 @@ public:
 | 
				
			||||||
                            m_ctx->get_model(md);
 | 
					                            m_ctx->get_model(md);
 | 
				
			||||||
                            mc = model2model_converter(md.get());
 | 
					                            mc = model2model_converter(md.get());
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        pc   = 0;
 | 
					 | 
				
			||||||
                        core = 0;
 | 
					 | 
				
			||||||
                        return;
 | 
					                        return;
 | 
				
			||||||
                    default:
 | 
					                    default:
 | 
				
			||||||
                        break;
 | 
					                        break;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -105,6 +105,7 @@ public:
 | 
				
			||||||
                            /* out */ model_converter_ref & mc, 
 | 
					                            /* out */ model_converter_ref & mc, 
 | 
				
			||||||
                            /* out */ proof_converter_ref & pc,
 | 
					                            /* out */ proof_converter_ref & pc,
 | 
				
			||||||
                            /* out */ expr_dependency_ref & core) {
 | 
					                            /* out */ expr_dependency_ref & core) {
 | 
				
			||||||
 | 
					        pc = 0; mc = 0; core = 0;
 | 
				
			||||||
        expr_ref_vector clauses(m);
 | 
					        expr_ref_vector clauses(m);
 | 
				
			||||||
        expr2expr_map               bool2dep;
 | 
					        expr2expr_map               bool2dep;
 | 
				
			||||||
        ptr_vector<expr>            assumptions;
 | 
					        ptr_vector<expr>            assumptions;
 | 
				
			||||||
| 
						 | 
					@ -123,8 +124,6 @@ public:
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            in->reset();
 | 
					            in->reset();
 | 
				
			||||||
            result.push_back(in.get());
 | 
					            result.push_back(in.get());
 | 
				
			||||||
            pc = 0;
 | 
					 | 
				
			||||||
            core = 0;
 | 
					 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        case l_false: {
 | 
					        case l_false: {
 | 
				
			||||||
            in->reset();
 | 
					            in->reset();
 | 
				
			||||||
| 
						 | 
					@ -132,6 +131,7 @@ public:
 | 
				
			||||||
            expr_dependency* lcore = 0;
 | 
					            expr_dependency* lcore = 0;
 | 
				
			||||||
            if (in->proofs_enabled()) {
 | 
					            if (in->proofs_enabled()) {
 | 
				
			||||||
                pr = local_solver->get_proof();
 | 
					                pr = local_solver->get_proof();
 | 
				
			||||||
 | 
					                pc = proof2proof_converter(m, pr);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            if (in->unsat_core_enabled()) {
 | 
					            if (in->unsat_core_enabled()) {
 | 
				
			||||||
                ptr_vector<expr> core;
 | 
					                ptr_vector<expr> core;
 | 
				
			||||||
| 
						 | 
					@ -142,9 +142,7 @@ public:
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            in->assert_expr(m.mk_false(), pr, lcore);
 | 
					            in->assert_expr(m.mk_false(), pr, lcore);
 | 
				
			||||||
            result.push_back(in.get());
 | 
					            result.push_back(in.get());
 | 
				
			||||||
            mc = 0;
 | 
					            core = lcore;
 | 
				
			||||||
            pc = 0;
 | 
					 | 
				
			||||||
            core = 0;
 | 
					 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        case l_undef:
 | 
					        case l_undef:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -137,7 +137,9 @@ lbool tactic2solver::check_sat_core(unsigned num_assumptions, expr * const * ass
 | 
				
			||||||
        g->assert_expr(m_assertions.get(i));
 | 
					        g->assert_expr(m_assertions.get(i));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    for (unsigned i = 0; i < num_assumptions; i++) {
 | 
					    for (unsigned i = 0; i < num_assumptions; i++) {
 | 
				
			||||||
        g->assert_expr(assumptions[i], m.mk_asserted(assumptions[i]), m.mk_leaf(assumptions[i]));
 | 
					        proof_ref pr(m.mk_asserted(assumptions[i]), m);
 | 
				
			||||||
 | 
					        expr_dependency_ref ans(m.mk_leaf(assumptions[i]), m);    
 | 
				
			||||||
 | 
					        g->assert_expr(assumptions[i], pr, ans);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    model_ref           md;
 | 
					    model_ref           md;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -237,6 +237,9 @@ void goal::slow_process(expr * f, proof * pr, expr_dependency * d) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void goal::assert_expr(expr * f, proof * pr, expr_dependency * d) {
 | 
					void goal::assert_expr(expr * f, proof * pr, expr_dependency * d) {
 | 
				
			||||||
 | 
					    expr_ref _f(f, m());
 | 
				
			||||||
 | 
					    proof_ref _pr(pr, m());
 | 
				
			||||||
 | 
					    expr_dependency_ref _d(d, m());
 | 
				
			||||||
    SASSERT(proofs_enabled() == (pr != 0 && !m().is_undef_proof(pr)));
 | 
					    SASSERT(proofs_enabled() == (pr != 0 && !m().is_undef_proof(pr)));
 | 
				
			||||||
    if (m_inconsistent)
 | 
					    if (m_inconsistent)
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -200,7 +200,7 @@ static void test_sorting_eq(unsigned n, unsigned k) {
 | 
				
			||||||
    // equality:
 | 
					    // equality:
 | 
				
			||||||
    std::cout << "eq " << k << "\n";
 | 
					    std::cout << "eq " << k << "\n";
 | 
				
			||||||
    solver.push();
 | 
					    solver.push();
 | 
				
			||||||
    result = sn.eq(k, in.size(), in.c_ptr());
 | 
					    result = sn.eq(true, k, in.size(), in.c_ptr());
 | 
				
			||||||
    solver.assert_expr(result);
 | 
					    solver.assert_expr(result);
 | 
				
			||||||
    for (unsigned i = 0; i < ext.m_clauses.size(); ++i) {
 | 
					    for (unsigned i = 0; i < ext.m_clauses.size(); ++i) {
 | 
				
			||||||
        solver.assert_expr(ext.m_clauses[i].get());
 | 
					        solver.assert_expr(ext.m_clauses[i].get());
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue