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 #include <cmath>
00039
00040 namespace Gecode { namespace Int { namespace Arithmetic {
00041
00042
00043
00044
00045
00046 template <class VA, class VB>
00047 forceinline
00048 SqrPlus<VA,VB>::SqrPlus(Space* home, VA x0, VB x1)
00049 : MixBinaryPropagator<VA,PC_INT_BND,VB,PC_INT_BND>(home,x0,x1) {}
00050
00051 template <class VA, class VB>
00052 forceinline ExecStatus
00053 SqrPlus<VA,VB>::post(Space* home, VA x0, VB x1) {
00054 (void) new (home) SqrPlus<VA,VB>(home,x0,x1);
00055 return ES_OK;
00056 }
00057
00058 template <class VA, class VB>
00059 forceinline void
00060 SqrPlus<VA,VB>::post(Space* home, Reflection::VarMap& vars,
00061 const Reflection::ActorSpec& spec) {
00062 spec.checkArity(2);
00063 VA x0(home, vars, spec[0]);
00064 VB x1(home, vars, spec[1]);
00065 (void) new (home) SqrPlus<VA,VB>(home,x0,x1);
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_INT_BND,VB,PC_INT_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, ModEventDelta) {
00082 bool mod;
00083 do {
00084 mod = false;
00085 {
00086 ModEvent me = x0.lq(home,floor(::sqrt(static_cast<double>(x1.max()))));
00087 if (me_failed(me)) return ES_FAILED;
00088 mod |= me_modified(me);
00089 }
00090 {
00091 ModEvent me = x0.gq(home,ceil(::sqrt(static_cast<double>(x1.min()))));
00092 if (me_failed(me)) return ES_FAILED;
00093 mod |= me_modified(me);
00094 }
00095 {
00096 ModEvent me = x1.lq(home,x0.max()*x0.max());
00097 if (me_failed(me)) return ES_FAILED;
00098 mod |= me_modified(me);
00099 }
00100 {
00101 ModEvent me = x1.gq(home,x0.min()*x0.min());
00102 if (me_failed(me)) return ES_FAILED;
00103 mod |= me_modified(me);
00104 }
00105 } while (mod);
00106 return x0.assigned() ? ES_SUBSUMED(this,sizeof(*this)) : ES_FIX;
00107 }
00108
00109 template <class VA, class VB>
00110 Support::Symbol
00111 SqrPlus<VA,VB>::ati(void) {
00112 return Reflection::mangle<VA,VB>("Gecode::Int::Arithmetic::SqrPlus");
00113 }
00114
00115 template <class VA, class VB>
00116 Reflection::ActorSpec
00117 SqrPlus<VA,VB>::spec(const Space* home, Reflection::VarMap& m) const {
00118 return MixBinaryPropagator<VA,PC_INT_BND,VB,PC_INT_BND>
00119 ::spec(home, m, ati());
00120 }
00121
00122
00123
00124
00125
00126
00127 template <class View>
00128 forceinline
00129 Sqr<View>::Sqr(Space* home, View x0, View x1)
00130 : BinaryPropagator<View,PC_INT_BND>(home,x0,x1) {}
00131
00132 template <class View>
00133 forceinline ExecStatus
00134 Sqr<View>::post(Space* home, View x0, View x1) {
00135 GECODE_ME_CHECK(x1.gq(home,0));
00136 if (same(x0,x1)) {
00137 GECODE_ME_CHECK(x1.lq(home,1));
00138 } else {
00139 GECODE_ME_CHECK(x0.lq(home,floor(::sqrt(static_cast<double>
00140 (Limits::max)))));
00141 GECODE_ME_CHECK(x0.gq(home,-floor(::sqrt(static_cast<double>
00142 (-Limits::min)))));
00143 if (x0.min() >= 0)
00144 return SqrPlus<IntView,IntView>::post(home,x0,x1);
00145 if (x0.max() <= 0)
00146 return SqrPlus<MinusView,IntView>::post(home,x0,x1);
00147 (void) new (home) Sqr<View>(home,x0,x1);
00148 }
00149 return ES_OK;
00150 }
00151
00152 template <class View>
00153 forceinline void
00154 Sqr<View>::post(Space* home, Reflection::VarMap& vars,
00155 const Reflection::ActorSpec& spec) {
00156 spec.checkArity(2);
00157 View x0(home, vars, spec[0]);
00158 View x1(home, vars, spec[1]);
00159 (void) new (home) Sqr<View>(home,x0,x1);
00160 }
00161
00162 template <class View>
00163 forceinline
00164 Sqr<View>::Sqr(Space* home, bool share, Sqr<View>& p)
00165 : BinaryPropagator<View,PC_INT_BND>(home,share,p) {}
00166
00167 template <class View>
00168 Actor*
00169 Sqr<View>::copy(Space* home, bool share) {
00170 return new (home) Sqr<View>(home,share,*this);
00171 }
00172
00173 template <class View>
00174 PropCost
00175 Sqr<View>::cost(ModEventDelta) const {
00176 return PC_BINARY_HI;
00177 }
00178
00179 template <class View>
00180 ExecStatus
00181 Sqr<View>::propagate(Space* home, ModEventDelta) {
00182 assert(x1.min() >= 0);
00183 if (x0.min() >= 0)
00184 GECODE_REWRITE(this,(SqrPlus<IntView,IntView>::post(home,x0,x1)));
00185 if (x0.max() <= 0)
00186 GECODE_REWRITE(this,(SqrPlus<MinusView,IntView>::post(home,x0,x1)));
00187
00188 GECODE_ME_CHECK(x1.lq(home,std::max(x0.min()*x0.min(),
00189 x0.max()*x0.max())));
00190
00191 int s = static_cast<int>(floor(::sqrt(static_cast<double>(x1.max()))));
00192
00193 GECODE_ME_CHECK(x0.gq(home,-s));
00194 GECODE_ME_CHECK(x0.lq(home,s));
00195
00196 if (x0.assigned() && x1.assigned())
00197 return (x0.val()*x0.val() == x1.val()) ?
00198 ES_SUBSUMED(this,sizeof(*this)) : ES_FAILED;
00199
00200 return ES_NOFIX;
00201 }
00202
00203 template <class View>
00204 Support::Symbol
00205 Sqr<View>::ati(void) {
00206 return Reflection::mangle<View>("Gecode::Int::Arithmetic::Sqr");
00207 }
00208
00209 template <class View>
00210 Reflection::ActorSpec
00211 Sqr<View>::spec(const Space* home, Reflection::VarMap& m) const {
00212 return BinaryPropagator<View,PC_INT_BND>::spec(home, m, ati());
00213 }
00214
00215 }}}
00216
00217
00218