3 #include <carl-arith/constraint/Substitution.h>
4 #include <carl-formula/formula/functions/Complexity.h>
10 namespace preprocessor {
12 inline std::size_t
complexity(
const std::vector<FormulaT>& origin) {
13 return std::accumulate(origin.begin(), origin.end(),
static_cast<std::size_t
>(0),
14 [](std::size_t i,
const auto& f){ return i + carl::complexity(f); }
20 for (
auto oit = it->second.begin(); oit != it->second.end(); ) {
21 auto keep =
std::find(oit->begin(), oit->end(), f) == oit->end();
23 else oit = it->second.erase(oit);
25 if (it->second.empty()) {
36 mOrigins.emplace(f, std::vector<std::vector<FormulaT>>({origin}));
37 SMTRAT_LOG_DEBUG(
"smtrat.cad.pp",
"Adding new origins " << f <<
" -> " << origin);
40 SMTRAT_LOG_DEBUG(
"smtrat.cad.pp",
"Adding new origins " << f <<
" -> " << origin);
41 it->second.emplace_back(origin);
42 std::sort(it->second.begin(), it->second.end(),
43 [](
const auto& a,
const auto& b){
44 if (a.size() != b.size()) return a.size() < b.size();
45 return complexity(a) < complexity(b);
61 return it->second.front();
65 bool didReplacement =
false;
66 for (
const auto& origins:
mOrigins) {
67 const auto& c = origins.second.front();
68 SMTRAT_LOG_DEBUG(
"smtrat.cad.pp",
"Considering origin " << origins.first <<
" -> " << c);
69 if (c.size() == 1 && c.front() == origins.first) {
72 if (conflict.erase(origins.first) > 0) {
73 conflict.insert(c.begin(), c.end());
74 didReplacement =
true;
75 SMTRAT_LOG_DEBUG(
"smtrat.cad.pp",
"Replaced " << origins.first <<
" by origins " << c);
78 return didReplacement;
82 bool foundAssignment =
false;
84 auto assignment = get_assignment(it->second);
85 if (assignment &&
mModel.find(assignment->first) ==
mModel.end()) {
86 SMTRAT_LOG_DEBUG(
"smtrat.cad.pp",
"Newly extracted " << assignment->first <<
" = " << assignment->second);
87 mModel.emplace(assignment->first, assignment->second);
88 mReasons.emplace(assignment->first, it->first);
91 foundAssignment =
true;
97 return foundAssignment;
100 bool foundAssignment =
false;
102 auto substitution = carl::get_substitution(it->second);
103 if (substitution &&
mModel.find(substitution->first) ==
mModel.end()) {
104 SMTRAT_LOG_DEBUG(
"smtrat.cad.pp",
"Newly extracted " << substitution->first <<
" = " << substitution->second);
105 mModel.emplace(substitution->first, carl::createSubstitution<Rational,Poly,ModelPolynomialSubstitution>(substitution->second));
106 mReasons.emplace(substitution->first, it->first);
109 foundAssignment =
true;
116 return foundAssignment;
125 bool changed =
false;
132 if (c.second.is_consistent() == 0) {
133 SMTRAT_LOG_DEBUG(
"smtrat.cad.pp",
"Simplification found conflict in " << c.first <<
" (" << c.second <<
")");
142 if (std::holds_alternative<ConstraintT>(sres)) {
145 assert(std::holds_alternative<bool>(sres));
146 bool foundNew = std::get<bool>(sres);
147 bool continueSearch =
true;
148 while (continueSearch) {
152 if (std::holds_alternative<ConstraintT>(sres)) {
155 assert(std::holds_alternative<bool>(sres));
157 foundNew = foundNew || continueSearch || std::get<bool>(sres);
163 if (is_zero(poly))
return true;
165 std::size_t level = 0;
166 UPoly p = carl::to_univariate_polynomial(poly,
mVars[level]);
169 p = carl::to_univariate_polynomial(poly,
mVars[level]);
171 SMTRAT_LOG_TRACE(
"smtrat.cad.pp",
"Inserting " << p <<
" into level " << level);
173 mData[level].emplace_back(p);
178 if (poly.is_number())
return true;
182 assert(p.main_var() ==
mVars[level]);
185 p = carl::to_univariate_polynomial(mp,
mVars[level]);
187 SMTRAT_LOG_TRACE(
"smtrat.cad.pp",
"Inserting " << p <<
" into level " << level);
192 mData[level].emplace_back(p);
197 if (cons.is_consistent() == 0)
return false;
202 for (std::size_t pid = 0; pid <
mData[level].size(); ++pid) {
203 for (std::size_t qid = pid + 1; qid <
mData[level].size(); ++qid) {
206 std::vector<FormulaT> origin;
208 origin.insert(origin.end(), op.begin(), op.end());
210 origin.insert(origin.end(), oq.begin(), oq.end());
211 if (!
addPoly(r, level + 1, origin)) {
212 SMTRAT_LOG_DEBUG(
"smtrat.cad.pp",
"Found direct conflict due to " << origin);
224 for (
const auto& c: constraints) {
226 if (!
addPoly(c.second.lhs())) {
227 SMTRAT_LOG_DEBUG(
"smtrat.cad.pp",
"Found direct conflict due to " << c.first);
228 return std::vector<FormulaT>({
FormulaT(c.first) });
233 for (std::size_t level = 0; level <
mData.size() - 1; ++level) {
235 if (conflict)
return conflict;
260 bool addedNew =
false;
261 for (
const auto& c: constraints) {
271 std::vector<ConstraintT> cur;
273 cur.emplace_back(c.second);
279 bool didReplacement =
false;
280 for (
const auto& c: constraints) {
281 if (c.first == c.second)
continue;
282 if (conflict.erase(
FormulaT(c.second)) > 0) {
283 conflict.emplace(c.first);
284 didReplacement =
true;
285 SMTRAT_LOG_DEBUG(
"smtrat.cad.pp",
"Replaced " << c.second <<
" by origin " << c.first);
288 return didReplacement;
292 SMTRAT_LOG_DEBUG(
"smtrat.cad.pp",
"Adding necessary parts of model to conflict: " << conflict);
293 carl::carlVariables
vars;
294 bool changed =
false;
295 for (
const auto& f: conflict) carl::variables(f,
vars);
296 while (!
vars.empty()) {
297 carl::carlVariables newvars;
301 if (added.find(v) != added.end())
continue;
303 auto cit = conflict.emplace(it->second);
306 carl::variables(*cit.first, newvars);
307 SMTRAT_LOG_DEBUG(
"smtrat.cad.pp",
"Added " << it->second <<
" to conflict.");
323 SMTRAT_LOG_TRACE(
"smtrat.cad.pp",
"Added " << c <<
" to " << std::endl << *
this);
336 SMTRAT_LOG_TRACE(
"smtrat.cad.pp",
"Removed " << c <<
" from " << std::endl << *
this);
347 SMTRAT_LOG_DEBUG(
"smtrat.cad.pp",
"Collecting assignments from:" << std::endl << *
this);
349 if (std::holds_alternative<ConstraintT>(collectResult)) {
354 assert(std::holds_alternative<bool>(collectResult));
355 if (std::get<bool>(collectResult) ==
true) {
356 SMTRAT_LOG_DEBUG(
"smtrat.cad.pp",
"Collected assignments:" << std::endl << *
this);
370 SMTRAT_LOG_DEBUG(
"smtrat.cad.pp",
"Computing Resultants from:" << std::endl << *
this);
372 if (conflict.has_value()) {
373 mConflict = std::set<FormulaT>(conflict->begin(), conflict->end());
385 carl::substitute_inplace(c.second,
mModel);
386 if (c.second.is_consistent() == 0) {
392 SMTRAT_LOG_DEBUG(
"smtrat.cad.pp",
"After preprocessing:" << std::endl << *
this);
405 SMTRAT_LOG_DEBUG(
"smtrat.cad.pp",
"Postprocessing conflict: " << mis <<
" based on" << std::endl << *
this);
410 carl::Variables modelAdded;
std::vector< ConstraintT > mEqualities
Equalities from the input.
std::map< ConstraintT, ConstraintT > mDerivedEqualities
Derived set of equalities, essentially mEqualities - mModel.
bool collectOriginsOfConflict(std::set< FormulaT > &conflict, const std::map< ConstraintT, ConstraintT > &constraints) const
Replace constraints that have been modified by its origins in the given conflict.
bool addEqualities(const std::vector< ConstraintT > &constraints)
std::set< FormulaT > getConflict() const
void postprocessConflict(std::set< FormulaT > &mis) const
preprocessor::ResultantRule mResultants
The resultant rule.
void removeEquality(const ConstraintT &c)
std::optional< std::set< FormulaT > > mConflict
preprocessor::AssignmentCollector mAssignments
The assignment collector.
void removeConstraint(const ConstraintT &c)
bool addModelToConflict(std::set< FormulaT > &conflict, carl::Variables &added) const
bool preprocess()
Performs the preprocessing.
Model mModel
The model used for variable elimination.
std::vector< ConstraintT > collectDerivedEqualities() const
void addConstraint(const ConstraintT &c)
std::map< ConstraintT, ConstraintT > mInequalities
Inequalities from the input.
preprocessor::Origins mOrigins
Origins of new formulas.
bool extractAssignments(std::map< ConstraintT, ConstraintT > &constraints)
std::map< ConstraintT, carl::Variable > mConstraints
std::variant< bool, ConstraintT > CollectionResult
Result of an assignment collection.
CollectionResult simplify(std::map< ConstraintT, ConstraintT > &constraints)
CollectionResult collect(std::map< ConstraintT, ConstraintT > &constraints)
const auto & reasons() const
bool extractParametricAssignments(std::map< ConstraintT, ConstraintT > &constraints)
bool extractValueAssignments(std::map< ConstraintT, ConstraintT > &constraints)
const auto & constraints() const
std::map< carl::Variable, ConstraintT > mReasons
Reasons for the assignment of variables.
const auto & getNewECs() const
std::vector< std::vector< UPoly > > mData
std::vector< ConstraintT > mNewECs
std::vector< ConstraintT > mConstraints
bool addPoly(const Poly &poly)
std::optional< std::vector< FormulaT > > compute(const std::map< ConstraintT, ConstraintT > &constraints)
std::optional< std::vector< FormulaT > > computeResultants(std::size_t level)
const std::vector< carl::Variable > & mVars
void sort(T *array, int size, LessThan lt)
static bool find(V &ts, const T &t)
static void remove(V &ts, const T &t)
std::size_t complexity(const std::vector< FormulaT > &origin)
Poly resultant(carl::Variable variable, const Poly &p, const Poly &q)
Computes the resultant of two polynomials.
carl::UnivariatePolynomial< Poly > UPoly
const auto & settings_cadpp()
bool is_constant(const T &t)
Checks whether the constraint is constant, i.e.
bool substitute(const FormulaT &constr, const carl::Variable var, const carl::vs::Term< Poly > &term, FormulaT &result)
std::vector< carl::Variable > vars(const std::pair< QuantifierType, std::vector< carl::Variable >> &p)
carl::Formula< Poly > FormulaT
carl::MultivariatePolynomial< Rational > Poly
carl::Constraint< Poly > ConstraintT
#define SMTRAT_LOG_TRACE(channel, msg)
#define SMTRAT_LOG_DEBUG(channel, msg)
static bool register_hook()
const std::vector< FormulaT > & get(const FormulaT &f) const
bool resolve(std::set< FormulaT > &conflict) const
void cleanOrigins(const FormulaT &f)
void add(const FormulaT &f, const std::vector< FormulaT > &origin)
std::map< FormulaT, std::vector< std::vector< FormulaT > > > mOrigins
void remove(const FormulaT &f)