@@ -97,6 +97,38 @@ namespace Rice::detail {
9797 };
9898} // namespace Rice::detail
9999
100+ int64_t int64_strict (VALUE v) {
101+ if (!Object (v).is_a (rb_cInteger)) {
102+ throw std::invalid_argument{" Coefficient must be integer" };
103+ }
104+ return Rice::detail::From_Ruby<int64_t >().convert (v);
105+ }
106+
107+ operations_research::IntExpr* int_expr (operations_research::Solver& solver, Object o) {
108+ Object utils = Rice::define_module (" ORTools" ).const_get (" Utils" );
109+ Rice::Hash rb_coeffs = utils.call (" index_expression" , o);
110+
111+ std::vector<operations_research::IntVar*> vars;
112+ std::vector<int64_t > coeffs;
113+ int64_t constant = 0 ;
114+
115+ for (const auto & entry : rb_coeffs) {
116+ auto coeff = int64_strict (entry.value .value ());
117+ if (Object (entry.key ).is_nil ()) {
118+ constant = coeff;
119+ } else {
120+ vars.push_back (Rice::detail::From_Ruby<operations_research::IntVar*>().convert (entry.key .value ()));
121+ coeffs.push_back (coeff);
122+ }
123+ }
124+
125+ operations_research::IntExpr* expr = solver.MakeScalProd (vars, coeffs);
126+ if (constant != 0 ) {
127+ expr = solver.MakeSum (expr, constant);
128+ }
129+ return expr;
130+ }
131+
100132void init_routing (Rice::Module& m) {
101133 auto rb_cRoutingSearchParameters = Rice::define_class_under<RoutingSearchParameters>(m, " RoutingSearchParameters" );
102134 auto rb_cIntVar = Rice::define_class_under<operations_research::IntVar>(m, " RoutingIntVar" );
@@ -298,11 +330,20 @@ void init_routing(Rice::Module& m) {
298330 [](operations_research::Solver& self, Object o) {
299331 operations_research::Constraint* constraint;
300332 if (o.respond_to (" left" )) {
301- operations_research::IntExpr* left (Rice::detail::From_Ruby<operations_research::IntVar*>(). convert ( o.call (" left" ) ));
302- operations_research::IntExpr* right (Rice::detail::From_Ruby<operations_research::IntVar*>(). convert ( o.call (" right" ) ));
333+ auto left = int_expr (self, o.call (" left" ));
334+ auto right = int_expr (self, o.call (" right" ));
303335 std::string op = o.call (" op" ).to_s ().str ();
336+
304337 if (op == " ==" ) {
305338 constraint = self.MakeEquality (left, right);
339+ } else if (op == " !=" ) {
340+ constraint = self.MakeNonEquality (left, right);
341+ } else if (op == " >" ) {
342+ constraint = self.MakeGreater (left, right);
343+ } else if (op == " >=" ) {
344+ constraint = self.MakeGreaterOrEqual (left, right);
345+ } else if (op == " <" ) {
346+ constraint = self.MakeLess (left, right);
306347 } else if (op == " <=" ) {
307348 constraint = self.MakeLessOrEqual (left, right);
308349 } else {
0 commit comments