1 |
|
/****************************************************************************** |
2 |
|
* Top contributors (to current version): |
3 |
|
* Gereon Kremer, Aina Niemetz |
4 |
|
* |
5 |
|
* This file is part of the cvc5 project. |
6 |
|
* |
7 |
|
* Copyright (c) 2009-2021 by the authors listed in the file AUTHORS |
8 |
|
* in the top-level source directory and their institutional affiliations. |
9 |
|
* All rights reserved. See the file COPYING in the top-level source |
10 |
|
* directory for licensing information. |
11 |
|
* **************************************************************************** |
12 |
|
* |
13 |
|
* Utilities for working with LibPoly. |
14 |
|
*/ |
15 |
|
|
16 |
|
#include "cvc5_private.h" |
17 |
|
|
18 |
|
#ifndef CVC5__POLY_UTIL_H |
19 |
|
#define CVC5__POLY_UTIL_H |
20 |
|
|
21 |
|
#include <vector> |
22 |
|
|
23 |
|
#include "maybe.h" |
24 |
|
#include "util/integer.h" |
25 |
|
#include "util/rational.h" |
26 |
|
#include "util/real_algebraic_number.h" |
27 |
|
|
28 |
|
#ifdef CVC5_POLY_IMP |
29 |
|
|
30 |
|
#include <poly/polyxx.h> |
31 |
|
|
32 |
|
namespace cvc5 { |
33 |
|
/** |
34 |
|
* Utilities for working with libpoly. |
35 |
|
* This namespace contains various basic conversion routines necessary for the |
36 |
|
* integration of LibPoly. Firstly, LibPoly is based on GMP and hence we need |
37 |
|
* conversion from and to CLN (in case CLN is enabled). Otherwise, conversion of |
38 |
|
* number types mostly reduces to simple type casts. |
39 |
|
* Furthermore, conversions between poly::Rational and poly::DyadicRational and |
40 |
|
* constructors for algebraic numbers that need initial refinement of the |
41 |
|
* interval are provided. |
42 |
|
*/ |
43 |
|
namespace poly_utils { |
44 |
|
|
45 |
|
/** Converts a poly::Integer to a cvc5::Integer. */ |
46 |
|
Integer toInteger(const poly::Integer& i); |
47 |
|
/** Converts a poly::Integer to a cvc5::Rational. */ |
48 |
|
Rational toRational(const poly::Integer& r); |
49 |
|
/** Converts a poly::Rational to a cvc5::Rational. */ |
50 |
|
Rational toRational(const poly::Rational& r); |
51 |
|
/** Converts a poly::DyadicRational to a cvc5::Rational. */ |
52 |
|
Rational toRational(const poly::DyadicRational& dr); |
53 |
|
|
54 |
|
/** Converts a poly::Value to a cvc5::Rational (that may be a bit above). */ |
55 |
|
Rational toRationalAbove(const poly::Value& v); |
56 |
|
/** Converts a poly::Value to a cvc5::Rational (that may be a bit below). */ |
57 |
|
Rational toRationalBelow(const poly::Value& v); |
58 |
|
|
59 |
|
/** Converts a cvc5::Integer to a poly::Integer. */ |
60 |
|
poly::Integer toInteger(const Integer& i); |
61 |
|
/** Converts a vector of cvc5::Integers to a vector of poly::Integers. */ |
62 |
|
std::vector<poly::Integer> toInteger(const std::vector<Integer>& vi); |
63 |
|
/** Converts a cvc5::Rational to a poly::Rational. */ |
64 |
|
poly::Rational toRational(const Rational& r); |
65 |
|
/** |
66 |
|
* Converts a cvc5::Rational to a poly::DyadicRational. If the input is not |
67 |
|
* dyadic, no result is produced. |
68 |
|
*/ |
69 |
|
Maybe<poly::DyadicRational> toDyadicRational(const Rational& r); |
70 |
|
/** |
71 |
|
* Converts a poly::Rational to a poly::DyadicRational. If the input is not |
72 |
|
* dyadic, no result is produced. |
73 |
|
*/ |
74 |
|
Maybe<poly::DyadicRational> toDyadicRational(const poly::Rational& r); |
75 |
|
|
76 |
|
/** |
77 |
|
* Iteratively approximates a poly::Rational by a dyadic poly::Rational. |
78 |
|
* Assuming that r is dyadic, makes one refinement step to move r closer to |
79 |
|
* original. |
80 |
|
* Assumes one starts with lower(original) or ceil(original) for r. |
81 |
|
*/ |
82 |
|
poly::Rational approximateToDyadic(const poly::Rational& r, |
83 |
|
const poly::Rational& original); |
84 |
|
|
85 |
|
/** |
86 |
|
* Constructs a poly::AlgebraicNumber, allowing for refinement of the |
87 |
|
* cvc5::Rational bounds. As a poly::AlgebraicNumber works on |
88 |
|
* poly::DyadicRationals internally, the bounds are iteratively refined using |
89 |
|
* approximateToDyadic until the respective interval is isolating. If the |
90 |
|
* provided rational bounds are already dyadic, the refinement is skipped. |
91 |
|
*/ |
92 |
|
poly::AlgebraicNumber toPolyRanWithRefinement(poly::UPolynomial&& p, |
93 |
|
const Rational& lower, |
94 |
|
const Rational& upper); |
95 |
|
|
96 |
|
/** |
97 |
|
* Constructs a cvc5::RealAlgebraicNumber, simply wrapping |
98 |
|
* toPolyRanWithRefinement. |
99 |
|
*/ |
100 |
|
RealAlgebraicNumber toRanWithRefinement(poly::UPolynomial&& p, |
101 |
|
const Rational& lower, |
102 |
|
const Rational& upper); |
103 |
|
|
104 |
|
std::size_t totalDegree(const poly::Polynomial& p); |
105 |
|
|
106 |
|
/** |
107 |
|
* Collects information about a single variable in a set of polynomials. |
108 |
|
* Used for determining a variable ordering. |
109 |
|
*/ |
110 |
133 |
struct VariableInformation |
111 |
|
{ |
112 |
|
poly::Variable var; |
113 |
|
/** Maximum degree of this variable. */ |
114 |
|
std::size_t max_degree = 0; |
115 |
|
/** Maximum degree of the leading coefficient of this variable. */ |
116 |
|
std::size_t max_lc_degree = 0; |
117 |
|
/** Maximum of total degrees of terms that contain this variable. */ |
118 |
|
std::size_t max_terms_tdegree = 0; |
119 |
|
/** Sum of degrees of this variable within all terms. */ |
120 |
|
std::size_t sum_term_degree = 0; |
121 |
|
/** Sum of degrees of this variable within all polynomials. */ |
122 |
|
std::size_t sum_poly_degree = 0; |
123 |
|
/** Number of polynomials that contain this variable. */ |
124 |
|
std::size_t num_polynomials = 0; |
125 |
|
/** Number of terms that contain this variable. */ |
126 |
|
std::size_t num_terms = 0; |
127 |
|
}; |
128 |
|
std::ostream& operator<<(std::ostream& os, const VariableInformation& vi); |
129 |
|
|
130 |
|
void getVariableInformation(VariableInformation& vi, |
131 |
|
const poly::Polynomial& poly); |
132 |
|
|
133 |
|
} // namespace poly_utils |
134 |
|
} // namespace cvc5 |
135 |
|
|
136 |
|
#endif |
137 |
|
|
138 |
|
#endif /* CVC5__POLY_UTIL_H */ |