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.
|
|
//=========================================================================
|
|
|
|
struct 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
|