3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-13 12:28:44 +00:00

Add mk_algebraic method

Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2013-01-10 11:13:21 -08:00
parent 872165fa55
commit 4a0b431cf4
2 changed files with 74 additions and 11 deletions

View file

@ -275,15 +275,15 @@ namespace realclosure {
struct algebraic : public extension {
polynomial m_p;
sign_det * m_sign_det; //!< != 0 if m_interval constains more than one root of m_p.
unsigned m_idx; //!< != UINT_MAX if m_sign_det != 0, in this case m_idx < m_sign_det->m_sign_conditions.size()
unsigned m_sdt_idx; //!< != UINT_MAX if m_sign_det != 0, in this case m_sdt_idx < m_sign_det->m_sign_conditions.size()
bool m_real; //!< True if the polynomial p does not depend on infinitesimal extensions.
algebraic(unsigned idx):extension(ALGEBRAIC, idx), m_sign_det(0), m_idx(0), m_real(false) {}
algebraic(unsigned idx):extension(ALGEBRAIC, idx), m_sign_det(0), m_sdt_idx(0), m_real(false) {}
polynomial const & p() const { return m_p; }
bool is_real() const { return m_real; }
sign_det * sdt() const { return m_sign_det; }
unsigned sdt_idx() const { return m_idx; }
unsigned sdt_idx() const { return m_sdt_idx; }
};
struct transcendental : public extension {
@ -445,6 +445,7 @@ namespace realclosure {
m_scs.append(scs.m_scs.size(), scs.m_scs.c_ptr());
scs.release();
}
sign_condition * const * c_ptr() { return m_scs.c_ptr(); }
};
imp(unsynch_mpq_manager & qm, params_ref const & p, small_object_allocator * a):
@ -639,6 +640,11 @@ namespace realclosure {
cleanup(extension::INFINITESIMAL);
return m_extensions[extension::INFINITESIMAL].size();
}
unsigned next_algebraic_idx() {
cleanup(extension::ALGEBRAIC);
return m_extensions[extension::ALGEBRAIC].size();
}
void set_cancel(bool f) {
m_cancel = f;
@ -1620,6 +1626,53 @@ namespace realclosure {
return false;
}
/**
\brief Store the polynomials in prs into the array of polynomials ps.
*/
void set_array_p(array<polynomial> & ps, scoped_polynomial_seq const & prs) {
unsigned sz = prs.size();
ps.set(allocator(), sz, polynomial());
for (unsigned i = 0; i < sz; i++) {
unsigned pi_sz = prs.size(i);
value * const * pi = prs.coeffs(i);
set_p(ps[i], pi_sz, pi);
}
}
/**
\brief Create a "sign determination" data-structure for an algebraic extension.
The new object will assume the ownership of the elements stored in M and scs.
M and scs will be empty after this operation.
*/
sign_det * mk_sign_det(mpz_matrix & M, scoped_polynomial_seq const & prs, scoped_polynomial_seq const & qs, scoped_sign_conditions & scs) {
sign_det * r = new (allocator()) sign_det();
r->M.swap(M);
set_array_p(r->m_prs, prs);
set_array_p(r->m_qs, qs);
r->m_sign_conditions.set(allocator(), scs.size(), scs.c_ptr());
scs.release();
return r;
}
/**
\brief Create a new algebraic extension
*/
algebraic * mk_algebraic(unsigned p_sz, value * const * p, mpbqi const & interval, sign_det * sd, unsigned sdt_idx) {
unsigned idx = next_algebraic_idx();
algebraic * r = new (allocator()) algebraic(idx);
m_extensions[extension::ALGEBRAIC].push_back(r);
set_p(r->m_p, p_sz, p);
set_interval(r->m_interval, interval);
r->m_sign_det = sd;
inc_ref_sign_det(sd);
r->m_sdt_idx = sdt_idx;
r->m_real = is_real(p_sz, p);
return r;
}
/**
\brief Isolate roots of p in the given interval using sign conditions to distinguish between them.
We need this method when the polynomial contains roots that are infinitesimally close to each other.
@ -1834,12 +1887,14 @@ namespace realclosure {
for (unsigned j = 0; j < prs.size(); j++) {
display_poly(tout, prs.size(j), prs.coeffs(j)); tout << "\n";
});
// TODO: create the extension objects using
// M_s, prs, scs, qs
// Remark: scs and qs are only for pretty printing
// For determining the signs of other polynomials in the new extension objects,
// we only need M_s and prs
SASSERT(M_s.n() == M_s.m()); SASSERT(M_s.n() == static_cast<unsigned>(num_roots));
sign_det * sd = mk_sign_det(M_s, prs, qs, scs);
for (unsigned idx = 0; idx < static_cast<unsigned>(num_roots); idx++) {
algebraic * a = mk_algebraic(p_sz, p, interval, sd, idx);
numeral r;
set(r, mk_rational_function_value(a));
roots.push_back(r);
}
}
/**

View file

@ -53,11 +53,11 @@ private:
set_data(mem, sz);
}
void init() {
void init(T const & v) {
iterator it = begin();
iterator e = end();
for (; it != e; ++it) {
new (it) T();
new (it) T(v);
}
}
@ -140,6 +140,13 @@ public:
init(vs);
}
template<typename Allocator>
void set(Allocator & a, size_t sz, T const & v = T()) {
SASSERT(m_data == 0);
allocate(a, sz);
init(v);
}
size_t size() const {
if (m_data == 0) {
return 0;
@ -181,6 +188,7 @@ public:
void swap(array & other) {
std::swap(m_data, other.m_data);
}
};
template<typename T>