Generated on Mon Aug 25 11:35:38 2008 for Gecode by doxygen 1.5.6

propagator.icc

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Christian Schulte <schulte@gecode.org>
00005  *     Guido Tack <tack@gecode.org>
00006  *
00007  *  Copyright:
00008  *     Christian Schulte, 2002
00009  *     Guido Tack, 2004
00010  *
00011  *  Last modified:
00012  *     $Date: 2008-01-29 13:37:51 +0100 (Tue, 29 Jan 2008) $ by $Author: tack $
00013  *     $Revision: 5993 $
00014  *
00015  *  This file is part of Gecode, the generic constraint
00016  *  development environment:
00017  *     http://www.gecode.org
00018  *
00019  *  Permission is hereby granted, free of charge, to any person obtaining
00020  *  a copy of this software and associated documentation files (the
00021  *  "Software"), to deal in the Software without restriction, including
00022  *  without limitation the rights to use, copy, modify, merge, publish,
00023  *  distribute, sublicense, and/or sell copies of the Software, and to
00024  *  permit persons to whom the Software is furnished to do so, subject to
00025  *  the following conditions:
00026  *
00027  *  The above copyright notice and this permission notice shall be
00028  *  included in all copies or substantial portions of the Software.
00029  *
00030  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00031  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00032  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00033  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00034  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00035  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00036  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00037  *
00038  */
00039 
00040 namespace Gecode {
00041 
00050   enum PropKind {
00051     PK_DEF,    
00052     PK_SPEED,  
00053     PK_MEMORY  
00054   };
00055 
00056 
00063   PropCost cost_lo(int n, PropCost pc);
00070   PropCost cost_hi(int n, PropCost pc);
00071 
00072 
00089   template <class View, PropCond pc>
00090   class UnaryPropagator : public Propagator {
00091   protected:
00093     View x0;
00095     UnaryPropagator(Space* home, bool share, UnaryPropagator& p);
00097     UnaryPropagator(Space* home, bool share, Propagator& p,
00098                     View x0);
00100     UnaryPropagator(Space* home, View x0);
00101   public:
00103     virtual PropCost cost(ModEventDelta med) const;
00105     virtual size_t dispose(Space* home);
00107     Reflection::ActorSpec spec(const Space* home, Reflection::VarMap& m,
00108                                 const Support::Symbol& name) const;
00109   };
00110 
00120   template <class View, PropCond pc>
00121   class BinaryPropagator : public Propagator {
00122   protected:
00124     View x0, x1;
00126     BinaryPropagator(Space* home, bool share, BinaryPropagator& p);
00128     BinaryPropagator(Space* home, View x0, View x1);
00130     BinaryPropagator(Space* home, bool share, Propagator& p,
00131                      View x0, View x1);
00132   public:
00134     virtual PropCost cost(ModEventDelta med) const;
00136     virtual size_t dispose(Space* home);
00138     Reflection::ActorSpec spec(const Space* home, Reflection::VarMap& m,
00139                                 const Support::Symbol& name) const;
00140   };
00141 
00151   template <class View, PropCond pc>
00152   class TernaryPropagator : public Propagator {
00153   protected:
00155     View x0, x1, x2;
00157     TernaryPropagator(Space* home, bool share, TernaryPropagator& p);
00159     TernaryPropagator(Space* home, View x0, View x1, View x2);
00161     TernaryPropagator(Space* home, bool share, Propagator& p,
00162                       View x0, View x1, View x2);
00163   public:
00165     virtual PropCost cost(ModEventDelta med) const;
00167     virtual size_t dispose(Space* home);
00169     Reflection::ActorSpec spec(const Space* home, Reflection::VarMap& m,
00170                                 const Support::Symbol& name) const;
00171   };
00172 
00182   template <class View, PropCond pc>
00183   class NaryPropagator : public Propagator {
00184   protected:
00186     ViewArray<View> x;
00188     NaryPropagator(Space* home, bool share, NaryPropagator& p);
00190     NaryPropagator(Space* home, bool share, Propagator& p,
00191                    ViewArray<View>& x);
00193     NaryPropagator(Space* home, ViewArray<View>& x);
00194   public:
00196     virtual PropCost cost(ModEventDelta med) const;
00198     virtual size_t dispose(Space* home);
00200     Reflection::ActorSpec spec(const Space* home, Reflection::VarMap& m,
00201                                 const Support::Symbol& name) const;
00202   };
00203 
00214   template <class View, PropCond pc>
00215   class NaryOnePropagator : public Propagator {
00216   protected:
00218     ViewArray<View> x;
00220     View y;
00222     NaryOnePropagator(Space* home, bool share, NaryOnePropagator& p);
00224     NaryOnePropagator(Space* home, bool share, Propagator& p,
00225                       ViewArray<View>& x, View y);
00227     NaryOnePropagator(Space* home, ViewArray<View>& x, View y);
00228   public:
00230     virtual PropCost cost(ModEventDelta med) const;
00232     virtual size_t dispose(Space* home);
00234     Reflection::ActorSpec spec(const Space* home, Reflection::VarMap& m,
00235                                 const Support::Symbol& name) const;
00236   };
00237 
00248   template <class View0, PropCond pc0, class View1, PropCond pc1>
00249   class MixBinaryPropagator : public Propagator {
00250   protected:
00251     View0 x0;
00252     View1 x1;
00254     MixBinaryPropagator(Space* home,bool,MixBinaryPropagator&);
00256     MixBinaryPropagator(Space* home,View0,View1);
00258     MixBinaryPropagator(Space* home, bool share, Propagator& p,
00259                         View0 x0, View1 x1);
00260   public:
00262     virtual PropCost cost(ModEventDelta med) const;
00264     virtual size_t dispose(Space* home);
00266     Reflection::ActorSpec spec(const Space* home, Reflection::VarMap& m,
00267                                 const Support::Symbol& name) const;
00268   };
00269 
00280   template <class View0, PropCond pc0, class View1, PropCond pc1,
00281             class View2, PropCond pc2>
00282   class MixTernaryPropagator : public Propagator {
00283   protected:
00284     View0 x0;
00285     View1 x1;
00286     View2 x2;
00288     MixTernaryPropagator(Space* home,bool,MixTernaryPropagator&);
00290     MixTernaryPropagator(Space* home,View0,View1,View2);
00292     MixTernaryPropagator(Space* home, bool share, Propagator& p,
00293                          View0 x0, View1 x1, View2 x2);
00294   public:
00296     virtual PropCost cost(ModEventDelta med) const;
00298     virtual size_t dispose(Space* home);
00300     Reflection::ActorSpec spec(const Space* home, Reflection::VarMap& m,
00301                                 const Support::Symbol& name) const;
00302   };
00303 
00314   template <class View0, PropCond pc0, class View1, PropCond pc1>
00315   class MixNaryOnePropagator : public Propagator {
00316   protected:
00318     ViewArray<View0> x;
00320     View1 y;
00322     MixNaryOnePropagator(Space* home, bool share, MixNaryOnePropagator& p);
00324     MixNaryOnePropagator(Space* home, ViewArray<View0>& x, View1 y);
00326     MixNaryOnePropagator(Space* home, bool share, Propagator& p,
00327                          ViewArray<View0>& x, View1 y);
00328   public:
00330     virtual PropCost cost(ModEventDelta med) const;
00332     virtual size_t dispose(Space* home);
00334     Reflection::ActorSpec spec(const Space* home, Reflection::VarMap& m,
00335                                 const Support::Symbol& name) const;
00336   };
00338 
00339 
00340 
00341 
00342 
00343 
00344   /*
00345    * Dynamic cost computation
00346    *
00347    */
00348 
00349   forceinline PropCost
00350   cost_lo(int n, PropCost c) {
00351     if (n > 3) return c;
00352     if (n < 2) return PC_UNARY_LO;
00353     return (n > 2) ? PC_TERNARY_LO : PC_BINARY_LO;
00354   }
00355 
00356   forceinline PropCost
00357   cost_hi(int n, PropCost c) {
00358     if (n > 3) return c;
00359     if (n < 2) return PC_UNARY_HI;
00360     return (n > 2) ? PC_TERNARY_HI : PC_BINARY_HI;
00361   }
00362 
00363   /*
00364    * Unary propagators
00365    *
00366    */
00367 
00368   template <class View, PropCond pc>
00369   UnaryPropagator<View,pc>::UnaryPropagator(Space* home, View y0)
00370     : Propagator(home), x0(y0) {
00371     if (pc != PC_GEN_NONE)
00372       x0.subscribe(home,this,pc);
00373   }
00374 
00375   template <class View, PropCond pc>
00376   forceinline
00377   UnaryPropagator<View,pc>::UnaryPropagator
00378   (Space* home, bool share, UnaryPropagator<View,pc>& p)
00379     : Propagator(home,share,p) {
00380     x0.update(home,share,p.x0);
00381   }
00382 
00383   template <class View, PropCond pc>
00384   forceinline
00385   UnaryPropagator<View,pc>::UnaryPropagator
00386   (Space* home, bool share, Propagator& p, View y0)
00387     : Propagator(home,share,p) {
00388     x0.update(home,share,y0);
00389   }
00390 
00391   template <class View, PropCond pc>
00392   PropCost
00393   UnaryPropagator<View,pc>::cost(ModEventDelta) const {
00394     return PC_UNARY_LO;
00395   }
00396 
00397   template <class View, PropCond pc>
00398   forceinline size_t
00399   UnaryPropagator<View,pc>::dispose(Space* home) {
00400     if (pc != PC_GEN_NONE)
00401       x0.cancel(home,this,pc);
00402     (void) Propagator::dispose(home);
00403     return sizeof(*this);
00404   }
00405 
00406   template <class View, PropCond pc>
00407   Reflection::ActorSpec
00408   UnaryPropagator<View,pc>::spec(const Space* home, Reflection::VarMap& m,
00409                                  const Support::Symbol& ati) const {
00410     Reflection::ActorSpec s(ati);
00411     return s << x0.spec(home, m);
00412   }
00413   
00414 
00415   /*
00416    * Binary propagators
00417    *
00418    */
00419 
00420   template <class View, PropCond pc>
00421   BinaryPropagator<View,pc>::BinaryPropagator(Space* home, View y0, View y1)
00422     : Propagator(home), x0(y0), x1(y1) {
00423     if (pc != PC_GEN_NONE) {
00424       x0.subscribe(home,this,pc);
00425       x1.subscribe(home,this,pc);
00426     }
00427   }
00428 
00429   template <class View, PropCond pc>
00430   forceinline
00431   BinaryPropagator<View,pc>::BinaryPropagator
00432   (Space* home, bool share, BinaryPropagator<View,pc>& p)
00433     : Propagator(home,share,p) {
00434     x0.update(home,share,p.x0);
00435     x1.update(home,share,p.x1);
00436   }
00437 
00438   template <class View, PropCond pc>
00439   forceinline
00440   BinaryPropagator<View,pc>::BinaryPropagator
00441   (Space* home, bool share, Propagator& p, View y0, View y1)
00442     : Propagator(home,share,p) {
00443     x0.update(home,share,y0);
00444     x1.update(home,share,y1);
00445   }
00446 
00447   template <class View, PropCond pc>
00448   PropCost
00449   BinaryPropagator<View,pc>::cost(ModEventDelta) const {
00450     return PC_BINARY_LO;
00451   }
00452 
00453   template <class View, PropCond pc>
00454   forceinline size_t
00455   BinaryPropagator<View,pc>::dispose(Space* home) {
00456     if (pc != PC_GEN_NONE) {
00457       x0.cancel(home,this,pc);
00458       x1.cancel(home,this,pc);
00459     }
00460     (void) Propagator::dispose(home);
00461     return sizeof(*this);
00462   }
00463 
00464   template <class View, PropCond pc>
00465   Reflection::ActorSpec
00466   BinaryPropagator<View,pc>::spec(const Space* home, Reflection::VarMap& m,
00467                                   const Support::Symbol& name) const {
00468     Reflection::ActorSpec s(name);
00469     return s << x0.spec(home, m)
00470              << x1.spec(home, m);
00471   }
00472 
00473   /*
00474    * Ternary propagators
00475    *
00476    */
00477 
00478   template <class View, PropCond pc>
00479   TernaryPropagator<View,pc>::TernaryPropagator
00480   (Space* home, View y0, View y1, View y2)
00481     : Propagator(home), x0(y0), x1(y1), x2(y2) {
00482     if (pc != PC_GEN_NONE) {
00483       x0.subscribe(home,this,pc);
00484       x1.subscribe(home,this,pc);
00485       x2.subscribe(home,this,pc);
00486     }
00487   }
00488 
00489   template <class View, PropCond pc>
00490   forceinline
00491   TernaryPropagator<View,pc>::TernaryPropagator
00492   (Space* home, bool share, TernaryPropagator<View,pc>& p)
00493     : Propagator(home,share,p) {
00494     x0.update(home,share,p.x0);
00495     x1.update(home,share,p.x1);
00496     x2.update(home,share,p.x2);
00497   }
00498 
00499   template <class View, PropCond pc>
00500   forceinline
00501   TernaryPropagator<View,pc>::TernaryPropagator
00502   (Space* home, bool share, Propagator& p, View y0, View y1, View y2)
00503     : Propagator(home,share,p) {
00504     x0.update(home,share,y0);
00505     x1.update(home,share,y1);
00506     x2.update(home,share,y2);
00507   }
00508 
00509   template <class View, PropCond pc>
00510   PropCost
00511   TernaryPropagator<View,pc>::cost(ModEventDelta) const {
00512     return PC_TERNARY_LO;
00513   }
00514 
00515   template <class View, PropCond pc>
00516   forceinline size_t
00517   TernaryPropagator<View,pc>::dispose(Space* home) {
00518     if (pc != PC_GEN_NONE) {
00519       x0.cancel(home,this,pc);
00520       x1.cancel(home,this,pc);
00521       x2.cancel(home,this,pc);
00522     }
00523     (void) Propagator::dispose(home);
00524     return sizeof(*this);
00525   }
00526 
00527   template <class View, PropCond pc>
00528   Reflection::ActorSpec
00529   TernaryPropagator<View,pc>::spec(const Space* home, Reflection::VarMap& m,
00530                                    const Support::Symbol& name) const {
00531     Reflection::ActorSpec s(name);
00532     return s << x0.spec(home, m)
00533              << x1.spec(home, m)
00534              << x2.spec(home, m);
00535   }
00536 
00537   /*
00538    * Nary propagators
00539    *
00540    */
00541 
00542   template <class View, PropCond pc>
00543   NaryPropagator<View,pc>::NaryPropagator
00544   (Space* home, ViewArray<View>& y)
00545     : Propagator(home), x(y) {
00546     if (pc != PC_GEN_NONE)
00547       x.subscribe(home,this,pc);
00548   }
00549 
00550   template <class View, PropCond pc>
00551   forceinline
00552   NaryPropagator<View,pc>::NaryPropagator
00553   (Space* home, bool share, NaryPropagator<View,pc>& p)
00554     : Propagator(home,share,p) {
00555     x.update(home,share,p.x);
00556   }
00557 
00558   template <class View, PropCond pc>
00559   forceinline
00560   NaryPropagator<View,pc>::NaryPropagator
00561   (Space* home, bool share, Propagator& p, ViewArray<View>& x0)
00562     : Propagator(home,share,p) {
00563     x.update(home,share,x0);
00564   }
00565 
00566   template <class View, PropCond pc>
00567   PropCost
00568   NaryPropagator<View,pc>::cost(ModEventDelta) const {
00569     return cost_lo(x.size(), PC_LINEAR_LO);
00570   }
00571 
00572   template <class View, PropCond pc>
00573   forceinline size_t
00574   NaryPropagator<View,pc>::dispose(Space* home) {
00575     if (pc != PC_GEN_NONE)
00576       x.cancel(home,this,pc);
00577     (void) Propagator::dispose(home);
00578     return sizeof(*this);
00579   }
00580 
00581   template <class View, PropCond pc>
00582   Reflection::ActorSpec
00583   NaryPropagator<View,pc>::spec(const Space* home, Reflection::VarMap& m,
00584                                 const Support::Symbol& name) const {
00585     Reflection::ActorSpec s(name);
00586     return s << x.spec(home, m);
00587   }
00588 
00589   /*
00590    * NaryOne (one additional variable) propagators
00591    *
00592    */
00593 
00594   template <class View, PropCond pc>
00595   NaryOnePropagator<View,pc>::NaryOnePropagator
00596   (Space* home, ViewArray<View>& x0, View y0)
00597     : Propagator(home), x(x0), y(y0) {
00598     if (pc != PC_GEN_NONE) {
00599       x.subscribe(home,this,pc);
00600       y.subscribe(home,this,pc);
00601     }
00602   }
00603 
00604   template <class View, PropCond pc>
00605   forceinline
00606   NaryOnePropagator<View,pc>::NaryOnePropagator
00607   (Space* home, bool share, NaryOnePropagator<View,pc>& p)
00608     : Propagator(home,share,p) {
00609     x.update(home,share,p.x);
00610     y.update(home,share,p.y);
00611   }
00612 
00613   template <class View, PropCond pc>
00614   forceinline
00615   NaryOnePropagator<View,pc>::NaryOnePropagator
00616   (Space* home, bool share, Propagator& p, ViewArray<View>& x0, View y0)
00617     : Propagator(home,share,p) {
00618     x.update(home,share,x0);
00619     y.update(home,share,y0);
00620   }
00621 
00622   template <class View, PropCond pc>
00623   PropCost
00624   NaryOnePropagator<View,pc>::cost(ModEventDelta) const {
00625     return cost_lo(x.size()+1, PC_LINEAR_LO);
00626   }
00627 
00628   template <class View, PropCond pc>
00629   forceinline size_t
00630   NaryOnePropagator<View,pc>::dispose(Space* home) {
00631     if (pc != PC_GEN_NONE) {
00632       x.cancel(home,this,pc);
00633       y.cancel(home,this,pc);
00634     }
00635     (void) Propagator::dispose(home);
00636     return sizeof(*this);
00637   }
00638 
00639   template <class View, PropCond pc>
00640   Reflection::ActorSpec
00641   NaryOnePropagator<View,pc>::spec(const Space* home, Reflection::VarMap& m,
00642                                    const Support::Symbol& name) const {
00643     Reflection::ActorSpec s(name);
00644     return s << x.spec(home, m)
00645              << y.spec(home, m);
00646   }
00647 
00648   /*
00649    * Mixed binary propagators
00650    *
00651    */
00652 
00653   template <class View0, PropCond pc0, class View1, PropCond pc1>
00654   MixBinaryPropagator<View0,pc0,View1,pc1>::MixBinaryPropagator
00655   (Space* home, View0 y0, View1 y1)
00656     : Propagator(home), x0(y0), x1(y1) {
00657     if (pc0 != PC_GEN_NONE)
00658       x0.subscribe(home,this,pc0);
00659     if (pc1 != PC_GEN_NONE)
00660       x1.subscribe(home,this,pc1);
00661   }
00662 
00663   template <class View0, PropCond pc0, class View1, PropCond pc1>
00664   forceinline
00665   MixBinaryPropagator<View0,pc0,View1,pc1>::MixBinaryPropagator
00666   (Space* home, bool share, MixBinaryPropagator<View0,pc0,View1,pc1>& p)
00667     : Propagator(home,share,p) {
00668     x0.update(home,share,p.x0);
00669     x1.update(home,share,p.x1);
00670   }
00671 
00672   template <class View0, PropCond pc0, class View1, PropCond pc1>
00673   forceinline
00674   MixBinaryPropagator<View0,pc0,View1,pc1>::MixBinaryPropagator
00675   (Space* home, bool share, Propagator& p, View0 y0, View1 y1)
00676     : Propagator(home,share,p) {
00677     x0.update(home,share,y0);
00678     x1.update(home,share,y1);
00679   }
00680 
00681   template <class View0, PropCond pc0, class View1, PropCond pc1>
00682   PropCost
00683   MixBinaryPropagator<View0,pc0,View1,pc1>::cost(ModEventDelta) const {
00684     return PC_BINARY_LO;
00685   }
00686 
00687   template <class View0, PropCond pc0, class View1, PropCond pc1>
00688   forceinline size_t
00689   MixBinaryPropagator<View0,pc0,View1,pc1>::dispose(Space* home) {
00690     if (pc0 != PC_GEN_NONE)
00691       x0.cancel(home,this,pc0);
00692     if (pc1 != PC_GEN_NONE)
00693       x1.cancel(home,this,pc1);
00694     (void) Propagator::dispose(home);
00695     return sizeof(*this);
00696   }
00697 
00698   template <class View0, PropCond pc0, class View1, PropCond pc1>
00699   Reflection::ActorSpec
00700   MixBinaryPropagator<View0,pc0,View1,pc1>
00701   ::spec(const Space* home, Reflection::VarMap& m,
00702          const Support::Symbol& name) const {
00703     Reflection::ActorSpec s(name);
00704     return s << x0.spec(home, m)
00705              << x1.spec(home, m);
00706   }
00707 
00708   /*
00709    * Mixed ternary propagators
00710    *
00711    */
00712 
00713   template <class View0, PropCond pc0, class View1, PropCond pc1,
00714             class View2, PropCond pc2>
00715   MixTernaryPropagator<View0,pc0,View1,pc1,View2,pc2>::
00716   MixTernaryPropagator(Space* home, View0 y0, View1 y1, View2 y2)
00717     : Propagator(home), x0(y0), x1(y1), x2(y2) {
00718     if (pc0 != PC_GEN_NONE)
00719       x0.subscribe(home,this,pc0);
00720     if (pc1 != PC_GEN_NONE)
00721       x1.subscribe(home,this,pc1);
00722     if (pc2 != PC_GEN_NONE)
00723       x2.subscribe(home,this,pc2);
00724   }
00725 
00726   template <class View0, PropCond pc0, class View1, PropCond pc1,
00727             class View2, PropCond pc2>
00728   forceinline
00729   MixTernaryPropagator<View0,pc0,View1,pc1,View2,pc2>::
00730   MixTernaryPropagator(Space* home, bool share,
00731                          MixTernaryPropagator<View0,pc0,View1,pc1,
00732                          View2,pc2>& p)
00733     : Propagator(home,share,p) {
00734     x0.update(home,share,p.x0);
00735     x1.update(home,share,p.x1);
00736     x2.update(home,share,p.x2);
00737   }
00738 
00739   template <class View0, PropCond pc0, class View1, PropCond pc1,
00740             class View2, PropCond pc2>
00741   forceinline
00742   MixTernaryPropagator<View0,pc0,View1,pc1,View2,pc2>::MixTernaryPropagator
00743   (Space* home, bool share, Propagator& p, View0 y0, View1 y1, View2 y2)
00744     : Propagator(home,share,p) {
00745     x0.update(home,share,y0);
00746     x1.update(home,share,y1);
00747     x2.update(home,share,y2);
00748   }
00749 
00750   template <class View0, PropCond pc0, class View1, PropCond pc1,
00751             class View2, PropCond pc2>
00752   PropCost
00753   MixTernaryPropagator<View0,pc0,View1,pc1,View2,pc2>::cost(ModEventDelta) const {
00754     return PC_BINARY_LO;
00755   }
00756 
00757   template <class View0, PropCond pc0, class View1, PropCond pc1,
00758             class View2, PropCond pc2>
00759   forceinline size_t
00760   MixTernaryPropagator<View0,pc0,View1,pc1,View2,pc2>::dispose(Space* home) {
00761     if (pc0 != PC_GEN_NONE)
00762       x0.cancel(home,this,pc0);
00763     if (pc1 != PC_GEN_NONE)
00764       x1.cancel(home,this,pc1);
00765     if (pc2 != PC_GEN_NONE)
00766       x2.cancel(home,this,pc2);
00767     (void) Propagator::dispose(home);
00768     return sizeof(*this);
00769   }
00770 
00771   template <class View0, PropCond pc0, class View1, PropCond pc1,
00772             class View2, PropCond pc2>
00773   Reflection::ActorSpec
00774   MixTernaryPropagator<View0,pc0,View1,pc1,View2,pc2>
00775   ::spec(const Space* home, Reflection::VarMap& m,
00776          const Support::Symbol& name) const {
00777     Reflection::ActorSpec s(name);
00778     return s << x0.spec(home, m)
00779              << x1.spec(home, m)
00780              << x2.spec(home, m);
00781   }
00782 
00783   /*
00784    * MixNaryOne (one additional variable) propagators
00785    *
00786    */
00787 
00788   template <class View0, PropCond pc0, class View1, PropCond pc1>
00789   MixNaryOnePropagator<View0,pc0,View1,pc1>::MixNaryOnePropagator
00790   (Space* home, ViewArray<View0>& x0, View1 y0)
00791     : Propagator(home), x(x0), y(y0) {
00792     if (pc0 != PC_GEN_NONE)
00793       x.subscribe(home,this,pc0);
00794     if (pc1 != PC_GEN_NONE)
00795       y.subscribe(home,this,pc1);
00796   }
00797 
00798   template <class View0, PropCond pc0, class View1, PropCond pc1>
00799   forceinline
00800   MixNaryOnePropagator<View0,pc0,View1,pc1>::MixNaryOnePropagator
00801   (Space* home, bool share, MixNaryOnePropagator<View0,pc0,View1,pc1>& p)
00802     : Propagator(home,share,p) {
00803     x.update(home,share,p.x);
00804     y.update(home,share,p.y);
00805   }
00806 
00807   template <class View0, PropCond pc0, class View1, PropCond pc1>
00808   forceinline
00809   MixNaryOnePropagator<View0,pc0,View1,pc1>::MixNaryOnePropagator
00810   (Space* home, bool share, Propagator& p, ViewArray<View0>& x0, View1 y0)
00811     : Propagator(home,share,p) {
00812     x.update(home,share,x0);
00813     y.update(home,share,y0);
00814   }
00815 
00816   template <class View0, PropCond pc0, class View1, PropCond pc1>
00817   PropCost
00818   MixNaryOnePropagator<View0,pc0,View1,pc1>::cost(ModEventDelta) const {
00819     return cost_lo(x.size()+1, PC_LINEAR_LO);
00820   }
00821 
00822   template <class View0, PropCond pc0, class View1, PropCond pc1>
00823   forceinline size_t
00824   MixNaryOnePropagator<View0,pc0,View1,pc1>::dispose(Space* home) {
00825     if (pc0 != PC_GEN_NONE)
00826       x.cancel(home,this,pc0);
00827     if (pc1 != PC_GEN_NONE)
00828       y.cancel(home,this,pc1);
00829     (void) Propagator::dispose(home);
00830     return sizeof(*this);
00831   }
00832 
00833   template <class View0, PropCond pc0, class View1, PropCond pc1>
00834   Reflection::ActorSpec
00835   MixNaryOnePropagator<View0,pc0,View1,pc1>
00836   ::spec(const Space* home, Reflection::VarMap& m,
00837          const Support::Symbol& name) const {
00838     Reflection::ActorSpec s(name);
00839     return s << x.spec(home, m)
00840              << y.spec(home, m);
00841   }
00842 
00843 }
00844 
00845 // STATISTICS: kernel-other