mirror of
https://github.com/Z3Prover/z3
synced 2025-04-15 13:28:47 +00:00
Simplify data-structures
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
14827e94f0
commit
322d355290
|
@ -93,6 +93,8 @@ namespace realclosure {
|
||||||
numeral const & upper() const { return m_upper; }
|
numeral const & upper() const { return m_upper; }
|
||||||
bool lower_is_inf() const { return m_lower_inf; }
|
bool lower_is_inf() const { return m_lower_inf; }
|
||||||
bool upper_is_inf() const { return m_upper_inf; }
|
bool upper_is_inf() const { return m_upper_inf; }
|
||||||
|
bool lower_is_open() const { return m_lower_open; }
|
||||||
|
bool upper_is_open() const { return m_upper_open; }
|
||||||
};
|
};
|
||||||
|
|
||||||
void set_rounding(bool to_plus_inf) { m_manager.m_to_plus_inf = to_plus_inf; }
|
void set_rounding(bool to_plus_inf) { m_manager.m_to_plus_inf = to_plus_inf; }
|
||||||
|
@ -149,6 +151,7 @@ namespace realclosure {
|
||||||
value(bool rat):m_ref_count(0), m_rational(rat) {}
|
value(bool rat):m_ref_count(0), m_rational(rat) {}
|
||||||
bool is_rational() const { return m_rational; }
|
bool is_rational() const { return m_rational; }
|
||||||
mpbqi const & interval() const { return m_interval; }
|
mpbqi const & interval() const { return m_interval; }
|
||||||
|
mpbqi & interval() { return m_interval; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rational_value : public value {
|
struct rational_value : public value {
|
||||||
|
@ -160,52 +163,22 @@ namespace realclosure {
|
||||||
|
|
||||||
struct extension;
|
struct extension;
|
||||||
bool rank_lt(extension * r1, extension * r2);
|
bool rank_lt(extension * r1, extension * r2);
|
||||||
|
|
||||||
struct polynomial_expr {
|
|
||||||
// The values occurring in this polynomial m_p may only contain extensions that are smaller than m_ext.
|
|
||||||
// The polynomial m_p must not be the constant polynomial on m_ext. That is,
|
|
||||||
// it contains a nonzero coefficient at position k > 0. It is not a constant polynomial on m_ext.
|
|
||||||
polynomial m_p;
|
|
||||||
extension * m_ext;
|
|
||||||
bool m_real; //!< True if the polynomial expression does not depend on infinitesimal values
|
|
||||||
mpbqi m_interval; //!< approximation as an interval with binary rational end-points
|
|
||||||
polynomial_expr():m_ext(0), m_real(false) {}
|
|
||||||
extension * ext() const { return m_ext; }
|
|
||||||
bool is_real() const { return m_real; }
|
|
||||||
polynomial const & p() const { return m_p; }
|
|
||||||
mpbqi const & interval() const { return m_interval; }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct rational_function_value : public value {
|
struct rational_function_value : public value {
|
||||||
// We assume that a null polynomial_expr denotes 1.
|
polynomial m_numerator;
|
||||||
// m_numerator OR m_denominator must be different from NULL
|
polynomial m_denominator;
|
||||||
polynomial_expr * m_numerator;
|
extension * m_ext;
|
||||||
polynomial_expr * m_denominator;
|
bool m_real; //!< True if the polynomial expression does not depend on infinitesimal values.
|
||||||
|
rational_function_value(extension * ext):value(false), m_ext(ext), m_real(false) {}
|
||||||
|
|
||||||
polynomial_expr * num() const { return m_numerator; }
|
polynomial const & num() const { return m_numerator; }
|
||||||
polynomial_expr * den() const { return m_denominator; }
|
polynomial & num() { return m_numerator; }
|
||||||
|
polynomial const & den() const { return m_denominator; }
|
||||||
rational_function_value(polynomial_expr * num, polynomial_expr * den):value(false), m_numerator(num), m_denominator(den) {
|
polynomial & den() { return m_denominator; }
|
||||||
SASSERT(num != 0 || den != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
extension * ext() const {
|
extension * ext() const { return m_ext; }
|
||||||
if (den() == 0)
|
bool is_real() const { return m_real; }
|
||||||
return num()->ext();
|
void set_real(bool f) { m_real = f; }
|
||||||
else if (num() == 0 || rank_lt(num()->ext(), den()->ext()))
|
|
||||||
return den()->ext();
|
|
||||||
else
|
|
||||||
return num()->ext();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_real() const {
|
|
||||||
if (den() == 0)
|
|
||||||
return num()->is_real();
|
|
||||||
else if (num() == 0)
|
|
||||||
return den()->is_real();
|
|
||||||
else
|
|
||||||
return num()->is_real() && den()->is_real();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef ptr_vector<value> value_vector;
|
typedef ptr_vector<value> value_vector;
|
||||||
|
@ -244,6 +217,7 @@ namespace realclosure {
|
||||||
bool is_transcendental() const { return knd() == TRANSCENDENTAL; }
|
bool is_transcendental() const { return knd() == TRANSCENDENTAL; }
|
||||||
|
|
||||||
mpbqi const & interval() const { return m_interval; }
|
mpbqi const & interval() const { return m_interval; }
|
||||||
|
mpbqi & interval() { return m_interval; }
|
||||||
};
|
};
|
||||||
|
|
||||||
bool rank_lt(extension * r1, extension * r2) {
|
bool rank_lt(extension * r1, extension * r2) {
|
||||||
|
@ -417,18 +391,15 @@ namespace realclosure {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
void finalize_polynomial(polynomial & p) {
|
/**
|
||||||
|
\brief Reset the given polynomial.
|
||||||
|
That is, after the call p is the 0 polynomial.
|
||||||
|
*/
|
||||||
|
void reset_p(polynomial & p) {
|
||||||
dec_ref(p.size(), p.c_ptr());
|
dec_ref(p.size(), p.c_ptr());
|
||||||
p.finalize(allocator());
|
p.finalize(allocator());
|
||||||
}
|
}
|
||||||
|
|
||||||
void del_polynomial_expr(polynomial_expr * p) {
|
|
||||||
finalize_polynomial(p->m_p);
|
|
||||||
bqim().del(p->m_interval);
|
|
||||||
dec_ref_ext(p->m_ext);
|
|
||||||
allocator().deallocate(sizeof(polynomial_expr), p);
|
|
||||||
}
|
|
||||||
|
|
||||||
void del_rational(rational_value * v) {
|
void del_rational(rational_value * v) {
|
||||||
bqim().del(v->m_interval);
|
bqim().del(v->m_interval);
|
||||||
qm().del(v->m_value);
|
qm().del(v->m_value);
|
||||||
|
@ -437,10 +408,9 @@ namespace realclosure {
|
||||||
|
|
||||||
void del_rational_function(rational_function_value * v) {
|
void del_rational_function(rational_function_value * v) {
|
||||||
bqim().del(v->m_interval);
|
bqim().del(v->m_interval);
|
||||||
if (v->num())
|
reset_p(v->num());
|
||||||
del_polynomial_expr(v->num());
|
reset_p(v->den());
|
||||||
if (v->den())
|
dec_ref_ext(v->ext());
|
||||||
del_polynomial_expr(v->den());
|
|
||||||
allocator().deallocate(sizeof(rational_function_value), v);
|
allocator().deallocate(sizeof(rational_function_value), v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,11 +422,11 @@ namespace realclosure {
|
||||||
}
|
}
|
||||||
|
|
||||||
void del_algebraic(algebraic * a) {
|
void del_algebraic(algebraic * a) {
|
||||||
finalize_polynomial(a->m_p);
|
reset_p(a->m_p);
|
||||||
bqim().del(a->m_interval);
|
bqim().del(a->m_interval);
|
||||||
unsigned sz = a->m_signs.size();
|
unsigned sz = a->m_signs.size();
|
||||||
for (unsigned i = 0; i < sz; i++) {
|
for (unsigned i = 0; i < sz; i++) {
|
||||||
finalize_polynomial(a->m_signs[i].first);
|
reset_p(a->m_signs[i].first);
|
||||||
}
|
}
|
||||||
allocator().deallocate(sizeof(algebraic), a);
|
allocator().deallocate(sizeof(algebraic), a);
|
||||||
}
|
}
|
||||||
|
@ -544,13 +514,22 @@ namespace realclosure {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Return true if v is one.
|
\brief Return true if v is represented as rational value one.
|
||||||
*/
|
*/
|
||||||
bool is_one(value * v) const {
|
bool is_rational_one(value * v) const {
|
||||||
// TODO: make the check complete
|
|
||||||
return !is_zero(v) && is_nz_rational(v) && qm().is_one(to_mpq(v));
|
return !is_zero(v) && is_nz_rational(v) && qm().is_one(to_mpq(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Return true if v is the value one;
|
||||||
|
*/
|
||||||
|
bool is_one(value * v) const {
|
||||||
|
if (is_rational_one(v))
|
||||||
|
return true;
|
||||||
|
// TODO: check if v is equal to one.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Return true if v is a represented as a rational function of the set of field extensions.
|
\brief Return true if v is a represented as a rational function of the set of field extensions.
|
||||||
*/
|
*/
|
||||||
|
@ -651,7 +630,22 @@ namespace realclosure {
|
||||||
SASSERT(ext->is_algebraic());
|
SASSERT(ext->is_algebraic());
|
||||||
return static_cast<algebraic*>(ext);
|
return static_cast<algebraic*>(ext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Return True if the given extension is a Real value.
|
||||||
|
The result is approximate for algebraic extensions.
|
||||||
|
For algebraic extensions, we have
|
||||||
|
- true result is always correct (i.e., the extension is really a real value)
|
||||||
|
- false result is approximate (i.e., the extension may be a real value although it is a root of a polynomial that contains non-real coefficients)
|
||||||
|
Example: Assume eps is an infinitesimal, and pi is 3.14... .
|
||||||
|
Assume also that ext is the unique root between (3, 4) of the following polynomial:
|
||||||
|
x^2 - (pi + eps)*x + pi*ext
|
||||||
|
Thus, x is pi, but the system will return false, since its defining polynomial has infinitesimal
|
||||||
|
coefficients. In the future, to make everything precise, we should be able to factor the polynomial
|
||||||
|
above as
|
||||||
|
(x - eps)*(x - pi)
|
||||||
|
and then detect that x is actually the root of (x - pi).
|
||||||
|
*/
|
||||||
bool is_real(extension * ext) {
|
bool is_real(extension * ext) {
|
||||||
switch (ext->knd()) {
|
switch (ext->knd()) {
|
||||||
case extension::TRANSCENDENTAL: return true;
|
case extension::TRANSCENDENTAL: return true;
|
||||||
|
@ -663,48 +657,113 @@ namespace realclosure {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
polynomial_expr * mk_polynomial_expr(unsigned sz, value * const * p, extension * ext, mpbqi & interval) {
|
/**
|
||||||
SASSERT(sz > 1);
|
\brief Return true if v is definitely a real value.
|
||||||
SASSERT(p[sz-1] != 0);
|
*/
|
||||||
polynomial_expr * r = new (allocator()) polynomial_expr();
|
bool is_real(value * v) {
|
||||||
r->m_p.set(allocator(), sz, p);
|
if (v->is_rational())
|
||||||
inc_ref(sz, p);
|
return true;
|
||||||
inc_ref_ext(ext);
|
else
|
||||||
r->m_ext = ext;
|
return to_rational_function(v)->is_real();
|
||||||
realclosure::swap(r->m_interval, interval);
|
}
|
||||||
r->m_real = is_real(ext);
|
|
||||||
for (unsigned i = 0; i < sz && r->m_real; i++) {
|
bool is_real(unsigned sz, value * const * p) {
|
||||||
|
for (unsigned i = 0; i < sz; i++)
|
||||||
if (!is_real(p[i]))
|
if (!is_real(p[i]))
|
||||||
r->m_real = false;
|
return false;
|
||||||
}
|
return true;
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void updt_interval(rational_function_value & v) {
|
/**
|
||||||
if (v.den() == 0) {
|
\brief Set the polynomial p with the given coefficients as[0], ..., as[n-1]
|
||||||
bqim().set(v.m_interval, v.num()->interval());
|
*/
|
||||||
}
|
void set_p(polynomial & p, unsigned n, value * const * as) {
|
||||||
else if (v.num() == 0) {
|
SASSERT(n > 0);
|
||||||
bqim().inv(v.den()->interval(), v.m_interval);
|
SASSERT(!is_zero(as[n - 1]));
|
||||||
}
|
reset_p(p);
|
||||||
else {
|
p.set(allocator(), n, as);
|
||||||
bqim().div(v.num()->interval(), v.den()->interval(), v.m_interval);
|
inc_ref(n, as);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set the polynomial p as the constant polynomial 1.
|
||||||
|
*/
|
||||||
|
void set_p_one(polynomial & p) {
|
||||||
|
set_p(p, 1, &m_one);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set the lower bound of the given interval.
|
||||||
|
*/
|
||||||
|
void set_lower_core(mpbqi & a, mpbq const & k, bool open, bool inf) {
|
||||||
|
bqm().set(a.lower(), k);
|
||||||
|
a.set_lower_is_open(open);
|
||||||
|
a.set_lower_is_inf(inf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief a.lower <- k
|
||||||
|
*/
|
||||||
|
void set_lower(mpbqi & a, mpbq const & k, bool open = true) {
|
||||||
|
set_lower_core(a, k, open, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set the upper bound of the given interval.
|
||||||
|
*/
|
||||||
|
void set_upper_core(mpbqi & a, mpbq const & k, bool open, bool inf) {
|
||||||
|
bqm().set(a.upper(), k);
|
||||||
|
a.set_upper_is_open(open);
|
||||||
|
a.set_upper_is_inf(inf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief a.upper <- k
|
||||||
|
*/
|
||||||
|
void set_upper(mpbqi & a, mpbq const & k, bool open = true) {
|
||||||
|
set_upper_core(a, k, open, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief a <- b
|
||||||
|
*/
|
||||||
|
void set_interval(mpbqi & a, mpbqi const & b) {
|
||||||
|
set_lower_core(a, b.lower(), b.lower_is_open(), b.lower_is_inf());
|
||||||
|
set_upper_core(a, b.upper(), b.upper_is_open(), b.upper_is_inf());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Create a value using the given extension.
|
||||||
|
*/
|
||||||
|
rational_function_value * mk_value(extension * ext) {
|
||||||
|
rational_function_value * v = alloc(rational_function_value, ext);
|
||||||
|
inc_ref_ext(ext);
|
||||||
|
|
||||||
|
value * num[2] = { 0, one() };
|
||||||
|
set_p(v->num(), 2, num);
|
||||||
|
set_p_one(v->den());
|
||||||
|
|
||||||
|
set_interval(v->interval(), ext->interval());
|
||||||
|
|
||||||
|
v->set_real(is_real(ext));
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Create a new infinitesimal.
|
||||||
|
*/
|
||||||
void mk_infinitesimal(symbol const & n, numeral & r) {
|
void mk_infinitesimal(symbol const & n, numeral & r) {
|
||||||
unsigned idx = next_infinitesimal_idx();
|
unsigned idx = next_infinitesimal_idx();
|
||||||
infinitesimal * eps = alloc(infinitesimal, idx, n);
|
infinitesimal * eps = alloc(infinitesimal, idx, n);
|
||||||
m_extensions[extension::INFINITESIMAL].push_back(eps);
|
m_extensions[extension::INFINITESIMAL].push_back(eps);
|
||||||
value * p[2] = { 0, one() };
|
|
||||||
mpbq zero(0);
|
set_lower(eps->interval(), mpbq(0));
|
||||||
mpbq tiny(1, m_ini_precision);
|
set_upper(eps->interval(), mpbq(1, m_ini_precision));
|
||||||
mpbqi interval(zero, tiny);
|
|
||||||
polynomial_expr * numerator = mk_polynomial_expr(2, p, eps, interval);
|
r.m_value = mk_value(eps);
|
||||||
rational_function_value * v = alloc(rational_function_value, numerator, 0);
|
|
||||||
r.m_value = v;
|
|
||||||
inc_ref(r.m_value);
|
inc_ref(r.m_value);
|
||||||
updt_interval(*v);
|
|
||||||
SASSERT(sign(r) > 0);
|
SASSERT(sign(r) > 0);
|
||||||
SASSERT(!is_real(r));
|
SASSERT(!is_real(r));
|
||||||
}
|
}
|
||||||
|
@ -738,17 +797,6 @@ namespace realclosure {
|
||||||
SASSERT(is_zero(a));
|
SASSERT(is_zero(a));
|
||||||
}
|
}
|
||||||
|
|
||||||
int sign(polynomial_expr * p) {
|
|
||||||
if (p == 0) {
|
|
||||||
// Remark: The null polynomial expression denotes 1
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SASSERT(!bqim().contains_zero(p->m_interval));
|
|
||||||
return bqim().is_P(p->m_interval) ? 1 : -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int sign(numeral const & a) {
|
int sign(numeral const & a) {
|
||||||
if (is_zero(a))
|
if (is_zero(a))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -756,8 +804,9 @@ namespace realclosure {
|
||||||
return qm().is_pos(to_mpq(a)) ? 1 : -1;
|
return qm().is_pos(to_mpq(a)) ? 1 : -1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rational_function_value * v = to_rational_function(a);
|
value * v = a.m_value;
|
||||||
return sign(v->num()) * sign(v->den());
|
SASSERT(!bqim().contains_zero(v->interval()));
|
||||||
|
return bqim().is_P(v->interval()) ? 1 : -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -772,7 +821,7 @@ namespace realclosure {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_real(value * v) {
|
bool is_real(value * v) const {
|
||||||
if (is_zero(v) || is_nz_rational(v))
|
if (is_zero(v) || is_nz_rational(v))
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
|
@ -780,10 +829,7 @@ namespace realclosure {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_real(numeral const & a) const {
|
bool is_real(numeral const & a) const {
|
||||||
if (is_zero(a) || is_nz_rational(a))
|
return is_real(a.m_value);
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return to_rational_function(a)->is_real();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void mpq_to_mpbqi(mpq const & q, mpbqi & interval) {
|
void mpq_to_mpbqi(mpq const & q, mpbqi & interval) {
|
||||||
|
@ -986,7 +1032,7 @@ namespace realclosure {
|
||||||
*/
|
*/
|
||||||
void div(value_ref_buffer & p, value * a) {
|
void div(value_ref_buffer & p, value * a) {
|
||||||
SASSERT(!is_zero(a));
|
SASSERT(!is_zero(a));
|
||||||
if (is_one(a))
|
if (is_rational_one(a))
|
||||||
return;
|
return;
|
||||||
unsigned sz = p.size();
|
unsigned sz = p.size();
|
||||||
for (unsigned i = 0; i < sz; i++)
|
for (unsigned i = 0; i < sz; i++)
|
||||||
|
@ -1102,12 +1148,17 @@ namespace realclosure {
|
||||||
*/
|
*/
|
||||||
void mk_monic(value_ref_buffer & p) {
|
void mk_monic(value_ref_buffer & p) {
|
||||||
unsigned sz = p.size();
|
unsigned sz = p.size();
|
||||||
if (sz > 0 && !is_one(p[sz-1])) {
|
if (sz > 0) {
|
||||||
SASSERT(p[sz-1] != 0);
|
SASSERT(p[sz-1] != 0);
|
||||||
for (unsigned i = 0; i < sz - 1; i++) {
|
if (!is_one(p[sz-1])) {
|
||||||
p.set(i, div(p[i], p[sz-1]));
|
for (unsigned i = 0; i < sz - 1; i++) {
|
||||||
|
p.set(i, div(p[i], p[sz-1]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
p.set(0, one());
|
// I perform the following assignment even when is_one(p[sz-1]) returns true,
|
||||||
|
// Reason: the leading coefficient may be equal to one but may not be encoded using
|
||||||
|
// the rational value 1.
|
||||||
|
p.set(sz-1, one());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1339,7 +1390,8 @@ namespace realclosure {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rational_function_value * v = to_rational_function(a);
|
rational_function_value * v = to_rational_function(a);
|
||||||
std::swap(v->m_numerator, v->m_denominator);
|
v->num().swap(v->den());
|
||||||
|
// TODO: Invert interval
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -1385,13 +1437,6 @@ namespace realclosure {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void mark(polynomial_expr * p) {
|
|
||||||
if (p == 0)
|
|
||||||
return;
|
|
||||||
mark(p->ext());
|
|
||||||
mark(p->p());
|
|
||||||
}
|
|
||||||
|
|
||||||
void mark(polynomial const & p) {
|
void mark(polynomial const & p) {
|
||||||
for (unsigned i = 0; i < p.size(); i++) {
|
for (unsigned i = 0; i < p.size(); i++) {
|
||||||
mark(p[i]);
|
mark(p[i]);
|
||||||
|
@ -1402,6 +1447,7 @@ namespace realclosure {
|
||||||
if (v == 0 || is_nz_rational(v))
|
if (v == 0 || is_nz_rational(v))
|
||||||
return;
|
return;
|
||||||
rational_function_value * rf = to_rational_function(v);
|
rational_function_value * rf = to_rational_function(v);
|
||||||
|
mark(rf->ext());
|
||||||
mark(rf->num());
|
mark(rf->num());
|
||||||
mark(rf->den());
|
mark(rf->den());
|
||||||
}
|
}
|
||||||
|
@ -1423,7 +1469,7 @@ namespace realclosure {
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
display(out, p[i], compact);
|
display(out, p[i], compact);
|
||||||
else {
|
else {
|
||||||
if (!is_one(p[i])) {
|
if (!is_rational_one(p[i])) {
|
||||||
out << "(";
|
out << "(";
|
||||||
display(out, p[i], compact);
|
display(out, p[i], compact);
|
||||||
out << ")*";
|
out << ")*";
|
||||||
|
@ -1450,8 +1496,8 @@ namespace realclosure {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void display_polynomial_expr(std::ostream & out, polynomial_expr const & p, bool compact) const {
|
void display_polynomial_expr(std::ostream & out, polynomial const & p, extension * ext, bool compact) const {
|
||||||
display_polynomial(out, p.p(), display_ext_proc(*this, p.ext()), compact);
|
display_polynomial(out, p, display_ext_proc(*this, ext), compact);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void display_poly_sign(std::ostream & out, int s) {
|
static void display_poly_sign(std::ostream & out, int s) {
|
||||||
|
@ -1491,6 +1537,17 @@ namespace realclosure {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Return true if p is the constant polynomial where the coefficient is
|
||||||
|
the rational value 1.
|
||||||
|
|
||||||
|
\remark This is NOT checking whether p is actually equal to 1.
|
||||||
|
That is, it is just checking the representation.
|
||||||
|
*/
|
||||||
|
bool is_rational_one(polynomial const & p) const {
|
||||||
|
return p.size() == 1 && is_one(p[0]);
|
||||||
|
}
|
||||||
|
|
||||||
void display(std::ostream & out, value * v, bool compact) const {
|
void display(std::ostream & out, value * v, bool compact) const {
|
||||||
if (v == 0)
|
if (v == 0)
|
||||||
out << "0";
|
out << "0";
|
||||||
|
@ -1498,19 +1555,19 @@ namespace realclosure {
|
||||||
qm().display(out, to_mpq(v));
|
qm().display(out, to_mpq(v));
|
||||||
else {
|
else {
|
||||||
rational_function_value * rf = to_rational_function(v);
|
rational_function_value * rf = to_rational_function(v);
|
||||||
if (rf->den() == 0) {
|
if (is_rational_one(rf->den())) {
|
||||||
display_polynomial_expr(out, *rf->num(), compact);
|
display_polynomial_expr(out, rf->num(), rf->ext(), compact);
|
||||||
}
|
}
|
||||||
else if (rf->num() == 0) {
|
else if (is_rational_one(rf->num())) {
|
||||||
out << "1/(";
|
out << "1/(";
|
||||||
display_polynomial_expr(out, *rf->den(), compact);
|
display_polynomial_expr(out, rf->den(), rf->ext(), compact);
|
||||||
out << ")";
|
out << ")";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
out << "(";
|
out << "(";
|
||||||
display_polynomial_expr(out, *rf->num(), compact);
|
display_polynomial_expr(out, rf->num(), rf->ext(), compact);
|
||||||
out << ")/(";
|
out << ")/(";
|
||||||
display_polynomial_expr(out, *rf->den(), compact);
|
display_polynomial_expr(out, rf->den(), rf->ext(), compact);
|
||||||
out << ")";
|
out << ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -176,6 +176,10 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
T * c_ptr() { return m_data; }
|
T * c_ptr() { return m_data; }
|
||||||
|
|
||||||
|
void swap(array & other) {
|
||||||
|
std::swap(m_data, other.m_data);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|
Loading…
Reference in a new issue