| 153 | } |
| 154 | |
| 155 | void |
| 156 | LinIntExpr::post(Home home, IntRelType irt, |
| 157 | const IntPropLevels& ipls) const { |
| 158 | if (home.failed()) return; |
| 159 | Region r; |
| 160 | if (n->n_bool == 0) { |
| 161 | // Only integer variables |
| 162 | if (n->t==NT_ADD && n->l == nullptr && n->r->t==NT_NONLIN) { |
| 163 | n->r->sum.ne->post(home,irt,-n->c,ipls); |
| 164 | } else if (n->t==NT_SUB && n->r->t==NT_NONLIN && n->l==nullptr) { |
| 165 | switch (irt) { |
| 166 | case IRT_LQ: irt=IRT_GQ; break; |
| 167 | case IRT_LE: irt=IRT_GR; break; |
| 168 | case IRT_GQ: irt=IRT_LQ; break; |
| 169 | case IRT_GR: irt=IRT_LE; break; |
| 170 | default: break; |
| 171 | } |
| 172 | n->r->sum.ne->post(home,irt,n->c,ipls); |
| 173 | } else if (irt==IRT_EQ && |
| 174 | n->t==NT_SUB && n->r->t==NT_NONLIN && |
| 175 | n->l != nullptr && n->l->t==NT_VAR_INT |
| 176 | && n->l->a==1) { |
| 177 | (void) n->r->sum.ne->post(home,&n->l->x_int,ipls); |
| 178 | } else if (irt==IRT_EQ && |
| 179 | n->t==NT_SUB && n->r->t==NT_VAR_INT && |
| 180 | n->l != nullptr && n->l->t==NT_NONLIN |
| 181 | && n->r->a==1) { |
| 182 | (void) n->l->sum.ne->post(home,&n->r->x_int,ipls); |
| 183 | } else { |
| 184 | Int::Linear::Term<Int::IntView>* its = |
| 185 | r.alloc<Int::Linear::Term<Int::IntView> >(n->n_int); |
| 186 | int c = n->fill(home,ipls,its,nullptr); |
| 187 | Int::Linear::post(home, its, n->n_int, irt, -c, |
| 188 | (n->n_int > 2) ? ipls.linear() : ipls.linear2()); |
| 189 | } |
| 190 | } else if (n->n_int == 0) { |
| 191 | // Only Boolean variables |
| 192 | Int::Linear::Term<Int::BoolView>* bts = |
| 193 | r.alloc<Int::Linear::Term<Int::BoolView> >(n->n_bool); |
| 194 | int c = n->fill(home,ipls,nullptr,bts); |
| 195 | Int::Linear::post(home, bts, n->n_bool, irt, -c, |
| 196 | (n->n_bool > 2) ? ipls.linear() : ipls.linear2()); |
| 197 | } else if (n->n_bool == 1) { |
| 198 | // Integer variables and only one Boolean variable |
| 199 | Int::Linear::Term<Int::IntView>* its = |
| 200 | r.alloc<Int::Linear::Term<Int::IntView> >(n->n_int+1); |
| 201 | Int::Linear::Term<Int::BoolView>* bts = |
| 202 | r.alloc<Int::Linear::Term<Int::BoolView> >(1); |
| 203 | int c = n->fill(home,ipls,its,bts); |
| 204 | IntVar x(home,0,1); |
| 205 | channel(home,bts[0].x,x); |
| 206 | its[n->n_int].x = x; |
| 207 | its[n->n_int].a = bts[0].a; |
| 208 | Int::Linear::post(home, its, n->n_int+1, irt, -c, |
| 209 | (n->n_int > 1) ? ipls.linear() : ipls.linear2()); |
| 210 | } else { |
| 211 | // Both integer and Boolean variables |
| 212 | Int::Linear::Term<Int::IntView>* its = |