/** * Create a propagator on real variables, propagated using IBEX. <br> * A constraint is defined using <code>functions</code>. A function is a string declared using the * following format: <br> * - the '{i}' tag defines a variable, where 'i' is an explicit index the array of variables * <code>vars</code>, <br> * - one or more operators :'+,-,*,/,=,<,>,<=,>=,exp( ),ln( ),max( ),min( ),abs( ),cos( ), sin( * ),...' <br> * A complete list is available in the documentation of IBEX. * * <p> * * <p> * * <blockquote> * * <pre> * new RealConstraint("({0}*{1})+sin({0})=1.0;ln({0}+[-0.1,0.1])>=2.6", new RealVar[]{x,y}, new String[]{""}, solver); * </pre> * * </blockquote> * * @param functions list of functions, separated by a semi-colon * @param vars array of variables * @param options list of options to give to IBEX */ public RealPropagator(String functions, RealVar[] vars, int options) { super(vars, PropagatorPriority.LINEAR, false); this.ibex = solver.getIbex(); this.functions = functions; this.option = options; this.contractorIdx = ibex.add_contractor(vars.length, functions, option); }
@Override public void propagate(int evtmask) throws ContradictionException { double domains[] = new double[2 * vars.length]; for (int i = 0; i < vars.length; i++) { domains[2 * i] = vars[i].getLB(); domains[2 * i + 1] = vars[i].getUB(); } int result = ibex.contract(contractorIdx, domains); switch (result) { case Ibex.FAIL: contradiction(null, "Ibex failed"); case Ibex.CONTRACT: for (int i = 0; i < vars.length; i++) { vars[i].updateBounds(domains[2 * i], domains[2 * i + 1], aCause); } break; case Ibex.ENTAILED: for (int i = 0; i < vars.length; i++) { vars[i].updateBounds(domains[2 * i], domains[2 * i + 1], aCause); } setPassive(); break; case Ibex.NOT_SIGNIFICANT: default: } }
@Override public ESat isEntailed() { double domains[] = new double[2 * vars.length]; for (int i = 0; i < vars.length; i++) { domains[2 * i] = vars[i].getLB(); domains[2 * i + 1] = vars[i].getUB(); } int result = ibex.contract(contractorIdx, domains); if (result == Ibex.FAIL) { return ESat.FALSE; } if (result == Ibex.ENTAILED || isCompletelyInstantiated()) { for (int i = 0; i < vars.length; i++) { if (vars[i].getLB() < domains[2 * i] || vars[i].getUB() > domains[2 * i + 1]) { if (domains[2 * i + 1] - domains[2 * i] >= vars[i].getPrecision()) { return ESat.UNDEFINED; } else { return ESat.FALSE; } } } return ESat.TRUE; } return ESat.UNDEFINED; }