/* Creation of an empty piecewise constraint for variable v */ void rp_ctr_piecewise_create(rp_ctr_piecewise * c, int v) { rp_malloc(*c,rp_ctr_piecewise,sizeof(rp_ctr_piecewise_def)); rp_ctr_piecewise_var(*c) = v; rp_ctr_piecewise_ptr(*c) = NULL; rp_ctr_piecewise_arity(*c) = 0; rp_union_create(&rp_ctr_piecewise_guard(*c)); }
// Application of operator to reduce the box b int rp_operator_piecewise::apply(rp_box b) { DREAL_LOG_DEBUG << "rp_operator_piecewise::apply"; // Check each piece Ij:Cj, if Cj violated then the elements of Ij // are removed from the domain of the main variable of _c for (int i=0; i<rp_ctr_piecewise_arity(_c); ++i) { int violated = 0, j = 0; while ((!violated) && (j<rp_ctr_piecewise_elem_size(_c,i))) { if (rp_ctr_num_unfeasible(rp_ctr_piecewise_elem_ctrnum(_c,i,j),b)) { violated = 1; } else ++j; } if (violated) { // domain restriction dom(var) := dom(var) \ Ij rp_interval aux; rp_interval_copy(aux,rp_box_elem(b,rp_ctr_piecewise_var(_c))); rp_interval_setminus(rp_box_elem(b,rp_ctr_piecewise_var(_c)), aux, rp_ctr_piecewise_elem_dom(_c,i)); if (rp_interval_empty(rp_box_elem(b,rp_ctr_piecewise_var(_c)))) { return( 0 ); } } } // Check whether the domain of the main variable of _c // intersects at least one Ij int intersect = 0, i = 0; while ((!intersect) && (i<rp_ctr_piecewise_arity(_c))) { if (!rp_interval_disjoint(rp_box_elem(b,rp_ctr_piecewise_var(_c)), rp_ctr_piecewise_elem_dom(_c,i))) { intersect = 1; } else ++i; } return( intersect ); }
// Construction rp_operator_piecewise::rp_operator_piecewise(rp_ctr_piecewise c): rp_operator(RP_OPERATOR_DOMAIN_PRIORITY,0,1), _c(c) { rp_intset_create(&_vars); // depends on every variable of c for (int i=0; i<rp_ctr_piecewise_arity(c); ++i) { for (int j=0; j<rp_ctr_piecewise_elem_size(c,i); ++j) { rp_ctr_num cnum = rp_ctr_piecewise_elem_ctrnum(c,i,j); for (int k=0; k<rp_ctr_num_arity(cnum); ++k) { rp_intset_insert(_vars,rp_ctr_num_var(cnum,k)); } } } rp_intset_insert(_vars,rp_ctr_piecewise_var(c)); }
/* constraint */ int rp_rule_constraint(rp_parser p, rp_constraint * c) { rp_ctr_num cnum; rp_ctr_piecewise piece; int result = 0; /* piecewise constraint */ if (rp_parser_accept(p,RP_TOKEN_PIECEWISE)) { if (rp_rule_ctr_piecewise(p,&piece)) { /* intersection of the initial domain of the main variable */ /* and the set of pieces of the given constraint */ int index = rp_ctr_piecewise_var(piece); rp_variable v = ((rp_variable)rp_vector_elem(rp_parser_vars(p),index)); if (rp_union_inter_uu(rp_variable_domain(v),rp_ctr_piecewise_guard(piece))) { /* creation of the new constraint */ rp_constraint_create_piece(c,piece); result = 1; } else { rp_ctr_piecewise_destroy(&piece); rp_parser_stop(p,"no piece intersects with the variable domain"); } } } /* numerical or conditional constraint */ else if (rp_rule_ctr_num(p,&cnum)) { int guard = 0, conc = 0; if (rp_parser_accept(p,RP_TOKEN_SHARP)) { guard = 1; } else if (rp_parser_accept(p,RP_TOKEN_IMPLY)) { conc = 1; } if (guard || conc) { rp_ctr_cond cond; rp_ctr_cond_create(&cond); rp_ctr_cond_insert_guard(cond,cnum); if (rp_rule_ctr_cond(p,cond,guard)) { rp_constraint_create_cond(c,cond); result = 1; } else { rp_ctr_cond_destroy(&cond); } } else { rp_constraint_create_num(c,cnum); result = 1; } } return( result ); }
// Variables that can be pruned by the operator int rp_operator_piecewise::pruned_var(int /*i*/) const { return( rp_ctr_piecewise_var(_c) ); }