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