3 #include <carl-arith/poly/umvpoly/functions/Derivative.h>
4 #include <carl-arith/poly/umvpoly/functions/Factorization.h>
5 #include <carl-arith/poly/umvpoly/functions/Resultant.h>
6 #include <carl-arith/poly/umvpoly/functions/Definiteness.h>
7 #include <carl-arith/poly/umvpoly/functions/Representation.h>
17 #include <unordered_map>
21 #include <carl-arith/ran/ran.h>
29 namespace onecellcad {
33 using RANMap = std::map<carl::Variable, RAN>;
35 #ifdef SMTRAT_DEVOPTION_Statistics
36 OCStatistics& getStatistic();
50 return os <<
"ORD_INV";
52 return os <<
"SIGN_INV";
63 return r == InvarianceType ::ORD_INV;
84 return os <<
"(poly " << p.
tag <<
" " << p.
poly <<
")";
91 inline std::ostream&
operator<<(std::ostream& os,
const std::vector<TagPoly>& polys) {
92 os <<
"[ " << polys.size() <<
": ";
93 for (
const auto& poly : polys)
94 os << poly.tag <<
" " << poly.poly <<
", ";
98 inline std::ostream&
operator<<(std::ostream& os,
const std::vector<std::vector<TagPoly>>& lvls) {
99 int lvl = (int)lvls.size() - 1;
100 for (
auto it = lvls.rbegin(); it != lvls.rend(); ++it) {
116 return carl::total_degree(carl::to_univariate_polynomial(p.
poly, v));
139 const std::vector<carl::Variable>& variableOrder,
151 std::set<carl::Variable> polyVariables = carl::variables(poly).as_set();
154 if(polyVariables.empty()){
159 for (std::size_t level = 0; level < variableOrder.size(); ++level) {
160 polyVariables.erase(variableOrder[level]);
162 if (polyVariables.empty()) {
167 throw(
"Poly contains variable not found in variableOrder");
172 std::vector<carl::Variable> variableOrder,
176 std::vector<TagPoly> factors;
177 for (
const Poly& factor : carl::irreducible_factors(poly,
false)) {
178 factors.emplace_back(
TagPoly{tag, factor, *
levelOf(variableOrder, factor)});
180 assert(!factor.is_constant());
191 for (
const auto& factor : factors) {
192 if (!factor.poly.is_constant()) {
193 #ifdef SMTRAT_DEVOPTION_Statistics
194 OCStatistics& mStatistics = getStatistic();
196 bool maxDegStatisticOn =
true;
197 if(maxDegStatisticOn){
198 std::size_t curDeg =
getDegree(factor, variableOrder[factor.level]);
199 if(curDeg > mStatistics.getCurrentMaxDegree()){
200 mStatistics.updateMaxDegree(curDeg);
209 auto siContained =
std::find(polys[factor.level].begin(), polys[factor.level].end(), siFactor);
210 auto oiContained =
std::find(polys[factor.level].begin(), polys[factor.level].end(), oiFactor);
212 if (siContained == polys[factor.level].end() && oiContained == polys[factor.level].end()) {
214 polys[factor.level].push_back(factor);
216 polys[factor.level].erase(siContained);
217 polys[factor.level].push_back(factor);
280 using CADCell = std::vector<std::variant<Sector, Section>>;
284 for (std::size_t i = 0; i < cell.size(); i++) {
285 if (std::holds_alternative<Sector>(cell[i])) {
286 const auto cellSctr = std::get<Sector>(cell[i]);
287 if (cellSctr.lowBound)
288 os << cellSctr.lowBound->boundFunction;
291 os <<
" < var_" << i <<
" < ";
292 if (cellSctr.highBound)
293 os << cellSctr.highBound->boundFunction;
297 os <<
"var_" << i <<
" = ";
298 const auto cellSctn = std::get<Section>(cell[i]);
299 os << cellSctn.boundFunction;
307 inline std::vector<Poly>
asMultiPolys(
const std::vector<TagPoly> polys) {
308 std::vector<Poly> mPolys;
309 for (
const auto& poly : polys)
310 mPolys.emplace_back(poly.poly);
314 inline bool contains(
const std::vector<TagPoly>& polys,
const Poly& poly) {
315 auto isMatch = [&poly](
const TagPoly& taggedPoly) {
316 return taggedPoly.poly == poly;
318 return std::find_if(polys.begin(), polys.end(), isMatch) != polys.end();
322 bool contains(
const std::vector<T>& list,
const T& elem) {
323 return std::find(list.begin(), list.end(), elem) != list.end();
331 assert(carl::variables(poly).has(rootVariable));
338 std::vector<RAN> point;
340 const auto& modelValue = data.
model().evaluated(variable);
341 assert(modelValue.isRational() || modelValue.isRAN());
342 modelValue.isRational() ? point.emplace_back(modelValue.asRational()) : point.emplace_back(modelValue.asRAN());
349 std::vector<T>
prefix(
const std::vector<T>
vars, std::size_t prefixSize) {
350 std::vector<T> prefixVars(
vars.begin(), std::next(
vars.begin(), (
long)prefixSize));
356 for (
auto it1 = vec.begin(); it1 != vec.end();) {
358 if(it1->first == it1->second){
359 it1 = vec.erase(it1);
362 for (
auto it2 = it1 + 1; it2 != vec.end();) {
363 if (((*it1).first == (*it2).first && (*it1).second == (*it2).second) ||
364 ((*it1).first == (*it2).second && (*it1).second == (*it2).first)) {
365 it2 = vec.erase(it2);
377 for (
auto it1 = vec.begin(); it1 != vec.end() - 1; it1++) {
378 for (
auto it2 = it1 + 1; it2 != vec.end();) {
380 it2 = vec.erase(it2);
405 const auto p1UPoly = carl::to_univariate_polynomial(p1, mainVariable);
406 const auto p2UPoly = carl::to_univariate_polynomial(p2, mainVariable);
413 return p.lcoeff(mainVariable);
418 std::vector<std::vector<TagPoly>>& polys,
419 carl::Variable mainVar,
420 const std::vector<carl::Variable>& variableOrder){
421 if(!resultants.empty()) {
424 for (
auto const& elem : resultants) {
426 SMTRAT_LOG_TRACE(
"smtrat.cad",
"Add resultant(" << elem.first <<
"," << elem.second <<
") = " << res <<
" (if not const)");
439 std::size_t sectorCount = 0;
440 for (std::size_t i = 0; i <= uptoLevel; i++)
441 if (std::holds_alternative<Sector>(cell[i]))
447 return CADCell(cellComponentCount);
472 const std::size_t componentCount) {
473 std::map<carl::Variable, RAN> varToRANMap;
474 for (std::size_t i = 0; i < componentCount; i++)
485 const std::size_t polyLevel,
488 return carl::real_roots(
489 carl::to_univariate_polynomial(poly,
variableOrder[polyLevel]),
499 const std::size_t polyLevel,
502 assert(!poly.is_constant());
503 if (poly.is_linear())
506 const carl::Variable mainVariable =
variableOrder[polyLevel];
508 return carl::real_roots(carl::to_univariate_polynomial(poly, mainVariable),
prefixPointToStdMap(polyLevel)).is_nullified();
512 const std::size_t polyLevel,
514 const std::size_t componentCount = polyLevel + 1;
520 assert(!indeterminate(res));
537 const auto boundCandidateUniPoly =
538 carl::to_univariate_polynomial(boundCandidate.
poly, mainVariable);
541 for (
const auto& coeff : boundCandidateUniPoly.coefficients()) {
542 if (coeff.is_constant() && !carl::is_zero(coeff))
563 for (
const auto& coeff : boundCandidateUniPoly.coefficients()) {
565 if (carl::is_zero(coeff))
continue;
575 for (std::size_t lvl = 0; lvl < cell.size(); lvl++) {
577 const auto cellCmp = cell[lvl];
578 if (std::holds_alternative<Sector>(cellCmp)) {
580 const auto cellSctr = std::get<Sector>(cellCmp);
581 if (cellSctr.lowBound) {
582 if (!(cellSctr.lowBound->isolatedRoot < pointCmp))
585 if (cellSctr.highBound) {
586 if (!(cellSctr.highBound->isolatedRoot > pointCmp))
590 const auto cellSctn = std::get<Section>(cellCmp);
592 SMTRAT_LOG_DEBUG(
"smtrat.cad",
"Section: " << cellSctn <<
" point_" << lvl <<
": " << pointCmp);
593 if (!(cellSctn.isolatedRoot == pointCmp))
603 carl::Variable mainVar,
605 std::vector<std::vector<TagPoly>>& projectionLevels,
608 std::vector<TagPoly>& polys = projectionLevels[currentLevel];
609 SMTRAT_LOG_DEBUG(
"smtrat.cad",
"Do optimized McCallum projection of " << polys);
611 std::vector<std::pair<RAN, Poly>> root_list;
612 for (
auto const& tpoly : polys) {
613 auto poly = tpoly.poly;
615 auto r = carl::real_roots(carl::to_univariate_polynomial(poly, mainVar), cad.
prefixPointToStdMap(currentLevel));
617 if(r.is_nullified()){
620 for(
auto const& root : r.roots()){
621 root_list.emplace_back(std::make_pair(root, poly));
625 SMTRAT_LOG_TRACE(
"smtrat.cad.projection",
"Add leadcoefficient(" << poly <<
") = " << ldcf <<
" (if not const)");
629 if (coeff.has_value()) {
630 SMTRAT_LOG_TRACE(
"smtrat.cad",
"Add result of coeffNonNull: " << coeff.value() <<
" (if not const)");
635 SMTRAT_LOG_TRACE(
"smtrat.cad.projection",
"Add discriminant(" << poly <<
") = " << disc <<
" (if not const)");
640 std::sort(root_list.begin(), root_list.end(), [](
auto const& t1,
auto const& t2) {
641 return t1.first < t2.first;
644 std::vector<std::pair<Poly, Poly>> resultants;
645 if(!root_list.empty()) {
646 for (
auto it = root_list.begin(); it != root_list.end() - 1; it++) {
647 resultants.emplace_back(std::make_pair((*it).second, (*(it+1)).second));
656 std::vector<carl::Variable>& variableOrder,
657 carl::Variable mainVar,
659 std::vector<std::vector<TagPoly>>& projectionLevels) {
661 std::vector<TagPoly>& polys = projectionLevels[currentLevel];
663 for (std::size_t i = 0; i < polys.size(); i++) {
664 Poly poly = polys[i].poly;
666 std::vector<Poly> coeffs = carl::to_univariate_polynomial(poly, mainVar).coefficients();
667 for (
const auto& coeff : coeffs) {
668 SMTRAT_LOG_TRACE(
"smtrat.cad.projection",
"Add coefficient(" << poly <<
") = " << coeff <<
" (if not const)");
673 SMTRAT_LOG_TRACE(
"smtrat.cad.projection",
"Add discriminant(" << poly <<
") = " << disc <<
" (if not const)");
676 std::vector<std::pair<Poly, Poly>> resultants;
677 for (std::size_t j = i + 1; j < polys.size(); j++) {
678 auto poly2 = polys[j].poly;
679 resultants.emplace_back(std::make_pair(poly, poly2));
681 addResultants(resultants, projectionLevels, mainVar, variableOrder);
A collection of helper functions to check assertable conditions for CAD properties,...
Represent the trail, i.e.
const auto & assignedVariables() const
const auto & model() const
const std::vector< carl::Variable > & variableOrder
Variables can also be indexed by level.
std::optional< Poly > coeffNonNull(const TagPoly &boundCandidate)
bool isPointRootOfPoly(const std::size_t polyLevel, const Poly &poly)
bool vanishesEarly(const std::size_t polyLevel, const Poly &poly)
Check if an n-variate 'poly' p(x1,..,xn) with n>=1 already becomes the zero poly after plugging in p(...
std::vector< RAN > isolateLastVariableRoots(const std::size_t polyLevel, const Poly &poly)
src/lib/datastructures/mcsat/onecellcad/OneCellCAD.h Given a poly p(x1,..,xn), return all roots of th...
bool isMainPointInsideCell(const CADCell &cell)
const RealAlgebraicPoint< Rational > & point
std::map< carl::Variable, RAN > prefixPointToStdMap(const std::size_t componentCount)
Create a mapping from the first variables (with index 0 to 'componentCount') in the 'variableOrder' t...
bool isPointRootOfPoly(const TagPoly &poly)
OneCellCAD(const std::vector< carl::Variable > &variableOrder, const RealAlgebraicPoint< Rational > &point)
Represent a multidimensional point whose components are algebraic reals.
void sort(T *array, int size, LessThan lt)
static bool find(V &ts, const T &t)
Rational evaluate(carl::Variable v, const Poly &p, const Rational &r)
bool operator<(const InvarianceType &l, const InvarianceType &r)
std::ostream & operator<<(std::ostream &os, const RealAlgebraicPoint< Number > &r)
Streaming operator for a RealAlgebraicPoint.
std::vector< T > prefix(const std::vector< T > vars, std::size_t prefixSize)
std::vector< std::variant< Sector, Section > > CADCell
Represent a single cell [brown15].
bool isNonConstIrreducible(const PolyType &poly)
bool contains(const std::vector< TagPoly > &polys, const Poly &poly)
std::vector< TagPoly > nonConstIrreducibleFactors(std::vector< carl::Variable > variableOrder, Poly poly, InvarianceType tag)
std::vector< Poly > asMultiPolys(const std::vector< TagPoly > polys)
void appendOnCorrectLevel(const Poly &poly, InvarianceType tag, std::vector< std::vector< TagPoly >> &polys, std::vector< carl::Variable > variableOrder)
std::size_t getDegree(TagPoly p, carl::Variable v)
Poly leadcoefficient(const carl::Variable &mainVariable, const Poly &p)
RealAlgebraicPoint< smtrat::Rational > asRANPoint(const mcsat::Bookkeeping &data)
bool operator==(RealAlgebraicPoint< Number > &lhs, RealAlgebraicPoint< Number > &rhs)
Check if two RealAlgebraicPoints are equal.
std::size_t cellDimension(const CADCell &cell, const std::size_t uptoLevel)
void singleLevelFullProjection(std::vector< carl::Variable > &variableOrder, carl::Variable mainVar, size_t currentLevel, std::vector< std::vector< TagPoly >> &projectionLevels)
MultivariateRootT asRootExpr(carl::Variable rootVariable, Poly poly, std::size_t rootIdx)
CADCell fullSpaceCell(std::size_t cellComponentCount)
bool optimized_singleLevelFullProjection(carl::Variable mainVar, size_t currentLevel, std::vector< std::vector< TagPoly >> &projectionLevels, OneCellCAD &cad)
std::map< carl::Variable, RAN > RANMap
InvarianceType
Invariance Types.
void addResultants(std::vector< std::pair< Poly, Poly >> &resultants, std::vector< std::vector< TagPoly >> &polys, carl::Variable mainVar, const std::vector< carl::Variable > &variableOrder)
std::vector< std::pair< Poly, Poly > > duplicateElimination(std::vector< std::pair< Poly, Poly >> vec)
std::optional< std::size_t > levelOf(const std::vector< carl::Variable > &variableOrder, const Poly &poly)
Find the index of the highest variable (wrt.
Poly discriminant(const carl::Variable &mainVariable, const Poly &p)
Projection related utilities for onecellcad.
bool hasUniqElems(const std::vector< T > &container)
Poly resultant(const carl::Variable &mainVariable, const Poly &p1, const Poly &p2)
std::vector< carl::Variable > vars(const std::pair< QuantifierType, std::vector< carl::Variable >> &p)
Class to create the formulas for axioms.
carl::IntRepRealAlgebraicNumber< Rational > RAN
carl::MultivariatePolynomial< Rational > Poly
carl::MultivariateRoot< Poly > MultivariateRootT
#define SMTRAT_LOG_TRACE(channel, msg)
#define SMTRAT_LOG_DEBUG(channel, msg)
Represent a cell's (closed-interval-boundary) component along th k-th axis.
MultivariateRootT boundFunction
RAN isolatedRoot
For performance we cache the isolated root from ‘boundFunction’ that lies closest along this section'...
Represent a cell's open-interval boundary object along one single axis by two irreducible,...
std::optional< Section > highBound
A std:nullopt highBound represents infinity.
std::optional< Section > lowBound
A std::nullopt lowBound represents negative infinity.