@@ -9,7 +9,7 @@ namespace linspire
99 {
1010 assert (lb <= ub);
1111 const auto x = vars.size ();
12- vars.emplace_back (lb, ub);
12+ vars.emplace_back (x, lb, ub);
1313 t_watches.emplace_back ();
1414 return x;
1515 }
@@ -28,8 +28,8 @@ namespace linspire
2828 return slack;
2929 }
3030
31- utils::inf_rational solver::lb (const utils::var x) const noexcept { return vars[x].lb (); }
32- utils::inf_rational solver::ub (const utils::var x) const noexcept { return vars[x].ub (); }
31+ utils::inf_rational solver::lb (const utils::var x) const noexcept { return vars[x].get_lb (); }
32+ utils::inf_rational solver::ub (const utils::var x) const noexcept { return vars[x].get_ub (); }
3333 utils::inf_rational solver::val (const utils::var x) const noexcept { return vars[x].val ; }
3434
3535 bool solver::new_eq (const utils::lin &lhs, const utils::lin &rhs, std::shared_ptr<constraint> reason) noexcept
@@ -113,18 +113,10 @@ namespace linspire
113113 void solver::retract (const std::shared_ptr<constraint> c) noexcept
114114 {
115115 for (const auto &[x, lb] : c->lbs )
116- {
117- vars[x].lbs [lb].erase (c);
118- if (vars[x].lbs [lb].empty ())
119- vars[x].lbs .erase (lb);
120- }
116+ vars[x].unset_lb (lb, c);
121117 c->lbs .clear ();
122118 for (const auto &[x, ub] : c->ubs )
123- {
124- vars[x].ubs [ub].erase (c);
125- if (vars[x].ubs [ub].empty ())
126- vars[x].ubs .erase (ub);
127- }
119+ vars[x].unset_ub (ub, c);
128120 c->ubs .clear ();
129121 }
130122
@@ -187,57 +179,49 @@ namespace linspire
187179 bool solver::set_lb (const utils::var x, const utils::inf_rational &v, std::shared_ptr<constraint> reason) noexcept
188180 {
189181 assert (x < vars.size ());
182+ assert (v > utils::rational::negative_infinite);
190183 LOG_TRACE (" x" << std::to_string (x) << " = " << utils::to_string (val (x)) << " [" << utils::to_string (lb (x)) << " -> " << utils::to_string (v) << " , " << utils::to_string (ub (x)) << " ]" );
191- if (v <= lb (x))
192- return true ; // no update needed..
193- else if (v > ub (x))
194- return false ; // inconsistent bounds..
195-
184+ if (v > ub (x)) // inconsistent bound..
185+ return false ;
196186 if (reason)
197- {
198- if (auto it = vars[x].lbs .find (v); it != vars[x].lbs .end ())
199- it->second .insert (reason);
187+ { // we have a reason for this bound..
188+ if (auto it = reason->lbs .find (x); it != reason->lbs .end ())
189+ { // we already have a lower bound for this variable in the reason..
190+ if (it->second < v)
191+ { // we update the lower bound only if the new one is more restrictive..
192+ vars.at (x).unset_lb (it->second , reason);
193+ it->second = v;
194+ }
195+ }
200196 else
201- vars[x].lbs .emplace (v, std::set<std::shared_ptr<constraint>>{reason});
202- reason->lbs .emplace (x, v);
203- }
204- else
205- {
206- auto &lbs = vars[x].lbs ;
207- auto it = lbs.upper_bound (v);
208- lbs.erase (lbs.begin (), it);
209- lbs.emplace (v, std::set<std::shared_ptr<constraint>>());
197+ reason->lbs .emplace (x, v);
210198 }
211-
199+ vars. at (x). set_lb (v, reason);
212200 if (val (x) < v && !is_basic (x))
213201 update (x, v);
214202 return true ;
215203 }
216204 bool solver::set_ub (const utils::var x, const utils::inf_rational &v, std::shared_ptr<constraint> reason) noexcept
217205 {
218206 assert (x < vars.size ());
207+ assert (v < utils::rational::positive_infinite);
219208 LOG_TRACE (" x" << std::to_string (x) << " = " << utils::to_string (val (x)) << " [" << utils::to_string (lb (x)) << " , " << utils::to_string (v) << " <- " << utils::to_string (ub (x)) << " ]" );
220- if (v >= ub (x))
221- return true ; // no update needed..
222- else if (v < lb (x))
223- return false ; // inconsistent bounds..
224-
209+ if (v < lb (x)) // inconsistent bound..
210+ return false ;
225211 if (reason)
226- {
227- if (auto it = vars[x].ubs .find (v); it != vars[x].ubs .end ())
228- it->second .insert (reason);
212+ { // we have a reason for this bound..
213+ if (auto it = reason->ubs .find (x); it != reason->ubs .end ())
214+ { // we already have an upper bound for this variable in the reason..
215+ if (it->second > v)
216+ { // we update the upper bound only if the new one is more restrictive..
217+ vars.at (x).unset_ub (it->second , reason);
218+ it->second = v;
219+ }
220+ }
229221 else
230- vars[x].ubs .emplace (v, std::set<std::shared_ptr<constraint>>{reason});
231- reason->ubs .emplace (x, v);
232- }
233- else
234- {
235- auto &ubs = vars[x].ubs ;
236- auto it = ubs.lower_bound (v);
237- ubs.erase (it, ubs.end ());
238- ubs.emplace (v, std::set<std::shared_ptr<constraint>>());
222+ reason->ubs .emplace (x, v);
239223 }
240-
224+ vars. at (x). set_ub (v, reason);
241225 if (val (x) > v && !is_basic (x))
242226 update (x, v);
243227 return true ;
@@ -350,11 +334,6 @@ namespace linspire
350334 tableau.emplace (x, std::move (l));
351335 }
352336
353- var::var (const utils::inf_rational &lb, const utils::inf_rational &ub) noexcept { assert (lb < ub); }
354-
355- utils::inf_rational var::lb () const noexcept { return lbs.empty () ? utils::rational::negative_infinite : lbs.rbegin ()->first ; }
356- utils::inf_rational var::ub () const noexcept { return ubs.empty () ? utils::rational::positive_infinite : ubs.begin ()->first ; }
357-
358337 std::string to_string (const solver &s) noexcept
359338 {
360339 std::string str;
@@ -381,18 +360,6 @@ namespace linspire
381360
382361 json::json to_json (const utils::rational &r) noexcept { return json::json{{" num" , r.numerator ()}, {" den" , r.denominator ()}}; }
383362
384- std::string to_string (const var &x) noexcept { return utils::to_string (x.val ) + " [" + utils::to_string (x.lb ()) + " , " + utils::to_string (x.ub ()) + " ]" ; }
385-
386- json::json to_json (const var &x) noexcept
387- {
388- json::json j = linspire::to_json (x.val );
389- if (!x.lbs .empty ())
390- j[" lb" ] = linspire::to_json (x.lbs .rbegin ()->first );
391- if (!x.ubs .empty ())
392- j[" ub" ] = linspire::to_json (x.ubs .begin ()->first );
393- return j;
394- }
395-
396363 json::json to_json (const utils::inf_rational &r) noexcept
397364 {
398365 json::json j = to_json (r.get_rational ());
0 commit comments