@@ -41,7 +41,7 @@ namespace linspire
4141 utils::inf_rational solver::ub (const utils::var x) const noexcept { return vars[x].get_ub (); }
4242 utils::inf_rational solver::val (const utils::var x) const noexcept { return vars[x].val ; }
4343
44- bool solver::new_eq (const utils::lin &lhs, const utils::lin &rhs, constraint * reason) noexcept
44+ bool solver::new_eq (const utils::lin &lhs, const utils::lin &rhs, std::optional<std::reference_wrapper< constraint>> reason) noexcept
4545 {
4646 LOG_TRACE (utils::to_string (lhs) + " == " + utils::to_string (rhs));
4747 utils::lin expr = lhs - rhs;
@@ -68,18 +68,17 @@ namespace linspire
6868 assert (c != 0 );
6969 const utils::inf_rational c_right = utils::inf_rational (-expr.known_term ) / c; // the right-hand side of the constraint is the division of the negation of the known term by the coefficient..
7070 // we can set both the lower and upper bound of the variable to the right-hand side of the constraint..
71- return set_lb (x, c_right, reason) && set_ub (x, c_right, reason);
71+ return reason ? set_lb (x, c_right, reason. value ()) && set_ub (x, c_right, reason. value ()) : set_lb (x, c_right) && set_ub (x, c_right );
7272 }
7373 default : // the expression is still a general linear expression..
7474 const utils::inf_rational c_right = utils::inf_rational (-expr.known_term );
7575 expr.known_term = utils::rational::zero;
7676 // we add the expression to the tableau, associating it with a new (slack) variable
7777 utils::var slack = new_var (std::move (expr));
78- return set_lb (slack, c_right, reason) && set_ub (slack, c_right, reason);
78+ return reason ? set_lb (slack, c_right, reason. value ()) && set_ub (slack, c_right, reason. value ()) : set_lb (slack, c_right) && set_ub (slack, c_right );
7979 }
8080 }
81-
82- bool solver::new_lt (const utils::lin &lhs, const utils::lin &rhs, bool strict, constraint *reason) noexcept
81+ bool solver::new_lt (const utils::lin &lhs, const utils::lin &rhs, bool strict, std::optional<std::reference_wrapper<constraint>> reason) noexcept
8382 {
8483 LOG_TRACE (utils::to_string (lhs) + (strict ? " < " : " <= " ) + utils::to_string (rhs));
8584 utils::lin expr = lhs - rhs;
@@ -106,18 +105,25 @@ namespace linspire
106105 assert (c != 0 );
107106 const utils::inf_rational c_right = utils::inf_rational (-expr.known_term , strict ? -1 : 0 ) / c; // the right-hand side of the constraint is the division of the negation of the known term minus an infinitesimal by the coefficient..
108107 if (is_positive (c))
109- return set_ub (x, c_right, reason); // we are in the case `c * v < c_right`..
108+ return reason ? set_ub (x, c_right, reason. value ()) : set_ub (x, c_right ); // we are in the case `c * v < c_right`..
110109 else
111- return set_lb (x, c_right, reason); // we are in the case `c * v > c_right`..
110+ return reason ? set_lb (x, c_right, reason. value ()) : set_lb (x, c_right ); // we are in the case `c * v > c_right`..
112111 }
113112 default : // the expression is still a general linear expression..
114113 const utils::inf_rational c_right = utils::inf_rational (-expr.known_term , strict ? -1 : 0 );
115114 expr.known_term = utils::rational::zero;
116115 // we add the expression to the tableau, associating it with a new (slack) variable
117116 utils::var slack = new_var (std::move (expr));
118- return set_ub (slack, c_right, reason); // we are in the case `expr < c_right`..
117+ return reason ? set_ub (slack, c_right, reason. value ()) : set_ub (slack, c_right ); // we are in the case `expr < c_right`..
119118 }
120119 }
120+ bool solver::new_gt (const utils::lin &lhs, const utils::lin &rhs, bool strict, std::optional<std::reference_wrapper<constraint>> reason) noexcept
121+ {
122+ if (reason)
123+ return new_lt (rhs, lhs, strict, *reason);
124+ else
125+ return new_lt (rhs, lhs, strict);
126+ }
121127
122128 void solver::retract (constraint &c) noexcept
123129 {
@@ -152,12 +158,12 @@ namespace linspire
152158 for (const auto &[v, c] : l.vars )
153159 if (is_positive (c)) // we use the most restrictive upper bound of v
154160 for (const auto &w : vars.at (v).ubs .begin ()->second )
155- cnfl.push_back (w);
161+ cnfl.push_back (* w);
156162 else if (is_negative (c)) // we use the most restrictive lower bound of v
157163 for (const auto &w : vars.at (v).lbs .rbegin ()->second )
158- cnfl.push_back (w);
164+ cnfl.push_back (* w);
159165 for (const auto &w : vars.at (x_i).lbs .rbegin ()->second ) // we use the most restrictive lower bound of x_i
160- cnfl.push_back (w);
166+ cnfl.push_back (* w);
161167 return false ;
162168 }
163169 }
@@ -173,12 +179,12 @@ namespace linspire
173179 for (const auto &[v, c] : l.vars )
174180 if (is_positive (c)) // we use the most restrictive lower bound of v
175181 for (const auto &w : vars.at (v).lbs .rbegin ()->second )
176- cnfl.push_back (w);
182+ cnfl.push_back (* w);
177183 else if (is_negative (c)) // we use the most restrictive upper bound of v
178184 for (const auto &w : vars.at (v).ubs .begin ()->second )
179- cnfl.push_back (w);
185+ cnfl.push_back (* w);
180186 for (const auto &w : vars.at (x_i).ubs .begin ()->second ) // we use the most restrictive upper bound of x_i
181- cnfl.push_back (w);
187+ cnfl.push_back (* w);
182188 return false ;
183189 }
184190 }
@@ -187,7 +193,7 @@ namespace linspire
187193
188194 bool solver::match (const utils::lin &l0, const utils::lin &l1) const noexcept { return lb (l0) <= ub (l1) && ub (l0) >= lb (l1); }
189195
190- bool solver::set_lb (const utils::var x, const utils::inf_rational &v, constraint * reason) noexcept
196+ bool solver::set_lb (const utils::var x, const utils::inf_rational &v, std::optional<std::reference_wrapper< constraint>> reason) noexcept
191197 {
192198 assert (x < vars.size ());
193199 assert (v > utils::rational::negative_infinite);
@@ -196,14 +202,14 @@ namespace linspire
196202 { // inconsistent bound..
197203 cnfl.clear ();
198204 if (reason)
199- cnfl.push_back (reason);
205+ cnfl.push_back (reason. value () );
200206 for (const auto &w : vars.at (x).ubs .begin ()->second ) // we use the most restrictive upper bound of x
201- cnfl.push_back (w);
207+ cnfl.push_back (* w);
202208 return false ;
203209 }
204210 if (reason)
205211 { // we have a reason for this bound..
206- if (auto it = reason->lbs .find (x); it != reason->lbs .end ())
212+ if (auto it = reason->get (). lbs .find (x); it != reason->get (). lbs .end ())
207213 { // we already have a lower bound for this variable in the reason..
208214 if (it->second < v)
209215 { // we update the lower bound only if the new one is more restrictive..
@@ -212,14 +218,14 @@ namespace linspire
212218 }
213219 }
214220 else
215- reason->lbs .emplace (x, v);
221+ reason->get (). lbs .emplace (x, v);
216222 }
217223 vars.at (x).set_lb (v, reason);
218224 if (val (x) < v && !is_basic (x))
219225 update (x, v);
220226 return true ;
221227 }
222- bool solver::set_ub (const utils::var x, const utils::inf_rational &v, constraint * reason) noexcept
228+ bool solver::set_ub (const utils::var x, const utils::inf_rational &v, std::optional<std::reference_wrapper< constraint>> reason) noexcept
223229 {
224230 assert (x < vars.size ());
225231 assert (v < utils::rational::positive_infinite);
@@ -228,14 +234,14 @@ namespace linspire
228234 { // inconsistent bound..
229235 cnfl.clear ();
230236 if (reason)
231- cnfl.push_back (reason);
237+ cnfl.push_back (reason. value () );
232238 for (const auto &w : vars.at (x).lbs .rbegin ()->second ) // we use the most restrictive lower bound of x
233- cnfl.push_back (w);
239+ cnfl.push_back (* w);
234240 return false ;
235241 }
236242 if (reason)
237243 { // we have a reason for this bound..
238- if (auto it = reason->ubs .find (x); it != reason->ubs .end ())
244+ if (auto it = reason->get (). ubs .find (x); it != reason->get (). ubs .end ())
239245 { // we already have an upper bound for this variable in the reason..
240246 if (it->second > v)
241247 { // we update the upper bound only if the new one is more restrictive..
@@ -244,7 +250,7 @@ namespace linspire
244250 }
245251 }
246252 else
247- reason->ubs .emplace (x, v);
253+ reason->get (). ubs .emplace (x, v);
248254 }
249255 vars.at (x).set_ub (v, reason);
250256 if (val (x) > v && !is_basic (x))
0 commit comments