00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 namespace Gecode { namespace Float { namespace Arithmetic {
00043
00044
00045
00046
00047
00048 template<class VA, class VB>
00049 forceinline
00050 SqrPlus<VA,VB>::SqrPlus(Home home, VA x0, VB x1)
00051 : MixBinaryPropagator<VA,PC_FLOAT_BND,VB,PC_FLOAT_BND>(home,x0,x1) {}
00052
00053 template<class VA, class VB>
00054 forceinline ExecStatus
00055 SqrPlus<VA,VB>::post(Home home, VA x0, VB x1) {
00056 if (same(x0,x1)) {
00057 if (x0.assigned())
00058 return ((x0.val() == 0) || (x0.val() == 1))? ES_OK : ES_FAILED;
00059 } else {
00060 GECODE_ME_CHECK(x0.eq(home,sqrt(x1.val())));
00061 GECODE_ME_CHECK(x1.eq(home,sqr(x0.val())));
00062 }
00063
00064 (void) new (home) SqrPlus<VA,VB>(home,x0,x1);
00065 return ES_OK;
00066 }
00067
00068 template<class VA, class VB>
00069 forceinline
00070 SqrPlus<VA,VB>::SqrPlus(Space& home, bool share, SqrPlus<VA,VB>& p)
00071 : MixBinaryPropagator<VA,PC_FLOAT_BND,VB,PC_FLOAT_BND>(home,share,p) {}
00072
00073 template<class VA, class VB>
00074 Actor*
00075 SqrPlus<VA,VB>::copy(Space& home, bool share) {
00076 return new (home) SqrPlus<VA,VB>(home,share,*this);
00077 }
00078
00079 template<class VA, class VB>
00080 ExecStatus
00081 SqrPlus<VA,VB>::propagate(Space& home, const ModEventDelta&) {
00082 if (same(x0,x1)) {
00083 if (x0.max() < 1) GECODE_ME_CHECK(x0.eq(home,0));
00084 else if (x0.min() > 0) GECODE_ME_CHECK(x0.eq(home,1));
00085 if (x0.assigned())
00086 return ((x0.val() == 0) || (x0.val() == 1))? home.ES_SUBSUMED(*this) : ES_FAILED;
00087 } else {
00088 GECODE_ME_CHECK(x0.eq(home,sqrt(x1.val())));
00089 GECODE_ME_CHECK(x1.eq(home,sqr(x0.val())));
00090 if (x0.assigned() || x1.assigned()) return home.ES_SUBSUMED(*this);
00091 }
00092
00093 return ES_FIX;
00094 }
00095
00096
00097
00098
00099
00100
00101
00102 template<class View>
00103 forceinline
00104 Sqr<View>::Sqr(Home home, View x0, View x1)
00105 : BinaryPropagator<View,PC_FLOAT_BND>(home,x0,x1) {}
00106
00107 template<class View>
00108 forceinline ExecStatus
00109 Sqr<View>::post(Home home, View x0, View x1) {
00110 GECODE_ME_CHECK(x1.gq(home,0));
00111 if (same(x0,x1)) {
00112 if (x0.assigned())
00113 return ((x0.val() == 0) || (x0.val() == 1))? ES_OK : ES_FAILED;
00114 GECODE_ME_CHECK(x1.lq(home,1));
00115 return SqrPlus<FloatView,FloatView>::post(home,x0,x1);
00116 } else {
00117 if (x0.min() >= 0)
00118 return SqrPlus<FloatView,FloatView>::post(home,x0,x1);
00119 if (x0.max() <= 0)
00120 return SqrPlus<MinusView,FloatView>::post(home,MinusView(x0),x1);
00121 GECODE_ME_CHECK(x1.eq(home,sqr(x0.val())));
00122 (void) new (home) Sqr<View>(home,x0,x1);
00123 }
00124 return ES_OK;
00125 }
00126
00127 template<class View>
00128 forceinline
00129 Sqr<View>::Sqr(Space& home, bool share, Sqr<View>& p)
00130 : BinaryPropagator<View,PC_FLOAT_BND>(home,share,p) {}
00131
00132 template<class View>
00133 Actor*
00134 Sqr<View>::copy(Space& home, bool share) {
00135 return new (home) Sqr<View>(home,share,*this);
00136 }
00137
00138 template<class View>
00139 ExecStatus
00140 Sqr<View>::propagate(Space& home, const ModEventDelta&) {
00141 assert(x1.min() >= 0);
00142 if (x0.min() >= 0)
00143 GECODE_REWRITE(*this,(SqrPlus<FloatView,FloatView>::post(home(*this),x0,x1)));
00144 if (x0.max() <= 0)
00145 GECODE_REWRITE(*this,(SqrPlus<MinusView,FloatView>::post(home(*this),
00146 MinusView(x0),x1)));
00147
00148 GECODE_ME_CHECK(x1.eq(home,sqr(x0.val())));
00149 Rounding r;
00150 FloatVal z = sqrt(x1.val());
00151 if (x0.min() > -r.sqrt_up(x1.min()))
00152 GECODE_ME_CHECK(x0.eq(home,z));
00153 else if (x0.max() < r.sqrt_down(x1.min()))
00154 GECODE_ME_CHECK(x0.eq(home,-z));
00155 else
00156 GECODE_ME_CHECK(x0.eq(home,hull(z,-z)));
00157
00158 return ES_NOFIX;
00159 }
00160
00161
00162
00163
00164
00165
00166
00167 template<class A, class B>
00168 forceinline
00169 Sqrt<A,B>::Sqrt(Home home, A x0, B x1)
00170 : MixBinaryPropagator<A,PC_FLOAT_BND,B,PC_FLOAT_BND>(home,x0,x1) {}
00171
00172 template<class A, class B>
00173 ExecStatus
00174 Sqrt<A,B>::post(Home home, A x0, B x1) {
00175 GECODE_ME_CHECK(x0.gq(home,0));
00176 if (same(x0,x1)) {
00177 if (x0.assigned())
00178 return ((x0.val() == 0) || (x0.val() == 1))? ES_OK : ES_FAILED;
00179 GECODE_ME_CHECK(x0.lq(home,1));
00180 (void) new (home) Sqrt<A,B>(home,x0,x1);
00181 } else {
00182 GECODE_ME_CHECK(x1.eq(home,sqrt(x0.val())));
00183 (void) new (home) Sqrt<A,B>(home,x0,x1);
00184 }
00185 return ES_OK;
00186 }
00187
00188 template<class A, class B>
00189 forceinline
00190 Sqrt<A,B>::Sqrt(Space& home, bool share, Sqrt<A,B>& p)
00191 : MixBinaryPropagator<A,PC_FLOAT_BND,B,PC_FLOAT_BND>(home,share,p) {}
00192
00193 template<class A, class B>
00194 Actor*
00195 Sqrt<A,B>::copy(Space& home, bool share) {
00196 return new (home) Sqrt<A,B>(home,share,*this);
00197 }
00198
00199 template<class A, class B>
00200 ExecStatus
00201 Sqrt<A,B>::propagate(Space& home, const ModEventDelta&) {
00202 if (same(x0,x1)) {
00203 if (x0.max() < 1) GECODE_ME_CHECK(x0.eq(home,0));
00204 else if (x0.min() > 0) GECODE_ME_CHECK(x0.eq(home,1));
00205 if (x0.assigned())
00206 return ((x0.val() == 0) || (x0.val() == 1))? home.ES_SUBSUMED(*this) : ES_FAILED;
00207 } else {
00208 GECODE_ME_CHECK(x0.eq(home,sqr(x1.val())));
00209 GECODE_ME_CHECK(x1.eq(home,sqrt(x0.val())));
00210 if (x0.assigned() || x1.assigned()) return home.ES_SUBSUMED(*this);
00211 }
00212
00213 return ES_FIX;
00214 }
00215
00216 }}}
00217
00218
00219