18 #include <unordered_map>
21 #include <carl-arith/poly/umvpoly/CoCoAAdaptor.h>
22 #include <carl-arith/poly/umvpoly/MultivariatePolynomial.h>
23 #include <carl-arith/poly/umvpoly/functions/Resultant.h>
24 #include <carl-arith/poly/umvpoly/UnivariatePolynomial.h>
25 #include <carl-arith/core/Variable.h>
26 #include <carl-arith/core/VariablePool.h>
28 #include <carl-arith/ran/ran.h>
29 #include <carl-arith/ran/RealAlgebraicPoint.h>
34 namespace onecellcad {
37 using UniPoly = carl::UnivariatePolynomial<smtrat::Rational>;
38 using MultiPoly = carl::MultivariatePolynomial<smtrat::Rational>;
40 using RANPoint = RealAlgebraicPoint<smtrat::Rational>;
41 using RANMap = std::map<carl::Variable, RAN>;
106 o <<
"(cell (level " << c.size() <<
") ";
107 for (
auto& sector : c) {
134 const std::vector<carl::Variable>& variableOrder) {
136 std::set<carl::Variable> polyVarSet = carl::variables(poly).as_set();
142 if (polyVarSet.empty())
146 for (
const auto&
var : variableOrder) {
147 polyVarSet.erase(
var);
149 if (polyVarSet.empty()) {
165 const std::vector<carl::Variable>& variableOrder) {
166 std::map<carl::Variable, RAN> pointAsMap;
167 for (
size_t i = 0; i < count; i++)
168 pointAsMap[variableOrder[i]] = point[i];
184 const std::vector<carl::Variable>& variableOrder,
187 assert(!carl::is_zero(poly));
188 size_t level =
levelOf(poly, variableOrder);
190 size_t levelVariableIdx = level - 1;
191 SMTRAT_LOG_DEBUG(
"smtrat.opencad",
"At level " << level <<
" merge it with " << cell);
193 return std::optional<OpenCADCell>(cell);
197 toStdMap(point, level, variableOrder));
204 std::optional<OpenCADCell> newCell(cell);
205 carl::Variable mainVariable = variableOrder[levelVariableIdx];
206 SMTRAT_LOG_TRACE(
"smtrat.opencad",
"Current level variable: " << mainVariable);
207 MultiCoeffUniPoly polyAsUnivar = carl::to_univariate_polynomial(poly, mainVariable);
209 SMTRAT_LOG_INFO(
"smtrat.opencad",
"Do Open-McCallum projection of this poly into level " << level - 1);
210 std::vector<MultiPoly> projectionPolys;
211 projectionPolys.emplace_back(polyAsUnivar.lcoeff());
213 SMTRAT_LOG_TRACE(
"smtrat.opencad",
"Add leading coeff: " << polyAsUnivar.lcoeff());
216 Sector& sectorAtLvl = (*newCell)[levelVariableIdx];
230 SMTRAT_LOG_DEBUG(
"smtrat.opencad",
"Projection result: " << projectionPolys);
231 SMTRAT_LOG_INFO(
"smtrat.opencad",
"Projection complete. Merge into cell");
235 carl::CoCoAAdaptor<MultiPoly> factorizer(projectionPolys);
236 for (
auto& p : projectionPolys) {
237 for (
const auto& factor : factorizer.irreducible_factors(p,
false)) {
253 RAN point_k = point[levelVariableIdx];
255 <<
". Search closest bounds to " << point_k);
257 std::vector<RAN> roots = carl::real_roots(polyAsUnivar,
258 toStdMap(point, level - 1, variableOrder)).roots();
266 Sector& sectorAtLvl = (*newCell)[levelVariableIdx];
271 auto root_higher = std::find_if(
274 [&point_k](
const RAN& otherPoint) { return otherPoint > point_k; });
275 assert(root_higher == roots.end() || *root_higher != point_k);
278 if (root_higher != roots.end() &&
280 *root_higher < sectorAtLvl.highBound->cachedPoint)) {
286 if (root_higher != roots.begin()) {
287 auto root_lower = --root_higher;
288 assert(*root_lower != point_k);
290 *root_lower > sectorAtLvl.
lowBound->cachedPoint) {
315 const std::vector<MultiPoly> polySet,
317 const std::vector<carl::Variable>& variableOrder) {
322 assert(variableOrder.size() == point.dim());
324 SMTRAT_LOG_DEBUG(
"smtrat.opencad",
"Use point " << point <<
" wrt. variable order " << variableOrder);
327 for (
const auto& poly : polySet) {
void sort(T *array, int size, LessThan lt)
Poly resultant(carl::Variable variable, const Poly &p, const Poly &q)
Computes the resultant of two polynomials.
Poly discriminant(carl::Variable variable, const Poly &p)
Computes the discriminant of a polynomial.
Rational evaluate(carl::Variable v, const Poly &p, const Rational &r)
size_t levelOf(const MultiPoly &poly, const std::vector< carl::Variable > &variableOrder)
Find the index of the highest variable (wrt.
std::map< carl::Variable, RAN > toStdMap(const RANPoint &point, size_t count, const std::vector< carl::Variable > &variableOrder)
Create a mapping from the first 'count'-many variables in the given 'variableOrder' to the first 'cou...
carl::MultivariatePolynomial< smtrat::Rational > MultiPoly
RealAlgebraicPoint< smtrat::Rational > RANPoint
std::ostream & operator<<(std::ostream &o, const Section &s)
carl::UnivariatePolynomial< MultiPoly > MultiCoeffUniPoly
std::optional< OpenCADCell > createOpenCADCell(const std::vector< MultiPoly > polySet, const RANPoint &point, const std::vector< carl::Variable > &variableOrder)
Construct a OpenCADCell for the given set of polynomials 'polySet' that contains the given 'point'.
OpenCADCell createFullspaceCoveringCell(size_t level)
std::map< carl::Variable, RAN > RANMap
std::optional< OpenCADCell > mergeCellWithPoly(OpenCADCell &cell, const RANPoint &point, const std::vector< carl::Variable > &variableOrder, const MultiPoly poly)
Merge the given open OpenCADCell 'cell' that contains the given 'point' (called "alpha" in [1]) with ...
carl::UnivariatePolynomial< smtrat::Rational > UniPoly
std::vector< Sector > OpenCADCell
Represent a single open cell [1].
Class to create the formulas for axioms.
#define SMTRAT_LOG_TRACE(channel, msg)
#define SMTRAT_LOG_WARN(channel, msg)
#define SMTRAT_LOG_INFO(channel, msg)
#define SMTRAT_LOG_DEBUG(channel, msg)
Represent a cell's closed-interval-boundary object along one single axis by an irreducible,...
RAN cachedPoint
A single, special bound after having plugged a specific point of level k-1 can be cached for performa...
Represent a cell's open-interval boundary object along one single axis by two irreducible,...
bool isLowBoundNegInfty() const
std::optional< Section > highBound
std::optional< Section > lowBound
bool isHighBoundInfty() const