mirror of
				https://github.com/Z3Prover/z3
				synced 2025-10-31 11:42:28 +00:00 
			
		
		
		
	mbqi
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
		
							parent
							
								
									34e0e26e3d
								
							
						
					
					
						commit
						1ee2ba2a9b
					
				
					 17 changed files with 132 additions and 80 deletions
				
			
		|  | @ -590,32 +590,29 @@ public: | ||||||
|             return out; |             return out; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         out << "[" << j << "]\t"; |         out << "[" << j << "] " << std::setw(6) << " := " << m_x[j]; | ||||||
|              |         if (m_basis_heading[j] >= 0) | ||||||
|  |             out << " base\t"; | ||||||
|  |         else  | ||||||
|  |             out << "     \t"; | ||||||
|         switch (m_column_types[j]) { |         switch (m_column_types[j]) { | ||||||
|         case column_type::fixed: |         case column_type::fixed: | ||||||
|         case column_type::boxed: |         case column_type::boxed: | ||||||
|             out << " [" << m_lower_bounds[j] << ", " << m_upper_bounds[j] << "]"; |             out << "[" << m_lower_bounds[j] << ", " << m_upper_bounds[j] << "]"; | ||||||
|             break; |             break; | ||||||
|         case column_type::lower_bound: |         case column_type::lower_bound: | ||||||
|             out << " [" << m_lower_bounds[j] << "," << "oo" << "]"; |             out << "[" << m_lower_bounds[j] << ", oo" << "]"; | ||||||
|             break; |             break; | ||||||
|         case column_type::upper_bound: |         case column_type::upper_bound: | ||||||
|             out << " [-oo, " << m_upper_bounds[j] << ']'; |             out << "[-oo, " << m_upper_bounds[j] << ']'; | ||||||
|             break; |             break; | ||||||
|         case column_type::free_column: |         case column_type::free_column: | ||||||
|             out << " [-oo, oo]"; |             out << "[-oo, oo]"; | ||||||
|             break; |             break; | ||||||
|         default: |         default: | ||||||
|             lp_assert(false); |             lp_assert(false); | ||||||
|         } |         } | ||||||
|         //        out << "basis heading = " << m_basis_heading[j] << std::endl;
 |         return out << "\n"; | ||||||
|         out << "\tx = " << m_x[j]; |  | ||||||
|         if (m_basis_heading[j] >= 0) |  | ||||||
|             out << " base\n"; |  | ||||||
|         else |  | ||||||
|            out << " \n"; |  | ||||||
|         return out; |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     bool column_is_free(unsigned j) const { return this->m_column_types[j] == column_type::free_column; } |     bool column_is_free(unsigned j) const { return this->m_column_types[j] == column_type::free_column; } | ||||||
|  |  | ||||||
|  | @ -215,6 +215,13 @@ void func_interp::insert_new_entry(expr * const * args, expr * r) { | ||||||
|     m_entries.push_back(new_entry); |     m_entries.push_back(new_entry); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void func_interp::del_entry(unsigned idx) { | ||||||
|  |     auto* e = m_entries[idx]; | ||||||
|  |     m_entries[idx] = m_entries.back(); | ||||||
|  |     m_entries.pop_back(); | ||||||
|  |     e->deallocate(m(), m_arity); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| bool func_interp::eval_else(expr * const * args, expr_ref & result) const { | bool func_interp::eval_else(expr * const * args, expr_ref & result) const { | ||||||
|     if (m_else == nullptr) |     if (m_else == nullptr) | ||||||
|         return false; |         return false; | ||||||
|  |  | ||||||
|  | @ -109,6 +109,7 @@ public: | ||||||
|     ptr_vector<func_entry>::const_iterator end() const { return m_entries.end(); } |     ptr_vector<func_entry>::const_iterator end() const { return m_entries.end(); } | ||||||
|     func_entry const * const * get_entries() const { return m_entries.c_ptr(); } |     func_entry const * const * get_entries() const { return m_entries.c_ptr(); } | ||||||
|     func_entry const * get_entry(unsigned idx) const { return m_entries[idx]; } |     func_entry const * get_entry(unsigned idx) const { return m_entries[idx]; } | ||||||
|  |     void del_entry(unsigned idx); | ||||||
| 
 | 
 | ||||||
|     expr * get_max_occ_result() const; |     expr * get_max_occ_result() const; | ||||||
|     void compress(); |     void compress(); | ||||||
|  |  | ||||||
|  | @ -37,7 +37,14 @@ namespace mbp { | ||||||
| 
 | 
 | ||||||
|         ast_manager&      m; |         ast_manager&      m; | ||||||
|         arith_util        a; |         arith_util        a; | ||||||
|         bool              m_check_purified;  // check that variables are properly pure 
 |         bool              m_check_purified { true };  // check that variables are properly pure 
 | ||||||
|  |         bool              m_apply_projection { false }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         imp(ast_manager& m) : | ||||||
|  |             m(m), a(m) {} | ||||||
|  | 
 | ||||||
|  |         ~imp() {} | ||||||
| 
 | 
 | ||||||
|         void insert_mul(expr* x, rational const& v, obj_map<expr, rational>& ts) { |         void insert_mul(expr* x, rational const& v, obj_map<expr, rational>& ts) { | ||||||
|             // TRACE("qe", tout << "Adding variable " << mk_pp(x, m) << " " << v << "\n";);
 |             // TRACE("qe", tout << "Adding variable " << mk_pp(x, m) << " " << v << "\n";);
 | ||||||
|  | @ -238,11 +245,6 @@ namespace mbp { | ||||||
|             return rational(b.is_pos()?-1:1); |             return rational(b.is_pos()?-1:1); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         imp(ast_manager& m):  |  | ||||||
|             m(m), a(m), m_check_purified(true) {} |  | ||||||
| 
 |  | ||||||
|         ~imp() {} |  | ||||||
| 
 |  | ||||||
|         bool operator()(model& model, app* v, app_ref_vector& vars, expr_ref_vector& lits) { |         bool operator()(model& model, app* v, app_ref_vector& vars, expr_ref_vector& lits) { | ||||||
|             app_ref_vector vs(m); |             app_ref_vector vs(m); | ||||||
|             vs.push_back(v); |             vs.push_back(v); | ||||||
|  | @ -271,6 +273,7 @@ namespace mbp { | ||||||
|             model_evaluator eval(model); |             model_evaluator eval(model); | ||||||
|             TRACE("qe", tout << model;); |             TRACE("qe", tout << model;); | ||||||
|             eval.set_model_completion(true); |             eval.set_model_completion(true); | ||||||
|  |             compute_def |= m_apply_projection; | ||||||
| 
 | 
 | ||||||
|             opt::model_based_opt mbo; |             opt::model_based_opt mbo; | ||||||
|             obj_map<expr, unsigned> tids; |             obj_map<expr, unsigned> tids; | ||||||
|  | @ -341,15 +344,19 @@ namespace mbp { | ||||||
|                   for (unsigned v : real_vars) tout << "v" << v << " " << mk_pp(index2expr[v], m) << "\n"; |                   for (unsigned v : real_vars) tout << "v" << v << " " << mk_pp(index2expr[v], m) << "\n"; | ||||||
|                   mbo.display(tout);); |                   mbo.display(tout);); | ||||||
|             vector<opt::model_based_opt::def> defs = mbo.project(real_vars.size(), real_vars.c_ptr(), compute_def); |             vector<opt::model_based_opt::def> defs = mbo.project(real_vars.size(), real_vars.c_ptr(), compute_def); | ||||||
|             TRACE("qe", mbo.display(tout << "mbo result\n"); | 
 | ||||||
|                   for (auto const& d : defs) tout << "def: " << d << "\n";); |  | ||||||
|             vector<row> rows; |             vector<row> rows; | ||||||
|             mbo.get_live_rows(rows); |             mbo.get_live_rows(rows); | ||||||
|             rows2fmls(rows, index2expr, fmls); |             rows2fmls(rows, index2expr, fmls); | ||||||
|  |             TRACE("qe", mbo.display(tout << "mbo result\n"); | ||||||
|  |                   for (auto const& d : defs) tout << "def: " << d << "\n"; | ||||||
|  |                   tout << fmls << "\n";); | ||||||
|              |              | ||||||
|             vector<def> result; |             vector<def> result; | ||||||
|             if (compute_def)  |             if (compute_def)  | ||||||
|                 optdefs2mbpdef(defs, index2expr, real_vars, result);             |                 optdefs2mbpdef(defs, index2expr, real_vars, result);      | ||||||
|  |             if (m_apply_projection) | ||||||
|  |                 apply_projection(result, fmls); | ||||||
|             return result; |             return result; | ||||||
|         }         |         }         | ||||||
| 
 | 
 | ||||||
|  | @ -523,6 +530,20 @@ namespace mbp { | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         void apply_projection(vector<def>& defs, expr_ref_vector& fmls) { | ||||||
|  |             if (fmls.empty() || defs.empty()) | ||||||
|  |                 return; | ||||||
|  |             expr_safe_replace subst(m); | ||||||
|  |             for (auto const& d : defs)  | ||||||
|  |                 subst.insert(d.var, d.term);             | ||||||
|  |             unsigned j = 0; | ||||||
|  |             expr_ref tmp(m); | ||||||
|  |             for (expr* fml : fmls) { | ||||||
|  |                 subst(fml, tmp); | ||||||
|  |                 fmls[j++] = tmp; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     arith_project_plugin::arith_project_plugin(ast_manager& m):project_plugin(m) { |     arith_project_plugin::arith_project_plugin(ast_manager& m):project_plugin(m) { | ||||||
|  | @ -549,6 +570,10 @@ namespace mbp { | ||||||
|         m_imp->m_check_purified = check_purified; |         m_imp->m_check_purified = check_purified; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     void arith_project_plugin::set_apply_projection(bool f) { | ||||||
|  |         m_imp->m_apply_projection = f; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     family_id arith_project_plugin::get_family_id() { |     family_id arith_project_plugin::get_family_id() { | ||||||
|         return m_imp->a.get_family_id(); |         return m_imp->a.get_family_id(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -41,6 +41,11 @@ namespace mbp { | ||||||
|          */ |          */ | ||||||
|         void set_check_purified(bool check_purified); |         void set_check_purified(bool check_purified); | ||||||
| 
 | 
 | ||||||
|  |         /**
 | ||||||
|  |         * \brief apply projection  | ||||||
|  |         */ | ||||||
|  |         void set_apply_projection(bool apply_project); | ||||||
|  | 
 | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     bool arith_project(model& model, app* var, expr_ref_vector& lits); |     bool arith_project(model& model, app* var, expr_ref_vector& lits); | ||||||
|  |  | ||||||
|  | @ -327,10 +327,10 @@ namespace mbp { | ||||||
| 
 | 
 | ||||||
|     void project_plugin::purify(euf_inverter& inv, model& mdl, app_ref_vector const& vars, expr_ref_vector& lits) { |     void project_plugin::purify(euf_inverter& inv, model& mdl, app_ref_vector const& vars, expr_ref_vector& lits) { | ||||||
|         TRACE("mbp", tout << lits << "\n" << mdl << "\n";); |         TRACE("mbp", tout << lits << "\n" << mdl << "\n";); | ||||||
|  |         model_evaluator eval(mdl); | ||||||
|         extract_literals(mdl, vars, lits); |         extract_literals(mdl, vars, lits); | ||||||
|         if (!m.inc()) |         if (!m.inc()) | ||||||
|             return; |             return; | ||||||
|         model_evaluator eval(mdl); |  | ||||||
|         eval.set_expand_array_equalities(true); |         eval.set_expand_array_equalities(true); | ||||||
|         m_non_ground.reset(); |         m_non_ground.reset(); | ||||||
|         m_to_visit.reset(); |         m_to_visit.reset(); | ||||||
|  | @ -341,7 +341,6 @@ namespace mbp { | ||||||
|             m_non_ground.mark(v); |             m_non_ground.mark(v); | ||||||
|         for (unsigned i = 0; m.inc() && i < lits.size(); ++i)  |         for (unsigned i = 0; m.inc() && i < lits.size(); ++i)  | ||||||
|             lits[i] = purify(inv, eval, lits.get(i), lits);  |             lits[i] = purify(inv, eval, lits.get(i), lits);  | ||||||
|         std::cout << m_pure_eqs << "\n"; |  | ||||||
|         lits.append(m_pure_eqs); |         lits.append(m_pure_eqs); | ||||||
|         TRACE("mbp", tout << lits << "\n";); |         TRACE("mbp", tout << lits << "\n";); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -296,21 +296,19 @@ namespace arith { | ||||||
|         return lp::EQ; |         return lp::EQ; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     void solver::mk_eq_axiom(theory_var v1, theory_var v2) { |     void solver::mk_eq_axiom(bool is_eq, theory_var v1, theory_var v2) { | ||||||
|         if (is_bool(v1)) |         if (is_bool(v1)) | ||||||
|             return; |             return; | ||||||
|         expr* e1 = var2expr(v1); |         expr* e1 = var2expr(v1); | ||||||
|         expr* e2 = var2expr(v2); |         expr* e2 = var2expr(v2); | ||||||
|         if (e1 == e2) |         if (is_eq && m.are_equal(e1, e2)) | ||||||
|             return; |             return; | ||||||
|  |         if (!is_eq && m.are_distinct(e1, e2)) | ||||||
|  |             return;        | ||||||
|         literal le, ge; |         literal le, ge; | ||||||
|         if (a.is_numeral(e1)) |         if (a.is_numeral(e1)) | ||||||
|             std::swap(e1, e2); |             std::swap(e1, e2); | ||||||
|         if (a.is_numeral(e1)) { |         SASSERT(!a.is_numeral(e1)); | ||||||
|             add_unit(~mk_literal(m.mk_eq(e1, e2))); |  | ||||||
|             std::cout << "two numerals\n"; |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|         literal eq = eq_internalize(e1, e2); |         literal eq = eq_internalize(e1, e2); | ||||||
|         if (a.is_numeral(e2)) { |         if (a.is_numeral(e2)) { | ||||||
|             le = mk_literal(a.mk_le(e1, e2)); |             le = mk_literal(a.mk_le(e1, e2)); | ||||||
|  | @ -321,8 +319,11 @@ namespace arith { | ||||||
|             expr_ref zero(a.mk_numeral(rational(0), a.is_int(e1)), m); |             expr_ref zero(a.mk_numeral(rational(0), a.is_int(e1)), m); | ||||||
|             rewrite(diff); |             rewrite(diff); | ||||||
|             if (a.is_numeral(diff)) { |             if (a.is_numeral(diff)) { | ||||||
|                 std::cout << "diff " << diff << " " << mk_pp(e1, m) << " " << mk_pp(e2, m) << "\n"; |                 if (is_eq && a.is_zero(diff)) | ||||||
|                 if (zero == diff) |                     return; | ||||||
|  |                 if (!is_eq && !a.is_zero(diff)) | ||||||
|  |                     return; | ||||||
|  |                 if (a.is_zero(diff)) | ||||||
|                     add_unit(eq); |                     add_unit(eq); | ||||||
|                 else  |                 else  | ||||||
|                     add_unit(~eq); |                     add_unit(~eq); | ||||||
|  | @ -331,8 +332,8 @@ namespace arith { | ||||||
|             le = mk_literal(a.mk_le(diff, zero)); |             le = mk_literal(a.mk_le(diff, zero)); | ||||||
|             ge = mk_literal(a.mk_ge(diff, zero)); |             ge = mk_literal(a.mk_ge(diff, zero)); | ||||||
|         } |         } | ||||||
|         std::cout << mk_pp(e1, m) << " " << mk_pp(e2, m) << " "; |         // std::cout << "eq " << mk_pp(e1, m) << " " << mk_pp(e2, m) << " ";
 | ||||||
|         std::cout << le << " " << ge << "\n"; |         // std::cout << le << " " << ge << "\n";
 | ||||||
|         add_clause(~eq, le); |         add_clause(~eq, le); | ||||||
|         add_clause(~eq, ge); |         add_clause(~eq, ge); | ||||||
|         add_clause(~le, ~ge, eq); |         add_clause(~le, ~ge, eq); | ||||||
|  |  | ||||||
|  | @ -21,6 +21,7 @@ Author: | ||||||
| namespace arith { | namespace arith { | ||||||
| 
 | 
 | ||||||
|     sat::literal solver::internalize(expr* e, bool sign, bool root, bool learned) { |     sat::literal solver::internalize(expr* e, bool sign, bool root, bool learned) { | ||||||
|  |         force_push(); | ||||||
|         flet<bool> _is_learned(m_is_redundant, learned); |         flet<bool> _is_learned(m_is_redundant, learned); | ||||||
|         internalize_atom(e); |         internalize_atom(e); | ||||||
|         literal lit = ctx.expr2literal(e); |         literal lit = ctx.expr2literal(e); | ||||||
|  | @ -30,6 +31,7 @@ namespace arith { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     void solver::internalize(expr* e, bool redundant) { |     void solver::internalize(expr* e, bool redundant) { | ||||||
|  |         force_push(); | ||||||
|         flet<bool> _is_learned(m_is_redundant, redundant); |         flet<bool> _is_learned(m_is_redundant, redundant); | ||||||
|         if (m.is_bool(e)) |         if (m.is_bool(e)) | ||||||
|             internalize_atom(e); |             internalize_atom(e); | ||||||
|  |  | ||||||
|  | @ -583,7 +583,7 @@ namespace arith { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     void solver::push_core() { |     void solver::push_core() { | ||||||
|         TRACE("arith", tout << "push\n";); |         TRACE("arith_verbose", tout << "push\n";); | ||||||
|         m_scopes.push_back(scope()); |         m_scopes.push_back(scope()); | ||||||
|         scope& sc = m_scopes.back(); |         scope& sc = m_scopes.back(); | ||||||
|         sc.m_bounds_lim = m_bounds_trail.size(); |         sc.m_bounds_lim = m_bounds_trail.size(); | ||||||
|  | @ -596,11 +596,11 @@ namespace arith { | ||||||
|         if (m_nla) |         if (m_nla) | ||||||
|             m_nla->push(); |             m_nla->push(); | ||||||
|         th_euf_solver::push_core(); |         th_euf_solver::push_core(); | ||||||
|  | 
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     void solver::pop_core(unsigned num_scopes) { |     void solver::pop_core(unsigned num_scopes) { | ||||||
|         TRACE("arith", tout << "pop " << num_scopes << "\n";); |         TRACE("arith", tout << "pop " << num_scopes << "\n";); | ||||||
|         th_euf_solver::pop_core(num_scopes); |  | ||||||
|         unsigned old_size = m_scopes.size() - num_scopes; |         unsigned old_size = m_scopes.size() - num_scopes; | ||||||
|         del_bounds(m_scopes[old_size].m_bounds_lim); |         del_bounds(m_scopes[old_size].m_bounds_lim); | ||||||
|         m_idiv_terms.shrink(m_scopes[old_size].m_idiv_lim); |         m_idiv_terms.shrink(m_scopes[old_size].m_idiv_lim); | ||||||
|  | @ -613,7 +613,8 @@ namespace arith { | ||||||
|         m_new_bounds.reset(); |         m_new_bounds.reset(); | ||||||
|         if (m_nla) |         if (m_nla) | ||||||
|             m_nla->pop(num_scopes); |             m_nla->pop(num_scopes); | ||||||
|         TRACE("arith", tout << "num scopes: " << num_scopes << " new scope level: " << m_scopes.size() << "\n";); |         TRACE("arith_verbose", tout << "num scopes: " << num_scopes << " new scope level: " << m_scopes.size() << "\n";); | ||||||
|  |         th_euf_solver::pop_core(num_scopes); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     void solver::del_bounds(unsigned old_size) { |     void solver::del_bounds(unsigned old_size) { | ||||||
|  | @ -964,7 +965,7 @@ namespace arith { | ||||||
|                 return sat::check_result::CR_CONTINUE; |                 return sat::check_result::CR_CONTINUE; | ||||||
|             case l_undef: |             case l_undef: | ||||||
|                 TRACE("arith", tout << "check feasible is undef\n";); |                 TRACE("arith", tout << "check feasible is undef\n";); | ||||||
|                 return m.inc() ? sat::check_result::CR_CONTINUE : sat::check_result::CR_GIVEUP; |                 return sat::check_result::CR_CONTINUE; | ||||||
|             case l_true: |             case l_true: | ||||||
|                 break; |                 break; | ||||||
|             default: |             default: | ||||||
|  |  | ||||||
|  | @ -303,7 +303,7 @@ namespace arith { | ||||||
|         void refine_bound(theory_var v, const lp::implied_bound& be); |         void refine_bound(theory_var v, const lp::implied_bound& be); | ||||||
|         literal is_bound_implied(lp::lconstraint_kind k, rational const& value, api_bound const& b) const; |         literal is_bound_implied(lp::lconstraint_kind k, rational const& value, api_bound const& b) const; | ||||||
|         void assert_bound(bool is_true, api_bound& b); |         void assert_bound(bool is_true, api_bound& b); | ||||||
|         void mk_eq_axiom(theory_var v1, theory_var v2); |         void mk_eq_axiom(bool is_eq, theory_var v1, theory_var v2); | ||||||
|         void assert_idiv_mod_axioms(theory_var u, theory_var v, theory_var w, rational const& r); |         void assert_idiv_mod_axioms(theory_var u, theory_var v, theory_var w, rational const& r); | ||||||
|         api_bound* mk_var_bound(sat::literal lit, theory_var v, lp_api::bound_kind bk, rational const& bound); |         api_bound* mk_var_bound(sat::literal lit, theory_var v, lp_api::bound_kind bk, rational const& bound); | ||||||
|         lp::lconstraint_kind bound2constraint_kind(bool is_int, lp_api::bound_kind bk, bool is_true); |         lp::lconstraint_kind bound2constraint_kind(bool is_int, lp_api::bound_kind bk, bool is_true); | ||||||
|  | @ -423,8 +423,8 @@ namespace arith { | ||||||
|         void collect_statistics(statistics& st) const override; |         void collect_statistics(statistics& st) const override; | ||||||
|         euf::th_solver* clone(euf::solver& ctx) override; |         euf::th_solver* clone(euf::solver& ctx) override; | ||||||
|         bool use_diseqs() const override { return true; } |         bool use_diseqs() const override { return true; } | ||||||
|         void new_eq_eh(euf::th_eq const& eq) override { mk_eq_axiom(eq.v1(), eq.v2()); } |         void new_eq_eh(euf::th_eq const& eq) override { mk_eq_axiom(true, eq.v1(), eq.v2()); } | ||||||
|         void new_diseq_eh(euf::th_eq const& de) override { mk_eq_axiom(de.v1(), de.v2()); } |         void new_diseq_eh(euf::th_eq const& de) override { mk_eq_axiom(false, de.v1(), de.v2()); } | ||||||
|         bool unit_propagate() override; |         bool unit_propagate() override; | ||||||
|         void init_model() override; |         void init_model() override; | ||||||
|         void add_value(euf::enode* n, model& mdl, expr_ref_vector& values) override; |         void add_value(euf::enode* n, model& mdl, expr_ref_vector& values) override; | ||||||
|  |  | ||||||
|  | @ -402,12 +402,15 @@ namespace euf { | ||||||
|         if (!init_relevancy()) |         if (!init_relevancy()) | ||||||
|             give_up = true; |             give_up = true; | ||||||
| 
 | 
 | ||||||
|         for (auto* e : m_solvers) |         for (auto* e : m_solvers) { | ||||||
|  |             if (!m.inc()) | ||||||
|  |                 return sat::check_result::CR_GIVEUP; | ||||||
|             switch (e->check()) { |             switch (e->check()) { | ||||||
|             case sat::check_result::CR_CONTINUE: cont = true; break; |             case sat::check_result::CR_CONTINUE: cont = true; break; | ||||||
|             case sat::check_result::CR_GIVEUP: give_up = true; break; |             case sat::check_result::CR_GIVEUP: give_up = true; break; | ||||||
|             default: break; |             default: break; | ||||||
|             } |             } | ||||||
|  |         } | ||||||
|         if (cont) |         if (cont) | ||||||
|             return sat::check_result::CR_CONTINUE; |             return sat::check_result::CR_CONTINUE; | ||||||
|         if (give_up) |         if (give_up) | ||||||
|  |  | ||||||
|  | @ -39,6 +39,7 @@ namespace q { | ||||||
|     { |     { | ||||||
|         auto* ap = alloc(mbp::arith_project_plugin, m); |         auto* ap = alloc(mbp::arith_project_plugin, m); | ||||||
|         ap->set_check_purified(false); |         ap->set_check_purified(false); | ||||||
|  |         ap->set_apply_projection(true); | ||||||
|         add_plugin(ap); |         add_plugin(ap); | ||||||
|         add_plugin(alloc(mbp::datatype_project_plugin, m)); |         add_plugin(alloc(mbp::datatype_project_plugin, m)); | ||||||
|         add_plugin(alloc(mbp::array_project_plugin, m)); |         add_plugin(alloc(mbp::array_project_plugin, m)); | ||||||
|  | @ -186,11 +187,13 @@ namespace q { | ||||||
|     expr_ref mbqi::solver_project(model& mdl, q_body& qb) { |     expr_ref mbqi::solver_project(model& mdl, q_body& qb) { | ||||||
|         for (app* v : qb.vars) |         for (app* v : qb.vars) | ||||||
|             m_model->register_decl(v->get_decl(), mdl(v)); |             m_model->register_decl(v->get_decl(), mdl(v)); | ||||||
|  |         std::cout << "Project\n"; | ||||||
|  |         std::cout << *m_model << "\n"; | ||||||
|  |         std::cout << qb.vbody << "\n"; | ||||||
|         expr_ref_vector fmls(qb.vbody); |         expr_ref_vector fmls(qb.vbody); | ||||||
|         app_ref_vector vars(qb.vars); |         app_ref_vector vars(qb.vars); | ||||||
|         mbp::project_plugin proj(m); |         mbp::project_plugin proj(m); | ||||||
|         proj.purify(m_model_fixer, *m_model, vars, fmls); |         proj.purify(m_model_fixer, *m_model, vars, fmls); | ||||||
|         std::cout << "fmls\n" << fmls << "\n"; |  | ||||||
|         for (unsigned i = 0; i < vars.size(); ++i) { |         for (unsigned i = 0; i < vars.size(); ++i) { | ||||||
|             app* v = vars.get(i); |             app* v = vars.get(i); | ||||||
|             auto* p = get_plugin(v); |             auto* p = get_plugin(v); | ||||||
|  |  | ||||||
|  | @ -103,15 +103,17 @@ namespace q { | ||||||
| 
 | 
 | ||||||
|     void model_fixer::add_projection_functions(model& mdl, ptr_vector<quantifier> const& qs) { |     void model_fixer::add_projection_functions(model& mdl, ptr_vector<quantifier> const& qs) { | ||||||
|         func_decl_set fns; |         func_decl_set fns; | ||||||
|  |         TRACE("q", tout << mdl << "\n";); | ||||||
|         collect_partial_functions(qs, fns); |         collect_partial_functions(qs, fns); | ||||||
|         for (func_decl* f : fns) |         for (func_decl* f : fns) | ||||||
|             add_projection_functions(mdl, f); |             add_projection_functions(mdl, f); | ||||||
|  |         TRACE("q", tout << mdl << "\n";); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     void model_fixer::add_projection_functions(model& mdl, func_decl* f) { |     void model_fixer::add_projection_functions(model& mdl, func_decl* f) { | ||||||
|         // update interpretation of f so that the graph of f is fully determined by the
 |         // update interpretation of f so that the graph of f is fully determined by the
 | ||||||
|         // ground values of its arguments.
 |         // ground values of its arguments.
 | ||||||
|         TRACE("q", tout << mdl << "\n";); | 
 | ||||||
|         func_interp* fi = mdl.get_func_interp(f); |         func_interp* fi = mdl.get_func_interp(f); | ||||||
|         if (!fi)  |         if (!fi)  | ||||||
|             return; |             return; | ||||||
|  | @ -120,8 +122,12 @@ namespace q { | ||||||
|         expr_ref_vector args(m); |         expr_ref_vector args(m); | ||||||
|         for (unsigned i = 0; i < f->get_arity(); ++i)  |         for (unsigned i = 0; i < f->get_arity(); ++i)  | ||||||
|             args.push_back(add_projection_function(mdl, f, i)); |             args.push_back(add_projection_function(mdl, f, i)); | ||||||
|         if (!fi->get_else() && fi->num_entries() > 0) |         if (!fi->get_else() && fi->num_entries() > 0) { | ||||||
|             fi->set_else(fi->get_entry(ctx.s().rand()(fi->num_entries()))->get_result()); |             unsigned idx = ctx.s().rand()(fi->num_entries()); | ||||||
|  |             func_entry const* e = fi->get_entry(idx); | ||||||
|  |             fi->set_else(e->get_result()); | ||||||
|  |             fi->del_entry(idx); | ||||||
|  |         } | ||||||
|         bool has_projection = false; |         bool has_projection = false; | ||||||
|         for (expr* arg : args) |         for (expr* arg : args) | ||||||
|             has_projection |= !is_var(arg); |             has_projection |= !is_var(arg); | ||||||
|  | @ -132,7 +138,6 @@ namespace q { | ||||||
|         new_fi->set_else(m.mk_app(f_new, args)); |         new_fi->set_else(m.mk_app(f_new, args)); | ||||||
|         mdl.update_func_interp(f, new_fi); |         mdl.update_func_interp(f, new_fi); | ||||||
|         mdl.register_decl(f_new, fi); |         mdl.register_decl(f_new, fi); | ||||||
|         TRACE("q", tout << mdl << "\n";); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     expr_ref model_fixer::add_projection_function(model& mdl, func_decl* f, unsigned idx) { |     expr_ref model_fixer::add_projection_function(model& mdl, func_decl* f, unsigned idx) { | ||||||
|  |  | ||||||
|  | @ -217,8 +217,8 @@ namespace euf { | ||||||
|         return n; |         return n; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     unsigned th_propagation::get_obj_size(unsigned num_lits, unsigned num_eqs) { |     size_t th_propagation::get_obj_size(unsigned num_lits, unsigned num_eqs) { | ||||||
|         return sizeof(th_propagation) + sizeof(sat::literal) * num_lits + sizeof(enode_pair) * num_eqs; |         return sat::constraint_base::obj_size(sizeof(th_propagation) + sizeof(sat::literal) * num_lits + sizeof(enode_pair) * num_eqs); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     th_propagation::th_propagation(unsigned n_lits, sat::literal const* lits, unsigned n_eqs, enode_pair const* eqs) { |     th_propagation::th_propagation(unsigned n_lits, sat::literal const* lits, unsigned n_eqs, enode_pair const* eqs) { | ||||||
|  |  | ||||||
|  | @ -161,7 +161,7 @@ namespace euf { | ||||||
|         virtual void push_core(); |         virtual void push_core(); | ||||||
|         virtual void pop_core(unsigned n); |         virtual void pop_core(unsigned n); | ||||||
|         void force_push() { |         void force_push() { | ||||||
|             CTRACE("euf", m_num_scopes > 0, tout << "push-core " << m_num_scopes << "\n";); |             CTRACE("euf_verbose", m_num_scopes > 0, tout << "push-core " << m_num_scopes << "\n";); | ||||||
|             for (; m_num_scopes > 0; --m_num_scopes) push_core(); |             for (; m_num_scopes > 0; --m_num_scopes) push_core(); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | @ -194,7 +194,7 @@ namespace euf { | ||||||
|         unsigned       m_num_eqs; |         unsigned       m_num_eqs; | ||||||
|         sat::literal*  m_literals; |         sat::literal*  m_literals; | ||||||
|         enode_pair*    m_eqs; |         enode_pair*    m_eqs; | ||||||
|         static unsigned get_obj_size(unsigned num_lits, unsigned num_eqs); |         static size_t get_obj_size(unsigned num_lits, unsigned num_eqs); | ||||||
|         th_propagation(unsigned n_lits, sat::literal const* lits, unsigned n_eqs, enode_pair const* eqs); |         th_propagation(unsigned n_lits, sat::literal const* lits, unsigned n_eqs, enode_pair const* eqs); | ||||||
|     public: |     public: | ||||||
|         static th_propagation* mk(th_euf_solver& th, sat::literal_vector const& lits, enode_pair_vector const& eqs); |         static th_propagation* mk(th_euf_solver& th, sat::literal_vector const& lits, enode_pair_vector const& eqs); | ||||||
|  |  | ||||||
|  | @ -21,9 +21,33 @@ Revision History: | ||||||
| #ifdef Z3DEBUG | #ifdef Z3DEBUG | ||||||
| 
 | 
 | ||||||
| void region::display_mem_stats(std::ostream & out) const { | void region::display_mem_stats(std::ostream & out) const { | ||||||
|     out << "num. objects:      " << m_chuncks.size() << "\n"; |     out << "num. objects:      " << m_chunks.size() << "\n"; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void * region::allocate(size_t size) { | ||||||
|  |     char * r = alloc_svect(char, size); | ||||||
|  |     m_chunks.push_back(r); | ||||||
|  |     return r; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void region::reset() { | ||||||
|  |     for (auto* c : m_chunks) | ||||||
|  |         dealloc_svect(c); | ||||||
|  |     m_chunks.reset(); | ||||||
|  |     m_scopes.reset(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void region::pop_scope() { | ||||||
|  |     unsigned old_size = m_scopes.back(); | ||||||
|  |     m_scopes.pop_back(); | ||||||
|  |     ptr_vector<char>::iterator it  = m_chunks.begin() + old_size; | ||||||
|  |     ptr_vector<char>::iterator end = m_chunks.end(); | ||||||
|  |     for (; it != end; ++it)  | ||||||
|  |         dealloc_svect(*it);     | ||||||
|  |     m_chunks.shrink(old_size); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| #else | #else | ||||||
| 
 | 
 | ||||||
| #include "util/tptr.h" | #include "util/tptr.h" | ||||||
|  |  | ||||||
|  | @ -25,44 +25,23 @@ Revision History: | ||||||
| #include "util/vector.h" | #include "util/vector.h" | ||||||
| 
 | 
 | ||||||
| class region { | class region { | ||||||
|     ptr_vector<char> m_chuncks; |     ptr_vector<char> m_chunks; | ||||||
|     unsigned_vector  m_scopes; |     unsigned_vector  m_scopes; | ||||||
| public: | public: | ||||||
|     ~region() { |     ~region() { | ||||||
|         reset(); |         reset(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     void * allocate(size_t size) { |  | ||||||
|         char * r = alloc_svect(char, size); |  | ||||||
|         m_chuncks.push_back(r); |  | ||||||
|         return r; |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     void reset() { |     void * allocate(size_t size); | ||||||
|         ptr_vector<char>::iterator it  = m_chuncks.begin(); | 
 | ||||||
|         ptr_vector<char>::iterator end = m_chuncks.end(); |     void reset(); | ||||||
|         for (; it != end; ++it) { |  | ||||||
|             dealloc_svect(*it); |  | ||||||
|         } |  | ||||||
|         m_chuncks.reset(); |  | ||||||
|         m_scopes.reset(); |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     void push_scope() { |     void push_scope() { | ||||||
|         m_scopes.push_back(m_chuncks.size()); |         m_scopes.push_back(m_chunks.size()); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 |     void pop_scope(); | ||||||
|     void pop_scope() { |  | ||||||
|         unsigned old_size = m_scopes.back(); |  | ||||||
|         m_scopes.pop_back(); |  | ||||||
|         ptr_vector<char>::iterator it  = m_chuncks.begin() + old_size; |  | ||||||
|         ptr_vector<char>::iterator end = m_chuncks.end(); |  | ||||||
|         for (; it != end; ++it) { |  | ||||||
|             dealloc_svect(*it); |  | ||||||
|         } |  | ||||||
|         m_chuncks.shrink(old_size); |  | ||||||
|     } |  | ||||||
|      |      | ||||||
|     void pop_scope(unsigned num_scopes) { |     void pop_scope(unsigned num_scopes) { | ||||||
|         for (unsigned i = 0; i < num_scopes; i++) { |         for (unsigned i = 0; i < num_scopes; i++) { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue