5 #include <carl-arith/interval/Interval.h>
6 #include <carl-arith/intervalcontraction/Contractor.h>
7 #include <carl-arith/interval/Sampling.h>
23 std::map<carl::Variable, carl::Interval<double>>
mBox;
34 [](
const auto&
qe) { return qe.priority > threshold_priority; }
38 return std::any_of(
mBox.begin(),
mBox.end(),
40 return (!dim.second.is_unbounded()) && dim.second.diameter() < threshold_width;
51 carl::Interval<Rational> i(lower, upper);
56 i.lower() * (absside - 1) + i.upper()
60 i.lower() + i.upper() * (absside - 1),
65 auto res = carl::sample_stern_brocot(i /
Rational(absside));
70 std::pair<bool,double>
update_model(carl::Variable v,
const std::vector<carl::Interval<double>>& intervals) {
71 auto it =
mBox.find(v);
72 assert(it !=
mBox.end());
73 auto& cur = it->second;
76 if (cur.lower_bound() < intervals.front().lower_bound()) {
77 cur = carl::Interval<double>(intervals.front().lower(), intervals.front().lower_bound_type(), cur.upper(), cur.upper_bound_type());
80 if (intervals.back().upper_bound() < cur.upper_bound()) {
81 cur = carl::Interval<double>(cur.lower(), cur.lower_bound_type(), intervals.back().upper(), intervals.back().upper_bound_type());
85 if (old.is_infinite()) {
86 if (cur.is_infinite()) {
88 return std::make_pair(changed, 0.0);
92 return std::make_pair(changed, 1.0);
94 }
else if (old.is_unbounded()) {
95 assert(!cur.is_infinite());
96 if (cur.is_unbounded()) {
98 if (old.lower() < cur.lower() || cur.upper() < old.upper()) {
102 return std::make_pair(changed, 0.0);
107 return std::make_pair(changed, 1.0);
111 auto size = old.diameter();
112 return std::make_pair(changed, (size - cur.diameter()) / size);
116 std::optional<FormulaT>
find_excluded_interval(carl::Variable v,
const std::vector<carl::Interval<double>>& admissible)
const {
120 SMTRAT_LOG_DEBUG(
"smtrat.mcsat.icp",
"Checking whether the current model is admissible...");
121 auto value =
mModel.evaluated(v);
122 if (value.isRational()) {
125 std::optional<Rational> lower;
126 std::optional<Rational> upper;
127 for (std::size_t i = 0; i < admissible.size(); ++i) {
128 const auto& a = admissible[i];
129 carl::Interval<Rational> cur(
130 carl::rationalize<Rational>(a.lower()),
131 a.lower_bound_type(),
132 carl::rationalize<Rational>(a.upper()),
141 if (cur.contains(val)) {
147 if (lower || upper) {
151 subs.emplace_back(v - *lower, carl::Relation::LEQ);
155 subs.emplace_back(v - *upper, carl::Relation::GEQ);
170 SMTRAT_LOG_DEBUG(
"smtrat.mcsat.icp",
"Constructing " << constraints <<
" => " << excluded);
171 constraints.emplace_back(excluded);
176 #ifdef SMTRAT_DEVOPTION_Validation
179 for (
const auto& kv:
mBox) {
180 if (kv.second.lower_bound_type() != carl::BoundType::INFTY || kv.second.upper_bound_type() != carl::BoundType::INFTY) {
186 if (kv.second.lower_bound_type() == carl::BoundType::WEAK) {
188 box.emplace_back(
ConstraintT(
Poly(carl::rationalize<Rational>(kv.second.lower())) - kv.first, carl::Relation::GREATER));
189 }
else if (kv.second.lower_bound_type() == carl::BoundType::STRICT) {
190 box.emplace_back(
ConstraintT(
Poly(carl::rationalize<Rational>(kv.second.lower())) - kv.first, carl::Relation::GEQ));
192 if (kv.second.upper_bound_type() == carl::BoundType::WEAK) {
194 box.emplace_back(
ConstraintT(
Poly(kv.first) - carl::rationalize<Rational>(kv.second.upper()), carl::Relation::GREATER));
195 }
else if (kv.second.upper_bound_type() == carl::BoundType::STRICT) {
196 box.emplace_back(
ConstraintT(
Poly(kv.first) - carl::rationalize<Rational>(kv.second.upper()), carl::Relation::GEQ));
207 mBox.emplace(v, carl::Interval<double>(0, carl::BoundType::INFTY, 0, carl::BoundType::INFTY));
209 for (
const auto& c: constraints) {
210 if (c.constraint().relation() == carl::Relation::NEQ)
continue;
211 for (
const auto& v: c.variables()) {
212 mContractors.emplace_back(
QueueEntry {1.0, carl::contractor::Contractor<FormulaT, Poly>(c, c.constraint(), v)});
221 SMTRAT_LOG_DEBUG(
"smtrat.mcsat.icp",
"No contraction candidate above the threshold, terminating.");
225 SMTRAT_LOG_DEBUG(
"smtrat.mcsat.icp",
"The box is below the threshold, terminating.");
228 bool contracted =
false;
231 SMTRAT_LOG_DEBUG(
"smtrat.mcsat.icp",
"Contracting " <<
mBox <<
" with " << c.contractor.var() <<
" by " << c.contractor.origin());
232 auto res = c.contractor.contract(
mBox);
235 SMTRAT_LOG_DEBUG(
"smtrat.mcsat.icp",
"Contracted to empty interval, conflict for " << c.contractor.var());
242 SMTRAT_LOG_DEBUG(
"smtrat.mcsat.icp",
"Contracted to exclude current model, conflict for " << c.contractor.var());
246 SMTRAT_LOG_DEBUG(
"smtrat.mcsat.icp",
"Contracted " << c.contractor.var() <<
" to " << res);
247 auto update_result =
update_model(c.contractor.var(), res);
248 SMTRAT_LOG_DEBUG(
"smtrat.mcsat.icp",
"Updated: " << update_result.first <<
"; Contraction factor: " << update_result.second);
249 if (update_result.first) {
253 c.priority =
weight_age * c.priority + update_result.second * (1 - c.priority);
261 SMTRAT_LOG_DEBUG(
"smtrat.mcsat.icp",
"No contraction candidate worked, reached a fixpoint.");
#define SMTRAT_VALIDATION_ADD(channel, name, formula, consistent)
std::vector< FormulaT > get(carl::Variable v, bool negate=true) const
void add(const Contractor &c)
std::pair< bool, double > update_model(carl::Variable v, const std::vector< carl::Interval< double >> &intervals)
std::optional< FormulaT > execute()
static constexpr double weight_age
IntervalPropagation(const std::vector< carl::Variable > &vars, const std::vector< FormulaT > &constraints, const Model &model)
auto construct_direct_conflict(carl::Variable v) const
bool has_interval_below_threshold() const
Dependencies mDependencies
auto construct_interval_conflict(carl::Variable v, const FormulaT &excluded) const
std::optional< FormulaT > find_excluded_interval(carl::Variable v, const std::vector< carl::Interval< double >> &admissible) const
static constexpr double threshold_width
static constexpr double threshold_priority
Rational sample_small_rational(const Rational &lower, const Rational &upper, int side) const
Samples a rational with a small representation size.
void validate_box() const
bool has_contractor_above_threshold() const
std::vector< QueueEntry > mContractors
std::map< carl::Variable, carl::Interval< double > > mBox
Numeric abs(const Numeric &_value)
Calculates the absolute value of the given Numeric.
std::optional< FormulaT > qe(const FormulaT &input)
std::vector< carl::Variable > vars(const std::pair< QuantifierType, std::vector< carl::Variable >> &p)
Class to create the formulas for axioms.
carl::Formula< Poly > FormulaT
carl::Model< Rational, Poly > Model
carl::MultivariatePolynomial< Rational > Poly
carl::Constraint< Poly > ConstraintT
carl::Formulas< Poly > FormulasT
#define SMTRAT_LOG_DEBUG(channel, msg)
carl::contractor::Contractor< FormulaT, Poly > contractor