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 converting to and from LibPoly objects. |
14 |
|
*/ |
15 |
|
|
16 |
|
#ifndef CVC5__THEORY__ARITH__NL__POLY_CONVERSION_H |
17 |
|
#define CVC5__THEORY__ARITH__NL__POLY_CONVERSION_H |
18 |
|
|
19 |
|
#include "cvc5_private.h" |
20 |
|
|
21 |
|
#ifdef CVC5_POLY_IMP |
22 |
|
|
23 |
|
#include <poly/polyxx.h> |
24 |
|
|
25 |
|
#include <cstddef> |
26 |
|
#include <map> |
27 |
|
#include <utility> |
28 |
|
|
29 |
|
#include "expr/node.h" |
30 |
|
#include "util/real_algebraic_number.h" |
31 |
|
|
32 |
|
namespace cvc5 { |
33 |
|
namespace theory { |
34 |
|
namespace arith { |
35 |
|
|
36 |
|
class BoundInference; |
37 |
|
|
38 |
|
namespace nl { |
39 |
|
|
40 |
|
/** Bijective mapping between cvc5 variables and poly variables. */ |
41 |
20800 |
struct VariableMapper |
42 |
|
{ |
43 |
|
/** A mapping from cvc5 variables to poly variables. */ |
44 |
|
std::map<cvc5::Node, poly::Variable> mVarCVCpoly; |
45 |
|
/** A mapping from poly variables to cvc5 variables. */ |
46 |
|
std::map<poly::Variable, cvc5::Node> mVarpolyCVC; |
47 |
|
|
48 |
|
/** Retrieves the according poly variable. */ |
49 |
|
poly::Variable operator()(const cvc5::Node& n); |
50 |
|
/** Retrieves the according cvc5 variable. */ |
51 |
|
cvc5::Node operator()(const poly::Variable& n); |
52 |
|
}; |
53 |
|
|
54 |
|
/** Convert a poly univariate polynomial to a cvc5::Node. */ |
55 |
|
cvc5::Node as_cvc_upolynomial(const poly::UPolynomial& p, |
56 |
|
const cvc5::Node& var); |
57 |
|
|
58 |
|
/** Convert a cvc5::Node to a poly univariate polynomial. */ |
59 |
|
poly::UPolynomial as_poly_upolynomial(const cvc5::Node& n, |
60 |
|
const cvc5::Node& var); |
61 |
|
|
62 |
|
/** |
63 |
|
* Constructs a polynomial from the given node. |
64 |
|
* |
65 |
|
* While a Node may contain rationals, a Polynomial does not. |
66 |
|
* We therefore also store the denominator of the returned polynomial and |
67 |
|
* use it to construct the integer polynomial recursively. |
68 |
|
* Once the polynomial has been fully constructed, we can oftentimes ignore the |
69 |
|
* denominator (except for its sign, which is always positive, though). |
70 |
|
* This is the case if we are solely interested in the roots of the polynomials |
71 |
|
* (like in the context of CAD). If we need the actual polynomial (for example |
72 |
|
* in the context of ICP) the second overload provides the denominator in the |
73 |
|
* third argument. |
74 |
|
*/ |
75 |
|
poly::Polynomial as_poly_polynomial(const cvc5::Node& n, VariableMapper& vm); |
76 |
|
poly::Polynomial as_poly_polynomial(const cvc5::Node& n, |
77 |
|
VariableMapper& vm, |
78 |
|
poly::Rational& denominator); |
79 |
|
|
80 |
|
/** |
81 |
|
* Constructs a node from the given polynomial. |
82 |
|
* |
83 |
|
* This methods does the straight-forward conversion from a polynomial into Node |
84 |
|
* representation, using the given variable mapper. |
85 |
|
* The resulting node is not minimized in any form (it may contain spurious |
86 |
|
* multiplications with one or use NONLINEAR_MULT where regular MULT may be |
87 |
|
* sufficient), so it may be sensible to rewrite it afterwards. |
88 |
|
*/ |
89 |
|
cvc5::Node as_cvc_polynomial(const poly::Polynomial& p, VariableMapper& vm); |
90 |
|
|
91 |
|
/** |
92 |
|
* Constructs a constraints (a polynomial and a sign condition) from the given |
93 |
|
* node. |
94 |
|
*/ |
95 |
|
std::pair<poly::Polynomial, poly::SignCondition> as_poly_constraint( |
96 |
|
Node n, VariableMapper& vm); |
97 |
|
|
98 |
|
/** |
99 |
|
* Transforms a real algebraic number to a node suitable for putting it into a |
100 |
|
* model. The resulting node can be either a constant (suitable for |
101 |
|
* addCheckModelSubstitution) or a witness term (suitable for |
102 |
|
* addCheckModelWitness). |
103 |
|
*/ |
104 |
|
Node ran_to_node(const RealAlgebraicNumber& ran, const Node& ran_variable); |
105 |
|
|
106 |
|
Node ran_to_node(const poly::AlgebraicNumber& an, const Node& ran_variable); |
107 |
|
|
108 |
|
/** |
109 |
|
* Transforms a poly::Value to a node. |
110 |
|
* The resulting node can be either a constant or a witness term. |
111 |
|
*/ |
112 |
|
Node value_to_node(const poly::Value& v, const Node& ran_variable); |
113 |
|
|
114 |
|
/** |
115 |
|
* Constructs a lemma that excludes a given interval from the feasible values of |
116 |
|
* a variable. Conceptually, the resulting lemma has the form |
117 |
|
* (OR |
118 |
|
* (<= var interval.lower) |
119 |
|
* (<= interval.upper var) |
120 |
|
* ) |
121 |
|
* This method honors the interval bound types (open or closed), but also deals |
122 |
|
* with real algebraic endpoints. If allowNonlinearLemma is false, real |
123 |
|
* algebraic endpoints are reflected by coarse (numeric) approximations and thus |
124 |
|
* may lead to lemmas that are weaker than they could be. Also, lemma creation |
125 |
|
* may fail altogether. |
126 |
|
* If allowNonlinearLemma is true, it tries to construct better lemmas (based on |
127 |
|
* the sign of the defining polynomial of the real algebraic number). These |
128 |
|
* lemmas are nonlinear, though, and may thus be expensive to use in the |
129 |
|
* subsequent solving process. |
130 |
|
*/ |
131 |
|
Node excluding_interval_to_lemma(const Node& variable, |
132 |
|
const poly::Interval& interval, |
133 |
|
bool allowNonlinearLemma); |
134 |
|
|
135 |
|
/** |
136 |
|
* Transforms a node to a poly::AlgebraicNumber. |
137 |
|
* Expects a node of the following form: |
138 |
|
* (AND |
139 |
|
* (= (polynomial in __z) 0) |
140 |
|
* (< CONST __z) |
141 |
|
* (< __z CONST) |
142 |
|
* ) |
143 |
|
*/ |
144 |
|
poly::AlgebraicNumber node_to_poly_ran(const Node& n, const Node& ran_variable); |
145 |
|
|
146 |
|
/** Transforms a node to a RealAlgebraicNumber by calling node_to_poly_ran. */ |
147 |
|
RealAlgebraicNumber node_to_ran(const Node& n, const Node& ran_variable); |
148 |
|
|
149 |
|
/** |
150 |
|
* Transforms a node to a poly::Value. |
151 |
|
*/ |
152 |
|
poly::Value node_to_value(const Node& n, const Node& ran_variable); |
153 |
|
|
154 |
|
/** |
155 |
|
* Give a rough estimate of the bitsize of the representation of `v`. |
156 |
|
* It can be used as a rough measure of the size of complexity of a value, for |
157 |
|
* example to avoid divergence or disallow huge lemmas. |
158 |
|
*/ |
159 |
|
std::size_t bitsize(const poly::Value& v); |
160 |
|
|
161 |
|
poly::IntervalAssignment getBounds(VariableMapper& vm, const BoundInference& bi); |
162 |
|
|
163 |
|
} // namespace nl |
164 |
|
} // namespace arith |
165 |
|
} // namespace theory |
166 |
|
} // namespace cvc5 |
167 |
|
|
168 |
|
#endif |
169 |
|
|
170 |
|
#endif |