8 #include <carl-formula/model/Assignment.h>
15 namespace arithmetic {
17 using carl::operator<<;
33 SMTRAT_LOG_TRACE(
"smtrat.mcsat.assignmentfinder",
"is " << f <<
" univariate in " <<
mVar <<
"?");
34 carl::Variables
vars = carl::arithmetic_variables(f).as_set();
37 if (it ==
vars.end())
return false;
47 SMTRAT_LOG_TRACE(
"smtrat.mcsat.assignmentfinder",
"Evaluating " << f <<
" on " << m <<
" -> " << res);
48 if (!res.isBool())
return true;
54 SMTRAT_LOG_DEBUG(
"smtrat.mcsat.assignmentfinder", lhs <<
" < " << rhs <<
"?");
62 if (carl::is_integer(l) != carl::is_integer(r))
return carl::is_integer(l);
63 if (l.is_numeric() != r.is_numeric())
return l.is_numeric();
64 if (carl::bitsize(l) != carl::bitsize(r))
return carl::bitsize(l) < carl::bitsize(r);
70 std::vector<std::size_t> samples;
74 assert(samples.size() > 0);
75 SMTRAT_LOG_DEBUG(
"smtrat.mcsat.assignmentfinder",
"Finding minimum from " << samples);
76 auto min = std::min_element(samples.begin(), samples.end(), [
this](
auto lhs,
auto rhs){ return this->compare_assignments(lhs, rhs); });
84 assert(f.type() == carl::FormulaType::CONSTRAINT);
89 assert(f.is_true() || f.is_false());
90 if (f.is_false())
return false;
93 SMTRAT_LOG_TRACE(
"smtrat.mcsat.assignmentfinder",
"Checking fully assigned " << f);
96 SMTRAT_LOG_TRACE(
"smtrat.mcsat.assignmentfinder",
"Ignoring " << f <<
" which simplified to true.");
99 assert(fnew.is_false());
100 SMTRAT_LOG_DEBUG(
"smtrat.mcsat.assignmentfinder",
"Conflict: " << f <<
" simplified to false.");
106 SMTRAT_LOG_DEBUG(
"smtrat.mcsat.assignmentfinder",
"Considering univariate constraint " << f);
109 SMTRAT_LOG_DEBUG(
"smtrat.mcsat.assignmentfinder",
"Considering unassigned constraint " << f <<
" (which may still become univariate)");
114 std::vector<RAN> list;
115 if (fnew.type() == carl::FormulaType::CONSTRAINT) {
116 const auto& poly = fnew.constraint().lhs();
118 auto upoly = carl::to_univariate_polynomial(poly,
mVar);
119 auto polyvars = carl::variables(upoly);
120 polyvars.erase(
mVar);
121 auto roots = carl::real_roots(upoly, *carl::get_ran_assignment(polyvars,
mModel));
122 if (roots.is_univariate()) {
123 list = roots.roots();
126 assert(roots.is_nullified());
127 SMTRAT_LOG_DEBUG(
"smtrat.mcsat.assignmentfinder",
"Failed to compute roots because polynomial is nullified.");
128 if (
carl::evaluate(carl::Sign::ZERO, fnew.constraint().relation())) {
129 SMTRAT_LOG_DEBUG(
"smtrat.mcsat.assignmentfinder", f <<
" simplified to true.");
132 SMTRAT_LOG_DEBUG(
"smtrat.mcsat.assignmentfinder",
"Conflict: " << f <<
" simplified to false.");
136 }
else if (fnew.is_true()) {
137 SMTRAT_LOG_TRACE(
"smtrat.mcsat.assignmentfinder",
"Ignoring " << f <<
" which simplified to true.");
140 assert(fnew.is_false());
141 SMTRAT_LOG_DEBUG(
"smtrat.mcsat.assignmentfinder",
"Conflict: " << f <<
" simplified to false.");
145 SMTRAT_LOG_DEBUG(
"smtrat.mcsat.assignmentfinder",
"Adding " << list <<
" with " << fnew);
147 mRootMap.emplace(f, std::make_pair(std::move(list), fnew));
152 assert(f.type() == carl::FormulaType::VARCOMPARE);
154 SMTRAT_LOG_DEBUG(
"smtrat.mcsat.assignmentfinder",
"Ignoring non-univariate bound " << f);
157 SMTRAT_LOG_DEBUG(
"smtrat.mcsat.assignmentfinder",
"Adding univariate bound " << f);
160 if (fnew.is_true()) {
161 SMTRAT_LOG_DEBUG(
"smtrat.mcsat.assignmentfinder",
"Bound evaluated to true, we can ignore it.");
163 }
else if (fnew.is_false()) {
164 SMTRAT_LOG_DEBUG(
"smtrat.mcsat.assignmentfinder",
"Conflict: " << f <<
" simplified to false.");
167 assert(fnew.type() == carl::FormulaType::VARCOMPARE);
168 ModelValue value = fnew.variable_comparison().value();
169 if (value.isSubstitution()) {
171 auto res = value.asSubstitution()->evaluate(
mModel);
174 SMTRAT_LOG_DEBUG(
"smtrat.mcsat.assignmentfinder",
"Evaluated to " << value);
175 if (!value.isRational() && !value.isRAN()) {
176 SMTRAT_LOG_DEBUG(
"smtrat.mcsat.assignmentfinder",
"Value is neither rational nor RAN, cannot generate roots from it");
177 if (value.isBool()) {
184 std::vector<RAN> list;
185 if (value.isRational()) list.emplace_back(value.asRational());
186 else list.push_back(value.asRAN());
187 SMTRAT_LOG_DEBUG(
"smtrat.mcsat.assignmentfinder",
"Adding " << list <<
" with " << fnew);
189 mRootMap.emplace(f, std::make_pair(std::move(list), fnew));
199 const auto& roots = c.second.first;
200 const auto& constraint = c.second.second;
201 std::size_t last = 0;
202 for (
const auto& r: roots) {
203 std::size_t cur =
mRI[r];
208 b.set_interval(last, 2*cur);
213 SMTRAT_LOG_DEBUG(
"smtrat.mcsat.assignmentfinder", constraint <<
" refutes " << r <<
" -> " << 2*cur+1);
214 b.set(2*cur+1, 2*cur+1);
223 b.set_interval(last,
mRI.
size()*2);
226 cover.
add(c.first, b);
265 SMTRAT_LOG_DEBUG(
"smtrat.mcsat.assignmentfinder",
"No Assignment, built conflicting core " << conflict <<
" under model " <<
mModel);
270 assert(assignment.isRAN());
271 if (assignment.asRAN().is_numeric()) {
272 assignment = assignment.asRAN().value();
274 SMTRAT_LOG_DEBUG(
"smtrat.mcsat.assignmentfinder",
"Assignment: " <<
mVar <<
" = " << assignment);
276 res.push_back(std::make_pair(
mVar,assignment));
bool addMVBound(const FormulaT &f)
AssignmentFinder_detail(carl::Variable var, const Model &model)
std::map< FormulaT, std::pair< std::vector< RAN >, FormulaT > > mRootMap
Maps the input formula to the list of real roots and the simplified formula where mModel was substitu...
bool compare_assignments(std::size_t lhs, std::size_t rhs) const
bool is_univariate(const FormulaT &f) const
Checks whether a formula is univariate, meaning it contains mVar and only variables from mModel other...
std::vector< FormulaT > mMVBounds
bool addConstraint(const FormulaT &f)
bool satisfies(const FormulaT &f, const RAN &r) const
RootIndexer< typename Poly::RootType > mRI
AssignmentOrConflict findAssignment()
ModelValue selectAssignment(const Covering &cover) const
Semantics: The space is divided into a number of intervals: (-oo,a)[a,a](a,b)[b,b](b,...
void buildConflictingCore(std::vector< FormulaT > &core) const
const auto & satisfyingSamples() const
void add(const FormulaT &c, const carl::Bitset &b)
std::size_t satisfyingInterval() const
void add(const std::vector< RANT > &list)
bool is_root(std::size_t n) const
const RANT & sampleFrom(std::size_t n) const
Numeric abs(const Numeric &_value)
Calculates the absolute value of the given Numeric.
Rational evaluate(carl::Variable v, const Poly &p, const Rational &r)
bool is_univariate(const T &t, const Model &model, carl::Variable next)
Checks whether the constraint contains only a single unassigned variable, and this is the next one.
ConstraintType categorize(const T &t, const Model &model, carl::Variable next)
bool substitute(const FormulaT &constr, const carl::Variable var, const carl::vs::Term< Poly > &term, FormulaT &result)
std::vector< std::pair< carl::Variable, ModelValue > > ModelValues
@ Unassigned
The constraint has a single unassigned variable being the next one.
@ Univariate
The constraint is fully assigned.
@ Assigned
The constraint contains no variables.
std::variant< ModelValues, FormulasT > AssignmentOrConflict
std::vector< carl::Variable > vars(const std::pair< QuantifierType, std::vector< carl::Variable >> &p)
Class to create the formulas for axioms.
carl::ModelValue< Rational, Poly > ModelValue
carl::Formula< Poly > FormulaT
carl::Model< Rational, Poly > Model
carl::Formulas< Poly > FormulasT
#define SMTRAT_LOG_TRACE(channel, msg)
#define SMTRAT_LOG_DEBUG(channel, msg)