3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-29 11:55:51 +00:00

Add skeleton for the realclosure package

Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2013-01-02 16:39:08 -08:00
parent a51c6d125d
commit edf62481e9
5 changed files with 856 additions and 3 deletions

View file

@ -0,0 +1,265 @@
/*++
Copyright (c) 2013 Microsoft Corporation
Module Name:
realclosure.h
Abstract:
Package for computing with elements of the realclosure of a field containing
- all rationals
- extended with computable transcendental real numbers (e.g., pi and e)
- infinitesimals
Author:
Leonardo (leonardo) 2013-01-02
Notes:
--*/
#ifndef _REALCLOSURE_H_
#define _REALCLOSURE_H_
#include"mpq.h"
#include"params.h"
#include"scoped_numeral.h"
#include"scoped_numeral_vector.h"
#include"interval.h"
namespace realclosure {
class num;
typedef interval_manager<im_default_config> mpqi_manager;
class mk_interval {
public:
virtual void operator()(unsigned k, mpqi_manager & im, mpqi_manager::interval & r) = 0;
};
class manager {
public:
struct imp;
private:
imp * m_imp;
public:
manager(unsynch_mpq_manager & m, params_ref const & p = params_ref(), small_object_allocator * a = 0);
~manager();
typedef num numeral;
typedef svector<numeral> numeral_vector;
typedef _scoped_numeral<manager> scoped_numeral;
typedef _scoped_numeral_vector<manager> scoped_numeral_vector;
static void get_param_descrs(param_descrs & r);
static void collect_param_descrs(param_descrs & r) { get_param_descrs(r); }
void set_cancel(bool f);
void cancel() { set_cancel(true); }
void reset_cancel() { set_cancel(false); }
void updt_params(params_ref const & p);
unsynch_mpq_manager & qm() const;
void del(numeral & a);
/**
\brief Add a new infinitesimal to the current field. The new infinitesimal is smaller than any positive element in the field.
*/
void mk_infinitesimal(char const * prefix_name, numeral & r);
void mk_infinitesimal(numeral & r) { mk_infinitesimal("eps", r); }
/**
\brief Add a new transcendental real value to the field.
The functor \c mk_interval is used to compute approximations of the transcendental value.
This procedure should be used with care, if the value is not really transcendental with respect to the current
field, computations with the new numeral may not terminate.
Example: we extended the field with Pi. Pi is transcendental with respect to a field that contains only algebraic real numbers.
So, this step is fine. Let us call the resultant field F.
Then, we extend the field F with 1 - Pi. 1 - Pi is transcendental with respect to algebraic real numbers, but it is NOT transcendental
with respect to F, since F contains Pi.
*/
void mk_transcendental(char const * prefix_name, mk_interval & proc, numeral & r);
void mk_transcendental(mk_interval & proc, numeral & r) { mk_transcendental("k", proc, r); }
/**
\brief Isolate the roots of the univariate polynomial as[0] + as[1]*x + ... + as[n-1]*x^{n-1}
The roots are stored in \c roots.
*/
void isolate_roots(char const * prefix_name, unsigned n, numeral const * as, numeral_vector & roots);
void isolate_roots(unsigned n, numeral const * as, numeral_vector & roots) { isolate_roots("a", n, as, roots); }
/**
\brief a <- 0
*/
void reset(numeral & a);
/**
\brief Return the sign of a.
*/
int sign(numeral const & a);
/**
\brief Return true if a is zero.
*/
bool is_zero(numeral const & a);
/**
\brief Return true if a is positive.
*/
bool is_pos(numeral const & a);
/**
\brief Return true if a is negative.
*/
bool is_neg(numeral const & a);
/**
\brief Return true if a is an integer.
*/
bool is_int(numeral const & a);
/**
\brief Return true if a is a real number.
*/
bool is_real(numeral const & a);
/**
\brief a <- n
*/
void set(numeral & a, int n);
void set(numeral & a, mpz const & n);
void set(numeral & a, mpq const & n);
void set(numeral & a, numeral const & n);
void swap(numeral & a, numeral & b);
/**
\brief Return a^{1/k}
Throws an exception if (a is negative and k is even) or (k is zero).
*/
void root(numeral const & a, unsigned k, numeral & b);
/**
\brief Return a^k
Throws an exception if 0^0.
*/
void power(numeral const & a, unsigned k, numeral & b);
/**
\brief c <- a + b
*/
void add(numeral const & a, numeral const & b, numeral & c);
void add(numeral const & a, mpz const & b, numeral & c);
/**
\brief c <- a - b
*/
void sub(numeral const & a, numeral const & b, numeral & c);
/**
\brief c <- a * b
*/
void mul(numeral const & a, numeral const & b, numeral & c);
/**
\brief a <- -a
*/
void neg(numeral & a);
/**
\brief a <- 1/a if a != 0
*/
void inv(numeral & a);
/**
\brief c <- a/b if b != 0
*/
void div(numeral const & a, numeral const & b, numeral & c);
/**
Return -1 if a < b
Return 0 if a == b
Return 1 if a > b
*/
int compare(numeral const & a, numeral const & b);
/**
\brief a == b
*/
bool eq(numeral const & a, numeral const & b);
bool eq(numeral const & a, mpq const & b);
bool eq(numeral const & a, mpz const & b);
/**
\brief a != b
*/
bool neq(numeral const & a, numeral const & b) { return !eq(a, b); }
bool neq(numeral const & a, mpq const & b) { return !eq(a, b); }
bool neq(numeral const & a, mpz const & b) { return !eq(a, b); }
/**
\brief a < b
*/
bool lt(numeral const & a, numeral const & b);
bool lt(numeral const & a, mpq const & b);
bool lt(numeral const & a, mpz const & b);
/**
\brief a > b
*/
bool gt(numeral const & a, numeral const & b) { return lt(b, a); }
bool gt(numeral const & a, mpq const & b);
bool gt(numeral const & a, mpz const & b);
/**
\brief a <= b
*/
bool le(numeral const & a, numeral const & b) { return !gt(a, b); }
bool le(numeral const & a, mpq const & b) { return !gt(a, b); }
bool le(numeral const & a, mpz const & b) { return !gt(a, b); }
/**
\brief a >= b
*/
bool ge(numeral const & a, numeral const & b) { return !lt(a, b); }
bool ge(numeral const & a, mpq const & b) { return !lt(a, b); }
bool ge(numeral const & a, mpz const & b) { return !lt(a, b); }
/**
\brief Store in result a value in the interval (prev, next)
\pre lt(pre, next)
*/
void select(numeral const & prev, numeral const & next, numeral & result);
void display(std::ostream & out, numeral const & a) const;
/**
\brief Display a real number in decimal notation.
A question mark is added based on the precision requested.
This procedure throws an exception if the \c a is not a real.
*/
void display_decimal(std::ostream & out, numeral const & a, unsigned precision = 10) const;
};
class value;
class num {
friend class manager;
friend class manager::imp;
value * m_value;
public:
num():m_value(0) {}
};
};
typedef realclosure::manager rcmanager;
typedef rcmanager::numeral rcnumeral;
typedef rcmanager::numeral_vector rcnumeral_vector;
typedef rcmanager::scoped_numeral scoped_rcnumeral;
typedef rcmanager::scoped_numeral_vector scoped_rcnumeral_vector;
#endif