mirror of
				https://github.com/Z3Prover/z3
				synced 2025-10-31 03:32:28 +00:00 
			
		
		
		
	Extract defining components of algebraic number via C and C++ API (#3321)
* First steps toward adding Julia bindings * Simplifications * Streamlining * Friends of tactic and probe * Add missing functions * Update azure-pipelines.yml for Azure Pipelines * Update azure-pipelines.yml for Azure Pipelines * Update azure-pipelines.yml for Azure Pipelines * Update azure-pipelines.yml for Azure Pipelines * Changes for CxxWrap v0.9.0 * Wrap enumeration and tuple sort * Wrap z3::fixedpoint * Wrap z3::optimize * Wrap missing functions * Fix aux types * Add some missing functions * Revert "Update azure-pipelines.yml for Azure Pipelines" This reverts commit5aab9f9240. * Revert "Update azure-pipelines.yml for Azure Pipelines" This reverts commitcfccd7ca2c. * Revert "Update azure-pipelines.yml for Azure Pipelines" This reverts commitf24740c595. * Revert "Update azure-pipelines.yml for Azure Pipelines" This reverts commit592499eaa0. * Checkout current version of pipeline * Build Julia bindings on macOS * Extract components of algebraic number * Add type to C API function name * Remove blank line * Typo in doc * Return Z3_ast_vector containing coefficients
This commit is contained in:
		
							parent
							
								
									1c5283f3a4
								
							
						
					
					
						commit
						de9bc930e9
					
				
					 6 changed files with 160 additions and 72 deletions
				
			
		|  | @ -418,4 +418,36 @@ extern "C" { | |||
|         Z3_CATCH_RETURN(0); | ||||
|     } | ||||
| 
 | ||||
|     Z3_ast_vector Z3_API Z3_algebraic_get_poly(Z3_context c, Z3_ast a) { | ||||
|         Z3_TRY; | ||||
|         LOG_Z3_algebraic_get_poly(c, a); | ||||
|         RESET_ERROR_CODE(); | ||||
|         CHECK_IS_ALGEBRAIC(a, 0); | ||||
|         algebraic_numbers::manager & _am = am(c); | ||||
|         algebraic_numbers::anum const & av = get_irrational(c, a); | ||||
|         scoped_mpz_vector coeffs(_am.qm()); | ||||
|         _am.get_polynomial(av, coeffs); | ||||
|         api::context * _c = mk_c(c); | ||||
|         sort * s = _c->m().mk_sort(_c->get_arith_fid(), REAL_SORT); | ||||
|         Z3_ast_vector_ref* result = alloc(Z3_ast_vector_ref, *_c, _c->m()); | ||||
|         mk_c(c)->save_object(result); | ||||
|         for (unsigned i = 0; i < coeffs.size(); i++) { | ||||
|             rational r(coeffs[i]); | ||||
|             expr * a = _c->mk_numeral_core(r, s); | ||||
|             result->m_ast_vector.push_back(a); | ||||
|         } | ||||
|         RETURN_Z3(of_ast_vector(result)); | ||||
|         Z3_CATCH_RETURN(nullptr); | ||||
|     } | ||||
| 
 | ||||
|     unsigned Z3_API Z3_algebraic_get_i(Z3_context c, Z3_ast a) { | ||||
|         Z3_TRY; | ||||
|         LOG_Z3_algebraic_get_i(c, a); | ||||
|         RESET_ERROR_CODE(); | ||||
|         CHECK_IS_ALGEBRAIC(a, 0); | ||||
|         algebraic_numbers::manager & _am = am(c); | ||||
|         algebraic_numbers::anum const & av = get_irrational(c, a); | ||||
|         return _am.get_i(av); | ||||
|         Z3_CATCH_RETURN(0); | ||||
|     } | ||||
| }; | ||||
|  |  | |||
|  | @ -66,6 +66,7 @@ namespace z3 { | |||
|     class func_entry; | ||||
|     class statistics; | ||||
|     class apply_result; | ||||
|     template<typename T> class cast_ast; | ||||
|     template<typename T> class ast_vector_tpl; | ||||
|     typedef ast_vector_tpl<ast>       ast_vector; | ||||
|     typedef ast_vector_tpl<expr>      expr_vector; | ||||
|  | @ -511,6 +512,74 @@ namespace z3 { | |||
| 
 | ||||
|     inline bool eq(ast const & a, ast const & b) { return Z3_is_eq_ast(a.ctx(), a, b); } | ||||
| 
 | ||||
|     template<typename T> | ||||
|     class ast_vector_tpl : public object { | ||||
|         Z3_ast_vector m_vector; | ||||
|         void init(Z3_ast_vector v) { Z3_ast_vector_inc_ref(ctx(), v); m_vector = v; } | ||||
|     public: | ||||
|         ast_vector_tpl(context & c):object(c) { init(Z3_mk_ast_vector(c)); } | ||||
|         ast_vector_tpl(context & c, Z3_ast_vector v):object(c) { init(v); } | ||||
|         ast_vector_tpl(ast_vector_tpl const & s):object(s), m_vector(s.m_vector) { Z3_ast_vector_inc_ref(ctx(), m_vector); } | ||||
|         ast_vector_tpl(context& c, ast_vector_tpl const& src): object(c) { init(Z3_ast_vector_translate(src.ctx(), src, c)); } | ||||
| 
 | ||||
|         ~ast_vector_tpl() { Z3_ast_vector_dec_ref(ctx(), m_vector); } | ||||
|         operator Z3_ast_vector() const { return m_vector; } | ||||
|         unsigned size() const { return Z3_ast_vector_size(ctx(), m_vector); } | ||||
|         T operator[](int i) const { assert(0 <= i); Z3_ast r = Z3_ast_vector_get(ctx(), m_vector, i); check_error(); return cast_ast<T>()(ctx(), r); } | ||||
|         void push_back(T const & e) { Z3_ast_vector_push(ctx(), m_vector, e); check_error(); } | ||||
|         void resize(unsigned sz) { Z3_ast_vector_resize(ctx(), m_vector, sz); check_error(); } | ||||
|         T back() const { return operator[](size() - 1); } | ||||
|         void pop_back() { assert(size() > 0); resize(size() - 1); } | ||||
|         bool empty() const { return size() == 0; } | ||||
|         ast_vector_tpl & operator=(ast_vector_tpl const & s) { | ||||
|             Z3_ast_vector_inc_ref(s.ctx(), s.m_vector); | ||||
|             Z3_ast_vector_dec_ref(ctx(), m_vector); | ||||
|             m_ctx = s.m_ctx; | ||||
|             m_vector = s.m_vector; | ||||
|             return *this; | ||||
|         } | ||||
|         ast_vector_tpl& set(unsigned idx, ast& a) { | ||||
|             Z3_ast_vector_set(ctx(), m_vector, idx, a); | ||||
|             return *this; | ||||
|         } | ||||
|         /*
 | ||||
|           Disabled pending C++98 build upgrade | ||||
|         bool contains(T const& x) const { | ||||
|             for (T y : *this) if (eq(x, y)) return true; | ||||
|             return false; | ||||
|         } | ||||
|         */ | ||||
| 
 | ||||
|         class iterator { | ||||
|             ast_vector_tpl const* m_vector; | ||||
|             unsigned m_index; | ||||
|         public: | ||||
|             iterator(ast_vector_tpl const* v, unsigned i): m_vector(v), m_index(i) {} | ||||
|             iterator(iterator const& other): m_vector(other.m_vector), m_index(other.m_index) {} | ||||
|             iterator operator=(iterator const& other) { m_vector = other.m_vector; m_index = other.m_index; return *this; } | ||||
| 
 | ||||
|             bool operator==(iterator const& other) const { | ||||
|                 return other.m_index == m_index; | ||||
|             }; | ||||
|             bool operator!=(iterator const& other) const { | ||||
|                 return other.m_index != m_index; | ||||
|             }; | ||||
|             iterator& operator++() { | ||||
|                 ++m_index; | ||||
|                 return *this; | ||||
|             } | ||||
|             void set(T& arg) { | ||||
|                 Z3_ast_vector_set(m_vector->ctx(), *m_vector, m_index, arg); | ||||
|             } | ||||
|             iterator operator++(int) { iterator tmp = *this; ++m_index; return tmp; } | ||||
|             T * operator->() const { return &(operator*()); } | ||||
|             T operator*() const { return (*m_vector)[m_index]; } | ||||
|         }; | ||||
|         iterator begin() const { return iterator(this, 0); } | ||||
|         iterator end() const { return iterator(this, size()); } | ||||
|         friend std::ostream & operator<<(std::ostream & out, ast_vector_tpl const & v) { out << Z3_ast_vector_to_string(v.ctx(), v); return out; } | ||||
|     }; | ||||
| 
 | ||||
| 
 | ||||
|     /**
 | ||||
|        \brief A Z3 sort (aka type). Every expression (i.e., formula or term) in Z3 has a sort. | ||||
|  | @ -665,7 +734,6 @@ namespace z3 { | |||
|        \brief A Z3 expression is used to represent formulas and terms. For Z3, a formula is any expression of sort Boolean. | ||||
|        Every expression has a sort. | ||||
|     */ | ||||
| 
 | ||||
|     class expr : public ast { | ||||
|     public: | ||||
|         expr(context & c):ast(c) {} | ||||
|  | @ -815,6 +883,25 @@ namespace z3 { | |||
|             return expr(ctx(), r); | ||||
|         } | ||||
|          | ||||
|         /**
 | ||||
|            \brief Return coefficients for p of an algebraic number (root-obj p i) | ||||
|          */ | ||||
|         expr_vector algebraic_poly() const { | ||||
|             assert(is_algebraic()); | ||||
|             Z3_ast_vector r = Z3_algebraic_get_poly(ctx(), m_ast); | ||||
|             check_error(); | ||||
|             return expr_vector(ctx(), r); | ||||
|         } | ||||
| 
 | ||||
|         /**
 | ||||
|            \brief Return i of an algebraic number (root-obj p i) | ||||
|          */ | ||||
|         unsigned algebraic_i() const { | ||||
|             assert(is_algebraic()); | ||||
|             unsigned i = Z3_algebraic_get_i(ctx(), m_ast); | ||||
|             check_error(); | ||||
|             return i; | ||||
|         } | ||||
| 
 | ||||
|         /**
 | ||||
|            \brief retrieve unique identifier for expression. | ||||
|  | @ -1848,8 +1935,6 @@ namespace z3 { | |||
|         return to_func_decl(a.ctx(), Z3_mk_tree_order(a.ctx(), a, index)); | ||||
|     } | ||||
| 
 | ||||
|     template<typename T> class cast_ast; | ||||
| 
 | ||||
|     template<> class cast_ast<ast> { | ||||
|     public: | ||||
|         ast operator()(context & c, Z3_ast a) { return ast(c, a); } | ||||
|  | @ -1882,75 +1967,6 @@ namespace z3 { | |||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     template<typename T> | ||||
|     class ast_vector_tpl : public object { | ||||
|         Z3_ast_vector m_vector; | ||||
|         void init(Z3_ast_vector v) { Z3_ast_vector_inc_ref(ctx(), v); m_vector = v; } | ||||
|     public: | ||||
|         ast_vector_tpl(context & c):object(c) { init(Z3_mk_ast_vector(c)); } | ||||
|         ast_vector_tpl(context & c, Z3_ast_vector v):object(c) { init(v); } | ||||
|         ast_vector_tpl(ast_vector_tpl const & s):object(s), m_vector(s.m_vector) { Z3_ast_vector_inc_ref(ctx(), m_vector); } | ||||
|         ast_vector_tpl(context& c, ast_vector_tpl const& src): object(c) { init(Z3_ast_vector_translate(src.ctx(), src, c)); } | ||||
| 
 | ||||
|         ~ast_vector_tpl() { Z3_ast_vector_dec_ref(ctx(), m_vector); } | ||||
|         operator Z3_ast_vector() const { return m_vector; } | ||||
|         unsigned size() const { return Z3_ast_vector_size(ctx(), m_vector); } | ||||
|         T operator[](int i) const { assert(0 <= i); Z3_ast r = Z3_ast_vector_get(ctx(), m_vector, i); check_error(); return cast_ast<T>()(ctx(), r); } | ||||
|         void push_back(T const & e) { Z3_ast_vector_push(ctx(), m_vector, e); check_error(); } | ||||
|         void resize(unsigned sz) { Z3_ast_vector_resize(ctx(), m_vector, sz); check_error(); } | ||||
|         T back() const { return operator[](size() - 1); } | ||||
|         void pop_back() { assert(size() > 0); resize(size() - 1); } | ||||
|         bool empty() const { return size() == 0; } | ||||
|         ast_vector_tpl & operator=(ast_vector_tpl const & s) { | ||||
|             Z3_ast_vector_inc_ref(s.ctx(), s.m_vector); | ||||
|             Z3_ast_vector_dec_ref(ctx(), m_vector); | ||||
|             m_ctx = s.m_ctx; | ||||
|             m_vector = s.m_vector; | ||||
|             return *this; | ||||
|         } | ||||
|         ast_vector_tpl& set(unsigned idx, ast& a) { | ||||
|             Z3_ast_vector_set(ctx(), m_vector, idx, a); | ||||
|             return *this; | ||||
|         } | ||||
|         /*
 | ||||
|           Disabled pending C++98 build upgrade | ||||
|         bool contains(T const& x) const { | ||||
|             for (T y : *this) if (eq(x, y)) return true; | ||||
|             return false; | ||||
|         } | ||||
|         */ | ||||
| 
 | ||||
|         class iterator { | ||||
|             ast_vector_tpl const* m_vector; | ||||
|             unsigned m_index; | ||||
|         public: | ||||
|             iterator(ast_vector_tpl const* v, unsigned i): m_vector(v), m_index(i) {} | ||||
|             iterator(iterator const& other): m_vector(other.m_vector), m_index(other.m_index) {} | ||||
|             iterator operator=(iterator const& other) { m_vector = other.m_vector; m_index = other.m_index; return *this; } | ||||
| 
 | ||||
|             bool operator==(iterator const& other) const { | ||||
|                 return other.m_index == m_index; | ||||
|             }; | ||||
|             bool operator!=(iterator const& other) const { | ||||
|                 return other.m_index != m_index; | ||||
|             }; | ||||
|             iterator& operator++() { | ||||
|                 ++m_index; | ||||
|                 return *this; | ||||
|             } | ||||
|             void set(T& arg) { | ||||
|                 Z3_ast_vector_set(m_vector->ctx(), *m_vector, m_index, arg); | ||||
|             } | ||||
|             iterator operator++(int) { iterator tmp = *this; ++m_index; return tmp; } | ||||
|             T * operator->() const { return &(operator*()); } | ||||
|             T operator*() const { return (*m_vector)[m_index]; } | ||||
|         }; | ||||
|         iterator begin() const { return iterator(this, 0); } | ||||
|         iterator end() const { return iterator(this, size()); } | ||||
|         friend std::ostream & operator<<(std::ostream & out, ast_vector_tpl const & v) { out << Z3_ast_vector_to_string(v.ctx(), v); return out; } | ||||
|     }; | ||||
| 
 | ||||
| 
 | ||||
|     template<typename T> | ||||
|     template<typename T2> | ||||
|     array<T>::array(ast_vector_tpl<T2> const & v) { | ||||
|  |  | |||
|  | @ -203,6 +203,10 @@ JLCXX_MODULE define_julia_module(jlcxx::Module &m) | |||
|         .MM(expr, is_well_sorted) | ||||
|         .MM(expr, get_decimal_string) | ||||
|         .MM(expr, id) | ||||
|         .MM(expr, algebraic_lower) | ||||
|         .MM(expr, algebraic_upper) | ||||
|         .MM(expr, algebraic_poly) | ||||
|         .MM(expr, algebraic_i) | ||||
|         .MM(expr, get_numeral_int) | ||||
|         .MM(expr, get_numeral_uint) | ||||
|         .MM(expr, get_numeral_int64) | ||||
|  |  | |||
|  | @ -223,6 +223,24 @@ extern "C" { | |||
|     */ | ||||
|     int Z3_API Z3_algebraic_eval(Z3_context c, Z3_ast p, unsigned n, Z3_ast a[]); | ||||
| 
 | ||||
|     /**
 | ||||
|        \brief Return the coefficients of the defining polynomial. | ||||
| 
 | ||||
|        \pre Z3_algebraic_is_value(c, a) | ||||
| 
 | ||||
|        def_API('Z3_algebraic_get_poly', AST_VECTOR, (_in(CONTEXT), _in(AST))) | ||||
|     */ | ||||
|     Z3_ast_vector Z3_API Z3_algebraic_get_poly(Z3_context c, Z3_ast a); | ||||
| 
 | ||||
|     /**
 | ||||
|        \brief Return which root of the polynomial the algebraic number represents. | ||||
| 
 | ||||
|        \pre Z3_algebraic_is_value(c, a) | ||||
| 
 | ||||
|        def_API('Z3_algebraic_get_i', UINT, (_in(CONTEXT), _in(AST))) | ||||
|     */ | ||||
|     unsigned Z3_API Z3_algebraic_get_i(Z3_context c, Z3_ast a); | ||||
| 
 | ||||
|     /*@}*/ | ||||
|     /*@}*/ | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue