157 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			157 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| 
								 | 
							
								// -*- c++ -*-
							 | 
						||
| 
								 | 
							
								//=============================================================================
							 | 
						||
| 
								 | 
							
								// Copyright (C) 2011 by Denys Duchier
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// This program is free software: you can redistribute it and/or modify it
							 | 
						||
| 
								 | 
							
								// under the terms of the GNU Lesser General Public License as published by the
							 | 
						||
| 
								 | 
							
								// Free Software Foundation, either version 3 of the License, or (at your
							 | 
						||
| 
								 | 
							
								// option) any later version.
							 | 
						||
| 
								 | 
							
								// 
							 | 
						||
| 
								 | 
							
								// This program is distributed in the hope that it will be useful, but WITHOUT
							 | 
						||
| 
								 | 
							
								// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
							 | 
						||
| 
								 | 
							
								// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
							 | 
						||
| 
								 | 
							
								// more details.
							 | 
						||
| 
								 | 
							
								// 
							 | 
						||
| 
								 | 
							
								// You should have received a copy of the GNU Lesser General Public License
							 | 
						||
| 
								 | 
							
								// along with this program.  If not, see <http://www.gnu.org/licenses/>.
							 | 
						||
| 
								 | 
							
								//=============================================================================
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifndef __GECODE_DISJUNCTOR_HH__
							 | 
						||
| 
								 | 
							
								#define __GECODE_DISJUNCTOR_HH__
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <gecode/kernel.hh>
							 | 
						||
| 
								 | 
							
								#include <gecode/int.hh>
							 | 
						||
| 
								 | 
							
								#include <gecode/set.hh>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace Gecode { namespace Disjunctor_ {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    using namespace generic_gecode;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    //=========================================================================
							 | 
						||
| 
								 | 
							
								    // from a user perspective, a Disjunctor corresponds to a set of
							 | 
						||
| 
								 | 
							
								    // speculative clauses:
							 | 
						||
| 
								 | 
							
								    //
							 | 
						||
| 
								 | 
							
								    // - when a non-committed clause fails, it is simply discarded
							 | 
						||
| 
								 | 
							
								    // - when a single clause remains, it is committed
							 | 
						||
| 
								 | 
							
								    //
							 | 
						||
| 
								 | 
							
								    // from an implementation perspective, a Disjunctor is an object shared by
							 | 
						||
| 
								 | 
							
								    // several clauses, that contains a counter keeping track of how many
							 | 
						||
| 
								 | 
							
								    // clauses remain.  when the counter reaches 1, the remaining clause
							 | 
						||
| 
								 | 
							
								    // becomes committed.
							 | 
						||
| 
								 | 
							
								    //=========================================================================
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // following the example in MPG
							 | 
						||
| 
								 | 
							
								    struct Disjunctor: public LocalHandle
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      Disjunctor();
							 | 
						||
| 
								 | 
							
								      Disjunctor(Space& home);
							 | 
						||
| 
								 | 
							
								      Disjunctor(const Disjunctor& d);
							 | 
						||
| 
								 | 
							
								      int get() const;
							 | 
						||
| 
								 | 
							
								      void incr();
							 | 
						||
| 
								 | 
							
								      void decr();
							 | 
						||
| 
								 | 
							
								      void dispose(Space& home);
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    //=========================================================================
							 | 
						||
| 
								 | 
							
								    // a Clause encapsulates the speculative execution of a set of propagators.
							 | 
						||
| 
								 | 
							
								    // Therefore, these propagators must be posted in a separate (sub)space.
							 | 
						||
| 
								 | 
							
								    // However they normally want to constrain variables of the original home
							 | 
						||
| 
								 | 
							
								    // space: for each such variable X, a variable Y local to the subspace must
							 | 
						||
| 
								 | 
							
								    // be created and used instead, and a forwarder must be created from X to
							 | 
						||
| 
								 | 
							
								    // Y. A Clause is then a Propagator that subscribes to the Xs.  Whenever a
							 | 
						||
| 
								 | 
							
								    // X changes, the domains of the Xs are forwarded into the Ys and
							 | 
						||
| 
								 | 
							
								    // constraint propagation is run in the subspace.  When a clause is
							 | 
						||
| 
								 | 
							
								    // committed, after propagation, the domains of Ys are forwarded back into
							 | 
						||
| 
								 | 
							
								    // the Xs.
							 | 
						||
| 
								 | 
							
								    //=========================================================================
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // TODO: copy (difficulty is forwarder list)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    class SubSpace;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    class Clause: public Propagator {
							 | 
						||
| 
								 | 
							
								      Disjunctor disj;
							 | 
						||
| 
								 | 
							
								      SubSpace*const subhome;
							 | 
						||
| 
								 | 
							
								    public:
							 | 
						||
| 
								 | 
							
								      Clause(Space& home_, Disjunctor disj_);
							 | 
						||
| 
								 | 
							
								      Clause(Space& home, bool share, Clause& c);
							 | 
						||
| 
								 | 
							
								      virtual Propagator* copy(Space& home, bool share);
							 | 
						||
| 
								 | 
							
								      virtual size_t dispose(Space& home);
							 | 
						||
| 
								 | 
							
								      virtual PropCost cost(const Space&, const ModEventDelta&) const;
							 | 
						||
| 
								 | 
							
								      virtual ExecStatus propagate(Space& home, const ModEventDelta&);
							 | 
						||
| 
								 | 
							
								      // user API
							 | 
						||
| 
								 | 
							
								      operator GenericSpace&();
							 | 
						||
| 
								 | 
							
								      operator Space&();
							 | 
						||
| 
								 | 
							
								      operator Home();
							 | 
						||
| 
								 | 
							
								      GenericSpace* generic_space() const;
							 | 
						||
| 
								 | 
							
								      Space* space() const;
							 | 
						||
| 
								 | 
							
								      void forward(Space& home, IntVar  outer, IntVar  inner);
							 | 
						||
| 
								 | 
							
								      void forward(Space& home, BoolVar outer, BoolVar inner);
							 | 
						||
| 
								 | 
							
								      void forward(Space& home, SetVar  outer, SetVar  inner);
							 | 
						||
| 
								 | 
							
								    protected:
							 | 
						||
| 
								 | 
							
								      ExecStatus forward_in();
							 | 
						||
| 
								 | 
							
								      ExecStatus forward_out(Space& outer_home);
							 | 
						||
| 
								 | 
							
								      bool committed() const;
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    //=========================================================================
							 | 
						||
| 
								 | 
							
								    // a SubSpace is the Space associated with a Clause.  It also contains the
							 | 
						||
| 
								 | 
							
								    // forwarder linked-list because we want it to manage the memory for that
							 | 
						||
| 
								 | 
							
								    // list.
							 | 
						||
| 
								 | 
							
								    //=========================================================================
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    class BasicForwarder;
							 | 
						||
| 
								 | 
							
								    using Int::IntView;
							 | 
						||
| 
								 | 
							
								    using Int::BoolView;
							 | 
						||
| 
								 | 
							
								    using Set::SetView;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    class SubSpace: public GenericSpace
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								    private:
							 | 
						||
| 
								 | 
							
								      Space* homeDuringCloning;
							 | 
						||
| 
								 | 
							
								      // linked-list of pairs of a variable in the parent space and a
							 | 
						||
| 
								 | 
							
								      // corresponding variable in the subspace
							 | 
						||
| 
								 | 
							
								      BasicForwarder* forwarder;
							 | 
						||
| 
								 | 
							
								      // auxiliary methods for adding an entry to the forwarder list
							 | 
						||
| 
								 | 
							
								      void forward(IntView  outer, IntView  inner);
							 | 
						||
| 
								 | 
							
								      void forward(BoolView outer, BoolView inner);
							 | 
						||
| 
								 | 
							
								      void forward(SetView  outer, SetView  inner);
							 | 
						||
| 
								 | 
							
								      // for forwarding domains into and out of the subhome
							 | 
						||
| 
								 | 
							
								      ExecStatus forward_in();
							 | 
						||
| 
								 | 
							
								      ExecStatus forward_out(Space&);
							 | 
						||
| 
								 | 
							
								      // for cancelling subscriptions
							 | 
						||
| 
								 | 
							
								      void cancel(Space& home, Clause&);
							 | 
						||
| 
								 | 
							
								      // allow Clause to use this private API
							 | 
						||
| 
								 | 
							
								      friend class Clause;
							 | 
						||
| 
								 | 
							
								    public:
							 | 
						||
| 
								 | 
							
								      SubSpace();
							 | 
						||
| 
								 | 
							
								      SubSpace(bool share, SubSpace& s);
							 | 
						||
| 
								 | 
							
								      virtual Space* copy(bool share);
							 | 
						||
| 
								 | 
							
								      SubSpace* copy(Space& home, bool share);
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								}}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace Gecode
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  using Disjunctor_::Disjunctor;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  class Clause
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    generic_gecode::GenericSpace& _home;
							 | 
						||
| 
								 | 
							
								    Disjunctor_::Clause* _clause;
							 | 
						||
| 
								 | 
							
								  public:
							 | 
						||
| 
								 | 
							
								    Clause(generic_gecode::GenericSpace& home, Disjunctor disj);
							 | 
						||
| 
								 | 
							
								    operator generic_gecode::GenericSpace&();
							 | 
						||
| 
								 | 
							
								    operator Space&();
							 | 
						||
| 
								 | 
							
								    operator Home();
							 | 
						||
| 
								 | 
							
								    generic_gecode::GenericSpace* generic_space();
							 | 
						||
| 
								 | 
							
								    generic_gecode::GenericSpace* generic_parent();
							 | 
						||
| 
								 | 
							
								    Space* space();
							 | 
						||
| 
								 | 
							
								    void forward(IntVar  outer, IntVar  inner);
							 | 
						||
| 
								 | 
							
								    void forward(BoolVar outer, BoolVar inner);
							 | 
						||
| 
								 | 
							
								    void forward(SetVar  outer, SetVar  inner);
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif
							 |