11 #include <carl-formula/model/Assignment.h>
28 template<
typename Settings>
33 using Super::mLiftingQueues;
34 using Super::mOperator;
35 using Super::callRemoveCallback;
47 std::vector<std::vector<std::pair<UPoly,std::size_t>>>
mPolynomials;
52 assert(level > 0 && level <=
dim());
53 return mPolynomialIDs[level - 1];
55 const auto&
polyIDs(std::size_t level)
const {
56 assert(level > 0 && level <=
dim());
57 return mPolynomialIDs[level - 1];
59 auto&
polys(std::size_t level) {
60 assert(level > 0 && level <=
dim());
61 return mPolynomials[level - 1];
63 const auto&
polys(std::size_t level)
const {
64 assert(level > 0 && level <=
dim());
65 return mPolynomials[level - 1];
70 assert(level > 0 && level <=
dim());
71 assert(polyIDs(level).
find(p) == polyIDs(level).end());
72 std::size_t
id = polys(level).size();
73 polys(level).emplace_back(p, origin);
74 polyIDs(level).emplace(p,
id);
79 assert(level > 0 && level <=
dim());
80 auto it = polyIDs(level).find(polys(level).back().first);
81 assert(it != polyIDs(level).end());
83 polyIDs(level).erase(it);
84 polys(level).pop_back();
89 auto val = mModel.evaluated(
var);
90 assert(val.isRational() || val.isRAN());
91 RAN value = val.isRational() ?
RAN(val.asRational()) : val.asRAN();
93 for (std::size_t pid = 0; pid <
size(level); pid++) {
96 if (carl::is_zero(psubs))
continue;
97 auto polyvars = carl::variables(poly);
98 polyvars.erase(poly.main_var());
99 auto list = carl::real_roots(poly, *carl::get_ran_assignment(polyvars, model));
100 if (list.is_nullified())
continue;
101 assert(list.is_univariate());
103 std::optional<std::pair<RAN,bool>> lower;
104 std::optional<std::pair<RAN,bool>> upper;
105 for (
const auto& root: list.roots()) {
107 if (!lower || root > lower->first) {
108 lower = std::make_pair(root,
true);
111 }
else if (root == value) {
112 lower = std::make_pair(root,
true);
117 if (!upper || root < upper->first) {
118 upper = std::make_pair(root,
true);
128 assert(level > 0 && level <=
dim());
131 addToCorrectLevel(level + 1, carl::switch_main_variable(p,
var(level+1)), origin);
134 SMTRAT_LOG_DEBUG(
"smtrat.cad.projection",
"Adding " << p <<
" to projection level " << level);
135 assert(p.main_var() ==
var(level));
136 auto it = polyIDs(level).find(p);
137 if (it != polyIDs(level).end()) {
139 if (level > 0 && !(polys(level)[it->second].second <= origin)) {
140 polys(level)[it->second].second = origin;
144 insertPolynomial(level, p, origin);
149 assert(level > 0 && level <=
dim());
153 return addToProjection(level + 1, carl::switch_main_variable(p,
var(level+1)), origin);
155 SMTRAT_LOG_DEBUG(
"smtrat.cad.projection",
"Adding " << p <<
" to projection level " << level);
156 assert(p.main_var() ==
var(level));
157 auto it = polyIDs(level).find(p);
158 if (it != polyIDs(level).end()) {
161 assert(polys(level)[it->second].second <= origin);
163 return carl::Bitset();
165 carl::Bitset res = carl::Bitset();
167 if (level == 1 &&
dim() > 1) {
168 mOperator(Settings::projectionOperator, p,
var(level + 1),
169 [&](
const UPoly& np){ addToCorrectLevel(level + 1, np, origin); }
171 for (
const auto& it: polys(level)) {
172 std::size_t newOrigin = std::max(origin, it.second);
173 mOperator(Settings::projectionOperator, p, it.first,
var(level + 1),
174 [&](
const UPoly& np){ addToCorrectLevel(level + 1, np, newOrigin); }
179 insertPolynomial(level, p, origin);
190 mPolynomials.clear();
191 mPolynomials.resize(
dim());
192 mPolynomialIDs.clear();
193 mPolynomialIDs.resize(
dim());
200 SMTRAT_LOG_DEBUG(
"smtrat.cad.projection",
"Adding " << p <<
" from constraint " << cid);
201 assert(p.main_var() ==
var(1));
202 return addToProjection(1, p, cid);
210 SMTRAT_LOG_DEBUG(
"smtrat.cad.projection",
"Removing " << p <<
" from constraint " << cid);
211 assert(polys(1).back().first == p);
212 assert(polys(1).back().second == cid);
214 std::size_t origin = cid;
218 for (std::size_t level = 2; level <=
dim(); level++) {
219 carl::Bitset removed;
220 if (polys(level).empty())
continue;
221 while (polys(level).back().second == origin) {
222 std::size_t
id = polys(level).size() - 1;
227 assert(polys(level).
empty() || polys(level).back().second < origin);
234 assert(level > 1 && level <
dim());
236 for(std::size_t l =
dim(); l > level; l--) {
237 carl::Variable v =
var(l);
238 if (mModel.find(v) == mModel.end())
continue;
239 m.emplace(v, mModel.evaluated(v));
241 bool modelBased = m.find(
var(level)) != m.end();
243 SMTRAT_LOG_INFO(
"smtrat.cad.projection",
"Projection is model-based for " <<
var(level));
245 SMTRAT_LOG_INFO(
"smtrat.cad.projection",
"Projection is not model-based for " <<
var(level));
248 for(
const auto& it: polys(level)) {
249 assert(it.first.main_var() ==
var(level));
251 mOperator(Settings::projectionOperator, it.first,
var(level + 1),
252 [&](
const UPoly& np){ addToCorrectLevel(level + 1, np, it.second); }
257 std::pair<std::size_t, std::size_t> pids;
258 findPIDsForProjection(
var(level), level, m, pids);
259 for (
const auto& itPID: polys(level)) {
261 std::size_t newOrigin = std::max(it.second, itPID.second);
262 mOperator(Settings::projectionOperator, it.first, itPID.first,
var(level + 1),
263 [&](
const UPoly& np){ addToCorrectLevel(level + 1, np, newOrigin); }
269 for (
const auto& itPID: polys(level)) {
270 std::size_t newOrigin = std::max(it.second, itPID.second);
271 mOperator(Settings::projectionOperator, it.first, itPID.first,
var(level + 1),
272 [&](
const UPoly& np){ addToCorrectLevel(level + 1, np, newOrigin); }
282 std::size_t
size(std::size_t level)
const override {
283 return polys(level).size();
286 bool empty(std::size_t level)
const override {
287 return polys(level).empty();
292 return carl::Bitset();
295 assert(level > 0 && level <=
dim());
296 return id < polys(level).size();
300 assert(level > 0 && level <=
dim());
301 assert(
id < polys(level).
size());
302 return polys(level)[id].first;
308 for (std::size_t level = 1; level <= p.
dim(); level++) {
309 os << level <<
" / " << p.
var(level) <<
":" << std::endl;
310 for (
const auto& it: p.polys(level)) {
311 os <<
"\t" << it.first <<
" [" << it.second <<
"]" << std::endl;
void removePolynomial(const Poly &p, std::size_t cid, bool isBound)
Removes the given polynomial from the projection. Converts to a UPoly and calls the appropriate overl...
ProjectionOperator mOperator
The projection operator.
std::size_t dim() const
Returns the dimension of the projection.
virtual const UPoly & getPolynomialById(std::size_t level, std::size_t id) const =0
Retrieves a polynomial from its id.
std::vector< PolynomialLiftingQueue< BaseProjection > > mLiftingQueues
List of lifting queues that can be used for incremental projection.
carl::Variable var(std::size_t level) const
Returns the variable that corresponds to the given level, that is the variable eliminated in this lev...
void callRemoveCallback(std::size_t level, const SampleLiftedWith &slw) const
void projectNextLevel(std::size_t level)
Performs the projection model-based for one level, using only polynomials with closest roots.
bool empty(std::size_t level) const override
Returns whether the number of polynomials in this level is zero.
void insertPolynomial(std::size_t level, const UPoly &p, std::size_t origin)
Inserts a polynomial with the given origin into the given level.
carl::Bitset addPolynomial(const UPoly &p, std::size_t cid, bool) override
Adds the given polynomial to the projection with the given constraint id as origin.
const auto & polys(std::size_t level) const
ModelBasedProjection(const Constraints &c, const Model &model)
const UPoly & getPolynomialById(std::size_t level, std::size_t id) const override
Get the polynomial from this level with the given id.
std::vector< std::vector< std::pair< UPoly, std::size_t > > > mPolynomials
Stores polynomials with their origin constraint ids.
void addToCorrectLevel(std::size_t level, const UPoly &p, std::size_t origin)
Adds a polynomial with the given origin to the suitable level.
std::size_t size(std::size_t level) const override
Returns the number of polynomials in this level.
void reset()
Resets all datastructures, use the given variables from now on.
void removePolynomial(const UPoly &p, std::size_t cid, bool) override
Removed the given polynomial from the projection.
carl::Bitset projectNewPolynomial(const ConstraintSelection &=carl::Bitset(true))
Returns false, as the projection is not incremental.
auto & polys(std::size_t level)
void findPIDsForProjection(carl::Variable var, std::size_t level, const Model &model, std::pair< std::size_t, std::size_t > &pids)
Finds pids of polynomials with closest roots.
const auto & polyIDs(std::size_t level) const
std::vector< std::map< UPoly, std::size_t > > mPolynomialIDs
Maps polynomials to a (per level) unique ID.
bool hasPolynomialById(std::size_t level, std::size_t id) const override
auto & polyIDs(std::size_t level)
carl::Bitset addToProjection(std::size_t level, const UPoly &p, std::size_t origin)
Adds a new polynomial to the given level (used to performs the first step of the projection)
void removePolynomial(std::size_t level)
Removed the last polynomial from the given level.
static bool find(V &ts, const T &t)
bool canBeRemoved(const UPoly &p)
Checks whether a polynomial can safely be ignored.
bool canBeForwarded(std::size_t, const UPoly &p)
Checks whether a polynomial can safely be forwarded to the next level.
std::ostream & operator<<(std::ostream &os, const SampleIteratorQueue< I, C > &siq)
carl::UnivariatePolynomial< Poly > UPoly
carl::Bitset SampleLiftedWith
carl::Bitset ConstraintSelection
bool substitute(const FormulaT &constr, const carl::Variable var, const carl::vs::Term< Poly > &term, FormulaT &result)
Class to create the formulas for axioms.
const settings::Settings & Settings()
carl::Model< Rational, Poly > Model
#define SMTRAT_LOG_INFO(channel, msg)
#define SMTRAT_LOG_DEBUG(channel, msg)