mirror of
				https://github.com/Z3Prover/z3
				synced 2025-10-31 11:42:28 +00:00 
			
		
		
		
	merge useful utilities from qsat
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
		
							parent
							
								
									f951372f03
								
							
						
					
					
						commit
						f175f864ec
					
				
					 32 changed files with 323 additions and 38 deletions
				
			
		|  | @ -604,8 +604,16 @@ namespace z3 { | |||
| 
 | ||||
|         /**
 | ||||
|            \brief Return true if this expression is a numeral. | ||||
|            Specialized functions also return representations for the numerals as | ||||
|            small integers, 64 bit integers or rational or decimal strings. | ||||
|         */ | ||||
|         bool is_numeral() const { return kind() == Z3_NUMERAL_AST; } | ||||
|         bool is_numeral_i64(__int64& i) const { bool r = Z3_get_numeral_int64(ctx(), m_ast, &i); return r;} | ||||
|         bool is_numeral_u64(__uint64& i) const { bool r = Z3_get_numeral_uint64(ctx(), m_ast, &i); return r;} | ||||
|         bool is_numeral_i(int& i) const { bool r = Z3_get_numeral_int(ctx(), m_ast, &i); return r;} | ||||
|         bool is_numeral_u(unsigned& i) const { bool r = Z3_get_numeral_uint(ctx(), m_ast, &i); return r;} | ||||
|         bool is_numeral(std::string& s) const { if (!is_numeral()) return false; s = Z3_get_numeral_string(ctx(), m_ast); return true; } | ||||
|         bool is_numeral(std::string& s, unsigned precision) const { if (!is_numeral()) return false; s = Z3_get_numeral_decimal_string(ctx(), m_ast, precision); return true; } | ||||
|         /**
 | ||||
|            \brief Return true if this expression is an application. | ||||
|         */ | ||||
|  |  | |||
|  | @ -3940,7 +3940,7 @@ class ArraySortRef(SortRef): | |||
|         >>> A.range() | ||||
|         Bool | ||||
|         """ | ||||
|         return _to_sort_ref(Z3_get_array_sort_range(self.ctx_ref(), self.ast), self.ctx) | ||||
|         return _to_sort_ref(Z3_get_array_sort_range(self.ctx_ref(), self.ast), self.ctx)     | ||||
| 
 | ||||
| class ArrayRef(ExprRef): | ||||
|     """Array expressions. """ | ||||
|  | @ -4162,6 +4162,16 @@ def Select(a, i): | |||
|         _z3_assert(is_array(a), "First argument must be a Z3 array expression") | ||||
|     return a[i] | ||||
| 
 | ||||
| def Default(a): | ||||
|     """ Return a default value for array expression. | ||||
|     >>> b = K(IntSort(), 1) | ||||
|     >>> prove(Default(b) == 1) | ||||
|     proved | ||||
|     """ | ||||
|     if __debug__: | ||||
|         _z3_assert(is_array(a), "First argument must be a Z3 array expression") | ||||
|     return a.mk_default() | ||||
|      | ||||
| def Map(f, *args): | ||||
|     """Return a Z3 map array expression. | ||||
| 
 | ||||
|  |  | |||
|  | @ -664,3 +664,45 @@ algebraic_numbers::anum const & arith_util::to_irrational_algebraic_numeral(expr | |||
|     SASSERT(is_irrational_algebraic_numeral(n)); | ||||
|     return plugin().aw().to_anum(to_app(n)->get_decl()); | ||||
| } | ||||
| 
 | ||||
| expr_ref arith_util::mk_mul_simplify(expr_ref_vector const& args) { | ||||
|     return mk_mul_simplify(args.size(), args.c_ptr()); | ||||
| 
 | ||||
| } | ||||
| expr_ref arith_util::mk_mul_simplify(unsigned sz, expr* const* args) { | ||||
|     expr_ref result(m_manager); | ||||
|      | ||||
|     switch (sz) { | ||||
|     case 0: | ||||
|         result = mk_numeral(rational(1), true); | ||||
|         break; | ||||
|     case 1: | ||||
|         result = args[0]; | ||||
|         break; | ||||
|     default: | ||||
|         result = mk_mul(sz, args); | ||||
|         break;                     | ||||
|     } | ||||
|     return result; | ||||
| } | ||||
| 
 | ||||
| expr_ref arith_util::mk_add_simplify(expr_ref_vector const& args) { | ||||
|     return mk_add_simplify(args.size(), args.c_ptr()); | ||||
| 
 | ||||
| } | ||||
| expr_ref arith_util::mk_add_simplify(unsigned sz, expr* const* args) { | ||||
|     expr_ref result(m_manager); | ||||
|      | ||||
|     switch (sz) { | ||||
|     case 0: | ||||
|         result = mk_numeral(rational(0), true); | ||||
|         break; | ||||
|     case 1: | ||||
|         result = args[0]; | ||||
|         break; | ||||
|     default: | ||||
|         result = mk_add(sz, args); | ||||
|         break;                     | ||||
|     } | ||||
|     return result; | ||||
| } | ||||
|  |  | |||
|  | @ -149,7 +149,6 @@ protected: | |||
|     func_decl * m_mod_0_decl; | ||||
|     func_decl * m_u_asin_decl; | ||||
|     func_decl * m_u_acos_decl; | ||||
| 
 | ||||
|     ptr_vector<app> m_small_ints; | ||||
|     ptr_vector<app> m_small_reals; | ||||
| 
 | ||||
|  | @ -416,6 +415,11 @@ public: | |||
|         return m_manager.mk_eq(lhs, rhs); | ||||
|     } | ||||
| 
 | ||||
|     expr_ref mk_mul_simplify(expr_ref_vector const& args); | ||||
|     expr_ref mk_mul_simplify(unsigned sz, expr* const* args); | ||||
| 
 | ||||
|     expr_ref mk_add_simplify(expr_ref_vector const& args); | ||||
|     expr_ref mk_add_simplify(unsigned sz, expr* const* args); | ||||
| }; | ||||
| 
 | ||||
| #endif /* ARITH_DECL_PLUGIN_H_ */ | ||||
|  |  | |||
|  | @ -1200,6 +1200,14 @@ std::ostream& operator<<(std::ostream& out, app_ref const&  e) { | |||
|     return out << mk_ismt2_pp(e.get(), e.get_manager()); | ||||
| } | ||||
| 
 | ||||
| std::ostream& operator<<(std::ostream& out, func_decl_ref const&  e) { | ||||
|     return out << mk_ismt2_pp(e.get(), e.get_manager()); | ||||
| } | ||||
| 
 | ||||
| std::ostream& operator<<(std::ostream& out, sort_ref const&  e) { | ||||
|     return out << mk_ismt2_pp(e.get(), e.get_manager()); | ||||
| } | ||||
| 
 | ||||
| std::ostream& operator<<(std::ostream& out, expr_ref_vector const&  e) { | ||||
|     for (unsigned i = 0; i < e.size(); ++i) { | ||||
|         out << mk_ismt2_pp(e[i], e.get_manager()); | ||||
|  | @ -1216,6 +1224,18 @@ std::ostream& operator<<(std::ostream& out, app_ref_vector const&  e) { | |||
|     return out; | ||||
| } | ||||
| 
 | ||||
| std::ostream& operator<<(std::ostream& out, func_decl_ref_vector const&  e) { | ||||
|     for (unsigned i = 0; i < e.size(); ++i)  | ||||
|         out << mk_ismt2_pp(e[i], e.get_manager()) << "\n"; | ||||
|     return out; | ||||
| } | ||||
| 
 | ||||
| std::ostream& operator<<(std::ostream& out, sort_ref_vector const&  e) { | ||||
|     for (unsigned i = 0; i < e.size(); ++i)  | ||||
|         out << mk_ismt2_pp(e[i], e.get_manager()) << "\n"; | ||||
|     return out; | ||||
| } | ||||
| 
 | ||||
| #ifdef Z3DEBUG | ||||
| void pp(expr const * n, ast_manager & m) { | ||||
|     std::cout << mk_ismt2_pp(const_cast<expr*>(n), m) << std::endl; | ||||
|  |  | |||
|  | @ -117,8 +117,13 @@ std::ostream& operator<<(std::ostream& out, mk_ismt2_pp const & p); | |||
| 
 | ||||
| std::ostream& operator<<(std::ostream& out, expr_ref const& e); | ||||
| std::ostream& operator<<(std::ostream& out, app_ref const& e); | ||||
| std::ostream& operator<<(std::ostream& out, func_decl_ref const& e); | ||||
| std::ostream& operator<<(std::ostream& out, sort_ref const& e); | ||||
| 
 | ||||
| 
 | ||||
| std::ostream& operator<<(std::ostream& out, expr_ref_vector const& e); | ||||
| std::ostream& operator<<(std::ostream& out, app_ref_vector const& e); | ||||
| std::ostream& operator<<(std::ostream& out, func_decl_ref_vector const& e); | ||||
| std::ostream& operator<<(std::ostream& out, sort_ref_vector const& e); | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -170,7 +170,6 @@ app* mk_and(ast_manager & m, unsigned num_args, app * const * args) { | |||
|     return to_app(mk_and(m, num_args, (expr* const*) args)); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| expr * mk_or(ast_manager & m, unsigned num_args, expr * const * args) { | ||||
|     if (num_args == 0) | ||||
|         return m.mk_false(); | ||||
|  | @ -188,10 +187,43 @@ expr * mk_not(ast_manager & m, expr * arg) { | |||
|     expr * atom; | ||||
|     if (m.is_not(arg, atom)) | ||||
|         return atom; | ||||
|     else if (m.is_true(arg))  | ||||
|         return m.mk_false(); | ||||
|     else if (m.is_false(arg)) | ||||
|         return m.mk_true(); | ||||
|     else | ||||
|         return m.mk_not(arg); | ||||
| } | ||||
| 
 | ||||
| expr_ref push_not(const expr_ref& e) { | ||||
|     ast_manager& m = e.get_manager(); | ||||
|     if (!is_app(e)) { | ||||
|         return expr_ref(m.mk_not(e), m); | ||||
|     } | ||||
|     app* a = to_app(e); | ||||
|     if (m.is_and(a)) { | ||||
|         if (a->get_num_args() == 0) { | ||||
|             return expr_ref(m.mk_false(), m); | ||||
|         } | ||||
|         expr_ref_vector args(m); | ||||
|         for (unsigned i = 0; i < a->get_num_args(); ++i) { | ||||
|             args.push_back(push_not(expr_ref(a->get_arg(i), m))); | ||||
|         } | ||||
|         return mk_or(args); | ||||
|     } | ||||
|     if (m.is_or(a)) { | ||||
|         if (a->get_num_args() == 0) { | ||||
|             return expr_ref(m.mk_true(), m); | ||||
|         } | ||||
|         expr_ref_vector args(m); | ||||
|         for (unsigned i = 0; i < a->get_num_args(); ++i) { | ||||
|             args.push_back(push_not(expr_ref(a->get_arg(i), m))); | ||||
|         } | ||||
|         return mk_and(args); | ||||
|     } | ||||
|     return expr_ref(mk_not(m, e), m);     | ||||
| } | ||||
| 
 | ||||
| expr * expand_distinct(ast_manager & m, unsigned num_args, expr * const * args) { | ||||
|     expr_ref_buffer new_diseqs(m); | ||||
|     for (unsigned i = 0; i < num_args; i++) { | ||||
|  | @ -201,6 +233,24 @@ expr * expand_distinct(ast_manager & m, unsigned num_args, expr * const * args) | |||
|     return mk_and(m, new_diseqs.size(), new_diseqs.c_ptr()); | ||||
| } | ||||
| 
 | ||||
| expr* mk_distinct(ast_manager& m, unsigned num_args, expr * const * args) { | ||||
|     switch (num_args) { | ||||
|     case 0: | ||||
|     case 1: | ||||
|         return m.mk_true(); | ||||
|     case 2: | ||||
|         return m.mk_not(m.mk_eq(args[0], args[1])); | ||||
|     default: | ||||
|         return m.mk_distinct(num_args, args); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| expr_ref mk_distinct(expr_ref_vector const& args) { | ||||
|     ast_manager& m = args.get_manager(); | ||||
|     return expr_ref(mk_distinct(m, args.size(), args.c_ptr()), m); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void flatten_and(expr_ref_vector& result) { | ||||
|     ast_manager& m = result.get_manager(); | ||||
|     expr* e1, *e2, *e3; | ||||
|  |  | |||
|  | @ -121,18 +121,29 @@ app  * mk_or(ast_manager & m, unsigned num_args, app * const * args); | |||
| inline app_ref mk_or(app_ref_vector const& args) { return app_ref(mk_or(args.get_manager(), args.size(), args.c_ptr()), args.get_manager()); } | ||||
| inline expr_ref mk_or(expr_ref_vector const& args) { return expr_ref(mk_or(args.get_manager(), args.size(), args.c_ptr()), args.get_manager()); } | ||||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|    Return a          if arg = (not a) | ||||
|    Retur (not arg)   otherwise | ||||
|  */ | ||||
| expr * mk_not(ast_manager & m, expr * arg); | ||||
| 
 | ||||
| /**
 | ||||
|    Negate and push over conjunction or disjunction. | ||||
|  */ | ||||
| expr_ref push_not(const expr_ref& arg); | ||||
| 
 | ||||
| /**
 | ||||
|    Return the expression (and (not (= args[0] args[1])) (not (= args[0] args[2])) ... (not (= args[num_args-2] args[num_args-1]))) | ||||
| */ | ||||
| expr * expand_distinct(ast_manager & m, unsigned num_args, expr * const * args); | ||||
| 
 | ||||
| /**
 | ||||
|    Create simplified distinct term. Binary distinct becomes a single disequality. | ||||
|  */ | ||||
| expr * mk_distinct(ast_manager& m, unsigned num_args, expr * const * args); | ||||
| 
 | ||||
| expr_ref mk_distinct(expr_ref_vector const& args); | ||||
| 
 | ||||
| /**
 | ||||
|    \brief Collect top-level conjunctions and disjunctions. | ||||
| */ | ||||
|  |  | |||
|  | @ -865,6 +865,12 @@ sort * bv_util::mk_sort(unsigned bv_size) { | |||
|     return m_manager.mk_sort(get_fid(), BV_SORT, 1, p); | ||||
| } | ||||
| 
 | ||||
| unsigned bv_util::get_int2bv_size(parameter const& p) { | ||||
|     int sz; | ||||
|     VERIFY(m_plugin->get_int2bv_size(1, &p, sz)); | ||||
|     return static_cast<unsigned>(sz); | ||||
| } | ||||
| 
 | ||||
| app * bv_util::mk_bv2int(expr* e) { | ||||
|     sort* s = m_manager.mk_sort(m_manager.mk_family_id("arith"), INT_SORT); | ||||
|     parameter p(s); | ||||
|  |  | |||
|  | @ -234,7 +234,6 @@ protected: | |||
| 
 | ||||
|     func_decl * mk_mkbv(unsigned arity, sort * const * domain); | ||||
| 
 | ||||
|     bool get_int2bv_size(unsigned num_parameters, parameter const * parameters, int & result); | ||||
| 
 | ||||
|     func_decl * mk_num_decl(unsigned num_parameters, parameter const * parameters, unsigned arity); | ||||
| 
 | ||||
|  | @ -267,6 +266,8 @@ public: | |||
| 
 | ||||
|     virtual expr * get_some_value(sort * s); | ||||
| 
 | ||||
|     bool get_int2bv_size(unsigned num_parameters, parameter const * parameters, int & result); | ||||
| 
 | ||||
|     virtual bool is_considered_uninterpreted(func_decl * f) { | ||||
|         if (f->get_family_id() != get_family_id()) | ||||
|             return false; | ||||
|  | @ -390,6 +391,8 @@ public: | |||
|         return static_cast<unsigned>(s->get_parameter(0).get_int()); | ||||
|     } | ||||
|     unsigned get_bv_size(expr const * n) const { return get_bv_size(m_manager.get_sort(n)); } | ||||
|     unsigned get_int2bv_size(parameter const& p); | ||||
| 
 | ||||
| 
 | ||||
|     app * mk_ule(expr * arg1, expr * arg2) { return m_manager.mk_app(get_fid(), OP_ULEQ, arg1, arg2); } | ||||
|     app * mk_sle(expr * arg1, expr * arg2) { return m_manager.mk_app(get_fid(), OP_SLEQ, arg1, arg2); } | ||||
|  | @ -427,6 +430,7 @@ public: | |||
|     app * mk_bvumul_no_ovfl(expr* m, expr* n) { return m_manager.mk_app(get_fid(), OP_BUMUL_NO_OVFL, n, m); } | ||||
| 
 | ||||
|     app * mk_bv(unsigned n, expr* const* es) { return m_manager.mk_app(get_fid(), OP_MKBV, n, es); } | ||||
| 
 | ||||
| }; | ||||
| 
 | ||||
| #endif /* BV_DECL_PLUGIN_H_ */ | ||||
|  |  | |||
|  | @ -1000,3 +1000,25 @@ void datatype_util::display_datatype(sort *s0, std::ostream& strm) { | |||
|     } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| bool datatype_util::is_func_decl(datatype_op_kind k, unsigned num_params, parameter const* params, func_decl* f) { | ||||
|     bool eq =  | ||||
|         f->get_decl_kind() == k && | ||||
|         f->get_family_id() == m_family_id && | ||||
|         f->get_num_parameters() == num_params; | ||||
|     for (unsigned i = 0; eq && i < num_params; ++i) { | ||||
|         eq = params[i] == f->get_parameter(i); | ||||
|     } | ||||
|     return eq; | ||||
| } | ||||
| 
 | ||||
| bool datatype_util::is_constructor_of(unsigned num_params, parameter const* params, func_decl* f) { | ||||
|     return  | ||||
|         num_params == 2 && | ||||
|         m_family_id == f->get_family_id() && | ||||
|         OP_DT_CONSTRUCTOR == f->get_decl_kind() && | ||||
|         2 == f->get_num_parameters() && | ||||
|         params[0] == f->get_parameter(0) && | ||||
|         params[1] == f->get_parameter(1); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -209,6 +209,8 @@ public: | |||
|     func_decl * get_recognizer_constructor(func_decl * recognizer); | ||||
|     family_id get_family_id() const { return m_family_id; } | ||||
|     bool are_siblings(sort * s1, sort * s2); | ||||
|     bool is_func_decl(datatype_op_kind k, unsigned num_params, parameter const* params, func_decl* f); | ||||
|     bool is_constructor_of(unsigned num_params, parameter const* params, func_decl* f); | ||||
|     void reset(); | ||||
|     void display_datatype(sort *s, std::ostream& strm); | ||||
| 
 | ||||
|  |  | |||
|  | @ -22,6 +22,10 @@ Notes: | |||
| 
 | ||||
| void expr_abstractor::operator()(unsigned base, unsigned num_bound, expr* const* bound, expr* n, expr_ref& result) { | ||||
|      | ||||
|     if (num_bound == 0) { | ||||
|         result = n; | ||||
|         return; | ||||
|     } | ||||
|     expr * curr = 0, *b = 0; | ||||
|     SASSERT(n->get_ref_count() > 0); | ||||
| 
 | ||||
|  | @ -106,3 +110,27 @@ void expr_abstract(ast_manager& m, unsigned base, unsigned num_bound, expr* cons | |||
|     expr_abstractor abs(m); | ||||
|     abs(base, num_bound, bound, n, result); | ||||
| } | ||||
| 
 | ||||
| expr_ref mk_quantifier(bool is_forall, ast_manager& m, unsigned num_bound, app* const* bound, expr* n) { | ||||
|     expr_ref result(m); | ||||
|     expr_abstract(m, 0, num_bound, (expr* const*)bound, n, result);     | ||||
|     if (num_bound > 0) { | ||||
|         ptr_vector<sort> sorts; | ||||
|         svector<symbol> names; | ||||
|         for (unsigned i = 0; i < num_bound; ++i) { | ||||
|             sorts.push_back(m.get_sort(bound[i])); | ||||
|             names.push_back(bound[i]->get_decl()->get_name()); | ||||
|         } | ||||
|         result = m.mk_quantifier(is_forall, num_bound, sorts.c_ptr(), names.c_ptr(), result); | ||||
|     } | ||||
|     return result; | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| expr_ref mk_forall(ast_manager& m, unsigned num_bound, app* const* bound, expr* n) { | ||||
|     return mk_quantifier(true, m, num_bound, bound, n); | ||||
| } | ||||
| 
 | ||||
| expr_ref mk_exists(ast_manager& m, unsigned num_bound, app* const* bound, expr* n) { | ||||
|     return mk_quantifier(false, m, num_bound, bound, n); | ||||
| } | ||||
|  |  | |||
|  | @ -33,6 +33,8 @@ public: | |||
| }; | ||||
| 
 | ||||
| void expr_abstract(ast_manager& m, unsigned base, unsigned num_bound, expr* const* bound, expr* n, expr_ref&  result); | ||||
| expr_ref mk_forall(ast_manager& m, unsigned num_bound, app* const* bound, expr* n); | ||||
| expr_ref mk_exists(ast_manager& m, unsigned num_bound, app* const* bound, expr* n); | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
|  |  | |||
|  | @ -30,6 +30,14 @@ void expr_safe_replace::insert(expr* src, expr* dst) { | |||
|     m_subst.insert(src, dst); | ||||
| } | ||||
| 
 | ||||
| void expr_safe_replace::operator()(expr_ref_vector& es) { | ||||
|     expr_ref val(m); | ||||
|     for (unsigned i = 0; i < es.size(); ++i) { | ||||
|         (*this)(es[i].get(), val); | ||||
|         es[i] = val; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void expr_safe_replace::operator()(expr* e, expr_ref& res) { | ||||
|     m_todo.push_back(e); | ||||
|     expr* a, *b; | ||||
|  |  | |||
|  | @ -42,6 +42,8 @@ public: | |||
| 
 | ||||
|     void operator()(expr* src, expr_ref& e); | ||||
| 
 | ||||
|     void operator()(expr_ref_vector& es); | ||||
| 
 | ||||
|     void apply_substitution(expr* s, expr* def, expr_ref& t); | ||||
| 
 | ||||
|     void reset(); | ||||
|  |  | |||
|  | @ -73,7 +73,7 @@ public: | |||
|         unsigned nd = q->get_num_decls(); | ||||
|         for (unsigned i = 0; i < nd; ++i) { | ||||
|             sort* s = q->get_decl_sort(i); | ||||
|             app* a = m.mk_fresh_const("x", s); | ||||
|             app* a = m.mk_fresh_const(q->get_decl_name(i).str().c_str(), s); | ||||
|             vars.push_back(a); | ||||
|         } | ||||
|         expr * const * exprs = (expr* const*) (vars.c_ptr() + vars.size()- nd); | ||||
|  | @ -154,9 +154,7 @@ private: | |||
|     } | ||||
|      | ||||
|     quantifier_type& negate(quantifier_type& qt) { | ||||
|         TRACE("qe", display(qt, tout); tout << "\n";); | ||||
|         qt = static_cast<quantifier_type>(qt ^0x1); | ||||
|         TRACE("qe", display(qt, tout); tout << "\n";); | ||||
|         return qt; | ||||
|     } | ||||
|      | ||||
|  | @ -205,6 +203,7 @@ private: | |||
|         case AST_APP: { | ||||
|             expr_ref_vector args(m); | ||||
|             expr_ref tmp(m); | ||||
|             expr* t1, *t2, *t3; | ||||
|             unsigned num_args = 0; | ||||
|             app* a = to_app(fml); | ||||
|             if (m.is_and(fml)) { | ||||
|  | @ -228,16 +227,35 @@ private: | |||
|                 negate(qt); | ||||
|                 result = m.mk_not(tmp); | ||||
|             } | ||||
|             else if (m.is_implies(fml)) { | ||||
|                 pull_quantifier(to_app(fml)->get_arg(0), negate(qt), vars, tmp); | ||||
|             else if (m.is_implies(fml, t1, t2)) { | ||||
|                 pull_quantifier(t1, negate(qt), vars, tmp); | ||||
|                 negate(qt); | ||||
|                 pull_quantifier(to_app(fml)->get_arg(1), qt, vars, result); | ||||
|                 pull_quantifier(t2, qt, vars, result); | ||||
|                 result = m.mk_implies(tmp, result); | ||||
|             } | ||||
|             else if (m.is_ite(fml)) { | ||||
|                 pull_quantifier(to_app(fml)->get_arg(1), qt, vars, tmp); | ||||
|                 pull_quantifier(to_app(fml)->get_arg(2), qt, vars, result); | ||||
|                 result = m.mk_ite(to_app(fml)->get_arg(0), tmp, result); | ||||
|             else if (m.is_ite(fml, t1, t2, t3)) { | ||||
|                 expr_ref tt1(m), tt2(m), tt3(m), ntt1(m), nt1(m); | ||||
|                 pull_quantifier(t2, qt, vars, tt2); | ||||
|                 pull_quantifier(t3, qt, vars, tt3); | ||||
|                 if (has_quantifiers(t1)) { | ||||
|                     pull_quantifier(t1, qt, vars, tt1); | ||||
|                     nt1 = m.mk_not(t1); | ||||
|                     pull_quantifier(nt1, qt, vars, ntt1); | ||||
|                     result = m.mk_and(m.mk_or(ntt1, tt2), m.mk_or(tt1, tt3)); | ||||
|                 } | ||||
|                 else { | ||||
|                     result = m.mk_ite(t1, tt2, tt3); | ||||
|                 } | ||||
|             } | ||||
|             else if ((m.is_eq(fml, t1, t2) && m.is_bool(t1)) || m.is_iff(fml, t1, t2)) { | ||||
|                 expr_ref tt1(m), tt2(m), ntt1(m), ntt2(m), nt1(m), nt2(m); | ||||
|                 pull_quantifier(t1, qt, vars, tt1); | ||||
|                 pull_quantifier(t2, qt, vars, tt2); | ||||
|                 nt1 = m.mk_not(t1); | ||||
|                 nt2 = m.mk_not(t2); | ||||
|                 pull_quantifier(nt1, qt, vars, ntt1); | ||||
|                 pull_quantifier(nt2, qt, vars, ntt2); | ||||
|                 result = m.mk_and(m.mk_or(ntt1, tt2), m.mk_or(ntt2, tt1)); | ||||
|             } | ||||
|             else { | ||||
|                 // the formula contains a quantifier, but it is "inaccessible"
 | ||||
|  |  | |||
|  | @ -303,8 +303,8 @@ public: | |||
|             goal_ref g = alloc(goal, m, ctx.produce_proofs(), ctx.produce_models(), ctx.produce_unsat_cores()); | ||||
|             assert_exprs_from(ctx, *g); | ||||
| 
 | ||||
|             unsigned timeout   = p.get_uint("timeout", UINT_MAX); | ||||
|             unsigned rlimit  =   p.get_uint("rlimit", 0); | ||||
|             unsigned timeout   = p.get_uint("timeout", ctx.params().m_timeout); | ||||
|             unsigned rlimit  =   p.get_uint("rlimit", ctx.params().m_rlimit); | ||||
| 
 | ||||
|             goal_ref_buffer     result_goals; | ||||
|             model_converter_ref mc; | ||||
|  |  | |||
|  | @ -539,7 +539,6 @@ namespace algebraic_numbers { | |||
|         } | ||||
| 
 | ||||
|         bool factor(scoped_upoly const & up, factors & r) { | ||||
|             // std::cout << "factor: "; upm().display(std::cout, up); std::cout << std::endl;
 | ||||
|             if (m_factor) { | ||||
|                 return upm().factor(up, r, m_factor_params); | ||||
|             } | ||||
|  | @ -547,7 +546,7 @@ namespace algebraic_numbers { | |||
|                 scoped_upoly & up_sqf = m_isolate_tmp3; | ||||
|                 up_sqf.reset(); | ||||
|                 upm().square_free(up.size(), up.c_ptr(), up_sqf); | ||||
|                 TRACE("anum_bug", upm().display(tout, up_sqf.size(), up_sqf.c_ptr()); tout << "\n";); | ||||
|                 TRACE("algebraic", upm().display(tout, up_sqf.size(), up_sqf.c_ptr()); tout << "\n";); | ||||
|                 r.push_back(up_sqf, 1); | ||||
|                 return false; | ||||
|             } | ||||
|  | @ -566,6 +565,7 @@ namespace algebraic_numbers { | |||
|         } | ||||
| 
 | ||||
|         void isolate_roots(scoped_upoly const & up, numeral_vector & roots) { | ||||
|             TRACE("algebraic", upm().display(tout, up); tout << "\n";); | ||||
|             if (up.empty()) | ||||
|                 return; // ignore the zero polynomial
 | ||||
|             factors & fs = m_isolate_factors; | ||||
|  | @ -586,6 +586,7 @@ namespace algebraic_numbers { | |||
|                 upolynomial::numeral_vector const & f = fs[i]; | ||||
|                 // polynomial f contains the non zero roots
 | ||||
|                 unsigned d = upm().degree(f); | ||||
|                 TRACE("algebraic", tout << "factor " << i << " degree: " << d << "\n";); | ||||
|                 if (d == 0) | ||||
|                     continue; // found all roots of f
 | ||||
|                 scoped_mpq r(qm()); | ||||
|  | @ -601,8 +602,9 @@ namespace algebraic_numbers { | |||
|                 } | ||||
|                 SASSERT(m_isolate_roots.empty() && m_isolate_lowers.empty() && m_isolate_uppers.empty()); | ||||
|                 upm().sqf_isolate_roots(f.size(), f.c_ptr(), bqm(), m_isolate_roots, m_isolate_lowers, m_isolate_uppers); | ||||
|                 // collect rational/basic roots
 | ||||
|                 // collect rational/basic roots                
 | ||||
|                 unsigned sz = m_isolate_roots.size(); | ||||
|                 TRACE("algebraic", tout << "isolated roots: " << sz << "\n";); | ||||
|                 for (unsigned i = 0; i < sz; i++) { | ||||
|                     to_mpq(qm(), m_isolate_roots[i], r); | ||||
|                     roots.push_back(numeral(mk_basic_cell(r))); | ||||
|  |  | |||
|  | @ -29,7 +29,6 @@ Revision History: | |||
| #include"ast_counter.h" | ||||
| #include"statistics.h" | ||||
| #include"lbool.h" | ||||
| #include"qe_util.h" | ||||
| 
 | ||||
| namespace datalog { | ||||
| 
 | ||||
|  |  | |||
|  | @ -20,6 +20,7 @@ Revision History: | |||
| #include "pdr_closure.h" | ||||
| #include "pdr_context.h" | ||||
| #include "expr_safe_replace.h" | ||||
| #include "ast_util.h" | ||||
| 
 | ||||
| namespace pdr { | ||||
| 
 | ||||
|  | @ -147,7 +148,7 @@ namespace pdr { | |||
|         for (unsigned i = 0; i < fmls.size(); ++i) { | ||||
|             fmls[i] = close_fml(fmls[i].get());             | ||||
|         } | ||||
|         return qe::mk_and(fmls); | ||||
|         return expr_ref(mk_and(fmls), m); | ||||
|     } | ||||
| 
 | ||||
|     expr_ref closure::relax(unsigned i, expr* fml) { | ||||
|  | @ -169,7 +170,7 @@ namespace pdr { | |||
|         for (unsigned i = 0; i < As.size(); ++i) { | ||||
|             fmls.push_back(relax(i, As[i])); | ||||
|         } | ||||
|         B = qe::mk_and(fmls); | ||||
|         B = mk_and(fmls); | ||||
|         return B; | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -45,7 +45,6 @@ Notes: | |||
| #include "smt_value_sort.h" | ||||
| #include "proof_utils.h" | ||||
| #include "dl_boogie_proof.h" | ||||
| #include "qe_util.h" | ||||
| #include "scoped_proof.h" | ||||
| #include "blast_term_ite_tactic.h" | ||||
| #include "model_implicant.h" | ||||
|  |  | |||
|  | @ -201,7 +201,7 @@ namespace pdr { | |||
|                 lits.push_back(extract_consequence(lo, hi)); | ||||
|                 lo = hi; | ||||
|             } | ||||
|             res = qe::mk_or(lits); | ||||
|             res = mk_or(lits); | ||||
|             IF_VERBOSE(2, { if (lits.size() > 1) { verbose_stream() << "combined lemma: " << mk_pp(res, m) << "\n"; } }); | ||||
| #endif | ||||
|         } | ||||
|  | @ -415,6 +415,7 @@ namespace pdr { | |||
|                 return false; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|     }; | ||||
| 
 | ||||
|     class collect_pure_proc { | ||||
|  |  | |||
|  | @ -117,7 +117,7 @@ namespace pdr { | |||
|     void core_farkas_generalizer::operator()(model_node& n, expr_ref_vector& core, bool& uses_level) { | ||||
|         ast_manager& m  = n.pt().get_manager(); | ||||
|         if (core.empty()) return; | ||||
|         expr_ref A(m), B(qe::mk_and(core)), C(m); | ||||
|         expr_ref A(m), B(mk_and(core)), C(m); | ||||
|         expr_ref_vector Bs(m); | ||||
|         flatten_or(B, Bs); | ||||
|         A = n.pt().get_propagation_formula(m_ctx.get_pred_transformers(), n.level()); | ||||
|  | @ -129,13 +129,13 @@ namespace pdr { | |||
|             if (m_farkas_learner.get_lemma_guesses(A, B, lemmas)) { | ||||
|                 TRACE("pdr",  | ||||
|                       tout << "Old core:\n" << mk_pp(B, m) << "\n"; | ||||
|                       tout << "New core:\n" << mk_pp(qe::mk_and(lemmas), m) << "\n";);             | ||||
|                 Bs[i] = qe::mk_and(lemmas); | ||||
|                       tout << "New core:\n" << mk_and(lemmas) << "\n";);             | ||||
|                 Bs[i] = mk_and(lemmas); | ||||
|                 change = true; | ||||
|             } | ||||
|         } | ||||
|         if (change) { | ||||
|             C = qe::mk_or(Bs); | ||||
|             C = mk_or(Bs); | ||||
|             TRACE("pdr", tout << "prop:\n" << mk_pp(A,m) << "\ngen:" << mk_pp(B, m) << "\nto: " << mk_pp(C, m) << "\n";); | ||||
|             core.reset(); | ||||
|             flatten_and(C, core);     | ||||
|  | @ -186,7 +186,7 @@ namespace pdr { | |||
|         }         | ||||
|         closure cl(n.pt(), m_is_closure); | ||||
| 
 | ||||
|         expr_ref fml1 = qe::mk_and(core);         | ||||
|         expr_ref fml1 = mk_and(core);         | ||||
|         expr_ref fml2 = n.pt().get_formulas(n.level(), false); | ||||
|         fml1_2.push_back(fml1); | ||||
|         fml1_2.push_back(0); | ||||
|  | @ -205,7 +205,7 @@ namespace pdr { | |||
|             if (l_false == n.pt().is_reachable(nd, &conv2, uses_level1)) { | ||||
|                 new_cores.push_back(std::make_pair(conv2, uses_level1)); | ||||
|                 change = true; | ||||
|                 expr_ref state1 = qe::mk_and(conv2); | ||||
|                 expr_ref state1 = mk_and(conv2); | ||||
|                 TRACE("pdr",  | ||||
|                       tout << mk_pp(state, m) << "\n"; | ||||
|                       tout << "Generalized to:\n" << mk_pp(state1, m) << "\n";); | ||||
|  | @ -593,7 +593,7 @@ namespace pdr { | |||
|             for (unsigned i = ut_size; i < t_size; i++) { | ||||
|                 conj.push_back(rule.get_tail(i)); | ||||
|             }          | ||||
|             result = qe::mk_and(conj); | ||||
|             result = mk_and(conj); | ||||
|             if (!sub.empty()) { | ||||
|                 expr_ref tmp = result; | ||||
|                 var_subst(m, false)(tmp, sub.size(), sub.c_ptr(), result); | ||||
|  | @ -685,7 +685,7 @@ namespace pdr { | |||
|             for (unsigned i = 0; i < rules.size(); ++i) { | ||||
|                 fmls.push_back(m.mk_not(mk_transition_rule(reps, level, *rules[i])));            | ||||
|             } | ||||
|             fml = qe::mk_and(fmls); | ||||
|             fml = mk_and(fmls); | ||||
|             TRACE("pdr", tout << mk_pp(fml, m) << "\n";); | ||||
|             return fml; | ||||
|         } | ||||
|  | @ -741,7 +741,7 @@ namespace pdr { | |||
|                 }                 | ||||
|             } | ||||
| 
 | ||||
|             expr_ref result = qe::mk_and(conjs); | ||||
|             expr_ref result = mk_and(conjs); | ||||
|             TRACE("pdr", tout << mk_pp(result, m) << "\n";); | ||||
|             return result; | ||||
|         } | ||||
|  |  | |||
|  | @ -6,7 +6,6 @@ Copyright (c) 2015 Microsoft Corporation | |||
| 
 | ||||
| #include "check_relation.h" | ||||
| #include "dl_relation_manager.h" | ||||
| #include "qe_util.h" | ||||
| #include "ast_util.h" | ||||
| #include "smt_kernel.h" | ||||
| #include <typeinfo> | ||||
|  |  | |||
|  | @ -23,7 +23,6 @@ Notes: | |||
| --*/ | ||||
| #include "udoc_relation.h" | ||||
| #include "dl_relation_manager.h" | ||||
| #include "qe_util.h" | ||||
| #include "ast_util.h" | ||||
| #include "smt_kernel.h" | ||||
| 
 | ||||
|  |  | |||
|  | @ -39,6 +39,17 @@ namespace nlsat { | |||
|             m_values.swap(other.m_values); | ||||
|             m_assigned.swap(other.m_assigned); | ||||
|         } | ||||
|         void copy(assignment const& other) { | ||||
|             m_assigned.reset(); | ||||
|             m_assigned.append(other.m_assigned); | ||||
|             m_values.reserve(m_assigned.size(), anum()); | ||||
|             for (unsigned i = 0; i < m_assigned.size(); ++i) { | ||||
|                 if (is_assigned(i)) { | ||||
|                     am().set(m_values[i], other.value(i)); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         void set_core(var x, anum & v) { | ||||
|             m_values.reserve(x+1, anum()); | ||||
|             m_assigned.reserve(x+1, false);  | ||||
|  | @ -52,11 +63,26 @@ namespace nlsat { | |||
|             am().set(m_values[x], v);  | ||||
|         } | ||||
|         void reset(var x) { if (x < m_assigned.size()) m_assigned[x] = false; } | ||||
|         void reset() { m_assigned.reset(); } | ||||
|         bool is_assigned(var x) const { return m_assigned.get(x, false); } | ||||
|         anum const & value(var x) const { return m_values[x]; } | ||||
|         virtual anum_manager & m() const { return am(); } | ||||
|         virtual bool contains(var x) const { return is_assigned(x); } | ||||
|         virtual anum const & operator()(var x) const { SASSERT(is_assigned(x)); return value(x); } | ||||
|         void swap(var x, var y) { | ||||
|             SASSERT(x < m_values.size() && y < m_values.size()); | ||||
|             std::swap(m_assigned[x], m_assigned[y]); | ||||
|             std::swap(m_values[x], m_values[y]); | ||||
|         } | ||||
|         void display(std::ostream& out) const { | ||||
|             for (unsigned i = 0; i < m_assigned.size(); ++i) { | ||||
|                 if (m_assigned[i]) { | ||||
|                     out << "x" << i << " := "; | ||||
|                     m_values.m().display(out, m_values[i]); | ||||
|                     out << "\n"; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
|      | ||||
|     /**
 | ||||
|  |  | |||
|  | @ -111,6 +111,20 @@ namespace nlsat { | |||
|         struct eq_proc { bool operator()(ineq_atom const * a1, ineq_atom const * a2) const; }; | ||||
|     }; | ||||
| 
 | ||||
|     inline std::ostream& operator<<(std::ostream& out, atom::kind k) { | ||||
|         switch (k) { | ||||
|         case atom::kind::EQ: return out << "="; | ||||
|         case atom::kind::LT: return out << "<"; | ||||
|         case atom::kind::ROOT_EQ: return out << "= root"; | ||||
|         case atom::kind::ROOT_LT: return out << "< root"; | ||||
|         case atom::kind::ROOT_LE: return out << "<= root"; | ||||
|         case atom::kind::ROOT_GT: return out << "> root"; | ||||
|         case atom::kind::ROOT_GE: return out << ">= root"; | ||||
|         default: UNREACHABLE(); | ||||
|         } | ||||
|         return out; | ||||
|     } | ||||
| 
 | ||||
|     class root_atom : public atom { | ||||
|         friend class solver; | ||||
|         var      m_x; | ||||
|  |  | |||
|  | @ -60,7 +60,7 @@ class nla2bv_tactic : public tactic { | |||
|         expr_ref_vector             m_trail; | ||||
|         unsigned                    m_num_bits; | ||||
|         unsigned                    m_default_bv_size; | ||||
|         ref<filter_model_converter> m_fmc; | ||||
|         filter_model_converter_ref  m_fmc; | ||||
|          | ||||
|     public: | ||||
|         imp(ast_manager & m, params_ref const& p): | ||||
|  |  | |||
|  | @ -60,7 +60,7 @@ struct bv_size_reduction_tactic::imp { | |||
|     obj_map<app, numeral>     m_unsigned_lowers; | ||||
|     obj_map<app, numeral>     m_unsigned_uppers; | ||||
|     ref<bv_size_reduction_mc> m_mc; | ||||
|     ref<filter_model_converter> m_fmc; | ||||
|     filter_model_converter_ref m_fmc; | ||||
|     scoped_ptr<expr_replacer> m_replacer; | ||||
|     bool                      m_produce_models; | ||||
| 
 | ||||
|  |  | |||
|  | @ -45,6 +45,7 @@ public: | |||
|     bool contains(T1 * t1, T2 * t2) const { return m_set.contains(obj_pair(t1, t2)); } | ||||
|     bool contains(obj_pair const & p) const { return m_set.contains(p); } | ||||
|     void reset() { m_set.reset(); } | ||||
|     bool empty() const { return m_set.empty(); } | ||||
| }; | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -69,6 +69,7 @@ void small_object_allocator::reset() { | |||
| #define MASK ((1 << PTR_ALIGNMENT) - 1) | ||||
| 
 | ||||
| void small_object_allocator::deallocate(size_t size, void * p) { | ||||
|     if (size == 0) return; | ||||
| #if defined(Z3DEBUG) && !defined(_WINDOWS) | ||||
|     // Valgrind friendly
 | ||||
|     memory::deallocate(p); | ||||
|  | @ -91,6 +92,7 @@ void small_object_allocator::deallocate(size_t size, void * p) { | |||
| } | ||||
| 
 | ||||
| void * small_object_allocator::allocate(size_t size) { | ||||
|     if (size == 0) return 0; | ||||
| #if defined(Z3DEBUG) && !defined(_WINDOWS) | ||||
|     // Valgrind friendly
 | ||||
|     return memory::allocate(size); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue